4 #include <twr_scheduler.h>
5 #include <twr_ds28e17.h>
6 #include <twr_module_sensor.h>
7 #include <twr_module_x1.h>
8 #include <twr_onewire.h>
9 #include <twr_system.h>
12 #define _TWR_I2C_TX_TIMEOUT_ADJUST_FACTOR 1.5
13 #define _TWR_I2C_RX_TIMEOUT_ADJUST_FACTOR 1.5
15 #define _TWR_I2C_MEMORY_ADDRESS_SIZE_8BIT 1
16 #define _TWR_I2C_MEMORY_ADDRESS_SIZE_16BIT 2
17 #define _TWR_I2C_RELOAD_MODE I2C_CR2_RELOAD
18 #define _TWR_I2C_AUTOEND_MODE I2C_CR2_AUTOEND
19 #define _TWR_I2C_SOFTEND_MODE (0x00000000U)
20 #define _TWR_I2C_NO_STARTSTOP (0x00000000U)
21 #define _TWR_I2C_GENERATE_START_WRITE I2C_CR2_START
22 #define _TWR_I2C_BYTE_TRANSFER_TIME_US_100 80
23 #define _TWR_I2C_BYTE_TRANSFER_TIME_US_400 20
25 #define __TWR_I2C_RESET_PERIPHERAL(__I2C__) {__I2C__->CR1 &= ~I2C_CR1_PE; __I2C__->CR1 |= I2C_CR1_PE; }
29 int initialized_semaphore;
34 [
TWR_I2C_I2C0] = { .initialized_semaphore = 0, .i2c = I2C2 },
35 [
TWR_I2C_I2C1] = { .initialized_semaphore = 0, .i2c = I2C1 },
42 static bool _twr_i2c_mem_write(I2C_TypeDef *i2c, uint8_t device_address, uint16_t memory_address, uint16_t memory_address_length, uint8_t *buffer, uint16_t length);
43 static bool _twr_i2c_mem_read(I2C_TypeDef *i2c, uint8_t device_address, uint16_t memory_address, uint16_t memory_address_length, uint8_t *buffer, uint16_t length);
44 static bool _twr_i2c_req_mem_write(I2C_TypeDef *i2c, uint8_t device_address, uint16_t memory_address, uint16_t memory_address_length);
45 static bool _twr_i2c_req_mem_read(I2C_TypeDef *i2c, uint8_t device_address, uint16_t memory_address, uint16_t memory_address_length);
46 static void _twr_i2c_config(I2C_TypeDef *i2c, uint8_t device_address, uint8_t length, uint32_t mode, uint32_t Request);
47 static bool _twr_i2c_watch_flag(I2C_TypeDef *i2c, uint32_t flag, FlagStatus status);
48 static bool _twr_i2c_is_ack_failure(I2C_TypeDef *i2c);
49 static bool _twr_i2c_read(I2C_TypeDef *i2c,
const void *buffer,
size_t length);
50 static bool _twr_i2c_write(I2C_TypeDef *i2c,
const void *buffer,
size_t length);
53 static void _twr_i2c_timeout_begin(uint32_t timeout_ms);
54 static bool _twr_i2c_timeout_is_expired(
void);
55 static void _twr_i2c_restore_bus(I2C_TypeDef *i2c);
59 if (++_twr_i2c[channel].initialized_semaphore != 1)
75 GPIOB->OTYPER |= GPIO_OTYPER_OT_10 | GPIO_OTYPER_OT_11;
76 GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEED10 | GPIO_OSPEEDER_OSPEED11;
79 RCC->APB1ENR |= RCC_APB1ENR_I2C2EN;
85 I2C2->CR1 |= I2C_CR1_PE;
100 GPIOB->OTYPER |= GPIO_OTYPER_OT_8 | GPIO_OTYPER_OT_9;
101 GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEED8 | GPIO_OSPEEDER_OSPEED9;
104 RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
110 I2C1->CR1 |= I2C_CR1_PE;
118 #if TWR_USE_X1_FOR_I2C_1W != 1
142 if (--_twr_i2c[channel].initialized_semaphore != 0)
150 I2C2->CR1 &= ~I2C_CR1_PE;
153 RCC->APB1ENR &= ~RCC_APB1ENR_I2C2EN;
158 GPIOB->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEED10_Msk | GPIO_OSPEEDER_OSPEED11_Msk);
169 I2C1->CR1 &= ~I2C_CR1_PE;
172 RCC->APB1ENR &= ~RCC_APB1ENR_I2C1EN;
177 GPIOB->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEED8_Msk | GPIO_OSPEEDER_OSPEED9_Msk);
197 return _twr_i2c[channel].speed;
204 if (_twr_i2c[channel].initialized_semaphore == 0)
213 _twr_i2c[channel].speed = speed;
229 I2C2->CR1 &= ~I2C_CR1_PE;
230 I2C2->TIMINGR = timingr;
231 I2C2->CR1 |= I2C_CR1_PE;
235 I2C1->CR1 &= ~I2C_CR1_PE;
236 I2C1->TIMINGR = timingr;
237 I2C1->CR1 |= I2C_CR1_PE;
240 _twr_i2c[channel].speed = speed;
245 if (_twr_i2c[channel].initialized_semaphore == 0)
255 I2C_TypeDef *i2c = _twr_i2c[channel].i2c;
257 twr_system_pll_enable();
260 uint32_t timeout_ms = _TWR_I2C_TX_TIMEOUT_ADJUST_FACTOR * twr_i2c_get_timeout_ms(channel, transfer->
length);
262 _twr_i2c_timeout_begin(timeout_ms);
267 if (_twr_i2c_watch_flag(i2c, I2C_ISR_BUSY, SET))
270 _twr_i2c_config(i2c, transfer->
device_address << 1, transfer->
length, I2C_CR2_AUTOEND, _TWR_I2C_GENERATE_START_WRITE);
273 status = _twr_i2c_write(i2c, transfer->
buffer, transfer->
length);
280 __TWR_I2C_RESET_PERIPHERAL(i2c);
283 twr_system_pll_disable();
291 if (_twr_i2c[channel].initialized_semaphore == 0)
301 I2C_TypeDef *i2c = _twr_i2c[channel].i2c;
303 twr_system_pll_enable();
306 uint32_t timeout_ms = _TWR_I2C_RX_TIMEOUT_ADJUST_FACTOR * twr_i2c_get_timeout_ms(channel, transfer->
length);
308 _twr_i2c_timeout_begin(timeout_ms);
313 if (_twr_i2c_watch_flag(i2c, I2C_ISR_BUSY, SET))
316 _twr_i2c_config(i2c, transfer->
device_address << 1, transfer->
length, I2C_CR2_AUTOEND, I2C_CR2_START | I2C_CR2_RD_WRN);
319 status = _twr_i2c_read(i2c, transfer->
buffer, transfer->
length);
325 _twr_i2c_restore_bus(i2c);
328 twr_system_pll_disable();
335 if (_twr_i2c[channel].initialized_semaphore == 0)
345 I2C_TypeDef *i2c = _twr_i2c[channel].i2c;
348 twr_system_pll_enable();
350 uint16_t transfer_memory_address_length =
357 __TWR_I2C_RESET_PERIPHERAL(i2c);
360 twr_system_pll_disable();
366 twr_system_pll_disable();
373 if (_twr_i2c[channel].initialized_semaphore == 0)
383 I2C_TypeDef *i2c = _twr_i2c[channel].i2c;
386 twr_system_pll_enable();
388 uint16_t transfer_memory_address_length =
394 _twr_i2c_restore_bus(i2c);
397 twr_system_pll_disable();
403 twr_system_pll_disable();
424 buffer[0] = data >> 8;
465 *data = buffer[0] << 8 | buffer[1];
470 static bool _twr_i2c_mem_write(I2C_TypeDef *i2c, uint8_t device_address, uint16_t memory_address, uint16_t memory_address_length, uint8_t *buffer, uint16_t length)
473 uint32_t timeout_ms = _TWR_I2C_TX_TIMEOUT_ADJUST_FACTOR * twr_i2c_get_timeout_ms(i2c == I2C2 ?
TWR_I2C_I2C0 :
TWR_I2C_I2C1, length);
475 _twr_i2c_timeout_begin(timeout_ms);
478 if (!_twr_i2c_watch_flag(i2c, I2C_ISR_BUSY, SET))
484 if (!_twr_i2c_req_mem_write(i2c, device_address, memory_address, memory_address_length))
490 _twr_i2c_config(i2c, device_address, length, _TWR_I2C_AUTOEND_MODE, _TWR_I2C_NO_STARTSTOP);
493 return _twr_i2c_write(i2c, buffer, length);
496 static bool _twr_i2c_mem_read(I2C_TypeDef *i2c, uint8_t device_address, uint16_t memory_address, uint16_t memory_address_length, uint8_t *buffer, uint16_t length)
499 uint32_t timeout_ms = _TWR_I2C_RX_TIMEOUT_ADJUST_FACTOR * twr_i2c_get_timeout_ms(i2c == I2C2 ?
TWR_I2C_I2C0 :
TWR_I2C_I2C1, length);
501 _twr_i2c_timeout_begin(timeout_ms);
504 if (!_twr_i2c_watch_flag(i2c, I2C_ISR_BUSY, SET))
510 if (!_twr_i2c_req_mem_read(i2c, device_address, memory_address, memory_address_length))
516 _twr_i2c_config(i2c, device_address, length, I2C_CR2_AUTOEND, I2C_CR2_START | I2C_CR2_RD_WRN);
519 return _twr_i2c_read(i2c, buffer, length);
522 static bool _twr_i2c_req_mem_write(I2C_TypeDef *i2c, uint8_t device_address, uint16_t memory_address, uint16_t memory_address_length)
524 _twr_i2c_config(i2c, device_address, memory_address_length, _TWR_I2C_RELOAD_MODE, _TWR_I2C_GENERATE_START_WRITE);
527 if (!_twr_i2c_watch_flag(i2c, I2C_ISR_TXIS, RESET))
533 if (memory_address_length == _TWR_I2C_MEMORY_ADDRESS_SIZE_16BIT)
536 i2c->TXDR = (memory_address >> 8) & 0xff;
539 if (!_twr_i2c_watch_flag(i2c, I2C_ISR_TXIS, RESET))
546 i2c->TXDR = memory_address & 0xff;
549 if (!_twr_i2c_watch_flag(i2c, I2C_ISR_TCR, RESET))
557 static bool _twr_i2c_req_mem_read(I2C_TypeDef *i2c, uint8_t device_address, uint16_t memory_address, uint16_t memory_address_length)
559 _twr_i2c_config(i2c, device_address, memory_address_length, _TWR_I2C_SOFTEND_MODE, _TWR_I2C_GENERATE_START_WRITE);
562 if (!_twr_i2c_watch_flag(i2c, I2C_ISR_TXIS, RESET))
568 if (memory_address_length == _TWR_I2C_MEMORY_ADDRESS_SIZE_16BIT)
571 i2c->TXDR = (memory_address >> 8) & 0xff;
574 if (!_twr_i2c_watch_flag(i2c, I2C_ISR_TXIS, RESET))
581 i2c->TXDR = memory_address & 0xff;
584 if (!_twr_i2c_watch_flag(i2c, I2C_ISR_TC, RESET))
592 static void _twr_i2c_config(I2C_TypeDef *i2c, uint8_t device_address, uint8_t length, uint32_t mode, uint32_t Request)
600 reg &= ~(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP);
603 reg |= (device_address & I2C_CR2_SADD) | (length << I2C_CR2_NBYTES_Pos) | mode | Request;
609 static bool _twr_i2c_watch_flag(I2C_TypeDef *i2c, uint32_t flag, FlagStatus status)
611 while ((i2c->ISR & flag) == status)
613 if ((flag == I2C_ISR_STOPF) || (flag == I2C_ISR_TXIS))
616 if (!_twr_i2c_is_ack_failure(i2c))
622 if (_twr_i2c_timeout_is_expired())
630 static bool _twr_i2c_is_ack_failure(I2C_TypeDef *i2c)
632 if ((i2c->ISR & I2C_ISR_NACKF) != 0)
636 while ((i2c->ISR & I2C_ISR_STOPF) == 0)
638 if (_twr_i2c_timeout_is_expired())
645 i2c->ICR = I2C_ISR_NACKF;
648 i2c->ICR = I2C_ISR_STOPF;
651 if ((i2c->ISR & I2C_ISR_TXIS) != 0)
658 if ((i2c->ISR & I2C_ISR_TXE) == 0)
660 i2c->ISR |= I2C_ISR_TXE;
664 i2c->CR2 &= ~(I2C_CR2_SADD | I2C_CR2_HEAD10R | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_RD_WRN);
672 static bool _twr_i2c_read(I2C_TypeDef *i2c,
const void *buffer,
size_t length)
674 uint8_t *p = (uint8_t *) buffer;
679 if (!_twr_i2c_watch_flag(i2c, I2C_ISR_RXNE, RESET))
693 if (!_twr_i2c_watch_flag(i2c, I2C_ISR_STOPF, RESET))
699 i2c->ICR = I2C_ICR_STOPCF;
702 i2c->CR2 &= ~(I2C_CR2_SADD | I2C_CR2_HEAD10R | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_RD_WRN);
709 uint32_t timeout_us = twr_i2c_get_timeout_us(channel, length);
711 return (timeout_us / 1000) + 10;
718 return _TWR_I2C_BYTE_TRANSFER_TIME_US_100 * (length + 3);
722 return _TWR_I2C_BYTE_TRANSFER_TIME_US_400 * (length + 3);
726 static bool _twr_i2c_write(I2C_TypeDef *i2c,
const void *buffer,
size_t length)
728 uint8_t *p = (uint8_t *) buffer;
733 if (!_twr_i2c_watch_flag(i2c, I2C_ISR_TXIS, RESET))
747 if (!_twr_i2c_watch_flag(i2c, I2C_ISR_STOPF, RESET))
753 i2c->ICR = I2C_ICR_STOPCF;
756 i2c->CR2 &= ~(I2C_CR2_SADD | I2C_CR2_HEAD10R | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_RD_WRN);
761 void _twr_i2c_timeout_begin(uint32_t timeout_ms)
766 bool _twr_i2c_timeout_is_expired(
void)
768 bool is_expired = tick_timeout <
twr_tick_get() ? true :
false;
773 static void _twr_i2c_restore_bus(I2C_TypeDef *i2c)
779 GPIOB->MODER &= ~GPIO_MODER_MODE10_Msk;
780 GPIOB->MODER |= GPIO_MODER_MODE10_0;
781 GPIOB->BSRR = GPIO_BSRR_BS_10;
783 GPIOB->MODER &= ~GPIO_MODER_MODE11_Msk;
785 while (!(GPIOB->IDR & GPIO_IDR_ID11))
787 GPIOB->ODR ^= GPIO_ODR_OD10;
790 GPIOB->BSRR = GPIO_BSRR_BR_11;
791 GPIOB->BSRR = GPIO_BSRR_BS_11;
794 _twr_i2c_config(i2c, 0xfe, 1, I2C_CR2_STOP, _TWR_I2C_SOFTEND_MODE);
797 __TWR_I2C_RESET_PERIPHERAL(i2c);
799 GPIOB->MODER &= ~GPIO_MODER_MODE10_Msk;
800 GPIOB->MODER |= GPIO_MODER_MODE10_1;
802 GPIOB->MODER &= ~GPIO_MODER_MODE11_Msk;
803 GPIOB->MODER |= GPIO_MODER_MODE11_1;
805 GPIOB->BSRR = GPIO_BSRR_BR_10;
806 GPIOB->BSRR = GPIO_BSRR_BR_11;
810 GPIOB->MODER &= ~GPIO_MODER_MODE8_Msk;
811 GPIOB->MODER |= GPIO_MODER_MODE8_0;
812 GPIOB->BSRR = GPIO_BSRR_BS_8;
814 GPIOB->MODER &= ~GPIO_MODER_MODE9_Msk;
816 while (!(GPIOB->IDR & GPIO_IDR_ID9))
818 GPIOB->ODR ^= GPIO_ODR_OD9;
821 GPIOB->BSRR = GPIO_BSRR_BR_9;
822 GPIOB->BSRR = GPIO_BSRR_BS_9;
825 _twr_i2c_config(i2c, 0xfe, 1, I2C_CR2_STOP, _TWR_I2C_SOFTEND_MODE);
828 __TWR_I2C_RESET_PERIPHERAL(i2c);
830 GPIOB->MODER &= ~GPIO_MODER_MODE8_Msk;
831 GPIOB->MODER |= GPIO_MODER_MODE8_1;
833 GPIOB->MODER &= ~GPIO_MODER_MODE9_Msk;
834 GPIOB->MODER |= GPIO_MODER_MODE9_1;
836 GPIOB->BSRR = GPIO_BSRR_BR_8;
837 GPIOB->BSRR = GPIO_BSRR_BR_11;
bool twr_ds28e17_write(twr_ds28e17_t *self, const twr_i2c_transfer_t *transfer)
Write to I2C.
bool twr_ds28e17_memory_read(twr_ds28e17_t *self, const twr_i2c_memory_transfer_t *transfer)
Memory read from I2C.
void twr_ds28e17_deinit(twr_ds28e17_t *self)
Deinitialize DS28E17.
bool twr_ds28e17_memory_write(twr_ds28e17_t *self, const twr_i2c_memory_transfer_t *transfer)
Memory write to I2C.
bool twr_ds28e17_set_speed(twr_ds28e17_t *self, twr_i2c_speed_t speed)
Set I2C speed.
void twr_ds28e17_init(twr_ds28e17_t *self, twr_onewire_t *onewire, uint64_t device_number)
Initialize DS28E17.
bool twr_ds28e17_read(twr_ds28e17_t *self, const twr_i2c_transfer_t *transfer)
Read from I2C.
void twr_gpio_set_pull(twr_gpio_channel_t channel, twr_gpio_pull_t pull)
Set pull-up/pull-down configuration for GPIO channel.
void twr_gpio_init(twr_gpio_channel_t channel)
Initialize GPIO channel.
void twr_gpio_set_mode(twr_gpio_channel_t channel, twr_gpio_mode_t mode)
Set mode of operation for GPIO channel.
@ TWR_GPIO_MODE_ALTERNATE_6
GPIO channel operates in alternate mode AF6.
@ TWR_GPIO_MODE_ALTERNATE_4
GPIO channel operates in alternate mode AF4.
@ TWR_GPIO_MODE_ANALOG
GPIO channel operates in analog mode.
@ TWR_GPIO_SDA0
GPIO channel SDA0.
@ TWR_GPIO_P17
GPIO channel P17, SDA1.
@ TWR_GPIO_SCL0
GPIO channel SCL0.
@ TWR_GPIO_P16
GPIO channel P16, SCL1.
@ TWR_GPIO_PULL_NONE
GPIO channel has no pull-up/pull-down.
@ TWR_GPIO_PULL_UP
GPIO channel has pull-up.
twr_i2c_speed_t
I2C communication speed.
void twr_i2c_deinit(twr_i2c_channel_t channel)
Deitialize I2C channel.
void twr_i2c_init(twr_i2c_channel_t channel, twr_i2c_speed_t speed)
Initialize I2C channel.
#define TWR_I2C_MEMORY_ADDRESS_16_BIT
This flag extends I2C memory transfer address from 8-bit to 16-bit.
bool twr_i2c_memory_write(twr_i2c_channel_t channel, const twr_i2c_memory_transfer_t *transfer)
Memory write to I2C channel.
bool twr_i2c_memory_read(twr_i2c_channel_t channel, const twr_i2c_memory_transfer_t *transfer)
Memory read from I2C channel.
void twr_i2c_set_speed(twr_i2c_channel_t channel, twr_i2c_speed_t speed)
Set I2C channel speed.
bool twr_i2c_read(twr_i2c_channel_t channel, const twr_i2c_transfer_t *transfer)
Read from I2C channel.
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_speed_t twr_i2c_get_speed(twr_i2c_channel_t channel)
Get speed I2C channel.
bool twr_i2c_write(twr_i2c_channel_t channel, const twr_i2c_transfer_t *transfer)
Write to I2C channel.
bool twr_i2c_memory_read_8b(twr_i2c_channel_t channel, uint8_t device_address, uint32_t memory_address, uint8_t *data)
Memory read 1 byte from I2C channel.
twr_i2c_channel_t
I2C channels.
@ TWR_I2C_SPEED_400_KHZ
I2C communication speed is 400 kHz.
@ TWR_I2C_SPEED_100_KHZ
I2C communication speed is 100 kHz.
@ TWR_I2C_I2C0
I2C channel I2C0.
@ TWR_I2C_I2C_1W
I2C channel 1wire.
@ TWR_I2C_I2C1
I2C channel I2C1.
twr_onewire_t * twr_module_sensor_get_onewire(void)
Initialize and get Instance 1-Wire for channel B.
bool twr_module_sensor_onewire_power_up(void)
Semaphore for 1Wire Power up: for R1.1 set VDD On, for R1.0 pull up 56R on channel A.
bool twr_module_sensor_init(void)
Initialize Sensor Module.
bool twr_module_sensor_set_pull(twr_module_sensor_channel_t channel, twr_module_sensor_pull_t pull)
Set pull of Sensor Module channel.
@ TWR_MODULE_SENSOR_PULL_NONE
Channel has no pull.
@ TWR_MODULE_SENSOR_CHANNEL_B
Channel B.
@ TWR_MODULE_SENSOR_CHANNEL_A
Channel A.
bool twr_module_x1_init(void)
Initialize X1 Module.
twr_onewire_t * twr_module_x1_get_onewire(void)
Initialize and get Instance 1-Wire for channel B.
struct twr_onewire_t twr_onewire_t
1-Wire instance
twr_tick_t twr_tick_get(void)
Get absolute timestamp since start of program.
uint64_t twr_tick_t
Timestamp data type.
I2C memory transfer parameters.
uint32_t memory_address
8-bit I2C memory address (it can be extended to 16-bit format if OR-ed with TWR_I2C_MEMORY_ADDRESS_16...
uint8_t device_address
7-bit I2C device address
size_t length
Length of buffer which is being written or read.
void * buffer
Pointer to buffer which is being written or read.
void * buffer
Pointer to buffer which is being written or read.
uint8_t device_address
7-bit I2C device address
size_t length
Length of buffer which is being written or read.