mirror of
https://github.com/mysensors/MySensors.git
synced 2026-02-20 01:21:27 +01:00
* Add hal for megaAvrs * Add mcu selector setting * Register hal * Pull up pins to save power * Remove dead code * Add before/after sleep delegates * Remove pin turn stable state setting * Make hardware messages mysensors alike * Enable route size reduction for devices with smaller eeprom * Add macro for routes size to keywords * Fix keyworkds.txt - using tabs instead of spaces * Remove tinyAVR hardware debugging * Remove unused macros * Remove .history folder * Fix formatting according to astyle * Remove unused count variable * Update MyTransportHAL.cpp --------- Co-authored-by: Olivier <tekka007@users.noreply.github.com>
596 lines
17 KiB
C++
596 lines
17 KiB
C++
#include "Arduino.h"
|
|
#include "ATSHA204.h"
|
|
|
|
/* Local data and function prototypes */
|
|
|
|
static uint8_t device_pin;
|
|
#if defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_MEGAAVR)
|
|
static volatile uint8_t *device_port_DDR, *device_port_OUT, *device_port_IN;
|
|
#endif
|
|
static void sha204c_calculate_crc(uint8_t length, uint8_t *data, uint8_t *crc);
|
|
static uint8_t sha204c_check_crc(uint8_t *response);
|
|
static void swi_set_signal_pin(uint8_t is_high);
|
|
static uint8_t swi_receive_bytes(uint8_t count, uint8_t *buffer);
|
|
static uint8_t swi_send_bytes(uint8_t count, uint8_t *buffer);
|
|
static uint8_t swi_send_byte(uint8_t value);
|
|
static uint8_t sha204p_receive_response(uint8_t size, uint8_t *response);
|
|
static uint8_t sha204c_resync(uint8_t size, uint8_t *response);
|
|
static uint8_t sha204c_send_and_receive(uint8_t *tx_buffer, uint8_t rx_size, uint8_t *rx_buffer,
|
|
uint8_t execution_delay, uint8_t execution_timeout);
|
|
|
|
/* SWI bit bang functions */
|
|
|
|
static void swi_set_signal_pin(uint8_t is_high)
|
|
{
|
|
SHA204_SET_OUTPUT();
|
|
|
|
if (is_high) {
|
|
SHA204_POUT_HIGH();
|
|
} else {
|
|
SHA204_POUT_LOW();
|
|
}
|
|
}
|
|
|
|
static uint8_t swi_send_bytes(uint8_t count, uint8_t *buffer)
|
|
{
|
|
uint8_t i, bit_mask;
|
|
|
|
// Disable interrupts while sending.
|
|
noInterrupts(); //swi_disable_interrupts();
|
|
|
|
// Set signal pin as output.
|
|
SHA204_POUT_HIGH();
|
|
SHA204_SET_OUTPUT();
|
|
|
|
|
|
// Wait turn around time.
|
|
delayMicroseconds(RX_TX_DELAY); //RX_TX_DELAY;
|
|
|
|
for (i = 0; i < count; i++) {
|
|
for (bit_mask = 1; bit_mask > 0; bit_mask <<= 1) {
|
|
if (bit_mask & buffer[i]) {
|
|
SHA204_POUT_LOW(); //*device_port_OUT &= ~device_pin;
|
|
delayMicroseconds(BIT_DELAY); //BIT_DELAY_1;
|
|
SHA204_POUT_HIGH(); //*device_port_OUT |= device_pin;
|
|
delayMicroseconds(7*BIT_DELAY); //BIT_DELAY_7;
|
|
} else {
|
|
// Send a zero bit.
|
|
SHA204_POUT_LOW(); //*device_port_OUT &= ~device_pin;
|
|
delayMicroseconds(BIT_DELAY); //BIT_DELAY_1;
|
|
SHA204_POUT_HIGH(); //*device_port_OUT |= device_pin;
|
|
delayMicroseconds(BIT_DELAY); //BIT_DELAY_1;
|
|
SHA204_POUT_LOW(); //*device_port_OUT &= ~device_pin;
|
|
delayMicroseconds(BIT_DELAY); //BIT_DELAY_1;
|
|
SHA204_POUT_HIGH(); //*device_port_OUT |= device_pin;
|
|
delayMicroseconds(5*BIT_DELAY); //BIT_DELAY_5;
|
|
}
|
|
}
|
|
}
|
|
interrupts(); //swi_enable_interrupts();
|
|
return SWI_FUNCTION_RETCODE_SUCCESS;
|
|
}
|
|
|
|
static uint8_t swi_send_byte(uint8_t value)
|
|
{
|
|
return swi_send_bytes(1, &value);
|
|
}
|
|
|
|
static uint8_t swi_receive_bytes(uint8_t count, uint8_t *buffer)
|
|
{
|
|
uint8_t status = SWI_FUNCTION_RETCODE_SUCCESS;
|
|
uint8_t i;
|
|
uint8_t bit_mask;
|
|
uint8_t pulse_count;
|
|
uint8_t timeout_count;
|
|
|
|
// Disable interrupts while receiving.
|
|
noInterrupts(); //swi_disable_interrupts();
|
|
|
|
// Configure signal pin as input.
|
|
SHA204_SET_INPUT();
|
|
|
|
// Receive bits and store in buffer.
|
|
for (i = 0; i < count; i++) {
|
|
for (bit_mask = 1; bit_mask > 0; bit_mask <<= 1) {
|
|
pulse_count = 0;
|
|
|
|
// Make sure that the variable below is big enough.
|
|
// Change it to uint16_t if 255 is too small, but be aware that
|
|
// the loop resolution decreases on an 8-bit controller in that case.
|
|
timeout_count = START_PULSE_TIME_OUT;
|
|
|
|
// Detect start bit.
|
|
while (--timeout_count > 0) {
|
|
// Wait for falling edge.
|
|
if (SHA204_PIN_READ() == 0) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
//cppcheck-suppress knownConditionTrueFalse
|
|
if (timeout_count == 0) {
|
|
status = SWI_FUNCTION_RETCODE_TIMEOUT;
|
|
break;
|
|
}
|
|
|
|
do {
|
|
// Wait for rising edge.
|
|
if (SHA204_PIN_READ() != 0) {
|
|
// For an Atmel microcontroller this might be faster than "pulse_count++".
|
|
pulse_count = 1;
|
|
break;
|
|
}
|
|
} while (--timeout_count > 0);
|
|
|
|
if (pulse_count == 0) {
|
|
status = SWI_FUNCTION_RETCODE_TIMEOUT;
|
|
break;
|
|
}
|
|
|
|
// Trying to measure the time of start bit and calculating the timeout
|
|
// for zero bit detection is not accurate enough for an 8 MHz 8-bit CPU.
|
|
// So let's just wait the maximum time for the falling edge of a zero bit
|
|
// to arrive after we have detected the rising edge of the start bit.
|
|
timeout_count = ZERO_PULSE_TIME_OUT;
|
|
|
|
// Detect possible edge indicating zero bit.
|
|
do {
|
|
if (SHA204_PIN_READ() == 0) {
|
|
// For an Atmel microcontroller this might be faster than "pulse_count++".
|
|
pulse_count = 2;
|
|
break;
|
|
}
|
|
} while (--timeout_count > 0);
|
|
|
|
// Wait for rising edge of zero pulse before returning. Otherwise we might interpret
|
|
// its rising edge as the next start pulse.
|
|
if (pulse_count == 2) {
|
|
do {
|
|
if (SHA204_PIN_READ() != 0) {
|
|
break;
|
|
}
|
|
} while (timeout_count-- > 0);
|
|
}
|
|
|
|
// Update byte at current buffer index.
|
|
else {
|
|
buffer[i] |= bit_mask; // received "one" bit
|
|
}
|
|
}
|
|
|
|
if (status != SWI_FUNCTION_RETCODE_SUCCESS) {
|
|
break;
|
|
}
|
|
}
|
|
interrupts(); //swi_enable_interrupts();
|
|
|
|
if (status == SWI_FUNCTION_RETCODE_TIMEOUT) {
|
|
if (i > 0) {
|
|
// Indicate that we timed out after having received at least one byte.
|
|
status = SWI_FUNCTION_RETCODE_RX_FAIL;
|
|
}
|
|
}
|
|
return status;
|
|
}
|
|
|
|
/* Physical functions */
|
|
|
|
static uint8_t sha204p_receive_response(uint8_t size, uint8_t *response)
|
|
{
|
|
uint8_t i;
|
|
uint8_t ret_code;
|
|
|
|
for (i = 0; i < size; i++) {
|
|
response[i] = 0;
|
|
}
|
|
|
|
(void) swi_send_byte(SHA204_SWI_FLAG_TX);
|
|
|
|
ret_code = swi_receive_bytes(size, response);
|
|
if (ret_code == SWI_FUNCTION_RETCODE_SUCCESS || ret_code == SWI_FUNCTION_RETCODE_RX_FAIL) {
|
|
uint8_t count_byte;
|
|
count_byte = response[SHA204_BUFFER_POS_COUNT];
|
|
if ((count_byte < SHA204_RSP_SIZE_MIN) || (count_byte > size)) {
|
|
return SHA204_INVALID_SIZE;
|
|
}
|
|
|
|
return SHA204_SUCCESS;
|
|
}
|
|
|
|
// Translate error so that the Communication layer
|
|
// can distinguish between a real error or the
|
|
// device being busy executing a command.
|
|
if (ret_code == SWI_FUNCTION_RETCODE_TIMEOUT) {
|
|
return SHA204_RX_NO_RESPONSE;
|
|
} else {
|
|
return SHA204_RX_FAIL;
|
|
}
|
|
}
|
|
|
|
/* Communication functions */
|
|
|
|
static uint8_t sha204c_resync(uint8_t size, uint8_t *response)
|
|
{
|
|
// Try to re-synchronize without sending a Wake token
|
|
// (step 1 of the re-synchronization process).
|
|
delay(SHA204_SYNC_TIMEOUT);
|
|
uint8_t ret_code = sha204p_receive_response(size, response);
|
|
if (ret_code == SHA204_SUCCESS) {
|
|
return ret_code;
|
|
}
|
|
|
|
// We lost communication. Send a Wake pulse and try
|
|
// to receive a response (steps 2 and 3 of the
|
|
// re-synchronization process).
|
|
atsha204_sleep();
|
|
ret_code = atsha204_wakeup(response);
|
|
|
|
// Translate a return value of success into one
|
|
// that indicates that the device had to be woken up
|
|
// and might have lost its TempKey.
|
|
return (ret_code == SHA204_SUCCESS ? SHA204_RESYNC_WITH_WAKEUP : ret_code);
|
|
}
|
|
|
|
static uint8_t sha204c_send_and_receive(uint8_t *tx_buffer, uint8_t rx_size, uint8_t *rx_buffer,
|
|
uint8_t execution_delay, uint8_t execution_timeout)
|
|
{
|
|
uint8_t ret_code = SHA204_FUNC_FAIL;
|
|
uint8_t ret_code_resync;
|
|
uint8_t n_retries_send;
|
|
uint8_t n_retries_receive;
|
|
uint8_t i;
|
|
uint8_t status_byte;
|
|
uint8_t count = tx_buffer[SHA204_BUFFER_POS_COUNT];
|
|
uint8_t count_minus_crc = count - SHA204_CRC_SIZE;
|
|
uint16_t execution_timeout_us = (uint16_t) (execution_timeout * 1000) + SHA204_RESPONSE_TIMEOUT;
|
|
volatile uint16_t timeout_countdown;
|
|
|
|
// Append CRC.
|
|
sha204c_calculate_crc(count_minus_crc, tx_buffer, tx_buffer + count_minus_crc);
|
|
|
|
// Retry loop for sending a command and receiving a response.
|
|
n_retries_send = SHA204_RETRY_COUNT + 1;
|
|
|
|
while ((n_retries_send-- > 0) && (ret_code != SHA204_SUCCESS)) {
|
|
// Send command.
|
|
ret_code = swi_send_byte(SHA204_SWI_FLAG_CMD);
|
|
if (ret_code != SWI_FUNCTION_RETCODE_SUCCESS) {
|
|
ret_code = SHA204_COMM_FAIL;
|
|
} else {
|
|
ret_code = swi_send_bytes(count, tx_buffer);
|
|
}
|
|
|
|
if (ret_code != SHA204_SUCCESS) {
|
|
if (sha204c_resync(rx_size, rx_buffer) == SHA204_RX_NO_RESPONSE) {
|
|
return ret_code; // The device seems to be dead in the water.
|
|
} else {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// Wait minimum command execution time and then start polling for a response.
|
|
delay(execution_delay);
|
|
|
|
// Retry loop for receiving a response.
|
|
n_retries_receive = SHA204_RETRY_COUNT + 1;
|
|
while (n_retries_receive-- > 0) {
|
|
// Reset response buffer.
|
|
for (i = 0; i < rx_size; i++) {
|
|
rx_buffer[i] = 0;
|
|
}
|
|
|
|
// Poll for response.
|
|
timeout_countdown = execution_timeout_us;
|
|
do {
|
|
ret_code = sha204p_receive_response(rx_size, rx_buffer);
|
|
timeout_countdown -= SHA204_RESPONSE_TIMEOUT;
|
|
} while ((timeout_countdown > SHA204_RESPONSE_TIMEOUT) && (ret_code == SHA204_RX_NO_RESPONSE));
|
|
|
|
if (ret_code == SHA204_RX_NO_RESPONSE) {
|
|
// We did not receive a response. Re-synchronize and send command again.
|
|
if (sha204c_resync(rx_size, rx_buffer) == SHA204_RX_NO_RESPONSE) {
|
|
// The device seems to be dead in the water.
|
|
return ret_code;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Check whether we received a valid response.
|
|
if (ret_code == SHA204_INVALID_SIZE) {
|
|
// We see 0xFF for the count when communication got out of sync.
|
|
ret_code_resync = sha204c_resync(rx_size, rx_buffer);
|
|
if (ret_code_resync == SHA204_SUCCESS) {
|
|
// We did not have to wake up the device. Try receiving response again.
|
|
continue;
|
|
}
|
|
if (ret_code_resync == SHA204_RESYNC_WITH_WAKEUP) {
|
|
// We could re-synchronize, but only after waking up the device.
|
|
// Re-send command.
|
|
break;
|
|
} else {
|
|
// We failed to re-synchronize.
|
|
return ret_code;
|
|
}
|
|
}
|
|
|
|
// We received a response of valid size.
|
|
// Check the consistency of the response.
|
|
ret_code = sha204c_check_crc(rx_buffer);
|
|
if (ret_code == SHA204_SUCCESS) {
|
|
// Received valid response.
|
|
if (rx_buffer[SHA204_BUFFER_POS_COUNT] > SHA204_RSP_SIZE_MIN) {
|
|
// Received non-status response. We are done.
|
|
return ret_code;
|
|
}
|
|
|
|
// Received status response.
|
|
status_byte = rx_buffer[SHA204_BUFFER_POS_STATUS];
|
|
|
|
// Translate the three possible device status error codes
|
|
// into library return codes.
|
|
if (status_byte == SHA204_STATUS_BYTE_PARSE) {
|
|
return SHA204_PARSE_ERROR;
|
|
}
|
|
if (status_byte == SHA204_STATUS_BYTE_EXEC) {
|
|
return SHA204_CMD_FAIL;
|
|
}
|
|
if (status_byte == SHA204_STATUS_BYTE_COMM) {
|
|
// In case of the device status byte indicating a communication
|
|
// error this function exits the retry loop for receiving a response
|
|
// and enters the overall retry loop
|
|
// (send command / receive response).
|
|
ret_code = SHA204_STATUS_CRC;
|
|
break;
|
|
}
|
|
|
|
// Received status response from CheckMAC, DeriveKey, GenDig,
|
|
// Lock, Nonce, Pause, UpdateExtra, or Write command.
|
|
return ret_code;
|
|
}
|
|
|
|
else {
|
|
// Received response with incorrect CRC.
|
|
ret_code_resync = sha204c_resync(rx_size, rx_buffer);
|
|
if (ret_code_resync == SHA204_SUCCESS) {
|
|
// We did not have to wake up the device. Try receiving response again.
|
|
continue;
|
|
}
|
|
if (ret_code_resync == SHA204_RESYNC_WITH_WAKEUP) {
|
|
// We could re-synchronize, but only after waking up the device.
|
|
// Re-send command.
|
|
break;
|
|
} else {
|
|
// We failed to re-synchronize.
|
|
return ret_code;
|
|
}
|
|
} // block end of check response consistency
|
|
|
|
} // block end of receive retry loop
|
|
|
|
} // block end of send and receive retry loop
|
|
|
|
return ret_code;
|
|
}
|
|
|
|
/* CRC Calculator and Checker */
|
|
|
|
static void sha204c_calculate_crc(uint8_t length, uint8_t *data, uint8_t *crc)
|
|
{
|
|
uint8_t counter;
|
|
uint16_t crc_register = 0;
|
|
uint16_t polynom = 0x8005;
|
|
uint8_t shift_register;
|
|
uint8_t data_bit, crc_bit;
|
|
|
|
for (counter = 0; counter < length; counter++) {
|
|
for (shift_register = 0x01; shift_register > 0x00; shift_register <<= 1) {
|
|
data_bit = (data[counter] & shift_register) ? 1 : 0;
|
|
crc_bit = crc_register >> 15;
|
|
|
|
// Shift CRC to the left by 1.
|
|
crc_register <<= 1;
|
|
|
|
if ((data_bit ^ crc_bit) != 0) {
|
|
crc_register ^= polynom;
|
|
}
|
|
}
|
|
}
|
|
crc[0] = (uint8_t) (crc_register & 0x00FF);
|
|
crc[1] = (uint8_t) (crc_register >> 8);
|
|
}
|
|
|
|
static uint8_t sha204c_check_crc(uint8_t *response)
|
|
{
|
|
uint8_t crc[SHA204_CRC_SIZE];
|
|
uint8_t count = response[SHA204_BUFFER_POS_COUNT];
|
|
|
|
count -= SHA204_CRC_SIZE;
|
|
sha204c_calculate_crc(count, response, crc);
|
|
|
|
return (crc[0] == response[count] && crc[1] == response[count + 1])
|
|
? SHA204_SUCCESS : SHA204_BAD_CRC;
|
|
}
|
|
|
|
/* Public functions */
|
|
|
|
void atsha204_init(uint8_t pin)
|
|
{
|
|
#if defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_MEGAAVR)
|
|
device_pin = digitalPinToBitMask(pin); // Find the bit value of the pin
|
|
uint8_t port = digitalPinToPort(pin); // temoporarily used to get the next three registers
|
|
|
|
// Point to data direction register port of pin
|
|
device_port_DDR = portModeRegister(port);
|
|
// Point to output register of pin
|
|
device_port_OUT = portOutputRegister(port);
|
|
// Point to input register of pin
|
|
device_port_IN = portInputRegister(port);
|
|
#else
|
|
device_pin = pin;
|
|
#endif
|
|
}
|
|
|
|
void atsha204_idle(void)
|
|
{
|
|
swi_send_byte(SHA204_SWI_FLAG_IDLE);
|
|
}
|
|
|
|
void atsha204_sleep(void)
|
|
{
|
|
swi_send_byte(SHA204_SWI_FLAG_SLEEP);
|
|
}
|
|
|
|
uint8_t atsha204_wakeup(uint8_t *response)
|
|
{
|
|
swi_set_signal_pin(0);
|
|
delayMicroseconds(10*SHA204_WAKEUP_PULSE_WIDTH);
|
|
swi_set_signal_pin(1);
|
|
delay(SHA204_WAKEUP_DELAY);
|
|
|
|
uint8_t ret_code = sha204p_receive_response(SHA204_RSP_SIZE_MIN, response);
|
|
if (ret_code != SHA204_SUCCESS) {
|
|
return ret_code;
|
|
}
|
|
|
|
// Verify status response.
|
|
if (response[SHA204_BUFFER_POS_COUNT] != SHA204_RSP_SIZE_MIN) {
|
|
ret_code = SHA204_INVALID_SIZE;
|
|
} else if (response[SHA204_BUFFER_POS_STATUS] != SHA204_STATUS_BYTE_WAKEUP) {
|
|
ret_code = SHA204_COMM_FAIL;
|
|
} else {
|
|
if ((response[SHA204_RSP_SIZE_MIN - SHA204_CRC_SIZE] != 0x33)
|
|
|| (response[SHA204_RSP_SIZE_MIN + 1 - SHA204_CRC_SIZE] != 0x43)) {
|
|
ret_code = SHA204_BAD_CRC;
|
|
}
|
|
}
|
|
if (ret_code != SHA204_SUCCESS) {
|
|
delay(SHA204_COMMAND_EXEC_MAX);
|
|
}
|
|
|
|
return ret_code;
|
|
}
|
|
|
|
uint8_t atsha204_execute(uint8_t op_code, uint8_t param1, uint16_t param2,
|
|
uint8_t datalen1, uint8_t *data1, uint8_t tx_size, uint8_t *tx_buffer, uint8_t rx_size,
|
|
uint8_t *rx_buffer)
|
|
{
|
|
uint8_t poll_delay, poll_timeout, response_size;
|
|
uint8_t *p_buffer;
|
|
uint8_t len;
|
|
(void)tx_size;
|
|
|
|
// Supply delays and response size.
|
|
switch (op_code) {
|
|
case SHA204_GENDIG:
|
|
poll_delay = GENDIG_DELAY;
|
|
poll_timeout = GENDIG_EXEC_MAX - GENDIG_DELAY;
|
|
response_size = GENDIG_RSP_SIZE;
|
|
break;
|
|
|
|
case SHA204_HMAC:
|
|
poll_delay = HMAC_DELAY;
|
|
poll_timeout = HMAC_EXEC_MAX - HMAC_DELAY;
|
|
response_size = HMAC_RSP_SIZE;
|
|
break;
|
|
|
|
case SHA204_NONCE:
|
|
poll_delay = NONCE_DELAY;
|
|
poll_timeout = NONCE_EXEC_MAX - NONCE_DELAY;
|
|
response_size = param1 == NONCE_MODE_PASSTHROUGH
|
|
? NONCE_RSP_SIZE_SHORT : NONCE_RSP_SIZE_LONG;
|
|
break;
|
|
|
|
case SHA204_RANDOM:
|
|
poll_delay = RANDOM_DELAY;
|
|
poll_timeout = RANDOM_EXEC_MAX - RANDOM_DELAY;
|
|
response_size = RANDOM_RSP_SIZE;
|
|
break;
|
|
|
|
case SHA204_SHA:
|
|
poll_delay = SHA_DELAY;
|
|
poll_timeout = SHA_EXEC_MAX - SHA_DELAY;
|
|
response_size = param1 == SHA_INIT
|
|
? SHA_RSP_SIZE_SHORT : SHA_RSP_SIZE_LONG;
|
|
break;
|
|
|
|
case SHA204_WRITE:
|
|
poll_delay = WRITE_DELAY;
|
|
poll_timeout = WRITE_EXEC_MAX - WRITE_DELAY;
|
|
response_size = WRITE_RSP_SIZE;
|
|
break;
|
|
|
|
default:
|
|
poll_delay = 0;
|
|
poll_timeout = SHA204_COMMAND_EXEC_MAX;
|
|
response_size = rx_size;
|
|
}
|
|
|
|
// Assemble command.
|
|
len = datalen1 + SHA204_CMD_SIZE_MIN;
|
|
p_buffer = tx_buffer;
|
|
*p_buffer++ = len;
|
|
*p_buffer++ = op_code;
|
|
*p_buffer++ = param1;
|
|
*p_buffer++ = param2 & 0xFF;
|
|
*p_buffer++ = param2 >> 8;
|
|
|
|
if (datalen1 > 0) {
|
|
memcpy(p_buffer, data1, datalen1);
|
|
p_buffer += datalen1;
|
|
}
|
|
|
|
sha204c_calculate_crc(len - SHA204_CRC_SIZE, tx_buffer, p_buffer);
|
|
|
|
// Send command and receive response.
|
|
return sha204c_send_and_receive(&tx_buffer[0], response_size,
|
|
&rx_buffer[0], poll_delay, poll_timeout);
|
|
}
|
|
|
|
uint8_t atsha204_getSerialNumber(uint8_t * response)
|
|
{
|
|
uint8_t readCommand[READ_COUNT];
|
|
uint8_t readResponse[READ_4_RSP_SIZE];
|
|
|
|
/* read from bytes 0->3 of config zone */
|
|
uint8_t returnCode = atsha204_read(readCommand, readResponse, SHA204_ZONE_CONFIG, ADDRESS_SN03);
|
|
if (!returnCode) {
|
|
for (int i=0; i<4; i++) {// store bytes 0-3 into respones array
|
|
response[i] = readResponse[SHA204_BUFFER_POS_DATA+i];
|
|
}
|
|
|
|
/* read from bytes 8->11 of config zone */
|
|
returnCode = atsha204_read(readCommand, readResponse, SHA204_ZONE_CONFIG, ADDRESS_SN47);
|
|
|
|
for (int i=4; i<8; i++) {// store bytes 4-7 of SN into response array
|
|
response[i] = readResponse[SHA204_BUFFER_POS_DATA+(i-4)];
|
|
}
|
|
|
|
if (!returnCode) {
|
|
/* Finally if last two reads were successful, read byte 8 of the SN */
|
|
returnCode = atsha204_read(readCommand, readResponse, SHA204_ZONE_CONFIG, ADDRESS_SN8);
|
|
response[8] = readResponse[SHA204_BUFFER_POS_DATA]; // Byte 8 of SN should always be 0xEE
|
|
}
|
|
}
|
|
|
|
return returnCode;
|
|
}
|
|
|
|
uint8_t atsha204_read(uint8_t *tx_buffer, uint8_t *rx_buffer, uint8_t zone, uint16_t address)
|
|
{
|
|
uint8_t rx_size;
|
|
|
|
address >>= 2;
|
|
|
|
tx_buffer[SHA204_COUNT_IDX] = READ_COUNT;
|
|
tx_buffer[SHA204_OPCODE_IDX] = SHA204_READ;
|
|
tx_buffer[READ_ZONE_IDX] = zone;
|
|
tx_buffer[READ_ADDR_IDX] = (uint8_t) (address & SHA204_ADDRESS_MASK);
|
|
tx_buffer[READ_ADDR_IDX + 1] = 0;
|
|
|
|
rx_size = (zone & SHA204_ZONE_COUNT_FLAG) ? READ_32_RSP_SIZE : READ_4_RSP_SIZE;
|
|
|
|
return sha204c_send_and_receive(&tx_buffer[0], rx_size, &rx_buffer[0], READ_DELAY,
|
|
READ_EXEC_MAX - READ_DELAY);
|
|
}
|