This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

SD card uninitialization

I'm using:

OS : Windows 10

IDE : Segger Embedded  Studio for ARM Realease 4.52c Windows x64

SDK : nRF_SDK_15.0.0_a53641a

In my project I'm using 4 pressure sensors and 1 SD card, all of this using the same SPI.

1) I started with the presure sensors, For this I used the exemple found here : examples\peripheral\SPI and modified it a bit, add a custom Chip Select switching function and It worked just fine.

2) I continued with the SD Card, using the following exemple : examples\peripheral\fatfs, no major problems either 

3) I tried to merge 2) in 1), a little of work with the include and the path but my code compiles. Except that it crash,

    3.1) I initialize the SPI instance (sensor) make some measures

    3.2) Unitialise the SPI instance (sensor)

    3.3) Initialize, mount, write the SD Card (which use SPI)

    3.4) Unmount, uninitialize the SD_Card

    3.5) Unitialize the SPI instance (SD Card... I least I hope)

    3.6) Initialize the SPI instance (sensor) make some measures

    3.7) Uninitialize the SPI instance (sensor)

    3.8) Initialize, mount, write the SD Card (which use SPI)           But that dosen't work anymore

If I don't do 3.2) I can't do 3.3) because the SPI is already used

I don't know if I do 3.5) correctly, but if I just uninitialize the SD card it seems that the SPI instance is still used for the SD Card.

Includes:

#include "nrf_drv_spi.h"
#include "app_util_platform.h"
#include "nrf_gpio.h"
#include "nrf_delay.h"
#include "boards.h"
#include "app_error.h"
#include <string.h>
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"

#include "nrf.h"
#include "bsp.h"
#include "ff.h"
#include "diskio_blkdev.h"
#include "nrf_block_dev_sdc.h"

Defines:

#define SPI_INSTANCE  0 /**< SPI instance index. */

#define MISO 15     // P0.15
#define MOSI 16     // P0.16
#define SCLK 14     // P0.14

#define CS_P1 22    // prov DK 
#define CS_P2 23    // prov DK 
#define CS_P3 24    // prov DK 
#define CS_P4 25    // prov DK
#define CS_A1 26    // prov DK
#define CS_A2 27    // prov DK
#define CS_SD 2     // prov DK
#define LED_1 17    // prov DK

#define FILE_NAME   "LOG.CSV"

#define SDC_SCK_PIN     SCLK  ///< SDC serial clock (SCK) pin.
#define SDC_MOSI_PIN    MOSI  ///< SDC serial data in (DI) pin.
#define SDC_MISO_PIN    MISO  ///< SDC serial data out (DO) pin.
#define SDC_CS_PIN      CS_SD  ///< SDC chip select (CS) pin.

#define SAMPLE_NBR      100
#define SAMPLE_LENGHT   27

/**
 * @brief  SDC block device definition
 * */
NRF_BLOCK_DEV_SDC_DEFINE(
        m_block_dev_sdc,
        NRF_BLOCK_DEV_SDC_CONFIG(
                SDC_SECTOR_SIZE,
                APP_SDCARD_CONFIG(SDC_MOSI_PIN, SDC_MISO_PIN, SDC_SCK_PIN, SDC_CS_PIN)
         ),
         NFR_BLOCK_DEV_INFO_CONFIG("Nordic", "SDC", "1.00")
);

SD card writing function

static void ecriture_SD(char data[SAMPLE_NBR][SAMPLE_LENGHT])
{
    static FATFS fs;
    static DIR dir;
    static FILINFO fno;
    static FIL file;
    bool erreur = false;
    uint32_t cpt =  0;
    uint32_t bytes_written;
    FRESULT ff_result;
    DSTATUS disk_state = STA_NOINIT;

    // Initialize FATFS disk I/O interface by providing the block device.
    static diskio_blkdev_t drives[] =
    {
            DISKIO_BLOCKDEV_CONFIG(NRF_BLOCKDEV_BASE_ADDR(m_block_dev_sdc, block_dev), NULL)
    };

    diskio_blockdev_register(drives, ARRAY_SIZE(drives));


    // initialisation de la carte
    NRF_LOG_INFO("Initializing disk 0 (SDC)...");
    for (uint32_t retries = 3; retries && disk_state; --retries)
    {
        disk_state = disk_initialize(0);
    }
    if (disk_state)
    {
        NRF_LOG_INFO("Disk initialization failed.");
        return;
    }

    
    // monte la carte
    NRF_LOG_INFO("Mounting volume...");
    ff_result = f_mount(&fs, "", 1);
    if (ff_result)
    {
        NRF_LOG_INFO("Mount failed.");
        return;
    }
    

    // delete l'ancien fichier de log si 1er passage
    if(clear_data)
    {
        f_unlink(FILE_NAME);
        NRF_LOG_INFO("old file deleted.")
        clear_data = false;
    }


    // ouvre ou cree le fichier
    NRF_LOG_INFO("Writing to file " FILE_NAME "...");
    ff_result = f_open(&file, FILE_NAME, FA_READ | FA_WRITE | FA_OPEN_APPEND);
    if (ff_result != FR_OK)
    {
        NRF_LOG_INFO("Unable to open or create file: " FILE_NAME ".");
        return;
    }

    // ecrit dans le fichier
    for(cpt = 0; cpt < SAMPLE_NBR; cpt++)
    {
        ff_result = f_write(&file, data[cpt], SAMPLE_LENGHT - 1, (UINT *) &bytes_written);
        if (ff_result != FR_OK) erreur = true;
    }
    if (erreur)
    {
        NRF_LOG_INFO("Write failed\r\n.");
    }
    else
    {
        NRF_LOG_INFO("%d bytes written.\n", bytes_written * SAMPLE_NBR);
    }
    	
  
    // ferme le fichier
    (void) f_close(&file);


    // modif 23.07.2020
    // Unmonte la carte
    NRF_LOG_INFO("Unmounting volume...");
    ff_result = f_mount(NULL, "", 1);
    if (ff_result)
    {
        NRF_LOG_INFO("Unmount failed.");
        return;
    }
   
    // uninitialize disk 0
    NRF_LOG_INFO("Uninitializing disk 0 (SDC)...");
    for (uint32_t retries = 3; retries && disk_state; --retries)
    {
        disk_state = disk_uninitialize(0);
    }
    if (disk_state)
    {
        NRF_LOG_INFO("Disk uninitialization failed.");
        return;
    }
    
    nrf_drv_spi_uninit(&spi);   // detruit l'instance SPI
	// end of modif

    NRF_LOG_FLUSH();
    return;
}

Main

int main(void)
{
    
    uint32_t v_Press_1, v_Press_2, v_Press_3, v_Press_4;
    char data[SAMPLE_NBR][SAMPLE_LENGHT];
    uint32_t cpt = 0;
    uint32_t sample_number = 0;


    init_cs();      // init et set les Chip Select 

    // initialisation des log
    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_DEFAULT_BACKENDS_INIT();

    NRF_LOG_INFO("Main TB Wipfli start.");
    NRF_LOG_FLUSH();

    // initialisation SPI
    nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
    spi_config.ss_pin   = LED_1;
    spi_config.frequency = NRF_SPI_FREQ_4M;
    spi_config.miso_pin = MISO;
    spi_config.mosi_pin = MOSI;
    spi_config.sck_pin  = SCLK;
    APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));

    spi_xfer_done = false;    // reset fin de transfet
    
    // initialisation des capteurs de pression
    if(init_Capt_Press(CS_P1))NRF_LOG_INFO("Erreur init capt press 1");
    if(init_Capt_Press(CS_P2))NRF_LOG_INFO("Erreur init capt press 2");
    if(init_Capt_Press(CS_P3))NRF_LOG_INFO("Erreur init capt press 3");
    if(init_Capt_Press(CS_P4))NRF_LOG_INFO("Erreur init capt press 4");
    NRF_LOG_INFO("Init capt press done");

    NRF_LOG_INFO("Start main");
    NRF_LOG_FLUSH();

    while (1)
    {
        // Reset rx buffer and transfer done flag
        memset(m_rx_buf, 0, m_length);

        v_Press_1 = 0; // reset pression
        v_Press_2 = 0; // reset pression
        v_Press_3 = 0; // reset pression
        v_Press_4 = 0; // reset pression

        v_Press_1 = get_pression(CS_P1);
        v_Press_2 = get_pression(CS_P2);
        v_Press_3 = get_pression(CS_P3);
        v_Press_4 = get_pression(CS_P4);

        // log provisoir pour lire sur 4 digit
        NRF_LOG_INFO("Capt1 : %d hPa",v_Press_1);
        NRF_LOG_INFO("Capt2 : %d hPa",v_Press_2);
        NRF_LOG_INFO("Capt3 : %d hPa",v_Press_3);
        NRF_LOG_INFO("Capt4 : %d hPa\n",v_Press_4);
        NRF_LOG_FLUSH();

        // met en forme les datas dans un chunk
        sprintf(data[cpt],"%05d;%04d;%04d;%04d;%04d\n",sample_number,v_Press_1,v_Press_2,v_Press_3,v_Press_4);
        sample_number++;
        cpt++;

        // des qu'un chunk de data est pret
        if(cpt==SAMPLE_NBR)
        {
            nrf_drv_spi_uninit(&spi);   // detruit l'instance SPI
            cpt = 0;
            ecriture_SD(data);

            // recree l'instance SPI
            APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));
        }

        nrf_delay_ms(100);
    }
}

As I already said it work until I write in the SD card for the second time

Thanks for your time

Parents Reply
  • Hi

    Sorry for the slow response. Stian is currently out in vacation, and I will handle your case in the mean time. 

    As an exercise have you tried only initializing, using and uninitializing the SPI repeatedly for the SD card, without using it for your sensor also?

    It would be interesting to know if it is the re-initialization of the SD card that fails, or if it is related to using the SPI for something else in between. 

    Unfortunately I don't have the hardware needed to test this myself right now, but I will try to acquire it by tomorrow so I can try to reproduce your issue. 

    Best regards
    Torbjørn

Children
No Data
Related