Other Parts Discussed in Thread: HALCOGEN
Hello everyone,
I’m working on transmitting and receiving data by SPI with DMA. After trying to send a message once, clock will be constantly active but MOSI and MISO remain completely disabled.
Can you please check my config, maybe I’m doing something wrong?
P.S. I'm wondering that there are some code examples for MIBSPI working with DMA, but literally nothing similar for the SPI, although they have some difference in their base registers.
Thanks in advance!
Here is my config:
/* Include Files */ #include "HL_sys_common.h" #include "HL_sys_dma.h" #include "HL_spi.h" #include "main.h" #include "spi.h" #include "dma.h" /* Defines */ #define D_SIZE 8 #define SPI_REGISTER spiREG3 #define BIT_SHIFTING_24 24 #define BIT_SHIFTING_16 16 #define HEX_ONE 0x1 #define HEX_ZERO 0x0 #define DMA_REQ_LINE_SPI3_TX 15 #define DMA_REQ_LINE_SPI3_RX 14 /* Variables */ uint16_t TXDATA[D_SIZE] = {0x03, 0x88, 0xFF, 0xFF, 0x00, 0xFF, 0x88, 0xF0}; /* transmit buffer */ uint16_t RXDATA[D_SIZE] = {0}; /* receive buffer */ g_dmaCTRL g_dmaCTRLPKT_TX, g_dmaCTRLPKT_RX; /* dma control packet configuration stack */ /* Function declarations */ void spi_test(void); /* Function definitions */ int main(void) { spi_test(); return 0; } void spi_test(void) { /* Initialize SPI interface */ spiInit(); // assigning dma request: channel - 0 with request line - 15 (SPI3 Transmit DMA Request) (TRM p710) dmaReqAssign((uint32_t)DMA_CH0, DMA_REQ_LINE_SPI3_TX); // assigning dma request: channel - 1 with request line - 14 (SPI3 Receive DMA Request) dmaReqAssign((uint32_t)DMA_CH1, DMA_REQ_LINE_SPI3_RX); // Enable Interrupt after reception of data // Group A - Interrupts (FTC, LFS, HBC, and BTC) are routed to the ARM CPU // User software should configure only Group A interrupts dmaEnableInterrupt((uint32_t)DMA_CH0, (dmaInterrupt_t)BTC, DMA_INTA); dmaEnableInterrupt((uint32_t)DMA_CH1, (dmaInterrupt_t)BTC, DMA_INTA); /* - configuring dma control packets */ g_dmaCTRLPKT_TX.SADD = (uint32_t)TXDATA; /* source address */ g_dmaCTRLPKT_TX.DADD = (uint32_t)(&SPI_REGISTER->DAT1) + 3U; /* destination address */ g_dmaCTRLPKT_TX.CHCTRL = 0; /* channel control */ g_dmaCTRLPKT_TX.FRCNT = 1U; /* frame count */ g_dmaCTRLPKT_TX.ELCNT = D_SIZE; /* element count */ g_dmaCTRLPKT_TX.ELDOFFSET = 0U;/*D_SIZE;*/ /* element destination offset */ g_dmaCTRLPKT_TX.ELSOFFSET = 0U; /* element destination offset */ g_dmaCTRLPKT_TX.FRDOFFSET = 0U; /* frame destination offset */ g_dmaCTRLPKT_TX.FRSOFFSET = 0U; /* frame destination offset */ g_dmaCTRLPKT_TX.PORTASGN = PORTA_READ_PORTB_WRITE; /* port assignment */ g_dmaCTRLPKT_TX.RDSIZE = ACCESS_8_BIT; /* read size */ g_dmaCTRLPKT_TX.WRSIZE = ACCESS_8_BIT; /* write size */ g_dmaCTRLPKT_TX.TTYPE = FRAME_TRANSFER;/*BLOCK_TRANSFER;*/ /* transfer type */ g_dmaCTRLPKT_TX.ADDMODERD = ADDR_INC1; /* address mode read */ g_dmaCTRLPKT_TX.ADDMODEWR = ADDR_FIXED; /* address mode write */ g_dmaCTRLPKT_TX.AUTOINIT = AUTOINIT_ON; /* autoinit */ g_dmaCTRLPKT_RX.SADD = (uint32_t)(&SPI_REGISTER->BUF); /* source address */ g_dmaCTRLPKT_RX.DADD = (uint32_t)RXDATA; /* destination address */ g_dmaCTRLPKT_RX.CHCTRL = 0U; /* channel control */ g_dmaCTRLPKT_RX.FRCNT = 1U; /* frame count */ g_dmaCTRLPKT_RX.ELCNT = D_SIZE; /* element count */ g_dmaCTRLPKT_RX.ELDOFFSET = 0U; /* element destination offset */ g_dmaCTRLPKT_RX.ELSOFFSET = 0;/*D_SIZE;*/ /* element destination offset */ g_dmaCTRLPKT_RX.FRDOFFSET = 0U; /* frame destination offset */ g_dmaCTRLPKT_RX.FRSOFFSET = 0U; /* frame destination offset */ g_dmaCTRLPKT_RX.PORTASGN = PORTB_READ_PORTA_WRITE; /* port assignment */ g_dmaCTRLPKT_RX.RDSIZE = ACCESS_8_BIT; /* read size */ g_dmaCTRLPKT_RX.WRSIZE = ACCESS_8_BIT; /* write size */ g_dmaCTRLPKT_RX.TTYPE = FRAME_TRANSFER;/*BLOCK_TRANSFER;*/ /* transfer type */ g_dmaCTRLPKT_RX.ADDMODERD = ADDR_FIXED; /* address mode read */ g_dmaCTRLPKT_RX.ADDMODEWR = ADDR_INC1; /* address mode write */ g_dmaCTRLPKT_RX.AUTOINIT = AUTOINIT_ON; /* autoinit */ /* - setting dma control packets */ dmaSetCtrlPacket((uint32_t)DMA_CH0, g_dmaCTRLPKT_TX); // channel - 0 for transmit dmaSetCtrlPacket((uint32_t)DMA_CH1, g_dmaCTRLPKT_RX); // channel - 1 for receive /* - setting the dma channels 0 and 1 to trigger on h/w request */ dmaSetChEnable((uint32_t)DMA_CH0, (uint32_t)DMA_HW); dmaSetChEnable((uint32_t)DMA_CH1, (uint32_t)DMA_HW); // enabling dma module : this brings DMA out of reset dmaEnable(); /* spi port config */ spiDAT1_t dataconfig1_t; dataconfig1_t.CS_HOLD = TRUE; // The chip select signal is activated dataconfig1_t.WDEL = TRUE; // No delay will be inserted dataconfig1_t.DFSEL = SPI_FMT_0; // Data word format select dataconfig1_t.CSNR = 0xFE; // Chip select (CS) number; 0x01h for CS[0] /* Check whether SPIEN bit = 1 */ if ((SPI_REGISTER->GCR1>>BIT_SHIFTING_24)&(HEX_ONE) == HEX_ONE) { /* DMA_REQ_Enable */ SPI_REGISTER->INT0^=(-HEX_ONE^SPI_REGISTER->INT0)&(HEX_ONE<<BIT_SHIFTING_16); } else { /* Set SPIEN bit = 1 */ SPI_REGISTER->GCR1^=(-HEX_ONE^SPI_REGISTER->GCR1)&(HEX_ONE<<BIT_SHIFTING_24); /* DMA_REQ_Enable */ SPI_REGISTER->INT0^=(-HEX_ONE^SPI_REGISTER->INT0)&(HEX_ONE<<BIT_SHIFTING_16); } /* SPI transmit and receive */ // Function spiSendAndGetData sets bits 8 & 9 in INT0 to 1. // Bit 8 -> RXINTENA causes an interrupt to be generated when the RXINTFLAG bit // (SPI Flag Register (SPIFLG)[8]) is set by hardware. // Bit 9 -> TXINTENA causes an interrupt to be generated every time data is written // to the shift register, so that the next word can be written to TXBUF. Setting this // bit will generate an interrupt if the TXINTFLG bit (SPI Flag Register (SPIFLG)[9]) // is set to 1. /* Transmit and Receive Data using Interrupt mode */ spiSendAndGetData(SPI_REGISTER, &dataconfig1_t, D_SIZE, TXDATA, RXDATA); /* Transmit and Receive Data using Polling method */ // spiTransmitAndReceiveData(SPI_REGISTER, &dataconfig1_t, D_SIZE, TXDATA, RXDATA); int64_t count = 0; while(dmaREG->BTCFLAG != 0x00000003) { // Wait for Block Transfer Complete count++; } dmaREG->BTCFLAG = 0x00000003; // Clear BTC Flag // Because Channel 0 and 1 are configured with AutoInit // DMA is ready to transmit / receive the next Block count = 0; }