Tool/software: Code Composer Studio
HI,
I have two boards, one is custom design with TM4CENCZAD, the second is the TI TM4C129EXL dev board. These two boards are connected via QSSI, port 1 on the custom board, port 3 on the TI dev board. I have been testing QSSI with a few modes of operation:
1.custom set as master QSSI, writing 8 bit frames to header connector (probing connector with DSO) - CSS, CLK, and 4data lines work as expected. NOTE: Custom board does not have an external cyrstal; clock is via on-chip clock source.
2.TI board set as master QSSI, writing 8 bit frames to BoosterPack hdr pins corresponding to port3. Again, probing connector pins with DSO, works as expected.
3. custom board set as master QSSI, TI dev set as slave QSSI, with master sending one 8 bit sequence to slave (custom bd to TI dev bd), slave receives the data, both board's switch modes so that master switches from write to read, and TI dev bd switches from read to write, then slave board sends data back to master (or master reads data from slave - This is part of my confusion, how is this part of the transaction initiated, the slave sending data back to master?)
At this point, case #3 fails when master has issued SSIDataGet, and slave has reached the call to SSIDataPut. No data gets sent (watching on the scope) after the initial write from master to slave, and the two debugger sessions (one connected to master, second connected to slave) are stuck at these two SSIDataXXX calls.
I've been studying the following previous forums;
https://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/p/341195/1202177#1202177
I believe have applied all the suggestions that were provided. I think I'm doing something fundamentally wrong here but can't seem to get my head around it. Hoping someone here can get me on-track.
The master code segment from main:
InitGPIO();
SysCtlClockFreqSet(SYSCTL_OSC_INT, SYSCTL_SYSDIV_1 | SYSCTL_USE_PLL );
clock = SysCtlClockGet();
Board_initQSSI(clock, baud_rate, 0);
SSIDataPut (SSI1_BASE, 0xA5);
SSIAdvModeSet(SSI1_BASE, SSI_ADV_MODE_QUAD_READ);
//SSIDataPutNonBlocking(SSI1_BASE, 0x4000); //dummy write to get clock running to config slave, 0x20=QuadMode ---> This didn't make any difference
while(1)
{
SSIDataGet(SSI1_BASE, rcv_data); ---------------> hangs here
System_printf("receved: %d\n", rcv_data[0]);
//SysCtlDelay(1000);
}
Code segment from slave's main
Board_initGeneral();
Board_initGPIO();
Board_initEMAC();
Board_initUART();
//Board_initSPI();
clock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |
SYSCTL_CFG_VCO_480), 120000000);
Board_initQSSI(clock, baud_rate, 1);
while( go == 0 )
{
SSIDataGet(SSI3_BASE, dataBuffer);
if( dataBuffer[0]==165 )
go = 1;
}
SSIAdvModeSet(SSI3_BASE, SSI_ADV_MODE_QUAD_WRITE);
SSIDataPutNonBlocking(SSI3_BASE, 0x4000); //dummy write to get clock running to config slave
System_printf("Switched to transmit mode\n");
while(1) {
SSIDataPut (SSI3_BASE, 0x53); ---------------> hangs here
System_printf("Sent %x\n", 0x53);
//SysCtlDelay(1000);
}
Finally, the call to Board_initQSSI in each of the above, where the last input arg is 0 corresponding to master, and 1, corrsp to slave:
void Board_initQSSI(uint32_t SysClk_Freq, uint32_t baud_rate, bool slave)
{
// Enable QSSI Peripherals
if(slave==0) { //using ports B, D, E on QSSI1 - RevX master
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI1);
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
}
else { //using ports P, Q on QSSI3 - TI dev bd slave
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI3);
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOP);
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOQ);
}
// Pin function via mux setting. This macro is mapped to GPIOPinConfigure in rom_map.h.
// GPIOPinConfigure is def in gpio.c
if(slave==0) { //using ports B, D, E on QSSI1
MAP_GPIOPinConfigure(GPIO_PB5_SSI1CLK);
MAP_GPIOPinConfigure(GPIO_PB4_SSI1FSS);
MAP_GPIOPinConfigure(GPIO_PE4_SSI1XDAT0);
MAP_GPIOPinConfigure(GPIO_PE5_SSI1XDAT1);
MAP_GPIOPinConfigure(GPIO_PD4_SSI1XDAT2);
MAP_GPIOPinConfigure(GPIO_PD5_SSI1XDAT3);
}
else { //using ports P, Q on QSSI3
MAP_GPIOPinConfigure(GPIO_PQ0_SSI3CLK);
MAP_GPIOPinConfigure(GPIO_PQ1_SSI3FSS);
MAP_GPIOPinConfigure(GPIO_PQ2_SSI3XDAT0);
MAP_GPIOPinConfigure(GPIO_PQ3_SSI3XDAT1);
MAP_GPIOPinConfigure(GPIO_PP0_SSI3XDAT2);
MAP_GPIOPinConfigure(GPIO_PP1_SSI3XDAT3);
}
// Pin operation settings. This macro is mapped to GPIOPinTypeSSI in rom_map.h.
// GPIOPinTypeSSI is def in gpio.c
if(slave==0) { //using ports B, D, E on QSSI1
MAP_GPIOPinTypeSSI(GPIO_PORTB_AHB_BASE, GPIO_PIN_5 | GPIO_PIN_4);
MAP_GPIOPinTypeSSI(GPIO_PORTD_AHB_BASE, GPIO_PIN_4 | GPIO_PIN_5);
MAP_GPIOPinTypeSSI(GPIO_PORTE_AHB_BASE, GPIO_PIN_4 | GPIO_PIN_5);
}
else { //using ports P, Q on QSSI3
MAP_GPIOPinTypeSSI(GPIO_PORTP_BASE, GPIO_PIN_0 | GPIO_PIN_1);
MAP_GPIOPinTypeSSI(GPIO_PORTQ_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
}
// Set to SPI Mode0 for QSSI (Advanced) mode; set master mode
if(slave==0) {
MAP_SSIConfigSetExpClk(SSI1_BASE, SysClk_Freq, SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, baud_rate, 8);
SSIAdvModeSet(SSI1_BASE, SSI_ADV_MODE_QUAD_WRITE);
}
else {
SSIConfigSetExpClk(SSI3_BASE, SysClk_Freq, SSI_FRF_MOTO_MODE_0, SSI_MODE_SLAVE, baud_rate, 8);
SSIAdvModeSet(SSI3_BASE, SSI_ADV_MODE_QUAD_READ);
SSIDataPut(SSI3_BASE, 0x4000); //dummy write to get clock running to config slave
}
// Enable QSSI
if(slave==0) {
MAP_SSIEnable(SSI1_BASE);
}
else {
MAP_SSIEnable(SSI3_BASE);
}
The calls to SSIDataPut were added based on guidance from the above referenced forums.
In summary, initially, master sends a frame to slave, slave receives that frame, then proceeds to switch mode from read to write. Meanwhile, master switches from write to read.
I am running this so that slave is ready to go, waiting at the first (and only) SSIDataGet. Stepping thru with debugger on both boards, the action stops after completing the calls to switch mode, on both boards.
I could use some help getting this straightened out - any suggestions appreciated.
Thank you.