Hello Experts,
I am looking for a working example for MibSPI transmit and receive over DMA. I am using MibSPI1 as master which will send the data and MibSPI3 as slave which will receive the data.
Thanks
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hello Experts,
I am looking for a working example for MibSPI transmit and receive over DMA. I am using MibSPI1 as master which will send the data and MibSPI3 as slave which will receive the data.
Thanks
Hello,
The attached is the example code of MibSPI1+MibSPI3+DMA on TMS570LC43x
MibSPI1 is SPI master, and MibSPI3 is SPI slave.
/** @file HL_sys_main.c * @brief Application main file * @date 11-Dec-2018 * @version 04.07.01 * * This file contains an empty main function, * which can be used for the application. */ /* * Copyright (C) 2009-2018 Texas Instruments Incorporated - www.ti.com * * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /* USER CODE BEGIN (0) */ /* USER CODE END */ /* Include Files */ #include "HL_sys_common.h" /* USER CODE BEGIN (1) */ #include "HL_gio.h" #include "HL_mibspi.h" #include "HL_sys_dma.h" #include "HL_sys_core.h" #include "HL_sci.h" #include "HL_reg_esm.h" #include <stdio.h> #include <string.h> #define E_COUNT 4 /*Element count*/ #define F_COUNT 2 /*Frame count*/ #define D_SIZE E_COUNT * F_COUNT #define TG0 1 #define TG1 0 /* USER CODE END */ /** @fn void main(void) * @brief Application main function * @note This function is empty by default. * * This function is called after startup. * The user can use this function to implement the application. */ /* USER CODE BEGIN (2) */ void loadDataPattern(uint32 psize, uint16* pptr, uint16 pattern); void mibspiDmaConfig(mibspiBASE_t *mibspi,uint32 channel, uint32 txchannel, uint32 rxchannel); void dmaConfigCtrlRxPacket(uint32 sadd, uint32 dadd, uint16 ElmntCnt, uint16 FrameCnt); void dmaConfigCtrlTxPacket(uint32 sadd, uint32 dadd, uint16 ElmntCnt, uint16 FrameCnt); /* TG start address */ uint16 tgPSTART1[8]; //for MibSPI1 uint16 tgPSTART3[8]; //for MibSPI3 g_dmaCTRL g_dmaCTRLPKT_RX, g_dmaCTRLPKT_TX; #pragma SET_DATA_SECTION(".sharedRAM") uint16 TXDATA_TG10[D_SIZE]; /* transmit buffer in sys ram, MibSPI1 TG0 */ uint16 RXDATA_TG10[D_SIZE]= {0}; /* receive buffer in sys ram, MibSPI1 TG0 */ //uint16 TXDATA_TG11[D_SIZE]; /* transmit buffer in sys ram, MibSPI1 TG1 */ //uint16 RXDATA_TG11[D_SIZE]= {0}; /* receive buffer in sys ram, MibSPI1 TG1 */ uint16 TXDATA_TG30[D_SIZE]; /* transmit buffer in sys ram, MibSPI3 TG0 */ uint16 RXDATA_TG30[D_SIZE]= {0}; /* receive buffer in sys ram, MibSPI3 TG0 */ #pragma SET_DATA_SECTION() /* USER CODE END */ int main(void) { /* USER CODE BEGIN (3) */ uint16 i; esmREG->SR1[0] = 0xFFFFFFFF; esmREG->SR1[1] = 0xFFFFFFFF; esmREG->SR1[2] = 0xFFFFFFFF; esmREG->EKR = 0x0A; esmREG->EKR = 0x00; esmREG->EKR = 0x05; esmREG->EKR = 0x00; sciInit(); //gioInit(); //gioSetDirection(gioPORTA, 0x01); _enable_IRQ_interrupt_(); /* - initializing mibspi - enabling tg 0 , length 127 (halcogen file)*/ mibspiInit(); mibspiEnableGroupNotification(mibspiREG3, 0, 1); mibspiREG1->TICKCNT = (0 << 31) | (0<<28) | (0x100); //mibspiEnableLoopback(mibspiREG1, Digital_Lbk); mibspiREG1->TGCTRL[0U] = (uint32)((uint32)1U << 30U) /* oneshot */ | (uint32)((uint32)0U << 29U) /* pcurrent reset */ | (uint32)((uint32)TRG_ALWAYS<< 20U) /* trigger event */ | (uint32)((uint32)TRG_DISABLED << 16U) /* trigger source */ | (uint32)((uint32)0U << 8U); /* start buffer */ mibspiREG1->TGCTRL[1U] = (uint32)((uint32)1U << 30U) /* oneshot */ | (uint32)((uint32)0U << 29U) /* pcurrent reset */ | (uint32)((uint32)TRG_ALWAYS << 20U) /* trigger event */ | (uint32)((uint32)TRG_DISABLED << 16U) /* trigger source */ | (uint32)((uint32)4U << 8U); /* start buffer */ /*MibSPI1 TG0*/ for (i=0; i<3; i++) { mibspiRAM1->tx[i].control = (uint16)((uint16)5U << 13U) /* buffer mode */ | (uint16)((uint16)1U << 12U) /* chip select hold */ | (uint16)((uint16)0U << 10U) /* enable WDELAY */ | (uint16)((uint16)0U << 11U) /* lock transmission */ | (uint16)((uint16)0U << 8U) /* data format */ | ((uint16)(~((uint16)0xFFU ^ (uint16)CS_0)) & (uint16)0x00FFU); /* chip select */ } mibspiRAM1->tx[3].control = (uint16)((uint16)5U << 13U) /* buffer mode */ | (uint16)((uint16)0U << 12U) /* chip select hold */ | (uint16)((uint16)0U << 10U) /* enable WDELAY */ | (uint16)((uint16)0U << 8U) /* data format */ | ((uint16)(~((uint16)0xFFU ^ (uint16)CS_0)) & (uint16)0x00FFU); /* chip select */ /*MibSPI1 TG1*/ for (i=4; i<7; i++) { mibspiRAM1->tx[i].control = (uint16)((uint16)5U << 13U) /* buffer mode */ | (uint16)((uint16)1U << 12U) /* chip select hold */ | (uint16)((uint16)0U << 10U) /* enable WDELAY */ | (uint16)((uint16)0U << 11U) /* lock transmission */ | (uint16)((uint16)0U << 8U) /* data format */ | ((uint16)(~((uint16)0xFFU ^ (uint16)CS_0)) & (uint16)0x00FFU); /* chip select */ } mibspiRAM1->tx[7].control = (uint16)((uint16)5U << 13U) /* buffer mode */ | (uint16)((uint16)0U << 12U) /* chip select hold */ | (uint16)((uint16)0U << 10U) /* enable WDELAY */ | (uint16)((uint16)0U << 8U) /* data format */ | ((uint16)(~((uint16)0xFFU ^ (uint16)CS_0)) & (uint16)0x00FFU); /* chip select */ /** - initialize transfer groups */ mibspiREG3->TGCTRL[0U] = (uint32)((uint32)1U << 30U) /* oneshot */ | (uint32)((uint32)0U << 29U) /* pcurrent reset */ | (uint32)((uint32)TRG_ALWAYS << 20U) /* trigger event */ | (uint32)((uint32)TRG_DISABLED << 16U) /* trigger source */ | (uint32)((uint32)0U << 8U); /* start buffer */ /** - initialize transfer groups */ mibspiREG3->TGCTRL[1U] = (uint32)((uint32)1U << 30U) /* oneshot */ | (uint32)((uint32)0U << 29U) /* pcurrent reset */ | (uint32)((uint32)TRG_ALWAYS << 20U) /* trigger event */ | (uint32)((uint32)TRG_DISABLED << 16U) /* trigger source */ | (uint32)((uint32)4U << 8U); /* start buffer */ //MibSPI3 Transfer Group 0 for(i=0; i<3; i++) { mibspiRAM3->tx[i].control = (uint16)((uint16)6U << 13U) /* buffer mode */ | (uint16)((uint16)1U << 12U) /* chip select hold */ | (uint16)((uint16)0U << 10U) /* enable WDELAY */ | (uint16)((uint16)0U << 11U) /* lock transmission */ | (uint16)((uint16)0U << 8U) /* data format */ | ((uint16)(~((uint16)0xFFU ^ (uint16)CS_0)) & (uint16)0x00FFU); /* chip select */ } mibspiRAM3->tx[3].control = (uint16)((uint16)6U << 13U) /* buffer mode */ | (uint16)((uint16)0U << 12U) /* chip select hold */ | (uint16)((uint16)0U << 10U) /* enable WDELAY */ | (uint16)((uint16)0U << 8U) /* data format */ | ((uint16)(~((uint16)0xFFU ^ (uint16)CS_0)) & (uint16)0x00FFU); /* chip select */ /* TG start address. PSTARTx stores the start address of the corresponding TG. The corresponding */ /* end address is inherently defined by the subsequent TG start address minus 1 (PENDx[TGx] = */ /* PSTARTx[TGx+1]-1). PSTARTx is copied into PCURRENTx when:*/ for(i=0; i<8; i++){ tgPSTART1[i] = (mibspiREG1->TGCTRL[i] >> 8) & 0xFF; tgPSTART3[i] = (mibspiREG3->TGCTRL[i] >> 8) & 0xFF; } /*MibSPI1 TG0, DMA config*/ /* - creating a data chunk in system ram to start with ... */ /* TXDATA_TG10 ->MibSPI1 TG0 */ loadDataPattern(D_SIZE, &TXDATA_TG10[0], 0x5A00); dmaConfigCtrlTxPacket((uint32)TXDATA_TG10, (uint32)&(mibspiRAM1->tx[tgPSTART1[0]].data), E_COUNT, F_COUNT); dmaConfigCtrlRxPacket((uint32)&(mibspiRAM1->rx[tgPSTART1[0]].data), (uint32)RXDATA_TG10, E_COUNT, F_COUNT); //using DAM_CH0 for RX, DMA_CH1 for TX /* - setting dma control packets */ dmaSetCtrlPacket(DMA_CH1,g_dmaCTRLPKT_TX); //tx dmaSetCtrlPacket(DMA_CH0,g_dmaCTRLPKT_RX); //rx /* - setting the dma channel to trigger on h/w request */ dmaSetChEnable(DMA_CH1, DMA_HW); dmaSetChEnable(DMA_CH0, DMA_HW); dmaReqAssign(DMA_CH1, DMA_REQ1); //DMA request line 1, TX dmaReqAssign(DMA_CH0, DMA_REQ0); //DMA request line 0, RX /* - configuring the mibspi dma , channel 0 , tx line -0 , rxline -1 */ /* - refer to the device data sheet dma request source for mibspi tx/rx */ mibspiDmaConfig(mibspiREG1,0,0,1); //RX_DMA_Line=1, TX_DMA_Line=0 /*NOBRKx */ //mibspiREG1->DMACTRL[0] |= (1 << 13); /* Enable Block Transfer Complete interrupt for the receive after transfer complete */ dmaEnableInterrupt(DMA_CH0, BTC, DMA_INTA); #if 0 /* MibSPI TG1, DMA*/ //using DAM_CH6 for RX, DMA_CH8 for TX /* - creating a data chunk in system ram to start with ... */ loadDataPattern(D_SIZE, &TXDATA_TG11[0], 0x6B00); dmaConfigCtrlTxPacket((uint32)TXDATA_TG11, (uint32)&(mibspiRAM1->tx[tgPSTART1[1]].data), E_COUNT, F_COUNT); dmaConfigCtrlRxPacket((uint32)&(mibspiRAM1->rx[tgPSTART1[1]].data), (uint32)RXDATA_TG11, E_COUNT, F_COUNT); /* - setting dma control packets */ dmaSetCtrlPacket(DMA_CH7,g_dmaCTRLPKT_TX); //tx dmaSetCtrlPacket(DMA_CH4,g_dmaCTRLPKT_RX); //rx /* - setting the dma channel to trigger on h/w request */ dmaSetChEnable(DMA_CH7, DMA_HW); dmaSetChEnable(DMA_CH4, DMA_HW); dmaReqAssign(DMA_CH7, DMA_REQ16); //DMA request line 16 -- TX (last col, Table 6-41) dmaReqAssign(DMA_CH4, DMA_REQ22); //DMA request line 22 -- RX (last col, Table 6-41) /* - configuring the mibspi dma , channel 2, MibSPI TX Line -8 , MibSPI RX Line - 10 */ /* MibSPI TX Line and MibSPI RX Line are in the parentheses following MibSPI1 */ mibspiDmaConfig(mibspiREG1,1,8,10); /* Enable Block Transfer Complete interrupt for the receive after transfer complete */ dmaEnableInterrupt(DMA_CH4, BTC, DMA_INTA); #endif /* MibSPI3, Slave, TG0, DMA*/ //using DAM_CH6 for RX, DMA_CH8 for TX /* - creating a data chunk in system ram to start with ... */ /* TXDATA_TG30 --> MibSPI3, TG0*/ loadDataPattern(D_SIZE, &TXDATA_TG30[0], 0x3A00); dmaConfigCtrlTxPacket((uint32)TXDATA_TG30, (uint32)&(mibspiRAM3->tx[tgPSTART3[0]].data), E_COUNT, F_COUNT); //TG0 dmaConfigCtrlRxPacket((uint32)&(mibspiRAM3->rx[tgPSTART3[0]].data), (uint32)RXDATA_TG30, E_COUNT, F_COUNT); /* - setting dma control packets */ dmaSetCtrlPacket(DMA_CH9,g_dmaCTRLPKT_TX); //tx dmaSetCtrlPacket(DMA_CH8,g_dmaCTRLPKT_RX); //rx /* - setting the dma channel to trigger on h/w request */ dmaSetChEnable(DMA_CH9, DMA_HW); dmaSetChEnable(DMA_CH8, DMA_HW); dmaReqAssign(DMA_CH9, DMA_REQ4); //DMA request line 4 -- TX (last col, Table 6-41) dmaReqAssign(DMA_CH8, DMA_REQ5); //DMA request line 5 -- RX (last col, Table 6-41) /* - configuring the mibspi dma , channel 2, MibSPI TX Line -2 , MibSPI RX Line - 3 */ /* MibSPI TX Line and MibSPI RX Line are in the parentheses following MibSPI1 */ /* MibSPI3 transfer group 0*/ mibspiDmaConfig(mibspiREG3,0,2,3); /* Enable Block Transfer Complete interrupt for the receive after transfer complete */ dmaEnableInterrupt(DMA_CH8, BTC, DMA_INTA); dmaEnable(); /* - start the mibspi transfer tg 0 */ mibspiTransfer(mibspiREG3, 0); mibspiTransfer(mibspiREG1, 0); while(1); /* USER CODE END */ return 0; } /* USER CODE BEGIN (4) */ /** configuring mibspi dma with * * channel > mibspi dma channel number * txchannel > transmit channel dedicated for mibspi * rxchannel > receive channel dedicated for mibspi */ void mibspiDmaConfig(mibspiBASE_t *mibspi,uint32 channel, uint32 txchannel, uint32 rxchannel) { uint32 bufid; //uint32 bufid = (channel + 1) * E_COUNT - 1; if (mibspi == mibspiREG1){ bufid = tgPSTART1[channel] + E_COUNT - 1; }else{ bufid = tgPSTART3[channel] + E_COUNT - 1; } /* setting transmit and receive channels */ mibspi->DMACTRL[channel] |= (rxchannel << 20) | (txchannel << 16); if (F_COUNT > 1) { mibspi->TGCTRL[channel] &= 0xBFFFFFFF; // Disable ONESHOT } else { mibspi->TGCTRL[channel] |= 0x40000000; // Enable ONESHOT } /* enabling transmit and receive dma */ mibspi->DMACTRL[channel] |= 0x8000C000; /* setting Initial Count of DMA transfers and the buffer utilized for DMA transfer */ mibspi->DMACTRL[channel] |= (bufid<<24); /* Enable Large count transfer */ mibspi->DMACNTLEN = 0x1; mibspi->DMACOUNT[channel] = (F_COUNT - 1) << 16; } void loadDataPattern(uint32 psize, uint16* pptr, uint16 pattern) { int i; for(i=0;i<psize;i++) { *(pptr++) = 0x5A5A; //pattern + i; } } void dmaConfigCtrlTxPacket(uint32 sadd, uint32 dadd, uint16 ElmntCnt, uint16 FrameCnt) { g_dmaCTRLPKT_TX.SADD = sadd; /* source address */ g_dmaCTRLPKT_TX.DADD = dadd; /* destination address */ g_dmaCTRLPKT_TX.CHCTRL = 0; /* channel control */ g_dmaCTRLPKT_TX.FRCNT = FrameCnt ; /* frame count */ g_dmaCTRLPKT_TX.ELCNT = ElmntCnt; /* element count */ g_dmaCTRLPKT_TX.ELDOFFSET = 4; /* element destination offset */ g_dmaCTRLPKT_TX.ELSOFFSET = 0; /* element destination offset */ g_dmaCTRLPKT_TX.FRDOFFSET = 0; /* frame destination offset */ g_dmaCTRLPKT_TX.FRSOFFSET = 0; /* frame destination offset */ g_dmaCTRLPKT_TX.PORTASGN = PORTA_READ_PORTB_WRITE; /* port b */ g_dmaCTRLPKT_TX.RDSIZE = ACCESS_16_BIT; /* read size */ g_dmaCTRLPKT_TX.WRSIZE = ACCESS_16_BIT; /* write size */ g_dmaCTRLPKT_TX.TTYPE = FRAME_TRANSFER ; /* transfer type */ g_dmaCTRLPKT_TX.ADDMODERD = ADDR_INC1; /* address mode read */ g_dmaCTRLPKT_TX.ADDMODEWR = ADDR_OFFSET; /* address mode write */ g_dmaCTRLPKT_TX.AUTOINIT = AUTOINIT_OFF; /* autoinit */ //return g_dmaCTRLPKT_TX; } void dmaConfigCtrlRxPacket(uint32 sadd, uint32 dadd, uint16 ElmntCnt, uint16 FrameCnt) { g_dmaCTRLPKT_RX.SADD = sadd; /* source address */ g_dmaCTRLPKT_RX.DADD = dadd; /* destination address */ g_dmaCTRLPKT_RX.CHCTRL = 0; /* channel control */ g_dmaCTRLPKT_RX.FRCNT = FrameCnt; /* frame count */ g_dmaCTRLPKT_RX.ELCNT = ElmntCnt; /* element count */ g_dmaCTRLPKT_RX.ELDOFFSET = 0; /* element destination offset */ g_dmaCTRLPKT_RX.ELSOFFSET = 4; /* element source offset */ g_dmaCTRLPKT_RX.FRDOFFSET = 0; /* frame destination offset */ g_dmaCTRLPKT_RX.FRSOFFSET = 0; /* frame destination offset */ g_dmaCTRLPKT_RX.PORTASGN = PORTB_READ_PORTA_WRITE; /* port b */ g_dmaCTRLPKT_RX.RDSIZE = ACCESS_16_BIT; /* read size */ g_dmaCTRLPKT_RX.WRSIZE = ACCESS_16_BIT; /* write size */ g_dmaCTRLPKT_RX.TTYPE = FRAME_TRANSFER ; /* transfer type */ g_dmaCTRLPKT_RX.ADDMODERD = ADDR_OFFSET; /* address mode read */ g_dmaCTRLPKT_RX.ADDMODEWR = ADDR_INC1; /* address mode write */ g_dmaCTRLPKT_RX.AUTOINIT = AUTOINIT_OFF; /* autoinit */ //return g_dmaCTRLPKT_RX; } /* USER CODE END */