]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/blob - rpp/src/rpp/sci.c
Make the RPP layer thread safe
[pes-rpp/rpp-lib.git] / rpp / src / rpp / sci.c
1 /* Copyright (C) 2013, 2015 Czech Technical University in Prague
2  *
3  * Authors:
4  *     - Carlos Jenkins <carlos@jenkins.co.cr>
5  *
6  * This document contains proprietary information belonging to Czech
7  * Technical University in Prague. Passing on and copying of this
8  * document, and communication of its contents is not permitted
9  * without prior written authorization.
10  *
11  * File : sci.c
12  * Abstract:
13  *     Serial Communication Interface RPP API implementation file.
14  *
15  * References:
16  *     sci.h
17  *     RPP API documentation.
18  */
19
20
21 #include "rpp/rpp.h"
22 #include <stdio.h>  // vsnprintf()
23 #include <stdarg.h> // va_start, va_end
24
25 #ifndef FREERTOS_POSIX
26 #include "drv/drv.h"
27 #endif
28
29 static boolean_t initialized = FALSE;
30
31 int8_t rpp_sci_init()
32 {
33         if (initialized)
34                 return FAILURE;
35         initialized = TRUE;
36
37 #ifndef FREERTOS_POSIX
38         drv_sci_init();
39         drv_sci_set_crlf_conv_en(TRUE);
40 #endif
41         return SUCCESS;
42 }
43
44
45 boolean_t rpp_sci_setup(uint32_t baud)
46 {
47         boolean_t known = FALSE;
48         // FIXME This is a standard list of baud rates. This should include only
49         // tested baud rates.
50         static const uint32_t baud_list[] = {110, 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 56000, 57600, 115200};
51
52         if (baud == 0)
53                 baud = 9600;
54         uint32_t i;
55         for (i = 0; i < ARRAY_SIZE(baud_list); i++) {
56                 if (baud == baud_list[i]) {
57                         known = TRUE;
58                         break;
59                 }
60         }
61
62 #ifndef FREERTOS_POSIX
63         drv_sci_set_baudrate(baud);
64 #endif
65         return known;
66 }
67
68
69 #ifndef FREERTOS_POSIX
70 uint16_t rpp_sci_available()
71 {
72         uint16_t available = 0;
73
74         available = drv_sci_available();
75
76         return available;
77 }
78
79
80 int8_t rpp_sci_read(uint32_t amount, uint8_t *buffer)
81 {
82         drv_sci_receive(amount, buffer, portMAX_DELAY);
83
84         return SUCCESS;
85 }
86
87
88 int8_t rpp_sci_read_nb(uint32_t amount, uint8_t *buffer)
89 {
90         if (drv_sci_receive(amount, buffer, 0) != SUCCESS)
91                 return FAILURE;
92
93         return SUCCESS;
94 }
95
96
97 int8_t rpp_sci_write(uint32_t amount, uint8_t *data)
98 {
99         drv_sci_send(amount, data, portMAX_DELAY);
100
101         return SUCCESS;
102 }
103
104
105 int8_t rpp_sci_write_nb(uint32_t amount, uint8_t *data)
106 {
107         if (drv_sci_send(amount, data, 0) != SUCCESS)
108                 return FAILURE;
109
110         return SUCCESS;
111 }
112
113
114 int8_t rpp_sci_flush(boolean_t buff)
115 {
116         return drv_sci_flush(buff);
117 }
118
119 int32_t rpp_sci_printk(const char *format, ...)
120 {
121         char str[MAX_BUFFER_LEN];
122         int length = -1;
123         va_list argList;
124
125         va_start(argList, format);
126
127         length = vsnprintf(str, sizeof(str), format, argList);
128
129         va_end(argList);
130
131         if (length > 0) {
132                 // According to the C stdlib about vsnprintf:
133                 // If the resulting string would be longer than n-1 characters, the
134                 // remaining characters are discarded and not stored, but counted
135                 // for the value returned by the function.
136                 // In consequence we need to trim the value if larger than buffer.
137                 if (length > sizeof(str))
138                         length = sizeof(str);
139
140                 drv_sci_send_imm((uint32_t)length, (uint8_t *)str);
141         }
142
143         return length;
144 }
145
146 int32_t rpp_sci_printkb(const char *format, ...)
147 {
148         char str[MAX_BUFFER_LEN];
149         int length = -1;
150         va_list argList;
151
152         va_start(argList, format);
153
154         length = vsnprintf(str, sizeof(str), format, argList);
155
156         va_end(argList);
157
158         if (length > 0) {
159                 // According to the C stdlib about vsnprintf:
160                 // If the resulting string would be longer than n-1 characters, the
161                 // remaining characters are discarded and not stored, but counted
162                 // for the value returned by the function.
163                 // In consequence we need to trim the value if larger than buffer.
164                 if (length > sizeof(str))
165                         length = sizeof(str);
166
167                 return drv_sci_send_try_append((uint32_t)length, (uint8_t *)str);
168
169         }
170         return length;
171 }
172
173 int32_t rpp_sci_printf(const char *format, ...)
174 {
175         int length = -1;
176         va_list argList;
177
178         va_start(argList, format);
179         length = rpp_sci_vprintf(format, argList);
180         va_end(argList);
181
182         return length;
183 }
184
185 int32_t rpp_sci_vprintf(const char *format, va_list argList)
186 {
187         char str[MAX_BUFFER_LEN];
188         int length = -1;
189
190         length = vsnprintf(str, sizeof(str), format, argList);
191
192         if (length > 0) {
193                 // According to the C stdlib about vsnprintf:
194                 // If the resulting string would be longer than n-1 characters, the
195                 // remaining characters are discarded and not stored, but counted
196                 // for the value returned by the function.
197                 // In consequence we need to trim the value if larger than buffer.
198                 if (length > sizeof(str))
199                         length = sizeof(str);
200                 if (drv_sci_send(
201                                 (uint32_t)length,
202                                 (uint8_t *)str,
203                                 portMAX_DELAY) != SUCCESS)
204                         return -1;
205         }
206
207         return length;
208 }
209
210
211 int8_t rpp_sci_putc(uint8_t byte)
212 {
213         drv_sci_send(1, &byte, portMAX_DELAY);
214
215         return SUCCESS;
216 }
217
218
219 int16_t rpp_sci_getc()
220 {
221         uint8_t result = 0;
222
223         if (drv_sci_receive(1, &result, portMAX_DELAY) == FAILURE)
224                 return FAILURE;
225
226         return (int16_t)result;
227 }
228 #endif /* !FREERTOS_POSIX */