/************************************************************************************************** * @fn DMAExecCrc * * @brief This function assumes CRC has been initialized and sets up and * starts a dma tranfer from a flash page to the CRC HW module. * * @note This function uses NV DMA Ch; Ch0 * * input parameters * * @param page - A valid flash page number. * @param offset - A valid offset into the page. * @param len - A valid number of bytes to calculate crc of. * * @return None. ************************************************************************************************** */ void DMAExecCrc(uint8 page, uint16 offset, uint16 len) { uint8 memctr = MEMCTR; // Save to restore. // Calculate the offset into the containing flash bank as it gets mapped into XDATA. uint16 address = (offset + HAL_FLASH_PAGE_MAP) + ((page % HAL_FLASH_PAGE_PER_BANK) * HAL_FLASH_PAGE_SIZE); // Pointer to DMA config structure halDMADesc_t *dmaCh0_p = HAL_DMA_GET_DESC0(); #if !defined HAL_OAD_BOOT_CODE halIntState_t is; #endif page /= HAL_FLASH_PAGE_PER_BANK; // Calculate the flash bank from the flash page. #if !defined HAL_OAD_BOOT_CODE HAL_ENTER_CRITICAL_SECTION(is); #endif // Calculate and map the containing flash bank into XDATA. MEMCTR = (MEMCTR & 0xF8) | page; // page is actually bank // Start address for CRC calculation in the XDATA mapped flash bank HAL_DMA_SET_SOURCE(dmaCh0_p, address); // Destination for data transfer, RNDH mapped to XDATA HAL_DMA_SET_DEST(dmaCh0_p, 0x70BD); // One whole page (or len) at a time HAL_DMA_SET_LEN(dmaCh0_p, len); // 8-bit, block, no trigger HAL_DMA_SET_WORD_SIZE(dmaCh0_p, HAL_DMA_WORDSIZE_BYTE); HAL_DMA_SET_TRIG_MODE(dmaCh0_p, HAL_DMA_TMODE_BLOCK); HAL_DMA_SET_TRIG_SRC(dmaCh0_p, HAL_DMA_TRIG_NONE); // SRC += 1, DST = constant, no IRQ, all 8 bits, high priority HAL_DMA_SET_SRC_INC(dmaCh0_p, HAL_DMA_SRCINC_1); HAL_DMA_SET_DST_INC(dmaCh0_p, HAL_DMA_DSTINC_0); HAL_DMA_SET_IRQ(dmaCh0_p, HAL_DMA_IRQMASK_DISABLE); HAL_DMA_SET_M8(dmaCh0_p, HAL_DMA_M8_USE_8_BITS); HAL_DMA_SET_PRIORITY(dmaCh0_p, HAL_DMA_PRI_HIGH); // Arm the DMA channel (0) HAL_DMA_ARM_CH(0); // 9 cycles wait asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); // Start DMA tranfer HAL_DMA_MAN_TRIGGER(0); // Wait for dma to finish. while(DMAREQ & 0x1); // Restore bank mapping MEMCTR = memctr; #if !defined HAL_OAD_BOOT_CODE HAL_EXIT_CRITICAL_SECTION(is); #endif }
/****************************************************************************** * @fn HalIrGenInitNec * * @brief Initialize driver * * input parameters * * None. * * output parameters * * None. * * @return None. * */ void HalIrGenInitNec(void) { // Set TICKSPD:4M CLKCONCMD &= ~HAL_IRGEN_CLKCON_TICKSPD_MASK; CLKCONCMD |= HAL_IRGEN_TICKSPD_4MHZ; // Select port direction to output: P1.1 set output(1) P1DIR |= HAL_IRGEN_P1SEL_PORT; // Initially clear the port so that there will be no conflict P1 &= ~HAL_IRGEN_P1SEL_PORT; // Select port function to peripheral: P1.1 set Peripherial(1) P1SEL |= HAL_IRGEN_P1SEL_PORT; // Select alternative 2 location for T1 CH1 output (P1.1) PERCFG |= HAL_IRGEN_PERCFG_T1CFG; // -- set up bit signal generation timer -- // -- run timer once to make sure output is deactivated // Halt timer 1:Suspended T1CTL = HAL_IRGEN_T1CTL_MODE_SUSPEND; // Set up timer 1 channel 0 to compare mode 4 T1CCTL0 = HAL_IRGEN_TxCCTLx_CMP_CLR_SET | HAL_IRGEN_TxCCTLx_MODE_COMPARE; // Set up timer 1 channel 1 to compare mode 4 T1CCTL1 = HAL_IRGEN_TxCCTLx_CMP_CLR_SET | HAL_IRGEN_TxCCTLx_MODE_COMPARE; // Run one timer 1 until output is pulled low. // T1CNTL = 0; // Set up timer comparators for single carrier pulse output T1CC0L = 2; T1CC0H = 0; T1CC1L = 1; T1CC1H = 0; // Clear timer 1 // this will activate the output pin so start timer immediately. T1CNTL = 0; // Start timer 1: Set Modulo Mode T1CTL = HAL_IRGEN_BIT_TIMING_PRESCALER_DIV1 | HAL_IRGEN_T1CTL_MODE_MODULO; // Wait till the single bit is cleared while (T1CNTL == 0); // Stop timer 1 T1CTL = HAL_IRGEN_T1CTL_MODE_SUSPEND; #ifdef HAL_IRGEN_CARRIER // -- set up carrier signal generation timer -- // Clear counter and halt the timer T3CTL = HAL_IRGEN_T3CTL_CLR; // Set up timer 3 channel 0 to compare mode 4 T3CCTL0 = HAL_IRGEN_TxCCTLx_CMP_CLR_SET | HAL_IRGEN_TxCCTLx_MODE_COMPARE; // Set up timer 3 channel 1 to compare mode 4 T3CCTL1 = HAL_IRGEN_TxCCTLx_CMP_CLR_SET | HAL_IRGEN_TxCCTLx_MODE_COMPARE; // Configure 38kHz carrier with 33% duty cycle T3CC0 = HAL_IRGEN_NEC_CARRIER_DUTY_CYCLE; T3CC1 = HAL_IRGEN_NEC_CARRIER_ACTIVE_PER; // Combine carrier signal (Timer 1 CH 1 and Timer 3 CH 1 output) IRCTL |= 1; #endif // HAL_IRGEN_CARRIER // -- Configure DMA -- // Select proper DMA channel descriptor structure // Set up DMA channel for CC0 #if HAL_IRGEN_DMA_CH_CC0 == 0 pDmaDescCc0 = HAL_DMA_GET_DESC0(); #else pDmaDescCc0 = HAL_DMA_GET_DESC1234(HAL_IRGEN_DMA_CH_CC0); #endif // The start address of the destination. HAL_DMA_SET_DEST(pDmaDescCc0, HAL_IRGEN_T1CC0L_ADDR); // Using the length field to determine how many bytes to transfer. HAL_DMA_SET_VLEN(pDmaDescCc0, HAL_DMA_VLEN_USE_LEN); // Two bytes are transferred each time. HAL_DMA_SET_WORD_SIZE(pDmaDescCc0, HAL_DMA_WORDSIZE_WORD); // One word is transferred each time . HAL_DMA_SET_TRIG_MODE(pDmaDescCc0, HAL_DMA_TMODE_SINGLE); // Timer 1 channel 1 trigger DMA xfer HAL_DMA_SET_TRIG_SRC(pDmaDescCc0, HAL_DMA_TRIG_T1_CH1); // The source address is incremented by 1 word after each transfer. HAL_DMA_SET_SRC_INC(pDmaDescCc0, HAL_DMA_SRCINC_1); // The destination address is constant - T1CC0. HAL_DMA_SET_DST_INC(pDmaDescCc0, HAL_DMA_DSTINC_0); // IRQ handler is set up to tigger on CC1 HAL_DMA_SET_IRQ(pDmaDescCc0, HAL_DMA_IRQMASK_DISABLE); // Xfer all 8 bits of a byte xfer. HAL_DMA_SET_M8(pDmaDescCc0, HAL_DMA_M8_USE_8_BITS); // Set highest priority HAL_DMA_SET_PRIORITY(pDmaDescCc0, HAL_DMA_PRI_HIGH); // Set source data stream HAL_DMA_SET_SOURCE(pDmaDescCc0, &halIrGenCc0Buf[0]); // Set up DMA channel for CC1 #if HAL_IRGEN_DMA_CH_CC1 == 0 pDmaDescCc1 = HAL_DMA_GET_DESC0(); #else pDmaDescCc1 = HAL_DMA_GET_DESC1234(HAL_IRGEN_DMA_CH_CC1); #endif // The start address of the destination. HAL_DMA_SET_DEST(pDmaDescCc1, HAL_IRGEN_T1CC1L_ADDR); // Using the length field to determine how many bytes to transfer. HAL_DMA_SET_VLEN(pDmaDescCc1, HAL_DMA_VLEN_USE_LEN); // Two bytes are transferred each time. HAL_DMA_SET_WORD_SIZE(pDmaDescCc1, HAL_DMA_WORDSIZE_WORD); // One word is transferred each time HAL_DMA_SET_TRIG_MODE( pDmaDescCc1, HAL_DMA_TMODE_SINGLE ); // Timer 1 channel 1 trigger HAL_DMA_SET_TRIG_SRC(pDmaDescCc1, HAL_DMA_TRIG_T1_CH1); // The source address is not incremented since active periode is constant. HAL_DMA_SET_SRC_INC(pDmaDescCc1, HAL_DMA_SRCINC_0); // The destination address is constant - T1CC1. HAL_DMA_SET_DST_INC(pDmaDescCc1, HAL_DMA_DSTINC_0); // IRQ handler is set up so that sleep enable/disable can be determined. HAL_DMA_SET_IRQ(pDmaDescCc1, HAL_DMA_IRQMASK_ENABLE); // Xfer all 8 bits of a byte xfer. HAL_DMA_SET_M8(pDmaDescCc1, HAL_DMA_M8_USE_8_BITS); // Set highest priority HAL_DMA_SET_PRIORITY(pDmaDescCc1, HAL_DMA_PRI_HIGH); // Set source data stream. It is always constant. HAL_DMA_SET_SOURCE(pDmaDescCc1, &halIrGenCc1); // Timer is not running halIrGenTimerRunning = FALSE; }