Part Number: RM48L952
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.
Part Number: RM48L952
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 */