Other Parts Discussed in Thread: TM4C123GH6PM, , EK-TM4C1294XL, SYSCONFIG, TM4C1294NCPDT
Tool/software:
In an existing mature code base that runs on TM4C123GH6PM and TM4C123GHPGE, all 4 SSI are used.
We are adding support for TM4C1290NCPDT. UART0, I2C0 are working but SSI0 which is used for microSD card / FatFS is not.
Looking at the Tiva Migration doc: https://www.ti.com/lit/an/spma065/spma065.pdf, nothing stands out with respect to SSI0 other than PA4/PA5 TX/RX roles are swapped between 123g and 1290N.
Single stepping the call stack:
- fresult = f_opendir(&g_sDirObject, g_cCwdBuf); calls disk_initialize (SPI) (in microsd.c)
- res = find_volume(&fs, &path, 0); ultimately returns FR_NOT_READY. find_volume calls disk_initialize
- stat = disk_initialize(fs->drv); /* Initialize the physical drive */ disk_initialize calls power_on which sets up the SSI. See below.
Legacy SPI mapping:
123G MISO=RX=PA4=SSI0_MISO MOSI=TX=PA5=SSI0_MOSI CLK=PA2=SSI0_CLK CS=PA3
1290: MISO=RX=PA5=SSI0_DAT1 MOSI=TX=PA4=SSI0_DAT0 CLK=PA2=SSI0_CLK CS=PA3
I'd like to know if I'm missing something with respect to SSI0 migrating code from TM4c123g to TM4c1290n?
Thanks
In diskio.c, the platform bindings and SSI setup:
#ifdef PART_TM4C1290NCPDT/* Peripheral definitions for TM4c1290N base serlog_msc3 board */// SSI port#define SDC_SSI_BASE SSI0_BASE#define SDC_SSI_SYSCTL_PERIPH SYSCTL_PERIPH_SSI0
// GPIO for SSI pins#define SDC_GPIO_PORT_BASE GPIO_PORTA_BASE#define SDC_GPIO_SYSCTL_PERIPH SYSCTL_PERIPH_GPIOA#define SDC_SSI_CLK GPIO_PIN_2#define SDC_SSI_TX GPIO_PIN_4 //NOTE: RX/TX swapped vs TM4c123g per www.ti.com/.../spma065.pdf#define SDC_SSI_RX GPIO_PIN_5#define SDC_SSI_FSS GPIO_PIN_3#define SDC_SSI_PINS (SDC_SSI_TX | SDC_SSI_RX | SDC_SSI_CLK | SDC_SSI_FSS)
#else/* Peripheral definitions for TM4C123G board */// SSI port#define SDC_SSI_BASE SSI0_BASE#define SDC_SSI_SYSCTL_PERIPH SYSCTL_PERIPH_SSI0
// GPIO for SSI pins#define SDC_GPIO_PORT_BASE GPIO_PORTA_BASE#define SDC_GPIO_SYSCTL_PERIPH SYSCTL_PERIPH_GPIOA#define SDC_SSI_CLK GPIO_PIN_2#define SDC_SSI_TX GPIO_PIN_5#define SDC_SSI_RX GPIO_PIN_4#define SDC_SSI_FSS GPIO_PIN_3#define SDC_SSI_PINS (SDC_SSI_TX | SDC_SSI_RX | SDC_SSI_CLK | SDC_SSI_FSS)
#endif
staticvoid power_on (void){ /* * This doesn't really turn the power on unless the hardware supports it, but initializes the * SSI port and pins needed to talk to the card. */
/* Enable the peripherals used to drive the SDC on SSI */ ROM_SysCtlPeripheralEnable(SDC_SSI_SYSCTL_PERIPH); ROM_SysCtlPeripheralEnable(SDC_GPIO_SYSCTL_PERIPH);
/* * Configure the appropriate pins to be SSI instead of GPIO. The FSS (CS) * signal is directly driven to ensure that we can hold it low through a * complete transaction with the SD card. */ ROM_GPIOPinTypeSSI(SDC_GPIO_PORT_BASE, SDC_SSI_TX | SDC_SSI_RX | SDC_SSI_CLK); ROM_GPIOPinTypeGPIOOutput(SDC_GPIO_PORT_BASE, SDC_SSI_FSS);
/* * Set the SSI output pins to 4MA drive strength and engage the * pull-up on the receive line. */ ROM_GPIOPadConfigSet(SDC_GPIO_PORT_BASE, SDC_SSI_RX, GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD_WPU); ROM_GPIOPadConfigSet(SDC_GPIO_PORT_BASE, SDC_SSI_CLK | SDC_SSI_TX | SDC_SSI_FSS, GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD);
/* Configure the SSI0 port */// ROM_SSIConfigSetExpClk(SDC_SSI_BASE, ROM_SysCtlClockGet(),// SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 400000, 8); ROM_SSIConfigSetExpClk(SDC_SSI_BASE, g_ui32SysClock, //ROM_SysCtlClockGet() is not available on TM4C1290 SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 400000, 8); ROM_SSIEnable(SDC_SSI_BASE);
/* Set DI and CS high and apply more than 74 pulses to SCLK for the card */ /* to be able to accept a native command. */ send_initial_clock_train();
/*-----------------------------------------------------------------------*//* Send 80 or so clock transitions with CS and DI held high. This is *//* required after card power up to get it into SPI mode *//*-----------------------------------------------------------------------*/staticvoid send_initial_clock_train(void){ unsigned int i; uint32_t ui32Dat;
/* Ensure CS is held high. */ DESELECT();
/* Switch the SSI TX line to a GPIO and drive it high too. */ ROM_GPIOPinTypeGPIOOutput(SDC_GPIO_PORT_BASE, SDC_SSI_TX); ROM_GPIOPinWrite(SDC_GPIO_PORT_BASE, SDC_SSI_TX, SDC_SSI_TX);
/* Send 10 bytes over the SSI. This causes the clock to wiggle the */ /* required number of times. */ for(i = 0 ; i < 10 ; i++) { /* Write DUMMY data. SSIDataPut() waits until there is room in the */ /* FIFO. */ ROM_SSIDataPut(SDC_SSI_BASE, 0xFF);
/* Flush data read during data write. */ ROM_SSIDataGet(SDC_SSI_BASE, &ui32Dat); }
/* Revert to hardware control of the SSI TX line. */ ROM_GPIOPinTypeSSI(SDC_GPIO_PORT_BASE, SDC_SSI_TX);}