initial revision
[ucgine.git] / examples / spi-flash / uart.c
1 /*
2  * Copyright 2015, Olivier MATZ <zer0@droids-corp.org>
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
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.
15  *
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.
26  */
27
28 #include <stdio.h>
29 #include <inttypes.h>
30 #include <unistd.h>
31 #include "stm32f4xx.h"
32
33 #include <ucg_gloss_chardev.h>
34
35 static _ssize_t
36 uart_write_r(__attribute__((unused)) struct _reent *r,
37         __attribute__((unused)) int fd,
38         const void *ptr, size_t len)
39 {
40         size_t i;
41         const char *buf = ptr;
42
43
44         for (i = 0; i < len; i++) {
45                 /* wait that uart is ready */
46                 while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)
47                         ;
48                 USART_SendData(USART2, buf[i]);
49         }
50         return len;
51 }
52
53 static _ssize_t
54 uart_read_r(__attribute__((unused)) struct _reent *r,
55         __attribute__((unused)) int fd,
56         void *ptr, size_t len)
57 {
58         size_t i;
59         char *buf = ptr;
60
61         for (i = 0; i < len; i++) {
62                 /* wait that uart is ready */
63                 while (USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == RESET)
64                         ;
65                 buf[i] = USART_ReceiveData(USART2);
66         }
67         return len;
68 }
69
70 struct ucg_chardev uart_stdin_dev = {
71         .name = "stdin",
72         .open_r = NULL,
73         .close_r = NULL,
74         .read_r = uart_read_r,
75         .write_r = NULL,
76 };
77
78 struct ucg_chardev uart_stdout_dev = {
79         .name = "stdout",
80         .open_r = NULL,
81         .close_r = NULL,
82         .read_r = NULL,
83         .write_r = uart_write_r,
84 };
85
86 struct ucg_chardev uart_stderr_dev = {
87         .name = "stderr",
88         .open_r = NULL,
89         .close_r = NULL,
90         .read_r = NULL,
91         .write_r = uart_write_r,
92 };
93
94 void uart_init(void)
95 {
96         USART_InitTypeDef uart;
97         GPIO_InitTypeDef gpio;
98
99         /* Enable the USART2 peripheral clock. */
100         RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
101         __asm("dsb");
102
103         /* Enable the AHB1 peripheral clock for GPIOA. */
104         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
105         __asm("dsb");
106
107         /* connect to alternate function */
108         GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
109         GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
110
111         GPIO_StructInit(&gpio);
112         gpio.GPIO_Speed = GPIO_Speed_25MHz;
113
114         /* configure tx on PA2 */
115         gpio.GPIO_Pin = GPIO_Pin_2;
116         gpio.GPIO_Mode = GPIO_Mode_AF;
117         GPIO_Init(GPIOA, &gpio);
118
119         /* configure rx on PA3 */
120         gpio.GPIO_Pin = GPIO_Pin_3;
121         gpio.GPIO_Mode = GPIO_Mode_AF;
122         GPIO_Init(GPIOA, &gpio);
123
124         /* USART configuration */
125         uart.USART_BaudRate = 115200;
126         uart.USART_WordLength = USART_WordLength_8b;
127         uart.USART_StopBits = USART_StopBits_1;
128         uart.USART_Parity = USART_Parity_No;
129         uart.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
130         uart.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
131         USART_Init(USART2, &uart);
132
133         /* Enable USART */
134         USART_Cmd(USART2, ENABLE);
135 }
136
137 void uart_register_stdio(void)
138 {
139         ucg_chardev_register(&uart_stdin_dev);
140         ucg_chardev_register(&uart_stdout_dev);
141         ucg_chardev_register(&uart_stderr_dev);
142
143         /* Disable buffering */
144         setbuf(stdin, NULL);
145         setbuf(stdout, NULL);
146         setbuf(stderr, NULL);
147 }
148