pybuart.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669
  1. /*
  2. * This file is part of the MicroPython 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. #include <stdint.h>
  28. #include <stdio.h>
  29. #include <string.h>
  30. #include "py/runtime.h"
  31. #include "py/objlist.h"
  32. #include "py/stream.h"
  33. #include "py/mphal.h"
  34. #include "lib/utils/interrupt_char.h"
  35. #include "inc/hw_types.h"
  36. #include "inc/hw_ints.h"
  37. #include "inc/hw_memmap.h"
  38. #include "inc/hw_uart.h"
  39. #include "rom_map.h"
  40. #include "interrupt.h"
  41. #include "prcm.h"
  42. #include "uart.h"
  43. #include "pybuart.h"
  44. #include "mpirq.h"
  45. #include "pybsleep.h"
  46. #include "mpexception.h"
  47. #include "osi.h"
  48. #include "utils.h"
  49. #include "pin.h"
  50. #include "pybpin.h"
  51. #include "pins.h"
  52. #include "moduos.h"
  53. /// \moduleref pyb
  54. /// \class UART - duplex serial communication bus
  55. /******************************************************************************
  56. DEFINE CONSTANTS
  57. *******-***********************************************************************/
  58. #define PYBUART_FRAME_TIME_US(baud) ((11 * 1000000) / baud)
  59. #define PYBUART_2_FRAMES_TIME_US(baud) (PYBUART_FRAME_TIME_US(baud) * 2)
  60. #define PYBUART_RX_TIMEOUT_US(baud) (PYBUART_2_FRAMES_TIME_US(baud) * 8) // we need at least characters in the FIFO
  61. #define PYBUART_TX_WAIT_US(baud) ((PYBUART_FRAME_TIME_US(baud)) + 1)
  62. #define PYBUART_TX_MAX_TIMEOUT_MS (5)
  63. #define PYBUART_RX_BUFFER_LEN (256)
  64. // interrupt triggers
  65. #define UART_TRIGGER_RX_ANY (0x01)
  66. #define UART_TRIGGER_RX_HALF (0x02)
  67. #define UART_TRIGGER_RX_FULL (0x04)
  68. #define UART_TRIGGER_TX_DONE (0x08)
  69. /******************************************************************************
  70. DECLARE PRIVATE FUNCTIONS
  71. ******************************************************************************/
  72. STATIC void uart_init (pyb_uart_obj_t *self);
  73. STATIC bool uart_rx_wait (pyb_uart_obj_t *self);
  74. STATIC void uart_check_init(pyb_uart_obj_t *self);
  75. STATIC mp_obj_t uart_irq_new (pyb_uart_obj_t *self, byte trigger, mp_int_t priority, mp_obj_t handler);
  76. STATIC void UARTGenericIntHandler(uint32_t uart_id);
  77. STATIC void UART0IntHandler(void);
  78. STATIC void UART1IntHandler(void);
  79. STATIC void uart_irq_enable (mp_obj_t self_in);
  80. STATIC void uart_irq_disable (mp_obj_t self_in);
  81. /******************************************************************************
  82. DEFINE PRIVATE TYPES
  83. ******************************************************************************/
  84. struct _pyb_uart_obj_t {
  85. mp_obj_base_t base;
  86. pyb_uart_id_t uart_id;
  87. uint reg;
  88. uint baudrate;
  89. uint config;
  90. uint flowcontrol;
  91. byte *read_buf; // read buffer pointer
  92. volatile uint16_t read_buf_head; // indexes first empty slot
  93. uint16_t read_buf_tail; // indexes first full slot (not full if equals head)
  94. byte peripheral;
  95. byte irq_trigger;
  96. bool irq_enabled;
  97. byte irq_flags;
  98. };
  99. /******************************************************************************
  100. DECLARE PRIVATE DATA
  101. ******************************************************************************/
  102. STATIC pyb_uart_obj_t pyb_uart_obj[PYB_NUM_UARTS] = { {.reg = UARTA0_BASE, .baudrate = 0, .read_buf = NULL, .peripheral = PRCM_UARTA0},
  103. {.reg = UARTA1_BASE, .baudrate = 0, .read_buf = NULL, .peripheral = PRCM_UARTA1} };
  104. STATIC const mp_irq_methods_t uart_irq_methods;
  105. STATIC const mp_obj_t pyb_uart_def_pin[PYB_NUM_UARTS][2] = { {&pin_GP1, &pin_GP2}, {&pin_GP3, &pin_GP4} };
  106. /******************************************************************************
  107. DEFINE PUBLIC FUNCTIONS
  108. ******************************************************************************/
  109. void uart_init0 (void) {
  110. // save references of the UART objects, to prevent the read buffers from being trashed by the gc
  111. MP_STATE_PORT(pyb_uart_objs)[0] = &pyb_uart_obj[0];
  112. MP_STATE_PORT(pyb_uart_objs)[1] = &pyb_uart_obj[1];
  113. }
  114. uint32_t uart_rx_any(pyb_uart_obj_t *self) {
  115. if (self->read_buf_tail != self->read_buf_head) {
  116. // buffering via irq
  117. return (self->read_buf_head > self->read_buf_tail) ? self->read_buf_head - self->read_buf_tail :
  118. PYBUART_RX_BUFFER_LEN - self->read_buf_tail + self->read_buf_head;
  119. }
  120. return MAP_UARTCharsAvail(self->reg) ? 1 : 0;
  121. }
  122. int uart_rx_char(pyb_uart_obj_t *self) {
  123. if (self->read_buf_tail != self->read_buf_head) {
  124. // buffering via irq
  125. int data = self->read_buf[self->read_buf_tail];
  126. self->read_buf_tail = (self->read_buf_tail + 1) % PYBUART_RX_BUFFER_LEN;
  127. return data;
  128. } else {
  129. // no buffering
  130. return MAP_UARTCharGetNonBlocking(self->reg);
  131. }
  132. }
  133. bool uart_tx_char(pyb_uart_obj_t *self, int c) {
  134. uint32_t timeout = 0;
  135. while (!MAP_UARTCharPutNonBlocking(self->reg, c)) {
  136. if (timeout++ > ((PYBUART_TX_MAX_TIMEOUT_MS * 1000) / PYBUART_TX_WAIT_US(self->baudrate))) {
  137. return false;
  138. }
  139. UtilsDelay(UTILS_DELAY_US_TO_COUNT(PYBUART_TX_WAIT_US(self->baudrate)));
  140. }
  141. return true;
  142. }
  143. bool uart_tx_strn(pyb_uart_obj_t *self, const char *str, uint len) {
  144. for (const char *top = str + len; str < top; str++) {
  145. if (!uart_tx_char(self, *str)) {
  146. return false;
  147. }
  148. }
  149. return true;
  150. }
  151. /******************************************************************************
  152. DEFINE PRIVATE FUNCTIONS
  153. ******************************************************************************/
  154. // assumes init parameters have been set up correctly
  155. STATIC void uart_init (pyb_uart_obj_t *self) {
  156. // Enable the peripheral clock
  157. MAP_PRCMPeripheralClkEnable(self->peripheral, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
  158. // Reset the uart
  159. MAP_PRCMPeripheralReset(self->peripheral);
  160. // re-allocate the read buffer after resetting the uart (which automatically disables any irqs)
  161. self->read_buf_head = 0;
  162. self->read_buf_tail = 0;
  163. self->read_buf = MP_OBJ_NULL; // free the read buffer before allocating again
  164. self->read_buf = m_new(byte, PYBUART_RX_BUFFER_LEN);
  165. // Initialize the UART
  166. MAP_UARTConfigSetExpClk(self->reg, MAP_PRCMPeripheralClockGet(self->peripheral),
  167. self->baudrate, self->config);
  168. // Enable the FIFO
  169. MAP_UARTFIFOEnable(self->reg);
  170. // Configure the FIFO interrupt levels
  171. MAP_UARTFIFOLevelSet(self->reg, UART_FIFO_TX4_8, UART_FIFO_RX4_8);
  172. // Configure the flow control mode
  173. UARTFlowControlSet(self->reg, self->flowcontrol);
  174. }
  175. // Waits at most timeout microseconds for at least 1 char to become ready for
  176. // reading (from buf or for direct reading).
  177. // Returns true if something available, false if not.
  178. STATIC bool uart_rx_wait (pyb_uart_obj_t *self) {
  179. int timeout = PYBUART_RX_TIMEOUT_US(self->baudrate);
  180. for ( ; ; ) {
  181. if (uart_rx_any(self)) {
  182. return true; // we have at least 1 char ready for reading
  183. }
  184. if (timeout > 0) {
  185. UtilsDelay(UTILS_DELAY_US_TO_COUNT(1));
  186. timeout--;
  187. }
  188. else {
  189. return false;
  190. }
  191. }
  192. }
  193. STATIC mp_obj_t uart_irq_new (pyb_uart_obj_t *self, byte trigger, mp_int_t priority, mp_obj_t handler) {
  194. // disable the uart interrupts before updating anything
  195. uart_irq_disable (self);
  196. if (self->uart_id == PYB_UART_0) {
  197. MAP_IntPrioritySet(INT_UARTA0, priority);
  198. MAP_UARTIntRegister(self->reg, UART0IntHandler);
  199. } else {
  200. MAP_IntPrioritySet(INT_UARTA1, priority);
  201. MAP_UARTIntRegister(self->reg, UART1IntHandler);
  202. }
  203. // create the callback
  204. mp_obj_t _irq = mp_irq_new ((mp_obj_t)self, handler, &uart_irq_methods);
  205. // enable the interrupts now
  206. self->irq_trigger = trigger;
  207. uart_irq_enable (self);
  208. return _irq;
  209. }
  210. STATIC void UARTGenericIntHandler(uint32_t uart_id) {
  211. pyb_uart_obj_t *self;
  212. uint32_t status;
  213. self = &pyb_uart_obj[uart_id];
  214. status = MAP_UARTIntStatus(self->reg, true);
  215. // receive interrupt
  216. if (status & (UART_INT_RX | UART_INT_RT)) {
  217. // set the flags
  218. self->irq_flags = UART_TRIGGER_RX_ANY;
  219. MAP_UARTIntClear(self->reg, UART_INT_RX | UART_INT_RT);
  220. while (UARTCharsAvail(self->reg)) {
  221. int data = MAP_UARTCharGetNonBlocking(self->reg);
  222. if (MP_STATE_PORT(os_term_dup_obj) && MP_STATE_PORT(os_term_dup_obj)->stream_o == self && data == mp_interrupt_char) {
  223. // raise an exception when interrupts are finished
  224. mp_keyboard_interrupt();
  225. } else { // there's always a read buffer available
  226. uint16_t next_head = (self->read_buf_head + 1) % PYBUART_RX_BUFFER_LEN;
  227. if (next_head != self->read_buf_tail) {
  228. // only store data if room in buf
  229. self->read_buf[self->read_buf_head] = data;
  230. self->read_buf_head = next_head;
  231. }
  232. }
  233. }
  234. }
  235. // check the flags to see if the user handler should be called
  236. if ((self->irq_trigger & self->irq_flags) && self->irq_enabled) {
  237. // call the user defined handler
  238. mp_irq_handler(mp_irq_find(self));
  239. }
  240. // clear the flags
  241. self->irq_flags = 0;
  242. }
  243. STATIC void uart_check_init(pyb_uart_obj_t *self) {
  244. // not initialized
  245. if (!self->baudrate) {
  246. mp_raise_OSError(MP_EPERM);
  247. }
  248. }
  249. STATIC void UART0IntHandler(void) {
  250. UARTGenericIntHandler(0);
  251. }
  252. STATIC void UART1IntHandler(void) {
  253. UARTGenericIntHandler(1);
  254. }
  255. STATIC void uart_irq_enable (mp_obj_t self_in) {
  256. pyb_uart_obj_t *self = self_in;
  257. // check for any of the rx interrupt types
  258. if (self->irq_trigger & (UART_TRIGGER_RX_ANY | UART_TRIGGER_RX_HALF | UART_TRIGGER_RX_FULL)) {
  259. MAP_UARTIntClear(self->reg, UART_INT_RX | UART_INT_RT);
  260. MAP_UARTIntEnable(self->reg, UART_INT_RX | UART_INT_RT);
  261. }
  262. self->irq_enabled = true;
  263. }
  264. STATIC void uart_irq_disable (mp_obj_t self_in) {
  265. pyb_uart_obj_t *self = self_in;
  266. self->irq_enabled = false;
  267. }
  268. STATIC int uart_irq_flags (mp_obj_t self_in) {
  269. pyb_uart_obj_t *self = self_in;
  270. return self->irq_flags;
  271. }
  272. /******************************************************************************/
  273. /* MicroPython bindings */
  274. STATIC void pyb_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
  275. pyb_uart_obj_t *self = self_in;
  276. if (self->baudrate > 0) {
  277. mp_printf(print, "UART(%u, baudrate=%u, bits=", self->uart_id, self->baudrate);
  278. switch (self->config & UART_CONFIG_WLEN_MASK) {
  279. case UART_CONFIG_WLEN_5:
  280. mp_print_str(print, "5");
  281. break;
  282. case UART_CONFIG_WLEN_6:
  283. mp_print_str(print, "6");
  284. break;
  285. case UART_CONFIG_WLEN_7:
  286. mp_print_str(print, "7");
  287. break;
  288. case UART_CONFIG_WLEN_8:
  289. mp_print_str(print, "8");
  290. break;
  291. default:
  292. break;
  293. }
  294. if ((self->config & UART_CONFIG_PAR_MASK) == UART_CONFIG_PAR_NONE) {
  295. mp_print_str(print, ", parity=None");
  296. } else {
  297. mp_printf(print, ", parity=UART.%q", (self->config & UART_CONFIG_PAR_MASK) == UART_CONFIG_PAR_EVEN ? MP_QSTR_EVEN : MP_QSTR_ODD);
  298. }
  299. mp_printf(print, ", stop=%u)", (self->config & UART_CONFIG_STOP_MASK) == UART_CONFIG_STOP_ONE ? 1 : 2);
  300. }
  301. else {
  302. mp_printf(print, "UART(%u)", self->uart_id);
  303. }
  304. }
  305. STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, const mp_arg_val_t *args) {
  306. // get the baudrate
  307. if (args[0].u_int <= 0) {
  308. goto error;
  309. }
  310. uint baudrate = args[0].u_int;
  311. uint config;
  312. switch (args[1].u_int) {
  313. case 5:
  314. config = UART_CONFIG_WLEN_5;
  315. break;
  316. case 6:
  317. config = UART_CONFIG_WLEN_6;
  318. break;
  319. case 7:
  320. config = UART_CONFIG_WLEN_7;
  321. break;
  322. case 8:
  323. config = UART_CONFIG_WLEN_8;
  324. break;
  325. default:
  326. goto error;
  327. break;
  328. }
  329. // parity
  330. if (args[2].u_obj == mp_const_none) {
  331. config |= UART_CONFIG_PAR_NONE;
  332. } else {
  333. uint parity = mp_obj_get_int(args[2].u_obj);
  334. if (parity == 0) {
  335. config |= UART_CONFIG_PAR_EVEN;
  336. } else if (parity == 1) {
  337. config |= UART_CONFIG_PAR_ODD;
  338. } else {
  339. goto error;
  340. }
  341. }
  342. // stop bits
  343. config |= (args[3].u_int == 1 ? UART_CONFIG_STOP_ONE : UART_CONFIG_STOP_TWO);
  344. // assign the pins
  345. mp_obj_t pins_o = args[4].u_obj;
  346. uint flowcontrol = UART_FLOWCONTROL_NONE;
  347. if (pins_o != mp_const_none) {
  348. mp_obj_t *pins;
  349. size_t n_pins = 2;
  350. if (pins_o == MP_OBJ_NULL) {
  351. // use the default pins
  352. pins = (mp_obj_t *)pyb_uart_def_pin[self->uart_id];
  353. } else {
  354. mp_obj_get_array(pins_o, &n_pins, &pins);
  355. if (n_pins != 2 && n_pins != 4) {
  356. goto error;
  357. }
  358. if (n_pins == 4) {
  359. if (pins[PIN_TYPE_UART_RTS] != mp_const_none && pins[PIN_TYPE_UART_RX] == mp_const_none) {
  360. goto error; // RTS pin given in TX only mode
  361. } else if (pins[PIN_TYPE_UART_CTS] != mp_const_none && pins[PIN_TYPE_UART_TX] == mp_const_none) {
  362. goto error; // CTS pin given in RX only mode
  363. } else {
  364. if (pins[PIN_TYPE_UART_RTS] != mp_const_none) {
  365. flowcontrol |= UART_FLOWCONTROL_RX;
  366. }
  367. if (pins[PIN_TYPE_UART_CTS] != mp_const_none) {
  368. flowcontrol |= UART_FLOWCONTROL_TX;
  369. }
  370. }
  371. }
  372. }
  373. pin_assign_pins_af (pins, n_pins, PIN_TYPE_STD_PU, PIN_FN_UART, self->uart_id);
  374. }
  375. self->baudrate = baudrate;
  376. self->config = config;
  377. self->flowcontrol = flowcontrol;
  378. // initialize and enable the uart
  379. uart_init (self);
  380. // register it with the sleep module
  381. pyb_sleep_add ((const mp_obj_t)self, (WakeUpCB_t)uart_init);
  382. // enable the callback
  383. uart_irq_new (self, UART_TRIGGER_RX_ANY, INT_PRIORITY_LVL_3, mp_const_none);
  384. // disable the irq (from the user point of view)
  385. uart_irq_disable(self);
  386. return mp_const_none;
  387. error:
  388. mp_raise_ValueError(mpexception_value_invalid_arguments);
  389. }
  390. STATIC const mp_arg_t pyb_uart_init_args[] = {
  391. { MP_QSTR_id, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
  392. { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 9600} },
  393. { MP_QSTR_bits, MP_ARG_INT, {.u_int = 8} },
  394. { MP_QSTR_parity, MP_ARG_OBJ, {.u_obj = mp_const_none} },
  395. { MP_QSTR_stop, MP_ARG_INT, {.u_int = 1} },
  396. { MP_QSTR_pins, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
  397. };
  398. STATIC mp_obj_t pyb_uart_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
  399. // parse args
  400. mp_map_t kw_args;
  401. mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
  402. mp_arg_val_t args[MP_ARRAY_SIZE(pyb_uart_init_args)];
  403. mp_arg_parse_all(n_args, all_args, &kw_args, MP_ARRAY_SIZE(args), pyb_uart_init_args, args);
  404. // work out the uart id
  405. uint uart_id;
  406. if (args[0].u_obj == MP_OBJ_NULL) {
  407. if (args[5].u_obj != MP_OBJ_NULL) {
  408. mp_obj_t *pins;
  409. size_t n_pins = 2;
  410. mp_obj_get_array(args[5].u_obj, &n_pins, &pins);
  411. // check the Tx pin (or the Rx if Tx is None)
  412. if (pins[0] == mp_const_none) {
  413. uart_id = pin_find_peripheral_unit(pins[1], PIN_FN_UART, PIN_TYPE_UART_RX);
  414. } else {
  415. uart_id = pin_find_peripheral_unit(pins[0], PIN_FN_UART, PIN_TYPE_UART_TX);
  416. }
  417. } else {
  418. // default id
  419. uart_id = 0;
  420. }
  421. } else {
  422. uart_id = mp_obj_get_int(args[0].u_obj);
  423. }
  424. if (uart_id > PYB_UART_1) {
  425. mp_raise_OSError(MP_ENODEV);
  426. }
  427. // get the correct uart instance
  428. pyb_uart_obj_t *self = &pyb_uart_obj[uart_id];
  429. self->base.type = &pyb_uart_type;
  430. self->uart_id = uart_id;
  431. // start the peripheral
  432. pyb_uart_init_helper(self, &args[1]);
  433. return self;
  434. }
  435. STATIC mp_obj_t pyb_uart_init(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
  436. // parse args
  437. mp_arg_val_t args[MP_ARRAY_SIZE(pyb_uart_init_args) - 1];
  438. mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), &pyb_uart_init_args[1], args);
  439. return pyb_uart_init_helper(pos_args[0], args);
  440. }
  441. STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_uart_init_obj, 1, pyb_uart_init);
  442. STATIC mp_obj_t pyb_uart_deinit(mp_obj_t self_in) {
  443. pyb_uart_obj_t *self = self_in;
  444. // unregister it with the sleep module
  445. pyb_sleep_remove (self);
  446. // invalidate the baudrate
  447. self->baudrate = 0;
  448. // free the read buffer
  449. m_del(byte, self->read_buf, PYBUART_RX_BUFFER_LEN);
  450. MAP_UARTIntDisable(self->reg, UART_INT_RX | UART_INT_RT);
  451. MAP_UARTDisable(self->reg);
  452. MAP_PRCMPeripheralClkDisable(self->peripheral, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
  453. return mp_const_none;
  454. }
  455. STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_deinit_obj, pyb_uart_deinit);
  456. STATIC mp_obj_t pyb_uart_any(mp_obj_t self_in) {
  457. pyb_uart_obj_t *self = self_in;
  458. uart_check_init(self);
  459. return mp_obj_new_int(uart_rx_any(self));
  460. }
  461. STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_any_obj, pyb_uart_any);
  462. STATIC mp_obj_t pyb_uart_sendbreak(mp_obj_t self_in) {
  463. pyb_uart_obj_t *self = self_in;
  464. uart_check_init(self);
  465. // send a break signal for at least 2 complete frames
  466. MAP_UARTBreakCtl(self->reg, true);
  467. UtilsDelay(UTILS_DELAY_US_TO_COUNT(PYBUART_2_FRAMES_TIME_US(self->baudrate)));
  468. MAP_UARTBreakCtl(self->reg, false);
  469. return mp_const_none;
  470. }
  471. STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_sendbreak_obj, pyb_uart_sendbreak);
  472. /// \method irq(trigger, priority, handler, wake)
  473. STATIC mp_obj_t pyb_uart_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
  474. mp_arg_val_t args[mp_irq_INIT_NUM_ARGS];
  475. mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, mp_irq_INIT_NUM_ARGS, mp_irq_init_args, args);
  476. // check if any parameters were passed
  477. pyb_uart_obj_t *self = pos_args[0];
  478. uart_check_init(self);
  479. // convert the priority to the correct value
  480. uint priority = mp_irq_translate_priority (args[1].u_int);
  481. // check the power mode
  482. uint8_t pwrmode = (args[3].u_obj == mp_const_none) ? PYB_PWR_MODE_ACTIVE : mp_obj_get_int(args[3].u_obj);
  483. if (PYB_PWR_MODE_ACTIVE != pwrmode) {
  484. goto invalid_args;
  485. }
  486. // check the trigger
  487. uint trigger = mp_obj_get_int(args[0].u_obj);
  488. if (!trigger || trigger > (UART_TRIGGER_RX_ANY | UART_TRIGGER_RX_HALF | UART_TRIGGER_RX_FULL | UART_TRIGGER_TX_DONE)) {
  489. goto invalid_args;
  490. }
  491. // register a new callback
  492. return uart_irq_new (self, trigger, priority, args[2].u_obj);
  493. invalid_args:
  494. mp_raise_ValueError(mpexception_value_invalid_arguments);
  495. }
  496. STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_uart_irq_obj, 1, pyb_uart_irq);
  497. STATIC const mp_rom_map_elem_t pyb_uart_locals_dict_table[] = {
  498. // instance methods
  499. { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_uart_init_obj) },
  500. { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&pyb_uart_deinit_obj) },
  501. { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&pyb_uart_any_obj) },
  502. { MP_ROM_QSTR(MP_QSTR_sendbreak), MP_ROM_PTR(&pyb_uart_sendbreak_obj) },
  503. { MP_ROM_QSTR(MP_QSTR_irq), MP_ROM_PTR(&pyb_uart_irq_obj) },
  504. /// \method read([nbytes])
  505. { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
  506. /// \method readline()
  507. { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) },
  508. /// \method readinto(buf[, nbytes])
  509. { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
  510. /// \method write(buf)
  511. { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
  512. // class constants
  513. { MP_ROM_QSTR(MP_QSTR_RX_ANY), MP_ROM_INT(UART_TRIGGER_RX_ANY) },
  514. };
  515. STATIC MP_DEFINE_CONST_DICT(pyb_uart_locals_dict, pyb_uart_locals_dict_table);
  516. STATIC mp_uint_t pyb_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
  517. pyb_uart_obj_t *self = self_in;
  518. byte *buf = buf_in;
  519. uart_check_init(self);
  520. // make sure we want at least 1 char
  521. if (size == 0) {
  522. return 0;
  523. }
  524. // wait for first char to become available
  525. if (!uart_rx_wait(self)) {
  526. // return MP_EAGAIN error to indicate non-blocking (then read() method returns None)
  527. *errcode = MP_EAGAIN;
  528. return MP_STREAM_ERROR;
  529. }
  530. // read the data
  531. byte *orig_buf = buf;
  532. for ( ; ; ) {
  533. *buf++ = uart_rx_char(self);
  534. if (--size == 0 || !uart_rx_wait(self)) {
  535. // return number of bytes read
  536. return buf - orig_buf;
  537. }
  538. }
  539. }
  540. STATIC mp_uint_t pyb_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) {
  541. pyb_uart_obj_t *self = self_in;
  542. const char *buf = buf_in;
  543. uart_check_init(self);
  544. // write the data
  545. if (!uart_tx_strn(self, buf, size)) {
  546. mp_raise_OSError(MP_EIO);
  547. }
  548. return size;
  549. }
  550. STATIC mp_uint_t pyb_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) {
  551. pyb_uart_obj_t *self = self_in;
  552. mp_uint_t ret;
  553. uart_check_init(self);
  554. if (request == MP_STREAM_POLL) {
  555. mp_uint_t flags = arg;
  556. ret = 0;
  557. if ((flags & MP_STREAM_POLL_RD) && uart_rx_any(self)) {
  558. ret |= MP_STREAM_POLL_RD;
  559. }
  560. if ((flags & MP_STREAM_POLL_WR) && MAP_UARTSpaceAvail(self->reg)) {
  561. ret |= MP_STREAM_POLL_WR;
  562. }
  563. } else {
  564. *errcode = MP_EINVAL;
  565. ret = MP_STREAM_ERROR;
  566. }
  567. return ret;
  568. }
  569. STATIC const mp_stream_p_t uart_stream_p = {
  570. .read = pyb_uart_read,
  571. .write = pyb_uart_write,
  572. .ioctl = pyb_uart_ioctl,
  573. .is_text = false,
  574. };
  575. STATIC const mp_irq_methods_t uart_irq_methods = {
  576. .init = pyb_uart_irq,
  577. .enable = uart_irq_enable,
  578. .disable = uart_irq_disable,
  579. .flags = uart_irq_flags
  580. };
  581. const mp_obj_type_t pyb_uart_type = {
  582. { &mp_type_type },
  583. .name = MP_QSTR_UART,
  584. .print = pyb_uart_print,
  585. .make_new = pyb_uart_make_new,
  586. .getiter = mp_identity_getiter,
  587. .iternext = mp_stream_unbuffered_iter,
  588. .protocol = &uart_stream_p,
  589. .locals_dict = (mp_obj_t)&pyb_uart_locals_dict,
  590. };