blob: 87d89f02fb0a5135cdb8071ed972557deea34b7c [file] [log] [blame]
danicampora87856452015-02-06 15:35:48 +01001/*
2 * This file is part of the Micro Python project, http://micropython.org/
3 *
4 * The MIT License (MIT)
5 *
6 * Copyright (c) 2013, 2014 Damien P. George
7 * Copyright (c) 2015 Daniel Campora
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 */
27
danicampora87856452015-02-06 15:35:48 +010028#include <stdint.h>
danicampora6b21c3f2015-02-20 16:31:30 +010029#include <stdio.h>
30#include <errno.h>
31#include <string.h>
danicampora87856452015-02-06 15:35:48 +010032
Damien George4a23a012015-02-21 18:58:43 +000033#include "py/mpconfig.h"
Damien George4a23a012015-02-21 18:58:43 +000034#include "py/obj.h"
35#include "py/runtime.h"
danicampora6b21c3f2015-02-20 16:31:30 +010036#include "py/objlist.h"
Damien George4a23a012015-02-21 18:58:43 +000037#include "py/stream.h"
Damien George731f3592015-10-30 23:03:58 +000038#include "py/mphal.h"
danicampora87856452015-02-06 15:35:48 +010039#include "inc/hw_types.h"
danicampora87856452015-02-06 15:35:48 +010040#include "inc/hw_ints.h"
41#include "inc/hw_memmap.h"
42#include "inc/hw_uart.h"
43#include "rom_map.h"
44#include "interrupt.h"
45#include "prcm.h"
danicampora87856452015-02-06 15:35:48 +010046#include "uart.h"
danicampora87856452015-02-06 15:35:48 +010047#include "pybuart.h"
Daniel Camporadbdcb582015-09-22 23:20:29 +020048#include "mpirq.h"
danicampora87856452015-02-06 15:35:48 +010049#include "pybioctl.h"
danicamporad226dd22015-02-27 16:50:06 +010050#include "pybsleep.h"
danicampora87856452015-02-06 15:35:48 +010051#include "mpexception.h"
danicampora6b21c3f2015-02-20 16:31:30 +010052#include "py/mpstate.h"
danicampora87856452015-02-06 15:35:48 +010053#include "osi.h"
Daniel Campora33197802015-06-09 17:14:31 +020054#include "utils.h"
Daniel Camporaf91f2122015-09-07 09:23:46 +020055#include "pin.h"
56#include "pybpin.h"
57#include "pins.h"
Daniel Camporaef369242015-09-25 15:20:07 +020058#include "moduos.h"
danicampora87856452015-02-06 15:35:48 +010059
danicampora87856452015-02-06 15:35:48 +010060/// \moduleref pyb
61/// \class UART - duplex serial communication bus
danicampora87856452015-02-06 15:35:48 +010062
danicampora87856452015-02-06 15:35:48 +010063/******************************************************************************
danicampora6b21c3f2015-02-20 16:31:30 +010064 DEFINE CONSTANTS
Daniel Camporaf91f2122015-09-07 09:23:46 +020065 *******-***********************************************************************/
66#define PYBUART_FRAME_TIME_US(baud) ((11 * 1000000) / baud)
67#define PYBUART_2_FRAMES_TIME_US(baud) (PYBUART_FRAME_TIME_US(baud) * 2)
danicampora075ca642015-10-21 14:54:16 +020068#define PYBUART_RX_TIMEOUT_US(baud) (PYBUART_2_FRAMES_TIME_US(baud) * 8) // we need at least characters in the FIFO
Daniel Camporaf91f2122015-09-07 09:23:46 +020069
70#define PYBUART_TX_WAIT_US(baud) ((PYBUART_FRAME_TIME_US(baud)) + 1)
Daniel Camporafa655ce2015-07-05 22:26:12 +020071#define PYBUART_TX_MAX_TIMEOUT_MS (5)
danicampora6b21c3f2015-02-20 16:31:30 +010072
Daniel Camporadbdcb582015-09-22 23:20:29 +020073#define PYBUART_RX_BUFFER_LEN (256)
Daniel Camporaf91f2122015-09-07 09:23:46 +020074
Daniel Campora4d7fa052015-09-07 21:19:11 +020075// interrupt triggers
danicampora075ca642015-10-21 14:54:16 +020076#define UART_TRIGGER_RX_ANY (0x01)
77#define UART_TRIGGER_RX_HALF (0x02)
78#define UART_TRIGGER_RX_FULL (0x04)
79#define UART_TRIGGER_TX_DONE (0x08)
Daniel Campora4d7fa052015-09-07 21:19:11 +020080
danicampora6b21c3f2015-02-20 16:31:30 +010081/******************************************************************************
danicampora87856452015-02-06 15:35:48 +010082 DECLARE PRIVATE FUNCTIONS
83 ******************************************************************************/
danicampora9e443832015-03-04 13:52:39 +010084STATIC void uart_init (pyb_uart_obj_t *self);
Daniel Camporaf91f2122015-09-07 09:23:46 +020085STATIC bool uart_rx_wait (pyb_uart_obj_t *self);
Daniel Campora4d7fa052015-09-07 21:19:11 +020086STATIC void uart_check_init(pyb_uart_obj_t *self);
Daniel Camporadbdcb582015-09-22 23:20:29 +020087STATIC mp_obj_t uart_irq_new (pyb_uart_obj_t *self, byte trigger, mp_int_t priority, mp_obj_t handler);
danicampora87856452015-02-06 15:35:48 +010088STATIC void UARTGenericIntHandler(uint32_t uart_id);
89STATIC void UART0IntHandler(void);
90STATIC void UART1IntHandler(void);
Daniel Camporadbdcb582015-09-22 23:20:29 +020091STATIC void uart_irq_enable (mp_obj_t self_in);
92STATIC void uart_irq_disable (mp_obj_t self_in);
danicampora87856452015-02-06 15:35:48 +010093
94/******************************************************************************
95 DEFINE PRIVATE TYPES
96 ******************************************************************************/
danicampora87856452015-02-06 15:35:48 +010097struct _pyb_uart_obj_t {
98 mp_obj_base_t base;
danicampora6b21c3f2015-02-20 16:31:30 +010099 pyb_uart_id_t uart_id;
danicampora87856452015-02-06 15:35:48 +0100100 uint reg;
101 uint baudrate;
102 uint config;
103 uint flowcontrol;
104 byte *read_buf; // read buffer pointer
danicampora87856452015-02-06 15:35:48 +0100105 volatile uint16_t read_buf_head; // indexes first empty slot
106 uint16_t read_buf_tail; // indexes first full slot (not full if equals head)
Daniel Campora2d717ad2015-03-26 10:25:28 +0100107 byte peripheral;
Daniel Camporaf91f2122015-09-07 09:23:46 +0200108 byte irq_trigger;
Daniel Camporadbdcb582015-09-22 23:20:29 +0200109 bool irq_enabled;
110 byte irq_flags;
danicampora87856452015-02-06 15:35:48 +0100111};
112
danicampora87856452015-02-06 15:35:48 +0100113/******************************************************************************
danicampora6de1b392015-03-17 11:05:59 +0100114 DECLARE PRIVATE DATA
115 ******************************************************************************/
Daniel Camporaf91f2122015-09-07 09:23:46 +0200116STATIC pyb_uart_obj_t pyb_uart_obj[PYB_NUM_UARTS] = { {.reg = UARTA0_BASE, .baudrate = 0, .read_buf = NULL, .peripheral = PRCM_UARTA0},
117 {.reg = UARTA1_BASE, .baudrate = 0, .read_buf = NULL, .peripheral = PRCM_UARTA1} };
Daniel Camporadbdcb582015-09-22 23:20:29 +0200118STATIC const mp_irq_methods_t uart_irq_methods;
danicampora6de1b392015-03-17 11:05:59 +0100119
Daniel Campora359b4e92015-09-08 15:07:42 +0200120STATIC const mp_obj_t pyb_uart_def_pin[PYB_NUM_UARTS][2] = { {&pin_GP1, &pin_GP2}, {&pin_GP3, &pin_GP4} };
Daniel Camporaf91f2122015-09-07 09:23:46 +0200121
danicampora6de1b392015-03-17 11:05:59 +0100122/******************************************************************************
danicampora87856452015-02-06 15:35:48 +0100123 DEFINE PUBLIC FUNCTIONS
124 ******************************************************************************/
125void uart_init0 (void) {
Daniel Camporaf91f2122015-09-07 09:23:46 +0200126 // save references of the UART objects, to prevent the read buffers from being trashed by the gc
127 MP_STATE_PORT(pyb_uart_objs)[0] = &pyb_uart_obj[0];
128 MP_STATE_PORT(pyb_uart_objs)[1] = &pyb_uart_obj[1];
danicampora87856452015-02-06 15:35:48 +0100129}
130
Daniel Camporaf91f2122015-09-07 09:23:46 +0200131uint32_t uart_rx_any(pyb_uart_obj_t *self) {
132 if (self->read_buf_tail != self->read_buf_head) {
133 // buffering via irq
134 return (self->read_buf_head > self->read_buf_tail) ? self->read_buf_head - self->read_buf_tail :
135 PYBUART_RX_BUFFER_LEN - self->read_buf_tail + self->read_buf_head;
136 }
137 return MAP_UARTCharsAvail(self->reg) ? 1 : 0;
danicampora87856452015-02-06 15:35:48 +0100138}
139
danicampora87856452015-02-06 15:35:48 +0100140int uart_rx_char(pyb_uart_obj_t *self) {
141 if (self->read_buf_tail != self->read_buf_head) {
Daniel Camporaf91f2122015-09-07 09:23:46 +0200142 // buffering via irq
danicampora87856452015-02-06 15:35:48 +0100143 int data = self->read_buf[self->read_buf_tail];
Daniel Camporaf91f2122015-09-07 09:23:46 +0200144 self->read_buf_tail = (self->read_buf_tail + 1) % PYBUART_RX_BUFFER_LEN;
danicampora87856452015-02-06 15:35:48 +0100145 return data;
146 } else {
147 // no buffering
148 return MAP_UARTCharGetNonBlocking(self->reg);
149 }
150}
151
152bool uart_tx_char(pyb_uart_obj_t *self, int c) {
153 uint32_t timeout = 0;
danicampora87856452015-02-06 15:35:48 +0100154 while (!MAP_UARTCharPutNonBlocking(self->reg, c)) {
Daniel Camporaf91f2122015-09-07 09:23:46 +0200155 if (timeout++ > ((PYBUART_TX_MAX_TIMEOUT_MS * 1000) / PYBUART_TX_WAIT_US(self->baudrate))) {
danicampora87856452015-02-06 15:35:48 +0100156 return false;
157 }
Daniel Camporaf91f2122015-09-07 09:23:46 +0200158 UtilsDelay(UTILS_DELAY_US_TO_COUNT(PYBUART_TX_WAIT_US(self->baudrate)));
danicampora87856452015-02-06 15:35:48 +0100159 }
160 return true;
161}
162
163bool uart_tx_strn(pyb_uart_obj_t *self, const char *str, uint len) {
164 for (const char *top = str + len; str < top; str++) {
165 if (!uart_tx_char(self, *str)) {
166 return false;
167 }
168 }
169 return true;
170}
171
danicampora87856452015-02-06 15:35:48 +0100172/******************************************************************************
173 DEFINE PRIVATE FUNCTIONS
174 ******************************************************************************/
danicampora9e443832015-03-04 13:52:39 +0100175// assumes init parameters have been set up correctly
176STATIC void uart_init (pyb_uart_obj_t *self) {
danicampora9e443832015-03-04 13:52:39 +0100177 // Enable the peripheral clock
Daniel Campora2d717ad2015-03-26 10:25:28 +0100178 MAP_PRCMPeripheralClkEnable(self->peripheral, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
danicampora9e443832015-03-04 13:52:39 +0100179
180 // Reset the uart
Daniel Campora2d717ad2015-03-26 10:25:28 +0100181 MAP_PRCMPeripheralReset(self->peripheral);
danicampora9e443832015-03-04 13:52:39 +0100182
Daniel Camporaf91f2122015-09-07 09:23:46 +0200183 // re-allocate the read buffer after resetting the uart (which automatically disables any irqs)
184 self->read_buf_head = 0;
185 self->read_buf_tail = 0;
186 self->read_buf = MP_OBJ_NULL; // free the read buffer before allocating again
187 self->read_buf = m_new(byte, PYBUART_RX_BUFFER_LEN);
188
danicampora9e443832015-03-04 13:52:39 +0100189 // Initialize the UART
Daniel Campora2d717ad2015-03-26 10:25:28 +0100190 MAP_UARTConfigSetExpClk(self->reg, MAP_PRCMPeripheralClockGet(self->peripheral),
danicampora9e443832015-03-04 13:52:39 +0100191 self->baudrate, self->config);
192
Daniel Campora2d717ad2015-03-26 10:25:28 +0100193 // Enable the FIFO
danicampora9e443832015-03-04 13:52:39 +0100194 MAP_UARTFIFOEnable(self->reg);
195
196 // Configure the FIFO interrupt levels
197 MAP_UARTFIFOLevelSet(self->reg, UART_FIFO_TX4_8, UART_FIFO_RX4_8);
198
199 // Configure the flow control mode
200 UARTFlowControlSet(self->reg, self->flowcontrol);
danicampora9e443832015-03-04 13:52:39 +0100201}
202
Daniel Camporaf91f2122015-09-07 09:23:46 +0200203// Waits at most timeout microseconds for at least 1 char to become ready for
danicampora9e443832015-03-04 13:52:39 +0100204// reading (from buf or for direct reading).
205// Returns true if something available, false if not.
Daniel Camporaf91f2122015-09-07 09:23:46 +0200206STATIC bool uart_rx_wait (pyb_uart_obj_t *self) {
207 int timeout = PYBUART_RX_TIMEOUT_US(self->baudrate);
Daniel Campora2d717ad2015-03-26 10:25:28 +0100208 for ( ; ; ) {
danicampora9e443832015-03-04 13:52:39 +0100209 if (uart_rx_any(self)) {
Daniel Camporaf91f2122015-09-07 09:23:46 +0200210 return true; // we have at least 1 char ready for reading
danicampora9e443832015-03-04 13:52:39 +0100211 }
212 if (timeout > 0) {
Daniel Camporaf91f2122015-09-07 09:23:46 +0200213 UtilsDelay(UTILS_DELAY_US_TO_COUNT(1));
danicampora9e443832015-03-04 13:52:39 +0100214 timeout--;
215 }
216 else {
217 return false;
218 }
219 }
220}
221
Daniel Camporadbdcb582015-09-22 23:20:29 +0200222STATIC mp_obj_t uart_irq_new (pyb_uart_obj_t *self, byte trigger, mp_int_t priority, mp_obj_t handler) {
223 // disable the uart interrupts before updating anything
224 uart_irq_disable (self);
225
226 if (self->uart_id == PYB_UART_0) {
227 MAP_IntPrioritySet(INT_UARTA0, priority);
228 MAP_UARTIntRegister(self->reg, UART0IntHandler);
229 } else {
230 MAP_IntPrioritySet(INT_UARTA1, priority);
231 MAP_UARTIntRegister(self->reg, UART1IntHandler);
232 }
233
234 // create the callback
235 mp_obj_t _irq = mp_irq_new ((mp_obj_t)self, handler, &uart_irq_methods);
236
237 // enable the interrupts now
238 self->irq_trigger = trigger;
239 uart_irq_enable (self);
240 return _irq;
241}
242
danicampora87856452015-02-06 15:35:48 +0100243STATIC void UARTGenericIntHandler(uint32_t uart_id) {
danicampora6b21c3f2015-02-20 16:31:30 +0100244 pyb_uart_obj_t *self;
danicampora87856452015-02-06 15:35:48 +0100245 uint32_t status;
246
danicampora6de1b392015-03-17 11:05:59 +0100247 self = &pyb_uart_obj[uart_id];
248 status = MAP_UARTIntStatus(self->reg, true);
249 // receive interrupt
250 if (status & (UART_INT_RX | UART_INT_RT)) {
Daniel Camporadbdcb582015-09-22 23:20:29 +0200251 // set the flags
252 self->irq_flags = UART_TRIGGER_RX_ANY;
danicampora6de1b392015-03-17 11:05:59 +0100253 MAP_UARTIntClear(self->reg, UART_INT_RX | UART_INT_RT);
254 while (UARTCharsAvail(self->reg)) {
255 int data = MAP_UARTCharGetNonBlocking(self->reg);
Daniel Camporaef369242015-09-25 15:20:07 +0200256 if (MP_STATE_PORT(os_term_dup_obj) && MP_STATE_PORT(os_term_dup_obj)->stream_o == self && data == user_interrupt_char) {
Daniel Campora2d717ad2015-03-26 10:25:28 +0100257 // raise an exception when interrupts are finished
danicampora6de1b392015-03-17 11:05:59 +0100258 mpexception_keyboard_nlr_jump();
Daniel Camporaef369242015-09-25 15:20:07 +0200259 } else { // there's always a read buffer available
Daniel Camporaf91f2122015-09-07 09:23:46 +0200260 uint16_t next_head = (self->read_buf_head + 1) % PYBUART_RX_BUFFER_LEN;
danicampora6de1b392015-03-17 11:05:59 +0100261 if (next_head != self->read_buf_tail) {
262 // only store data if room in buf
263 self->read_buf[self->read_buf_head] = data;
264 self->read_buf_head = next_head;
danicampora87856452015-02-06 15:35:48 +0100265 }
266 }
267 }
Daniel Campora4d7fa052015-09-07 21:19:11 +0200268 }
Daniel Camporadbdcb582015-09-22 23:20:29 +0200269
270 // check the flags to see if the user handler should be called
271 if ((self->irq_trigger & self->irq_flags) && self->irq_enabled) {
272 // call the user defined handler
273 mp_irq_handler(mp_irq_find(self));
274 }
275
276 // clear the flags
277 self->irq_flags = 0;
Daniel Campora4d7fa052015-09-07 21:19:11 +0200278}
279
280STATIC void uart_check_init(pyb_uart_obj_t *self) {
281 // not initialized
282 if (!self->baudrate) {
283 nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
danicampora87856452015-02-06 15:35:48 +0100284 }
285}
286
287STATIC void UART0IntHandler(void) {
288 UARTGenericIntHandler(0);
289}
290
291STATIC void UART1IntHandler(void) {
292 UARTGenericIntHandler(1);
293}
294
Daniel Camporadbdcb582015-09-22 23:20:29 +0200295STATIC void uart_irq_enable (mp_obj_t self_in) {
Daniel Campora2d717ad2015-03-26 10:25:28 +0100296 pyb_uart_obj_t *self = self_in;
Daniel Camporaf91f2122015-09-07 09:23:46 +0200297 // check for any of the rx interrupt types
Daniel Camporadbdcb582015-09-22 23:20:29 +0200298 if (self->irq_trigger & (UART_TRIGGER_RX_ANY | UART_TRIGGER_RX_HALF | UART_TRIGGER_RX_FULL)) {
Daniel Camporaf91f2122015-09-07 09:23:46 +0200299 MAP_UARTIntClear(self->reg, UART_INT_RX | UART_INT_RT);
300 MAP_UARTIntEnable(self->reg, UART_INT_RX | UART_INT_RT);
301 }
Daniel Camporadbdcb582015-09-22 23:20:29 +0200302 self->irq_enabled = true;
Daniel Campora2d717ad2015-03-26 10:25:28 +0100303}
304
Daniel Camporadbdcb582015-09-22 23:20:29 +0200305STATIC void uart_irq_disable (mp_obj_t self_in) {
Daniel Campora2d717ad2015-03-26 10:25:28 +0100306 pyb_uart_obj_t *self = self_in;
Daniel Camporadbdcb582015-09-22 23:20:29 +0200307 self->irq_enabled = false;
308}
309
310STATIC int uart_irq_flags (mp_obj_t self_in) {
311 pyb_uart_obj_t *self = self_in;
312 return self->irq_flags;
Daniel Campora2d717ad2015-03-26 10:25:28 +0100313}
314
danicampora87856452015-02-06 15:35:48 +0100315/******************************************************************************/
316/* Micro Python bindings */
317
Damien George7f9d1d62015-04-09 23:56:15 +0100318STATIC void pyb_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
danicampora87856452015-02-06 15:35:48 +0100319 pyb_uart_obj_t *self = self_in;
Daniel Campora2d717ad2015-03-26 10:25:28 +0100320 if (self->baudrate > 0) {
Daniel Camporaf91f2122015-09-07 09:23:46 +0200321 mp_printf(print, "UART(%u, baudrate=%u, bits=", self->uart_id, self->baudrate);
danicampora87856452015-02-06 15:35:48 +0100322 switch (self->config & UART_CONFIG_WLEN_MASK) {
323 case UART_CONFIG_WLEN_5:
Damien George7f9d1d62015-04-09 23:56:15 +0100324 mp_print_str(print, "5");
danicampora87856452015-02-06 15:35:48 +0100325 break;
326 case UART_CONFIG_WLEN_6:
Damien George7f9d1d62015-04-09 23:56:15 +0100327 mp_print_str(print, "6");
danicampora87856452015-02-06 15:35:48 +0100328 break;
329 case UART_CONFIG_WLEN_7:
Damien George7f9d1d62015-04-09 23:56:15 +0100330 mp_print_str(print, "7");
danicampora87856452015-02-06 15:35:48 +0100331 break;
332 case UART_CONFIG_WLEN_8:
Damien George7f9d1d62015-04-09 23:56:15 +0100333 mp_print_str(print, "8");
danicampora87856452015-02-06 15:35:48 +0100334 break;
335 default:
336 break;
337 }
338 if ((self->config & UART_CONFIG_PAR_MASK) == UART_CONFIG_PAR_NONE) {
Damien George7f9d1d62015-04-09 23:56:15 +0100339 mp_print_str(print, ", parity=None");
danicampora87856452015-02-06 15:35:48 +0100340 } else {
Daniel Campora83320442015-09-13 15:59:45 +0200341 mp_printf(print, ", parity=UART.%q", (self->config & UART_CONFIG_PAR_MASK) == UART_CONFIG_PAR_EVEN ? MP_QSTR_EVEN : MP_QSTR_ODD);
danicampora87856452015-02-06 15:35:48 +0100342 }
Daniel Camporaf91f2122015-09-07 09:23:46 +0200343 mp_printf(print, ", stop=%u)", (self->config & UART_CONFIG_STOP_MASK) == UART_CONFIG_STOP_ONE ? 1 : 2);
danicampora87856452015-02-06 15:35:48 +0100344 }
Daniel Campora2d717ad2015-03-26 10:25:28 +0100345 else {
Daniel Camporaf91f2122015-09-07 09:23:46 +0200346 mp_printf(print, "UART(%u)", self->uart_id);
Daniel Campora2d717ad2015-03-26 10:25:28 +0100347 }
danicampora87856452015-02-06 15:35:48 +0100348}
349
Daniel Camporadffa9f62015-09-16 14:09:51 +0200350STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, const mp_arg_val_t *args) {
danicampora9e443832015-03-04 13:52:39 +0100351 // get the baudrate
Daniel Camporaf91f2122015-09-07 09:23:46 +0200352 if (args[0].u_int <= 0) {
353 goto error;
354 }
355 uint baudrate = args[0].u_int;
356 uint config;
357 switch (args[1].u_int) {
358 case 5:
359 config = UART_CONFIG_WLEN_5;
360 break;
361 case 6:
362 config = UART_CONFIG_WLEN_6;
363 break;
364 case 7:
365 config = UART_CONFIG_WLEN_7;
366 break;
367 case 8:
368 config = UART_CONFIG_WLEN_8;
369 break;
370 default:
371 goto error;
372 break;
373 }
374 // parity
375 if (args[2].u_obj == mp_const_none) {
376 config |= UART_CONFIG_PAR_NONE;
377 } else {
Daniel Campora83320442015-09-13 15:59:45 +0200378 uint parity = mp_obj_get_int(args[2].u_obj);
379 if (parity != UART_CONFIG_PAR_ODD && parity != UART_CONFIG_PAR_EVEN) {
380 goto error;
381 }
382 config |= parity;
Daniel Camporaf91f2122015-09-07 09:23:46 +0200383 }
384 // stop bits
385 config |= (args[3].u_int == 1 ? UART_CONFIG_STOP_ONE : UART_CONFIG_STOP_TWO);
danicampora9e443832015-03-04 13:52:39 +0100386
Daniel Campora359b4e92015-09-08 15:07:42 +0200387 // assign the pins
Daniel Camporaf91f2122015-09-07 09:23:46 +0200388 mp_obj_t pins_o = args[4].u_obj;
389 uint flowcontrol = UART_FLOWCONTROL_NONE;
390 if (pins_o != mp_const_none) {
Daniel Campora359b4e92015-09-08 15:07:42 +0200391 mp_obj_t *pins;
Daniel Camporaf352fe82015-09-09 22:42:42 +0200392 mp_uint_t n_pins = 2;
Daniel Camporaf91f2122015-09-07 09:23:46 +0200393 if (pins_o == MP_OBJ_NULL) {
394 // use the default pins
Daniel Campora359b4e92015-09-08 15:07:42 +0200395 pins = (mp_obj_t *)pyb_uart_def_pin[self->uart_id];
danicampora87856452015-02-06 15:35:48 +0100396 } else {
Daniel Campora359b4e92015-09-08 15:07:42 +0200397 mp_obj_get_array(pins_o, &n_pins, &pins);
Daniel Camporaf91f2122015-09-07 09:23:46 +0200398 if (n_pins != 2 && n_pins != 4) {
399 goto error;
400 }
401 if (n_pins == 4) {
Daniel Campora359b4e92015-09-08 15:07:42 +0200402 if (pins[PIN_TYPE_UART_RTS] != mp_const_none && pins[PIN_TYPE_UART_RX] == mp_const_none) {
Daniel Camporaf91f2122015-09-07 09:23:46 +0200403 goto error; // RTS pin given in TX only mode
Daniel Campora359b4e92015-09-08 15:07:42 +0200404 } else if (pins[PIN_TYPE_UART_CTS] != mp_const_none && pins[PIN_TYPE_UART_TX] == mp_const_none) {
Daniel Camporaf91f2122015-09-07 09:23:46 +0200405 goto error; // CTS pin given in RX only mode
406 } else {
Daniel Campora359b4e92015-09-08 15:07:42 +0200407 if (pins[PIN_TYPE_UART_RTS] != mp_const_none) {
Daniel Camporaf91f2122015-09-07 09:23:46 +0200408 flowcontrol |= UART_FLOWCONTROL_RX;
409 }
Daniel Campora359b4e92015-09-08 15:07:42 +0200410 if (pins[PIN_TYPE_UART_CTS] != mp_const_none) {
Daniel Camporaf91f2122015-09-07 09:23:46 +0200411 flowcontrol |= UART_FLOWCONTROL_TX;
412 }
413 }
414 }
danicampora87856452015-02-06 15:35:48 +0100415 }
Daniel Campora359b4e92015-09-08 15:07:42 +0200416 pin_assign_pins_af (pins, n_pins, PIN_TYPE_STD_PU, PIN_FN_UART, self->uart_id);
danicampora87856452015-02-06 15:35:48 +0100417 }
Daniel Camporaf91f2122015-09-07 09:23:46 +0200418
419 self->baudrate = baudrate;
420 self->config = config;
421 self->flowcontrol = flowcontrol;
Daniel Campora2d717ad2015-03-26 10:25:28 +0100422
danicampora9e443832015-03-04 13:52:39 +0100423 // initialize and enable the uart
424 uart_init (self);
danicampora9e443832015-03-04 13:52:39 +0100425 // register it with the sleep module
Daniel Camporac92e6a42015-09-27 13:45:48 +0200426 pyb_sleep_add ((const mp_obj_t)self, (WakeUpCB_t)uart_init);
Daniel Campora4d7fa052015-09-07 21:19:11 +0200427 // enable the callback
Daniel Camporadbdcb582015-09-22 23:20:29 +0200428 uart_irq_new (self, UART_TRIGGER_RX_ANY, INT_PRIORITY_LVL_3, mp_const_none);
429 // disable the irq (from the user point of view)
430 uart_irq_disable(self);
danicampora87856452015-02-06 15:35:48 +0100431
danicampora87856452015-02-06 15:35:48 +0100432 return mp_const_none;
Daniel Campora8a6d93a2015-06-09 16:15:23 +0200433
434error:
435 nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
danicampora87856452015-02-06 15:35:48 +0100436}
437
Daniel Campora7d6b6f62015-09-11 09:33:19 +0200438STATIC const mp_arg_t pyb_uart_init_args[] = {
Daniel Campora57fa14b2015-09-26 22:55:24 +0200439 { MP_QSTR_id, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
Daniel Campora7d6b6f62015-09-11 09:33:19 +0200440 { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 9600} },
441 { MP_QSTR_bits, MP_ARG_INT, {.u_int = 8} },
442 { MP_QSTR_parity, MP_ARG_OBJ, {.u_obj = mp_const_none} },
443 { MP_QSTR_stop, MP_ARG_INT, {.u_int = 1} },
444 { MP_QSTR_pins, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
445};
Damien George5b3f0b72016-01-03 15:55:55 +0000446STATIC mp_obj_t pyb_uart_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
Daniel Campora7d6b6f62015-09-11 09:33:19 +0200447 // parse args
448 mp_map_t kw_args;
449 mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
450 mp_arg_val_t args[MP_ARRAY_SIZE(pyb_uart_init_args)];
451 mp_arg_parse_all(n_args, all_args, &kw_args, MP_ARRAY_SIZE(args), pyb_uart_init_args, args);
danicampora87856452015-02-06 15:35:48 +0100452
danicampora6b21c3f2015-02-20 16:31:30 +0100453 // work out the uart id
Daniel Camporaaba75e12015-09-13 21:44:09 +0200454 uint uart_id;
Daniel Campora57fa14b2015-09-26 22:55:24 +0200455 if (args[0].u_obj == MP_OBJ_NULL) {
Daniel Campora7d6b6f62015-09-11 09:33:19 +0200456 if (args[5].u_obj != MP_OBJ_NULL) {
457 mp_obj_t *pins;
458 mp_uint_t n_pins = 2;
459 mp_obj_get_array(args[5].u_obj, &n_pins, &pins);
460 // check the Tx pin (or the Rx if Tx is None)
461 if (pins[0] == mp_const_none) {
462 uart_id = pin_find_peripheral_unit(pins[1], PIN_FN_UART, PIN_TYPE_UART_RX);
463 } else {
464 uart_id = pin_find_peripheral_unit(pins[0], PIN_FN_UART, PIN_TYPE_UART_TX);
465 }
466 } else {
467 // default id
468 uart_id = 0;
469 }
470 } else {
471 uart_id = mp_obj_get_int(args[0].u_obj);
472 }
danicampora87856452015-02-06 15:35:48 +0100473
Daniel Camporaaba75e12015-09-13 21:44:09 +0200474 if (uart_id > PYB_UART_1) {
danicampora87856452015-02-06 15:35:48 +0100475 nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
476 }
477
danicampora6de1b392015-03-17 11:05:59 +0100478 // get the correct uart instance
479 pyb_uart_obj_t *self = &pyb_uart_obj[uart_id];
480 self->base.type = &pyb_uart_type;
481 self->uart_id = uart_id;
Daniel Campora8e611e82015-05-09 17:46:16 +0200482
Daniel Campora7d6b6f62015-09-11 09:33:19 +0200483 // start the peripheral
484 pyb_uart_init_helper(self, &args[1]);
danicampora87856452015-02-06 15:35:48 +0100485
486 return self;
487}
488
Daniel Campora7d6b6f62015-09-11 09:33:19 +0200489STATIC mp_obj_t pyb_uart_init(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
490 // parse args
491 mp_arg_val_t args[MP_ARRAY_SIZE(pyb_uart_init_args) - 1];
492 mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), &pyb_uart_init_args[1], args);
493 return pyb_uart_init_helper(pos_args[0], args);
danicampora87856452015-02-06 15:35:48 +0100494}
495STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_uart_init_obj, 1, pyb_uart_init);
496
Daniel Campora8e611e82015-05-09 17:46:16 +0200497STATIC mp_obj_t pyb_uart_deinit(mp_obj_t self_in) {
danicampora87856452015-02-06 15:35:48 +0100498 pyb_uart_obj_t *self = self_in;
danicampora87856452015-02-06 15:35:48 +0100499
danicamporad226dd22015-02-27 16:50:06 +0100500 // unregister it with the sleep module
Daniel Camporac92e6a42015-09-27 13:45:48 +0200501 pyb_sleep_remove (self);
Daniel Campora2d717ad2015-03-26 10:25:28 +0100502 // invalidate the baudrate
503 self->baudrate = 0;
Daniel Camporaf91f2122015-09-07 09:23:46 +0200504 // free the read buffer
505 m_del(byte, self->read_buf, PYBUART_RX_BUFFER_LEN);
danicampora87856452015-02-06 15:35:48 +0100506 MAP_UARTIntDisable(self->reg, UART_INT_RX | UART_INT_RT);
danicampora87856452015-02-06 15:35:48 +0100507 MAP_UARTDisable(self->reg);
Daniel Campora2d717ad2015-03-26 10:25:28 +0100508 MAP_PRCMPeripheralClkDisable(self->peripheral, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
danicampora87856452015-02-06 15:35:48 +0100509 return mp_const_none;
510}
511STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_deinit_obj, pyb_uart_deinit);
512
danicampora87856452015-02-06 15:35:48 +0100513STATIC mp_obj_t pyb_uart_any(mp_obj_t self_in) {
514 pyb_uart_obj_t *self = self_in;
Daniel Campora4d7fa052015-09-07 21:19:11 +0200515 uart_check_init(self);
Daniel Camporaf91f2122015-09-07 09:23:46 +0200516 return mp_obj_new_int(uart_rx_any(self));
danicampora87856452015-02-06 15:35:48 +0100517}
518STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_any_obj, pyb_uart_any);
519
Daniel Camporaf91f2122015-09-07 09:23:46 +0200520STATIC mp_obj_t pyb_uart_sendbreak(mp_obj_t self_in) {
521 pyb_uart_obj_t *self = self_in;
Daniel Campora4d7fa052015-09-07 21:19:11 +0200522 uart_check_init(self);
Daniel Camporaf91f2122015-09-07 09:23:46 +0200523 // send a break signal for at least 2 complete frames
524 MAP_UARTBreakCtl(self->reg, true);
525 UtilsDelay(UTILS_DELAY_US_TO_COUNT(PYBUART_2_FRAMES_TIME_US(self->baudrate)));
526 MAP_UARTBreakCtl(self->reg, false);
527 return mp_const_none;
528}
529STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_sendbreak_obj, pyb_uart_sendbreak);
530
Daniel Camporadbdcb582015-09-22 23:20:29 +0200531/// \method irq(trigger, priority, handler, wake)
532STATIC mp_obj_t pyb_uart_irq (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
533 mp_arg_val_t args[mp_irq_INIT_NUM_ARGS];
534 mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, mp_irq_INIT_NUM_ARGS, mp_irq_init_args, args);
Daniel Campora2d717ad2015-03-26 10:25:28 +0100535
536 // check if any parameters were passed
537 pyb_uart_obj_t *self = pos_args[0];
Daniel Campora4d7fa052015-09-07 21:19:11 +0200538 uart_check_init(self);
Daniel Campora2d717ad2015-03-26 10:25:28 +0100539
Daniel Camporadbdcb582015-09-22 23:20:29 +0200540 // convert the priority to the correct value
541 uint priority = mp_irq_translate_priority (args[1].u_int);
Daniel Campora2d717ad2015-03-26 10:25:28 +0100542
Daniel Camporadbdcb582015-09-22 23:20:29 +0200543 // check the power mode
544 uint8_t pwrmode = (args[3].u_obj == mp_const_none) ? PYB_PWR_MODE_ACTIVE : mp_obj_get_int(args[3].u_obj);
545 if (PYB_PWR_MODE_ACTIVE != pwrmode) {
546 goto invalid_args;
Daniel Campora2d717ad2015-03-26 10:25:28 +0100547 }
Daniel Camporadbdcb582015-09-22 23:20:29 +0200548
549 // check the trigger
550 uint trigger = mp_obj_get_int(args[0].u_obj);
551 if (!trigger || trigger > (UART_TRIGGER_RX_ANY | UART_TRIGGER_RX_HALF | UART_TRIGGER_RX_FULL | UART_TRIGGER_TX_DONE)) {
552 goto invalid_args;
553 }
554
555 // register a new callback
556 return uart_irq_new (self, trigger, priority, args[2].u_obj);
557
558invalid_args:
559 nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
Daniel Campora2d717ad2015-03-26 10:25:28 +0100560}
danicampora45426432015-10-14 12:32:01 +0200561STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_uart_irq_obj, 1, pyb_uart_irq);
Daniel Campora2d717ad2015-03-26 10:25:28 +0100562
danicampora87856452015-02-06 15:35:48 +0100563STATIC const mp_map_elem_t pyb_uart_locals_dict_table[] = {
564 // instance methods
danicampora87856452015-02-06 15:35:48 +0100565 { MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_uart_init_obj },
566 { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&pyb_uart_deinit_obj },
567 { MP_OBJ_NEW_QSTR(MP_QSTR_any), (mp_obj_t)&pyb_uart_any_obj },
Daniel Camporaf91f2122015-09-07 09:23:46 +0200568 { MP_OBJ_NEW_QSTR(MP_QSTR_sendbreak), (mp_obj_t)&pyb_uart_sendbreak_obj },
danicampora45426432015-10-14 12:32:01 +0200569 { MP_OBJ_NEW_QSTR(MP_QSTR_irq), (mp_obj_t)&pyb_uart_irq_obj },
danicampora87856452015-02-06 15:35:48 +0100570
571 /// \method read([nbytes])
572 { MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mp_stream_read_obj },
573 /// \method readall()
574 { MP_OBJ_NEW_QSTR(MP_QSTR_readall), (mp_obj_t)&mp_stream_readall_obj },
575 /// \method readline()
576 { MP_OBJ_NEW_QSTR(MP_QSTR_readline), (mp_obj_t)&mp_stream_unbuffered_readline_obj},
577 /// \method readinto(buf[, nbytes])
578 { MP_OBJ_NEW_QSTR(MP_QSTR_readinto), (mp_obj_t)&mp_stream_readinto_obj },
579 /// \method write(buf)
580 { MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&mp_stream_write_obj },
581
danicampora87856452015-02-06 15:35:48 +0100582 // class constants
Daniel Campora83320442015-09-13 15:59:45 +0200583 { MP_OBJ_NEW_QSTR(MP_QSTR_EVEN), MP_OBJ_NEW_SMALL_INT(UART_CONFIG_PAR_EVEN) },
584 { MP_OBJ_NEW_QSTR(MP_QSTR_ODD), MP_OBJ_NEW_SMALL_INT(UART_CONFIG_PAR_ODD) },
Daniel Camporadbdcb582015-09-22 23:20:29 +0200585 { MP_OBJ_NEW_QSTR(MP_QSTR_RX_ANY), MP_OBJ_NEW_SMALL_INT(UART_TRIGGER_RX_ANY) },
danicampora87856452015-02-06 15:35:48 +0100586};
587
588STATIC MP_DEFINE_CONST_DICT(pyb_uart_locals_dict, pyb_uart_locals_dict_table);
589
590STATIC mp_uint_t pyb_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
591 pyb_uart_obj_t *self = self_in;
592 byte *buf = buf_in;
Daniel Campora4d7fa052015-09-07 21:19:11 +0200593 uart_check_init(self);
danicampora87856452015-02-06 15:35:48 +0100594
595 // make sure we want at least 1 char
596 if (size == 0) {
597 return 0;
598 }
599
600 // wait for first char to become available
Daniel Camporaf91f2122015-09-07 09:23:46 +0200601 if (!uart_rx_wait(self)) {
danicampora7ff58532015-10-20 09:27:21 +0200602 // return EAGAIN error to indicate non-blocking (then read() method returns None)
603 *errcode = EAGAIN;
604 return MP_STREAM_ERROR;
danicampora87856452015-02-06 15:35:48 +0100605 }
606
607 // read the data
608 byte *orig_buf = buf;
Daniel Campora2d717ad2015-03-26 10:25:28 +0100609 for ( ; ; ) {
danicampora87856452015-02-06 15:35:48 +0100610 *buf++ = uart_rx_char(self);
Daniel Camporaf91f2122015-09-07 09:23:46 +0200611 if (--size == 0 || !uart_rx_wait(self)) {
danicampora87856452015-02-06 15:35:48 +0100612 // return number of bytes read
613 return buf - orig_buf;
614 }
615 }
616}
617
618STATIC mp_uint_t pyb_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) {
619 pyb_uart_obj_t *self = self_in;
620 const char *buf = buf_in;
Daniel Campora4d7fa052015-09-07 21:19:11 +0200621 uart_check_init(self);
danicampora87856452015-02-06 15:35:48 +0100622
623 // write the data
624 if (!uart_tx_strn(self, buf, size)) {
Daniel Camporafabe79f2015-05-26 12:27:13 +0200625 nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
danicampora87856452015-02-06 15:35:48 +0100626 }
627 return size;
628}
629
630STATIC mp_uint_t pyb_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) {
631 pyb_uart_obj_t *self = self_in;
632 mp_uint_t ret;
Daniel Campora4d7fa052015-09-07 21:19:11 +0200633 uart_check_init(self);
634
danicampora87856452015-02-06 15:35:48 +0100635 if (request == MP_IOCTL_POLL) {
636 mp_uint_t flags = arg;
637 ret = 0;
638 if ((flags & MP_IOCTL_POLL_RD) && uart_rx_any(self)) {
639 ret |= MP_IOCTL_POLL_RD;
640 }
641 if ((flags & MP_IOCTL_POLL_WR) && MAP_UARTSpaceAvail(self->reg)) {
642 ret |= MP_IOCTL_POLL_WR;
643 }
644 } else {
645 *errcode = EINVAL;
646 ret = MP_STREAM_ERROR;
647 }
648 return ret;
649}
650
651STATIC const mp_stream_p_t uart_stream_p = {
652 .read = pyb_uart_read,
653 .write = pyb_uart_write,
654 .ioctl = pyb_uart_ioctl,
655 .is_text = false,
656};
657
Daniel Camporadbdcb582015-09-22 23:20:29 +0200658STATIC const mp_irq_methods_t uart_irq_methods = {
659 .init = pyb_uart_irq,
660 .enable = uart_irq_enable,
661 .disable = uart_irq_disable,
662 .flags = uart_irq_flags
Daniel Campora2d717ad2015-03-26 10:25:28 +0100663};
664
danicampora87856452015-02-06 15:35:48 +0100665const mp_obj_type_t pyb_uart_type = {
666 { &mp_type_type },
667 .name = MP_QSTR_UART,
668 .print = pyb_uart_print,
669 .make_new = pyb_uart_make_new,
670 .getiter = mp_identity,
671 .iternext = mp_stream_unbuffered_iter,
672 .stream_p = &uart_stream_p,
673 .locals_dict = (mp_obj_t)&pyb_uart_locals_dict,
674};