Hello, Following is an excerpt of the code being used successfully on the LCDK. The code is based on the c6748 experimenter BSL and works well when modified to run on the LCDK6748.
I have tried to port this code to run using the TI-RTOS. My question is about the interrupts and timer. In the above code the INTMUX1 register (highlighted) is used to assign the EDMA Receive/Transmit event(event number 8) to interrupt number 4 and the ICR, CSR and other registers are configured manually (highlighted). If I configure the hardware interrupt statically using the .cfg file, which registers will it affect and which registers will have to be deleted so that their value is not set twice.
Also, would the timer initialization code (highlighted) need to be modified to be compatible with the SYS/BIOS Timer
Hope this is clear enough.
Regards,
Anshul
// L138_LCDK_aic3106_init.c // #define DUAL_RATE #include "L138_LCDK_aic3106_init.h" #include "evmomapl138_spi.h" int16_t *pingIN, *pingOUT, *pongIN, *pongOUT; AIC31_data_type AIC31_data; spi_config_t spiconf; extern void vectors(void); void EDMA3_PaRAM_setup() // sets up PaRAM and enables EDMA events { uint32_t *EDMA3_PaRAM_ptr; // PaRAM sets (channels) 0 and 1, triggered by McASP0 // receive and transmit events respectively, are used // with linked parameters set up in PaRAM sets (channels) 64, 65, 67, and 68 // the linked parameters differ only in the ping or pong buffers used // set up PaRAM set 1 (MCASP0 XEVT) EDMA3_PaRAM_ptr = (unsigned int *)(0x01C04020); *EDMA3_PaRAM_ptr++ = 0x00000000; // no EDMA3 interrupts on transfer complete *EDMA3_PaRAM_ptr++ = (unsigned int)pingOUT; // source is one of two output buffers *EDMA3_PaRAM_ptr++ = (int32_t)((((BUFCOUNT/2)<<16) & 0xFFFF0000) | 0x00000004); // BCNT = BUFCOUNT/2(arrays per frame), ACNT = 4(bytes per array) writing to a (32-bit) McASP0 serialiser *EDMA3_PaRAM_ptr++ = 0x01D02000; // destination is DMA port of McASP0 *EDMA3_PaRAM_ptr++ = 0x00000004; // dest address is static, increment source address by ACNT bytes *EDMA3_PaRAM_ptr++ = 0x00000800; // BCNT reload value is redundant - link to PaRAM set 64 *EDMA3_PaRAM_ptr++ = 0x00000000; // CCNTIDX *EDMA3_PaRAM_ptr++ = 0x00000001; // rsvd, CCNT = 1(frame per block) // set up PaRAM set 64 EDMA3_PaRAM_ptr = (unsigned int *)(0x01C04800); *EDMA3_PaRAM_ptr++ = 0x00000000; // same as PaRAM set 1 *EDMA3_PaRAM_ptr++ = (unsigned int)pongOUT; // apart from source buffer used *EDMA3_PaRAM_ptr++ = (int32_t)((((BUFCOUNT/2)<<16) & 0xFFFF0000) | 0x00000004); *EDMA3_PaRAM_ptr++ = 0x01D02000; *EDMA3_PaRAM_ptr++ = 0x00000004; *EDMA3_PaRAM_ptr++ = 0x00000820; // BCNT reload value is redundant - link to PaRAM set 65 *EDMA3_PaRAM_ptr++ = 0x00000000; *EDMA3_PaRAM_ptr++ = 0x00000001; // set up PaRAM set 65 EDMA3_PaRAM_ptr = (unsigned int *)(0x01C04820); *EDMA3_PaRAM_ptr++ = 0x00000000; // exactly the same as PaRAM set 1 *EDMA3_PaRAM_ptr++ = (unsigned int)pingOUT; *EDMA3_PaRAM_ptr++ = (int32_t)((((BUFCOUNT/2)<<16) & 0xFFFF0000) | 0x00000004); *EDMA3_PaRAM_ptr++ = 0x01D02000; *EDMA3_PaRAM_ptr++ = 0x00000004; *EDMA3_PaRAM_ptr++ = 0x00000800; // BCNT reload value is redundant - link to PaRAM set 64 *EDMA3_PaRAM_ptr++ = 0x00000000; *EDMA3_PaRAM_ptr++ = 0x00000001; // set up PaRAM set 0 (MCASP0 REVT) EDMA3_PaRAM_ptr = (unsigned int *)(0x01C04000); *EDMA3_PaRAM_ptr++ = 0x00100000; // OPT interrupt on transfer complete with TCC = 0 *EDMA3_PaRAM_ptr++ = 0x01D02000; // SRC DMA port of McASP0 *EDMA3_PaRAM_ptr++ = (int32_t)((((BUFCOUNT/2)<<16) & 0xFFFF0000) | 0x00000004); *EDMA3_PaRAM_ptr++ = (unsigned int)pingIN; // DST one of two output buffers *EDMA3_PaRAM_ptr++ = 0x00040000; // DSTBIDX, SRCBIDX increment dest by 4 bytes, src is static *EDMA3_PaRAM_ptr++ = 0x00000860; // BCNT reload value is redundant - link to PaRAM set 67 *EDMA3_PaRAM_ptr++ = 0x00000000; // *EDMA3_PaRAM_ptr++ = 0x00000001; // rsvd, CCNT 1 frame per block // set up parameter RAM set 67 EDMA3_PaRAM_ptr = (unsigned int *)(0x01C04860); *EDMA3_PaRAM_ptr++ = 0x00101000; // OPT similar to PaRAM set 1 but TCC = 1 and different buffer used *EDMA3_PaRAM_ptr++ = 0x01D02000; // SRC *EDMA3_PaRAM_ptr++ = (int32_t)((((BUFCOUNT/2)<<16) & 0xFFFF0000) | 0x00000004); *EDMA3_PaRAM_ptr++ = (unsigned int)pongIN; // DST - single address used for XBUFn, RBUFn if RBSEL = 0 *EDMA3_PaRAM_ptr++ = 0x00040000; // DSTBIDX, SRCBIDX *EDMA3_PaRAM_ptr++ = 0x00000880; // BCNT reload value is redundant - link to PaRAM set 68 *EDMA3_PaRAM_ptr++ = 0x00000000; // *EDMA3_PaRAM_ptr++ = 0x00000001; // rsvd, CCNT // set up parameter RAM set 68 EDMA3_PaRAM_ptr = (unsigned int *)(0x01C04880); // exactly the same as PaRAM set 1 *EDMA3_PaRAM_ptr++ = 0x00100000; // OPT *EDMA3_PaRAM_ptr++ = 0x01D02000; // SRC *EDMA3_PaRAM_ptr++ = (int32_t)((((BUFCOUNT/2)<<16) & 0xFFFF0000) | 0x00000004); *EDMA3_PaRAM_ptr++ = (unsigned int)pingIN; // DST - single address used for XBUFn, RBUFn if RBSEL = 0 *EDMA3_PaRAM_ptr++ = 0x00040000; // DSTBIDX, SRCBIDX *EDMA3_PaRAM_ptr++ = 0x00000860; // BCNT reload value is redundant - link to PaRAM set 67 *EDMA3_PaRAM_ptr++ = 0x00000000; // *EDMA3_PaRAM_ptr++ = 0x00000001; // rsvd, CCNT EDMA_3CC_IECRH = 0xffffffff; // IERH - Disable high interrupts EDMA_3CC_EECRH = 0xffffffff; // EERH - Disable high events EDMA_3CC_ICRH = 0xffffffff; // ICRH - Clear high interrupts EDMA_3CC_ECRH = 0xffffffff; // ICRH - Clear high events EDMA_3CC_IECR = 0xffffffff; // IER - Disable low interrupts EDMA_3CC_EECR = 0xffffffff; // EER - Disable low events EDMA_3CC_ICR = 0xffffffff; // ICR - Clear low interrupts EDMA_3CC_ECR = 0xffffffff; // ICRH - Clear low events EDMA_3CC_EESR = 0x00000003; // enable EDMA3 events 0 and 1, i.e. McASP REVT and XEVT } //configure and initialise MCASP0 for edma3-based i/o void L138_init_mcasp_edma() { // reset mcasp. MCASP->GBLCTL = 0; // configure receive registers. MCASP->RMASK = 0x0000FFFF; MCASP->RFMT = 0x00018070;// was 0x000080F0 MCASP->AFSRCTL = 0x00000111;// was 0x00000000 MCASP->ACLKRCTL = 0x00000080;// was 0x00000000 MCASP->AHCLKRCTL = 0x00000000;// was 0x00000000 MCASP->RTDM = 0x00000003;// was 0x00000001 MCASP->RINTCTL = 0x00000000; MCASP->RCLKCHK = 0x00FF0005;// was 0x00000000 // configure transmit registers. MCASP->XMASK = 0x0000FFFF; MCASP->XFMT = 0x00018074;// was 0x000080F0 MCASP->AFSXCTL = 0x00000110;// was 0x00000000 MCASP->ACLKXCTL = 0x00000080;// was 0x00000000 MCASP->AHCLKXCTL = 0x00000000;// was 0x00000000 MCASP->XTDM = 0x00000003;// was 0x00000001 MCASP->XINTCTL = 0x00000000; MCASP->XCLKCHK = 0x00FF0005;// was 0x00000000 // config serializers (13 = xmit, 14 = rcv). MCASP->SRCTL13 = 0x000D;// was 0x000D MCASP->SRCTL14 = 0x000E;// was 0x000E // config pin function and direction. MCASP->PFUNC = 0; MCASP->PDIR = 0x00002000; // MCASP->DITCTL = 0x00000000; MCASP->DLBCTL = 0x00000000; MCASP->AMUTE = 0x00000000; // enable the audio clocks, verifying each bit is properly set. SETBIT(MCASP->XGBLCTL, XHCLKRST); while (!CHKBIT(MCASP->XGBLCTL, XHCLKRST)) {} SETBIT(MCASP->RGBLCTL, RHCLKRST); while (!CHKBIT(MCASP->RGBLCTL, RHCLKRST)) {} EDMA3_PaRAM_setup(); MCASP->XSTAT = 0x0000FFFF; // Clear all MCASP->RSTAT = 0x0000FFFF; // Clear all // if DMA is being used, verify that the XDATA bit (5) in XSTAT // is cleared to 0. (it should have been cleared y writing 1 to it) while ( ( MCASP->XSTAT & 0x00000020 ) != 0x00000000 ); SETBIT(MCASP->XGBLCTL, XSRCLR); while (!CHKBIT(MCASP->XGBLCTL, XSRCLR)) {} SETBIT(MCASP->RGBLCTL, RSRCLR); while (!CHKBIT(MCASP->RGBLCTL, RSRCLR)) {} /* Write a 0, so that no underrun occurs after releasing the state machine */ MCASP->XBUF13 = 0; MCASP->RBUF14 = 0; SETBIT(MCASP->XGBLCTL, XSMRST); while (!CHKBIT(MCASP->XGBLCTL, XSMRST)) {} SETBIT(MCASP->RGBLCTL, RSMRST); while (!CHKBIT(MCASP->RGBLCTL, RSMRST)) {} SETBIT(MCASP->XGBLCTL, XFRST); while (!CHKBIT(MCASP->XGBLCTL, XFRST)) {} SETBIT(MCASP->RGBLCTL, RFRST); while (!CHKBIT(MCASP->RGBLCTL, RFRST)) {} // wait for transmit ready and send a dummy byte. while(!CHKBIT(MCASP->SRCTL13, XRDY)) {} MCASP->XBUF13 = 0; } // initialise AIC3106 codec by writing to its control registers // sampling frequency, ADC gain, and DAC attenuation are set according to parameters passed void L138_init_aic3106_registers(int32_t fs, int16_t adc_gain, int16_t dac_atten, int8_t input_type) { // not every register is set here - some are left with default(reset) values // each AIC3106 register is 8 bits wide AIC3106_writeRegister( 0, 0x00 ); // AIC3106_PAGESELECT is PAGE 0 REG 0 AIC3106_writeRegister( 1, 0x80 ); // reset AIC3106 using REG 1 switch(fs) // set up sampling rate - default 8kHz { case FS_8000_HZ: AIC3106_writeRegister( 2, 0xAA ); AIC3106_writeRegister( 7, 0x0A ); // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT] break; case FS_9600_HZ: AIC3106_writeRegister( 2, 0x88 ); AIC3106_writeRegister( 7, 0x0A ); // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT] break; case FS_11025_HZ: AIC3106_writeRegister( 2, 0x66 ); AIC3106_writeRegister( 7, 0x8A ); // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT] break; case FS_12000_HZ: AIC3106_writeRegister( 2, 0x66 ); AIC3106_writeRegister( 7, 0x0A ); // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT] break; case FS_16000_HZ: AIC3106_writeRegister( 2, 0x44 ); AIC3106_writeRegister( 7, 0x0A ); // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT] break; case FS_19200_HZ: AIC3106_writeRegister( 2, 0x33 ); AIC3106_writeRegister( 7, 0x0A ); // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT] break; case FS_22050_HZ: AIC3106_writeRegister( 2, 0x22 ); AIC3106_writeRegister( 7, 0x8A ); // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT] break; case FS_24000_HZ: AIC3106_writeRegister( 2, 0x22 ); AIC3106_writeRegister( 7, 0x0A ); // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT] break; case FS_32000_HZ: AIC3106_writeRegister( 2, 0x11 ); AIC3106_writeRegister( 7, 0x0A ); // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT] break; case FS_44100_HZ: AIC3106_writeRegister( 2, 0x00 ); AIC3106_writeRegister( 7, 0x8A ); // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT] break; case FS_48000_HZ: AIC3106_writeRegister( 2, 0x00 ); AIC3106_writeRegister( 7, 0x0A ); // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT] break; #if defined DUAL_RATE case FS_96000_HZ: AIC3106_writeRegister( 2, 0x00 ); AIC3106_writeRegister( 7, 0x6A ); // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT] break; #endif default: AIC3106_writeRegister( 2, 0x00 ); AIC3106_writeRegister( 7, 0x0A ); // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT] break; } AIC3106_writeRegister( 3, 0x22 ); // disable PLL and set Q=4(relevant) and P=2(irrelevant) // fsref will be MCLK/(128*Q) = 48000 // MCLK on eXperimenter is 24.576MHz from on-board Citizen oscillator AIC3106_writeRegister( 4, 0x20 ); // J=8 (irrelevant since PLL disabled) AIC3106_writeRegister( 5, 0x6E ); // D=7075 MS bits (irrelevant since PLL disabled) AIC3106_writeRegister( 6, 0x23 ); // D=7075 LS bits (irrelevant since PLL disabled) AIC3106_writeRegister( 8, 0xC0 ); // Audio Interface Control A BCLK=Slave(input), WCLK=Slave(input) AIC3106_writeRegister( 9, 0x00 ); // Audio Interface Control B DSP mode (1 slot), 32 bit slot width AIC3106_writeRegister( 12, 0x00 ); // Audio Interface Control C Data offset=0 AIC3106_writeRegister( 10, 0x00 ); // Audio Interface Control C Data offset=0 // WARNING - this assumes that adc_gain is a sensible value AIC3106_writeRegister( 15, adc_gain ); // Left ADC Programmable Gain Amplifier Mute=OFF Gain=0dB AIC3106_writeRegister( 16, adc_gain ); // Right ADC Programmable Gain Amplifier Mute=OFF Gain=0dB if (input_type == LCDK_LINE_INPUT) { AIC3106_writeRegister( 19, 0x04 ); // power up ADCs AIC3106_writeRegister( 22, 0x04 ); // and connect LINE1L/R to ADC } else { AIC3106_writeRegister( 19, 0x7C ); // power up ADCs AIC3106_writeRegister( 22, 0x7C ); // and do not connect LINE1L/R to ADC AIC3106_writeRegister( 17, 0x0F ); // 17 MIC3L to L ADC (default 0xFF, NC) 0x00 0dB AIC3106_writeRegister( 18, 0xF0 ); // 18 MIC3R to R ADC (default 0xFF, NC) 0x00 0dB AIC3106_writeRegister( 25, 0x40 ); // 25 MICBIAS 0x40 2V, 0x00 OFF } AIC3106_writeRegister( 37, 0xE0 ); // DAC Power & Output Dvr LeftDAC=ON, RightDAC=ON, HPLCOM=SingleEnd] // WARNING - this assumes that dac_atten is a sensible value AIC3106_writeRegister( 43, dac_atten ); // Left DAC Digital Volume Mute=OFF, Gain=0dB AIC3106_writeRegister( 44, dac_atten ); // Right DAC Digital Volume Mute=OFF, Gain=0dB AIC3106_writeRegister( 82, 0x80 ); // was 0x80 DAC_L1 to LEFT_LOP/M Volume Routed, Gain=0dB AIC3106_writeRegister( 86, 0x09 ); // LEFT_LOP/M Output Mute=OFF bit3 bit0 is REad only ?! must be set! AIC3106_writeRegister( 92, 0x80 ); // was 0x80 92 DAC_R1 to RIGHT_LOP/M Volume <- [Routed] AIC3106_writeRegister( 93, 0x09 ); // 93 RIGHT_LOP/M Output <- [Mute=OFF][Power=ON] AIC3106_writeRegister( 101, 0x01 ); // 101 GPIO Control Register B <- [CODEC_CLKIN = CLKDIV_OUT] AIC3106_writeRegister( 102, 0 ); } // initialisation routine called by example program for edma3-based i/o void L138_initialise_edma(int32_t fs, int16_t adc_gain, int16_t dac_atten, int8_t input_type) { poll = 0; // used in input_sample() and output_sample() functions // allocate memory for ping pong buffers pingOUT = (int16_t *)malloc(BUFCOUNT*sizeof(int16_t)); pongOUT = (int16_t *)malloc(BUFCOUNT*sizeof(int16_t)); pingIN = (int16_t *)malloc(BUFCOUNT*sizeof(int16_t)); pongIN = (int16_t *)malloc(BUFCOUNT*sizeof(int16_t)); USTIMER_init(); EVMOMAPL138_lpscTransition(PSC1, DOMAIN0, LPSC_MCASP0, PSC_ENABLE); EVMOMAPL138_pinmuxConfig(PINMUX_MCASP_REG_0, PINMUX_MCASP_MASK_0, PINMUX_MCASP_VAL_0); EVMOMAPL138_pinmuxConfig(PINMUX_MCASP_REG_1, PINMUX_MCASP_MASK_1, PINMUX_MCASP_VAL_1); // replaces I2C_init(); *( volatile uint32_t* )(0x01C22024) = 0; *( volatile uint32_t* )(0x01C22030) = 2; *( volatile uint32_t* )(0x01C2200C) = 5; *( volatile uint32_t* )(0x01C22010) = 5; *( volatile uint32_t* )(0x01C22024) |= 0x20; spiconf.mode = SPI_MODE_MASTER; spiconf.pin_option = SPI_4PIN_CS; spiconf.cs_active = SPI_CS_ACTIVE_LOW; spiconf.shift_dir = SPI_SHIFT_MSB; spiconf.polarity = 0; spiconf.phase = 0; spiconf.freq = 1500000; CSR = 0x0000; // disable interrupts globally while initialising // GIE is bit 0 of CSR register L138_init_aic3106_registers(fs, adc_gain, dac_atten,input_type); L138_init_mcasp_edma(); SPI_init(SPI0,&spiconf); // clear any pending interrupts within EDMA3CC EDMA_3CC_ICR = 0x0007; // writing to ICR affects IPR // associate event n with interrupt 4 by writing n into LSBs of INTMUX1 // LSBs of INTMUX1 are literally associated with INT4 // in this case n=8 (EDMA3CC event) INTC_INTMUX1 = 0x00000008; ISTP = (unsigned int)vectors; // enable TCC = 0 and TCC = 1 EDMA3 interrupts by setting bits 0 and 1 in IESR EDMA3_IESR = 0x0003; EDMA3_DRAE1 = 0x0003; // clear all pending interrupt flags // interrupt clear register ICR is used to clear bits in interrupt flag register IFR ICR = 0xFFF0; // ICR bits 3, 2, 1, and 0 are reserved, read as 0, write has no effect IER |= 0x12; //enable NMI (bit 1) and INT4 (bit 4) //InitSPI(); CSR |= 0x01; // enable interrupts globally }