Hello,
I am having some troubles configuring the EDMA for a bcnt > 1.
I use the rCSL_quick_start EDMA_event_trig_dspL138 example code, the modified code is in attachment.
I succeed to transfer with the EDMA from the external memory ( using the EMIF) to the internal memory.The edma transfers are a-synchronized with the timer. This successful EDMA configuration is: ACNT = 3, BCNT = 1, CCNT = 1
But, when I change only the bcnt value, leaving a a-synchronized transfer (ACNT = 3, BCNT = 2, CCNT = 1), I can actually see the multiple transfers happenning, synchronized with the timer, but the EDMA transfer completion ISR is now never reached.
Any help will be highly appreciated.
Veronica
/*-----------------------------------------------------------------------------
* Project: EDMA_event_trig_dspL138
* File: main.c
*
* This file contains the test / demo code to demonstrate basic EDMA
* operations using the Regsiter CSL macros.
*
* Copyright (C) 2010 Texas Instruments Incorporated - http://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.
*
*-----------------------------------------------------------------------------
*
* EDMA_event_trig_dspL138
* -----------------------
* Purpose: Demonstrate usage of EDMA rCSL
*
* Example Description:
* This example initializes the EDMA3 channel controller using the rCSL
* macros to perform a simple 1kB internal memory to memory transfer upon
* a timer time-out event. Once initialized, the timer is enabled once to
* trigger the EDMA3 event. The EDMA3 channel controller consequently
* sends a transfer request to the transfer controller and the data in
* the source buffer is transferred to the destination buffer. Upon
* completion of the transfer, the EDMA3 channel controller sends an
* interrupt to the CPU and the source and destination buffers are
* compared to verify the EDMA3 transfer. The results are printed to
* the console.
*
* -> SEE README IN PROJECT FOLDER FOR DETAILS AND STEPS TO RUN EXAMPLE <-
*
*---------------------------------------------------------------------------*/
#include <EDMA_event_trig_dspL138.h>
#include <ti/pspiom/cslr/cslr_emifa2.h>
//Uint8 srcBuffer[SRC_ARRAYS][SRC_ARRAY_SIZE];
Uint8 *srcBufferP = (Uint8 *)CSL_EMIFA_CS2_ADDR;
//Uint8 dstBuffer[DST_ARRAYS][DST_ARRAY_SIZE];
Uint8 dstBuffer[DST_ARRAYS*DST_ARRAY_SIZE];
Uint8 *dstBufferP = &dstBuffer[0];
Uint8 *dataPointer;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
CSL_EmifaRegsOvly emifaRegs = (CSL_EmifaRegsOvly)(CSL_EMIFA_0_REGS);
#define A_CNT 3
#define B_CNT 1
#define C_CNT 1
//#define B_CNTRLD B_CNT
#define B_CNTRLD 0
#define SB_IDX 0
#define SC_IDX 0
#define DB_IDX A_CNT
#define DC_IDX A_CNT // A-sync
//#define DC_IDX (A_CNT*B_CNT) // AB-sync
volatile int runTimerCount=0;
volatile int runExampleCount = 0;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
/*-----------------------------------------------------------------------------
*
* BEGIN EXAMPLE: EDMA_event_trig_dspL138
*
*---------------------------------------------------------------------------*/
void main (void)
{
// Initialize OMAPL138 EVM (Timer w/DSP)
init_OMAPL138();
// Enable Peripherals (EDMACC, EDMATC0)
enable_module_clocks();
// Setup Peripherals; Run Example
if(modulesEnabled)
{
// Configure the 64 Bit Timer0 as 32 Bit Unchain
setup_Timer0();
// Setup EMIFA
setup_EMIFA();
// Setup EDMA for Event 10 Transfer
setup_EDMA();
// Map System Interrupts to the DSP Interrupt Controller
setup_DSP_INTC();
// Run Example
EDMA_event_trig_DSPexample();
}
}/* End of main */
/*-----------------------------------------------------------------------------
*
* Internal Functions Defined
*
*---------------------------------------------------------------------------*/
static void init_OMAPL138 (void)
{
// Open Permissions to SYSCFG Registers
CSL_FINS(sysRegs->KICK0R, SYSCFG_KICK0R_KICK0, KICK0_KEY);
CSL_FINS(sysRegs->KICK1R, SYSCFG_KICK1R_KICK1, KICK1_KEY);
// Configure Timer0 with the DSP CPU
CSL_FINST(sysRegs->SUSPSRC, SYSCFG_SUSPSRC_TIMER64P_0SRC, DSP);
// Close Permissions to SYSCFG Registers
CSL_FINS(sysRegs->KICK0R, SYSCFG_KICK0R_KICK0, KICK_LOCK);
}/* init_OMAPL138 */
/*---------------------------------------------------------------------------*/
static void enable_module_clocks (void)
{
modulesEnabled = FALSE;
// Ensure previous initiated transitions have finished
if(check_psc_transition(CSL_PSC_0) == pscTimeout)
return;
// Enable peripherals; Initiate transition
CSL_FINST(psc0Regs->MDCTL[CSL_PSC_CC0], PSC_MDCTL_NEXT, ENABLE);
CSL_FINST(psc0Regs->MDCTL[CSL_PSC_TC0], PSC_MDCTL_NEXT, ENABLE);
CSL_FINST(psc0Regs->MDCTL[CSL_PSC_EMIFA], PSC_MDCTL_NEXT, ENABLE);
CSL_FINST(psc0Regs->PTCMD, PSC_PTCMD_GO0, SET);
// Ensure previous initiated transitions have finished
if(check_psc_transition(CSL_PSC_0) == pscTimeout)
return;
// Ensure EDMA3CC enabled
if(check_psc_MDSTAT(CSL_PSC_0, CSL_PSC_CC0, CSL_PSC_MDSTAT_STATE_ENABLE)
== pscTimeout)
return;
// Ensure EDMA3TC0 enabled
if(check_psc_MDSTAT(CSL_PSC_0, CSL_PSC_TC0, CSL_PSC_MDSTAT_STATE_ENABLE)
== pscTimeout)
return;
// Ensure CSL_PSC_EMIFA enabled
if(check_psc_MDSTAT(CSL_PSC_0, CSL_PSC_EMIFA, CSL_PSC_MDSTAT_STATE_ENABLE)
== pscTimeout)
return;
modulesEnabled = TRUE;
}/* enable_module_clocks */
/*---------------------------------------------------------------------------*/
static void setup_Timer0 (void)
{
// Set Timer0 as 32 Bit Unchain
CSL_FINST(tmr0Regs->TGCR, TMR_TGCR_TIMMODE, 32BIT_UNCHAIN);
// Remove Timer0:12 from Reset
CSL_FINST(tmr0Regs->TGCR, TMR_TGCR_TIM12RS, NO_RESET);
// Set Timer0:12 Period; 1 Second
//CSL_FINS(tmr0Regs->PRD12, TMR_PRD12_PRD12, CSL_ASYNC_2_FREQ);
CSL_FINS(tmr0Regs->PRD12, TMR_PRD12_PRD12, 24u); //24000000u
// Select Internal Clock for Timer0:12 (24 MHz)
CSL_FINST(tmr0Regs->TCR, TMR_TCR_CLKSRC12, INTERNAL);
// Reset the Counter for Timer0:12
CSL_FINST(tmr0Regs->TIM12, TMR_TIM12_TIM12, RESETVAL);
// Disable the New Timer Features
CSL_FINST(tmr0Regs->TGCR, TMR_TGCR_PLUSEN, DISABLE);
}/* setup_Timer0 */
/*---------------------------------------------------------------------------*/
static void setup_EMIFA (void)
{
volatile Uint32 thisVal;
// Configure EMIFA Signals
CSL_FINST(sysRegs->PINMUX7, SYSCFG_PINMUX7_PINMUX7_3_0, NEMA_CS2);
thisVal = sysRegs->PINMUX8;
sysRegs->PINMUX8 = 0x11111111 ;
thisVal = sysRegs->PINMUX8;
thisVal = sysRegs->PINMUX9;
sysRegs->PINMUX9 = 0x11111111 ;
thisVal = sysRegs->PINMUX9;
// Disable the interrupts CSL_EMIFA_INTMSKCLR_WR_MASK_CLR_MASK
CSL_FINST(emifaRegs->INTMSKCLR, EMIFA_INTMSKCLR_WR_MASK_CLR, CLEAR);
CSL_FINST(emifaRegs->INTMSKCLR, EMIFA_INTMSKCLR_LT_MASK_CLR, CLEAR);
CSL_FINST(emifaRegs->INTMSKCLR, EMIFA_INTMSKCLR_AT_MASK_CLR, CLEAR);
// Disables the extended wait cycles
CSL_FINST(emifaRegs->CE2CFG, EMIFA_CE2CFG_EW, EXT_WAIT_DISABLE);
// Configure the EMIFA Async timings
{
/*volatile EMIFATimingInfo_t *emifaTimingInfo = &emifDaqConfig;
unsigned int wtTimeConf = 0;*/
// Select the async interface opmode
CSL_FINST(emifaRegs->CE2CFG, EMIFA_CE2CFG_SS, SELSTRB_ENABLE);
// Configure the EMIFA Async timings
CSL_FINS(emifaRegs->CE2CFG, EMIFA_CE2CFG_R_STROBE, 0);
CSL_FINS(emifaRegs->CE2CFG, EMIFA_CE2CFG_R_HOLD, 0);
CSL_FINS(emifaRegs->CE2CFG, EMIFA_CE2CFG_R_SETUP, 0);
CSL_FINS(emifaRegs->CE2CFG, EMIFA_CE2CFG_W_STROBE, 1);
CSL_FINS(emifaRegs->CE2CFG, EMIFA_CE2CFG_W_HOLD, 1);
CSL_FINS(emifaRegs->CE2CFG, EMIFA_CE2CFG_W_SETUP, 0);
CSL_FINS(emifaRegs->CE2CFG, EMIFA_CE2CFG_TA, 0);
}
// set the buswidth of async device
CSL_FINST(emifaRegs->CE2CFG, EMIFA_CE2CFG_ASIZE, 8BIT);
}/* setup_EMIFA */
/*---------------------------------------------------------------------------*/
static void setup_EDMA (void)
{
// Clear Event Registers
CSL_FINST(edma3ccRegs->ECR, EDMA3CC_ECR_REG, MASK);
CSL_FINST(edma3ccRegs->SECR, EDMA3CC_SECR_REG, MASK);
// Enable Channel 10 to DSP (Region 1)
CSL_FINST(edma3ccRegs->DRA[CSL_EDMA3_REGION_1].DRAE,
EDMA3CC_DRAE_E10, ENABLE);
// Assign Channel 10 to Queue 0
CSL_FINST(edma3ccRegs->DMAQNUM[1], EDMA3CC_DMAQNUM_E2, Q0);
// Initialize PaRAM Transfer Context for Event 10
init_PaRAM_event10();
// Enable Channel 10 Event Register
CSL_FINST(edma3ccRegs->EESR, EDMA3CC_EESR_E10, SET);
// Enable Interrupts for Channel 10
CSL_FINST(edma3ccRegs->IESR, EDMA3CC_IESR_I10, SET);
}/* setup_EDMA */
/*---------------------------------------------------------------------------*/
static void init_PaRAM_event10 (void)
{
// Reset EDMA PaRAM OPT Register
edma3ccRegs->PARAMSET[EDMA_EVENT10].OPT = CSL_EDMA3CC_OPT_RESETVAL;
// Config PaRAM OPT (Enable TC Interrupt; Set TCC)
edma3ccRegs->PARAMSET[EDMA_EVENT10].OPT =
CSL_FMKT(EDMA3CC_OPT_TCINTEN, ENABLE) |
CSL_FMK(EDMA3CC_OPT_TCC, EDMA_EVENT10)|
CSL_FMKT(EDMA3CC_OPT_SYNCDIM, ASYNC) |
/*CSL_FMKT(EDMA3CC_OPT_SYNCDIM, ABSYNC) |*/
CSL_FMKT(EDMA3CC_OPT_STATIC, STATIC);
// Initialize EDMA Event Src and Dst Addresses
edma3ccRegs->PARAMSET[EDMA_EVENT10].SRC = (Uint32)srcBufferP;
edma3ccRegs->PARAMSET[EDMA_EVENT10].DST = (Uint32)dstBufferP;
// Set EDMA Event PaRAM A,B,C CNT
edma3ccRegs->PARAMSET[EDMA_EVENT10].A_B_CNT =
CSL_FMK(EDMA3CC_A_B_CNT_ACNT, A_CNT) |
CSL_FMK(EDMA3CC_A_B_CNT_BCNT, B_CNT);
edma3ccRegs->PARAMSET[EDMA_EVENT10].CCNT = C_CNT;
// Set EDMA Event PaRAM SRC/DST BIDX
edma3ccRegs->PARAMSET[EDMA_EVENT10].SRC_DST_BIDX =
CSL_FMK(EDMA3CC_SRC_DST_BIDX_SRCBIDX, SB_IDX) |
CSL_FMK(EDMA3CC_SRC_DST_BIDX_DSTBIDX, DB_IDX);
// Set EDMA Event PaRAM SRC/DST CIDX
edma3ccRegs->PARAMSET[EDMA_EVENT10].SRC_DST_CIDX =
CSL_FMK(EDMA3CC_SRC_DST_CIDX_SRCCIDX, SC_IDX) |
CSL_FMK(EDMA3CC_SRC_DST_CIDX_DSTCIDX, DC_IDX);
// Set EDMA Event PaRAM LINK and BCNTRLD
edma3ccRegs->PARAMSET[EDMA_EVENT10].LINK_BCNTRLD =
CSL_FMK(EDMA3CC_LINK_BCNTRLD_LINK, PaRAM_NULL_LINK) |
CSL_FMK(EDMA3CC_LINK_BCNTRLD_BCNTRLD, B_CNTRLD);
}/* init_PaRAM_event10 */
/*---------------------------------------------------------------------------*/
static void setup_DSP_INTC (void)
{
// Map EDMA3CC/Timer0:12 System interrupts to DSP INT4/5
dspintcRegs->INTMUX1 =
CSL_FMK(DSPINTC_INTMUX1_INTSEL4, CSL_INTC_EVENTID_EDMA3_0_CC0_INT1) |
CSL_FMK(DSPINTC_INTMUX1_INTSEL5, CSL_INTC_EVENTID_T64P0_TINT12);
// Assign the address of the IST to the IST pointer
ISTP = (unsigned int)intcVectorTable;
// Clear all CPU maskable interrupts
ICR = DSPINTC_IST_ALL_MASK_INT;
// Enable INT4-INT5 interrupts
IER = DSPINTC_IST_NMI | DSPINTC_IST_INT4 | DSPINTC_IST_INT5;
}/* setup_DSP_INTC */
/*---------------------------------------------------------------------------*/
static void EDMA_event_trig_DSPexample (void)
{
printf("Example: EDMA_event_trig_dspL138\n"
"Scope:\tEDMA triggered by Timer0:12 performs a 1kB internal "
"memory to memory transfer.\n"
"Begin...\n");
// Initialize Transfer Src and Dst Buffers
/*dataPointer = (Uint8*)srcBuffer;
for(counter = 0; counter < (SRC_ARRAYS * SRC_ARRAY_SIZE); counter++)
*dataPointer++ = (Uint8)counter;*/
dataPointer = (Uint8*)dstBuffer;
for(counter = 0; counter < (DST_ARRAYS * DST_ARRAY_SIZE); counter++)
*dataPointer++ = 0;
runExample = 1;
// Intrinsic Function to Enable Interrupts
_enable_interrupts();
printf("\tEnabling Timer with 1 second period...\n");
// Enable Timer1:12 Once (Trigger EDMA Event 10)
//CSL_FINST(tmr0Regs->TCR, TMR_TCR_ENAMODE12, EN_ONCE);
CSL_FINST(tmr0Regs->TCR, TMR_TCR_ENAMODE12, EN_CONT);
int burstTimerCount = 0, loopCount=0;
//for(burstTimerCount=0; burstTimerCount<3; burstTimerCount++)
while(1)
{
// Wait for Event 10 Completion Interrupt
while(runExample);
runExample = 1;
// Wait for A-Xfer done (not xFer complete yet!)
//for(loopCount=0; loopCount<20; loopCount++);
}
// Disable Timer0:12
CSL_FINST(tmr0Regs->TCR, TMR_TCR_ENAMODE12, DISABLE);
// Intrinsic Function to Disable Interrupts
_disable_interrupts();
// Verify Transfer
/*errorCount = verify_EDMA_xfer(
XFER_BYTES,
XFER_ARRAYS,
XFER_FRAMES,
SRC_ARRAY_SIZE,
DST_ARRAY_SIZE,
0,0,
&srcBuffer[0][0],
&dstBuffer[0][0],
FALSE);*/
if(errorCount == NO_ERRORS)
printf("\tTransfer Success!\n");
else
printf("\tTransfer Fail!\n");
printf("End of example!\n\n");
}/* EDMA_event_trig_DSPexample */
/*-----------------------------------------------------------------------------
*
* Interrupt Functions
*
*---------------------------------------------------------------------------*/
interrupt void EDMA3CC_INT1_isr (void)
{
Uint32 regIPR, IxBitMask, IxCounter;
runExampleCount++;
while(edma3ccRegs->IPR != 0)
{
// Read Interrupt Pending Register
regIPR = edma3ccRegs->IPR;
// Loop for Set Interrupt Pending Bit
for(IxCounter = 0; IxCounter < 32; IxCounter++)
{
IxBitMask = 1 << IxCounter;
if(regIPR & IxBitMask)
{
// Exit Example on Correct Interrupt
if(IxCounter == EDMA_EVENT10)
runExample = 0;
else
printf("Interrupt not supported!\n");
// Clear Pending Interrupt
edma3ccRegs->ICR = IxBitMask;
break;
}
}
}
}
// Need this for successful transfer
interrupt void Timer0_12_isr (void)
{
printf("\tInitiating transfer...\n");
runTimerCount++;
}