saiberion wrote on Monday, April 23, 2007:
Hi,
I have a problem with the AT91SAM7S Controller using the SPI over DMA.
I already had the application working (no interrupts, no dma) and now I’d like to use the DMA for better performance.
DMA transfer for itself works but after the transfer and it’s output to my serial debug port FreeRTOS starts again from the beginning in main().
Here some code snippets:
command for initiating a DMA transfer:
void spiDMA_sendandreceive(portCHAR cs, portCHAR *datatosend, portCHAR sizeofsend, portCHAR* datatoreceive, portCHAR sizeofreceive)
{
___portCHAR rectmp;
___// Use given Chipselect for transfer
___spi_select_cs(cs);
___// Initialize the Transmit and Receive Pointer
___AT91C_BASE_SPI->SPI_RPR = (unsigned int)datatoreceive;
___AT91C_BASE_SPI->SPI_TPR = (unsigned int)datatosend;
___// Intialize the Transmit and Receive Counters
___AT91C_BASE_SPI->SPI_RCR = sizeofreceive;
___AT91C_BASE_SPI->SPI_TCR = sizeofsend;
___// Enable Interrupts just for DMA transfer; The most of the application still uses the existing SPI commands
___AT91F_SPI_EnableIt(AT91C_BASE_SPI, AT91C_SPI_ENDRX);
___AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTEN + AT91C_PDC_RXTEN;
___// Wait for receive to be finished
___xQueueReceive(xQueueSPIRec,&rectmp,portMAX_DELAY);
___AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS;
___AT91F_SPI_DisableIt(AT91C_BASE_SPI, AT91C_SPI_ENDRX);
}
The ISR: (xQueueSPIRec from above and xSPIRecQueue from below are identical; queue passing as in EMAC example in uIP demo)
void SPIISR(void)
{
___portENTER_SWITCHING_ISR();
___portBASE_TYPE xTaskPreviouslyWoken;
___portCHAR cRec;
___cRec = 0xb5;
___xTaskPreviouslyWoken = pdFALSE;
___xTaskPreviouslyWoken = xQueueSendFromISR(xSPIRecQueue,&cRec,xTaskPreviouslyWoken );
___AT91C_BASE_AIC->AIC_EOICR = 0;
___portEXIT_SWITCHING_ISR(pdFALSE);
}
call of DMA:
[…]
portSHORT sRec;
spiDMA_sendandreceive(7,0,8,(portCHAR*)&sRec,8);
[…]
The SPI has following configuration:
Master Mode, Fixed Peripheral, chip select generation with decoder;
(each chip select register) CPOL = 0, NCPHA = 1, CSAAT = 0, 8-Bit transfers, SCK ~ 2MHz