2 * Copyright (c) 2015, Olivier MATZ <zer0@droids-corp.org>
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the University of California, Berkeley nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <ucg_stm32_uart.h>
33 static void disable_tx_irq(struct ucg_uart *uart)
35 struct ucg_stm32_uart *stm32_uart = uart->driver_data;
37 stm32_uart->uart->SR &= ~(USART_FLAG_TXE);
38 stm32_uart->uart->CR1 &= ~(USART_CR1_TXEIE);
41 static void enable_tx_irq(struct ucg_uart *uart)
43 struct ucg_stm32_uart *stm32_uart = uart->driver_data;
45 stm32_uart->uart->CR1 |= USART_CR1_TXEIE;
48 static uint8_t tx_ready(struct ucg_uart *uart)
50 struct ucg_stm32_uart *stm32_uart = uart->driver_data;
52 return !!(stm32_uart->uart->SR & USART_FLAG_TXE);
55 static uint8_t rx_ready(struct ucg_uart *uart)
57 struct ucg_stm32_uart *stm32_uart = uart->driver_data;
59 return !!(stm32_uart->uart->SR & USART_FLAG_RXNE);
62 static void set_udr(struct ucg_uart *uart, char c)
64 struct ucg_stm32_uart *stm32_uart = uart->driver_data;
66 stm32_uart->uart->DR = c;
69 static char get_udr(struct ucg_uart *uart)
71 struct ucg_stm32_uart *stm32_uart = uart->driver_data;
73 return stm32_uart->uart->DR;
76 static int set_conf(struct ucg_uart *uart, const struct ucg_uart_config *conf)
79 GPIO_InitTypeDef gpio;
80 NVIC_InitTypeDef nvic;
81 struct ucg_stm32_uart *stm32_uart = uart->driver_data;
84 /* even if it is asked to disable, keep the RCC enabled */
86 /* Enable the peripheral clock. */
87 RCC_APB1PeriphClockCmd(stm32_uart->rcc_uart, ENABLE);
90 /* Enable the peripheral clock for GPIO. */
91 RCC_AHB1PeriphClockCmd(stm32_uart->rcc_gpio, ENABLE);
94 if (conf->enable == 0) {
95 USART_ITConfig(stm32_uart->uart, USART_IT_TXE, DISABLE);
96 USART_ITConfig(stm32_uart->uart, USART_IT_RXNE, DISABLE);
97 USART_Cmd(stm32_uart->uart, ENABLE);
99 nvic.NVIC_IRQChannel = stm32_uart->irq;
100 nvic.NVIC_IRQChannelCmd = DISABLE;
105 if (conf->nbits != 8)
108 /* connect to alternate function */
109 for (i = 0; i < 16; i++) {
110 if ((1 << i) & stm32_uart->gpio_pins) {
111 GPIO_PinAFConfig(stm32_uart->gpio, i,
112 stm32_uart->gpio_af);
116 GPIO_StructInit(&gpio);
117 gpio.GPIO_Speed = stm32_uart->gpio_speed;
119 /* configure rx and tx */
120 gpio.GPIO_Pin = stm32_uart->gpio_pins;
121 gpio.GPIO_Mode = GPIO_Mode_AF;
122 GPIO_Init(stm32_uart->gpio, &gpio);
124 /* USART configuration */
125 u.USART_BaudRate = conf->baudrate;
126 u.USART_WordLength = USART_WordLength_8b;
127 u.USART_StopBits = USART_StopBits_1;
128 u.USART_Parity = USART_Parity_No;
129 u.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
130 u.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
131 USART_Init(stm32_uart->uart, &u);
133 /* Enable and set EXTI Interrupt to the defined priority */
134 nvic.NVIC_IRQChannel = stm32_uart->irq;
135 /* nvic.NVIC_IRQChannelPreemptionPriority = stm32_uart->irq_preempt_prio; */
136 /* nvic.NVIC_IRQChannelSubPriority = stm32_uart->irq_sub_prio; */
137 nvic.NVIC_IRQChannelCmd = ENABLE;
140 /* Enable RX interruption */
141 USART_ITConfig(stm32_uart->uart, USART_IT_RXNE, ENABLE);
144 USART_Cmd(stm32_uart->uart, ENABLE);
149 const struct ucg_uart_driver_ops stm32_uart_ops = {
150 .disable_tx_irq = disable_tx_irq,
151 .enable_tx_irq = enable_tx_irq,
152 .tx_ready = tx_ready,
153 .rx_ready = rx_ready,
156 .set_conf = set_conf,