Hot!Harmony SD Card in Polling Mode

Author
gbarker
New Member
  • Total Posts : 3
  • Reward points : 0
  • Joined: 2018/09/17 10:56:16
  • Location: 0
  • Status: offline
2018/09/18 08:53:48 (permalink)
0

Harmony SD Card in Polling Mode

I have provided a lot of information below, but the basic question is simple: Why does my SD Card access work in interrupt mode, but fail in polling mode?

We have a PIC32MX695F512L-based system, run by polling software pre-dating Harmony. The software has since been upgraded to Harmony v2_02_00b, MPLAB X IDE v4.15, still in polling mode. Now we want to add an SD Card interface, and I am having issues. I tried adding in the SD Card driver directly to our controller software, with little success. So I started over with a simpler project, which I will describe here.

I used the sdcard_fat_single_disk example, specifically pic32mx795_pim_e16_int_dyn_freertos, as a model. I started out trying to duplicate this interrupt-driven example on my hardware. I created a project from scratch, with the following Harmony settings. (I can't get Microchip web site to let me insert screenshots, so these are from default.mhc config file.) Note that ISR_MODE=y and POLLED_MODE=n:

CONFIG_USE_DRV_SDCARD=y
CONFIG_DRV_SDCARD_RTOS="Combined with System Tasks"
CONFIG_DRV_SDCARD_IMPL="DYNAMIC"
CONFIG_DRV_SDCARD_CLIENTS_NUMBER=1
CONFIG_DRV_SDCARD_INDEX="DRV_SDCARD_INDEX_0"
CONFIG_DRV_SDCARD_INDEX_MAX=1
CONFIG_DRV_SDCARD_QUEUE_POOL_SIZE=10
CONFIG_DRV_SDCARD_SPI_CLOCK_ID="CLK_BUS_PERIPHERAL_1"
CONFIG_DRV_SDCARD_SPEED=20000000
CONFIG_DRV_SDCARD_WRITE_PROTECT_SUPPORT=n
CONFIG_DRV_SDCARD_CS_PORT_CHANNEL="PORT_CHANNEL_D"
CONFIG_DRV_SDCARD_CS_BIT_POSITION="PORTS_BIT_POS_9"
CONFIG_DRV_SDCARD_SPI_DRV_INSTANCE=0
CONFIG_USE_DRV_SDCARD_SYS_FS_REGISTER=y

CONFIG_DRV_SPI_USE_DRIVER=y
CONFIG_DRV_SPI_DRIVER_MODE="DYNAMIC"
CONFIG_DRV_SPI_USE_ISR_MODE=y
CONFIG_DRV_SPI_USE_POLLED_MODE=n
CONFIG_DRV_SPI_USE_MASTER_MODE=y
CONFIG_DRV_SPI_USE_SLAVE_MODE=n
CONFIG_DRV_SPI_USE_STANDARD_BUFFER_MODE=n
CONFIG_DRV_SPI_USE_ENHANCED_BUFFER_MODE=y
CONFIG_DRV_SPI_USE_8BIT_MODE=y
CONFIG_DRV_SPI_USE_16BIT_MODE=n
CONFIG_DRV_SPI_USE_32BIT_MODE=n
CONFIG_DRV_SPI_USE_DMA=n
CONFIG_DRV_SPI_INSTANCES_NUMBER=1
CONFIG_DRV_SPI_CLIENT_NUMBER=1
CONFIG_DRV_SPI_NUM_ELEMENTS_PER_INSTANCE=10

CONFIG_DRV_SPI_IDX0=y
CONFIG_DRV_SPI_RTOS_IDX0="Standalone"
CONFIG_DRV_SPI_IDX0_RTOS_TASK_SIZE=1024
CONFIG_DRV_SPI_IDX0_RTOS_TASK_PRIORITY=1
CONFIG_DRV_SPI_IDX0_RTOS_USE_DELAY=y
CONFIG_DRV_SPI_IDX0_RTOS_DELAY=1000
CONFIG_DRV_SPI_SPI_ID_IDX0="SPI_ID_1"
CONFIG_DRV_SPI_TASK_MODE_ISR_IDX0=y
CONFIG_DRV_SPI_INT_PRIORITY_IDX0="INT_PRIORITY_LEVEL3"
CONFIG_DRV_SPI_INT_SUB_PRIORITY_IDX0="INT_SUBPRIORITY_LEVEL0"
CONFIG_DRV_SPI_SPI_MODE_MASTER_IDX0=y
CONFIG_DRV_SPI_COMM_WIDTH_8_BIT_IDX0=y
CONFIG_DRV_SPI_BUFFER_ENHANCED_IDX0=y
CONFIG_DRV_SPI_ALLOW_IDLE_RUN_IDX0=n
CONFIG_DRV_SPI_SPI_PROTOCOL_TYPE_IDX0="DRV_SPI_PROTOCOL_TYPE_STANDARD"
CONFIG_DRV_SPI_CLOCK_SOURCE1_IDX0="SPI_BAUD_RATE_PBCLK_CLOCK"
CONFIG_DRV_SPI_BAUD_RATE_IDX0=1000000
CONFIG_DRV_SPI_CLOCK_MODE_IDX0="DRV_SPI_CLOCK_MODE_IDLE_LOW_EDGE_RISE"
CONFIG_DRV_SPI_INPUT_PHASE_IDX0="SPI_INPUT_SAMPLING_PHASE_IN_MIDDLE"
CONFIG_DRV_SPI_TRANSMIT_DUMMY_BYTE_VALUE_IDX0="0xFF"
CONFIG_DRV_SPI_QUEUE_SIZE_IDX0=10
CONFIG_DRV_SPI_RESERVED_JOB_IDX0=1
CONFIG_DRV_SPI_SPI_ID_STATIC_IDX0="SPI_ID_1"
CONFIG_DRV_SPI_SPI_MODE_STATIC_IDX0="DRV_SPI_MODE_MASTER"
CONFIG_DRV_SPI_COMM_WIDTH_STATIC_IDX0="SPI_COMMUNICATION_WIDTH_8BITS"
CONFIG_DRV_SPI_BUFFER_STATIC_IDX0="DRV_SPI_BUFFER_TYPE_ENHANCED"
CONFIG_DRV_SPI_ALLOW_IDLE_RUN_STATIC_IDX0=n
CONFIG_DRV_SPI_SPI_PROTOCOL_TYPE_STATIC_IDX0="DRV_SPI_PROTOCOL_TYPE_STANDARD"
CONFIG_DRV_SPI_FRAME_SYNC_PULSE_STATIC_IDX0="SPI_FRAME_SYNC_PULSE_ON_EVERY_DATA_CHARACTER"
CONFIG_DRV_SPI_FRAME_PULSE_POLARITY_STATIC_IDX0="SPI_FRAME_PULSE_POLARITY_ACTIVE_LOW"
CONFIG_DRV_SPI_FRAME_PULSE_DIRECTION_STATIC_IDX0="SPI_FRAME_PULSE_DIRECTION_OUTPUT"
CONFIG_DRV_SPI_FRAME_PULSE_EDGE_STATIC_IDX0="SPI_FRAME_PULSE_EDGE_PRECEDES_FIRST_BIT_CLOCK"
CONFIG_DRV_SPI_FRAME_PULSE_WIDTH_STATIC_IDX0="SPI_FRAME_PULSE_WIDTH_ONE_CLOCK_WIDE"
CONFIG_DRV_SPI_AUDIO_TRANSMIT_MODE_STATIC_IDX0="SPI_AUDIO_TRANSMIT_STEREO"
CONFIG_DRV_SPI_AUDIO_PROTOCOL_MODE_STATIC_IDX0="SPI_AUDIO_PROTOCOL_I2S"
CONFIG_DRV_SPI_SPI_CLOCK_STATIC_IDX0="CLK_BUS_PERIPHERAL_1"
CONFIG_DRV_SPI_BAUD_RATE_STATIC_IDX0=1000000
CONFIG_DRV_SPI_CLOCK_MODE_STATIC_IDX0="DRV_SPI_CLOCK_MODE_IDLE_LOW_EDGE_RISE"
CONFIG_DRV_SPI_INPUT_PHASE_STATIC_IDX0="SPI_INPUT_SAMPLING_PHASE_IN_MIDDLE"

CONFIG_USE_SYS_FS=y
CONFIG_SYS_FS_RTOS="Combined with System Tasks"
CONFIG_SYS_FS_MAX_FILES=2
CONFIG_SYS_FS_MEDIA_MAX_BLOCK_SIZE=512
CONFIG_SYS_FS_MEDIA_MANAGER_BUFFER_SIZE=512
CONFIG_SYS_FS_AUTO_MOUNT=n
CONFIG_SYS_FS_INSTANCES_NUMBER=1
CONFIG_SYS_FS_VOLUME_NUMBER=1
CONFIG_SYS_FS_MAX_FILE_SYSTEM_TYPE=1
CONFIG_SYS_FS_FAT=y
CONFIG_SYS_FS_MPFS=n
CONFIG_SYS_FS_USE_MBR=n


Initialization looks like this:

void SYS_Initialize ( void* data )
{
SYS_CLK_Initialize( NULL );
SYS_DEVCON_Initialize(SYS_DEVCON_INDEX_0, (SYS_MODULE_INIT*)NULL);
SYS_DEVCON_PerformanceConfig(SYS_CLK_SystemFrequencyGet());
SYS_DEVCON_JTAGDisable();
SYS_PORTS_Initialize();

SYS_INT_VectorPrioritySet(DRV_SPI_INT_VECTOR_IDX0, DRV_SPI_INT_PRIORITY_IDX0);
SYS_INT_VectorSubprioritySet(DRV_SPI_INT_VECTOR_IDX0, DRV_SPI_INT_SUB_PRIORITY_IDX0);
sysObj.spiObjectIdx0 = DRV_SPI_Initialize(DRV_SPI_INDEX_0, (const SYS_MODULE_INIT * const)&drvSpi0InitData);
sysObj.drvSDCard = DRV_SDCARD_Initialize(DRV_SDCARD_INDEX_0,(SYS_MODULE_INIT *)&drvSDCardInit);
sysObj.drvTmr0 = DRV_TMR_Initialize(DRV_TMR_INDEX_0, (SYS_MODULE_INIT *)&drvTmr0InitData);

SYS_INT_VectorPrioritySet(INT_VECTOR_T5, INT_PRIORITY_LEVEL1);
SYS_INT_VectorSubprioritySet(INT_VECTOR_T5, INT_SUBPRIORITY_LEVEL0);

SYS_FS_Initialize( (const void *) sysFSInit );
SYS_INT_Initialize();

sysObj.sysTmr = SYS_TMR_Initialize(SYS_TMR_INDEX_0, (const SYS_MODULE_INIT * const)&sysTmrInitData);

SD_PIC32MX_Initialize();
}

void SD_PIC32MX_Initialize ( void )
{
sd_pic32mxData.state = SD_PIC32MX_STATE_MOUNT_DISK;
}

Processing loop looks like this:



void SYS_Tasks ( void )
{
xTaskCreate((TaskFunction_t) _SYS_Tasks,
"Sys Tasks",
1024, NULL, 1, NULL);
xTaskCreate((TaskFunction_t) _SYS_TMR_Tasks,
"SYS_TMR Tasks",
1024, NULL, 1, NULL);
xTaskCreate((TaskFunction_t) _SD_PIC32MX_Tasks,
"SD_PIC32MX Tasks",
1024, NULL, 1, NULL);
vTaskStartScheduler(); /* This function never returns. */
}

static void _SYS_Tasks ( void)
{
while(1)
{
SYS_FS_Tasks();
DRV_SDCARD_Tasks(sysObj.drvSDCard);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
static void _SD_PIC32MX_Tasks(void)
{
while(1)
{
SD_PIC32MX_Tasks();
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}

void SD_PIC32MX_Tasks ( void )
{
/* Set pins for SD card as needed ... */

/* The application task state machine */
switch(sd_pic32mxData.state)
{
case SD_PIC32MX_STATE_MOUNT_DISK:
if(SYS_FS_Mount("/dev/mmcblka1", "/mnt/myDrive", FAT, 0, NULL) != 0)
{
sd_pic32mxData.state = SD_PIC32MX_STATE_MOUNT_DISK;
}
else
{
sd_pic32mxData.state = SD_PIC32MX_STATE_UNMOUNT_DISK;
}
break;

case SD_PIC32MX_STATE_UNMOUNT_DISK:
/* etc ... */
default:
break;
}
}


When the state machine first starts in interrupt mode, The SYS_FS_Mount() call fails. But after looping for about 2 minutes and 20 seconds, it succeeds; after that, the SD card can be written. Obviously, I need to work on performance, but I consider this step a success.

Now I need to convert the project to run in polling mode, to be compatible with our system. I configured the SPI driver settings as shown below, and re-generated the code. This time, ISR_MODE=n and POLLED_MODE=y. SD and FS settings were same as for interrupt mode.

CONFIG_DRV_SPI_USE_DRIVER=y
CONFIG_DRV_SPI_DRIVER_MODE="DYNAMIC"
CONFIG_DRV_SPI_USE_ISR_MODE=n
CONFIG_DRV_SPI_USE_POLLED_MODE=y
CONFIG_DRV_SPI_USE_MASTER_MODE=y
CONFIG_DRV_SPI_USE_SLAVE_MODE=n
CONFIG_DRV_SPI_USE_STANDARD_BUFFER_MODE=n
CONFIG_DRV_SPI_USE_ENHANCED_BUFFER_MODE=y
CONFIG_DRV_SPI_USE_8BIT_MODE=y
CONFIG_DRV_SPI_USE_16BIT_MODE=n
CONFIG_DRV_SPI_USE_32BIT_MODE=n
CONFIG_DRV_SPI_USE_DMA=n
CONFIG_DRV_SPI_INSTANCES_NUMBER=1
CONFIG_DRV_SPI_CLIENT_NUMBER=1
CONFIG_DRV_SPI_NUM_ELEMENTS_PER_INSTANCE=10


Initialization did not change, but in the processing loop, the following code is added:

void SYS_Tasks ( void )
{
...
/* Add this call */
xTaskCreate((TaskFunction_t) _DRV_SPI_IDX0_Tasks,
"DRV_SPI Instance 0 Tasks",
1024, NULL, 1, NULL);
...
}
void _DRV_SPI_IDX0_Tasks(void)
{
while(1)
{
DRV_SPI_Tasks(sysObj.spiObjectIdx0);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}

Now inside SD_PIC32MX_Tasks(), the call to SYS_FS_Mount() never succeeds. I have let it run for 10 or 20 minutes, but it just loops endlessly. My understanding is that the DRV_SPI_Tasks() call is supposed to make polling work, but something is still missing here.

To debug, I have tried looking at the return value from DRV_SPI_Status(), but it is always SYS_STATUS_READY after DRV_SPI_Initialize().

Any ideas would be appreciated.
#1

6 Replies Related Threads

    gbarker
    New Member
    • Total Posts : 3
    • Reward points : 0
    • Joined: 2018/09/17 10:56:16
    • Location: 0
    • Status: offline
    Re: Harmony SD Card in Polling Mode 2018/09/18 09:05:23 (permalink)
    0
    Microchip web site mangled my formatting, so all the code looks flat.  I hope it is still readable.  Sorry, this is my first post.
    #2
    twelve12pm
    Overseer
    • Total Posts : 322
    • Reward points : 0
    • Joined: 2012/04/09 17:27:24
    • Location: 0
    • Status: offline
    Re: Harmony SD Card in Polling Mode 2018/09/18 10:01:25 (permalink)
    0
    Harmony is not "complete" in the sense that some configurations have not been implemented, are implemented incompletely, or have not been fully tested yet.
     
    Always check the release notes.
     
    There is a list of all drivers / components and whether they are Alpha, Beta, or Production.
     
    You'll find, for example, that some drivers have a different status for the Static version than for the Dynamic version. For example as of Harmony 2.06 the Non Volatile Memory (NVM) driver has Production status for the Dynamic version but only Beta status for the Static version.
     
    There may also be differences in the Polled / Interrupt versions of some drivers.
     
    The SPI Flash driver currently lacks high speed read, hold, and write protect.
     
    The SD Card driver lists the following caveat in the release notes: "The SD Card Driver has not been tested in a high frequency interrupt environment." That is Harmony 2.06, your version of Harmony may be different.
    #3
    qhb
    Superb Member
    • Total Posts : 7139
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: Harmony SD Card in Polling Mode 2018/09/19 19:35:59 (permalink)
    0
    gbarker
    Microchip web site mangled my formatting, so all the code looks flat.

    You need to put "code" tags around your code to maintain formatting.
    That means  "[  code  ]" before the block of code, and "[  /code  ]" after it, but without any spaces. I put them in so you could see the tags.
    Indenting will only work if it was done with spaces, not with tabs.
    If you don't use code tags, anything of the form "[something]" could be interpreted as a forum formatting string. This is a particular problem with "i", which triggers italic font.
     

    Worst forum problems are now fixed, but the damn firewall is still there.
    #4
    LostInSpace
    Super Member
    • Total Posts : 145
    • Reward points : 0
    • Joined: 2016/03/11 22:47:59
    • Location: 0
    • Status: offline
    Re: Harmony SD Card in Polling Mode 2018/09/24 18:46:48 (permalink)
    0
    I suggest that you start with a known working example and branch to what you need from there.
     
    The instructions here work (I have used them on several custom boards & several version of Harmony - they always get me a working SD Card setup - this proves that my hardware is correct).
    microchipdeveloper.com/harmony:audio-player-lab2
    I then glue in the "sd card fat single" code from the provided Harmony example and I always have a working SD Card setup.
     
    This audio player lab example uses a Dynamic SPI Interface and a timer. From what it sounds like you are trying this may be all the push start that you need.
     
    HTH...
     
    #5
    gbarker
    New Member
    • Total Posts : 3
    • Reward points : 0
    • Joined: 2018/09/17 10:56:16
    • Location: 0
    • Status: offline
    Re: Harmony SD Card in Polling Mode 2018/09/25 05:33:04 (permalink)
    0
    Thank you for looking into this, LostInSpace.  But unless I am missing your point, I have done what you suggest, with no success.  I created a standalone project, very similar to the audio-player-lab2 link (I actually started with sdcard_fat_single_disk example/pic32mx795_pim_e16_int_dyn_freertos example), and adapted to my hardware.  I was able to access the SD card successfully.
     
    However, all of the SD Card examples are in interrupt mode, and I need polled mode.  I have tried converting my standalone project to polled mode, but with no success (as evidenced in my long, confusing post).  
     
    If you have successful examples of SD Card access in polled mode, I would appreciate seeing them.
    #6
    LostInSpace
    Super Member
    • Total Posts : 145
    • Reward points : 0
    • Joined: 2016/03/11 22:47:59
    • Location: 0
    • Status: offline
    Re: Harmony SD Card in Polling Mode 2018/09/29 13:59:51 (permalink)
    0
    OK - I hear you. The Microchip code is rather tedious to navigate around - But it is based on FatFS, so that is useful.
     
    Here is an example that uses FatFS directly and used Register based calls to do the SPI (and no interrupts). I was able to quickly understand this implementation and rewire just a few calls to use my Static SPI implementation. If you did that you could use the Harmony SPI polling methods to keep track of the progress, etc.
     
    tutorial.cytron.io/2017/09/17/fatfs-for-pic32mxmz/
     
    This tutorial (above) does use a timer for timeouts, but it is written in such a way as to not require the timer, if you never timeout - which was a good assumption for my exact application. Your mileage may vary.
     
    HTH
    #7
    Jump to:
    © 2018 APG vNext Commercial Version 4.5