42 #if RUUVI_NRF5_SDK15_I2C_ENABLED
46 #include "ruuvi_boards.h"
47 #include "nrf_drv_twi.h"
54 #ifndef NRF_FIX_TWI_ISSUE_219
55 #define NRF_FIX_TWI_ISSUE_219
58 #ifdef NRF_FIX_TWI_ISSUE_219
59 #define NRF_DRV_TWI_FREQ_390K (0x06200000UL)
62 static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE (I2C_INSTANCE);
63 static bool m_i2c_is_init =
false;
64 static volatile bool m_tx_in_progress =
false;
65 static volatile ret_code_t xfer_status = NRF_SUCCESS;
66 static uint16_t timeout_us_per_byte = 1000;
68 static nrf_drv_twi_frequency_t ruuvi_to_nrf_frequency (
const
74 return NRF_DRV_TWI_FREQ_100K;
77 return NRF_DRV_TWI_FREQ_250K;
81 return NRF_DRV_TWI_FREQ_400K;
85 static void byte_timeout_set (
const
91 timeout_us_per_byte = 1000;
94 timeout_us_per_byte = 400;
98 timeout_us_per_byte = 200;
102 #ifdef NRF_FIX_TWI_ISSUE_219
103 static void byte_freq_set (nrf_drv_twi_t
const * p_instance,
106 NRF_TWI_Type * p_reg_twi = p_instance->u.twi.p_twi;
107 NRF_TWIM_Type * p_reg_twim = p_instance->u.twim.p_twim;
111 if (NRF_DRV_TWI_USE_TWIM) { p_reg_twim->FREQUENCY = NRF_DRV_TWI_FREQ_390K; }
112 else { p_reg_twi->FREQUENCY = NRF_DRV_TWI_FREQ_390K; }
117 static void on_complete (nrf_drv_twi_evt_t
const * p_event,
void * p_context)
119 m_tx_in_progress =
false;
121 if (p_event->type == NRF_DRV_TWI_EVT_ADDRESS_NACK) { xfer_status |= NRF_ERROR_NOT_FOUND; }
122 else if (p_event->type == NRF_DRV_TWI_EVT_DATA_NACK) { xfer_status |= NRF_ERROR_DRV_TWI_ERR_DNACK; }
123 else if (p_event->type != NRF_DRV_TWI_EVT_DONE) { xfer_status |= NRF_ERROR_INTERNAL; }
130 nrf_drv_twi_frequency_t frequency = ruuvi_to_nrf_frequency (config->
frequency);
132 const nrf_drv_twi_config_t twi_config =
134 .scl = ruuvi_to_nrf_pin_map (config->
scl),
135 .sda = ruuvi_to_nrf_pin_map (config->
sda),
136 .frequency = frequency,
137 .interrupt_priority = APP_IRQ_PRIORITY_LOW,
138 .clear_bus_init =
true
156 err_code = nrf_drv_twi_init (&m_twi, &twi_config, on_complete, NULL);
157 #ifdef NRF_FIX_TWI_ISSUE_219
158 byte_freq_set (&m_twi, config->
frequency);
160 nrf_drv_twi_enable (&m_twi);
161 m_i2c_is_init =
true;
162 m_tx_in_progress =
false;
168 return m_i2c_is_init;
178 nrf_drv_twi_disable (&m_twi);
179 nrf_drv_twi_uninit (&m_twi);
194 uint8_t *
const p_tx,
const size_t tx_len,
const bool stop)
202 int32_t err_code = NRF_SUCCESS;
203 m_tx_in_progress =
true;
204 err_code |= nrf_drv_twi_tx (&m_twi, address, p_tx, tx_len, !stop);
205 volatile uint32_t timeout = 0;
207 while (m_tx_in_progress && timeout < (timeout_us_per_byte * tx_len))
213 if (timeout >= (timeout_us_per_byte * tx_len)) { err_code |= NRF_ERROR_TIMEOUT; }
215 err_code |= xfer_status;
216 xfer_status = NRF_SUCCESS;
232 uint8_t *
const p_rx,
const size_t rx_len)
238 int32_t err_code = NRF_SUCCESS;
239 m_tx_in_progress =
true;
240 err_code |= nrf_drv_twi_rx (&m_twi, address, p_rx, rx_len);
241 volatile uint32_t timeout = 0;
243 while (m_tx_in_progress && timeout < (timeout_us_per_byte * rx_len))
249 if (timeout >= (timeout_us_per_byte * rx_len)) { err_code |= NRF_ERROR_TIMEOUT; }
251 err_code |= xfer_status;
252 xfer_status = NRF_SUCCESS;
#define RD_ERROR_NULL
Null Pointer.
uint32_t rd_status_t
bitfield for representing errors
rd_status_t ruuvi_nrf5_sdk15_to_ruuvi_error(const ret_code_t error)
convert nrf5 sdk15 error code into Ruuvi error code.
#define RD_SUCCESS
Internal Error.
#define RD_ERROR_INVALID_STATE
Invalid state, operation disallowed in this state.
#define RD_ERROR_INTERNAL
Internal Error.
#define RD_ERROR_BUSY
Busy.
rd_status_t ri_gpio_configure(const ri_gpio_id_t pin, const ri_gpio_mode_t mode)
Configure a pin of a port into a mode. If there are several ports the platform driver must implement ...
rd_status_t ri_gpio_read(const ri_gpio_id_t pin, ri_gpio_state_t *const p_state)
Read state of a pin of a port into bool high If there are several ports the platform driver must impl...
rd_status_t ri_gpio_write(const ri_gpio_id_t pin, const ri_gpio_state_t state)
Write a pin of a port into given state If there are several ports the platform driver must implement ...
Header to enable and disable module compilation.
Ruuvi error codes and error check function.
@ RI_GPIO_MODE_INPUT_PULLUP
Input, can be read. Pulled up by internal resistor, value depends on IC.
@ RI_GPIO_MODE_OUTPUT_HIGHDRIVE
Push-pull output, can be written. Higher current drive than standard.
ri_gpio_state_t
States of GPIO pins.
@ RI_GPIO_HIGH
GPIO electrically high.
Interface for I2C operations.
rd_status_t ri_i2c_init(const ri_i2c_init_config_t *const config)
Initialize I2C driver with given settings.
rd_status_t ri_i2c_write_blocking(const uint8_t address, uint8_t *const p_tx, const size_t tx_len, const bool stop)
I2C read function.
bool ri_i2c_is_init()
Check if i2c driver is initialized.
rd_status_t ri_i2c_uninit(void)
Uninitialize I2C.
@ RI_I2C_FREQUENCY_250k
250 kbps.
@ RI_I2C_FREQUENCY_400k
400 kbps.
@ RI_I2C_FREQUENCY_100k
100 kbps.
rd_status_t ri_i2c_read_blocking(const uint8_t address, uint8_t *const p_rx, const size_t rx_len)
I2C read function.
rd_status_t ri_delay_us(uint32_t time)
Delay a given number of microseconds.
ri_gpio_id_t bus_pwr
Power to pull-ups, UNUSED if fixed.
ri_gpio_id_t sda
pin number of SDA
ri_i2c_frequency_t frequency
Frequency of I2C Bus, see ri_i2c_frequency_t.
ri_gpio_id_t scl
pin number of SCL