Other Parts Discussed in Thread: SYSCONFIG, C2000WARE
Hello,
I'm coming to you because I've had a problem for a while that I can't seem to solve.
I have two microcontrollers that communicate with each other via SPI. My SPI works in full duplex, my slave receives information from the master correctly and sends data back at the same time. The signal is clean on the oscilloscope.
My problem is with reception on the TMS320F28388D configured as Master with SPI + DMA.
When I start a transmit/receive, the start of my received frame starts at the 4th byte of my receive buffer.
Here my DMA settings :
/*********************************/ /* DMA Channel 1, SPI-A transmit */ /*********************************/ GV_sDmaRegs.CH1.MODE.bit.CHINTE = 0; /* 0: Interrupt disabled */ GV_sDmaRegs.CH1.MODE.bit.DATASIZE = 0; /* 0: 16-bit data transfer size */ GV_sDmaRegs.CH1.MODE.bit.ONESHOT = 0; GV_sDmaRegs.CH1.BURST_SIZE.all = 0; /* 1 word/burst */ GV_sDmaRegs.CH1.SRC_BURST_STEP = 1; /* Move to next word in buffer */ GV_sDmaRegs.CH1.DST_BURST_STEP = 0; /* Don't move destination address */ GV_sDmaRegs.CH1.TRANSFER_SIZE = C_DRVDMA_SIZE - 1U; /* C_DRVDMA_SIZE transfer size in bursts */ GV_sDmaRegs.CH1.SRC_TRANSFER_STEP = 1; /* Move to next word in buffer after each word in a burst */ GV_sDmaRegs.CH1.DST_TRANSFER_STEP = 0; /* Don't move destination address */ GV_sDmaRegs.CH1.SRC_WRAP_SIZE = 0xFFFE; /* Put to maximum - don't want source wrap. */ GV_sDmaRegs.CH1.DST_WRAP_SIZE = 0xFFFE; /* Put to maximum - don't want destination wrap. */ GV_sDmaRegs.CH1.SRC_BEG_ADDR_SHADOW = (Uint32) GV_DRVDMA_transferTxDataCh1; /* Start address = DMA buffer */ GV_sDmaRegs.CH1.SRC_ADDR_SHADOW = (Uint32) GV_DRVDMA_transferTxDataCh1; /* Start address = DMA buffer */ GV_sDmaRegs.CH1.DST_BEG_ADDR_SHADOW = C_DRVSPI_SPIA_ADDR + C_DRVSPI_SPITXBUF_OFFSET; /* Start address */ GV_sDmaRegs.CH1.DST_ADDR_SHADOW = C_DRVSPI_SPIA_ADDR + C_DRVSPI_SPITXBUF_OFFSET; /* Start address */ GV_sDmaClaSrcSelRegs.DMACHSRCSEL1.bit.CH1 = 109; /* 109: SPIA_TXDMA as DMA channel 1 Trigger source */ GV_sDmaRegs.CH1.MODE.bit.PERINTSEL = 1; /* Peripheral interrupt select */ GV_sDmaRegs.CH1.MODE.bit.PERINTE = 1; /* Enable peripheral interrupt event */ GV_sDmaRegs.CH1.CONTROL.bit.PERINTCLR = 1; /* Clear peripheral interrupt event flag. */ /********************************/ /* DMA Channel 2, SPI-A receive */ /********************************/ GV_sDmaRegs.CH2.MODE.bit.CHINTE = 0; /* 0: Interrupt disabled */ GV_sDmaRegs.CH2.MODE.bit.DATASIZE = 0; /* 0: 16-bit data transfer size */ GV_sDmaRegs.CH2.MODE.bit.ONESHOT = 0; GV_sDmaRegs.CH2.MODE.bit.CONTINUOUS = 0; GV_sDmaRegs.CH2.BURST_SIZE.all = 0; /* 1 word/burst */ GV_sDmaRegs.CH2.SRC_BURST_STEP = 0; /* Don't move in FIFO */ GV_sDmaRegs.CH2.DST_BURST_STEP = 1; /* Move to next word in destination address */ GV_sDmaRegs.CH2.TRANSFER_SIZE = C_DRVDMA_SIZE - 1U; /* C_DRVDMA_SIZE transfer size in bursts */ GV_sDmaRegs.CH2.SRC_TRANSFER_STEP = 0; /* Don't move source address */ GV_sDmaRegs.CH2.DST_TRANSFER_STEP = 1; /* Move to next word in buffer after each word in a burst */ GV_sDmaRegs.CH2.SRC_WRAP_SIZE = 0xFFFE; /* Put to maximum - don't want source wrap. */ GV_sDmaRegs.CH2.DST_WRAP_SIZE = 0xFFFE; /* Put to maximum - don't want destination wrap. */ GV_sDmaRegs.CH2.SRC_BEG_ADDR_SHADOW = C_DRVSPI_SPIA_ADDR + C_DRVSPI_SPIRXBUF_OFFSET; /* Start address */ GV_sDmaRegs.CH2.SRC_ADDR_SHADOW = C_DRVSPI_SPIA_ADDR + C_DRVSPI_SPIRXBUF_OFFSET; /* Start address */ GV_sDmaRegs.CH2.DST_BEG_ADDR_SHADOW = (Uint32) GV_DRVDMA_transferRxDataCh2; /* Start address = DMA buffer */ GV_sDmaRegs.CH2.DST_ADDR_SHADOW = (Uint32) GV_DRVDMA_transferRxDataCh2; /* Start address = DMA buffer */ GV_sDmaClaSrcSelRegs.DMACHSRCSEL1.bit.CH2 = 110; /* 109: SPIA_RXDMA as DMA channel 1 Trigger source */ GV_sDmaRegs.CH2.MODE.bit.PERINTSEL = 1; /* Peripheral interrupt select */ GV_sDmaRegs.CH2.MODE.bit.PERINTE = 1; /* Enable peripheral interrupt event */ GV_sDmaRegs.CH2.CONTROL.bit.PERINTCLR = 1; /* Clear peripheral interrupt event flag. */
With :
C_DRVSPI_SPIA_ADDR = 0x006100U
C_DRVSPI_SPIRXBUF_OFFSET = 0x07U
C_DRVDMA_SIZE = 40U
And here my SPI settings
/* SPI-A Clear SPI Software Reset bit (SPISWRESET= to 0 to force the SPI to the reset state */
/* SPI-A Relinquish SPI from Reset, Reset on, rising edge in input, 8-bit char bits */
GV_sSpiARegs.SPICCR.all = 0x0007U;
/* SPI-A Master mode, normal SPI clocking scheme, enable talk and disable SPI interrupt (flag) */
GV_sSpiARegs.SPICTL.all = 0x0006U;
/* SPI-A Baud Rate is set */
GV_sSpiARegs.SPIBRR.all = 19U;
/* SPI-A FREE bit */
/* Halting on a breakpoint will not halt the SPI */
GV_sSpiARegs.SPIPRI.bit.FREE = 1;
/* SPI-A RX FIFO, RXFIFORESET: Reset the FIFO pointer to zero, and hold in reset. */
GV_sSpiARegs.SPIFFRX.all = 0U;
/* SPI-A TX FIFO, SPIRST: Reset the SPI transmit and receive channels. */
/* The SPI FIFO register configuration bits will be left as is. */
/* TXFIFO: Reset the FIFO pointer to zero, and hold in reset */
GV_sSpiARegs.SPIFFTX.all = 0U;
/* SPI-A RX FIFO interrupt is disabled, FIFO interrupt level bits to default value */
/* SPI-A is ready to receive (RX FIFO) */
GV_sSpiARegs.SPIFFRX.all = 0xE041U;
/* SPI-A Enable TX and RX FIFO and is ready to transmit (TX FIFO) */
GV_sSpiARegs.SPIFFTX.all = 0xE041U;
GV_sSpiARegs.SPIFFCT.all = 1;
/* SPI-A is ready to transmit and receive the next character, set this bit before resuming operation */
GV_sSpiARegs.SPICCR.bit.SPISWRESET = 1;
When I start a transmission/reception :
- I start first the RX DMA :
GV_sDmaRegs.CH2.CONTROL.bit.PERINTCLR = 1; GV_sDmaRegs.CH2.CONTROL.bit.RUN = 1;
- Then TX DMA:
GV_sDmaRegs.CH1.CONTROL.bit.RUN = 1;
Systematically, at start-up, the first 3 bytes of my DMA buffer are the current state of SPIRXBUF repeated 3 times, and then 4 bytes lost from my frame (= 0) and then part of my expected frame.
Example :
Expected:
- [0] --> 0x5A
- [1] --> 0 (Counter)
- [2] --> 2
- [3] --> 3
- [4] --> 4
- [5] --> 5
- [6] --> 6
- [7] --> 7
- ...
- [37] --> 37
- [38] --> 0 (Same counter)
- [39] --> 0xA5
All next transmission/reception, I have :
My counter is the same at [4] as at [1], so I interpret that I have received my entire frame, but my DMA has started writing at the 4th byte and looping (even though I don't have WRAP set).
In debug, a breakpoint after activating DMA RX and before DMA TX shows no DMA RX trigger, only when I activate TX.
If you have any clues, I can't understand this problem. Thanks !