Beispiel #1
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;
}
Beispiel #2
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;
}
Beispiel #3
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);
}
Beispiel #4
0
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;
}
Beispiel #5
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);
		}
	}
}
Beispiel #6
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;
}
Beispiel #7
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);
		}
	}
}
Beispiel #8
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;
}
Beispiel #9
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));
}
Beispiel #10
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);
	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;
}
Beispiel #11
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;
}
Beispiel #12
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;
}
Beispiel #13
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;
}
Beispiel #14
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;
}
Beispiel #15
0
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;
}
Beispiel #16
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));
}
Beispiel #17
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_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;
}
Beispiel #18
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;
}
Beispiel #19
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;
}
Beispiel #20
0
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);
}
Beispiel #21
0
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;
}
Beispiel #22
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;
}
Beispiel #23
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);
}
Beispiel #24
0
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;
}
Beispiel #25
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;
}
Beispiel #26
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);
}
Beispiel #27
0
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;
}
Beispiel #28
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;
}
Beispiel #29
0
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;
}
Beispiel #30
0
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;
}