/****************************************************************************** * @fn aesDmaInit * * @brief Initilize DMA for AES engine * * input parameters * * @param None * * @return None */ void aesDmaInit( void ) { halDMADesc_t *ch; /* Fill in DMA channel 1 descriptor and define it as input */ ch = HAL_DMA_GET_DESC1234( HAL_DMA_AES_IN ); HAL_DMA_SET_DEST( ch, HAL_AES_IN_ADDR ); /* Input of the AES module */ HAL_DMA_SET_VLEN( ch, HAL_DMA_VLEN_USE_LEN ); /* Using the length field */ HAL_DMA_SET_WORD_SIZE( ch, HAL_DMA_WORDSIZE_BYTE ); /* One byte is transferred each time */ HAL_DMA_SET_TRIG_MODE( ch, HAL_DMA_TMODE_SINGLE ); /* A single byte is transferred each time */ HAL_DMA_SET_TRIG_SRC( ch, HAL_DMA_TRIG_ENC_DW ); /* Setting the AES module to generate the DMA trigger */ HAL_DMA_SET_SRC_INC( ch, HAL_DMA_SRCINC_1 ); /* The address for data fetch is incremented by 1 byte */ HAL_DMA_SET_DST_INC( ch, HAL_DMA_DSTINC_0 ); /* The destination address is constant */ HAL_DMA_SET_IRQ( ch, HAL_DMA_IRQMASK_DISABLE ); /* The DMA complete interrupt flag is not set at completion */ HAL_DMA_SET_M8( ch, HAL_DMA_M8_USE_8_BITS ); /* Transferring all 8 bits in each byte */ HAL_DMA_SET_PRIORITY( ch, HAL_DMA_PRI_HIGH ); /* DMA has priority */ /* Fill in DMA channel 2 descriptor and define it as output */ ch = HAL_DMA_GET_DESC1234( HAL_DMA_AES_OUT ); HAL_DMA_SET_SOURCE( ch, HAL_AES_OUT_ADDR ); /* Start address of the segment */ HAL_DMA_SET_VLEN( ch, HAL_DMA_VLEN_USE_LEN ); /* Using the length field */ HAL_DMA_SET_WORD_SIZE( ch, HAL_DMA_WORDSIZE_BYTE ); /* One byte is transferred each time */ HAL_DMA_SET_TRIG_MODE( ch, HAL_DMA_TMODE_SINGLE ); /* A single byte is transferred each time */ HAL_DMA_SET_TRIG_SRC( ch, HAL_DMA_TRIG_ENC_UP ); /* Setting the AES module to generate the DMA trigger */ HAL_DMA_SET_SRC_INC( ch, HAL_DMA_SRCINC_0 ); /* The address for data fetch is constant */ HAL_DMA_SET_DST_INC( ch, HAL_DMA_DSTINC_1 ); /* The destination address is incremented by 1 byte */ HAL_DMA_SET_IRQ( ch, HAL_DMA_IRQMASK_DISABLE ); /* The DMA complete interrupt flag is not set at completion */ HAL_DMA_SET_M8( ch, HAL_DMA_M8_USE_8_BITS ); /* Transferring all 8 bits in each byte */ HAL_DMA_SET_PRIORITY( ch, HAL_DMA_PRI_HIGH ); /* DMA has priority */ }
/************************************************************************************************** * @fn HalFlashWrite * * @brief This function writes 'cnt' bytes to the internal flash. * * input parameters * * @param addr - Valid HAL flash write address: actual addr / 4 and quad-aligned. * @param buf - Valid buffer space at least as big as 'cnt' X 4. * @param cnt - Number of 4-byte blocks to write. * * output parameters * * None. * * @return None. ************************************************************************************************** */ void HalFlashWrite(uint16 addr, uint8 *buf, uint16 cnt) { halDMADesc_t *ch = HAL_NV_DMA_GET_DESC(); HAL_DMA_SET_SOURCE(ch, buf); HAL_DMA_SET_DEST(ch, &FWDATA); HAL_DMA_SET_VLEN(ch, HAL_DMA_VLEN_USE_LEN); HAL_DMA_SET_LEN(ch, (cnt * HAL_FLASH_WORD_SIZE)); HAL_DMA_SET_WORD_SIZE(ch, HAL_DMA_WORDSIZE_BYTE); HAL_DMA_SET_TRIG_MODE(ch, HAL_DMA_TMODE_SINGLE); HAL_DMA_SET_TRIG_SRC(ch, HAL_DMA_TRIG_FLASH); HAL_DMA_SET_SRC_INC(ch, HAL_DMA_SRCINC_1); HAL_DMA_SET_DST_INC(ch, HAL_DMA_DSTINC_0); // The DMA is to be polled and shall not issue an IRQ upon completion. HAL_DMA_SET_IRQ(ch, HAL_DMA_IRQMASK_DISABLE); HAL_DMA_SET_M8( ch, HAL_DMA_M8_USE_8_BITS); HAL_DMA_SET_PRIORITY(ch, HAL_DMA_PRI_HIGH); HAL_DMA_CLEAR_IRQ(HAL_NV_DMA_CH); HAL_DMA_ARM_CH(HAL_NV_DMA_CH); FADDRL = (uint8)addr; FADDRH = (uint8)(addr >> 8); FCTL |= 0x02; // Trigger the DMA writes. while (FCTL & 0x80); // Wait until writing is done. }
/************************************************************************************************** * @fn HalUARTInitSPI * * @brief Initialize the SPI UART Transport. * * input parameters * * None. * * output parameters * * None. * * @return None. */ static void HalUARTInitSPI(void) { #if (HAL_UART_SPI == 1) PERCFG &= ~HAL_UART_PERCFG_BIT; /* Set UART0 I/O to Alt. 1 location on P0 */ #else PERCFG |= HAL_UART_PERCFG_BIT; /* Set UART1 I/O to Alt. 2 location on P1 */ #endif #if defined HAL_SPI_MASTER PxSEL |= HAL_UART_Px_SEL_M; /* SPI-Master peripheral select */ UxCSR = 0; /* Mode is SPI-Master Mode */ UxGCR = 15; /* Cfg for the max Rx/Tx baud of 2-MHz */ UxBAUD = 255; #elif !defined HAL_SPI_MASTER PxSEL |= HAL_UART_Px_SEL_S; /* SPI-Slave peripheral select */ UxCSR = CSR_SLAVE; /* Mode is SPI-Slave Mode */ #endif UxUCR = UCR_FLUSH; /* Flush it */ UxGCR |= BV(5); /* Set bit order to MSB */ P2DIR &= ~P2DIR_PRIPO; P2DIR |= HAL_UART_PRIPO; /* Setup GPIO for interrupts by falling edge on SPI_RDY_IN */ PxIEN |= SPI_RDYIn_BIT; PICTL |= PICTL_BIT; SPI_CLR_RDY_OUT(); PxDIR |= SPI_RDYOut_BIT; /* Setup Tx by DMA */ halDMADesc_t *ch = HAL_DMA_GET_DESC1234( HAL_SPI_CH_TX ); /* Abort any pending DMA operations (in case of a soft reset) */ HAL_DMA_ABORT_CH( HAL_SPI_CH_TX ); /* The start address of the destination */ HAL_DMA_SET_DEST( ch, DMA_UxDBUF ); /* Using the length field to determine how many bytes to transfer */ HAL_DMA_SET_VLEN( ch, HAL_DMA_VLEN_USE_LEN ); /* One byte is transferred each time */ HAL_DMA_SET_WORD_SIZE( ch, HAL_DMA_WORDSIZE_BYTE ); /* The bytes are transferred 1-by-1 on Tx Complete trigger */ HAL_DMA_SET_TRIG_MODE( ch, HAL_DMA_TMODE_SINGLE ); HAL_DMA_SET_TRIG_SRC( ch, DMATRIG_TX ); /* The source address is incremented by 1 byte after each transfer */ HAL_DMA_SET_SRC_INC( ch, HAL_DMA_SRCINC_1 ); HAL_DMA_SET_SOURCE( ch, spiTxPkt ); /* The destination address is constant - the Tx Data Buffer */ HAL_DMA_SET_DST_INC( ch, HAL_DMA_DSTINC_0 ); /* The DMA Tx done is serviced by ISR */ HAL_DMA_SET_IRQ( ch, HAL_DMA_IRQMASK_ENABLE ); /* Xfer all 8 bits of a byte xfer */ HAL_DMA_SET_M8( ch, HAL_DMA_M8_USE_8_BITS ); /* DMA has highest priority for memory access */ HAL_DMA_SET_PRIORITY( ch, HAL_DMA_PRI_HIGH ); /* Setup Rx by DMA */ ch = HAL_DMA_GET_DESC1234( HAL_SPI_CH_RX ); /* Abort any pending DMA operations (in case of a soft reset) */ HAL_DMA_ABORT_CH( HAL_SPI_CH_RX ); /* The start address of the source */ HAL_DMA_SET_SOURCE( ch, DMA_UxDBUF ); /* Using the length field to determine how many bytes to transfer */ HAL_DMA_SET_VLEN( ch, HAL_DMA_VLEN_USE_LEN ); /* The trick is to cfg DMA to xfer 2 bytes for every 1 byte of Rx. * The byte after the Rx Data Buffer is the Baud Cfg Register, * which always has a known value. So init Rx buffer to inverse of that * known value. DMA word xfer will flip the bytes, so every valid Rx byte * in the Rx buffer will be preceded by a DMA_PAD char equal to the * Baud Cfg Register value. */ HAL_DMA_SET_WORD_SIZE( ch, HAL_DMA_WORDSIZE_WORD ); /* The bytes are transferred 1-by-1 on Rx Complete trigger */ HAL_DMA_SET_TRIG_MODE( ch, HAL_DMA_TMODE_SINGLE_REPEATED ); HAL_DMA_SET_TRIG_SRC( ch, DMATRIG_RX ); /* The source address is constant - the Rx Data Buffer */ HAL_DMA_SET_SRC_INC( ch, HAL_DMA_SRCINC_0 ); /* The destination address is incremented by 1 word after each transfer */ HAL_DMA_SET_DST_INC( ch, HAL_DMA_DSTINC_1 ); HAL_DMA_SET_DEST( ch, spiRxBuf ); HAL_DMA_SET_LEN( ch, SPI_MAX_PKT_LEN ); /* The DMA is to be polled and shall not issue an IRQ upon completion */ HAL_DMA_SET_IRQ( ch, HAL_DMA_IRQMASK_DISABLE ); /* Xfer all 8 bits of a byte xfer */ HAL_DMA_SET_M8( ch, HAL_DMA_M8_USE_8_BITS ); /* DMA has highest priority for memory access */ HAL_DMA_SET_PRIORITY( ch, HAL_DMA_PRI_HIGH ); volatile uint8 dummy = *(volatile uint8 *)DMA_UxDBUF; /* Clear the DMA Rx trigger */ HAL_DMA_CLEAR_IRQ(HAL_SPI_CH_RX); HAL_DMA_ARM_CH(HAL_SPI_CH_RX); (void)memset(spiRxBuf, (DMA_PAD ^ 0xFF), SPI_MAX_PKT_LEN * sizeof(uint16)); }
/****************************************************************************** * @fn HalUARTInitDMA * * @brief Initialize the UART * * @param none * * @return none *****************************************************************************/ static void HalUARTInitDMA(void) { halDMADesc_t *ch; #if (HAL_UART_DMA == 1) PERCFG &= ~HAL_UART_PERCFG_BIT; // Set UART0 I/O to Alt. 1 location on P0. #else PERCFG |= HAL_UART_PERCFG_BIT; // Set UART1 I/O to Alt. 2 location on P1. #endif PxSEL |= HAL_UART_Px_SEL; // Enable Peripheral control of Rx/Tx on Px. p0.2 P0.3 set peripheral //i0 setting UxCSR = CSR_MODE; // Mode is UART Mode. UxUCR = UCR_FLUSH; // Flush it. P2DIR &= ~P2DIR_PRIPO; //ÓÅÏȼ¶ P2DIR |= HAL_UART_PRIPO; if (DMA_PM) { // Setup GPIO for interrupts by falling edge on DMA_RDY_IN. PxIEN |= DMA_RDYIn_BIT; PICTL |= PICTL_BIT; HAL_UART_DMA_CLR_RDY_OUT(); PxDIR |= DMA_RDYOut_BIT; } #if !HAL_UART_TX_BY_ISR // Setup Tx by DMA. ch = HAL_DMA_GET_DESC1234( HAL_DMA_CH_TX ); // Abort any pending DMA operations (in case of a soft reset). HAL_DMA_ABORT_CH( HAL_DMA_CH_TX ); // The start address of the destination. HAL_DMA_SET_DEST( ch, DMA_UxDBUF ); // Using the length field to determine how many bytes to transfer. HAL_DMA_SET_VLEN( ch, HAL_DMA_VLEN_USE_LEN ); // One byte is transferred each time. HAL_DMA_SET_WORD_SIZE( ch, HAL_DMA_WORDSIZE_BYTE ); // The bytes are transferred 1-by-1 on Tx Complete trigger. HAL_DMA_SET_TRIG_MODE( ch, HAL_DMA_TMODE_SINGLE ); HAL_DMA_SET_TRIG_SRC( ch, DMATRIG_TX ); // The source address is incremented by 1 byte after each transfer. HAL_DMA_SET_SRC_INC( ch, HAL_DMA_SRCINC_1 ); // The destination address is constant - the Tx Data Buffer. HAL_DMA_SET_DST_INC( ch, HAL_DMA_DSTINC_0 ); // The DMA Tx done is serviced by ISR in order to maintain full thruput. HAL_DMA_SET_IRQ( ch, HAL_DMA_IRQMASK_ENABLE ); // Xfer all 8 bits of a byte xfer. HAL_DMA_SET_M8( ch, HAL_DMA_M8_USE_8_BITS ); // DMA has highest priority for memory access. HAL_DMA_SET_PRIORITY( ch, HAL_DMA_PRI_HIGH); #endif // Setup Rx by DMA. ch = HAL_DMA_GET_DESC1234( HAL_DMA_CH_RX ); // Abort any pending DMA operations (in case of a soft reset). HAL_DMA_ABORT_CH( HAL_DMA_CH_RX ); // The start address of the source. HAL_DMA_SET_SOURCE( ch, DMA_UxDBUF ); // Using the length field to determine how many bytes to transfer. HAL_DMA_SET_VLEN( ch, HAL_DMA_VLEN_USE_LEN ); /* The trick is to cfg DMA to xfer 2 bytes for every 1 byte of Rx. * The byte after the Rx Data Buffer is the Baud Cfg Register, * which always has a known value. So init Rx buffer to inverse of that * known value. DMA word xfer will flip the bytes, so every valid Rx byte * in the Rx buffer will be preceded by a DMA_PAD char equal to the * Baud Cfg Register value. */ HAL_DMA_SET_WORD_SIZE( ch, HAL_DMA_WORDSIZE_WORD ); // The bytes are transferred 1-by-1 on Rx Complete trigger. HAL_DMA_SET_TRIG_MODE( ch, HAL_DMA_TMODE_SINGLE_REPEATED ); HAL_DMA_SET_TRIG_SRC( ch, DMATRIG_RX ); // The source address is constant - the Rx Data Buffer. HAL_DMA_SET_SRC_INC( ch, HAL_DMA_SRCINC_0 ); // The destination address is incremented by 1 word after each transfer. HAL_DMA_SET_DST_INC( ch, HAL_DMA_DSTINC_1 ); HAL_DMA_SET_DEST( ch, dmaCfg.rxBuf ); HAL_DMA_SET_LEN( ch, HAL_UART_DMA_RX_MAX ); // The DMA is to be polled and shall not issue an IRQ upon completion. HAL_DMA_SET_IRQ( ch, HAL_DMA_IRQMASK_DISABLE ); // Xfer all 8 bits of a byte xfer. HAL_DMA_SET_M8( ch, HAL_DMA_M8_USE_8_BITS ); // DMA has highest priority for memory access. HAL_DMA_SET_PRIORITY( ch, HAL_DMA_PRI_HIGH); volatile uint8 dummy = *(volatile uint8 *)DMA_UxDBUF; // Clear the DMA Rx trigger. HAL_DMA_CLEAR_IRQ(HAL_DMA_CH_RX); HAL_DMA_ARM_CH(HAL_DMA_CH_RX); (void)memset(dmaCfg.rxBuf, (DMA_PAD ^ 0xFF), HAL_UART_DMA_RX_MAX * sizeof(uint16)); }
/************************************************************************************************** * @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 assumes DMA channel 0 is available for use. * * 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 = &dmaCh0; #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); // Tell DMA Controller where above configuration can be found HAL_DMA_SET_ADDR_DESC0(&dmaCh0); // 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 HalSpiDmaInit * * @brief This function initializes the DMA for the SPI driver. * * input parameters * * None. * * output parameters * * None. * * @return None. ************************************************************************************************** */ static void HalSpiDmaInit(void) { halDMADesc_t *ch; // Setup Tx by DMA ch = HAL_DMA_GET_DESC1234(HAL_DMA_CH_TX); // The start address of the source and destination. HAL_DMA_SET_SOURCE(ch, halSpiBuf); HAL_DMA_SET_DEST(ch, DMA_UDBUF); // Transfer the first byte + the number of bytes indicated by the first byte + 2 more bytes. HAL_DMA_SET_VLEN(ch, HAL_DMA_VLEN_1_P_VALOFFIRST_P_2); HAL_DMA_SET_LEN(ch, HAL_SPI_BUF_LEN); // One byte is transferred each time. HAL_DMA_SET_WORD_SIZE(ch, HAL_DMA_WORDSIZE_BYTE); // The bytes are transferred 1-by-1 on Tx Complete trigger. HAL_DMA_SET_TRIG_MODE(ch, HAL_DMA_TMODE_SINGLE); HAL_DMA_SET_TRIG_SRC(ch, DMATRIG_TX); // The source address is incremented by 1 byte after each transfer. HAL_DMA_SET_SRC_INC(ch, HAL_DMA_SRCINC_1); // The destination address is constant - the Tx Data Buffer. HAL_DMA_SET_DST_INC(ch, HAL_DMA_DSTINC_0); // The DMA shall issue an IRQ upon completion. HAL_DMA_SET_IRQ(ch, HAL_DMA_IRQMASK_ENABLE); // Xfer all 8 bits of a byte xfer. HAL_DMA_SET_M8(ch, HAL_DMA_M8_USE_8_BITS); // DMA has highest priority for memory access. HAL_DMA_SET_PRIORITY(ch, HAL_DMA_PRI_HIGH); ////////////////////////////////////////////////////////////////////////////// // Setup Rx by DMA. ch = HAL_DMA_GET_DESC1234(HAL_DMA_CH_RX); // The start address of the source and destination. HAL_DMA_SET_SOURCE(ch, DMA_UDBUF); HAL_DMA_SET_DEST(ch, halSpiBuf); // Transfer the first byte + the number of bytes indicated by the first byte + 2 more bytes. HAL_DMA_SET_VLEN(ch, HAL_DMA_VLEN_1_P_VALOFFIRST_P_2); HAL_DMA_SET_LEN(ch, HAL_SPI_BUF_LEN); HAL_DMA_SET_WORD_SIZE(ch, HAL_DMA_WORDSIZE_BYTE); // The bytes are transferred 1-by-1 on Rx Complete trigger. HAL_DMA_SET_TRIG_MODE(ch, HAL_DMA_TMODE_SINGLE); HAL_DMA_SET_TRIG_SRC(ch, DMATRIG_RX); // The source address is constant - the Rx Data Buffer. HAL_DMA_SET_SRC_INC(ch, HAL_DMA_SRCINC_0); // The destination address is incremented by 1 byte after each transfer. HAL_DMA_SET_DST_INC(ch, HAL_DMA_DSTINC_1); // The DMA shall issue an IRQ upon completion. HAL_DMA_SET_IRQ(ch, HAL_DMA_IRQMASK_ENABLE); // Xfer all 8 bits of a byte xfer. HAL_DMA_SET_M8(ch, HAL_DMA_M8_USE_8_BITS); // DMA has highest priority for memory access. HAL_DMA_SET_PRIORITY(ch, HAL_DMA_PRI_HIGH); }
/****************************************************************************** * @fn HalUARTInitDMA * * @brief Initialize the UART * * @param none * * @return none *****************************************************************************/ static void HalUARTInitDMA(void) { halDMADesc_t *ch; P2DIR &= ~P2DIR_PRIPO; P2DIR |= HAL_UART_PRIPO; #if (HAL_UART_DMA == 1) PERCFG &= ~HAL_UART_PERCFG_BIT; // Set UART0 I/O to Alt. 1 location on P0. #else PERCFG |= HAL_UART_PERCFG_BIT; // Set UART1 I/O to Alt. 2 location on P1. #endif PxSEL |= HAL_UART_Px_RX_TX; // Enable Tx and Rx on P1. ADCCFG &= ~HAL_UART_Px_RX_TX; // Make sure ADC doesnt use this. UxCSR = CSR_MODE; // Mode is UART Mode. UxUCR = UCR_FLUSH; // Flush it. // Setup Tx by DMA. ch = HAL_DMA_GET_DESC1234( HAL_DMA_CH_TX ); // The start address of the destination. HAL_DMA_SET_DEST( ch, DMA_UDBUF ); // Using the length field to determine how many bytes to transfer. HAL_DMA_SET_VLEN( ch, HAL_DMA_VLEN_USE_LEN ); // One byte is transferred each time. HAL_DMA_SET_WORD_SIZE( ch, HAL_DMA_WORDSIZE_BYTE ); // The bytes are transferred 1-by-1 on Tx Complete trigger. HAL_DMA_SET_TRIG_MODE( ch, HAL_DMA_TMODE_SINGLE ); HAL_DMA_SET_TRIG_SRC( ch, DMATRIG_TX ); // The source address is incremented by 1 byte after each transfer. HAL_DMA_SET_SRC_INC( ch, HAL_DMA_SRCINC_1 ); // The destination address is constant - the Tx Data Buffer. HAL_DMA_SET_DST_INC( ch, HAL_DMA_DSTINC_0 ); // The DMA Tx done is serviced by ISR in order to maintain full thruput. HAL_DMA_SET_IRQ( ch, HAL_DMA_IRQMASK_ENABLE ); // Xfer all 8 bits of a byte xfer. HAL_DMA_SET_M8( ch, HAL_DMA_M8_USE_8_BITS ); // DMA has highest priority for memory access. HAL_DMA_SET_PRIORITY( ch, HAL_DMA_PRI_HIGH ); // Setup Rx by DMA. ch = HAL_DMA_GET_DESC1234( HAL_DMA_CH_RX ); // The start address of the source. HAL_DMA_SET_SOURCE( ch, DMA_UDBUF ); // Using the length field to determine how many bytes to transfer. HAL_DMA_SET_VLEN( ch, HAL_DMA_VLEN_USE_LEN ); /* The trick is to cfg DMA to xfer 2 bytes for every 1 byte of Rx. * The byte after the Rx Data Buffer is the Baud Cfg Register, * which always has a known value. So init Rx buffer to inverse of that * known value. DMA word xfer will flip the bytes, so every valid Rx byte * in the Rx buffer will be preceded by a DMA_PAD char equal to the * Baud Cfg Register value. */ HAL_DMA_SET_WORD_SIZE( ch, HAL_DMA_WORDSIZE_WORD ); // The bytes are transferred 1-by-1 on Rx Complete trigger. HAL_DMA_SET_TRIG_MODE( ch, HAL_DMA_TMODE_SINGLE_REPEATED ); HAL_DMA_SET_TRIG_SRC( ch, DMATRIG_RX ); // The source address is constant - the Rx Data Buffer. HAL_DMA_SET_SRC_INC( ch, HAL_DMA_SRCINC_0 ); // The destination address is incremented by 1 word after each transfer. HAL_DMA_SET_DST_INC( ch, HAL_DMA_DSTINC_1 ); HAL_DMA_SET_DEST( ch, dmaCfg.rxBuf ); HAL_DMA_SET_LEN( ch, HAL_UART_DMA_RX_MAX ); // The DMA is to be polled and shall not issue an IRQ upon completion. HAL_DMA_SET_IRQ( ch, HAL_DMA_IRQMASK_DISABLE ); // Xfer all 8 bits of a byte xfer. HAL_DMA_SET_M8( ch, HAL_DMA_M8_USE_8_BITS ); // DMA has highest priority for memory access. HAL_DMA_SET_PRIORITY( ch, HAL_DMA_PRI_HIGH ); }
/****************************************************************************** * @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; }