Hi,
I have written a polling version of SSI that uses the below function to transfer bytes between the MCU and a Winbond flash memory. Everything works fine and I was able to interact with the flash normally.
uint8_t byte_transfer(uint8_t data) {
SSIDataPut(SSI0_BASE, data);
while(SSIBusy(SSI0_BASE));
uint32_t rx_buf;
SSIDataGet(SSI0_BASE, &rx_buf);
while(SSIBusy(SSI0_BASE));
return (uint8_t)rx_buf;
}
Recently I decided to make this polling version of SSI into an interrupt driven one however I am having trouble doing so. This is what I have so far.
// SSI Initialization
void init_spi(void) {
SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
GPIOPinConfigure(GPIO_PA2_SSI0CLK);
GPIOPinConfigure(GPIO_PA4_SSI0RX);
GPIOPinConfigure(GPIO_PA5_SSI0TX);
GPIOPinTypeSSI(GPIO_PORTA_BASE,
GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_2);
SSIConfigSetExpClk(SSI0_BASE,
SysCtlClockGet(),
SSI_FRF_MOTO_MODE_0,
SSI_MODE_MASTER,
1000000,
8);
GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_3);
GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_PIN_3);
SSIEnable(SSI0_BASE);
// Read any residual data from the SSI port.
while(SSIDataGetNonBlocking(SSI0_BASE, &g_rx_buf));
SSIIntDisable(SSI0_BASE, SSI_TXFF | SSI_RXFF | SSI_RXTO | SSI_RXOR);
SSIIntClear(SSI0_BASE, SSI_TXFF | SSI_RXFF | SSI_RXTO | SSI_RXOR);
// Enable the SSI interrupt.
IntEnable(INT_SSI0);
// Enable processor interrupts.
IntMasterEnable();
}
// Global Vars
uint32_t g_rx_buf = 0; // global rx buffer uint32_t g_tx_buf = 0; // global tx buffer volatile uint32_t g_wait_for_int = 0; // flag to wait for interrupt to happen
// SSI Data Byte Transfer
uint8_t byte_transfer(uint8_t data) {
g_wait_for_int = 1;
g_tx_buf = (uint32_t)data;
// Enable the transmit and receive interrupts. This will start the actual
// transfer.
SSIIntEnable(SSI0_BASE, SSI_TXFF | SSI_RXFF | SSI_RXTO);
while (g_wait_for_int); // wait for ISR to trigger
// IntTrigger(INT_SSI0);
return (uint8_t)g_rx_buf;
}
// SSI ISR
void SSI0IntHandler(void) {
uint32_t status = SSIIntStatus(SSI0_BASE, true);
g_wait_for_int = 0;
SSIIntClear(SSI0_BASE, SSI_TXFF | SSI_RXFF | SSI_RXTO);
SSIDataPutNonBlocking(SSI0_BASE, g_tx_buf);
SSIDataGetNonBlocking(SSI0_BASE, &g_rx_buf);
SSIIntDisable(SSI0_BASE, SSI_TXFF | SSI_RXFF | SSI_RXTO);
}
// Uses the transfer function to read flash IDs
void read_id(void) {
uint8_t man_id, dev_id;
UARTprintf("Acquiring Flash Info...\n");
chip_select(~GPIO_PIN_3); // /Chip select low
byte_transfer(WB_READ_ID);
byte_transfer(0x00);
byte_transfer(0x00);
byte_transfer(0x00);
man_id = byte_transfer(0x00);
dev_id = byte_transfer(0x00);
chip_select(GPIO_PIN_3); // /Chip select high
UARTprintf("Manufacturing ID: \%2x\n", man_id);
UARTprintf("Device ID: \%2x\n", dev_id);
}
So I used the debugger and set a break point at the ISR, and I step through till the end of the program, I get 0xFF for Manufacturing ID (which is the wrong value, it should be 0x17) and 0xEF for Device ID (which is correct).
If I just run the program without setting any breakpoints, I will get 0xFF for both IDs.
I am kind of stuck and I hope someone can provide some guidance. Thanks in advance!
Regards,
Jacky