1 #include <twr_atsha204.h>
4 #define _TWR_ATSHA204_OPCODE_NULL 0x00
5 #define _TWR_ATSHA204_OPCODE_DEVREV 0x30
6 #define _TWR_ATSHA204_OPCODE_READ 0x02
8 static void _twr_atsha204_task(
void *param);
9 static bool _twr_atsha204_send_command(
twr_atsha204_t *
self, uint8_t opcode, uint8_t param0, uint16_t param1);
12 static bool _twr_atsha204_read(
twr_atsha204_t *
self, uint8_t *buffer,
size_t length);
13 static uint16_t _twr_atsha204_calculate_crc16(uint8_t *buffer, uint8_t length);
17 memset(
self, 0,
sizeof(*
self));
19 self->_i2c_channel = i2c_channel;
20 self->_i2c_address = i2c_address;
31 self->_event_handler = event_handler;
32 self->_event_param = event_param;
47 if (!_twr_atsha204_send_command(
self, _TWR_ATSHA204_OPCODE_READ, 0, 0x00))
53 self->_state = TWR_ATSHA204_STATE_READ_SERIAL_NUMBER;
66 uint8_t *number = (uint8_t *) destination;
70 for (; (i < size) && (i < 2); i++)
72 *number++ =
self->_rx_buffer[3 + i];
75 for (; (i < size) && (i < 6); i++)
77 *number++ =
self->_rx_buffer[6 + i];
88 static void _twr_atsha204_task(
void *param)
94 switch (self->_state) {
95 case TWR_ATSHA204_STATE_READ_SERIAL_NUMBER:
97 if (!_twr_atsha204_read(
self, self->_rx_buffer, 7))
102 if (!_twr_atsha204_send_command(
self, _TWR_ATSHA204_OPCODE_READ, 0, 0x02))
107 self->_state = TWR_ATSHA204_STATE_READ_SERIAL_NUMBER2;
111 case TWR_ATSHA204_STATE_READ_SERIAL_NUMBER2:
113 if (!_twr_atsha204_read(
self, self->_rx_buffer + 7, 7))
118 self->_state = TWR_ATSHA204_STATE_SERIAL_NUMBER;
123 case TWR_ATSHA204_STATE_READY:
124 case TWR_ATSHA204_STATE_SERIAL_NUMBER:
133 if (self->_event_handler)
135 self->_event_handler(
self, event, self->_event_param);
141 static bool _twr_atsha204_send_command(
twr_atsha204_t *
self, uint8_t opcode, uint8_t param0, uint16_t param1)
148 buffer[4] = param1 & 0xff;
149 buffer[5] = param1 >> 8;
151 uint16_t crc = _twr_atsha204_calculate_crc16(buffer + 1, 5);
153 buffer[6] = crc & 0xff;
154 buffer[7] = crc >> 8;
163 if (!_twr_atsha204_wakeup(
self))
177 static bool _twr_atsha204_read(
twr_atsha204_t *
self, uint8_t *buffer,
size_t length)
187 _twr_atsha204_wakeup_puls(
self);
198 uint16_t crc = _twr_atsha204_calculate_crc16(buffer, length - 2);
200 return (buffer[0] == length) &&
201 (buffer[length - 2] == (uint8_t) (crc & 0x00FF)) &&
202 (buffer[length - 1] = (uint8_t) (crc >> 8));
218 _twr_atsha204_wakeup_puls(
self);
224 transfer.
length =
sizeof(buffer);
234 return ((buffer[0] == 0x04) && buffer[1] == 0x11 && buffer[2] == 0x33 && buffer[3] == 0x43);
237 static uint16_t _twr_atsha204_calculate_crc16(uint8_t *buffer, uint8_t length)
240 uint8_t shift_register;
245 for (crc16 = 0; length != 0; length--, buffer++)
249 for (shift_register = 0x01; shift_register > 0x00; shift_register <<= 1) {
251 data_bit = (data & shift_register) ? 1 : 0;
253 crc_bit = crc16 >> 15;
257 if (data_bit != crc_bit)
bool twr_atsha204_get_serial_number(twr_atsha204_t *self, void *destination, size_t size)
Get serial number.
bool twr_atsha204_is_ready(twr_atsha204_t *self)
Check if is ready for commands.
struct twr_atsha204_t twr_atsha204_t
ATSHA204 instance.
void twr_atsha204_init(twr_atsha204_t *self, twr_i2c_channel_t i2c_channel, uint8_t i2c_address)
Initialize ATSHA204 driver.
bool twr_atsha204_read_serial_number(twr_atsha204_t *self)
Reqeust for serial number.
void twr_atsha204_set_event_handler(twr_atsha204_t *self, void(*event_handler)(twr_atsha204_t *, twr_atsha204_event_t, void *), void *event_param)
Set callback function.
@ TWR_ATSHA204_EVENT_SERIAL_NUMBER
Event serial number is available.
@ TWR_ATSHA204_EVENT_ERROR
Error event.
void twr_i2c_init(twr_i2c_channel_t channel, twr_i2c_speed_t speed)
Initialize 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_write(twr_i2c_channel_t channel, const twr_i2c_transfer_t *transfer)
Write to 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.
void twr_scheduler_plan_current_from_now(twr_tick_t tick)
Schedule current task to tick relative from now.
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.
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.