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++; }