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

Related