/** **************************************************************************************** * @brief DMA form peripheral to peripheral * @param[in] src_index source peripheral index * @param[in] dst_index destination peripheral index * @param[in] size size of transfer * @param[in] trans_callback callback after transfer finish * @description * This function is used to transfer data from peripheral to peripheral by DMA. **************************************************************************************** */ void dma_transfer(enum DMA_PERIPHERAL_RX src_index, enum DMA_PERIPHERAL_TX dst_index, uint32_t size, void (*trans_callback)(void)) { uint32_t mask, reg; #if DMA_CALLBACK_EN==TRUE dma_env.callback = trans_callback; #endif dma_dma_SetSRC(QN_DMA, peripheral_src[src_index]); dma_dma_SetDST(QN_DMA, peripheral_dst[dst_index]); dev_prevent_sleep(PM_MASK_DMA_ACTIVE_BIT); mask = ~DMA_MASK_ALL_INT_EN; reg = (size << DMA_POS_TRANS_SIZE) /* dma transfer size */ | (src_index << DMA_POS_SRC_MUX) /* select src peripheral */ | (dst_index << DMA_POS_DST_MUX) /* select dst peripheral */ | (DMA_TRANS_WORD << DMA_POS_TRANS_MODE) /* transfer mode */ | DMA_MASK_SRC_REQ_EN | DMA_MASK_SRC_ADDR_FIX /* fix src address */ | DMA_MASK_DST_REQ_EN | DMA_MASK_DST_ADDR_FIX /* fix dst address */ #if DMA_UNDEFINE_LENGTH_EN==TRUE | DMA_MASK_SRC_UDLEN #endif | DMA_MASK_START; /* enable dma */ dma_dma_SetCRWithMask(QN_DMA, mask, reg); }
static int app_rco_cal_timer_handler(ke_msg_id_t const msgid, void const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { clock_32k_correction_enable(clock_32k_correction_cb); dev_prevent_sleep(PM_MASK_TIMER1_ACTIVE_BIT); ke_timer_set(APP_SYS_RCO_CAL_TIMER, TASK_APP, 100); return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief DMA memory copy * @param[in] src_addr source start address * @param[in] dst_addr destination start address * @param[in] size size of transfer * @param[in] callback callback after transfer * @description * This function is used to transfer data from memory to memory by DMA. **************************************************************************************** */ void dma_memory_copy (uint32_t src_addr, uint32_t dst_addr, uint32_t size, void (*callback)(void)) { uint32_t mask, reg; #if DMA_CALLBACK_EN==TRUE dma_env.callback = callback; #endif dma_dma_SetSRC(QN_DMA, src_addr); dma_dma_SetDST(QN_DMA, dst_addr); dev_prevent_sleep(PM_MASK_DMA_ACTIVE_BIT); mask = ~DMA_MASK_ALL_INT_EN; reg = (size << DMA_POS_TRANS_SIZE) /* dma transfer size */ | DMA_MASK_START; /* enable dma */ dma_dma_SetCRWithMask(QN_DMA, mask, reg); }
/** **************************************************************************************** * @brief DMA form fix to memory * @param[in] mode transfer mode: byte, half word, word * @param[in] src_index source peripheral index * @param[in] dst_addr destination address * @param[in] size size of transfer, the max size is 0x7FF * @param[in] rx_callback callback after transfer * @description * This function is used to transfer data from peripheral to memory by DMA. **************************************************************************************** */ void dma_rx(enum DMA_TRANS_MODE mode, enum DMA_PERIPHERAL_RX src_index, uint32_t dst_addr, uint32_t size, void (*rx_callback)(void)) { uint32_t mask, reg; #if DMA_CALLBACK_EN==TRUE dma_env.callback = rx_callback; #endif dma_dma_SetSRC(QN_DMA, peripheral_src[src_index]); dma_dma_SetDST(QN_DMA, dst_addr); #if UART_RX_DMA_EN==FALSE dev_prevent_sleep(PM_MASK_DMA_ACTIVE_BIT); #endif mask = ~DMA_MASK_ALL_INT_EN; reg = (size << DMA_POS_TRANS_SIZE) /* dma transfer size */ | (src_index << DMA_POS_SRC_MUX) /* select src peripheral */ | (mode << DMA_POS_TRANS_MODE) /* transfer mode */ | DMA_MASK_SRC_REQ_EN | DMA_MASK_SRC_ADDR_FIX /* fix src address */ | DMA_MASK_START; /* enable dma */ dma_dma_SetCRWithMask(QN_DMA, mask, reg); }
/** **************************************************************************************** * @brief Read ADC conversion result * @param[in] S ADC read configuration, contains work mode, trigger source, start/end channel * @param[in] buf ADC result buffer * @param[in] samples Sample number * @param[in] callback callback after all the samples conversion finish * @description * This function is used to read ADC specified channel conversion result. * @note * When use scaning mode, only can select first 6 channel (AIN0,AIN1,AIN2,AIN3,AIN01,AIN23) ***************************************************************************************** */ void adc_read(const adc_read_configuration *S, int16_t *buf, uint32_t samples, void (*callback)(void)) { uint32_t reg; uint32_t mask; int i = 0; adc_env.mode = S->mode; adc_env.trig_src = S->trig_src; adc_env.start_ch = S->start_ch; adc_env.end_ch = S->end_ch; adc_env.bufptr = buf; adc_env.samples = samples; adc_env.callback = callback; // Busrt scan mode, need read all of the channel after once trigger if (S->mode == SINGLE_SCAN_MOD) { scan_ch_num = S->end_ch - S->start_ch + 1; } else { scan_ch_num = 1; } #if (CONFIG_ADC_ENABLE_INTERRUPT==FALSE) && (ADC_DMA_EN==TRUE) dma_init(); // samples*2 <= 0x7FF dma_rx(DMA_TRANS_HALF_WORD, DMA_ADC, (uint32_t)buf, samples*2, callback); #endif mask = ADC_MASK_SCAN_CH_START | ADC_MASK_SCAN_CH_END | ADC_MASK_SCAN_INTV | ADC_MASK_SCAN_EN | ADC_MASK_SINGLE_EN | ADC_MASK_START_SEL | ADC_MASK_SFT_START | ADC_MASK_POW_UP_DLY | ADC_MASK_POW_DN_CTRL | ADC_MASK_ADC_EN; reg = (S->start_ch << ADC_POS_SCAN_CH_START) // set adc channel, or set scan start channel | (S->end_ch << ADC_POS_SCAN_CH_END) // set scan end channel | (0x03 << ADC_POS_SCAN_INTV) // should not be set to 0 at single mode | (S->trig_src << ADC_POS_START_SEL) // select ADC trigger source | (0x3F << ADC_POS_POW_UP_DLY) // power up delay | ADC_MASK_POW_DN_CTRL // enable power down control by hardware, only work in single mode | ADC_MASK_ADC_EN; // enable ADC if ((S->mode == SINGLE_SCAN_MOD) || (S->mode == SINGLE_MOD)) { // default is continue reg |= ADC_MASK_SINGLE_EN; // single mode enable } if ((S->mode == SINGLE_SCAN_MOD) || (S->mode == CONTINUE_SCAN_MOD)) { // default is not scan reg |= ADC_MASK_SCAN_EN; // scan mode enable } adc_adc_SetADC0WithMask(QN_ADC, mask, reg); if (adc_env.trig_src == ADC_TRIG_SOFT) { // SFT_START 0->1 trigger ADC conversion adc_adc_SetADC0WithMask(QN_ADC, ADC_MASK_SFT_START, MASK_ENABLE); } #if CONFIG_ADC_ENABLE_INTERRUPT==TRUE dev_prevent_sleep(PM_MASK_ADC_ACTIVE_BIT); #elif (CONFIG_ADC_ENABLE_INTERRUPT==FALSE) && (ADC_DMA_EN==FALSE) // polling while(samples > 0) { for (i = 0; ((i < scan_ch_num)&&(samples)); i++) { while(!(adc_adc_GetSR(QN_ADC) & ADC_MASK_DAT_RDY_IF)); *buf++ = adc_adc_GetDATA(QN_ADC); samples--; } // Single mode enable, software trigger if ( (samples) && (adc_env.trig_src == ADC_TRIG_SOFT) && ((S->mode == SINGLE_SCAN_MOD)||(S->mode == SINGLE_MOD))) { // SFT_START 0->1 trigger ADC conversion adc_adc_SetADC0WithMask(QN_ADC, ADC_MASK_SFT_START, MASK_DISABLE); adc_adc_SetADC0WithMask(QN_ADC, ADC_MASK_SFT_START, MASK_ENABLE); } } // disable ADC adc_enable(MASK_DISABLE); adc_clean_fifo(); #if ADC_CALLBACK_EN==TRUE if (callback != NULL) { callback(); } #endif #endif }