Other Parts Discussed in Thread: CC2650
Hello,
I have written a small bare-metal application for CC2650 (without RTOS) it works so far, but it has following issues:
After flashing and debugging starts the code shall be reset in another case the DMA do not starts.
If I'm trying to receive something with SPI all of the bytes are shifted ones to the right with padding "0" for first received byte. (e.g. the first value = 0xE1, SPI receives 0x70 == 1110 0001 -> 0111 0000) the bit shifted away is present in the next byte.This issue is not dependent on usage of DMA.
An example from RTOS do not have this problems...
Could someone point me on what i have forgot during initialization?
Thanks in Advance.
In following is the code for initialization of components and operation:
/*Initialisation code*/ void init_platform(uint32_t ui32SysClockSpeed) { IntMasterDisable(); SetupTrimDevice(); appDcdcOn(true); // Set Clock frequeuncy if(OSCClockSourceGet(OSC_SRC_CLK_HF) != OSC_XOSC_HF) { /* Request to switch to the crystal to enable radio operation. */ OSCClockSourceSet(OSC_SRC_CLK_LF | OSC_SRC_CLK_MF | OSC_SRC_CLK_HF, OSC_XOSC_HF); /* Switch the HF source to XTAL - Done via ROM API*/ OSCHfSourceSwitch(); } PRCMInfClockConfigureSet(PRCM_CLOCK_DIV_1, PRCM_RUN_MODE); PRCMInfClockConfigureSet(PRCM_CLOCK_DIV_8, PRCM_SLEEP_MODE); PRCMInfClockConfigureSet(PRCM_CLOCK_DIV_32, PRCM_DEEP_SLEEP_MODE); // set Power for serial CPU PRCMPowerDomainOn(PRCM_DOMAIN_CPU); // Activate CPU Domain PRCMLoadSet(); // wait on complete while(!PRCMLoadGet()); // set Power for serial SYSBUS PRCMPowerDomainOn(PRCM_DOMAIN_SYSBUS); // Activate System bus Domain PRCMLoadSet(); // wait on complete while(!PRCMLoadGet()); // set Power for serial VIMS PRCMPowerDomainOn(PRCM_DOMAIN_VIMS); // Activate VIMS Domain PRCMLoadSet(); // wait on complete while(!PRCMLoadGet()); // set Power for serial interfaces PRCMPowerDomainOn(PRCM_DOMAIN_SERIAL); // Activate perfirial Domain PRCMLoadSet(); // wait on complete while(!PRCMLoadGet()); // set Power MCU domain PRCMPowerDomainOn(PRCM_DOMAIN_MCU); // Activate perfirial Domain PRCMLoadSet(); // wait on complete while(!PRCMLoadGet()); // set Power for peripherie PRCMPowerDomainOn(PRCM_DOMAIN_PERIPH); // Activate perfirial Domain PRCMLoadSet(); // wait on complete while(!PRCMLoadGet()); // set Power for timer PRCMPeripheralRunEnable(PRCM_PERIPH_TIMER0); // enable clock and all resisters of timer 0 PRCMLoadSet(); // wait on complete while(!PRCMLoadGet()); // set Power for GPIO PRCMPeripheralRunEnable(PRCM_PERIPH_GPIO); PRCMLoadSet(); // Start Clocking while(!PRCMLoadGet()); // Check OK // set Power for DMA PRCMPeripheralRunEnable(PRCM_PERIPH_UDMA); // Enable DMA Pereferie PRCMLoadSet(); // Start Clocking while(!PRCMLoadGet()); // Check OK // set Power for UART PRCMPeripheralRunEnable(PRCM_PERIPH_UART0); // Activate UART Power domain PRCMLoadSet(); // check.. while(!PRCMLoadGet()); // wait on check completed // set Power for SPI PRCMPeripheralRunEnable(PRCM_PERIPH_SSI0); // Activate SPI/SSI Power domain PRCMLoadSet(); // check while(!PRCMLoadGet()); // wait on check completed AONBatMonEnable(); IntMasterEnable(); } void initUDMA(){ /* Disable all channels */ bspUDMAChannelDisable(0xFFFFFFFF); /* Set the base for the channel control table. */ uDMAControlBaseSet(BSP_DMA_BASE, (void *) UDMA_CONFIG_BASE); // Set the Base Address of the DMA Table /* Clear UDMA error status and all interrupts*/ /* Enable uDMA. */ uDMAEnable(BSP_DMA_BASE); } void bspUDMAConfig(uint8_t *SourceAddress, uint8_t *DistanationAdress, uint8_t NumberOfBytes){ volatile tDMAControlTable *dmaControlTableEntry; /*Setup receiver Side of the DMA controller */ dmaControlTableEntry = &dmaSpi0RxControlTableEntry; dmaControlTableEntry->ui32Control = dmaRxConfig[0]; dmaControlTableEntry->pvDstEndAddr = (void *)((uint32_t)(DistanationAdress) + NumberOfBytes - 1); dmaControlTableEntry->pvSrcEndAddr = (void *)(BSP_SPI_BASE + SSI_O_DR); dmaControlTableEntry->ui32Control |= UDMA_SET_TRANSFER_SIZE(NumberOfBytes); /*Setup transmitter Side of the DMA controller */ dmaControlTableEntry = &dmaSpi0TxControlTableEntry; dmaControlTableEntry->ui32Control = dmaTxConfig[0]; dmaControlTableEntry->pvSrcEndAddr = (void *)((uint32_t)(SourceAddress) + NumberOfBytes - 1); dmaControlTableEntry->pvDstEndAddr = (void *)(BSP_SPI_BASE + SSI_O_DR); dmaControlTableEntry->ui32Control |= UDMA_SET_TRANSFER_SIZE(NumberOfBytes); /* Enable DMA channel (quick) */ HWREG(BSP_DMA_BASE + UDMA_O_SETCHANNELEN) = ((UDMA_CHAN_SSI0_RX_MASK) | (UDMA_CHAN_SSI0_TX_MASK)); } void initSPI(uint32_t ui32SpiClockSpeed, void (*CallBack)(void)) { /* Register callback, if present */ if(CallBack) SPICallBack = CallBack; /* Set SPI mode and speed */ /* Disable SSI function before configuring module*/ SSIDisable(BSP_SPI_BASE); /* Disable SPI module interrupts */ SSIIntDisable(BSP_SPI_BASE, SSI_RXOR | SSI_RXFF | SSI_RXTO | SSI_TXFF); SSIIntClear(BSP_SPI_BASE, SSI_RXOR | SSI_RXTO); // // // Configure SSI module to Motorola/Freescale SPI mode 3: // Polarity = 1, SCK steady state is high // Phase = 1, Data changed on first and captured on second clock edge // Word size = 8 bits // SSIConfigSetExpClk(BSP_SPI_BASE, BSP_CLK_SPD_48MHZ, SSI_FRF_MOTO_MODE_3, SSI_MODE_MASTER, ui32SpiClockSpeed, 8); IOCPinTypeSsiMaster(BSP_SPI_BASE, BSP_IOID_SPI_MISO, BSP_IOID_SPI_MOSI, BSP_IOID_SPI_CS, BSP_IOID_SPI_SCK); SPIFlushFifos(); IntPendClear(INT_SSI0_COMB); IntRegister(INT_SSI0_COMB, bspSpiInterruptHandler); IntEnable(INT_SSI0_COMB); SSIEnable(BSP_SPI_BASE); } void SPI_SendOverDMA(uint8_t *SourceAddress, uint8_t *DistanationAdress, uint8_t NumberOfBytes){ SSIEnable(BSP_SPI_BASE); bspUDMAConfig(SourceAddress, DistanationAdress, NumberOfBytes); /* Start transaction due to enabling of the SPI DMA channels*/ SSIDMAEnable(BSP_SPI_BASE, SSI_DMA_TX | SSI_DMA_RX ); /* Enable the RX overrun interrupt in the SSI module */ SSIIntEnable(BSP_SPI_BASE, SSI_RXOR); //SSI_TXFF | SSI_RXFF | } /*Application */ int main() { // Power_init(); init_platform(BSP_CLK_SPD_48MHZ); initUDMA(); initSPI(12000000, 0); SPI_SendOverDMA(SendArray,ReceiveArray,20); while(1) { delay--; if(!delay) { delay = 48000000; SPI_SendOverDMA(SendArray,ReceiveArray,20); } } return 0; }