/** * @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 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; }
static void adc_sam_configure(struct device *dev) { const struct adc_sam_dev_cfg *dev_cfg = DEV_CFG(dev); Afec *const afec = dev_cfg->regs; /* Reset the AFEC */ afec->AFEC_CR = AFEC_CR_SWRST; afec->AFEC_MR = AFEC_MR_TRGEN_DIS | AFEC_MR_SLEEP_NORMAL | AFEC_MR_FWUP_OFF | AFEC_MR_FREERUN_OFF | AFEC_MR_PRESCAL(CONF_ADC_PRESCALER) | AFEC_MR_STARTUP_SUT96 | AFEC_MR_ONE | AFEC_MR_USEQ_NUM_ORDER; /* Set all channels CM voltage to Vrefp/2 (512) */ for (int i = 0; i < ADC_CHANNELS; i++) { afec->AFEC_CSELR = i; afec->AFEC_COCR = 512; } /* Enable PGA and Current Bias */ afec->AFEC_ACR = AFEC_ACR_PGA0EN | AFEC_ACR_PGA1EN | AFEC_ACR_IBCTL(1); }
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; }
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 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 usart_sam_irq_is_pending(struct device *dev) { volatile Usart * const usart = DEV_CFG(dev)->regs; return ((usart->US_CSR & US_CSR_TXRDY) | (usart->US_CSR & US_CSR_RXRDY)); }
static int i2c_mcux_configure(struct device *dev, u32_t dev_config_raw) { I2C_Type *base = DEV_BASE(dev); const struct i2c_mcux_config *config = DEV_CFG(dev); union dev_config dev_config = (union dev_config)dev_config_raw; u32_t clock_freq; u32_t baudrate; if (!dev_config.bits.is_master_device) { return -EINVAL; } if (dev_config.bits.use_10_bit_addr) { return -EINVAL; } switch (dev_config.bits.speed) { case I2C_SPEED_STANDARD: baudrate = KHZ(100); break; case I2C_SPEED_FAST: baudrate = MHZ(1); break; default: return -EINVAL; } clock_freq = CLOCK_GetFreq(config->clock_source); I2C_MasterSetBaudRate(base, baudrate, clock_freq); return 0; }
int stm32_i2c_msg_read(struct device *dev, struct i2c_msg *msg, u8_t *next_msg_flags, uint16_t slave) { const struct i2c_stm32_config *cfg = DEV_CFG(dev); I2C_TypeDef *i2c = cfg->i2c; unsigned int len = 0; u8_t *buf = msg->buf; msg_init(dev, msg, next_msg_flags, slave, LL_I2C_REQUEST_READ); len = msg->len; while (len) { while (!LL_I2C_IsActiveFlag_RXNE(i2c)) { ; } *buf = LL_I2C_ReceiveData8(i2c); buf++; len--; } msg_done(dev, msg->flags); return 0; }
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; }
static int i2c_mcux_configure(struct device *dev, u32_t dev_config_raw) { I2C_Type *base = DEV_BASE(dev); const struct i2c_mcux_config *config = DEV_CFG(dev); u32_t clock_freq; u32_t baudrate; if (!(I2C_MODE_MASTER & dev_config_raw)) { return -EINVAL; } if (I2C_ADDR_10_BITS & dev_config_raw) { return -EINVAL; } switch (I2C_SPEED_GET(dev_config_raw)) { case I2C_SPEED_STANDARD: baudrate = KHZ(100); break; case I2C_SPEED_FAST: baudrate = MHZ(1); break; default: return -EINVAL; } clock_freq = CLOCK_GetFreq(config->clock_source); I2C_MasterSetBaudRate(base, baudrate, clock_freq); return 0; }
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; }
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_sam_irq_is_pending(struct device *dev) { volatile Uart * const uart = DEV_CFG(dev)->regs; return (uart->UART_IMR & (UART_IMR_TXRDY | UART_IMR_RXRDY)) & (uart->UART_SR & (UART_SR_TXRDY | UART_SR_RXRDY)); }
/** * @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; }
/** * @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; }
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; }
static void i2c_sam_twi_isr(void *arg) { struct device *dev = (struct device *)arg; const struct i2c_sam_twi_dev_cfg *const dev_cfg = DEV_CFG(dev); struct i2c_sam_twi_dev_data *const dev_data = DEV_DATA(dev); Twi *const twi = dev_cfg->regs; struct twi_msg *msg = &dev_data->msg; u32_t isr_status; /* Retrieve interrupt status */ isr_status = twi->TWI_SR & twi->TWI_IMR; /* Not Acknowledged */ if (isr_status & TWI_SR_NACK) { msg->twi_sr = isr_status; goto tx_comp; } /* Byte received */ if (isr_status & TWI_SR_RXRDY) { msg->buf[msg->idx++] = twi->TWI_RHR; if (msg->idx == msg->len - 1) { /* Send a STOP condition on the TWI */ twi->TWI_CR = TWI_CR_STOP; } } /* Byte sent */ if (isr_status & TWI_SR_TXRDY) { if (msg->idx == msg->len) { if (msg->flags & I2C_MSG_STOP) { /* Send a STOP condition on the TWI */ twi->TWI_CR = TWI_CR_STOP; /* Disable Transmit Ready interrupt */ twi->TWI_IDR = TWI_IDR_TXRDY; } else { /* Transmission completed */ goto tx_comp; } } else { twi->TWI_THR = msg->buf[msg->idx++]; } } /* Transmission completed */ if (isr_status & TWI_SR_TXCOMP) { goto tx_comp; } return; tx_comp: /* Disable all enabled interrupts */ twi->TWI_IDR = twi->TWI_IMR; /* We are done */ k_sem_give(&dev_data->sem); }
static int i2s_stm32_set_clock(struct device *dev, u32_t bit_clk_freq) { const struct i2s_stm32_cfg *cfg = DEV_CFG(dev); u32_t pll_src = LL_RCC_PLL_GetMainSource(); int freq_in; u8_t i2s_div, i2s_odd; freq_in = (pll_src == LL_RCC_PLLSOURCE_HSI) ? HSI_VALUE : CONFIG_CLOCK_STM32_HSE_CLOCK; #ifdef CONFIG_I2S_STM32_USE_PLLI2S_ENABLE /* Set PLLI2S */ LL_RCC_PLLI2S_Disable(); LL_RCC_PLLI2S_ConfigDomain_I2S(pll_src, CONFIG_I2S_STM32_PLLI2S_PLLM, CONFIG_I2S_STM32_PLLI2S_PLLN, pllr(CONFIG_I2S_STM32_PLLI2S_PLLR)); LL_RCC_PLLI2S_Enable(); /* wait until PLLI2S gets locked */ while (!LL_RCC_PLLI2S_IsReady()) { if (plli2s_ms_count++ > PLLI2S_MAX_MS_TIME) { return -EIO; } /* wait 1 ms */ k_sleep(1); } LOG_DBG("PLLI2S is locked"); /* Adjust freq_in according to PLLM, PLLN, PLLR */ float freq_tmp; freq_tmp = freq_in / CONFIG_I2S_STM32_PLLI2S_PLLM; freq_tmp *= CONFIG_I2S_STM32_PLLI2S_PLLN; freq_tmp /= CONFIG_I2S_STM32_PLLI2S_PLLR; freq_in = (int) freq_tmp; #endif /* CONFIG_I2S_STM32_USE_PLLI2S_ENABLE */ /* Select clock source */ LL_RCC_SetI2SClockSource(cfg->i2s_clk_sel); /* * The ratio between input clock (I2SxClk) and output * clock on the pad (I2S_CK) is obtained using the * following formula: * (i2s_div * 2) + i2s_odd */ i2s_div = div_round_closest(freq_in, bit_clk_freq); i2s_odd = (i2s_div & 0x1) ? 1 : 0; i2s_div >>= 1; LOG_DBG("i2s_div: %d - i2s_odd: %d", i2s_div, i2s_odd); LL_I2S_SetPrescalerLinear(cfg->i2s, i2s_div); LL_I2S_SetPrescalerParity(cfg->i2s, i2s_odd); return 0; }
static int ipm_mhu_init(struct device *d) { const struct ipm_mhu_device_config *config = DEV_CFG(d); config->irq_config_func(d); return 0; }
static void stm32_i2c_event(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) { stm32_i2c_slave_event(dev); return; } #endif if (data->current.len) { /* Send next byte */ if (LL_I2C_IsActiveFlag_TXIS(i2c)) { LL_I2C_TransmitData8(i2c, *data->current.buf); } /* Receive next byte */ if (LL_I2C_IsActiveFlag_RXNE(i2c)) { *data->current.buf = LL_I2C_ReceiveData8(i2c); } data->current.buf++; data->current.len--; } /* NACK received */ if (LL_I2C_IsActiveFlag_NACK(i2c)) { LL_I2C_ClearFlag_NACK(i2c); data->current.is_nack = 1; goto end; } /* STOP received */ if (LL_I2C_IsActiveFlag_STOP(i2c)) { LL_I2C_ClearFlag_STOP(i2c); LL_I2C_DisableReloadMode(i2c); goto end; } /* Transfer Complete or Transfer Complete Reload */ if (LL_I2C_IsActiveFlag_TC(i2c) || LL_I2C_IsActiveFlag_TCR(i2c)) { /* Issue stop condition if necessary */ if (data->current.msg->flags & I2C_MSG_STOP) { LL_I2C_GenerateStopCondition(i2c); } else { stm32_i2c_disable_transfer_interrupts(dev); k_sem_give(&data->device_sync_sem); } } return; end: stm32_i2c_master_mode_end(dev); }
static int dw_dma_transfer_start(struct device *dev, u32_t channel) { 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; if (channel >= DW_MAX_CHAN) { return -EINVAL; } chan_data = &dev_data->chan[channel]; if (chan_data->dma_tfrcallback) { dw_write(dev_cfg->base, DW_MASK_TFR, INT_UNMASK(channel)); } if (chan_data->dma_blkcallback) { dw_write(dev_cfg->base, DW_MASK_BLOCK, INT_UNMASK(channel)); } dw_write(dev_cfg->base, DW_MASK_ERR, INT_UNMASK(channel)); /* write interrupt clear registers for the channel * ClearTfr, ClearBlock, ClearSrcTran, ClearDstTran, ClearErr */ dw_write(dev_cfg->base, DW_CLEAR_TFR, 0x1 << channel); dw_write(dev_cfg->base, DW_CLEAR_BLOCK, 0x1 << channel); dw_write(dev_cfg->base, DW_CLEAR_SRC_TRAN, 0x1 << channel); dw_write(dev_cfg->base, DW_CLEAR_DST_TRAN, 0x1 << channel); dw_write(dev_cfg->base, DW_CLEAR_ERR, 0x1 << channel); if (chan_data->lli->llp) { /* LLP mode - only write LLP pointer */ dw_write(dev_cfg->base, DW_LLP(channel), (u32_t)chan_data->lli); } else { /* single transfer, must set zero */ dw_write(dev_cfg->base, DW_LLP(channel), 0); } /* channel needs started from scratch, so write SARn, DARn */ dw_write(dev_cfg->base, DW_SAR(channel), chan_data->lli->sar); dw_write(dev_cfg->base, DW_DAR(channel), chan_data->lli->dar); /* program CTLn */ dw_write(dev_cfg->base, DW_CTRL_LOW(channel), chan_data->lli->ctrl_lo); dw_write(dev_cfg->base, DW_CTRL_HIGH(channel), chan_data->lli->ctrl_hi); /* write channel config */ dw_write(dev_cfg->base, DW_CFG_LOW(channel), chan_data->cfg_lo); dw_write(dev_cfg->base, DW_CFG_HIGH(channel), chan_data->cfg_hi); /* enable the channel */ dw_write(dev_cfg->base, DW_DMA_CHAN_EN, CHAN_ENABLE(channel)); return 0; }
static int rtc_stm32_init(struct device *dev) { struct device *clk = device_get_binding(STM32_CLOCK_CONTROL_NAME); const struct rtc_stm32_config *cfg = DEV_CFG(dev); __ASSERT_NO_MSG(clk); k_sem_init(DEV_SEM(dev), 1, UINT_MAX); DEV_DATA(dev)->cb_fn = NULL; clock_control_on(clk, (clock_control_subsys_t *) &cfg->pclken); LL_PWR_EnableBkUpAccess(); LL_RCC_ForceBackupDomainReset(); LL_RCC_ReleaseBackupDomainReset(); #if defined(CONFIG_RTC_STM32_CLOCK_LSI) LL_RCC_LSI_Enable(); while (LL_RCC_LSI_IsReady() != 1) ; LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSI); #else /* CONFIG_RTC_STM32_CLOCK_LSE */ LL_RCC_LSE_SetDriveCapability(CONFIG_RTC_STM32_LSE_DRIVE_STRENGTH); LL_RCC_LSE_Enable(); /* Wait untill LSE is ready */ while (LL_RCC_LSE_IsReady() != 1) ; LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSE); #endif /* CONFIG_RTC_STM32_CLOCK_SRC */ LL_RCC_EnableRTC(); if (LL_RTC_DeInit(RTC) != SUCCESS) { return -EIO; } if (LL_RTC_Init(RTC, ((LL_RTC_InitTypeDef *) &cfg->ll_rtc_config)) != SUCCESS) { return -EIO; } LL_RTC_EnableShadowRegBypass(RTC); LL_EXTI_EnableIT_0_31(EXTI_LINE); LL_EXTI_EnableRisingTrig_0_31(EXTI_LINE); rtc_stm32_irq_config(dev); return 0; }
static void stm32_i2c_enable_transfer_interrupts(struct device *dev) { const struct i2c_stm32_config *cfg = DEV_CFG(dev); I2C_TypeDef *i2c = cfg->i2c; LL_I2C_EnableIT_STOP(i2c); LL_I2C_EnableIT_NACK(i2c); LL_I2C_EnableIT_TC(i2c); LL_I2C_EnableIT_ERR(i2c); }
static int i2c_sam_twi_transfer(struct device *dev, struct i2c_msg *msgs, u8_t num_msgs, u16_t addr) { const struct i2c_sam_twi_dev_cfg *const dev_cfg = DEV_CFG(dev); struct i2c_sam_twi_dev_data *const dev_data = DEV_DATA(dev); Twi *const twi = dev_cfg->regs; __ASSERT_NO_MSG(msgs); if (!num_msgs) { return 0; } /* Clear pending interrupts, such as NACK. */ (void)twi->TWI_SR; /* Set number of internal address bytes to 0, not used. */ twi->TWI_IADR = 0; for (; num_msgs > 0; num_msgs--, msgs++) { dev_data->msg.buf = msgs->buf; dev_data->msg.len = msgs->len; dev_data->msg.idx = 0; dev_data->msg.twi_sr = 0; dev_data->msg.flags = msgs->flags; /* * REMARK: Dirty workaround: * * The controller does not have a documented, generic way to * issue RESTART when changing transfer direction as master. * Send a stop condition in such a case. */ if (num_msgs > 1) { if ((msgs[0].flags & I2C_MSG_RW_MASK) != (msgs[1].flags & I2C_MSG_RW_MASK)) { dev_data->msg.flags |= I2C_MSG_STOP; } } if ((msgs->flags & I2C_MSG_RW_MASK) == I2C_MSG_READ) { read_msg_start(twi, &dev_data->msg, addr); } else { write_msg_start(twi, &dev_data->msg, addr); } /* Wait for the transfer to complete */ k_sem_take(&dev_data->sem, K_FOREVER); if (dev_data->msg.twi_sr > 0) { /* Something went wrong */ return -EIO; } } return 0; }
static void uart_sam_poll_out(struct device *dev, unsigned char c) { Uart *const uart = DEV_CFG(dev)->regs; /* Wait for transmitter to be ready */ while (!(uart->UART_SR & UART_SR_TXRDY)) ; /* send a character */ uart->UART_THR = (u32_t)c; }
static int uart_sam_fifo_fill(struct device *dev, const uint8_t *tx_data, int size) { volatile Uart * const uart = DEV_CFG(dev)->regs; /* Wait for transmitter to be ready. */ while ((uart->UART_SR & UART_SR_TXRDY) == 0) ; uart->UART_THR = *tx_data; return 1; }
static int uart_sam_poll_in(struct device *dev, unsigned char *c) { Uart *const uart = DEV_CFG(dev)->regs; if (!(uart->UART_SR & UART_SR_RXRDY)) { return -EBUSY; } /* got a character */ *c = (unsigned char)uart->UART_RHR; return 0; }