/** **************************************************************************************** * @brief Start a data reception. * @param[in] UART QN_UART0 or QN_UART1 * @param[in,out] bufptr Pointer to the RX buffer * @param[in] size Size of the expected reception * @param[in] rx_callback Callback for end of reception * @description * This function is used to read Rx data from RX FIFO and the data will be stored in bufptr. * As soon as the end of the data transfer is detected, the callback function is executed. * ***************************************************************************************** */ void uart_read(QN_UART_TypeDef *UART, uint8_t *bufptr, uint32_t size, void (*rx_callback)(void)) { #if CONFIG_ENABLE_DRIVER_UART0==TRUE if (UART == QN_UART0) { #if UART_RX_DMA_EN==TRUE dma_rx(DMA_TRANS_BYTE, DMA_UART0_RX, (uint32_t)bufptr, size, rx_callback); #else //Store environment parameters uart0_env.rx.size = size; uart0_env.rx.bufptr = bufptr; #if UART_CALLBACK_EN==TRUE uart0_env.rx.callback = rx_callback; #endif #if CONFIG_UART0_RX_ENABLE_INTERRUPT==TRUE // Enable UART and all RX int uart_rx_int_enable(UART, MASK_ENABLE); #else // Start data transmission uart_receive_data(UART, &uart0_env); #endif #endif } #endif #if CONFIG_ENABLE_DRIVER_UART1==TRUE if (UART == QN_UART1) { #if UART_RX_DMA_EN==TRUE dma_rx(DMA_TRANS_BYTE, DMA_UART1_RX, (uint32_t)bufptr, size, rx_callback); #else //Store environment parameters uart1_env.rx.size = size; uart1_env.rx.bufptr = bufptr; #if UART_CALLBACK_EN==TRUE uart1_env.rx.callback = rx_callback; #endif #if CONFIG_UART1_RX_ENABLE_INTERRUPT==TRUE // Enable UART and all RX int uart_rx_int_enable(UART, MASK_ENABLE); #else // Start data transmission uart_receive_data(UART, &uart1_env); #endif #endif } #endif }
/** **************************************************************************************** * @brief Proprietary mode receive * @param[in] ble_ch_idx Channel frequency index * Get this parameter from rf_freq_tab[](in file qnrf.c) accroding to the frequency * chosen * @param[in] aa_buf Access address buffer, own device address * @param[in] aa_num Access address length * @param[in] data_buf Receive data buffer * @param[in] data_len Receive data length * @param[in] tx_callback Called after receive complete ***************************************************************************************** */ void prop_mode_rx(uint32_t ble_ch_idx, uint8_t *aa_buf, enum PROP_AA_NUM aa_num, uint8_t *data_buf, uint16_t data_len) { /* Wait for last transfer complete */ while(dp_dp_GetReg(0x38)& DP_MASK_TX_BUSY); /* Channel configure */ rf_set_freq(RF_RX_IMR0, ble_ch_idx); /* Access Address and Payload length, Note: Payload length in bit */ dp_dp_SetRegWithMask(0x00, DP_MASK_RX_PDU_LEN_IN, data_len << 3); dp_dp_SetRegWithMask(0x04, (DP_MASK_PROP_AA_NUM | DP_MASK_PROP_AA_ADDR_IN), (aa_num << DP_POS_PROP_AA_NUM) | (aa_buf[4])); dp_dp_SetReg(0x08, *(uint32_t *)aa_buf); /* Enable transmit request */ dp_dp_SetRegWithMask(0x00, DP_MASK_RX_REQ, 0); dp_dp_SetRegWithMask(0x00, DP_MASK_RX_REQ, DP_MASK_RX_REQ); //Wait for ready(40us) delay(70); /* Receive pack by DMA */ prop_ctrl_reset(); dma_rx(DMA_TRANS_BYTE, DMA_PROP_RX, (uint32_t)data_buf, data_len, NULL); /* Wait for transfer complete */ while(!(dma_dma_GetIntStatus(QN_DMA) & DMA_MASK_DONE)); dma_dma_ClrIntStatus(QN_DMA, DMA_MASK_DONE); }
static int BCMFASTPATH chiprxquota(ch_t *ch, int quota, void **rxpkts) { int rxcnt; void * pkt; uint8 * addr; ET_TRACE(("et%d: chiprxquota\n", ch->etc->unit)); ET_LOG("et%d: chiprxquota", ch->etc->unit, 0); rxcnt = 0; while ((quota > 0) && ((pkt = dma_rx(ch->di)) != NULL)) { addr = PKTDATA(ch->osh, pkt); #if !defined(_CFE_) bcm_prefetch_32B(addr + 32, 1); #endif /* _CFE_ */ rxpkts[rxcnt] = pkt; rxcnt++; quota--; } if (rxcnt < quota) { /* ring is "possibly" empty, enable et interrupts */ ch->intstatus &= ~I_RI; } return rxcnt; /* rxpkts[] has rxcnt number of pkts to be processed */ }
/* dma receive: returns a pointer to the next frame received, or NULL if there are no more */ static void * BCMFASTPATH chiprx(struct bcm4xxx *ch) { void *p; ET_TRACE(("et%d: chiprx\n", ch->etc->unit)); ET_LOG("et%d: chiprx", ch->etc->unit, 0); if ((p = dma_rx(ch->di)) == NULL) ch->intstatus &= ~I_RI; return (p); }
void b43_dma_rx(struct b43_dmaring *ring) { const struct b43_dma_ops *ops = ring->ops; int slot, current_slot; int used_slots = 0; B43_WARN_ON(ring->tx); current_slot = ops->get_current_rxslot(ring); B43_WARN_ON(!(current_slot >= 0 && current_slot < ring->nr_slots)); slot = ring->current_slot; for (; slot != current_slot; slot = next_slot(ring, slot)) { dma_rx(ring, &slot); update_max_used_slots(ring, ++used_slots); } wmb(); ops->set_current_rxslot(ring, slot); ring->current_slot = slot; }
/** **************************************************************************************** * @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 }
/** **************************************************************************************** * @brief Start a data reception. * @param[in] SPI QN_SPI0 or QN_SPI1 * @param[in,out] bufptr Pointer to the RX data buffer * @param[in] size Size of the expected reception, must be multiple of 4 at 32bit mode * @param[in] rx_callback Callback for end of reception * @description * This function is used to read Rx data from RX FIFO and the data will be stored in bufptr. * As soon as the end of the data transfer or a buffer overflow is detected, the callback function is called. * ***************************************************************************************** */ void spi_read(QN_SPI_TypeDef * SPI, uint8_t *bufptr, int32_t size, void (*rx_callback)(void)) { #if SPI_RX_DMA_EN==TRUE enum DMA_TRANS_MODE trans_mod; #endif // option: clear RX buffer //spi_spi_SetCR1(SPI, SPI_MASK_RX_FIFO_CLR); #if CONFIG_ENABLE_DRIVER_SPI0==TRUE if (SPI == QN_SPI0) { #if SPI0_MOD_3WIRE_EN==TRUE if (spi0_env.mode == SPI_MASTER_MOD) { spi_spi_SetCR1WithMask(QN_SPI0, SPI_MASK_M_SDIO_EN, MASK_DISABLE); } else { spi_spi_SetCR1WithMask(QN_SPI0, SPI_MASK_S_SDIO_EN, MASK_DISABLE); } #endif #if SPI_RX_DMA_EN==TRUE if (spi0_env.width == SPI_8BIT) { trans_mod = DMA_TRANS_BYTE; } else { trans_mod = DMA_TRANS_WORD; } dma_rx(trans_mod, DMA_SPI0_RX, (uint32_t)bufptr, size, rx_callback); #else //Store environment parameters spi0_env.rx.bufptr = bufptr; spi0_env.rx.size = size; #if SPI_CALLBACK_EN==TRUE spi0_env.rx.callback = rx_callback; #endif #if CONFIG_SPI0_RX_ENABLE_INTERRUPT==TRUE #else // Start data reception spi_receive_data(SPI, (struct spi_env_tag *)&spi0_env); #endif #endif } #endif #if CONFIG_ENABLE_DRIVER_SPI1==TRUE if (SPI == QN_SPI1) { #if SPI1_MOD_3WIRE_EN==TRUE if (spi1_env.mode == SPI_MASTER_MOD) { spi_spi_SetCR1WithMask(QN_SPI1, SPI_MASK_M_SDIO_EN, MASK_DISABLE); } else { spi_spi_SetCR1WithMask(QN_SPI1, SPI_MASK_S_SDIO_EN, MASK_DISABLE); } #endif #if SPI_RX_DMA_EN==TRUE if (spi1_env.width == SPI_8BIT) { trans_mod = DMA_TRANS_BYTE; } else { trans_mod = DMA_TRANS_WORD; } dma_rx(trans_mod, DMA_SPI1_RX, (uint32_t)bufptr, size, rx_callback); #else //Store environment parameters spi1_env.rx.bufptr = bufptr; spi1_env.rx.size = size; #if SPI_CALLBACK_EN==TRUE spi1_env.rx.callback = rx_callback; #endif #if CONFIG_SPI1_RX_ENABLE_INTERRUPT==TRUE #else // Start data reception spi_receive_data(SPI, (struct spi_env_tag *)&spi1_env); #endif #endif } #endif }