/** * @brief Set the callback function pointer for an Interrupt. * * @param dev UART device structure * @param cb Callback function pointer. * * @return N/A */ static void uart_cmsdk_apb_irq_callback_set(struct device *dev, uart_irq_callback_user_data_t cb, void *cb_data) { DEV_DATA(dev)->irq_cb = cb; DEV_DATA(dev)->irq_cb_data = cb_data; }
static int entropy_nrf5_get_entropy(struct device *device, u8_t *buf, u16_t len) { /* Mark the peripheral as being used */ atomic_inc(&DEV_DATA(device)->user_count); /* Disable the shortcut that stops the task after a byte is generated */ nrf_rng_shorts_disable(NRF_RNG_SHORT_VALRDY_STOP_MASK); /* Start the RNG generator peripheral */ nrf_rng_task_trigger(NRF_RNG_TASK_START); while (len) { *buf = entropy_nrf5_get_u8(); buf++; len--; } /* Only stop the RNG generator peripheral if we're the last user */ if (atomic_dec(&DEV_DATA(device)->user_count) == 1) { /* Disable the peripheral on the next VALRDY event */ nrf_rng_shorts_enable(NRF_RNG_SHORT_VALRDY_STOP_MASK); if (atomic_get(&DEV_DATA(device)->user_count) != 0) { /* Race condition: another thread started to use * the peripheral while we were disabling it. * Enable the peripheral again */ nrf_rng_shorts_disable(NRF_RNG_SHORT_VALRDY_STOP_MASK); nrf_rng_task_trigger(NRF_RNG_TASK_START); } } return 0; }
/** * @brief Initialize UART channel * * This routine is called to reset the chip in a quiescent state. * It is assumed that this function is called only once per UART. * * @param dev UART device struct * * @return 0 on success */ static int uart_nrf5_init(struct device *dev) { volatile struct _uart *uart = UART_STRUCT(dev); struct device *gpio_dev; gpio_dev = device_get_binding(CONFIG_GPIO_NRF5_P0_DEV_NAME); (void) gpio_pin_configure(gpio_dev, CONFIG_UART_NRF5_GPIO_TX_PIN, (GPIO_DIR_OUT | GPIO_PUD_PULL_UP)); (void) gpio_pin_configure(gpio_dev, CONFIG_UART_NRF5_GPIO_RX_PIN, (GPIO_DIR_IN)); uart->PSELTXD = CONFIG_UART_NRF5_GPIO_TX_PIN; uart->PSELRXD = CONFIG_UART_NRF5_GPIO_RX_PIN; #ifdef CONFIG_UART_NRF5_FLOW_CONTROL (void) gpio_pin_configure(gpio_dev, CONFIG_UART_NRF5_GPIO_RTS_PIN, (GPIO_DIR_OUT | GPIO_PUD_PULL_UP)); (void) gpio_pin_configure(gpio_dev, CONFIG_UART_NRF5_GPIO_CTS_PIN, (GPIO_DIR_IN)); uart->PSELRTS = CONFIG_UART_NRF5_GPIO_RTS_PIN; uart->PSELCTS = CONFIG_UART_NRF5_GPIO_CTS_PIN; uart->CONFIG = (UART_CONFIG_HWFC_Enabled << UART_CONFIG_HWFC_Pos); #endif /* CONFIG_UART_NRF5_FLOW_CONTROL */ DEV_DATA(dev)->baud_rate = CONFIG_UART_NRF5_BAUD_RATE; DEV_CFG(dev)->sys_clk_freq = CONFIG_UART_NRF5_CLK_FREQ; /* Set baud rate */ baudrate_set(dev, DEV_DATA(dev)->baud_rate, DEV_CFG(dev)->sys_clk_freq); /* Enable receiver and transmitter */ uart->ENABLE = (UART_ENABLE_ENABLE_Enabled << UART_ENABLE_ENABLE_Pos); uart->EVENTS_TXDRDY = 0; uart->EVENTS_RXDRDY = 0; uart->TASKS_STARTTX = 1; uart->TASKS_STARTRX = 1; dev->driver_api = &uart_nrf5_driver_api; #ifdef CONFIG_UART_INTERRUPT_DRIVEN DEV_CFG(dev)->irq_config_func(dev); #endif return 0; }
static void sam_xdmac_isr(void *arg) { struct device *dev = (struct device *)arg; const struct sam_xdmac_dev_cfg *const dev_cfg = DEV_CFG(dev); struct sam_xdmac_dev_data *const dev_data = DEV_DATA(dev); Xdmac *const xdmac = dev_cfg->regs; struct sam_xdmac_channel_cfg *channel_cfg; u32_t isr_status; u32_t err; /* Get global interrupt status */ isr_status = xdmac->XDMAC_GIS; for (int channel = 0; channel < DMA_CHANNELS_NO; channel++) { if (!(isr_status & (1 << channel))) { continue; } channel_cfg = &dev_data->dma_channels[channel]; /* Get channel errors */ err = xdmac->XDMAC_CHID[channel].XDMAC_CIS & XDMAC_INT_ERR; /* Execute callback */ if (channel_cfg->callback) { channel_cfg->callback(dev, channel, err); } } }
static inline void set_dlf(struct device *dev, u32_t val) { struct uart_ns16550_dev_data_t * const dev_data = DEV_DATA(dev); OUTBYTE(DLF(dev), val); dev_data->dlf = val; }
static int i2c_mcux_init(struct device *dev) { I2C_Type *base = DEV_BASE(dev); const struct i2c_mcux_config *config = DEV_CFG(dev); struct i2c_mcux_data *data = DEV_DATA(dev); u32_t clock_freq, bitrate_cfg; i2c_master_config_t master_config; int error; k_sem_init(&data->device_sync_sem, 0, UINT_MAX); clock_freq = CLOCK_GetFreq(config->clock_source); I2C_MasterGetDefaultConfig(&master_config); I2C_MasterInit(base, &master_config, clock_freq); I2C_MasterTransferCreateHandle(base, &data->handle, i2c_mcux_master_transfer_callback, dev); bitrate_cfg = _i2c_map_dt_bitrate(config->bitrate); error = i2c_mcux_configure(dev, I2C_MODE_MASTER | bitrate_cfg); if (error) { return error; } config->irq_config_func(dev); return 0; }
/** * @brief Initialize UART channel * * This routine is called to reset the chip in a quiescent state. * It is assumed that this function is called only once per UART. * * @param dev UART device struct * * @return 0 */ static int uart_stm32_init(struct device *dev) { const struct uart_stm32_config *config = DEV_CFG(dev); struct uart_stm32_data *data = DEV_DATA(dev); UART_HandleTypeDef *UartHandle = &data->huart; __uart_stm32_get_clock(dev); /* enable clock */ #if defined(CONFIG_SOC_SERIES_STM32F1X) || defined(CONFIG_SOC_SERIES_STM32L4X) clock_control_on(data->clock, config->clock_subsys); #elif defined(CONFIG_SOC_SERIES_STM32F4X) clock_control_on(data->clock, (clock_control_subsys_t *)&config->pclken); #endif UartHandle->Instance = UART_STRUCT(dev); UartHandle->Init.WordLength = UART_WORDLENGTH_8B; UartHandle->Init.StopBits = UART_STOPBITS_1; UartHandle->Init.Parity = UART_PARITY_NONE; UartHandle->Init.HwFlowCtl = UART_HWCONTROL_NONE; UartHandle->Init.Mode = UART_MODE_TX_RX; UartHandle->Init.OverSampling = UART_OVERSAMPLING_16; HAL_UART_Init(UartHandle); #ifdef CONFIG_UART_INTERRUPT_DRIVEN config->uconf.irq_config_func(dev); #endif return 0; }
static int uart_stm32_irq_is_pending(struct device *dev) { struct uart_stm32_data *data = DEV_DATA(dev); UART_HandleTypeDef *UartHandle = &data->huart; return __HAL_UART_GET_FLAG(UartHandle, UART_FLAG_TXE | UART_FLAG_RXNE); }
static void uart_stm32_irq_tx_enable(struct device *dev) { struct uart_stm32_data *data = DEV_DATA(dev); UART_HandleTypeDef *UartHandle = &data->huart; __HAL_UART_ENABLE_IT(UartHandle, UART_IT_TC); }
static void uart_sam_irq_callback_set(struct device *dev, uart_irq_callback_t cb) { struct uart_sam_dev_data *const dev_data = DEV_DATA(dev); dev_data->irq_cb = cb; }
/** * @brief Initialize UART channel * * This routine is called to reset the chip in a quiescent state. * It is assumed that this function is called only once per UART. * * @param dev UART device struct * * @return 0 */ static int uart_cmsdk_apb_init(struct device *dev) { volatile struct uart_cmsdk_apb *uart = UART_STRUCT(dev); #ifdef CONFIG_UART_INTERRUPT_DRIVEN const struct uart_device_config * const dev_cfg = DEV_CFG(dev); #endif #ifdef CONFIG_CLOCK_CONTROL /* Enable clock for subsystem */ struct device *clk = device_get_binding(CONFIG_ARM_CLOCK_CONTROL_DEV_NAME); struct uart_cmsdk_apb_dev_data * const data = DEV_DATA(dev); #ifdef CONFIG_SOC_SERIES_BEETLE clock_control_on(clk, (clock_control_subsys_t *) &data->uart_cc_as); clock_control_on(clk, (clock_control_subsys_t *) &data->uart_cc_ss); clock_control_on(clk, (clock_control_subsys_t *) &data->uart_cc_dss); #endif /* CONFIG_SOC_SERIES_BEETLE */ #endif /* CONFIG_CLOCK_CONTROL */ /* Set baud rate */ baudrate_set(dev); /* Enable receiver and transmitter */ uart->ctrl = UART_RX_EN | UART_TX_EN; #ifdef CONFIG_UART_INTERRUPT_DRIVEN dev_cfg->irq_config_func(dev); #endif return 0; }
static int i2s_stm32_initialize(struct device *dev) { const struct i2s_stm32_cfg *cfg = DEV_CFG(dev); struct i2s_stm32_data *const dev_data = DEV_DATA(dev); int ret, i; /* Enable I2S clock propagation */ ret = i2s_stm32_enable_clock(dev); if (ret < 0) { LOG_ERR("%s: clock enabling failed: %d", __func__, ret); return -EIO; } cfg->irq_config(dev); k_sem_init(&dev_data->rx.sem, 0, CONFIG_I2S_STM32_RX_BLOCK_COUNT); k_sem_init(&dev_data->tx.sem, CONFIG_I2S_STM32_TX_BLOCK_COUNT, CONFIG_I2S_STM32_TX_BLOCK_COUNT); for (i = 0; i < STM32_DMA_NUM_CHANNELS; i++) { active_dma_rx_channel[i] = NULL; active_dma_tx_channel[i] = NULL; } /* Get the binding to the DMA device */ dev_data->dev_dma = device_get_binding(dev_data->dma_name); if (!dev_data->dev_dma) { LOG_ERR("%s device not found", dev_data->dma_name); return -ENODEV; } LOG_INF("%s inited", dev->config->name); return 0; }
static int i2s_stm32_read(struct device *dev, void **mem_block, size_t *size) { struct i2s_stm32_data *const dev_data = DEV_DATA(dev); int ret; if (dev_data->rx.state == I2S_STATE_NOT_READY) { LOG_DBG("invalid state"); return -EIO; } if (dev_data->rx.state != I2S_STATE_ERROR) { ret = k_sem_take(&dev_data->rx.sem, dev_data->rx.cfg.timeout); if (ret < 0) { return ret; } } /* Get data from the beginning of RX queue */ ret = queue_get(&dev_data->rx.mem_block_queue, mem_block, size); if (ret < 0) { return -EIO; } return 0; }
static int adc_sam_initialize(struct device *dev) { const struct adc_sam_dev_cfg *dev_cfg = DEV_CFG(dev); struct adc_sam_dev_data *const dev_data = DEV_DATA(dev); /* Initialize semaphores */ k_sem_init(&dev_data->sem_meas, 0, 1); k_sem_init(&dev_data->mutex_thread, 1, 1); /* Configure interrupts */ dev_cfg->irq_config(); /* Enable module's clock */ soc_pmc_peripheral_enable(dev_cfg->periph_id); /* Configure ADC */ adc_sam_configure(dev); /* Enable module interrupt */ irq_enable(dev_cfg->irq_id); SYS_LOG_INF("Device %s initialized", DEV_NAME(dev)); return 0; }
u16_t sw_filter_lib_init(struct device *dev, struct dmic_cfg *cfg) { struct mpxxdtyy_data *const data = DEV_DATA(dev); TPDMFilter_InitStruct *pdm_filter = &data->pdm_filter; u16_t factor; u32_t audio_freq = cfg->streams->pcm_rate; /* calculate oversampling factor based on pdm clock */ for (factor = 64; factor <= 128; factor += 64) { u32_t pdm_bit_clk = (audio_freq * factor * cfg->channel.req_num_chan); if (pdm_bit_clk >= cfg->io.min_pdm_clk_freq && pdm_bit_clk <= cfg->io.max_pdm_clk_freq) { break; } } if (factor != 64 && factor != 128) { return 0; } /* init the filter lib */ pdm_filter->LP_HZ = audio_freq / 2; pdm_filter->HP_HZ = 10; pdm_filter->Fs = audio_freq; pdm_filter->Out_MicChannels = 1; pdm_filter->In_MicChannels = 1; pdm_filter->Decimation = factor; pdm_filter->MaxVolume = 64; Open_PDM_Filter_Init(pdm_filter); return factor; }
static int wpanusb_init(struct device *dev) { struct wpanusb_dev_data_t * const dev_data = DEV_DATA(dev); int ret; SYS_LOG_DBG(""); wpanusb_config.interface.payload_data = dev_data->interface_data; wpanusb_dev = dev; /* Initialize the USB driver with the right configuration */ ret = usb_set_config(&wpanusb_config); if (ret < 0) { SYS_LOG_ERR("Failed to configure USB"); return ret; } /* Enable USB driver */ ret = usb_enable(&wpanusb_config); if (ret < 0) { SYS_LOG_ERR("Failed to enable USB"); return ret; } return 0; }
int i2c_stm32_runtime_configure(struct device *dev, u32_t config) { const struct i2c_stm32_config *cfg = DEV_CFG(dev); struct i2c_stm32_data *data = DEV_DATA(dev); I2C_TypeDef *i2c = cfg->i2c; u32_t clock = 0U; int ret; #if defined(CONFIG_SOC_SERIES_STM32F3X) || defined(CONFIG_SOC_SERIES_STM32F0X) LL_RCC_ClocksTypeDef rcc_clocks; /* * STM32F0/3 I2C's independent clock source supports only * HSI and SYSCLK, not APB1. We force clock variable to * SYSCLK frequency. */ LL_RCC_GetSystemClocksFreq(&rcc_clocks); clock = rcc_clocks.SYSCLK_Frequency; #else clock_control_get_rate(device_get_binding(STM32_CLOCK_CONTROL_NAME), (clock_control_subsys_t *) &cfg->pclken, &clock); #endif /* CONFIG_SOC_SERIES_STM32F3X) || CONFIG_SOC_SERIES_STM32F0X */ data->dev_config = config; k_sem_take(&data->bus_mutex, K_FOREVER); LL_I2C_Disable(i2c); LL_I2C_SetMode(i2c, LL_I2C_MODE_I2C); ret = stm32_i2c_configure_timing(dev, clock); k_sem_give(&data->bus_mutex); return ret; }
void rtc_stm32_isr(void *arg) { struct device *const dev = (struct device *)arg; if (LL_RTC_IsActiveFlag_ALRA(RTC) != 0) { if (DEV_DATA(dev)->cb_fn != NULL) { DEV_DATA(dev)->cb_fn(dev); } LL_RTC_ClearFlag_ALRA(RTC); LL_RTC_DisableIT_ALRA(RTC); } LL_EXTI_ClearFlag_0_31(EXTI_LINE); }
static int uart_stm32_fifo_read(struct device *dev, uint8_t *rx_data, const int size) { struct uart_stm32_data *data = DEV_DATA(dev); UART_HandleTypeDef *UartHandle = &data->huart; uint8_t num_rx = 0; while ((size - num_rx > 0) && __HAL_UART_GET_FLAG(UartHandle, UART_FLAG_RXNE)) { /* Clear the interrupt */ __HAL_UART_CLEAR_FLAG(UartHandle, UART_FLAG_RXNE); /* Receive a character (8bit , parity none) */ #if defined(CONFIG_SOC_SERIES_STM32F1X) || defined(CONFIG_SOC_SERIES_STM32F4X) /* Use direct access for F1, F4 until Low Level API is available * Once it is we can remove the if/else */ rx_data[num_rx++] = (uint8_t)(UartHandle->Instance->DR & (uint8_t)0x00FF); #else rx_data[num_rx++] = LL_USART_ReceiveData8(UartHandle->Instance); #endif } return num_rx; }
static int entropy_nrf5_get_entropy(struct device *device, u8_t *buf, u16_t len) { /* Check if this API is called on correct driver instance. */ __ASSERT_NO_MSG(&entropy_nrf5_data == DEV_DATA(device)); while (len) { u16_t bytes; k_sem_take(&entropy_nrf5_data.sem_lock, K_FOREVER); bytes = rng_pool_get((struct rng_pool *)(entropy_nrf5_data.thr), buf, len); k_sem_give(&entropy_nrf5_data.sem_lock); if (bytes == 0) { /* Pool is empty: Sleep until next interrupt. */ k_sem_take(&entropy_nrf5_data.sem_sync, K_FOREVER); continue; } len -= bytes; buf += bytes; } return 0; }
static void uart_stm32_irq_rx_disable(struct device *dev) { struct uart_stm32_data *data = DEV_DATA(dev); UART_HandleTypeDef *UartHandle = &data->huart; __HAL_UART_DISABLE_IT(UartHandle, UART_IT_RXNE); }
static int entropy_nrf5_init(struct device *device) { /* Check if this API is called on correct driver instance. */ __ASSERT_NO_MSG(&entropy_nrf5_data == DEV_DATA(device)); /* Locking semaphore initialized to 1 (unlocked) */ k_sem_init(&entropy_nrf5_data.sem_lock, 1, 1); /* Synching semaphore */ k_sem_init(&entropy_nrf5_data.sem_sync, 0, 1); rng_pool_init((struct rng_pool *)(entropy_nrf5_data.thr), CONFIG_ENTROPY_NRF5_THR_POOL_SIZE, CONFIG_ENTROPY_NRF5_THR_THRESHOLD); rng_pool_init((struct rng_pool *)(entropy_nrf5_data.isr), CONFIG_ENTROPY_NRF5_ISR_POOL_SIZE, CONFIG_ENTROPY_NRF5_ISR_THRESHOLD); /* Enable or disable bias correction */ if (IS_ENABLED(CONFIG_ENTROPY_NRF5_BIAS_CORRECTION)) { nrf_rng_error_correction_enable(); } else { nrf_rng_error_correction_disable(); } nrf_rng_event_clear(NRF_RNG_EVENT_VALRDY); nrf_rng_int_enable(NRF_RNG_INT_VALRDY_MASK); nrf_rng_task_trigger(NRF_RNG_TASK_START); IRQ_CONNECT(RNG_IRQn, CONFIG_ENTROPY_NRF5_PRI, isr, &entropy_nrf5_data, 0); irq_enable(RNG_IRQn); return 0; }
static void uart_stm32_irq_callback_set(struct device *dev, uart_irq_callback_t cb) { struct uart_stm32_data *data = DEV_DATA(dev); data->user_cb = cb; }
int i2c_stm32_slave_unregister(struct device *dev, struct i2c_slave_config *config) { const struct i2c_stm32_config *cfg = DEV_CFG(dev); struct i2c_stm32_data *data = DEV_DATA(dev); I2C_TypeDef *i2c = cfg->i2c; if (!data->slave_attached) { return -EINVAL; } if (data->master_active) { return -EBUSY; } LL_I2C_DisableOwnAddress1(i2c); LL_I2C_DisableIT_ADDR(i2c); stm32_i2c_disable_transfer_interrupts(dev); LL_I2C_ClearFlag_NACK(i2c); LL_I2C_ClearFlag_STOP(i2c); LL_I2C_ClearFlag_ADDR(i2c); LL_I2C_Disable(i2c); SYS_LOG_DBG("i2c: slave unregistered"); return 0; }
static int uart_stm32_fifo_fill(struct device *dev, const uint8_t *tx_data, int size) { struct uart_stm32_data *data = DEV_DATA(dev); UART_HandleTypeDef *UartHandle = &data->huart; uint8_t num_tx = 0; while ((size - num_tx > 0) && __HAL_UART_GET_FLAG(UartHandle, UART_FLAG_TXE)) { /* TXE flag will be cleared with byte write to DR register */ /* Send a character (8bit , parity none) */ #if defined(CONFIG_SOC_SERIES_STM32F1X) || defined(CONFIG_SOC_SERIES_STM32F4X) /* Use direct access for F1, F4 until Low Level API is available * Once it is we can remove the if/else */ UartHandle->Instance->DR = (tx_data[num_tx++] & (uint8_t)0x00FF); #else LL_USART_TransmitData8(UartHandle->Instance, tx_data[num_tx++]); #endif } return num_tx; }
static int stm32_i2c_error(struct device *dev) { const struct i2c_stm32_config *cfg = DEV_CFG(dev); struct i2c_stm32_data *data = DEV_DATA(dev); I2C_TypeDef *i2c = cfg->i2c; #if defined(CONFIG_I2C_SLAVE) if (data->slave_attached && !data->master_active) { /* No need for a slave error function right now. */ return 0; } #endif if (LL_I2C_IsActiveFlag_ARLO(i2c)) { LL_I2C_ClearFlag_ARLO(i2c); data->current.is_arlo = 1; goto end; } if (LL_I2C_IsActiveFlag_BERR(i2c)) { LL_I2C_ClearFlag_BERR(i2c); data->current.is_err = 1; goto end; } return 0; end: stm32_i2c_master_mode_end(dev); return -EIO; }
static bool i2c_imx_write(struct device *dev, u8_t *txBuffer, u8_t txSize) { I2C_Type *base = DEV_BASE(dev); struct i2c_imx_data *data = DEV_DATA(dev); struct i2c_master_transfer *transfer = &data->transfer; transfer->isBusy = true; /* Clear I2C interrupt flag to avoid spurious interrupt */ I2C_ClearStatusFlag(base, i2cStatusInterrupt); /* Set I2C work under Tx mode */ I2C_SetDirMode(base, i2cDirectionTransmit); transfer->currentDir = i2cDirectionTransmit; transfer->txBuff = txBuffer; transfer->txSize = txSize; I2C_WriteByte(base, *transfer->txBuff); transfer->txBuff++; transfer->txSize--; /* Enable I2C interrupt, subsequent data transfer will be handled * in ISR. */ I2C_SetIntCmd(base, true); /* Wait for the transfer to complete */ k_sem_take(&data->device_sync_sem, K_FOREVER); return transfer->ack; }
int stm32_i2c_configure_timing(struct device *dev, u32_t clock) { const struct i2c_stm32_config *cfg = DEV_CFG(dev); struct i2c_stm32_data *data = DEV_DATA(dev); I2C_TypeDef *i2c = cfg->i2c; u32_t i2c_hold_time_min, i2c_setup_time_min; u32_t i2c_h_min_time, i2c_l_min_time; u32_t presc = 1; u32_t timing = 0; switch (I2C_SPEED_GET(data->dev_config)) { case I2C_SPEED_STANDARD: i2c_h_min_time = 4000; i2c_l_min_time = 4700; i2c_hold_time_min = 500; i2c_setup_time_min = 1250; break; case I2C_SPEED_FAST: i2c_h_min_time = 600; i2c_l_min_time = 1300; i2c_hold_time_min = 375; i2c_setup_time_min = 500; break; default: return -EINVAL; } /* Calculate period until prescaler matches */ do { u32_t t_presc = clock / presc; u32_t ns_presc = NSEC_PER_SEC / t_presc; u32_t sclh = i2c_h_min_time / ns_presc; u32_t scll = i2c_l_min_time / ns_presc; u32_t sdadel = i2c_hold_time_min / ns_presc; u32_t scldel = i2c_setup_time_min / ns_presc; if ((sclh - 1) > 255 || (scll - 1) > 255) { ++presc; continue; } if (sdadel > 15 || (scldel - 1) > 15) { ++presc; continue; } timing = __LL_I2C_CONVERT_TIMINGS(presc - 1, scldel - 1, sdadel, sclh - 1, scll - 1); break; } while (presc < 16); if (presc >= 16) { SYS_LOG_DBG("I2C:failed to find prescaler value"); return -EINVAL; } LL_I2C_SetTiming(i2c, timing); return 0; }
static void dw_dma_isr(void *arg) { struct device *dev = (struct device *)arg; const struct dw_dma_dev_cfg *const dev_cfg = DEV_CFG(dev); struct dw_dma_dev_data *const dev_data = DEV_DATA(dev); struct dma_chan_data *chan_data; u32_t status_tfr = 0; u32_t status_block = 0; u32_t status_err = 0; u32_t status_intr; u32_t channel; status_intr = dw_read(dev_cfg->base, DW_INTR_STATUS); if (!status_intr) { SYS_LOG_ERR("status_intr = %d", status_intr); } /* get the source of our IRQ. */ status_block = dw_read(dev_cfg->base, DW_STATUS_BLOCK); status_tfr = dw_read(dev_cfg->base, DW_STATUS_TFR); /* TODO: handle errors, just clear them atm */ status_err = dw_read(dev_cfg->base, DW_STATUS_ERR); if (status_err) { SYS_LOG_ERR("status_err = %d\n", status_err); dw_write(dev_cfg->base, DW_CLEAR_ERR, status_err); } /* clear interrupts */ dw_write(dev_cfg->base, DW_CLEAR_BLOCK, status_block); dw_write(dev_cfg->base, DW_CLEAR_TFR, status_tfr); /* Dispatch ISRs for channels depending upon the bit set */ while (status_block) { channel = find_lsb_set(status_block) - 1; status_block &= ~(1 << channel); chan_data = &dev_data->chan[channel]; if (chan_data->dma_blkcallback) { /* Ensure the linked list (chan_data->lli) is * freed in the user callback function once * all the blocks are transferred. */ chan_data->dma_blkcallback(dev, channel, 0); } } while (status_tfr) { channel = find_lsb_set(status_tfr) - 1; status_tfr &= ~(1 << channel); chan_data = &dev_data->chan[channel]; k_free(chan_data->lli); chan_data->lli = NULL; if (chan_data->dma_tfrcallback) { chan_data->dma_tfrcallback(dev, channel, 0); } } }
/** * @brief Initialize UART channel * * This routine is called to reset the chip in a quiescent state. * It is assumed that this function is called only once per UART. * * @param dev UART device struct * * @return DEV_OK */ static int uart_k20_init(struct device *dev) { int old_level; /* old interrupt lock level */ union C1 c1; /* UART C1 register value */ union C2 c2; /* UART C2 register value */ volatile struct K20_UART *uart = UART_STRUCT(dev); struct uart_device_config * const dev_cfg = DEV_CFG(dev); struct uart_k20_dev_data_t * const dev_data = DEV_DATA(dev); /* disable interrupts */ old_level = irq_lock(); _uart_k20_baud_rate_set(uart, dev_cfg->sys_clk_freq, dev_data->baud_rate); /* 1 start bit, 8 data bits, no parity, 1 stop bit */ c1.value = 0; uart->c1 = c1; /* enable Rx and Tx with interrupts disabled */ c2.value = 0; c2.field.rx_enable = 1; c2.field.tx_enable = 1; uart->c2 = c2; /* restore interrupt state */ irq_unlock(old_level); dev->driver_api = &uart_k20_driver_api; return DEV_OK; }