//*********************************************************************************** Variables #pragma DATA_ALIGN(uDmaControlTable, 1024) uint8_t uDmaControlTable[1024]; uint16_t SSITXbuf[SSI_TXBUF_SIZE]; uint16_t SSITXnul[SSI_TXNUL_SIZE+2]; volatile uint32_t SSITXbufInPtr = 0; volatile uint32_t SSITXbufCount = 0; volatile uint32_t ssiTxBufferOverflow = 0; volatile uint32_t TXopen = 1; uint16_t SSIRXbufA[SSI_RXBUF_SIZE]; uint16_t SSIRXbufB[SSI_RXBUF_SIZE]; #define SSIRX_FIFO_SIZE 1024 //size must be power of 2 volatile uint16_t SSIRXfifo[SSIRX_FIFO_SIZE]; volatile uint32_t SSIRXinptr = 0; volatile uint32_t SSIRXoutptr = 0; volatile uint32_t SSIRXcount = 0; volatile uint32_t ssiRxFifoOverflow = 0; //*********************************************************************************** //Initialisation //SSI0.............................................................................................................................. ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0); //fpga spi comms ROM_SSIDisable(SSI0_BASE); //disable it while we configure it ROM_GPIOPinConfigure(GPIO_PA2_SSI0CLK); ROM_GPIOPinConfigure(GPIO_PA3_SSI0FSS); ROM_GPIOPinConfigure(GPIO_PA4_SSI0RX); ROM_GPIOPinConfigure(GPIO_PA5_SSI0TX); ROM_GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 | GPIO_PIN_2); //tx, rx, fr, ck ROM_SSIClockSourceSet(SSI0_BASE, SSI_CLOCK_SYSTEM); ROM_SSIConfigSetExpClk(SSI0_BASE, ROM_SysCtlClockGet(), SSI_FRF_TI, SSI_MODE_MASTER, 5000000, 16); ROM_SSIEnable(SSI0_BASE); ROM_SSIDMAEnable(SSI0_BASE, SSI_DMA_RX | SSI_DMA_TX); // ROM_IntEnable(INT_SSI0); //enable SSI0 peripheral interrupts //note that no interrupts were enabled, but the uDMA controller will cause an interrupt on the SSI0 interrupt signal when a uDMA transfer is complete //*********************************************************************************** //Interrupt void SSI0IntHandler(void) { uint32_t ui32Status; uint32_t ui32Mode; int i; ui32Status = ROM_SSIIntStatus(SSI0_BASE, 1); ROM_SSIIntClear(SSI0_BASE, ui32Status); // Clear any pending ints - there should be none - this is triggered by uDMA //is A transfer complete? ui32Mode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_SSI0RX | UDMA_PRI_SELECT); // Check the DMA control table to see if the ping-pong "A" transfer is complete if(ui32Mode == UDMA_MODE_STOP) { // If the primary control structure indicates stop, that means the "A" receive buffer is done. The uDMA controller should still be receiving data into the "B" buffer ROM_uDMAChannelTransferSet(UDMA_CHANNEL_SSI0RX | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void *)(SSI0_BASE + SSI_O_DR), SSIRXbufA, SSI_RXBUF_SIZE); // Set up the next transfer for the "A" buffer for(i=0;i SSIRX_FIFO_SIZE) { ssiRxFifoOverflow = 1; //fifo overflow break; } } } } //is B transfer complete? ui32Mode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_SSI0RX | UDMA_ALT_SELECT); // Check the DMA control table to see if the ping-pong "B" transfer is complete if(ui32Mode == UDMA_MODE_STOP) { // If the alternate control structure indicates stop, that means the "B" ROM_uDMAChannelTransferSet(UDMA_CHANNEL_SSI0RX | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)(SSI0_BASE + SSI_O_DR), SSIRXbufB, SSI_RXBUF_SIZE); // Set up the next transfer for the "B" buffer for(i=0;i SSIRX_FIFO_SIZE) { ssiRxFifoOverflow = 1; //fifo overflow break; } } } } //is TX done? if(!ROM_uDMAChannelIsEnabled(UDMA_CHANNEL_SSI0TX)) { // If the SSI0 DMA TX channel is disabled, that means the TX DMA transfer is done if((SSITXbufCount != 0) && (TXopen != 0)) { //if nothing to send do a null packet ROM_uDMAChannelTransferSet(UDMA_CHANNEL_SSI0TX | UDMA_PRI_SELECT, UDMA_MODE_BASIC, SSITXbuf, (void *)(SSI0_BASE + SSI_O_DR), SSITXbufCount); // Start another DMA transfer to SSI0 TX. SSITXbufCount = 0; SSITXbufInPtr = 0; } else { ROM_uDMAChannelTransferSet(UDMA_CHANNEL_SSI0TX | UDMA_PRI_SELECT, UDMA_MODE_BASIC, SSITXnul, (void *)(SSI0_BASE + SSI_O_DR), SSI_TXNUL_SIZE); // Start another DMA transfer to SSI0 TX. } ROM_uDMAChannelEnable(UDMA_CHANNEL_SSI0TX); // The uDMA TX channel must be re-enabled. } } //*********************************************************************************** //Code //--------------------------------------------------------------------------- void sendFPGApair(uint16_t addr, uint16_t data) { if((SSITXbufCount + 2) > SSI_TXBUF_SIZE) { ssiTxBufferOverflow = 1; //no room, set overflow flag, exit return; } TXopen = 0; //add pair to the SSI TX FIFO SSITXbuf[SSITXbufInPtr++] = addr; SSITXbuf[SSITXbufInPtr++] = data; SSITXbufCount += 2; TXopen = 1; }