Addition of RTS/CTS/RS485 UART functionality

This commit is contained in:
Dave Marples 2020-02-16 00:23:43 +00:00
parent 6f06f92bb1
commit 84ad3d8393
6 changed files with 145 additions and 36 deletions

View File

@ -53,8 +53,8 @@ static void config_periph_pin(const mcu_periph_obj_t *periph) {
IOMUXC_SetPinConfig(0, 0, 0, 0,
periph->pin->cfg_reg,
IOMUXC_SW_PAD_CTL_PAD_HYS(0)
| IOMUXC_SW_PAD_CTL_PAD_PUS(0)
| IOMUXC_SW_PAD_CTL_PAD_PUE(0)
| IOMUXC_SW_PAD_CTL_PAD_PUS(1)
| IOMUXC_SW_PAD_CTL_PAD_PUE(1)
| IOMUXC_SW_PAD_CTL_PAD_PKE(1)
| IOMUXC_SW_PAD_CTL_PAD_ODE(0)
| IOMUXC_SW_PAD_CTL_PAD_SPEED(1)
@ -72,9 +72,10 @@ void LPUART_UserCallback(LPUART_Type *base, lpuart_handle_t *handle, status_t st
}
void common_hal_busio_uart_construct(busio_uart_obj_t *self,
const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate,
uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout,
uint16_t receiver_buffer_size) {
const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx,
const mcu_pin_obj_t * rts, const mcu_pin_obj_t * cts, bool rs485_mode,
uint32_t baudrate, uint8_t bits, uart_parity_t parity, uint8_t stop,
mp_float_t timeout, uint16_t receiver_buffer_size) {
// TODO: Allow none rx or tx
@ -111,12 +112,48 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
if(self->rx_pin == NULL || self->tx_pin == NULL) {
mp_raise_RuntimeError(translate("Invalid UART pin selection"));
} else {
self->uart = mcu_uart_banks[self->tx_pin->bank_idx - 1];
}
// Now check for RTS/CTS pin(s)
const uint32_t rts_count = sizeof(mcu_uart_rts_list) / sizeof(mcu_periph_obj_t);
const uint32_t cts_count = sizeof(mcu_uart_cts_list) / sizeof(mcu_periph_obj_t);
if (rts != mp_const_none) {
for (uint32_t i=0; i < rts_count; ++i)
{
if (mcu_uart_rts_list[i].bank_idx == self->rx_pin->bank_idx) {
if (mcu_uart_rts_list[i].pin == rts) {
self->rts_pin = &mcu_uart_rts_list[i];
break;
}
}
}
if (self->rts_pin == NULL)
mp_raise_ValueError(translate("Selected RTS pin not valid"));
}
if (cts != mp_const_none) {
for (uint32_t i=0; i < cts_count; ++i)
{
if (mcu_uart_cts_list[i].bank_idx == self->rx_pin->bank_idx) {
if (mcu_uart_cts_list[i].pin == cts) {
self->cts_pin = &mcu_uart_cts_list[i];
break;
}
}
}
if (self->cts_pin == NULL)
mp_raise_ValueError(translate("Selected CTS pin not valid"));
}
self->uart = mcu_uart_banks[self->tx_pin->bank_idx - 1];
config_periph_pin(self->rx_pin);
config_periph_pin(self->tx_pin);
if (self->rts_pin)
config_periph_pin(self->rts_pin);
if (self->cts_pin)
config_periph_pin(self->cts_pin);
lpuart_config_t config = { 0 };
LPUART_GetDefaultConfig(&config);
@ -125,10 +162,13 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
config.baudRate_Bps = self->baudrate;
config.enableTx = self->tx_pin != NULL;
config.enableRx = self->rx_pin != NULL;
config.enableRxRTS = self->rts_pin != NULL;
config.enableTxCTS = self->cts_pin != NULL;
LPUART_Init(self->uart, &config, UART_CLOCK_FREQ);
claim_pin(self->tx_pin->pin);
if (self->tx_pin != NULL)
claim_pin(self->tx_pin->pin);
if (self->rx_pin != NULL) {
ringbuf_alloc(&self->rbuf, receiver_buffer_size, true);
@ -203,7 +243,9 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
LPUART_TransferAbortReceive(self->uart, &self->handle);
}
return len - self->handle.rxDataSize;
// The only place we can reliably tell how many bytes have been received is from the current
// wp in the handle (because the abort nukes rxDataSize, and reading it before abort is a race.)
return self->handle.rxData-data;
}
// Write characters.

View File

@ -109,53 +109,93 @@ LPUART_Type *mcu_uart_banks[] = { LPUART1, LPUART2, LPUART3, LPUART4, LPUART5, L
const mcu_periph_obj_t mcu_uart_rx_list[16] = {
PERIPH_PIN(1, 2, 0, 0, &pin_GPIO_AD_B0_07),
PERIPH_PIN(2, 2, kIOMUXC_LPUART2_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_23),
PERIPH_PIN(2, 2, kIOMUXC_LPUART2_RX_SELECT_INPUT, 1, &pin_GPIO_AD_B1_09),
PERIPH_PIN(2, 2, kIOMUXC_LPUART2_RX_SELECT_INPUT, 0, &pin_GPIO_AD_B1_09),
PERIPH_PIN(2, 2, kIOMUXC_LPUART2_RX_SELECT_INPUT, 1, &pin_GPIO_EMC_23),
PERIPH_PIN(3, 2, kIOMUXC_LPUART3_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_07),
PERIPH_PIN(3, 2, kIOMUXC_LPUART3_RX_SELECT_INPUT, 1, &pin_GPIO_AD_B0_15),
PERIPH_PIN(4, 2, kIOMUXC_LPUART4_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_03),
PERIPH_PIN(4, 2, kIOMUXC_LPUART4_RX_SELECT_INPUT, 1, &pin_GPIO_EMC_33),
PERIPH_PIN(4, 2, kIOMUXC_LPUART4_RX_SELECT_INPUT, 2, &pin_GPIO_AD_B1_11),
PERIPH_PIN(4, 2, kIOMUXC_LPUART4_RX_SELECT_INPUT, 1, &pin_GPIO_AD_B1_11),
PERIPH_PIN(4, 2, kIOMUXC_LPUART4_RX_SELECT_INPUT, 2, &pin_GPIO_EMC_33),
PERIPH_PIN(5, 2, kIOMUXC_LPUART5_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_39),
PERIPH_PIN(5, 2, kIOMUXC_LPUART5_RX_SELECT_INPUT, 1, &pin_GPIO_AD_B0_11),
PERIPH_PIN(5, 2, kIOMUXC_LPUART5_RX_SELECT_INPUT, 0, &pin_GPIO_AD_B0_11),
PERIPH_PIN(5, 2, kIOMUXC_LPUART5_RX_SELECT_INPUT, 1, &pin_GPIO_EMC_39),
PERIPH_PIN(6, 2, kIOMUXC_LPUART6_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_13),
PERIPH_PIN(6, 2, kIOMUXC_LPUART6_RX_SELECT_INPUT, 1, &pin_GPIO_SD_B1_01),
PERIPH_PIN(7, 2, kIOMUXC_LPUART7_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_35),
PERIPH_PIN(7, 2, kIOMUXC_LPUART7_RX_SELECT_INPUT, 1, &pin_GPIO_SD_B0_05),
PERIPH_PIN(7, 2, kIOMUXC_LPUART7_RX_SELECT_INPUT, 0, &pin_GPIO_SD_B0_05),
PERIPH_PIN(7, 2, kIOMUXC_LPUART7_RX_SELECT_INPUT, 1, &pin_GPIO_EMC_35),
PERIPH_PIN(8, 2, kIOMUXC_LPUART8_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_27),
PERIPH_PIN(8, 2, kIOMUXC_LPUART8_RX_SELECT_INPUT, 1, &pin_GPIO_SD_B1_03),
PERIPH_PIN(8, 2, kIOMUXC_LPUART8_RX_SELECT_INPUT, 0, &pin_GPIO_SD_B1_03),
PERIPH_PIN(8, 2, kIOMUXC_LPUART8_RX_SELECT_INPUT, 1, &pin_GPIO_EMC_27),
};
const mcu_periph_obj_t mcu_uart_tx_list[16] = {
PERIPH_PIN(1, 2, 0, 0, &pin_GPIO_AD_B0_06),
PERIPH_PIN(2, 2, kIOMUXC_LPUART2_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_22),
PERIPH_PIN(2, 2, kIOMUXC_LPUART2_TX_SELECT_INPUT, 1, &pin_GPIO_AD_B1_08),
PERIPH_PIN(2, 2, kIOMUXC_LPUART2_TX_SELECT_INPUT, 0, &pin_GPIO_AD_B1_08),
PERIPH_PIN(2, 2, kIOMUXC_LPUART2_TX_SELECT_INPUT, 1, &pin_GPIO_EMC_22),
PERIPH_PIN(3, 2, kIOMUXC_LPUART3_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_06),
PERIPH_PIN(3, 2, kIOMUXC_LPUART3_TX_SELECT_INPUT, 1, &pin_GPIO_AD_B0_14),
PERIPH_PIN(4, 2, kIOMUXC_LPUART4_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_02),
PERIPH_PIN(4, 2, kIOMUXC_LPUART4_TX_SELECT_INPUT, 1, &pin_GPIO_EMC_32),
PERIPH_PIN(4, 2, kIOMUXC_LPUART4_TX_SELECT_INPUT, 2, &pin_GPIO_AD_B1_10),
PERIPH_PIN(4, 2, kIOMUXC_LPUART4_TX_SELECT_INPUT, 1, &pin_GPIO_AD_B1_10),
PERIPH_PIN(4, 2, kIOMUXC_LPUART4_TX_SELECT_INPUT, 2, &pin_GPIO_EMC_32),
PERIPH_PIN(5, 2, kIOMUXC_LPUART5_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_38),
PERIPH_PIN(5, 2, kIOMUXC_LPUART5_TX_SELECT_INPUT, 1, &pin_GPIO_AD_B0_10),
PERIPH_PIN(5, 2, kIOMUXC_LPUART5_TX_SELECT_INPUT, 0, &pin_GPIO_AD_B0_10),
PERIPH_PIN(5, 2, kIOMUXC_LPUART5_TX_SELECT_INPUT, 1, &pin_GPIO_EMC_38),
PERIPH_PIN(6, 2, kIOMUXC_LPUART6_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_12),
PERIPH_PIN(6, 2, kIOMUXC_LPUART6_TX_SELECT_INPUT, 1, &pin_GPIO_SD_B1_00),
PERIPH_PIN(7, 2, kIOMUXC_LPUART7_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_34),
PERIPH_PIN(7, 2, kIOMUXC_LPUART7_TX_SELECT_INPUT, 1, &pin_GPIO_SD_B0_04),
PERIPH_PIN(7, 2, kIOMUXC_LPUART7_TX_SELECT_INPUT, 0, &pin_GPIO_SD_B0_04),
PERIPH_PIN(7, 2, kIOMUXC_LPUART7_TX_SELECT_INPUT, 1, &pin_GPIO_EMC_34),
PERIPH_PIN(8, 2, kIOMUXC_LPUART8_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_26),
PERIPH_PIN(8, 2, kIOMUXC_LPUART8_TX_SELECT_INPUT, 1, &pin_GPIO_SD_B1_02),
PERIPH_PIN(8, 2, kIOMUXC_LPUART8_TX_SELECT_INPUT, 0, &pin_GPIO_SD_B1_02),
PERIPH_PIN(8, 2, kIOMUXC_LPUART8_TX_SELECT_INPUT, 1, &pin_GPIO_EMC_26),
};
const mcu_periph_obj_t mcu_uart_rts_list[10] = {
PERIPH_PIN(1, 2, 0, 0, &pin_GPIO_AD_B0_09),
PERIPH_PIN(2, 2, 0, 0, &pin_GPIO_EMC_21),
PERIPH_PIN(2, 2, 0, 1, &pin_GPIO_AD_B1_07),
PERIPH_PIN(3, 2, 0, 1, &pin_GPIO_AD_B0_13),
PERIPH_PIN(4, 2, 0, 0, &pin_GPIO_EMC_01),
PERIPH_PIN(4, 2, 0, 1, &pin_GPIO_EMC_31),
PERIPH_PIN(5, 2, 0, 0, &pin_GPIO_EMC_37),
PERIPH_PIN(6, 2, 0, 0, &pin_GPIO_EMC_15),
PERIPH_PIN(7, 2, 0, 1, &pin_GPIO_SD_B0_03),
PERIPH_PIN(8, 2, 0, 0, &pin_GPIO_EMC_25),
};
const mcu_periph_obj_t mcu_uart_cts_list[10] = {
PERIPH_PIN(1, 2, 0, 0, &pin_GPIO_AD_B0_08),
PERIPH_PIN(2, 2, kIOMUXC_LPUART2_CTS_B_SELECT_INPUT, 0, &pin_GPIO_AD_B1_06),
PERIPH_PIN(2, 2, kIOMUXC_LPUART2_CTS_B_SELECT_INPUT, 1, &pin_GPIO_EMC_20),
PERIPH_PIN(3, 2, 0, 1, &pin_GPIO_AD_B0_12),
PERIPH_PIN(4, 2, kIOMUXC_LPUART4_CTS_B_SELECT_INPUT, 0, &pin_GPIO_EMC_00),
PERIPH_PIN(4, 2, kIOMUXC_LPUART4_CTS_B_SELECT_INPUT, 0, &pin_GPIO_EMC_30),
PERIPH_PIN(5, 2, 0, 0, &pin_GPIO_EMC_36),
PERIPH_PIN(6, 2, 0, 0, &pin_GPIO_EMC_14),
PERIPH_PIN(7, 2, 0, 0, &pin_GPIO_SD_B0_02),
PERIPH_PIN(8, 2, 0, 0, &pin_GPIO_EMC_24),
};
const mcu_pwm_obj_t mcu_pwm_list[39] = {

View File

@ -37,6 +37,8 @@ extern const mcu_periph_obj_t mcu_spi_miso_list[8];
extern const mcu_periph_obj_t mcu_uart_rx_list[16];
extern const mcu_periph_obj_t mcu_uart_tx_list[16];
extern const mcu_periph_obj_t mcu_uart_rts_list[10];
extern const mcu_periph_obj_t mcu_uart_cts_list[10];
extern const mcu_pwm_obj_t mcu_pwm_list[39];

View File

@ -82,7 +82,7 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, co
// https://github.com/adafruit/circuitpython/issues/1056)
busio_uart_obj_t *self = m_new_ll_obj(busio_uart_obj_t);
self->base.type = &busio_uart_type;
enum { ARG_tx, ARG_rx, ARG_baudrate, ARG_bits, ARG_parity, ARG_stop, ARG_timeout, ARG_receiver_buffer_size};
enum { ARG_tx, ARG_rx, ARG_baudrate, ARG_bits, ARG_parity, ARG_stop, ARG_timeout, ARG_receiver_buffer_size, ARG_rts, ARG_cts, ARG_rs485};
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_tx, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_rx, MP_ARG_REQUIRED | MP_ARG_OBJ },
@ -92,6 +92,9 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, co
{ MP_QSTR_stop, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(1)} },
{ MP_QSTR_receiver_buffer_size, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64} },
{ MP_QSTR_rts, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_cts, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_rs485, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false } },
};
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);
@ -124,7 +127,13 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, co
mp_float_t timeout = mp_obj_get_float(args[ARG_timeout].u_obj);
validate_timeout(timeout);
common_hal_busio_uart_construct(self, tx, rx,
const mcu_pin_obj_t* rts = MP_OBJ_TO_PTR(args[ARG_rts].u_obj);
const mcu_pin_obj_t* cts = MP_OBJ_TO_PTR(args[ARG_cts].u_obj);
bool rs485 = args[ARG_rs485].u_bool;
common_hal_busio_uart_construct(self, tx, rx, rts, cts, rs485,
args[ARG_baudrate].u_int, bits, parity, stop, timeout,
args[ARG_receiver_buffer_size].u_int);
return (mp_obj_t)self;

View File

@ -40,9 +40,10 @@ typedef enum {
// Construct an underlying UART object.
extern void common_hal_busio_uart_construct(busio_uart_obj_t *self,
const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate,
uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout,
uint16_t receiver_buffer_size);
const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx,
const mcu_pin_obj_t * rts, const mcu_pin_obj_t * cts, bool rs485_mode,
uint32_t baudrate, uint8_t bits, uart_parity_t parity, uint8_t stop,
mp_float_t timeout, uint16_t receiver_buffer_size);
extern void common_hal_busio_uart_deinit(busio_uart_obj_t *self);
extern bool common_hal_busio_uart_deinited(busio_uart_obj_t *self);

View File

@ -100,8 +100,23 @@ mp_obj_t common_hal_board_create_uart(void) {
const mcu_pin_obj_t* rx = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_RX);
const mcu_pin_obj_t* tx = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_TX);
#ifdef DEFAULT_UART_BUS_RTS
const mcu_pin_obj_t* rts = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_RTS);
#else
const mcu_pin_obj_t* rts = mp_const_none;
#endif
#ifdef DEFAULT_UART_BUS_CTS
const mcu_pin_obj_t* cts = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_CTS);
#else
const mcu_pin_obj_t* cts = mp_const_none;
#endif
#ifdef DEFAULT_UART_IS_RS485
const bool rs485 = true;
#else
const bool rs485 = false;
#endif
common_hal_busio_uart_construct(self, tx, rx, 9600, 8, PARITY_NONE, 1, 1.0f, 64);
common_hal_busio_uart_construct(self, tx, rx, rts, cts, rs485, 9600, 8, PARITY_NONE, 1, 1.0f, 64);
MP_STATE_VM(shared_uart_bus) = MP_OBJ_FROM_PTR(self);
return MP_STATE_VM(shared_uart_bus);
}