ESP32: add support for RS485 (#2559)
* ESP32: add support for RS485 This commit adds support for switching UART mode to RS485/IRDA. Also included are patches for memory leaks then handling UART events other than data. * ESP32: Documentation for uart.setmode()
This commit is contained in:
parent
794a07bb51
commit
3257e557d4
|
@ -172,6 +172,20 @@ static int uart_setup( lua_State* L )
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int uart_setmode(lua_State* L)
|
||||
{
|
||||
unsigned id, mode;
|
||||
uint32_t res;
|
||||
|
||||
id = luaL_checkinteger( L, 1 );
|
||||
MOD_CHECK_ID( uart, id );
|
||||
mode = luaL_checkinteger( L, 2 );
|
||||
|
||||
platform_uart_setmode(id, mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: write( id, string1, [string2], ..., [stringn] )
|
||||
static int uart_write( lua_State* L )
|
||||
{
|
||||
|
@ -231,6 +245,7 @@ static const LUA_REG_TYPE uart_map[] = {
|
|||
{ LSTRKEY( "start" ), LFUNCVAL( uart_start ) },
|
||||
{ LSTRKEY( "stop" ), LFUNCVAL( uart_stop ) },
|
||||
{ LSTRKEY( "on" ), LFUNCVAL( uart_on ) },
|
||||
{ LSTRKEY( "setmode" ), LFUNCVAL( uart_setmode ) },
|
||||
{ LSTRKEY( "STOPBITS_1" ), LNUMVAL( PLATFORM_UART_STOPBITS_1 ) },
|
||||
{ LSTRKEY( "STOPBITS_1_5" ), LNUMVAL( PLATFORM_UART_STOPBITS_1_5 ) },
|
||||
{ LSTRKEY( "STOPBITS_2" ), LNUMVAL( PLATFORM_UART_STOPBITS_2 ) },
|
||||
|
@ -240,6 +255,11 @@ static const LUA_REG_TYPE uart_map[] = {
|
|||
{ LSTRKEY( "FLOWCTRL_NONE" ), LNUMVAL( PLATFORM_UART_FLOW_NONE ) },
|
||||
{ LSTRKEY( "FLOWCTRL_CTS" ), LNUMVAL( PLATFORM_UART_FLOW_CTS ) },
|
||||
{ LSTRKEY( "FLOWCTRL_RTS" ), LNUMVAL( PLATFORM_UART_FLOW_RTS ) },
|
||||
{ LSTRKEY( "MODE_UART" ), LNUMVAL( PLATFORM_UART_MODE_UART ) },
|
||||
{ LSTRKEY( "MODE_RS485_COLLISION_DETECT" ), LNUMVAL( PLATFORM_UART_MODE_RS485_COLLISION_DETECT ) },
|
||||
{ LSTRKEY( "MODE_RS485_APP_CONTROL" ), LNUMVAL( PLATFORM_UART_MODE_RS485_APP_CONTROL ) },
|
||||
{ LSTRKEY( "MODE_RS485_HALF_DUPLEX" ), LNUMVAL( PLATFORM_UART_MODE_HALF_DUPLEX ) },
|
||||
{ LSTRKEY( "MODE_IRDA" ), LNUMVAL( PLATFORM_UART_MODE_IRDA ) },
|
||||
{ LNILKEY, LNILVAL }
|
||||
};
|
||||
|
||||
|
|
|
@ -50,6 +50,15 @@ int platform_gpio_output_exists( unsigned gpio );
|
|||
|
||||
#define UART_BUFFER_SIZE 512
|
||||
|
||||
enum
|
||||
{
|
||||
PLATFORM_UART_MODE_UART = 0x0,
|
||||
PLATFORM_UART_MODE_RS485_COLLISION_DETECT = 0x1,
|
||||
PLATFORM_UART_MODE_RS485_APP_CONTROL = 0x2,
|
||||
PLATFORM_UART_MODE_HALF_DUPLEX = 0x3,
|
||||
PLATFORM_UART_MODE_IRDA = 0x4
|
||||
};
|
||||
|
||||
// Parity
|
||||
enum
|
||||
{
|
||||
|
@ -107,6 +116,7 @@ typedef struct {
|
|||
// The platform UART functions
|
||||
static inline int platform_uart_exists( unsigned id ) { return id < NUM_UART; }
|
||||
uint32_t platform_uart_setup( unsigned id, uint32_t baud, int databits, int parity, int stopbits, uart_pins_t* pins );
|
||||
void platform_uart_setmode(unsigned id, unsigned mode);
|
||||
void platform_uart_send_multi( unsigned id, const char *data, size_t len );
|
||||
void platform_uart_send( unsigned id, uint8_t data );
|
||||
void platform_uart_flush( unsigned id );
|
||||
|
|
|
@ -76,7 +76,6 @@ void uart_event_task( task_param_t param, task_prio_t prio ) {
|
|||
}
|
||||
|
||||
free(post->data);
|
||||
free(post);
|
||||
} else {
|
||||
char *err;
|
||||
switch(post->type) {
|
||||
|
@ -92,6 +91,7 @@ void uart_event_task( task_param_t param, task_prio_t prio ) {
|
|||
}
|
||||
uart_on_error_cb(id, err, strlen(err));
|
||||
}
|
||||
free(post);
|
||||
}
|
||||
|
||||
static void task_uart( void *pvParameters ){
|
||||
|
@ -130,6 +130,7 @@ static void task_uart( void *pvParameters ){
|
|||
}
|
||||
post->id = id;
|
||||
post->type = PLATFORM_UART_EVENT_BREAK;
|
||||
break;
|
||||
case UART_FIFO_OVF:
|
||||
case UART_BUFFER_FULL:
|
||||
case UART_PARITY_ERR:
|
||||
|
@ -242,6 +243,26 @@ uint32_t platform_uart_setup( unsigned id, uint32_t baud, int databits, int pari
|
|||
}
|
||||
}
|
||||
|
||||
void platform_uart_setmode(unsigned id, unsigned mode)
|
||||
{
|
||||
uart_mode_t uartMode;
|
||||
|
||||
switch(mode)
|
||||
{
|
||||
case PLATFORM_UART_MODE_IRDA:
|
||||
uartMode = UART_MODE_IRDA; break;
|
||||
case PLATFORM_UART_MODE_RS485_COLLISION_DETECT:
|
||||
uartMode = UART_MODE_RS485_COLLISION_DETECT; break;
|
||||
case PLATFORM_UART_MODE_RS485_APP_CONTROL:
|
||||
uartMode = UART_MODE_RS485_APP_CTRL; break;
|
||||
case PLATFORM_UART_MODE_HALF_DUPLEX:
|
||||
uartMode = UART_MODE_RS485_HALF_DUPLEX; break;
|
||||
case PLATFORM_UART_MODE_UART:
|
||||
default:
|
||||
uartMode = UART_MODE_UART; break;
|
||||
}
|
||||
uart_set_mode(id, uartMode);
|
||||
}
|
||||
|
||||
void platform_uart_send_multi( unsigned id, const char *data, size_t len )
|
||||
{
|
||||
|
|
|
@ -131,6 +131,26 @@ Stop the UART. You should not call `stop()` on the console uart.
|
|||
`nil`
|
||||
|
||||
|
||||
## uart.setmode()
|
||||
|
||||
Set UART controllers communication mode
|
||||
|
||||
#### Syntax
|
||||
|
||||
`uart.setmode(id, mode)`
|
||||
|
||||
#### Parameters
|
||||
- `id` uart id
|
||||
- `mode` value should be one of
|
||||
- `uart.MODE_UART` default UART mode, is set after uart.setup() call
|
||||
- `uart.MODE_RS485_COLLISION_DETECT` receiver must be always enabled, transmitter is automatically switched using RTS pin, collision is detected by UART hardware (note: no event is generated on collision, limitation of esp-idf)
|
||||
- `uart.MODE_RS485_APP_CONTROL` receiver/transmitter control is left to the application
|
||||
- `uart.MODE_RS485_HALF_DUPLEX` receiver/transmitter are controlled by RTS pin
|
||||
- `uart.MODE_IRDA`
|
||||
|
||||
#### Returns
|
||||
`nil`
|
||||
|
||||
## uart.write()
|
||||
|
||||
Write string or byte to the UART.
|
||||
|
|
Loading…
Reference in New Issue