Problem: Concerto only receive Data on C28-McBSP withDMA and missing the DMA-INTERRUPT
HW: Concerto-Kit
M3 setup_m3 all GPIO to C28
C28 (starting with mcbsp_loopback_dma)
Wanted function:
Read HSDC-data from acompanion chip (SPI) and store with DMA; NO TRANSMIT
The normal communication tothe companion chip runs over I2C and starts the sending from the HSDC-data. This chip is SPI master, Concerto use the McBSPa on C28 core to read a data-frame and store with DMA.
The SPI-datais a frame of 16words a 32bits with a 4MHz clock
I receive the data from companion chip, when running receiver and transmitter.
I used the transmitter (GPIO23, 22, 20) only to show on a Logic Analyser (LA) the receiveddata (GPIO5, 7, 21); in this picture not ok.
The first frame from the companion chip I used tosynchronisation and start then the McBSP, DMA.
MY PROBLEM:
The DMA- CH1 (receiver) interrupt and the DMA- CH2 (transmitter) interrupt occurs only during active frame (CH-8 gpio5 is low). Begin and end of DMA-CH1-INT (receiver) shown on CH-05 gpio08; DMA-CH2-INT (transmit) shown on CH07 gpio06 behind first frame. This is a wrong start of the next cycles!
AND
With stopped transmitter and running receiver I have NO interrupts. I’m missing the receiver- INT
During running receiver and transmitterI have both interrupts.
/*
* mcbsp_dma_hsdc_c28.c
*
* Created on: 16.10.2012
* Author: s_ferroni
*/
// Header file and Examples Include File
#include"DSP28x_Project.h"
…
#include"../mcbsp_ADEhsdc/mcbsp_dma_hsdc_c28.h"
#define HSDC_MESSAGE_SIZE 16
#define HSDC_FRAME_SIZE HSDC_MESSAGE_SIZE
#define HSDC_WORD_SIZE 32
//ram groessentest #define WAVE_SIZE 16
#define WAVE_SIZE 2
#define TRANSFER_BUFFER_SIZE ((HSDC_MESSAGE_SIZE+1) * WAVE_SIZE)
#define McbspaRegsSRGR2bitFPER (((HSDC_WORD_SIZE) * (HSDC_FRAME_SIZE))-1)
//fezumtesten....
#define MCBSP_TRANSMIT_ON
#defineDEBUG_HSDC_SHOW
// Prototype statements for functions found within this file.
interruptvoidlocal_D_INTCH1_ISR(void);
interruptvoidlocal_D_INTCH2_ISR(void);
voidmcbsp_init(void);
voidmcbspa_gpio_init(void);
voiddma_32_init(void);
voiddma_start(void);
voidhsdc_error(void);
voidc28gpio_init(void);
voidhsdc_start(void);
//#pragma DATA_SECTION(sdata, "DMARAMS4")
//#pragma DATA_SECTION(rdata, "DMARAMS4")
#pragma DATA_SECTION(sdata, "DMARAML2")
#pragma DATA_SECTION(rdata, "DMARAML2")
Uint32sdata[TRANSFER_BUFFER_SIZE];
Uint32rdata[TRANSFER_BUFFER_SIZE];
Uint16 uigpio5shift;
voidhsdc_start(void)
{
//start HSDC on the companion chip with I2C …
}
voidmsbsp_hsdc_init(void)
{
Uint16i;
mcbspa_gpio_init();
DINT;
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
EALLOW;
PieVectTable.DINTCH1= &local_D_INTCH1_ISR;
PieVectTable.DINTCH2= &local_D_INTCH2_ISR;
EDIS;
for (i=0; i < TRANSFER_BUFFER_SIZE; i++)
{
sdata[i] = (i<8)|0x8000000e; //i;
rdata[i] = 0;
}
#ifdefDEBUG_HSDC_SHOW
GpioG1DataRegs.GPBDAT.bit.GPIO34 = 1;// high testout1
GpioG1DataRegs.GPBDAT.bit.GPIO34 = 0;// low testout1
#endif
while (GpioG1DataRegs.GPADAT.bit.GPIO5 == 0); // wait for frame high;
dma_32_init();
dma_start();
mcbsp_init();
while (GpioG1DataRegs.GPADAT.bit.GPIO5 == 0); // wait for frame high;
//siehe 1.5.4.3
PieCtrlRegs.PIEIER7.bit.INTx1 = 1;
PieCtrlRegs.PIEIER7.bit.INTx2 = 1;
PieCtrlRegs.PIECTRL.bit.ENPIE = 1;
IER = M_INT7;
EINT;
//
// Waitfor an interrupt
//
}
voidmsbsp_hsdc(void)
{
hsdc_start();
uigpio5shift = 0;
// sync with first frame
while (GpioG1DataRegs.GPADAT.bit.GPIO5 == 1) DELAY_US(1); // wait for high end first frame
while (GpioG1DataRegs.GPADAT.bit.GPIO5 == 0) DELAY_US(1); // wait for low start first frame
//start McBSP and DMA after sync....
McbspaRegs.SPCR2.bit.GRST = 1; // rst sample rate generator
delay_loop();
#ifdef MCBSP_TRANSMIT_ON
McbspaRegs.SPCR2.bit.XRST = 1; // Transmitter enabled
McbspaRegs.MFFINT.bit.XINT = 1;
#else
McbspaRegs.SPCR2.bit.XRST = 0; // Transmitter in reset
McbspaRegs.MFFINT.bit.XINT = 0;
#endif
McbspaRegs.MFFINT.bit.RINT = 1;
McbspaRegs.SPCR1.bit.RRST = 1;
McbspaRegs.SPCR2.bit.FRST = 1;
#ifdefDEBUG_HSDC_SHOW
GpioG1DataRegs.GPADAT.bit.GPIO6 = 1;// high testout00
GpioG1DataRegs.GPBDAT.bit.GPIO34 = 1;// high testout1
GpioG1DataRegs.GPADAT.bit.GPIO8 = 1;// high testout0
GpioG1DataRegs.GPADAT.bit.GPIO8 = 0;// low testout0
GpioG1DataRegs.GPBDAT.bit.GPIO34 = 0;// low testout1
GpioG1DataRegs.GPADAT.bit.GPIO6 = 0;// low testout00
#endif
// Wait for an interrupt
//
//todoendlos
for(;;)
{
// show frame
uigpio5shift = (uigpio5shift<1) | GpioG1DataRegs.GPADAT.bit.GPIO5;
if ((uigpio5shift & 0x000f) == 0x000c)
{
GpioG1DataRegs.GPBDAT.bit.GPIO34 = 0; // low testout1
}
if ((uigpio5shift & 0x000f) == 0x0003)
{
GpioG1DataRegs.GPBDAT.bit.GPIO34 = 1; // high testout1
}
}
}
//*****************************************************************************
// Thehsdc_error routine that is called if the received character is in error.
//*****************************************************************************
voidhsdc_error(void)
{
asm(" ESTOP0"); // Test failed!! Stop!
for (;;);
}
voidmcbsp_init()
{
McbspaRegs.SPCR2.all=0x0000;
McbspaRegs.SPCR1.all=0x0000;
// McbspaRegs.SPCR1.bit.DLB = 1;
McbspaRegs.MFFINT.all=0x0;
McbspaRegs.RCR2.all=0x0;
McbspaRegs.RCR1.all=0x0;
McbspaRegs.XCR2.all=0x0;
McbspaRegs.XCR1.all=0x0;
//fe CLK for Sample Rate Generator --= 17.12.7 17.12.9
#ifdef MCBSP_TRANSMIT_ON // McBSP-Transiver
McbspaRegs.PCR.bit.SCLKME = 1; // extern
McbspaRegs.SRGR2.bit.CLKSM = 0; // clk for SamRateGen 0:MCLKRpin 1:MCLKXpin {mit SCLKME=1}
#else // ADEclk on gpio 7
McbspaRegs.PCR.bit.SCLKME = 1; // extern, Transmit OFF
McbspaRegs.SRGR2.bit.CLKSM = 0; // clk for SamRateGen 0:MCLKRpin 1:MCLKXpin {mit SCLKME=1}
#endif
McbspaRegs.SRGR2.bit.FPER = McbspaRegsSRGR2bitFPER; // McBSP 17.9.17
McbspaRegs.SRGR1.bit.FWID = 0;
McbspaRegs.SRGR1.bit.CLKGDV = 0; // 1 : 1 ( = 1; --> Xclk = Rclk/2 )
#ifdef MCBSP_TRANSMIT_ON // McBSP-Transiver
// // SPI-slave clk and fsx INPUT // with {SPCR1..CLKSTP = 2,3}
// McbspaRegs.PCR.bit.FSXM = 0; // transmit frame external ==> (FSXM-0,CLKXM-1)-> external clk -> only 1trans+rec
// McbspaRegs.PCR.bit.CLKXM = 0;
// SPI-master clk and fsx OUTPUT
McbspaRegs.PCR.bit.FSXM = 1; // transmit frame: 0:external+input, 1:internal+output
McbspaRegs.PCR.bit.CLKXM = 1; // with CLKSTP: 0:SPIslave+input, 1:SPImaster+output
#else // ADEclk on gpio 7
McbspaRegs.PCR.bit.FSXM = 0; // transmit frame external
McbspaRegs.PCR.bit.CLKXM = 0;
#endif
// with {DLB = 0} 0: clkextern siehe 17.12.9
McbspaRegs.PCR.bit.FSRM = 0; // receive frame external
McbspaRegs.PCR.bit.CLKRM = 0;
McbspaRegs.PCR.bit.CLKXP = 1; // clock polarity CLKX (transmit on -_ )
McbspaRegs.PCR.bit.CLKRP = 1; // clock polarity MCLKR (receive on _- )
McbspaRegs.PCR.bit.FSXP = 1; // TransmitFrameSyncPulse: activ 0
McbspaRegs.PCR.bit.FSRP = 1; // ReceiveFrameSyncPulse: activ 0
// McBSP 17.9.9
McbspaRegs.XCR2.bit.XCOMPAND = 0; // Transmit: no compand, MSB first
McbspaRegs.RCR2.bit.RCOMPAND = 0; // Receive : no compand, MSB first
McbspaRegs.XCR2.bit.XFIG = 1; // FrameSync: 0:new start, 1:ignore
McbspaRegs.XCR1.bit.XFRLEN1 = HSDC_FRAME_SIZE-1; // 15+1 woerter max:127 (==128words)
McbspaRegs.XCR1.bit.XWDLEN1 = 5; // ... a 32 bit
McbspaRegs.XCR2.bit.XWDLEN2 = 5; // ... a 32 bit
McbspaRegs.RCR2.bit.RPHASE = 0; // RPHASE: 1 phase
McbspaRegs.RCR2.bit.RFIG = 1; // FrameSync: 0:new start, 1:ignore
McbspaRegs.RCR2.bit.RDATDLY = 0; // R-DATA DELAY 0 ... 2 (..bit) nur receive
McbspaRegs.RCR1.bit.RFRLEN1 = HSDC_FRAME_SIZE-1; // 15+1 woerter max:127 (==128words)
McbspaRegs.RCR1.bit.RWDLEN1 = 5; // ... a 32 bit
McbspaRegs.RCR2.bit.RWDLEN2 = 5; // ... a 32 bit
McbspaRegs.SPCR1.bit.DLB = 0; // NO loop back
McbspaRegs.SRGR2.bit.GSYNC = 1; // clock syn mode for CLKG
McbspaRegs.SPCR1.bit.CLKSTP = 2; // clock stop mode with NO delay 3; half-cycle clk delay
}
voidmcbspa_gpio_init(void)
{
EALLOW;
GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 2;
GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 2;
GpioCtrlRegs.GPAQSEL2.bit.GPIO21 = 3;
GpioCtrlRegs.GPAMUX2.bit.GPIO22 = 2;
GpioCtrlRegs.GPAQSEL2.bit.GPIO22 = 3;
GpioCtrlRegs.GPAMUX1.bit.GPIO7 = 2;
GpioCtrlRegs.GPAQSEL1.bit.GPIO7 = 3;
GpioCtrlRegs.GPAMUX2.bit.GPIO23 = 2;
GpioCtrlRegs.GPAQSEL2.bit.GPIO23 = 3;
GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 2;
GpioCtrlRegs.GPAQSEL1.bit.GPIO5 = 3;
EDIS;
}
voiddma_32_init() // changed ch1-receive, ch2-transmit
{
EALLOW;
DmaRegs.DMACTRL.bit.HARDRESET = 1;
asm(" NOP"); // Only 1 NOP needed per Design
// transfer two 16-bit words per burst: inc source by 1 inc destination by 1 between words
DmaRegs.CH1.BURST_SIZE.all = 1; //limit to 1 (no fifo)
DmaRegs.CH1.SRC_BURST_STEP = 1;
DmaRegs.CH1.DST_BURST_STEP = 1;
DmaRegs.CH2.BURST_SIZE.all = 1;
DmaRegs.CH2.SRC_BURST_STEP = 1;
DmaRegs.CH2.DST_BURST_STEP = 1;
// interrupt every frame // DMA 13.6
DmaRegs.CH1.TRANSFER_SIZE = (HSDC_MESSAGE_SIZE-1);
DmaRegs.CH2.TRANSFER_SIZE = (HSDC_MESSAGE_SIZE-1);
// for recieve, after each burst: subt 1 from the source add 1 to the destination
DmaRegs.CH1.SRC_TRANSFER_STEP = 0xFFFF;
DmaRegs.CH1.DST_TRANSFER_STEP = 1;
// for transmit, after each burst: add 1 to the source subt 1 from the destination
DmaRegs.CH2.SRC_TRANSFER_STEP = 1;
DmaRegs.CH2.DST_TRANSFER_STEP = 0xFFFF;
// receive, transmit source and destination
DmaRegs.CH1.SRC_ADDR_SHADOW = (Uint32) &McbspaRegs.DRR2.all; // recieve source and destination
DmaRegs.CH1.DST_ADDR_SHADOW = (Uint32) &rdata[0];
DmaRegs.CH2.SRC_ADDR_SHADOW = (Uint32) &sdata[0];
DmaRegs.CH2.DST_ADDR_SHADOW = (Uint32) &McbspaRegs.DXR2.all;
// clear sync flag and error flag
DmaRegs.CH1.CONTROL.bit.SYNCCLR = 1;
DmaRegs.CH1.CONTROL.bit.ERRCLR = 1;
DmaRegs.CH2.CONTROL.bit.SYNCCLR = 1;
DmaRegs.CH2.CONTROL.bit.ERRCLR = 1;
// do not use wrap function
DmaRegs.CH1.DST_WRAP_SIZE = 0xFFFF;
DmaRegs.CH1.SRC_WRAP_SIZE = 0xFFFF;
DmaRegs.CH2.DST_WRAP_SIZE = 0xFFFF;
DmaRegs.CH2.SRC_WRAP_SIZE = 0xFFFF;
// no sync signal
DmaRegs.CH1.MODE.bit.SYNCE = 0;
DmaRegs.CH1.MODE.bit.SYNCSEL = 0;
DmaRegs.CH2.MODE.bit.SYNCE = 0;
DmaRegs.CH2.MODE.bit.SYNCSEL = 0;
// Enable channel interrupt at end of transfer
// Interrupt at end of the transfer (mode)
// Enable peripheral interrupt event
// Peripheral interrupt for recieve is McBSP MREVTA
// McBSPrecieve buffer is full
// Clear any interrupt flags
DmaRegs.CH1.MODE.bit.CHINTE =1;
DmaRegs.CH1.MODE.bit.CHINTMODE = 1;
DmaRegs.CH1.MODE.bit.PERINTE = 1;
DmaRegs.CH1.MODE.bit.PERINTSEL = DMA_MREVTA;
DmaRegs.CH1.CONTROL.bit.PERINTCLR = 1;
#ifdef MCBSP_TRANSMIT_ON
// Enable channel interrupt at end of transfer
// Interrupt at end of the transfer (mode)
// Enable peripheral interrupt event
// Peripheral interrupt for transfer is McBSP MXEVTA
// McBSP transmit buffer is empty
// Clear any interrupt flags
DmaRegs.CH2.MODE.bit.CHINTE = 1;
DmaRegs.CH2.MODE.bit.CHINTMODE = 1;
DmaRegs.CH2.MODE.bit.PERINTE = 1;
DmaRegs.CH2.MODE.bit.PERINTSEL = DMA_MXEVTA;
DmaRegs.CH2.CONTROL.bit.PERINTCLR = 1;
#endif
EDIS;
}
//*****************************************************************************
// Start DMA transmit and recieve from McBSP A
//*****************************************************************************
voiddma_start (void)
{
EALLOW;
#ifdef MCBSP_TRANSMIT_ON
DmaRegs.CH2.CONTROL.bit.RUN = 1; // Transmit
#endif
DmaRegs.CH1.CONTROL.bit.RUN = 1; // Receive
EDIS;
}
//*****************************************************************************
// DMA Channel 1 interrupt service routine
//*****************************************************************************
//todo:IRQ
interruptvoidlocal_D_INTCH2_ISR(void)
{
// orig....CH1
// Allow access to protected registers (EALLOW)
// Re-enable DMA CH1. Should be done every transfer
// To receive more interrupts from this PIE group, acknowledge this interrupt
// Disable access to protected registers (EDIS)
//
GpioG1DataRegs.GPADAT.bit.GPIO6 = 1;// high testout00
EALLOW;
DmaRegs.CH2.CONTROL.bit.RUN=0;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP7;
EDIS;
GpioG1DataRegs.GPADAT.bit.GPIO6 = 0;// low testout00
return;
}
//*****************************************************************************
// DMA Channel 2 interrupt service routine
//*****************************************************************************
interruptvoidlocal_D_INTCH1_ISR(void)
{
Uint16i;
//unsigned char countout;
//countout = 255; while((McbspaRegs.SPCR1.bit.RRDY == 0 ) & (countout > 0)) { countout--; }
#ifdefDEBUG_HSDC_SHOW
GpioG1DataRegs.GPADAT.bit.GPIO8 = 1;// high testout0
GpioG1DataRegs.GPADAT.bit.GPIO8 = 0;// low testout0
GpioG1DataRegs.GPADAT.bit.GPIO8 = 1;// high testout0
GpioG1DataRegs.GPADAT.bit.GPIO8 = 0;// low testout0
#endif
EALLOW;
DmaRegs.CH1.CONTROL.bit.RUN = 0; // stop DMA receive
PieCtrlRegs.PIEACK.all = PIEACK_GROUP7;
IAWV_reg.ulData = ((rdata[ 0]<12)&0xffffff00) | ((rdata[ 0]>20)&0x000000ff);
VAWV_reg.ulData = ((rdata[ 1]<12)&0xffffff00) | ((rdata[ 1]>20)&0x000000ff);
IBWV_reg.ulData = ((rdata[ 2]<12)&0xffffff00) | ((rdata[ 2]>20)&0x000000ff);
VBWV_reg.ulData = ((rdata[ 3]<12)&0xffffff00) | ((rdata[ 3]>20)&0x000000ff);
ICWV_reg.ulData = ((rdata[ 4]<12)&0xffffff00) | ((rdata[ 4]>20)&0x000000ff);
VCWV_reg.ulData = ((rdata[ 5]<12)&0xffffff00) | ((rdata[ 5]>20)&0x000000ff);
AVA_reg.ulData = ((rdata[ 6]<12)&0xffffff00) | ((rdata[ 6]>20)&0x000000ff);
INWV_reg.ulData = ((rdata[ 7]<12)&0xffffff00) | ((rdata[ 7]>20)&0x000000ff);
BVA_reg.ulData = ((rdata[ 8]<12)&0xffffff00) | ((rdata[ 8]>20)&0x000000ff);
CVA_reg.ulData = ((rdata[ 9]<12)&0xffffff00) | ((rdata[ 9]>20)&0x000000ff);
AWATT_reg.ulData = ((rdata[10]<12)&0xffffff00) | ((rdata[10]>20)&0x000000ff);
BWATT_reg.ulData = ((rdata[11]<12)&0xffffff00) | ((rdata[11]>20)&0x000000ff);
CWATT_reg.ulData = ((rdata[12]<12)&0xffffff00) | ((rdata[12]>20)&0x000000ff);
AFVARHR_reg.ulData = ((rdata[13]<12)&0xffffff00) | ((rdata[13]>20)&0x000000ff);
BFVARHR_reg.ulData = ((rdata[14]<12)&0xffffff00) | ((rdata[14]>20)&0x000000ff);
CFVARHR_reg.ulData = ((rdata[15]<12)&0xffffff00) | ((rdata[15]>20)&0x000000ff);
for (i=0; i < HSDC_MESSAGE_SIZE; i++)
{
sdata[i] = rdata[i];
rdata[i] = 0;
}
#ifdef MCBSP_TRANSMIT_ON
DmaRegs.CH2.CONTROL.bit.RUN = 1; // start DMA transmit
McbspaRegs.SPCR2.bit.XRST = 1; // Transmitter out off reset
#else
McbspaRegs.SPCR2.bit.XRST = 0; // Transmitter out off reset
DmaRegs.CH2.CONTROL.bit.RUN = 0; // stop DMA transmit
#endif
DmaRegs.CH1.CONTROL.bit.RUN = 1; // start DMA receive
EDIS;
#ifdefDEBUG_HSDC_SHOW
GpioG1DataRegs.GPADAT.bit.GPIO8 = 1;// high testout0
GpioG1DataRegs.GPADAT.bit.GPIO8 = 0;// low testout0
GpioG1DataRegs.GPADAT.bit.GPIO8 = 1;// high testout0
GpioG1DataRegs.GPADAT.bit.GPIO8 = 0;// low testout0
GpioG1DataRegs.GPADAT.bit.GPIO8 = 1;// high testout0
GpioG1DataRegs.GPADAT.bit.GPIO8 = 0;// low testout0
#endif
return;
}