This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320F28P650DK: SD Logging using CPU2 on TMS320F28P650DK9

Part Number: TMS320F28P650DK

Dear TI,

I am trying to achieve SD Card logging using CPU2 on the F28P65x core - the key objective is to write a simple message to a blank text file.

I have succeeded to use the TI example 'sd_fat32_exfat.c' to write a simple message to a blank text file (using CPU1).

I have also succeeded to follow the dual CORE examples: 'led_ex1_c28x_dual_blinky_cpu1.c' and 'led_ex1_c28x_dual_blinky_cpu2.c'.

My understanding is that CPU2 needs to be booted up by CPU1 - so my approach so far has been to modify the dual LED example by keeping the bootup logic but copying over the SD writing logic onto CPU2. 

However, I always seem to get FR_NOT_READY as my returned error code when i attempt f_open(). I know my pinMux is correct, as I have successfully written using CPU1.

I have attached my attempt at modifying the LED example for SD writing.

led_ex1_c28x_dual_blinky_cpu1.c 

led_ex1_c28x_dual_blinky_cpu2.c 

Any advice appreciated, 

Samuel.

  • Hi Samuel,

    The reason you might be getting that error is due to  CPU2 not currently having ownership of the peripheral you are attempting to use. For this SD Card logging are you attempting to use the SPI peripheral? 

    Kind regards,
    AJ Favela 

  • Hi Favela,

    Yes, the exchange uses SPI. In the code I attached, I use the CPU1 code to assign SPI ownership to CPU2 (plus boot CPU2). Then, on the CPU2 code, I perform the SPI config and SD write logic.

    Thanks, Samuel.

  • Hi Samuel,

    Apologies for the delayed response.

    GPIO_setControllerCore function must be called via CPU1, because only it has access to modify these registers
    Let me know if you continue to face issues after making this fix.
    Regards,
    Arnav
  • Hi Arnav,

    I followed your suggestion but I still seem to be receiving FR_NOT_READY. I have attached my latest code (sd_card_cpu1.c and sd_card_cpu2.c)

    I have found that CPU2 is able to have some control over SPI/FIFO registers by running this simple code, where I verify rxFifoActive = true:

    volatile bool rxFifoActive = false;
    
    // trigger transfer
    SPI_writeDataBlockingFIFO(SPID_BASE, 0xFF << 8);
    
    uint32_t timeout = 100000;
    while(SPI_getRxFIFOStatus(SPID_BASE) == 0 && timeout--)
    {
    }
    
    if(timeout != 0)
    {
    rxFifoActive = true;
    }

    #include "driverlib.h"
    #include "device.h"
    
    static void initSDPins(void)
    {
        // CS
        GPIO_setPinConfig(GPIO_94_GPIO94);
        GPIO_setPadConfig(94, GPIO_PIN_TYPE_STD);
        GPIO_setQualificationMode(94, GPIO_QUAL_SYNC);
        GPIO_setDirectionMode(94, GPIO_DIR_MODE_OUT);
        GPIO_writePin(94, 1);
    
        // LED
        GPIO_setPinConfig(GPIO_13_GPIO13);
        GPIO_setPadConfig(13, GPIO_PIN_TYPE_STD);
        GPIO_setDirectionMode(13, GPIO_DIR_MODE_OUT);
        GPIO_writePin(13, 1);
    
        // PICO
        GPIO_setPinConfig(GPIO_91_SPID_PICO);
        GPIO_setPadConfig(91, GPIO_PIN_TYPE_STD);
        GPIO_setQualificationMode(91, GPIO_QUAL_ASYNC);
    
        // POCI
        GPIO_setPinConfig(GPIO_92_SPID_POCI);
        GPIO_setPadConfig(92, GPIO_PIN_TYPE_STD);
        GPIO_setQualificationMode(92, GPIO_QUAL_ASYNC);
    
        // CLOCK
        GPIO_setPinConfig(GPIO_93_SPID_CLK);
        GPIO_setPadConfig(93, GPIO_PIN_TYPE_STD);
        GPIO_setQualificationMode(93, GPIO_QUAL_ASYNC);
    
    }
    
    
    void main(void)
    {
        //
        // Init device
        //
        Device_init();
        Device_initGPIO();
    
        //
        // Interrupt setup
        //
        Interrupt_initModule();
        Interrupt_initVectorTable();
    
        EINT;
        ERTM;
    
        //
        // Init SPI
        //
        initSDPins();
    
        EALLOW;
        // Give SPID ownership to CPU2 - this line is needed to make it through the f_open() stack
        SysCtl_selectCPUForPeripheralInstance(SYSCTL_CPUSEL_SPID, SYSCTL_CPUSEL_CPU2);
        //HWREG(DEVCFG_BASE + SYSCTL_O_CPUSEL6) |= (1UL << 3);
        EDIS;
    
        //
        // Assign memory to CPU2
        //
        MemCfg_setGSRAMControllerSel(MEMCFG_SECT_GS3, MEMCFG_GSRAMCONTROLLER_CPU2);
        MemCfg_setGSRAMControllerSel(MEMCFG_SECT_GS4, MEMCFG_GSRAMCONTROLLER_CPU2);
        SysCtl_allocateFlashBank(SYSCTL_FLASH_BANK3, SYSCTL_CPUSEL_CPU2);
        SysCtl_allocateFlashBank(SYSCTL_FLASH_BANK4, SYSCTL_CPUSEL_CPU2);
    
        //
        // Assign cores for SPI pins - this functions can only be called via CPU1
        //
        GPIO_setControllerCore(94, GPIO_CORE_CPU2);
        GPIO_setControllerCore(91, GPIO_CORE_CPU2);
        GPIO_setControllerCore(92, GPIO_CORE_CPU2);
        GPIO_setControllerCore(93, GPIO_CORE_CPU2);
    
        // Give GPIO13 control to CPU2
        GPIO_setControllerCore(13, GPIO_CORE_CPU2);
    
        //
        // Boot CPU2
        //
        #ifdef _FLASH
            Device_bootCPU2(BOOTMODE_BOOT_TO_FLASH_BANK3_SECTOR0);
        #else
            Device_bootCPU2(BOOTMODE_BOOT_TO_M0RAM);
        #endif
    
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    #include "driverlib.h"
    #include "device.h"
    
    #include <sdspi/sdspi.h>
    #include <sdspi/SDFatFS.h>
    #include <stdlib.h>
    #include <string.h>
    
    uint16_t SDFatFS_config_count = 1;
    SDFatFS_Object sdfatfsObject;
    
    #define SD_SPI_BASE      SPID_BASE
    #define SD_CS_GPIO       94
    #define SD_BITRATE       1000000U
    #define SD_DATAWIDTH     8U
    
    SDSPI_Object sdspiObject = {
        .spiHandle = SD_SPI_BASE,
        .spiCsGpioIndex = SD_CS_GPIO
    };
    
    SDFatFS_Object *SDFatFS_config[] = { &sdfatfsObject };
    SDSPI_Handle sdspiHandle = &sdspiObject;
    
    #define DRIVE_NUM 0
    #define STR_(n) #n
    #define STR(n)  STR_(n)
    
    const char outputfile[] = STR(DRIVE_NUM) ":hello.txt";
    const char textarray[]  = "hi nima\r\n";
    
    FIL dst;
    FRESULT fresult;
    unsigned int bytesWritten = 0U;
    
    
    static void initSPI(void)
    {
    
        EALLOW;
    
        // Enable SPID peripheral clock
        HWREG(CPUSYS_BASE + SYSCTL_O_PCLKCR8) |= (1UL << 3);
    
        // Put SPID into reset
        HWREG(CPUSYS_BASE + SYSCTL_O_SOFTPRES8) |= (1UL << 3);
    
        // Release SPID from soft reset
        HWREG(CPUSYS_BASE + SYSCTL_O_SOFTPRES8) &= ~(1UL << 3);
    
        // Make master
        HWREGH(SPID_BASE + SPI_O_CTL) |= (1U << 2);
    
        EDIS;
    
        // SPI
        SPI_reset(SPID_BASE);
        SPI_disableModule(SPID_BASE);
        SPI_disableFIFO(SPID_BASE);
        SPI_resetTxFIFO(SPID_BASE);
        SPI_resetRxFIFO(SPID_BASE);
    
    
        SPI_setConfig(SPID_BASE,
                      DEVICE_LSPCLK_FREQ,
                      SPI_PROT_POL0PHA1,
                      SPI_MODE_CONTROLLER,
                      400000,
                      8);
    
        SPI_setPTESignalPolarity(SPID_BASE, SPI_PTE_ACTIVE_LOW);
        SPI_disableLoopback(SPID_BASE);
        SPI_setEmulationMode(SPID_BASE, SPI_EMULATION_STOP_AFTER_TRANSMIT);
    
        SPI_enableFIFO(SPID_BASE);
        SPI_enableModule(SPID_BASE);
    
        GPIO_writePin(94, 1);
    
    }
    
    
    static void check_spid_health(void)
        {
        volatile bool spidClockEnabled =
                (HWREGH(CPUSYS_BASE + SYSCTL_O_PCLKCR8) & SYSCTL_PCLKCR8_SPI_D) != 0;
    
            volatile bool spidOwnedByCPU2 =
                ((HWREG(DEVCFG_BASE + SYSCTL_O_CPUSEL6) & (1UL << 3)) != 0);
    
            volatile bool spidSoftResetReleased =
                ((HWREG(CPUSYS_BASE + SYSCTL_O_SOFTPRES8) & (1UL << 3)) == 0);
    
            volatile bool spidOutOfReset =
                (HWREGH(SPID_BASE + SPI_O_CCR) & SPI_CCR_SPISWRESET) != 0;
    
            volatile bool spidMaster =
                ((HWREGH(SPID_BASE + SPI_O_CTL) & (1U << 2)) != 0);
    
            volatile bool spidFifoEnabled =
                ((HWREGH(SPID_BASE + SPI_O_FFTX) & (1U << 14)) != 0);
    
            volatile bool spidOwnedByCPU1 = ((HWREG(DEVCFG_BASE + SYSCTL_O_CPUSEL6) & (1UL << 3)) == 0);
    
        }
    
    
    void main(void)
    {
    
        // 0.5 second delay
        DEVICE_DELAY_US(500000);
    
        //Device_init();
        //Device_initGPIO();
    
        //Interrupt_initModule();
        //Interrupt_initVectorTable();
    
        // Init SPI
        initSPI();
    
        SDFatFS_init();
        SDFatFS_Handle handle = SDFatFS_open(sdspiHandle, DRIVE_NUM);
            if(handle == NULL)
            {
                ESTOP0;
                while(1)
                {
                }
            }
    
    
        // Turn off led
        GPIO_writePin(13, 1);
        DEVICE_DELAY_US(250000);
    
        // Attempt to open file on SD Card
        volatile FRESULT openResult;
        openResult = f_open(&dst, outputfile, FA_CREATE_ALWAYS | FA_WRITE);
        if(openResult != FR_OK)
           {
               ESTOP0;
               while(1)
               {
               }
           }
    
        fresult = f_write(&dst, textarray, (UINT)strlen(textarray), &bytesWritten);
        if((fresult != FR_OK) || (bytesWritten != (unsigned int)strlen(textarray)))
        {
            ESTOP0;
            while(1)
            {
            }
        }
    
    
    
        fresult = f_sync(&dst);
        if(fresult != FR_OK)
        {
            ESTOP0;
            while(1)
            {
            }
        }
    
        fresult = f_close(&dst);
        if(fresult != FR_OK)
        {
            ESTOP0;
            while(1)
            {
            }
        }
    
        SDFatFS_close(handle);
    
    
    
    
        ESTOP0;
    
        while(1)
        {
        }
    }
    
    int32_t fatfs_getFatTime(void)
    {
        return 0x4A210000;
    }
    
    void GPIO_init(void) {}
    void SPI_init(void) {}
    
    

    Any advice appreciated!

    Thanks,

    Samuel.

  • Hi Arnav,

    Update: I managed to succeed to SD log using CPU2, turns out I was using a modified sdspi.c which was breaking the spi transaction!

    I will share my working code.

    Thanks all for help!

    #include "driverlib.h"
    #include "device.h"
    
    static void initSDPins(void)
    {
        // CS
        GPIO_setPinConfig(GPIO_94_GPIO94);
        GPIO_setPadConfig(94, GPIO_PIN_TYPE_STD);
        GPIO_setQualificationMode(94, GPIO_QUAL_SYNC);
        GPIO_setDirectionMode(94, GPIO_DIR_MODE_OUT);
        GPIO_writePin(94, 1);
    
        // LED CPU2
        GPIO_setPinConfig(GPIO_13_GPIO13);
        GPIO_setPadConfig(13, GPIO_PIN_TYPE_STD);
        GPIO_setDirectionMode(13, GPIO_DIR_MODE_OUT);
        GPIO_writePin(13, 1);
    
        // LED CPU1
        GPIO_setPinConfig(GPIO_12_GPIO12);
        GPIO_setPadConfig(12, GPIO_PIN_TYPE_STD);
        GPIO_setDirectionMode(12, GPIO_DIR_MODE_OUT);
        GPIO_writePin(12, 1);
    
        // PICO (MOSI)
        GPIO_setPinConfig(GPIO_91_SPID_PICO);
        GPIO_setPadConfig(91, GPIO_PIN_TYPE_STD);
        GPIO_setQualificationMode(91, GPIO_QUAL_ASYNC);
    
        // POCI (MISO)
        GPIO_setPinConfig(GPIO_92_SPID_POCI);
        GPIO_setPadConfig(92, GPIO_PIN_TYPE_STD);
        GPIO_setQualificationMode(92, GPIO_QUAL_ASYNC);
    
        // CLOCK
        GPIO_setPinConfig(GPIO_93_SPID_CLK);
        GPIO_setPadConfig(93, GPIO_PIN_TYPE_STD);
        GPIO_setQualificationMode(93, GPIO_QUAL_ASYNC);
    
    }
    
    
    void main(void)
    {
        //
        // Init device
        //
        Device_init();
        Device_initGPIO();
    
        //
        // Assign memory to CPU2
        //
        MemCfg_setGSRAMControllerSel(MEMCFG_SECT_GS3, MEMCFG_GSRAMCONTROLLER_CPU2);
        MemCfg_setGSRAMControllerSel(MEMCFG_SECT_GS4, MEMCFG_GSRAMCONTROLLER_CPU2);
        SysCtl_allocateFlashBank(SYSCTL_FLASH_BANK3, SYSCTL_CPUSEL_CPU2);
        SysCtl_allocateFlashBank(SYSCTL_FLASH_BANK4, SYSCTL_CPUSEL_CPU2);
    
    
        //
        // Boot CPU2
        //
        #ifdef _FLASH
            Device_bootCPU2(BOOTMODE_BOOT_TO_FLASH_BANK3_SECTOR0);
        #else
            Device_bootCPU2(BOOTMODE_BOOT_TO_M0RAM);
        #endif
    
        // Enable SPID clock while CPU1 still owns system control
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SPID);
        EALLOW;
        // Give SPID ownership to CPU2 - this line is needed to make it through the f_open() stack
        SysCtl_selectCPUForPeripheralInstance(SYSCTL_CPUSEL_SPID, SYSCTL_CPUSEL_CPU2);
        //HWREG(DEVCFG_BASE + SYSCTL_O_CPUSEL6) |= (1UL << 3);
        EDIS;
    
        //
        // Init SPI
        //
        initSDPins();
    
        //
        // Assign cores for SPI pins - this functions can only be called via CPU1
        //
        GPIO_setControllerCore(94, GPIO_CORE_CPU2);
        GPIO_setControllerCore(91, GPIO_CORE_CPU2);
        GPIO_setControllerCore(92, GPIO_CORE_CPU2);
        GPIO_setControllerCore(93, GPIO_CORE_CPU2);
    
        // Give GPIO13 control to CPU2
        GPIO_setControllerCore(13, GPIO_CORE_CPU2);
    
        #define SYNC_FLAG 0x0001
        IPC_sync(IPC_CPU1_L_CPU2_R, SYNC_FLAG);
    
            while(1)
            {
                NOP;
            }
    
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    #include "driverlib.h"
    #include "device.h"
    
    #include <sdspi/sdspi.h>
    #include <sdspi/SDFatFS.h>
    #include <stdlib.h>
    #include <string.h>
    
    uint16_t SDFatFS_config_count = 1;
    SDFatFS_Object sdfatfsObject;
    
    #define SD_SPI_BASE      SPID_BASE
    #define SD_CS_GPIO       94
    #define SD_BITRATE       1000000U
    #define SD_DATAWIDTH     8U
    
    SDSPI_Object sdspiObject = {
        .spiHandle = SD_SPI_BASE,
        .spiCsGpioIndex = SD_CS_GPIO
    };
    
    SDFatFS_Object *SDFatFS_config[] = { &sdfatfsObject };
    SDSPI_Handle sdspiHandle = &sdspiObject;
    
    #define DRIVE_NUM 0
    #define STR_(n) #n
    #define STR(n)  STR_(n)
    
    const char outputfile[] = STR(DRIVE_NUM) ":hello.txt";
    const char textarray[]  = "hi nima\r\n";
    
    FIL dst;
    FRESULT fresult;
    unsigned int bytesWritten = 0U;
    
    
    static void initSPI(void)
    {
    
        EALLOW;
    
        // Enable SPID peripheral clock - seems to be essential to make it through f_open
        HWREG(CPUSYS_BASE + SYSCTL_O_PCLKCR8) |= (1UL << 3);
    
        EDIS;
    
        // SPI
    
        SPI_disableModule(SPID_BASE);
    
        SPI_setConfig(SPID_BASE,
                      DEVICE_LSPCLK_FREQ,
                      SPI_PROT_POL0PHA1,
                      SPI_MODE_CONTROLLER,
                      1000000,
                      8);
    
        SPI_setPTESignalPolarity(SPID_BASE, SPI_PTE_ACTIVE_LOW);
        SPI_disableLoopback(SPID_BASE);
        SPI_setEmulationMode(SPID_BASE, SPI_EMULATION_STOP_AFTER_TRANSMIT);
        SPI_enableFIFO(SPID_BASE);
        SPI_enableModule(SPID_BASE);
        GPIO_writePin(94, 1);
    
    }
    
    void main(void)
    {
    
        // 0.5 second delay
        DEVICE_DELAY_US(500000);
    
        Device_init();
    
        #define SYNC_FLAG 0x0001
        IPC_sync(IPC_CPU2_L_CPU1_R, SYNC_FLAG);
    
        // Init SPI
        initSPI();
    
        SDFatFS_init();
        SDFatFS_Handle handle = SDFatFS_open(sdspiHandle, DRIVE_NUM);
            if(handle == NULL)
            {
                ESTOP0;
                while(1)
                {
                }
            }
    
    
        // Turn off led
        GPIO_writePin(13, 1);
        DEVICE_DELAY_US(250000);
    
    
        volatile FRESULT openResult;
        openResult = f_open(&dst, outputfile, FA_CREATE_ALWAYS | FA_WRITE);
        if(openResult != FR_OK)
           {
               ESTOP0;
               while(1)
               {
               }
           }
    
    
        fresult = f_write(&dst, textarray, (UINT)strlen(textarray), &bytesWritten);
        if((fresult != FR_OK) || (bytesWritten != (unsigned int)strlen(textarray)))
        {
            ESTOP0;
            while(1)
            {
            }
        }
    
    
    
        fresult = f_sync(&dst);
        if(fresult != FR_OK)
        {
            ESTOP0;
            while(1)
            {
            }
        }
    
        fresult = f_close(&dst);
        if(fresult != FR_OK)
        {
            ESTOP0;
            while(1)
            {
            }
        }
    
        SDFatFS_close(handle);
    
    
    
    
        ESTOP0;
    
        while(1)
        {
        }
    }
    
    int32_t fatfs_getFatTime(void)
    {
        return 0x4A210000;
    }
    
    void GPIO_init(void) {}
    void SPI_init(void) {}