1 #include <twr_module_rs485.h>
4 #define _TWR_MODULE_RS485_I2C_UART_ADDRESS 0x4e
5 #define _TWR_MODULE_RS485_I2C_TLA2021_ADDRESS 0x48
7 #define _TWR_SC16IS7x0_REG_IER (0x01 << 3)
8 #define _TWR_SC16IS7X0_REG_IODIR (0x0a << 3)
9 #define _TWR_SC16IS7X0_REG_IOSTATE (0x0b << 3)
10 #define _TWR_SC16IS7X0_REG_IOINTENA (0x0c << 3)
11 #define _TWR_SC16IS7X0_REG_EFCR (0x0f << 3)
13 #define _TWR_MODULE_RS485_DELAY_RUN 50
14 #define _TWR_MODULE_RS485_DELAY_MEASUREMENT 100
16 #define _TWR_MODULE_RS485_ASYNC_WRITE_TASK_PERIOD 10
20 TWR_MODULE_RS485_STATE_ERROR = -1,
21 TWR_MODULE_RS485_STATE_INITIALIZE = 0,
22 TWR_MODULE_RS485_STATE_MEASURE = 1,
23 TWR_MODULE_RS485_STATE_READ = 2,
24 TWR_MODULE_RS485_STATE_UPDATE = 3
26 } twr_module_rs485_state_t;
31 twr_module_rs485_state_t _state;
32 twr_sc16is740_t _sc16is750;
40 bool _measurement_active;
49 bool _async_write_in_progress;
50 bool _async_read_in_progress;
52 uint8_t _async_buffer[64];
57 static void _twr_module_rs485_async_write_task(
void *param);
58 static void _twr_module_rs485_async_read_task(
void *param);
60 static void _twr_module_rs485_task_measure(
void *param);
61 static void _twr_module_rs485_task_interval(
void *param);
65 memset(&_twr_module_rs485, 0,
sizeof(_twr_module_rs485));
102 _twr_module_rs485._task_id_measure =
twr_scheduler_register(_twr_module_rs485_task_measure, NULL, _TWR_MODULE_RS485_DELAY_RUN);
104 _twr_module_rs485._initialized =
true;
112 if (_twr_module_rs485._initialized)
118 _twr_module_rs485._initialized =
false;
132 _twr_module_rs485._update_interval = interval;
148 if (!_twr_module_rs485._voltage_valid)
153 int16_t reg_result = _twr_module_rs485._reg_result;
162 *volt = 39.62f * reg_result / 2047.f;
169 if (_twr_module_rs485._measurement_active)
174 _twr_module_rs485._measurement_active =
true;
181 static void _twr_module_rs485_async_write_task(
void *param)
185 size_t space_available;
190 _twr_module_rs485._async_write_in_progress =
false;
200 _twr_module_rs485._async_write_in_progress =
false;
206 size_t bytes_read =
twr_fifo_read(_twr_module_rs485._write_fifo, _twr_module_rs485._async_buffer, space_available);
212 static void _twr_module_rs485_async_read_task(
void *param)
216 size_t available = 0;
225 twr_sc16is740_read(&_twr_module_rs485._sc16is750, _twr_module_rs485._async_buffer, available, 0);
226 twr_fifo_write(_twr_module_rs485._read_fifo, _twr_module_rs485._async_buffer, available);
241 static void _twr_module_rs485_task_interval(
void *param)
249 static void _twr_module_rs485_task_measure(
void *param)
255 switch (_twr_module_rs485._state)
257 case TWR_MODULE_RS485_STATE_ERROR:
259 if (_twr_module_rs485._event_handler != NULL)
264 _twr_module_rs485._state = TWR_MODULE_RS485_STATE_INITIALIZE;
268 case TWR_MODULE_RS485_STATE_INITIALIZE:
270 _twr_module_rs485._state = TWR_MODULE_RS485_STATE_ERROR;
277 _twr_module_rs485._state = TWR_MODULE_RS485_STATE_MEASURE;
281 if (_twr_module_rs485._measurement_active)
288 case TWR_MODULE_RS485_STATE_MEASURE:
290 _twr_module_rs485._state = TWR_MODULE_RS485_STATE_ERROR;
297 _twr_module_rs485._state = TWR_MODULE_RS485_STATE_READ;
303 case TWR_MODULE_RS485_STATE_READ:
305 _twr_module_rs485._state = TWR_MODULE_RS485_STATE_ERROR;
307 uint16_t reg_configuration;
314 if ((reg_configuration & 0x8000) != 0x8000)
324 _twr_module_rs485._voltage_valid =
true;
326 _twr_module_rs485._state = TWR_MODULE_RS485_STATE_UPDATE;
330 case TWR_MODULE_RS485_STATE_UPDATE:
332 _twr_module_rs485._measurement_active =
false;
334 if (_twr_module_rs485._event_handler != NULL)
339 _twr_module_rs485._state = TWR_MODULE_RS485_STATE_MEASURE;
345 _twr_module_rs485._state = TWR_MODULE_RS485_STATE_ERROR;
354 _twr_module_rs485._write_fifo = write_fifo;
355 _twr_module_rs485._read_fifo = read_fifo;
360 if (!_twr_module_rs485._initialized || _twr_module_rs485._write_fifo == NULL)
365 size_t bytes_written =
twr_fifo_write(_twr_module_rs485._write_fifo, (uint8_t *) buffer, length);
367 if (bytes_written != 0)
369 if (!_twr_module_rs485._async_write_in_progress)
371 _twr_module_rs485._async_write_task_id =
twr_scheduler_register(_twr_module_rs485_async_write_task, NULL, 10);
372 _twr_module_rs485._async_write_in_progress =
true;
376 return bytes_written;
381 if (!_twr_module_rs485._initialized || _twr_module_rs485._read_fifo == NULL || _twr_module_rs485._async_read_in_progress)
386 _twr_module_rs485._async_read_timeout = timeout;
387 _twr_module_rs485._async_read_task_id =
twr_scheduler_register(_twr_module_rs485_async_read_task, NULL, _twr_module_rs485._async_read_timeout);
388 _twr_module_rs485._async_read_in_progress =
true;
395 if (!_twr_module_rs485._initialized || !_twr_module_rs485._async_read_in_progress)
400 _twr_module_rs485._async_read_in_progress =
false;
408 if (!_twr_module_rs485._initialized || _twr_module_rs485._read_fifo == NULL || !_twr_module_rs485._async_read_in_progress)
413 return twr_fifo_read(_twr_module_rs485._read_fifo, buffer, length);
418 _twr_module_rs485._event_handler = event_handler;
419 _twr_module_rs485._event_param = event_param;
size_t twr_fifo_write(twr_fifo_t *fifo, const void *buffer, size_t length)
Write data to FIFO.
bool twr_fifo_is_empty(twr_fifo_t *fifo)
Is empty.
size_t twr_fifo_read(twr_fifo_t *fifo, void *buffer, size_t length)
Read data from FIFO.
bool twr_i2c_memory_write_8b(twr_i2c_channel_t channel, uint8_t device_address, uint32_t memory_address, uint8_t data)
Memory write 1 byte to I2C channel.
bool twr_i2c_memory_write_16b(twr_i2c_channel_t channel, uint8_t device_address, uint32_t memory_address, uint16_t data)
Memory write 2 bytes to I2C channel.
bool twr_i2c_memory_read_16b(twr_i2c_channel_t channel, uint8_t device_address, uint32_t memory_address, uint16_t *data)
Memory read 2 bytes from I2C channel.
@ TWR_I2C_I2C0
I2C channel I2C0.
bool twr_module_rs485_measure(void)
Start single voltage measurement.
size_t twr_module_rs485_read(uint8_t *buffer, size_t length, twr_tick_t timeout)
Read the received data.
size_t twr_module_rs485_async_write(uint8_t *buffer, size_t length)
Add data to be transmited in async mode.
void twr_module_rs485_set_event_handler(void(*event_handler)(twr_module_rs485_event_t, void *), void *event_param)
Set callback function.
size_t twr_module_rs485_write(uint8_t *buffer, size_t length)
Write data to RS-485 bus.
twr_module_rs485_event_t
Callback events.
void twr_module_rs485_set_async_fifo(twr_fifo_t *write_fifo, twr_fifo_t *read_fifo)
Set FIFO.
bool twr_module_rs485_get_voltage(float *volt)
Get measured voltage.
bool twr_module_rs485_available(size_t *available)
Get number of received bytes.
bool twr_module_rs485_deinit(void)
Deinitialize RS-485 Module.
size_t twr_module_rs485_async_read(void *buffer, size_t length)
Get data that has been received in async mode.
bool twr_module_rs485_init(void)
Initialize RS-485 Module.
bool twr_module_rs485_async_read_start(twr_tick_t timeout)
Start async reading.
bool twr_module_rs485_set_baudrate(twr_module_rs485_baudrate_t baudrate)
Set baudrate.
twr_module_rs485_baudrate_t
Baudrates.
void twr_module_rs485_set_update_interval(twr_tick_t interval)
Set measurement interval.
bool twr_module_rs485_async_read_stop(void)
Stop async reading.
@ TWR_MODULE_RS485_EVENT_ASYNC_READ_DATA
Reading done event.
@ TWR_MODULE_RS485_EVENT_ERROR
Error event.
@ TWR_MODULE_RS485_EVENT_VOLTAGE
Update event.
@ TWR_MODULE_RS485_EVENT_ASYNC_READ_TIMEOUT
Timeout event.
@ TWR_MODULE_RS485_EVENT_ASYNC_WRITE_DONE
Async write done.
bool twr_sc16is740_reset_fifo(twr_sc16is740_t *self, twr_sc16is740_fifo_t fifo)
Reset FIFO.
twr_sc16is740_baudrate_t
Baudrates.
size_t twr_sc16is740_write(twr_sc16is740_t *self, uint8_t *buffer, size_t length)
Write.
size_t twr_sc16is740_read(twr_sc16is740_t *self, uint8_t *buffer, size_t length, twr_tick_t timeout)
Read.
bool twr_sc16is740_set_baudrate(twr_sc16is740_t *self, twr_sc16is740_baudrate_t baudrate)
Set baudrate.
bool twr_sc16is740_init(twr_sc16is740_t *self, twr_i2c_channel_t i2c_channel, uint8_t i2c_address)
SC16IS740 instance.
bool twr_sc16is740_available(twr_sc16is740_t *self, size_t *available)
Get RX FIXO available data.
bool twr_sc16is740_get_spaces_available(twr_sc16is740_t *self, size_t *spaces_available)
Get TX FIXO space available.
void twr_scheduler_plan_current_from_now(twr_tick_t tick)
Schedule current task to tick relative from now.
void twr_scheduler_plan_current_relative(twr_tick_t tick)
Schedule current task to tick relative from current spin.
void twr_scheduler_plan_current_absolute(twr_tick_t tick)
Schedule current task to absolute tick.
void twr_scheduler_plan_absolute(twr_scheduler_task_id_t task_id, twr_tick_t tick)
Schedule specified task to absolute tick.
void twr_scheduler_unregister(twr_scheduler_task_id_t task_id)
Unregister specified task.
size_t twr_scheduler_task_id_t
Task ID assigned by scheduler.
void twr_scheduler_plan_relative(twr_scheduler_task_id_t task_id, twr_tick_t tick)
Schedule specified task to tick relative from current spin.
twr_scheduler_task_id_t twr_scheduler_register(void(*task)(void *), void *param, twr_tick_t tick)
Register task in scheduler.
#define TWR_TICK_INFINITY
Maximum timestamp value.
twr_tick_t twr_tick_get(void)
Get absolute timestamp since start of program.
uint64_t twr_tick_t
Timestamp data type.
Structure of FIFO instance.