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.

MSP432P401R: How to save Data on SD card and have multiple ADC channels using TI-RTOS

Part Number: MSP432P401R

Hello

I'm going to explain what i have and what i want to do.

Right now, I'm doing a multiple sampling data using 12 ADC channels. 3 channels for sensors, so i have 4 independents tasks for each sensors, becuase i set the sample time using the (Task_Sleep) function, so i get new data every task_sleep time i set for each one task.

/* VIBRATION TASK */ //Example of 1 of the 4 task
void vibWork(void)
{
   if (start == 1)
   {
       vxc = ADC14_getResult(ADC_MEM0);
       vyc = ADC14_getResult(ADC_MEM1);
       vzc = ADC14_getResult(ADC_MEM3);
       ADC14_toggleConversionTrigger();
   }
}
void vibTaskFunc(UArg arg0, UArg arg1)
{
   while (1) {
       vibWork();
       Task_sleep((freqgvibracion * 1000) * (1000 / Clock_tickPeriod)); //Periodic task
   }
}

The sample time of the taks are 1ms , 2ms, 4ms, etc.. So i cannot save the the value of ADC inside the task because the its take about 13ms to save one value (convert the int to string, then write (f_write) on SD).

so i need another way to save the data on SD and keep getting new data over ADC, maybe make another task for save the data on the SD card. i dont know how

Can you help me please?

Thanks in advance

  • Hello,
    I believe that there are a couple of examples that you will find helpful.

    Multi-thread example/tutorial

    dev.ti.com/.../

    SD Card FAT file system read/write

    dev.ti.com/.../

    Regards,
    Chris
  • Thanks for the reply Chris

    I have all the task for the sensor reading, and i have thread for each Bluetooth, RTC and each sensors.

    So the thing is, i need to save the obtained array of data and keep recording new data, something like a DMA(saving the buffer and sending to the SD card, but i dont know how to implement it in a Multi-thread application with TI-RTOS.

    i found example using DMA + ADC but they arent using RTOS.
  • Two suggestions:
    How fast is it if you don't convert to a string?

    How long do you need to record before you can wait for the SD card to catch up? DMA won't help you if you continuously read data each ms and it takes 13 ms to write it.
  • To wirte to sd card i did this: 

    sprintf(frecuencias, "Sample rate(Hz): %.1f\r\n", (1/freqgiroscopo));
    f_write(&objetogyro, frecuencias, strlen(frecuencias), &bytesWritten);

    or 

    sprintf(tiempo,"Time: %02d:%02d:%02d\r\n",horaRtc,minutos,segundos);
    f_write(&objetogyro, tiempo, strlen(tiempo), &bytesWritten);

    sprintf let me convert the int or float to string, then i can use f_write, to write on SD (these two instructions takes about 13ms to complete).

    The next data to records are the array of values obtained from de ADC, but i cant write "int variables" dirrectly using f_write that why i use sprintf.

    Any advice to do this in less time or another way to record new data (every 1ms o 500 us) while saving in the SD card?

  • I would dump raw data to the SD - you *really* don't want to do the reciprocal!
    You can always post-process later.

    Again, is this continuous or can you get say 1000 samples (You have 64KB of RAM to play with) and take a breather to dump it to the SD? You are running at 48 MHz, right? You have activated the FPU, right?
  • For example i would set to get sample every 1ms for 1 min or until i push a button to stop record. So this is a continous process!

    Yes i running at 48 MHz and active the FPU.

    CS_setExternalClockSourceFrequency(32000,48000000);
    /* Starting LFXT in non-bypass mode without a timeout. */
    CS_startLFXT(CS_LFXT_DRIVE3);
    
    /* Enabling the FPU for floating point operation */
    FPU_enableModule();
    FPU_enableLazyStacking();

    So any idea?? Can you help me with the code

  • That only starts the low frequency crystal. Do you have a CS_startHFXT() anywhere?
  • I would switch to the P411:
    www.ti.com/.../MSP-EXP432P4111

    It has 256KByte of RAM. You can buffer 16bits * 1/ms * 1 min or 120KB and still have plenty of room. Then you can read out at your leisure.
  • i cant switch to another MSP, i have to do it with the MSP432P401R,

    i dont know how to buffer the data on the RAM and then transfer to the SD card, any example code??
  • First, instead of sprintf, you can use K&R's itoa example. (There might be one in ti's stdlib):
    void itoa(int n, char s[])
    {
    int i, sign;
    if ((sign = n) < 0) /* record sign */
    n = -n; /* make n positive */
    i = 0;
    do { /* generate digits in reverse order */
    s[i++] = n % 10 + '0'; /* get next digit */
    } while ((n /= 10) > 0); /* delete it */
    if (sign < 0)
    s[i++] = '-';
    s[i] = '\0';
    reverse(s);
    return;
    }

    Second: Do you call CS_startHFXT()?

    Here is some pseudo code:

    uint16_t Buf[1024];

    fromADC_idx = 0;
    toSD_idx = 0;

    start ADC, use interrupt to fill buffer with Buf[fromADC_idx++]

    In main loop:
    if (fromADC_idx > toSD_idx)
    {
    // We have data to convert
    char result[16]
    itoa(toSD_idx++, result);
    writeToSD(result)
    }

    Adding the ability to wrap around in a circular buffer is left as an exercise.

    But unless you get your write to SD card time down, this won't work, the buffer will quickly fill up before it gets emptied.
  • Second: Do you call CS_startHFXT()? Now yes!
    FlashCtl_setWaitState(FLASH_BANK0, 2);
    FlashCtl_setWaitState(FLASH_BANK1, 2);
    
    CS_setExternalClockSourceFrequency(32000,48000000);
    /* Starting LFXT in non-bypass mode without a timeout. */
    CS_startLFXT(CS_LFXT_DRIVE3);
    CS_startHFXT(false);
    
    /* Enabling the FPU for floating point operation */
    FPU_enableModule();
    FPU_enableLazyStacking();

    I'm going to try the solutions you gave me and then I'll tell you how they were.

    Thanks in advance

  • If you have a red board, you only need 1 flash wait state, and you need to change Vcore, too.
  • Can you show me how please?

  • Check out the hfxt driverlib example. It is all there:
    MAP_PCM_setCoreVoltageLevel(PCM_VCORE1);
    MAP_FlashCtl_setWaitState(FLASH_BANK0, 1);
    MAP_FlashCtl_setWaitState(FLASH_BANK1, 1);

**Attention** This is a public forum