From 611b829138a0e02f47c26e7a3d7adce344e0e9ba Mon Sep 17 00:00:00 2001 From: Glenn Ruben Bakke Date: Fri, 10 Mar 2017 22:21:19 +0100 Subject: [PATCH] nrf5/uart: Refactoring UART module and HAL driver Facilitating for adding second HW uart. Moving pyb_uart into machine_uart. Adding return error codes from hal_uart functions, if the hardware detects an error. --- nrf5/hal/hal_uart.c | 81 +++++---- nrf5/hal/hal_uart.h | 106 ++++++------ nrf5/hal/hal_uarte.c | 181 +++++++------------- nrf5/main.c | 4 +- nrf5/modules/machine/uart.c | 326 +++++++++++++++--------------------- nrf5/modules/machine/uart.h | 12 +- nrf5/modules/pyb/modpyb.c | 2 +- nrf5/modules/uos/moduos.c | 2 +- nrf5/mpconfigport.h | 4 +- 9 files changed, 300 insertions(+), 418 deletions(-) diff --git a/nrf5/hal/hal_uart.c b/nrf5/hal/hal_uart.c index cda9ba60a1..13d549e103 100644 --- a/nrf5/hal/hal_uart.c +++ b/nrf5/hal/hal_uart.c @@ -33,14 +33,6 @@ #ifdef HAL_UART_MODULE_ENABLED -#ifdef NRF51 -#define UART_BASE ((NRF_UART_Type *) NRF_UART0_BASE) -#define UART_IRQ_NUM UART0_IRQn -#else -#define UART_BASE ((NRF_UART_Type *) NRF_UART0_BASE) -#define UART_IRQ_NUM UARTE0_UART0_IRQn -#endif - uint32_t hal_uart_baudrate_lookup[] = { UART_BAUDRATE_BAUDRATE_Baud1200, ///< 1200 baud. UART_BAUDRATE_BAUDRATE_Baud2400, ///< 2400 baud. @@ -60,80 +52,95 @@ uint32_t hal_uart_baudrate_lookup[] = { UART_BAUDRATE_BAUDRATE_Baud1M, ///< 1000000 baud. }; -void hal_uart_char_write(uint8_t ch) { - UART_BASE->TXD = (uint8_t)ch; - while (UART_BASE->EVENTS_TXDRDY != 1) { +hal_uart_error_t hal_uart_char_write(NRF_UART_Type * p_instance, uint8_t ch) { + p_instance->ERRORSRC = 0; + p_instance->TXD = (uint8_t)ch; + while (p_instance->EVENTS_TXDRDY != 1) { // Blocking wait. } // Clear the TX flag. - UART_BASE->EVENTS_TXDRDY = 0; + p_instance->EVENTS_TXDRDY = 0; + + return p_instance->ERRORSRC; } -uint8_t hal_uart_char_read(void) { - while (UART_BASE->EVENTS_RXDRDY != 1) { +hal_uart_error_t hal_uart_char_read(NRF_UART_Type * p_instance, uint8_t * ch) { + p_instance->ERRORSRC = 0; + while (p_instance->EVENTS_RXDRDY != 1) { // Wait for RXD data. } - UART_BASE->EVENTS_RXDRDY = 0; - return (uint8_t)UART_BASE->RXD; + p_instance->EVENTS_RXDRDY = 0; + *ch = p_instance->RXD; + + return p_instance->ERRORSRC; } -void hal_uart_buffer_write(uint8_t * p_buffer, uint32_t num_of_bytes, uart_complete_cb cb) { +hal_uart_error_t hal_uart_buffer_write(NRF_UART_Type * p_instance, uint8_t * p_buffer, uint32_t num_of_bytes, uart_complete_cb cb) { int i = 0; + hal_uart_error_t err = 0; uint8_t ch = p_buffer[i++]; while (i < num_of_bytes) { - hal_uart_char_write(ch); + err = hal_uart_char_write(p_instance, ch); + if (err) { + return err; + } ch = p_buffer[i++]; } cb(); + return err; } -void hal_uart_buffer_read(uint8_t * p_buffer, uint32_t num_of_bytes, uart_complete_cb cb) { +hal_uart_error_t hal_uart_buffer_read(NRF_UART_Type * p_instance, uint8_t * p_buffer, uint32_t num_of_bytes, uart_complete_cb cb) { int i = 0; + hal_uart_error_t err = 0; while (i < num_of_bytes) { - uint8_t ch = hal_uart_char_read(); - p_buffer[i] = ch; + hal_uart_error_t err = hal_uart_char_read(p_instance, &p_buffer[i]); + if (err) { + return err; + } i++; } cb(); + return err; } -void hal_uart_init(hal_uart_init_t const * p_uart_init) { +void hal_uart_init(NRF_UART_Type * p_instance, hal_uart_init_t const * p_uart_init) { hal_gpio_cfg_pin(p_uart_init->tx_pin->port, p_uart_init->tx_pin->pin, HAL_GPIO_MODE_OUTPUT, HAL_GPIO_PULL_DISABLED); hal_gpio_cfg_pin(p_uart_init->tx_pin->port, p_uart_init->rx_pin->pin, HAL_GPIO_MODE_INPUT, HAL_GPIO_PULL_DISABLED); hal_gpio_pin_clear(p_uart_init->tx_pin->port, p_uart_init->tx_pin->pin); - UART_BASE->PSELTXD = p_uart_init->tx_pin->pin; - UART_BASE->PSELRXD = p_uart_init->rx_pin->pin; + p_instance->PSELTXD = p_uart_init->tx_pin->pin; + p_instance->PSELRXD = p_uart_init->rx_pin->pin; #if NRF52840_XXAA - UART_BASE->PSELTXD |= (p_uart_init->tx_pin->port << UARTE_PSEL_TXD_PORT_Pos); - UART_BASE->PSELRXD |= (p_uart_init->rx_pin->port << UARTE_PSEL_RXD_PORT_Pos); + p_instance->PSELTXD |= (p_uart_init->tx_pin->port << UARTE_PSEL_TXD_PORT_Pos); + p_instance->PSELRXD |= (p_uart_init->rx_pin->port << UARTE_PSEL_RXD_PORT_Pos); #endif if (p_uart_init->flow_control) { hal_gpio_cfg_pin(p_uart_init->rts_pin->port, p_uart_init->rts_pin->pin, HAL_GPIO_MODE_OUTPUT, HAL_GPIO_PULL_DISABLED); hal_gpio_cfg_pin(p_uart_init->cts_pin->port, p_uart_init->cts_pin->pin, HAL_GPIO_MODE_INPUT, HAL_GPIO_PULL_DISABLED); - UART_BASE->PSELCTS = p_uart_init->cts_pin->pin; - UART_BASE->PSELRTS = p_uart_init->rts_pin->pin; + p_instance->PSELCTS = p_uart_init->cts_pin->pin; + p_instance->PSELRTS = p_uart_init->rts_pin->pin; #if NRF52840_XXAA - UART_BASE->PSELCTS |= (p_uart_init->cts_pin->port << UARTE_PSEL_CTS_PORT_Pos); - UART_BASE->PSELRTS |= (p_uart_init->rts_pin->port << UARTE_PSEL_RTS_PORT_Pos); + p_instance->PSELCTS |= (p_uart_init->cts_pin->port << UARTE_PSEL_CTS_PORT_Pos); + p_instance->PSELRTS |= (p_uart_init->rts_pin->port << UARTE_PSEL_RTS_PORT_Pos); #endif - UART_BASE->CONFIG = (UART_CONFIG_HWFC_Enabled << UART_CONFIG_HWFC_Pos); + p_instance->CONFIG = (UART_CONFIG_HWFC_Enabled << UART_CONFIG_HWFC_Pos); } - UART_BASE->BAUDRATE = (hal_uart_baudrate_lookup[p_uart_init->baud_rate]); - UART_BASE->ENABLE = (UART_ENABLE_ENABLE_Enabled << UART_ENABLE_ENABLE_Pos); - UART_BASE->EVENTS_TXDRDY = 0; - UART_BASE->EVENTS_RXDRDY = 0; - UART_BASE->TASKS_STARTTX = 1; - UART_BASE->TASKS_STARTRX = 1; + p_instance->BAUDRATE = (hal_uart_baudrate_lookup[p_uart_init->baud_rate]); + p_instance->ENABLE = (UART_ENABLE_ENABLE_Enabled << UART_ENABLE_ENABLE_Pos); + p_instance->EVENTS_TXDRDY = 0; + p_instance->EVENTS_RXDRDY = 0; + p_instance->TASKS_STARTTX = 1; + p_instance->TASKS_STARTRX = 1; } #endif // HAL_UART_MODULE_ENABLED diff --git a/nrf5/hal/hal_uart.h b/nrf5/hal/hal_uart.h index bc7a945d27..3f39f117c3 100644 --- a/nrf5/hal/hal_uart.h +++ b/nrf5/hal/hal_uart.h @@ -33,42 +33,49 @@ #include "nrf.h" #if NRF51 - -#define UART_HWCONTROL_NONE ((uint32_t)UART_CONFIG_HWFC_Disabled << UART_CONFIG_HWFC_Pos) -#define UART_HWCONTROL_RTS_CTS ((uint32_t)(UART_CONFIG_HWFC_Enabled << UART_CONFIG_HWFC_Pos) -#define IS_UART_HARDWARE_FLOW_CONTROL(CONTROL)\ + #define UART_HWCONTROL_NONE ((uint32_t)UART_CONFIG_HWFC_Disabled << UART_CONFIG_HWFC_Pos) + #define UART_HWCONTROL_RTS_CTS ((uint32_t)(UART_CONFIG_HWFC_Enabled << UART_CONFIG_HWFC_Pos) + #define IS_UART_HARDWARE_FLOW_CONTROL(CONTROL)\ (((CONTROL) == UART_HWCONTROL_NONE) || \ ((CONTROL) == UART_HWCONTROL_RTS_CTS)) + #define UART_BASE_POINTERS (const uint32_t[]){NRF_UART0_BASE} + #define UART_IRQ_VALUES (const uint32_t[]){UART0_IRQn} #elif NRF52 - -#define UART_HWCONTROL_NONE ((uint32_t)UARTE_CONFIG_HWFC_Disabled << UARTE_CONFIG_HWFC_Pos) -#define UART_HWCONTROL_RTS_CTS ((uint32_t)(UARTE_CONFIG_HWFC_Enabled << UARTE_CONFIG_HWFC_Pos) -#define IS_UART_HARDWARE_FLOW_CONTROL(CONTROL)\ + #define UART_HWCONTROL_NONE ((uint32_t)UARTE_CONFIG_HWFC_Disabled << UARTE_CONFIG_HWFC_Pos) + #define UART_HWCONTROL_RTS_CTS ((uint32_t)(UARTE_CONFIG_HWFC_Enabled << UARTE_CONFIG_HWFC_Pos) + #define IS_UART_HARDWARE_FLOW_CONTROL(CONTROL)\ (((CONTROL) == UART_HWCONTROL_NONE) || \ ((CONTROL) == UART_HWCONTROL_RTS_CTS)) + #ifdef HAL_UART_MODULE_ENABLED + #define UART_BASE_POINTERS (const uint32_t[]){NRF_UART0_BASE} + #define UART_IRQ_VALUES (const uint32_t[]){UARTE0_UART0_IRQn} + #else // HAL_UARTE_MODULE_ENABLED + #ifdef NRF52832_XXAA + #define UART_BASE_POINTERS (const uint32_t[]){NRF_UARTE0_BASE} + #define UART_IRQ_VALUES (const uint32_t[]){UARTE0_UART0_IRQn} + #elif NRF52840_XXAA + #define UART_BASE_POINTERS (const uint32_t[]){NRF_UARTE0_BASE, \ + NRF_UARTE1_BASE} + #define UART_IRQ_VALUES (const uint32_t[]){UARTE0_UART0_IRQn, \ + UARTE1_IRQn} + #endif // HAL_UARTE_MODULE_ENABLED + #endif #else #error "Device not supported." #endif -typedef enum { - HAL_UART_STATE_RESET = 0x00, /*!< Peripheral is not yet Initialized */ - HAL_UART_STATE_READY = 0x01, /*!< Peripheral Initialized and ready for use */ - HAL_UART_STATE_BUSY = 0x02, /*!< an internal process is ongoing */ - HAL_UART_STATE_BUSY_TX = 0x12, /*!< Data Transmission process is ongoing */ - HAL_UART_STATE_BUSY_RX = 0x22, /*!< Data Reception process is ongoing */ - HAL_UART_STATE_BUSY_TX_RX = 0x32, /*!< Data Transmission and Reception process is ongoing */ - HAL_UART_STATE_TIMEOUT = 0x03, /*!< Timeout state */ - HAL_UART_STATE_ERROR = 0x04 /*!< Error */ -} HAL_UART_StateTypeDef; + +#define UART_BASE(x) ((NRF_UART_Type *)UART_BASE_POINTERS[x]) +#define UART_IRQ_NUM(x) (UART_IRQ_VALUES[x]) typedef enum { - HAL_UART_ERROR_NONE = 0x00, /*!< No error */ - HAL_UART_ERROR_ORE = 0x01, /*!< Overrun error. A start bit is received while the previous data still lies in RXD. (Previous data is lost.) */ - HAL_UART_ERROR_PE = 0x02, /*!< Parity error. A character with bad parity is received, if HW parity check is enabled. */ - HAL_UART_ERROR_FE = 0x04, /*!< Frame error. A valid stop bit is not detected on the serial data input after all bits in a character have been received. */ - HAL_UART_ERROR_BE = 0x08, /*!< Break error. The serial data input is '0' for longer than the length of a data frame. (The data frame length is 10 bits without parity bit, and 11 bits with parity bit.). */ -} HAL_UART_ErrorTypeDef; + HAL_UART_ERROR_NONE = 0x00, /*!< No error */ + HAL_UART_ERROR_ORE = 0x01, /*!< Overrun error. A start bit is received while the previous data still lies in RXD. (Previous data is lost.) */ + HAL_UART_ERROR_PE = 0x02, /*!< Parity error. A character with bad parity is received, if HW parity check is enabled. */ + HAL_UART_ERROR_FE = 0x04, /*!< Frame error. A valid stop bit is not detected on the serial data input after all bits in a character have been received. */ + HAL_UART_ERROR_BE = 0x08, /*!< Break error. The serial data input is '0' for longer than the length of a data frame. (The data frame length is 10 bits without parity bit, and 11 bits with parity bit.). */ +} hal_uart_error_t; typedef enum { HAL_UART_BAUD_1K2 = 0, /**< 1200 baud */ @@ -89,47 +96,30 @@ typedef enum { } hal_uart_baudrate_t; typedef struct { - uint32_t baud_rate; - uint32_t flow_control; -} UART_InitTypeDef; + uint8_t id; /* UART instance id */ + const pin_obj_t * rx_pin; /* RX pin. */ + const pin_obj_t * tx_pin; /* TX pin. */ + const pin_obj_t * rts_pin; /* RTS pin, only used if flow control is enabled. */ + const pin_obj_t * cts_pin; /* CTS pin, only used if flow control is enabled. */ + bool flow_control; /* Flow control setting, if flow control is used, the system will use low power UART mode, based on CTS signal. */ + bool use_parity; /* Even parity if TRUE, no parity if FALSE. */ + uint32_t baud_rate; /* Baud rate configuration. */ + uint32_t irq_priority; /* UARTE IRQ priority. */ + uint32_t irq_num; +} hal_uart_init_t; typedef struct { - NRF_UART_Type *instance; /* UART registers base address */ - UART_InitTypeDef init; /* UART communication parameters */ - uint8_t *p_tx_buff; /* Pointer to UART Tx transfer Buffer */ - uint16_t tx_xfer_size; /* UART Tx Transfer size */ - uint16_t tx_xfer_count; /* UART Tx Transfer Counter */ - uint8_t *p_rx_buff; /* Pointer to UART Rx transfer Buffer */ - uint16_t rx_xfer_size; /* UART Rx Transfer size */ - uint16_t rx_xfer_count; /* UART Rx Transfer Counter */ - __IO HAL_UART_StateTypeDef state; /* UART communication state */ - __IO HAL_UART_ErrorTypeDef error_code; /* UART Error code */ - + NRF_UART_Type * p_instance; /* UART registers base address */ + hal_uart_init_t init; /* UART communication parameters */ } UART_HandleTypeDef; -typedef struct { - const pin_obj_t * rx_pin; /**< RX pin. */ - const pin_obj_t * tx_pin; /**< TX pin. */ - const pin_obj_t * rts_pin; /**< RTS pin, only used if flow control is enabled. */ - const pin_obj_t * cts_pin; /**< CTS pin, only used if flow control is enabled. */ - bool flow_control; /**< Flow control setting, if flow control is used, the system will use low power UART mode, based on CTS signal. */ - bool use_parity; /**< Even parity if TRUE, no parity if FALSE. */ - uint32_t baud_rate; /**< Baud rate configuration. */ - uint32_t irq_priority; /**< UARTE IRQ priority. */ -} hal_uart_init_t; - - typedef void (*uart_complete_cb)(void); -void hal_uart_init(hal_uart_init_t const * p_uart_init); +void hal_uart_init(NRF_UART_Type * p_instance, hal_uart_init_t const * p_uart_init); -void hal_uart_char_write(uint8_t ch); +hal_uart_error_t hal_uart_char_write(NRF_UART_Type * p_instance, uint8_t ch); -uint8_t hal_uart_char_read(void); +hal_uart_error_t hal_uart_char_read(NRF_UART_Type * p_instance, uint8_t * ch); -void hal_uart_buffer_write(uint8_t * p_buffer, uint32_t num_of_bytes, uart_complete_cb cb); - -void hal_uart_buffer_read(uint8_t * p_buffer, uint32_t num_of_bytes, uart_complete_cb cb); - -#endif // UART_H__ +#endif // HAL_UART_H__ diff --git a/nrf5/hal/hal_uarte.c b/nrf5/hal/hal_uarte.c index bb421bec20..6393c136d1 100644 --- a/nrf5/hal/hal_uarte.c +++ b/nrf5/hal/hal_uarte.c @@ -29,26 +29,22 @@ #include "mphalport.h" #include "hal_uart.h" +#include "hal_irq.h" #ifdef HAL_UARTE_MODULE_ENABLED #include "nrf.h" -#if NRF52 - -#define UARTE_BASE ((NRF_UARTE_Type *) NRF_UARTE0_BASE) -#define UART_IRQ_NUM UARTE0_UART0_IRQn - -#else +#ifndef NRF52 #error "Device not supported." #endif +#define UART_BASE(x) ((NRF_UART_Type *)UART_BASE_POINTERS[x]) +#define UART_IRQ_NUM(x) (UART_IRQ_VALUES[x]) + #define TX_BUF_SIZE 1 #define RX_BUF_SIZE 1 -static uart_complete_cb dma_read_cb = NULL; -static uart_complete_cb dma_write_cb = NULL; - static const uint32_t hal_uart_baudrate_lookup[] = { UARTE_BAUDRATE_BAUDRATE_Baud1200, ///< 1200 baud. UARTE_BAUDRATE_BAUDRATE_Baud2400, ///< 2400 baud. @@ -68,26 +64,19 @@ static const uint32_t hal_uart_baudrate_lookup[] = { UARTE_BAUDRATE_BAUDRATE_Baud1M, ///< 1000000 baud. }; -__STATIC_INLINE void hal_uart_irq_clear(void) { - NVIC_ClearPendingIRQ(UART_IRQ_NUM); +void nrf_sendchar(NRF_UART_Type * p_instance, int ch) { + hal_uart_char_write(p_instance, ch); } -__STATIC_INLINE void hal_uart_irq_enable(uint8_t priority) { - NVIC_SetPriority(UART_IRQ_NUM, priority); - hal_uart_irq_clear(); - NVIC_EnableIRQ(UART_IRQ_NUM); -} +void hal_uart_init(NRF_UART_Type * p_instance, hal_uart_init_t const * p_uart_init) { -void nrf_sendchar(int ch) { - hal_uart_char_write(ch); -} + NRF_UARTE_Type * uarte_instance = (NRF_UARTE_Type *)p_instance; -void hal_uart_init(hal_uart_init_t const * p_uart_init) { hal_gpio_cfg_pin(p_uart_init->tx_pin->port, p_uart_init->tx_pin->pin, HAL_GPIO_MODE_OUTPUT, HAL_GPIO_PULL_DISABLED); hal_gpio_pin_set(p_uart_init->tx_pin->port, p_uart_init->tx_pin->pin); hal_gpio_cfg_pin(p_uart_init->tx_pin->port, p_uart_init->rx_pin->pin, HAL_GPIO_MODE_INPUT, HAL_GPIO_PULL_DISABLED); - UARTE_BASE->BAUDRATE = (hal_uart_baudrate_lookup[p_uart_init->baud_rate]); + uarte_instance->BAUDRATE = (hal_uart_baudrate_lookup[p_uart_init->baud_rate]); uint32_t hwfc = (p_uart_init->flow_control) ? (UARTE_CONFIG_HWFC_Enabled << UARTE_CONFIG_HWFC_Pos) @@ -97,14 +86,14 @@ void hal_uart_init(hal_uart_init_t const * p_uart_init) { ? (UARTE_CONFIG_PARITY_Included << UARTE_CONFIG_PARITY_Pos) : (UARTE_CONFIG_PARITY_Excluded << UARTE_CONFIG_PARITY_Pos); - UARTE_BASE->CONFIG = (uint32_t)hwfc | (uint32_t)parity; + uarte_instance->CONFIG = (uint32_t)hwfc | (uint32_t)parity; - UARTE_BASE->PSEL.RXD = p_uart_init->rx_pin->pin; - UARTE_BASE->PSEL.TXD = p_uart_init->tx_pin->pin; + uarte_instance->PSEL.RXD = p_uart_init->rx_pin->pin; + uarte_instance->PSEL.TXD = p_uart_init->tx_pin->pin; #if NRF52840_XXAA - UARTE_BASE->PSEL.RXD |= (p_uart_init->rx_pin->port << UARTE_PSEL_RXD_PORT_Pos); - UARTE_BASE->PSEL.TXD |= (p_uart_init->tx_pin->port << UARTE_PSEL_TXD_PORT_Pos); + uarte_instance->PSEL.RXD |= (p_uart_init->rx_pin->port << UARTE_PSEL_RXD_PORT_Pos); + uarte_instance->PSEL.TXD |= (p_uart_init->tx_pin->port << UARTE_PSEL_TXD_PORT_Pos); #endif if (hwfc) { @@ -112,132 +101,80 @@ void hal_uart_init(hal_uart_init_t const * p_uart_init) { hal_gpio_cfg_pin(p_uart_init->rts_pin->port, p_uart_init->rts_pin->pin, HAL_GPIO_MODE_OUTPUT, HAL_GPIO_PULL_DISABLED); hal_gpio_pin_set(p_uart_init->rts_pin->port, p_uart_init->rts_pin->pin); - UARTE_BASE->PSEL.RTS = p_uart_init->rts_pin->pin; - UARTE_BASE->PSEL.CTS = p_uart_init->cts_pin->pin; + uarte_instance->PSEL.RTS = p_uart_init->rts_pin->pin; + uarte_instance->PSEL.CTS = p_uart_init->cts_pin->pin; #if NRF52840_XXAA - UARTE_BASE->PSEL.RTS |= (p_uart_init->rx_pin->port << UARTE_PSEL_RTS_PORT_Pos); - UARTE_BASE->PSEL.CTS |= (p_uart_init->rx_pin->port << UARTE_PSEL_CTS_PORT_Pos); + uarte_instance->PSEL.RTS |= (p_uart_init->rx_pin->port << UARTE_PSEL_RTS_PORT_Pos); + uarte_instance->PSEL.CTS |= (p_uart_init->rx_pin->port << UARTE_PSEL_CTS_PORT_Pos); #endif } - hal_uart_irq_enable(p_uart_init->irq_priority); + hal_irq_priority(p_uart_init->irq_num, p_uart_init->irq_priority); + hal_irq_enable(p_uart_init->irq_num); - UARTE_BASE->INTENSET = (UARTE_INTENSET_ENDRX_Set << UARTE_INTENSET_ENDRX_Pos); - UARTE_BASE->INTENSET = (UARTE_INTENSET_ENDTX_Set << UARTE_INTENSET_ENDTX_Pos); + uarte_instance->INTENSET = (UARTE_INTENSET_ENDRX_Set << UARTE_INTENSET_ENDRX_Pos); + uarte_instance->INTENSET = (UARTE_INTENSET_ENDTX_Set << UARTE_INTENSET_ENDTX_Pos); - UARTE_BASE->ENABLE = (UARTE_ENABLE_ENABLE_Enabled << UARTE_ENABLE_ENABLE_Pos); + uarte_instance->ENABLE = (UARTE_ENABLE_ENABLE_Enabled << UARTE_ENABLE_ENABLE_Pos); - UARTE_BASE->EVENTS_ENDTX = 0; - UARTE_BASE->EVENTS_ENDRX = 0; + uarte_instance->EVENTS_ENDTX = 0; + uarte_instance->EVENTS_ENDRX = 0; } -void hal_uart_char_write(uint8_t ch) { +hal_uart_error_t hal_uart_char_write(NRF_UART_Type * p_instance, uint8_t ch) { + + NRF_UARTE_Type * uarte_instance = (NRF_UARTE_Type *)p_instance; + + uarte_instance->ERRORSRC = 0; + + static volatile uint8_t m_tx_buf[TX_BUF_SIZE]; (void)m_tx_buf; - UARTE_BASE->INTENCLR = (UARTE_INTENSET_ENDTX_Set << UARTE_INTENSET_ENDTX_Pos); + uarte_instance->INTENCLR = (UARTE_INTENSET_ENDTX_Set << UARTE_INTENSET_ENDTX_Pos); m_tx_buf[0] = ch; - UARTE_BASE->TXD.PTR = (uint32_t)((uint8_t *)m_tx_buf); - UARTE_BASE->TXD.MAXCNT = (uint32_t)sizeof(m_tx_buf); + uarte_instance->TXD.PTR = (uint32_t)((uint8_t *)m_tx_buf); + uarte_instance->TXD.MAXCNT = (uint32_t)sizeof(m_tx_buf); - UARTE_BASE->TASKS_STARTTX = 1; + uarte_instance->TASKS_STARTTX = 1; - while((0 == UARTE_BASE->EVENTS_ENDTX)); + while((0 == uarte_instance->EVENTS_ENDTX)); - UARTE_BASE->EVENTS_ENDTX = 0; - UARTE_BASE->TASKS_STOPTX = 1; + uarte_instance->EVENTS_ENDTX = 0; + uarte_instance->TASKS_STOPTX = 1; - UARTE_BASE->INTENSET = (UARTE_INTENSET_ENDTX_Set << UARTE_INTENSET_ENDTX_Pos); + uarte_instance->INTENSET = (UARTE_INTENSET_ENDTX_Set << UARTE_INTENSET_ENDTX_Pos); + + return uarte_instance->ERRORSRC; } -uint8_t hal_uart_char_read(void) { +hal_uart_error_t hal_uart_char_read(NRF_UART_Type * p_instance, uint8_t * ch) { + + NRF_UARTE_Type * uarte_instance = (NRF_UARTE_Type *)p_instance; + + uarte_instance->ERRORSRC = 0; + static volatile uint8_t m_rx_buf[RX_BUF_SIZE]; - UARTE_BASE->INTENCLR = (UARTE_INTENSET_ENDRX_Set << UARTE_INTENSET_ENDRX_Pos); + uarte_instance->INTENCLR = (UARTE_INTENSET_ENDRX_Set << UARTE_INTENSET_ENDRX_Pos); - UARTE_BASE->RXD.PTR = (uint32_t)((uint8_t *)m_rx_buf); - UARTE_BASE->RXD.MAXCNT = (uint32_t)sizeof(m_rx_buf); + uarte_instance->RXD.PTR = (uint32_t)((uint8_t *)m_rx_buf); + uarte_instance->RXD.MAXCNT = (uint32_t)sizeof(m_rx_buf); - UARTE_BASE->TASKS_STARTRX = 1; + uarte_instance->TASKS_STARTRX = 1; - while ((0 == UARTE_BASE->EVENTS_ENDRX)); + while ((0 == uarte_instance->EVENTS_ENDRX)); - UARTE_BASE->EVENTS_ENDRX = 0; - UARTE_BASE->TASKS_STOPRX = 1; + uarte_instance->EVENTS_ENDRX = 0; + uarte_instance->TASKS_STOPRX = 1; - UARTE_BASE->INTENSET = (UARTE_INTENSET_ENDRX_Set << UARTE_INTENSET_ENDRX_Pos); + uarte_instance->INTENSET = (UARTE_INTENSET_ENDRX_Set << UARTE_INTENSET_ENDRX_Pos); + *ch = (uint8_t)m_rx_buf[0]; - return (uint8_t)m_rx_buf[0]; -} - -void hal_uart_buffer_write(uint8_t * p_buffer, uint32_t num_of_bytes, uart_complete_cb cb) { - dma_write_cb = cb; - - UARTE_BASE->TXD.PTR = (uint32_t)p_buffer; - UARTE_BASE->TXD.MAXCNT = num_of_bytes; - UARTE_BASE->TASKS_STARTTX = 1; - - while((0 == UARTE_BASE->EVENTS_ENDTX)); - - UARTE_BASE->EVENTS_ENDTX = 0; - UARTE_BASE->TASKS_STOPTX = 1; - - UARTE_BASE->INTENSET = (UARTE_INTENSET_ENDTX_Set << UARTE_INTENSET_ENDTX_Pos); - -} - -void hal_uart_buffer_read(uint8_t * p_buffer, uint32_t num_of_bytes, uart_complete_cb cb) { - dma_read_cb = cb; - - UARTE_BASE->RXD.PTR = (uint32_t)(p_buffer); - UARTE_BASE->RXD.MAXCNT = num_of_bytes; - UARTE_BASE->TASKS_STARTRX = 1; - - while ((0 == UARTE_BASE->EVENTS_ENDRX)); - - UARTE_BASE->EVENTS_ENDRX = 0; - UARTE_BASE->TASKS_STOPRX = 1; - - UARTE_BASE->INTENSET = (UARTE_INTENSET_ENDRX_Set << UARTE_INTENSET_ENDRX_Pos); - -} - -static void dma_read_complete(void) { - UARTE_BASE->TASKS_STOPRX = 1; - - if (dma_read_cb != NULL) { - uart_complete_cb temp_cb = dma_read_cb; - dma_read_cb = NULL; - temp_cb(); - } -} - -static void dma_write_complete(void) { - UARTE_BASE->TASKS_STOPTX = 1; - - if (dma_write_cb != NULL) { - uart_complete_cb temp_cb = dma_write_cb; - dma_write_cb = NULL; - temp_cb(); - } -} - -void UARTE0_UART0_IRQHandler(void) { - if ((UARTE_BASE->EVENTS_ENDRX) - && (UARTE_BASE->INTEN & UARTE_INTENSET_ENDRX_Msk)) { - - UARTE_BASE->EVENTS_ENDRX = 0; - dma_read_complete(); - - } else if ((UARTE_BASE->EVENTS_ENDTX) - && (UARTE_BASE->INTEN & UARTE_INTENSET_ENDTX_Msk)) { - - UARTE_BASE->EVENTS_ENDTX = 0; - dma_write_complete(); - } + return uarte_instance->ERRORSRC; } #endif // HAL_UARTE_MODULE_ENABLED diff --git a/nrf5/main.c b/nrf5/main.c index 8d0219a467..9412cabbff 100644 --- a/nrf5/main.c +++ b/nrf5/main.c @@ -135,10 +135,10 @@ int main(int argc, char **argv) { #if (MICROPY_PY_BLE_NUS == 0) { mp_obj_t args[2] = { - MP_OBJ_NEW_SMALL_INT(PYB_UART_1), + MP_OBJ_NEW_SMALL_INT(0), MP_OBJ_NEW_SMALL_INT(115200), }; - MP_STATE_PORT(pyb_stdio_uart) = pyb_uart_type.make_new((mp_obj_t)&pyb_uart_type, MP_ARRAY_SIZE(args), 0, args); + MP_STATE_PORT(pyb_stdio_uart) = machine_hard_uart_type.make_new((mp_obj_t)&machine_hard_uart_type, MP_ARRAY_SIZE(args), 0, args); } #endif diff --git a/nrf5/modules/machine/uart.c b/nrf5/modules/machine/uart.c index 83a584cfff..5714b8b4c5 100644 --- a/nrf5/modules/machine/uart.c +++ b/nrf5/modules/machine/uart.c @@ -46,86 +46,86 @@ #define CHAR_WIDTH_8BIT (0) #define CHAR_WIDTH_9BIT (1) -struct _pyb_uart_obj_t { +typedef struct _machine_hard_uart_obj_t { mp_obj_base_t base; - UART_HandleTypeDef uart; - IRQn_Type irqn; - pyb_uart_t uart_id : 8; - bool is_enabled : 1; + UART_HandleTypeDef * uart; byte char_width; // 0 for 7,8 bit chars, 1 for 9 bit chars - uint16_t char_mask; // 0x7f for 7 bit, 0xff for 8 bit, 0x1ff for 9 bit - uint16_t timeout; // timeout waiting for first char - uint16_t timeout_char; // timeout waiting between chars - uint16_t read_buf_len; // len in chars; buf can hold len-1 chars - volatile uint16_t read_buf_head; // indexes first empty slot - uint16_t read_buf_tail; // indexes first full slot (not full if equals head) - byte *read_buf; // byte or uint16_t, depending on char size +} machine_hard_uart_obj_t; + +UART_HandleTypeDef UARTHandle0 = {.p_instance = NULL, .init.id = 0}; +#if NRF52840_XXAA +UART_HandleTypeDef UARTHandle1 = {.p_instance = NULL, .init.id = 1}; +#endif + +STATIC machine_hard_uart_obj_t machine_hard_uart_obj[] = { + {{&machine_hard_uart_type}, &UARTHandle0}, +#if NRF52840_XXAA + {{&machine_hard_uart_type}, &UARTHandle1}, +#endif }; -STATIC mp_obj_t pyb_uart_deinit(mp_obj_t self_in); - void uart_init0(void) { + // reset the UART handles + memset(&UARTHandle0, 0, sizeof(UART_HandleTypeDef)); + UARTHandle0.p_instance = UART_BASE(0); +#if NRF52840_XXAA + memset(&UARTHandle1, 0, sizeof(UART_HandleTypeDef)); + UARTHandle0.p_instance = UART_BASE(1); +#endif +#if 0 for (int i = 0; i < MP_ARRAY_SIZE(MP_STATE_PORT(pyb_uart_obj_all)); i++) { MP_STATE_PORT(pyb_uart_obj_all)[i] = NULL; } +#endif } -// unregister all interrupt sources -void uart_deinit(void) { - for (int i = 0; i < MP_ARRAY_SIZE(MP_STATE_PORT(pyb_uart_obj_all)); i++) { - pyb_uart_obj_t *uart_obj = MP_STATE_PORT(pyb_uart_obj_all)[i]; - if (uart_obj != NULL) { - pyb_uart_deinit(uart_obj); - } +STATIC int uart_find(mp_obj_t id) { + // given an integer id + int uart_id = mp_obj_get_int(id); + if (uart_id >= 0 && uart_id <= MP_ARRAY_SIZE(machine_hard_uart_obj) + && machine_hard_uart_obj[uart_id].uart != NULL) { + return uart_id; } -} - -/// \method deinit() -/// Turn off the UART bus. -STATIC mp_obj_t pyb_uart_deinit(mp_obj_t self_in) { - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_deinit_obj, pyb_uart_deinit); - -//// assumes Init parameters have been set up correctly -STATIC bool uart_init2(pyb_uart_obj_t * uart_obj) { - uart_obj->is_enabled = true; - - return true; + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + "UART(%d) does not exist", uart_id)); } void uart_irq_handler(mp_uint_t uart_id) { } -bool uart_rx_any(pyb_uart_obj_t *uart_obj) { - // TODO: uart will block for now. - return true; +bool uart_rx_any(machine_hard_uart_obj_t *uart_obj) { + // TODO: uart will block for now. + return true; } +#if 0 // Waits at most timeout milliseconds for at least 1 char to become ready for // reading (from buf or for direct reading). // Returns true if something available, false if not. -STATIC bool uart_rx_wait(pyb_uart_obj_t *self, uint32_t timeout) { - return false; +STATIC bool uart_rx_wait(machine_hard_uart_obj_t * self, uint32_t timeout) { + return false; +} +#endif + +int uart_rx_char(machine_hard_uart_obj_t * self) { + uint8_t ch; + hal_uart_char_read(self->uart->p_instance, &ch); + return (int)ch; } -int uart_rx_char(pyb_uart_obj_t *self) { - return (int)hal_uart_char_read(); -} - -STATIC void uart_tx_char(pyb_uart_obj_t * self, int c) { - hal_uart_char_write((char)c); +STATIC hal_uart_error_t uart_tx_char(machine_hard_uart_obj_t * self, int c) { + return hal_uart_char_write(self->uart->p_instance, (char)c); } -void uart_tx_strn(pyb_uart_obj_t *uart_obj, const char *str, uint len) { +void uart_tx_strn(machine_hard_uart_obj_t *uart_obj, const char *str, uint len) { for (const char *top = str + len; str < top; str++) { uart_tx_char(uart_obj, *str); } } -void uart_tx_strn_cooked(pyb_uart_obj_t *uart_obj, const char *str, uint len) { +void uart_tx_strn_cooked(machine_hard_uart_obj_t *uart_obj, const char *str, uint len) { for (const char *top = str + len; str < top; str++) { if (*str == '\n') { uart_tx_char(uart_obj, '\r'); @@ -140,10 +140,12 @@ void uart_tx_strn_cooked(pyb_uart_obj_t *uart_obj, const char *str, uint len) { STATIC void pyb_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { } + + /// \method init(baudrate, bits=8, parity=None, stop=1, *, timeout=1000, timeout_char=0, read_buf_len=64) /// /// Initialise the UART bus with the given parameters: -/// +/// - `id`is bus id. /// - `baudrate` is the clock rate. /// - `bits` is the number of bits per byte, 7, 8 or 9. /// - `parity` is the parity, `None`, 0 (even) or 1 (odd). @@ -151,41 +153,40 @@ STATIC void pyb_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_k /// - `timeout` is the timeout in milliseconds to wait for the first character. /// - `timeout_char` is the timeout in milliseconds to wait between characters. /// - `read_buf_len` is the character length of the read buffer (0 to disable). -STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { +STATIC mp_obj_t machine_hard_uart_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { static const mp_arg_t allowed_args[] = { + { MP_QSTR_id, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_baudrate, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 9600} }, { MP_QSTR_bits, MP_ARG_INT, {.u_int = 8} }, { MP_QSTR_parity, MP_ARG_OBJ, {.u_obj = mp_const_none} }, { MP_QSTR_stop, MP_ARG_INT, {.u_int = 1} }, - { MP_QSTR_flow, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = UART_HWCONTROL_NONE} }, + { MP_QSTR_flow, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1000} }, { MP_QSTR_timeout_char, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_read_buf_len, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64} }, }; - // parse args mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - // set the UART configuration values - memset(&self->uart, 0, sizeof(self->uart)); - UART_InitTypeDef * init = &self->uart.init; + // get static peripheral object + int uart_id = uart_find(args[0].u_obj); + machine_hard_uart_obj_t * self = &machine_hard_uart_obj[uart_id]; - // baudrate - init->baud_rate = args[0].u_int; + hal_uart_init_t * init = &self->uart->init; // flow control - init->flow_control = args[4].u_int; - + init->flow_control = args[5].u_int; +#if 0 // init UART (if it fails, it's because the port doesn't exist) if (!uart_init2(self)) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "UART(%d) does not exist", self->uart_id)); } // set timeouts - self->timeout = args[5].u_int; - self->timeout_char = args[6].u_int; + self->timeout = args[6].u_int; + self->timeout_char = args[7].u_int; // setup the read buffer m_del(byte, self->read_buf, self->read_buf_len << self->char_width); @@ -193,75 +194,75 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, mp_uint_t n_args, con self->read_buf_head = 0; self->read_buf_tail = 0; - if (args[7].u_int <= 0) { + if (args[8].u_int <= 0) { // no read buffer self->read_buf_len = 0; self->read_buf = NULL; } else { // read buffer using interrupts - self->read_buf_len = args[7].u_int; - self->read_buf = m_new(byte, args[7].u_int << self->char_width); + self->read_buf_len = args[8].u_int; + self->read_buf = m_new(byte, args[8].u_int << self->char_width); } - hal_uart_init_t uart_init = { -#if MICROPY_HW_UART1_HWFC - .flow_control = true, -#else - .flow_control = false, -#endif - .use_parity = false, -#if (BLUETOOTH_SD == 100) - .irq_priority = 3 -#else - .irq_priority = 6 -#endif - }; +#endif // 0 - switch (init->baud_rate) { +#if MICROPY_HW_UART1_HWFC + init->flow_control = true; +#else + init->flow_control = false; +#endif + init->use_parity = false; +#if (BLUETOOTH_SD == 100) + init->irq_priority = 3; +#else + init->irq_priority = 6; +#endif + + switch (args[1].u_int) { case 1200: - uart_init.baud_rate = HAL_UART_BAUD_1K2; + init->baud_rate = HAL_UART_BAUD_1K2; break; case 2400: - uart_init.baud_rate = HAL_UART_BAUD_2K4; + init->baud_rate = HAL_UART_BAUD_2K4; break; case 4800: - uart_init.baud_rate = HAL_UART_BAUD_4K8; + init->baud_rate = HAL_UART_BAUD_4K8; break; case 9600: - uart_init.baud_rate = HAL_UART_BAUD_9K6; + init->baud_rate = HAL_UART_BAUD_9K6; break; case 14400: - uart_init.baud_rate = HAL_UART_BAUD_14K4; + init->baud_rate = HAL_UART_BAUD_14K4; break; case 19200: - uart_init.baud_rate = HAL_UART_BAUD_19K2; + init->baud_rate = HAL_UART_BAUD_19K2; break; case 28800: - uart_init.baud_rate = HAL_UART_BAUD_28K8; + init->baud_rate = HAL_UART_BAUD_28K8; break; case 38400: - uart_init.baud_rate = HAL_UART_BAUD_38K4; + init->baud_rate = HAL_UART_BAUD_38K4; break; case 57600: - uart_init.baud_rate = HAL_UART_BAUD_57K6; + init->baud_rate = HAL_UART_BAUD_57K6; break; case 76800: - uart_init.baud_rate = HAL_UART_BAUD_76K8; + init->baud_rate = HAL_UART_BAUD_76K8; break; case 115200: - uart_init.baud_rate = HAL_UART_BAUD_115K2; + init->baud_rate = HAL_UART_BAUD_115K2; break; case 230400: - uart_init.baud_rate = HAL_UART_BAUD_230K4; + init->baud_rate = HAL_UART_BAUD_230K4; break; case 250000: - uart_init.baud_rate = HAL_UART_BAUD_250K0; + init->baud_rate = HAL_UART_BAUD_250K0; break; case 500000: - uart_init.baud_rate = HAL_UART_BAUD_500K0; + init->baud_rate = HAL_UART_BAUD_500K0; break; case 1000000: - uart_init.baud_rate = HAL_UART_BAUD_1M0; + init->baud_rate = HAL_UART_BAUD_1M0; break; default: nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, @@ -269,72 +270,23 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, mp_uint_t n_args, con break; } - uart_init.rx_pin = &MICROPY_HW_UART1_RX; - uart_init.tx_pin = &MICROPY_HW_UART1_TX; + init->rx_pin = &MICROPY_HW_UART1_RX; + init->tx_pin = &MICROPY_HW_UART1_TX; #if MICROPY_HW_UART1_HWFC - uart_init.rts_pin = &MICROPY_HW_UART1_RTS; - uart_init.cts_pin = &MICROPY_HW_UART1_CTS; + init->rts_pin = &MICROPY_HW_UART1_RTS; + init->cts_pin = &MICROPY_HW_UART1_CTS; #endif - hal_uart_init(&uart_init); + hal_uart_init(self->uart->p_instance, init); - return mp_const_none; + return MP_OBJ_FROM_PTR(self); } -/// \classmethod \constructor(bus, ...) -/// -/// Construct a UART object. -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 *args) { - // check arguments - mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); - - // work out port - int uart_id = 0; - - if (MP_OBJ_IS_STR(args[0])) { - const char *port = mp_obj_str_get_str(args[0]); - if (0) { - - } else if (strcmp(port, "COM1") == 0) { - uart_id = PYB_UART_1; - } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "UART(%s) does not exist", port)); - } - } else { - uart_id = mp_obj_get_int(args[0]); - if (uart_id < 1 || uart_id > MP_ARRAY_SIZE(MP_STATE_PORT(pyb_uart_obj_all))) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "UART(%d) does not exist", uart_id)); - } - } - - pyb_uart_obj_t *self; - if (MP_STATE_PORT(pyb_uart_obj_all)[uart_id - 1] == NULL) { - // create new UART object - self = m_new0(pyb_uart_obj_t, 1); - self->base.type = &pyb_uart_type; - self->uart_id = uart_id; - MP_STATE_PORT(pyb_uart_obj_all)[uart_id - 1] = self; - } else { - // reference existing UART object - self = MP_STATE_PORT(pyb_uart_obj_all)[uart_id - 1]; - } - - if (n_args > 1 || n_kw > 0) { - // start the peripheral - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); - pyb_uart_init_helper(self, n_args - 1, args + 1, &kw_args); - } - - return self; -} - - /// \method any() /// Return `True` if any characters waiting, else `False`. STATIC mp_obj_t pyb_uart_any(mp_obj_t self_in) { - pyb_uart_obj_t *self = self_in; + machine_hard_uart_obj_t *self = self_in; if (uart_rx_any(self)) { return mp_const_true; } else { @@ -346,56 +298,53 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_any_obj, pyb_uart_any); /// \method writechar(char) /// Write a single character on the bus. `char` is an integer to write. /// Return value: `None`. -STATIC mp_obj_t pyb_uart_writechar(mp_obj_t self_in, mp_obj_t char_in) { - pyb_uart_obj_t *self = self_in; +STATIC mp_obj_t machine_hard_uart_writechar(mp_obj_t self_in, mp_obj_t char_in) { + machine_hard_uart_obj_t *self = self_in; // get the character to write (might be 9 bits) uint16_t data = mp_obj_get_int(char_in); + hal_uart_error_t err = 0; for (int i = 0; i < 2; i++) { - uart_tx_char(self, (int)(&data)[i]); + err = uart_tx_char(self, (int)(&data)[i]); } - self->uart.instance->TASKS_STOPTX = 0; + HAL_StatusTypeDef status = self->uart->p_instance->EVENTS_ERROR; - HAL_StatusTypeDef status = self->uart.instance->EVENTS_ERROR; - - if (status != HAL_OK) { + if (err != HAL_UART_ERROR_NONE) { mp_hal_raise(status); } return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_uart_writechar_obj, pyb_uart_writechar); +STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_hard_uart_writechar_obj, machine_hard_uart_writechar); /// \method readchar() /// Receive a single character on the bus. /// Return value: The character read, as an integer. Returns -1 on timeout. -STATIC mp_obj_t pyb_uart_readchar(mp_obj_t self_in) { - pyb_uart_obj_t *self = self_in; - +STATIC mp_obj_t machine_hard_uart_readchar(mp_obj_t self_in) { + machine_hard_uart_obj_t *self = self_in; +#if 0 if (uart_rx_wait(self, self->timeout)) { +#endif return MP_OBJ_NEW_SMALL_INT(uart_rx_char(self)); +#if 0 } else { // return -1 on timeout return MP_OBJ_NEW_SMALL_INT(-1); } +#endif } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_readchar_obj, pyb_uart_readchar); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hard_uart_readchar_obj, machine_hard_uart_readchar); // uart.sendbreak() -STATIC mp_obj_t pyb_uart_sendbreak(mp_obj_t self_in) { +STATIC mp_obj_t machine_hard_uart_sendbreak(mp_obj_t self_in) { return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_sendbreak_obj, pyb_uart_sendbreak); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hard_uart_sendbreak_obj, machine_hard_uart_sendbreak); STATIC const mp_map_elem_t pyb_uart_locals_dict_table[] = { // instance methods - - //{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_uart_init_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&pyb_uart_deinit_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_any), (mp_obj_t)&pyb_uart_any_obj }, - /// \method read([nbytes]) { MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mp_stream_read_obj }, /// \method readline() @@ -403,9 +352,9 @@ STATIC const mp_map_elem_t pyb_uart_locals_dict_table[] = { /// \method readinto(buf[, nbytes]) { MP_OBJ_NEW_QSTR(MP_QSTR_readinto), (mp_obj_t)&mp_stream_readinto_obj }, /// \method writechar(buf) - { MP_OBJ_NEW_QSTR(MP_QSTR_writechar), (mp_obj_t)&pyb_uart_writechar_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_readchar), (mp_obj_t)&pyb_uart_readchar_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_sendbreak), (mp_obj_t)&pyb_uart_sendbreak_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_writechar), (mp_obj_t)&machine_hard_uart_writechar_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_readchar), (mp_obj_t)&machine_hard_uart_readchar_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_sendbreak), (mp_obj_t)&machine_hard_uart_sendbreak_obj }, // class constants /* @@ -416,8 +365,8 @@ STATIC const mp_map_elem_t pyb_uart_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(pyb_uart_locals_dict, pyb_uart_locals_dict_table); -STATIC mp_uint_t pyb_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) { - pyb_uart_obj_t *self = self_in; +STATIC mp_uint_t machine_hard_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) { + machine_hard_uart_obj_t *self = self_in; byte *buf = buf_in; // check that size is a multiple of character width @@ -439,7 +388,7 @@ STATIC mp_uint_t pyb_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, i for (;;) { int data = uart_rx_char(self); - *buf++ = data; + *buf++ = data; if (--size == 0) { // return number of bytes read @@ -448,8 +397,8 @@ STATIC mp_uint_t pyb_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, i } } -STATIC mp_uint_t pyb_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) { - pyb_uart_obj_t *self = self_in; +STATIC mp_uint_t machine_hard_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) { + machine_hard_uart_obj_t *self = self_in; const byte *buf = buf_in; // check that size is a multiple of character width @@ -458,39 +407,38 @@ STATIC mp_uint_t pyb_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t return MP_STREAM_ERROR; } + hal_uart_error_t err = 0; for (int i = 0; i < size; i++) { - uart_tx_char(self, (int)((uint8_t *)buf)[i]); + err = uart_tx_char(self, (int)((uint8_t *)buf)[i]); } - HAL_StatusTypeDef status = self->uart.instance->EVENTS_ERROR; - - if (status == HAL_OK) { + if (err == HAL_UART_ERROR_NONE) { // return number of bytes written return size; } else { - *errcode = mp_hal_status_to_errno_table[status]; + *errcode = mp_hal_status_to_errno_table[err]; return MP_STREAM_ERROR; } } -STATIC mp_uint_t pyb_uart_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) { - pyb_uart_obj_t *self = self_in; +STATIC mp_uint_t machine_hard_uart_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) { + machine_hard_uart_obj_t *self = self_in; (void)self; return MP_STREAM_ERROR; } STATIC const mp_stream_p_t uart_stream_p = { - .read = pyb_uart_read, - .write = pyb_uart_write, - .ioctl = pyb_uart_ioctl, + .read = machine_hard_uart_read, + .write = machine_hard_uart_write, + .ioctl = machine_hard_uart_ioctl, .is_text = false, }; -const mp_obj_type_t pyb_uart_type = { +const mp_obj_type_t machine_hard_uart_type = { { &mp_type_type }, .name = MP_QSTR_UART, .print = pyb_uart_print, - .make_new = pyb_uart_make_new, + .make_new = machine_hard_uart_make_new, .getiter = mp_identity_getiter, .iternext = mp_stream_unbuffered_iter, .protocol = &uart_stream_p, diff --git a/nrf5/modules/machine/uart.h b/nrf5/modules/machine/uart.h index 26b79c949f..e05744dba8 100644 --- a/nrf5/modules/machine/uart.h +++ b/nrf5/modules/machine/uart.h @@ -33,16 +33,16 @@ typedef enum { PYB_UART_1 = 1, } pyb_uart_t; -typedef struct _pyb_uart_obj_t pyb_uart_obj_t; -extern const mp_obj_type_t pyb_uart_type; +typedef struct _machine_hard_uart_obj_t machine_hard_uart_obj_t; +extern const mp_obj_type_t machine_hard_uart_type; void uart_init0(void); void uart_deinit(void); void uart_irq_handler(mp_uint_t uart_id); -bool uart_rx_any(pyb_uart_obj_t *uart_obj); -int uart_rx_char(pyb_uart_obj_t *uart_obj); -void uart_tx_strn(pyb_uart_obj_t *uart_obj, const char *str, uint len); -void uart_tx_strn_cooked(pyb_uart_obj_t *uart_obj, const char *str, uint len); +bool uart_rx_any(machine_hard_uart_obj_t * uart_obj); +int uart_rx_char(machine_hard_uart_obj_t * uart_obj); +void uart_tx_strn(machine_hard_uart_obj_t * uart_obj, const char *str, uint len); +void uart_tx_strn_cooked(machine_hard_uart_obj_t *uart_obj, const char *str, uint len); #endif diff --git a/nrf5/modules/pyb/modpyb.c b/nrf5/modules/pyb/modpyb.c index b436c2468c..1a5848f869 100644 --- a/nrf5/modules/pyb/modpyb.c +++ b/nrf5/modules/pyb/modpyb.c @@ -37,7 +37,7 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_pyb) }, { MP_OBJ_NEW_QSTR(MP_QSTR_LED), (mp_obj_t)&pyb_led_type }, { MP_OBJ_NEW_QSTR(MP_QSTR_repl_info), (mp_obj_t)&pyb_set_repl_info_obj}, - { MP_OBJ_NEW_QSTR(MP_QSTR_UART), (mp_obj_t)&pyb_uart_type }, + { MP_OBJ_NEW_QSTR(MP_QSTR_UART), (mp_obj_t)&machine_hard_uart_type }, { MP_OBJ_NEW_QSTR(MP_QSTR_Pin), (mp_obj_t)&pin_type }, /* { MP_OBJ_NEW_QSTR(MP_QSTR_main), (mp_obj_t)&pyb_main_obj }*/ }; diff --git a/nrf5/modules/uos/moduos.c b/nrf5/modules/uos/moduos.c index 35bc3f0e64..0f814a9c55 100644 --- a/nrf5/modules/uos/moduos.c +++ b/nrf5/modules/uos/moduos.c @@ -118,7 +118,7 @@ STATIC mp_obj_t os_dupterm(mp_uint_t n_args, const mp_obj_t *args) { } else { if (args[0] == mp_const_none) { MP_STATE_PORT(pyb_stdio_uart) = NULL; - } else if (mp_obj_get_type(args[0]) == &pyb_uart_type) { + } else if (mp_obj_get_type(args[0]) == &machine_hard_uart_type) { MP_STATE_PORT(pyb_stdio_uart) = args[0]; } else { nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "need a UART object")); diff --git a/nrf5/mpconfigport.h b/nrf5/mpconfigport.h index 8dd4266eba..de50aa57e5 100644 --- a/nrf5/mpconfigport.h +++ b/nrf5/mpconfigport.h @@ -341,10 +341,10 @@ extern const struct _mp_obj_module_t ble_module; struct _pyb_timer_obj_t *pyb_timer_obj_all[14]; \ \ /* stdio is repeated on this UART object if it's not null */ \ - struct _pyb_uart_obj_t *pyb_stdio_uart; \ + struct _machine_hard_uart_obj_t *pyb_stdio_uart; \ \ /* pointers to all UART objects (if they have been created) */ \ - struct _pyb_uart_obj_t *pyb_uart_obj_all[1]; \ + struct _machine_hard_uart_obj_t *pyb_uart_obj_all[1]; \ \ /* list of registered NICs */ \ mp_obj_list_t mod_network_nic_list; \