Addition of RS485 support
This commit is contained in:
parent
84ad3d8393
commit
d388899985
@ -73,7 +73,8 @@ void LPUART_UserCallback(LPUART_Type *base, lpuart_handle_t *handle, status_t st
|
|||||||
|
|
||||||
void common_hal_busio_uart_construct(busio_uart_obj_t *self,
|
void common_hal_busio_uart_construct(busio_uart_obj_t *self,
|
||||||
const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx,
|
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,
|
const mcu_pin_obj_t * rts, const mcu_pin_obj_t * cts,
|
||||||
|
const mcu_pin_obj_t * rs485_dir, bool rs485_invert,
|
||||||
uint32_t baudrate, uint8_t bits, uart_parity_t parity, uint8_t stop,
|
uint32_t baudrate, uint8_t bits, uart_parity_t parity, uint8_t stop,
|
||||||
mp_float_t timeout, uint16_t receiver_buffer_size) {
|
mp_float_t timeout, uint16_t receiver_buffer_size) {
|
||||||
|
|
||||||
@ -114,7 +115,22 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
|
|||||||
mp_raise_RuntimeError(translate("Invalid UART pin selection"));
|
mp_raise_RuntimeError(translate("Invalid UART pin selection"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now check for RTS/CTS pin(s)
|
// Filter for sane settings for RS485
|
||||||
|
if (rs485_dir != mp_const_none) {
|
||||||
|
if ((rts != mp_const_none) || (cts != mp_const_none)) {
|
||||||
|
mp_raise_ValueError(translate("Cannot specify RTS or CTS in RS485 mode"));
|
||||||
|
}
|
||||||
|
// For IMXRT the RTS pin is used for RS485 direction
|
||||||
|
rts = rs485_dir;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (rs485_invert == true) {
|
||||||
|
mp_raise_ValueError(translate("RS485 inversion specified when not in RS485 mode"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now check for RTS/CTS (or overloaded RS485 direction) pin(s)
|
||||||
const uint32_t rts_count = sizeof(mcu_uart_rts_list) / sizeof(mcu_periph_obj_t);
|
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);
|
const uint32_t cts_count = sizeof(mcu_uart_cts_list) / sizeof(mcu_periph_obj_t);
|
||||||
|
|
||||||
@ -163,10 +179,24 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
|
|||||||
config.enableTx = self->tx_pin != NULL;
|
config.enableTx = self->tx_pin != NULL;
|
||||||
config.enableRx = self->rx_pin != NULL;
|
config.enableRx = self->rx_pin != NULL;
|
||||||
config.enableRxRTS = self->rts_pin != NULL;
|
config.enableRxRTS = self->rts_pin != NULL;
|
||||||
config.enableTxCTS = self->cts_pin != NULL;
|
config.enableTxCTS = self->cts_pin != NULL;
|
||||||
|
if (self->rts_pin != NULL)
|
||||||
|
claim_pin(self->rts_pin->pin);
|
||||||
|
if (self->cts_pin != NULL)
|
||||||
|
claim_pin(self->cts_pin->pin);
|
||||||
|
|
||||||
LPUART_Init(self->uart, &config, UART_CLOCK_FREQ);
|
LPUART_Init(self->uart, &config, UART_CLOCK_FREQ);
|
||||||
|
|
||||||
|
// Before we init, setup RS485 direction pin
|
||||||
|
// ..unfortunately this isn't done by the driver library
|
||||||
|
uint32_t modir = (self->uart->MODIR) & ~(LPUART_MODIR_TXRTSPOL_MASK | LPUART_MODIR_TXRTSE_MASK);
|
||||||
|
if (rs485_dir != mp_const_none) {
|
||||||
|
modir |= LPUART_MODIR_TXRTSE_MASK;
|
||||||
|
if ( rs485_invert == true )
|
||||||
|
modir |= LPUART_MODIR_TXRTSPOL_MASK;
|
||||||
|
}
|
||||||
|
self->uart->MODIR = modir;
|
||||||
|
|
||||||
if (self->tx_pin != NULL)
|
if (self->tx_pin != NULL)
|
||||||
claim_pin(self->tx_pin->pin);
|
claim_pin(self->tx_pin->pin);
|
||||||
|
|
||||||
|
@ -324,7 +324,7 @@ void flexspi_nor_flash_init(FLEXSPI_Type *base)
|
|||||||
config.ahbConfig.enableAHBBufferable = true;
|
config.ahbConfig.enableAHBBufferable = true;
|
||||||
config.ahbConfig.enableReadAddressOpt = true;
|
config.ahbConfig.enableReadAddressOpt = true;
|
||||||
config.ahbConfig.enableAHBCachable = true;
|
config.ahbConfig.enableAHBCachable = true;
|
||||||
config.rxSampleClock = kFLEXSPI_ReadSampleClkLoopbackFromDqsPad;
|
config.rxSampleClock = kFLEXSPI_ReadSampleClkLoopbackInternally; //kFLEXSPI_ReadSampleClkLoopbackFromDqsPad;
|
||||||
FLEXSPI_Init(base, &config);
|
FLEXSPI_Init(base, &config);
|
||||||
|
|
||||||
/* Configure flash settings according to serial flash feature. */
|
/* Configure flash settings according to serial flash feature. */
|
||||||
|
@ -53,6 +53,10 @@
|
|||||||
//|
|
//|
|
||||||
//| :param ~microcontroller.Pin tx: the pin to transmit with, or ``None`` if this ``UART`` is receive-only.
|
//| :param ~microcontroller.Pin tx: the pin to transmit with, or ``None`` if this ``UART`` is receive-only.
|
||||||
//| :param ~microcontroller.Pin rx: the pin to receive on, or ``None`` if this ``UART`` is transmit-only.
|
//| :param ~microcontroller.Pin rx: the pin to receive on, or ``None`` if this ``UART`` is transmit-only.
|
||||||
|
//| :param ~microcontroller.Pin rts: the pin for rts, or ``None`` if rts not in use.
|
||||||
|
//| :param ~microcontroller.Pin cts: the pin for cts, or ``None`` if cts not in use.
|
||||||
|
//| :param ~microcontroller.Pin rs485_dir: the pin for rs485 direction setting, or ``None`` if rs485 not in use.
|
||||||
|
//| :param bool rs485_invert: set to invert the sense of the rs485_dir pin.
|
||||||
//| :param int baudrate: the transmit and receive speed.
|
//| :param int baudrate: the transmit and receive speed.
|
||||||
//| :param int bits: the number of bits per byte, 7, 8 or 9.
|
//| :param int bits: the number of bits per byte, 7, 8 or 9.
|
||||||
//| :param Parity parity: the parity used for error checking.
|
//| :param Parity parity: the parity used for error checking.
|
||||||
@ -82,7 +86,8 @@ 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)
|
// https://github.com/adafruit/circuitpython/issues/1056)
|
||||||
busio_uart_obj_t *self = m_new_ll_obj(busio_uart_obj_t);
|
busio_uart_obj_t *self = m_new_ll_obj(busio_uart_obj_t);
|
||||||
self->base.type = &busio_uart_type;
|
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, ARG_rts, ARG_cts, ARG_rs485};
|
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_dir,ARG_rs485_invert};
|
||||||
static const mp_arg_t allowed_args[] = {
|
static const mp_arg_t allowed_args[] = {
|
||||||
{ MP_QSTR_tx, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
{ MP_QSTR_tx, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||||
{ MP_QSTR_rx, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
{ MP_QSTR_rx, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||||
@ -94,7 +99,8 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, co
|
|||||||
{ MP_QSTR_receiver_buffer_size, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64} },
|
{ 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_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_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_QSTR_rs485_dir, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none } },
|
||||||
|
{ MP_QSTR_rs485_invert, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false } },
|
||||||
};
|
};
|
||||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_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(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||||
@ -131,9 +137,10 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, co
|
|||||||
|
|
||||||
const mcu_pin_obj_t* cts = MP_OBJ_TO_PTR(args[ARG_cts].u_obj);
|
const mcu_pin_obj_t* cts = MP_OBJ_TO_PTR(args[ARG_cts].u_obj);
|
||||||
|
|
||||||
bool rs485 = args[ARG_rs485].u_bool;
|
const mcu_pin_obj_t* rs485_dir = args[ARG_rs485_dir].u_obj;
|
||||||
|
bool rs485_invert = args[ARG_rs485_invert].u_bool;
|
||||||
|
|
||||||
common_hal_busio_uart_construct(self, tx, rx, rts, cts, rs485,
|
common_hal_busio_uart_construct(self, tx, rx, rts, cts, rs485_dir, rs485_invert,
|
||||||
args[ARG_baudrate].u_int, bits, parity, stop, timeout,
|
args[ARG_baudrate].u_int, bits, parity, stop, timeout,
|
||||||
args[ARG_receiver_buffer_size].u_int);
|
args[ARG_receiver_buffer_size].u_int);
|
||||||
return (mp_obj_t)self;
|
return (mp_obj_t)self;
|
||||||
|
@ -41,7 +41,8 @@ typedef enum {
|
|||||||
// Construct an underlying UART object.
|
// Construct an underlying UART object.
|
||||||
extern void common_hal_busio_uart_construct(busio_uart_obj_t *self,
|
extern void common_hal_busio_uart_construct(busio_uart_obj_t *self,
|
||||||
const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx,
|
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,
|
const mcu_pin_obj_t * rts, const mcu_pin_obj_t * cts,
|
||||||
|
const mcu_pin_obj_t * rs485_dir, bool rs485_invert,
|
||||||
uint32_t baudrate, uint8_t bits, uart_parity_t parity, uint8_t stop,
|
uint32_t baudrate, uint8_t bits, uart_parity_t parity, uint8_t stop,
|
||||||
mp_float_t timeout, uint16_t receiver_buffer_size);
|
mp_float_t timeout, uint16_t receiver_buffer_size);
|
||||||
|
|
||||||
|
@ -111,12 +111,17 @@ mp_obj_t common_hal_board_create_uart(void) {
|
|||||||
const mcu_pin_obj_t* cts = mp_const_none;
|
const mcu_pin_obj_t* cts = mp_const_none;
|
||||||
#endif
|
#endif
|
||||||
#ifdef DEFAULT_UART_IS_RS485
|
#ifdef DEFAULT_UART_IS_RS485
|
||||||
const bool rs485 = true;
|
const mcu_pin_obj_t* rs485_dir = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_RS485DIR);
|
||||||
|
#ifdef DEFAULT_UART_RS485_INVERT
|
||||||
|
const bool rs485_invert = true;
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
const bool rs485 = false;
|
const mcu_pin_obj_t* rs485_dir = mp_const_none;
|
||||||
|
const bool rs485_invert = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
common_hal_busio_uart_construct(self, tx, rx, rts, cts, rs485, 9600, 8, PARITY_NONE, 1, 1.0f, 64);
|
common_hal_busio_uart_construct(self, tx, rx, rts, cts, rs485_dir, rs485_invert,
|
||||||
|
9600, 8, PARITY_NONE, 1, 1.0f, 64);
|
||||||
MP_STATE_VM(shared_uart_bus) = MP_OBJ_FROM_PTR(self);
|
MP_STATE_VM(shared_uart_bus) = MP_OBJ_FROM_PTR(self);
|
||||||
return MP_STATE_VM(shared_uart_bus);
|
return MP_STATE_VM(shared_uart_bus);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user