Added sha204 library
Taken from the sha204_library folder in https://github.com/jimblom/sha204-Breakout Commit 8e1ac05ef987b1869605ad067db2bdbaec1c109f ATSHA204 is a crypto cirquit from Atmel that enables SHA256-based MAC and HMAC calculations as well as secure key storage and random number generation. This can be used to sign messages passed between sensor nodes and prevent both man-in-the-middle and replay attacking.
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
/* ATSHA204 Library Simple Example
|
||||
by: Jim Lindblom
|
||||
SparkFun Electronics
|
||||
date: November 8, 2012
|
||||
|
||||
This code shows how to wake up and verify that an SHA204 is
|
||||
connected and operational. And how to obtain an SHA204's unique serial
|
||||
number, and send it a MAC challenge.
|
||||
|
||||
The ATSHA204's SDA pin can be connected to any of the Arduino's digital pins.
|
||||
When constructing your atsha204Class, pass the constructor the pin you want to use.
|
||||
In this example we'll attach SDA to pin 7.
|
||||
|
||||
The ATSHA204 can be powered between 3.3V and 5V.
|
||||
*/
|
||||
#include <sha204_library.h>
|
||||
|
||||
const int sha204Pin = 7;
|
||||
|
||||
atsha204Class sha204(sha204Pin);
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
Serial.println("Sending a Wakup Command. Response should be:\r\n4 11 33 43:");
|
||||
Serial.println("Response is:");
|
||||
wakeupExample();
|
||||
Serial.println();
|
||||
Serial.println("Asking the SHA204's serial number. Response should be:");
|
||||
Serial.println("1 23 x x x x x x x EE");
|
||||
Serial.println("Response is:");
|
||||
serialNumberExample();
|
||||
Serial.println();
|
||||
Serial.println("Sending a MAC Challenge. Response should be:");
|
||||
Serial.println("23 6 67 0 4F 28 4D 6E 98 62 4 F4 60 A3 E8 75 8A 59 85 A6 79 96 C4 8A 88 46 43 4E B3 DB 58 A4 FB E5 73");
|
||||
Serial.println("Response is:");
|
||||
macChallengeExample();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
byte wakeupExample()
|
||||
{
|
||||
uint8_t response[SHA204_RSP_SIZE_MIN];
|
||||
byte returnValue;
|
||||
|
||||
returnValue = sha204.sha204c_wakeup(&response[0]);
|
||||
for (int i=0; i<SHA204_RSP_SIZE_MIN; i++)
|
||||
{
|
||||
Serial.print(response[i], HEX);
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
byte serialNumberExample()
|
||||
{
|
||||
uint8_t serialNumber[9];
|
||||
byte returnValue;
|
||||
|
||||
returnValue = sha204.getSerialNumber(serialNumber);
|
||||
for (int i=0; i<9; i++)
|
||||
{
|
||||
Serial.print(serialNumber[i], HEX);
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
byte macChallengeExample()
|
||||
{
|
||||
uint8_t command[MAC_COUNT_LONG];
|
||||
uint8_t response[MAC_RSP_SIZE];
|
||||
|
||||
const uint8_t challenge[MAC_CHALLENGE_SIZE] = {
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
|
||||
};
|
||||
|
||||
uint8_t ret_code = sha204.sha204m_execute(SHA204_MAC, 0, 0, MAC_CHALLENGE_SIZE,
|
||||
(uint8_t *) challenge, 0, NULL, 0, NULL, sizeof(command), &command[0],
|
||||
sizeof(response), &response[0]);
|
||||
|
||||
for (int i=0; i<SHA204_RSP_SIZE_MAX; i++)
|
||||
{
|
||||
Serial.print(response[i], HEX);
|
||||
Serial.print(' ');
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
return ret_code;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ATMEL Microcontroller Software Support - Colorado Springs, CO -
|
||||
// ----------------------------------------------------------------------------
|
||||
// DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/** \file
|
||||
* \brief SHA204 Library Return Code Definitions
|
||||
* \author Atmel Crypto Products
|
||||
* \date September 27, 2010
|
||||
*/
|
||||
|
||||
#ifndef SHA204_LIB_RETURN_CODES_H
|
||||
# define SHA204_LIB_RETURN_CODES_H
|
||||
|
||||
#include <stddef.h> // data type definitions
|
||||
|
||||
/** \todo Use same values for same meanings for SHA204 and AES132.
|
||||
* */
|
||||
|
||||
#define SHA204_SUCCESS ((uint8_t) 0x00) //!< Function succeeded.
|
||||
#define SHA204_PARSE_ERROR ((uint8_t) 0xD2) //!< response status byte indicates parsing error
|
||||
#define SHA204_CMD_FAIL ((uint8_t) 0xD3) //!< response status byte indicates command execution error
|
||||
#define SHA204_STATUS_CRC ((uint8_t) 0xD4) //!< response status byte indicates CRC error
|
||||
#define SHA204_STATUS_UNKNOWN ((uint8_t) 0xD5) //!< response status byte is unknown
|
||||
#define SHA204_FUNC_FAIL ((uint8_t) 0xE0) //!< Function could not execute due to incorrect condition / state.
|
||||
#define SHA204_GEN_FAIL ((uint8_t) 0xE1) //!< unspecified error
|
||||
#define SHA204_BAD_PARAM ((uint8_t) 0xE2) //!< bad argument (out of range, null pointer, etc.)
|
||||
#define SHA204_INVALID_ID ((uint8_t) 0xE3) //!< invalid device id, id not set
|
||||
#define SHA204_INVALID_SIZE ((uint8_t) 0xE4) //!< Count value is out of range or greater than buffer size.
|
||||
#define SHA204_BAD_CRC ((uint8_t) 0xE5) //!< incorrect CRC received
|
||||
#define SHA204_RX_FAIL ((uint8_t) 0xE6) //!< Timed out while waiting for response. Number of bytes received is > 0.
|
||||
#define SHA204_RX_NO_RESPONSE ((uint8_t) 0xE7) //!< Not an error while the Command layer is polling for a command response.
|
||||
#define SHA204_RESYNC_WITH_WAKEUP ((uint8_t) 0xE8) //!< re-synchronization succeeded, but only after generating a Wake-up
|
||||
|
||||
#define SHA204_COMM_FAIL ((uint8_t) 0xF0) //!< Communication with device failed. Same as in hardware dependent modules.
|
||||
#define SHA204_TIMEOUT ((uint8_t) 0xF1) //!< Timed out while waiting for response. Number of bytes received is 0.
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,809 @@
|
||||
#include "Arduino.h"
|
||||
#include "sha204_library.h"
|
||||
#include "sha204_includes/sha204_lib_return_codes.h"
|
||||
|
||||
|
||||
// atsha204Class Constructor
|
||||
// Feed this function the Arduino-ized pin number you want to assign to the ATSHA204's SDA pin
|
||||
// This will find the DDRX, PORTX, and PINX registrs it'll need to point to to control that pin
|
||||
// As well as the bit value for each of those registers
|
||||
atsha204Class::atsha204Class(uint8_t pin)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/* Puts a the ATSHA204's unique, 4-byte serial number in the response array
|
||||
returns an SHA204 Return code */
|
||||
uint8_t atsha204Class::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 = sha204m_read(readCommand, readResponse, SHA204_ZONE_CONFIG, ADDRESS_SN03);
|
||||
if (!returnCode) // should return 0 if successful
|
||||
{
|
||||
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 = sha204m_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 = sha204m_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;
|
||||
}
|
||||
|
||||
/* SWI bit bang functions */
|
||||
|
||||
void atsha204Class::swi_set_signal_pin(uint8_t is_high)
|
||||
{
|
||||
*device_port_DDR |= device_pin;
|
||||
|
||||
if (is_high)
|
||||
*device_port_OUT |= device_pin;
|
||||
else
|
||||
*device_port_OUT &= ~device_pin;
|
||||
}
|
||||
|
||||
uint8_t atsha204Class::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.
|
||||
*device_port_OUT |= device_pin;
|
||||
*device_port_DDR |= device_pin;
|
||||
|
||||
// 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])
|
||||
{
|
||||
*device_port_OUT &= ~device_pin;
|
||||
delayMicroseconds(BIT_DELAY); //BIT_DELAY_1;
|
||||
*device_port_OUT |= device_pin;
|
||||
delayMicroseconds(7*BIT_DELAY); //BIT_DELAY_7;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Send a zero bit.
|
||||
*device_port_OUT &= ~device_pin;
|
||||
delayMicroseconds(BIT_DELAY); //BIT_DELAY_1;
|
||||
*device_port_OUT |= device_pin;
|
||||
delayMicroseconds(BIT_DELAY); //BIT_DELAY_1;
|
||||
*device_port_OUT &= ~device_pin;
|
||||
delayMicroseconds(BIT_DELAY); //BIT_DELAY_1;
|
||||
*device_port_OUT |= device_pin;
|
||||
delayMicroseconds(5*BIT_DELAY); //BIT_DELAY_5;
|
||||
}
|
||||
}
|
||||
}
|
||||
interrupts(); //swi_enable_interrupts();
|
||||
return SWI_FUNCTION_RETCODE_SUCCESS;
|
||||
}
|
||||
|
||||
uint8_t atsha204Class::swi_send_byte(uint8_t value)
|
||||
{
|
||||
return swi_send_bytes(1, &value);
|
||||
}
|
||||
|
||||
uint8_t atsha204Class::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.
|
||||
*device_port_DDR &= ~device_pin;
|
||||
|
||||
// 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 ((*device_port_IN & device_pin) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (timeout_count == 0)
|
||||
{
|
||||
status = SWI_FUNCTION_RETCODE_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
// Wait for rising edge.
|
||||
if ((*device_port_IN & device_pin) != 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 ((*device_port_IN & device_pin) == 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 ((*device_port_IN & device_pin) != 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 */
|
||||
|
||||
uint8_t atsha204Class::sha204p_wakeup()
|
||||
{
|
||||
swi_set_signal_pin(0);
|
||||
delayMicroseconds(10*SHA204_WAKEUP_PULSE_WIDTH);
|
||||
swi_set_signal_pin(1);
|
||||
delay(SHA204_WAKEUP_DELAY);
|
||||
|
||||
return SHA204_SUCCESS;
|
||||
}
|
||||
|
||||
uint8_t atsha204Class::sha204p_sleep()
|
||||
{
|
||||
return swi_send_byte(SHA204_SWI_FLAG_SLEEP);
|
||||
}
|
||||
|
||||
uint8_t atsha204Class::sha204p_resync(uint8_t size, uint8_t *response)
|
||||
{
|
||||
delay(SHA204_SYNC_TIMEOUT);
|
||||
return sha204p_receive_response(size, response);
|
||||
}
|
||||
|
||||
uint8_t atsha204Class::sha204p_receive_response(uint8_t size, uint8_t *response)
|
||||
{
|
||||
uint8_t count_byte;
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
uint8_t atsha204Class::sha204p_send_command(uint8_t count, uint8_t * command)
|
||||
{
|
||||
uint8_t ret_code = swi_send_byte(SHA204_SWI_FLAG_CMD);
|
||||
if (ret_code != SWI_FUNCTION_RETCODE_SUCCESS)
|
||||
return SHA204_COMM_FAIL;
|
||||
|
||||
return swi_send_bytes(count, command);
|
||||
}
|
||||
|
||||
/* Communication functions */
|
||||
|
||||
uint8_t atsha204Class::sha204c_wakeup(uint8_t *response)
|
||||
{
|
||||
uint8_t ret_code = sha204p_wakeup();
|
||||
if (ret_code != SHA204_SUCCESS)
|
||||
return ret_code;
|
||||
|
||||
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 atsha204Class::sha204c_resync(uint8_t size, uint8_t *response)
|
||||
{
|
||||
// Try to re-synchronize without sending a Wake token
|
||||
// (step 1 of the re-synchronization process).
|
||||
uint8_t ret_code = sha204p_resync(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).
|
||||
(void) sha204p_sleep();
|
||||
ret_code = sha204c_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);
|
||||
}
|
||||
|
||||
uint8_t atsha204Class::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 = sha204p_send_command(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;
|
||||
}
|
||||
|
||||
|
||||
/* Marshaling functions */
|
||||
|
||||
uint8_t atsha204Class::sha204m_random(uint8_t * tx_buffer, uint8_t * rx_buffer, uint8_t mode)
|
||||
{
|
||||
if (!tx_buffer || !rx_buffer || (mode > RANDOM_NO_SEED_UPDATE))
|
||||
return SHA204_BAD_PARAM;
|
||||
|
||||
tx_buffer[SHA204_COUNT_IDX] = RANDOM_COUNT;
|
||||
tx_buffer[SHA204_OPCODE_IDX] = SHA204_RANDOM;
|
||||
tx_buffer[RANDOM_MODE_IDX] = mode & RANDOM_SEED_UPDATE;
|
||||
|
||||
tx_buffer[RANDOM_PARAM2_IDX] =
|
||||
tx_buffer[RANDOM_PARAM2_IDX + 1] = 0;
|
||||
|
||||
return sha204c_send_and_receive(&tx_buffer[0], RANDOM_RSP_SIZE, &rx_buffer[0], RANDOM_DELAY, RANDOM_EXEC_MAX - RANDOM_DELAY);
|
||||
}
|
||||
|
||||
uint8_t atsha204Class::sha204m_dev_rev(uint8_t *tx_buffer, uint8_t *rx_buffer)
|
||||
{
|
||||
if (!tx_buffer || !rx_buffer)
|
||||
return SHA204_BAD_PARAM;
|
||||
|
||||
tx_buffer[SHA204_COUNT_IDX] = DEVREV_COUNT;
|
||||
tx_buffer[SHA204_OPCODE_IDX] = SHA204_DEVREV;
|
||||
|
||||
// Parameters are 0.
|
||||
tx_buffer[DEVREV_PARAM1_IDX] =
|
||||
tx_buffer[DEVREV_PARAM2_IDX] =
|
||||
tx_buffer[DEVREV_PARAM2_IDX + 1] = 0;
|
||||
|
||||
return sha204c_send_and_receive(&tx_buffer[0], DEVREV_RSP_SIZE, &rx_buffer[0],
|
||||
DEVREV_DELAY, DEVREV_EXEC_MAX - DEVREV_DELAY);
|
||||
}
|
||||
|
||||
uint8_t atsha204Class::sha204m_read(uint8_t *tx_buffer, uint8_t *rx_buffer, uint8_t zone, uint16_t address)
|
||||
{
|
||||
uint8_t rx_size;
|
||||
|
||||
if (!tx_buffer || !rx_buffer || ((zone & ~READ_ZONE_MASK) != 0)
|
||||
|| ((zone & READ_ZONE_MODE_32_BYTES) && (zone == SHA204_ZONE_OTP)))
|
||||
return SHA204_BAD_PARAM;
|
||||
|
||||
address >>= 2;
|
||||
if ((zone & SHA204_ZONE_MASK) == SHA204_ZONE_CONFIG)
|
||||
{
|
||||
if (address > SHA204_ADDRESS_MASK_CONFIG)
|
||||
return SHA204_BAD_PARAM;
|
||||
}
|
||||
else if ((zone & SHA204_ZONE_MASK) == SHA204_ZONE_OTP)
|
||||
{
|
||||
if (address > SHA204_ADDRESS_MASK_OTP)
|
||||
return SHA204_BAD_PARAM;
|
||||
}
|
||||
else if ((zone & SHA204_ZONE_MASK) == SHA204_ZONE_DATA)
|
||||
{
|
||||
if (address > SHA204_ADDRESS_MASK)
|
||||
return SHA204_BAD_PARAM;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
uint8_t atsha204Class::sha204m_execute(uint8_t op_code, uint8_t param1, uint16_t param2,
|
||||
uint8_t datalen1, uint8_t *data1, uint8_t datalen2, uint8_t *data2, uint8_t datalen3, uint8_t *data3,
|
||||
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;
|
||||
|
||||
uint8_t ret_code = sha204m_check_parameters(op_code, param1, param2,
|
||||
datalen1, data1, datalen2, data2, datalen3, data3,
|
||||
tx_size, tx_buffer, rx_size, rx_buffer);
|
||||
if (ret_code != SHA204_SUCCESS)
|
||||
return ret_code;
|
||||
|
||||
// Supply delays and response size.
|
||||
switch (op_code)
|
||||
{
|
||||
case SHA204_CHECKMAC:
|
||||
poll_delay = CHECKMAC_DELAY;
|
||||
poll_timeout = CHECKMAC_EXEC_MAX - CHECKMAC_DELAY;
|
||||
response_size = CHECKMAC_RSP_SIZE;
|
||||
break;
|
||||
|
||||
case SHA204_DERIVE_KEY:
|
||||
poll_delay = DERIVE_KEY_DELAY;
|
||||
poll_timeout = DERIVE_KEY_EXEC_MAX - DERIVE_KEY_DELAY;
|
||||
response_size = DERIVE_KEY_RSP_SIZE;
|
||||
break;
|
||||
|
||||
case SHA204_DEVREV:
|
||||
poll_delay = DEVREV_DELAY;
|
||||
poll_timeout = DEVREV_EXEC_MAX - DEVREV_DELAY;
|
||||
response_size = DEVREV_RSP_SIZE;
|
||||
break;
|
||||
|
||||
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_LOCK:
|
||||
poll_delay = LOCK_DELAY;
|
||||
poll_timeout = LOCK_EXEC_MAX - LOCK_DELAY;
|
||||
response_size = LOCK_RSP_SIZE;
|
||||
break;
|
||||
|
||||
case SHA204_MAC:
|
||||
poll_delay = MAC_DELAY;
|
||||
poll_timeout = MAC_EXEC_MAX - MAC_DELAY;
|
||||
response_size = MAC_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_PAUSE:
|
||||
poll_delay = PAUSE_DELAY;
|
||||
poll_timeout = PAUSE_EXEC_MAX - PAUSE_DELAY;
|
||||
response_size = PAUSE_RSP_SIZE;
|
||||
break;
|
||||
|
||||
case SHA204_RANDOM:
|
||||
poll_delay = RANDOM_DELAY;
|
||||
poll_timeout = RANDOM_EXEC_MAX - RANDOM_DELAY;
|
||||
response_size = RANDOM_RSP_SIZE;
|
||||
break;
|
||||
|
||||
case SHA204_READ:
|
||||
poll_delay = READ_DELAY;
|
||||
poll_timeout = READ_EXEC_MAX - READ_DELAY;
|
||||
response_size = (param1 & SHA204_ZONE_COUNT_FLAG)
|
||||
? READ_32_RSP_SIZE : READ_4_RSP_SIZE;
|
||||
break;
|
||||
|
||||
case SHA204_UPDATE_EXTRA:
|
||||
poll_delay = UPDATE_DELAY;
|
||||
poll_timeout = UPDATE_EXEC_MAX - UPDATE_DELAY;
|
||||
response_size = UPDATE_RSP_SIZE;
|
||||
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 + datalen2 + datalen3 + 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;
|
||||
}
|
||||
if (datalen2 > 0) {
|
||||
memcpy(p_buffer, data2, datalen2);
|
||||
p_buffer += datalen2;
|
||||
}
|
||||
if (datalen3 > 0) {
|
||||
memcpy(p_buffer, data3, datalen3);
|
||||
p_buffer += datalen3;
|
||||
}
|
||||
|
||||
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 atsha204Class::sha204m_check_parameters(uint8_t op_code, uint8_t param1, uint16_t param2,
|
||||
uint8_t datalen1, uint8_t *data1, uint8_t datalen2, uint8_t *data2, uint8_t datalen3, uint8_t *data3,
|
||||
uint8_t tx_size, uint8_t *tx_buffer, uint8_t rx_size, uint8_t *rx_buffer)
|
||||
{
|
||||
#ifdef SHA204_CHECK_PARAMETERS
|
||||
|
||||
uint8_t len = datalen1 + datalen2 + datalen3 + SHA204_CMD_SIZE_MIN;
|
||||
if (!tx_buffer || tx_size < len || rx_size < SHA204_RSP_SIZE_MIN || !rx_buffer)
|
||||
return SHA204_BAD_PARAM;
|
||||
|
||||
if ((datalen1 > 0 && !data1) || (datalen2 > 0 && !data2) || (datalen3 > 0 && !data3))
|
||||
return SHA204_BAD_PARAM;
|
||||
|
||||
// Check parameters depending on op-code.
|
||||
switch (op_code)
|
||||
{
|
||||
case SHA204_CHECKMAC:
|
||||
if (
|
||||
// no null pointers allowed
|
||||
!data1 || !data2
|
||||
// No reserved bits should be set.
|
||||
|| (param1 | CHECKMAC_MODE_MASK) != CHECKMAC_MODE_MASK
|
||||
// key_id > 15 not allowed
|
||||
|| param2 > SHA204_KEY_ID_MAX
|
||||
)
|
||||
return SHA204_BAD_PARAM;
|
||||
break;
|
||||
|
||||
case SHA204_DERIVE_KEY:
|
||||
if (param2 > SHA204_KEY_ID_MAX)
|
||||
return SHA204_BAD_PARAM;
|
||||
break;
|
||||
|
||||
case SHA204_DEVREV:
|
||||
break;
|
||||
|
||||
case SHA204_GENDIG:
|
||||
if ((param1 != GENDIG_ZONE_OTP) && (param1 != GENDIG_ZONE_DATA))
|
||||
return SHA204_BAD_PARAM;
|
||||
break;
|
||||
|
||||
case SHA204_HMAC:
|
||||
if ((param1 & ~HMAC_MODE_MASK) != 0)
|
||||
return SHA204_BAD_PARAM;
|
||||
break;
|
||||
|
||||
case SHA204_LOCK:
|
||||
if (((param1 & ~LOCK_ZONE_MASK) != 0)
|
||||
|| ((param1 & LOCK_ZONE_NO_CRC) && (param2 != 0)))
|
||||
return SHA204_BAD_PARAM;
|
||||
break;
|
||||
|
||||
case SHA204_MAC:
|
||||
if (((param1 & ~MAC_MODE_MASK) != 0)
|
||||
|| (((param1 & MAC_MODE_BLOCK2_TEMPKEY) == 0) && !data1))
|
||||
return SHA204_BAD_PARAM;
|
||||
break;
|
||||
|
||||
case SHA204_NONCE:
|
||||
if ( !data1
|
||||
|| (param1 > NONCE_MODE_PASSTHROUGH)
|
||||
|| (param1 == NONCE_MODE_INVALID)
|
||||
)
|
||||
return SHA204_BAD_PARAM;
|
||||
break;
|
||||
|
||||
case SHA204_PAUSE:
|
||||
break;
|
||||
|
||||
case SHA204_RANDOM:
|
||||
if (param1 > RANDOM_NO_SEED_UPDATE)
|
||||
return SHA204_BAD_PARAM;
|
||||
break;
|
||||
|
||||
case SHA204_READ:
|
||||
if (((param1 & ~READ_ZONE_MASK) != 0)
|
||||
|| ((param1 & READ_ZONE_MODE_32_BYTES) && (param1 == SHA204_ZONE_OTP)))
|
||||
return SHA204_BAD_PARAM;
|
||||
break;
|
||||
|
||||
case SHA204_TEMPSENSE:
|
||||
break;
|
||||
|
||||
case SHA204_UPDATE_EXTRA:
|
||||
if (param1 > UPDATE_CONFIG_BYTE_86)
|
||||
return SHA204_BAD_PARAM;
|
||||
break;
|
||||
|
||||
case SHA204_WRITE:
|
||||
if (!data1 || ((param1 & ~WRITE_ZONE_MASK) != 0))
|
||||
return SHA204_BAD_PARAM;
|
||||
break;
|
||||
|
||||
default:
|
||||
// unknown op-code
|
||||
return SHA204_BAD_PARAM;
|
||||
}
|
||||
|
||||
return SHA204_SUCCESS;
|
||||
|
||||
#else
|
||||
return SHA204_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* CRC Calculator and Checker */
|
||||
|
||||
void atsha204Class::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);
|
||||
}
|
||||
|
||||
uint8_t atsha204Class::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;
|
||||
}
|
||||
@@ -0,0 +1,320 @@
|
||||
#include "Arduino.h"
|
||||
|
||||
#ifndef sha204_library_H
|
||||
#define sha204_library_H
|
||||
|
||||
/* bitbang_config.h */
|
||||
|
||||
#define PORT_ACCESS_TIME (630) //! time it takes to toggle the pin at CPU clock of 16 MHz (ns)
|
||||
#define START_PULSE_WIDTH (4340) //! width of start pulse (ns)
|
||||
#define BIT_DELAY (4) //! delay macro for width of one pulse (start pulse or zero pulse, in ns)
|
||||
#define RX_TX_DELAY (15) //! turn around time when switching from receive to transmit
|
||||
#define START_PULSE_TIME_OUT (255) //! This value is decremented while waiting for the falling edge of a start pulse.
|
||||
#define ZERO_PULSE_TIME_OUT (26) //! This value is decremented while waiting for the falling edge of a zero pulse.
|
||||
|
||||
/* swi_phys.h */
|
||||
|
||||
#define SWI_FUNCTION_RETCODE_SUCCESS ((uint8_t) 0x00) //!< Communication with device succeeded.
|
||||
#define SWI_FUNCTION_RETCODE_TIMEOUT ((uint8_t) 0xF1) //!< Communication timed out.
|
||||
#define SWI_FUNCTION_RETCODE_RX_FAIL ((uint8_t) 0xF9) //!< Communication failed after at least one byte was received.
|
||||
|
||||
/* sha204_physical.h */
|
||||
|
||||
#define SHA204_RSP_SIZE_MIN ((uint8_t) 4) //!< minimum number of bytes in response
|
||||
#define SHA204_RSP_SIZE_MAX ((uint8_t) 35) //!< maximum size of response packet
|
||||
#define SHA204_BUFFER_POS_COUNT (0) //!< buffer index of count byte in command or response
|
||||
#define SHA204_BUFFER_POS_DATA (1) //!< buffer index of data in response
|
||||
#define SHA204_WAKEUP_PULSE_WIDTH (uint8_t) (6.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5) //! width of Wakeup pulse in 10 us units
|
||||
#define SHA204_WAKEUP_DELAY (uint8_t) (3.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5) //! delay between Wakeup pulse and communication in ms
|
||||
|
||||
/* sha204_swi.c */
|
||||
#define SHA204_SWI_FLAG_CMD ((uint8_t) 0x77) //!< flag preceding a command
|
||||
#define SHA204_SWI_FLAG_TX ((uint8_t) 0x88) //!< flag requesting a response
|
||||
#define SHA204_SWI_FLAG_IDLE ((uint8_t) 0xBB) //!< flag requesting to go into Idle mode
|
||||
#define SHA204_SWI_FLAG_SLEEP ((uint8_t) 0xCC) //!< flag requesting to go into Sleep mode
|
||||
|
||||
/* sha204_comm_marshaling.h */
|
||||
// command op-code definitions
|
||||
#define SHA204_CHECKMAC ((uint8_t) 0x28) //!< CheckMac command op-code
|
||||
#define SHA204_DERIVE_KEY ((uint8_t) 0x1C) //!< DeriveKey command op-code
|
||||
#define SHA204_DEVREV ((uint8_t) 0x30) //!< DevRev command op-code
|
||||
#define SHA204_GENDIG ((uint8_t) 0x15) //!< GenDig command op-code
|
||||
#define SHA204_HMAC ((uint8_t) 0x11) //!< HMAC command op-code
|
||||
#define SHA204_LOCK ((uint8_t) 0x17) //!< Lock command op-code
|
||||
#define SHA204_MAC ((uint8_t) 0x08) //!< MAC command op-code
|
||||
#define SHA204_NONCE ((uint8_t) 0x16) //!< Nonce command op-code
|
||||
#define SHA204_PAUSE ((uint8_t) 0x01) //!< Pause command op-code
|
||||
#define SHA204_RANDOM ((uint8_t) 0x1B) //!< Random command op-code
|
||||
#define SHA204_READ ((uint8_t) 0x02) //!< Read command op-code
|
||||
#define SHA204_UPDATE_EXTRA ((uint8_t) 0x20) //!< UpdateExtra command op-code
|
||||
#define SHA204_WRITE ((uint8_t) 0x12) //!< Write command op-code
|
||||
|
||||
// packet size definitions
|
||||
#define SHA204_RSP_SIZE_VAL ((uint8_t) 7) //!< size of response packet containing four bytes of data
|
||||
|
||||
// parameter range definitions
|
||||
#define SHA204_KEY_ID_MAX ((uint8_t) 15) //!< maximum value for key id
|
||||
#define SHA204_OTP_BLOCK_MAX ((uint8_t) 1) //!< maximum value for OTP block
|
||||
|
||||
// definitions for command packet indexes common to all commands
|
||||
#define SHA204_COUNT_IDX ( 0) //!< command packet index for count
|
||||
#define SHA204_OPCODE_IDX ( 1) //!< command packet index for op-code
|
||||
#define SHA204_PARAM1_IDX ( 2) //!< command packet index for first parameter
|
||||
#define SHA204_PARAM2_IDX ( 3) //!< command packet index for second parameter
|
||||
#define SHA204_DATA_IDX ( 5) //!< command packet index for second parameter
|
||||
|
||||
// zone definitions
|
||||
#define SHA204_ZONE_CONFIG ((uint8_t) 0x00) //!< Configuration zone
|
||||
#define SHA204_ZONE_OTP ((uint8_t) 0x01) //!< OTP (One Time Programming) zone
|
||||
#define SHA204_ZONE_DATA ((uint8_t) 0x02) //!< Data zone
|
||||
#define SHA204_ZONE_MASK ((uint8_t) 0x03) //!< Zone mask
|
||||
#define SHA204_ZONE_COUNT_FLAG ((uint8_t) 0x80) //!< Zone bit 7 set: Access 32 bytes, otherwise 4 bytes.
|
||||
#define SHA204_ZONE_ACCESS_4 ((uint8_t) 4) //!< Read or write 4 bytes.
|
||||
#define SHA204_ZONE_ACCESS_32 ((uint8_t) 32) //!< Read or write 32 bytes.
|
||||
#define SHA204_ADDRESS_MASK_CONFIG ( 0x001F) //!< Address bits 5 to 7 are 0 for Configuration zone.
|
||||
#define SHA204_ADDRESS_MASK_OTP ( 0x000F) //!< Address bits 4 to 7 are 0 for OTP zone.
|
||||
#define SHA204_ADDRESS_MASK ( 0x007F) //!< Address bit 7 to 15 are always 0.
|
||||
|
||||
// CheckMAC command definitions
|
||||
#define CHECKMAC_MODE_IDX SHA204_PARAM1_IDX //!< CheckMAC command index for mode
|
||||
#define CHECKMAC_KEYID_IDX SHA204_PARAM2_IDX //!< CheckMAC command index for key identifier
|
||||
#define CHECKMAC_CLIENT_CHALLENGE_IDX SHA204_DATA_IDX //!< CheckMAC command index for client challenge
|
||||
#define CHECKMAC_CLIENT_RESPONSE_IDX (37) //!< CheckMAC command index for client response
|
||||
#define CHECKMAC_DATA_IDX (69) //!< CheckMAC command index for other data
|
||||
#define CHECKMAC_COUNT (84) //!< CheckMAC command packet size
|
||||
#define CHECKMAC_MODE_MASK ((uint8_t) 0x27) //!< CheckMAC mode bits 3, 4, 6, and 7 are 0.
|
||||
#define CHECKMAC_CLIENT_CHALLENGE_SIZE (32) //!< CheckMAC size of client challenge
|
||||
#define CHECKMAC_CLIENT_RESPONSE_SIZE (32) //!< CheckMAC size of client response
|
||||
#define CHECKMAC_OTHER_DATA_SIZE (13) //!< CheckMAC size of "other data"
|
||||
|
||||
// DeriveKey command definitions
|
||||
#define DERIVE_KEY_RANDOM_IDX SHA204_PARAM1_IDX //!< DeriveKey command index for random bit
|
||||
#define DERIVE_KEY_TARGETKEY_IDX SHA204_PARAM2_IDX //!< DeriveKey command index for target slot
|
||||
#define DERIVE_KEY_MAC_IDX SHA204_DATA_IDX //!< DeriveKey command index for optional MAC
|
||||
#define DERIVE_KEY_COUNT_SMALL SHA204_CMD_SIZE_MIN //!< DeriveKey command packet size without MAC
|
||||
#define DERIVE_KEY_COUNT_LARGE (39) //!< DeriveKey command packet size with MAC
|
||||
#define DERIVE_KEY_RANDOM_FLAG ((uint8_t) 4) //!< DeriveKey 1. parameter
|
||||
#define DERIVE_KEY_MAC_SIZE (32) //!< DeriveKey MAC size
|
||||
|
||||
// DevRev command definitions
|
||||
#define DEVREV_PARAM1_IDX SHA204_PARAM1_IDX //!< DevRev command index for 1. parameter (ignored)
|
||||
#define DEVREV_PARAM2_IDX SHA204_PARAM2_IDX //!< DevRev command index for 2. parameter (ignored)
|
||||
#define DEVREV_COUNT SHA204_CMD_SIZE_MIN //!< DevRev command packet size
|
||||
|
||||
// GenDig command definitions
|
||||
#define GENDIG_ZONE_IDX SHA204_PARAM1_IDX //!< GenDig command index for zone
|
||||
#define GENDIG_KEYID_IDX SHA204_PARAM2_IDX //!< GenDig command index for key id
|
||||
#define GENDIG_DATA_IDX SHA204_DATA_IDX //!< GenDig command index for optional data
|
||||
#define GENDIG_COUNT SHA204_CMD_SIZE_MIN //!< GenDig command packet size without "other data"
|
||||
#define GENDIG_COUNT_DATA (11) //!< GenDig command packet size with "other data"
|
||||
#define GENDIG_OTHER_DATA_SIZE (4) //!< GenDig size of "other data"
|
||||
#define GENDIG_ZONE_CONFIG ((uint8_t) 0) //!< GenDig zone id config
|
||||
#define GENDIG_ZONE_OTP ((uint8_t) 1) //!< GenDig zone id OTP
|
||||
#define GENDIG_ZONE_DATA ((uint8_t) 2) //!< GenDig zone id data
|
||||
|
||||
// HMAC command definitions
|
||||
#define HMAC_MODE_IDX SHA204_PARAM1_IDX //!< HMAC command index for mode
|
||||
#define HMAC_KEYID_IDX SHA204_PARAM2_IDX //!< HMAC command index for key id
|
||||
#define HMAC_COUNT SHA204_CMD_SIZE_MIN //!< HMAC command packet size
|
||||
#define HMAC_MODE_MASK ((uint8_t) 0x74) //!< HMAC mode bits 0, 1, 3, and 7 are 0.
|
||||
|
||||
// Lock command definitions
|
||||
#define LOCK_ZONE_IDX SHA204_PARAM1_IDX //!< Lock command index for zone
|
||||
#define LOCK_SUMMARY_IDX SHA204_PARAM2_IDX //!< Lock command index for summary
|
||||
#define LOCK_COUNT SHA204_CMD_SIZE_MIN //!< Lock command packet size
|
||||
#define LOCK_ZONE_NO_CONFIG ((uint8_t) 0x01) //!< Lock zone is OTP or Data
|
||||
#define LOCK_ZONE_NO_CRC ((uint8_t) 0x80) //!< Lock command: Ignore summary.
|
||||
#define LOCK_ZONE_MASK (0x81) //!< Lock parameter 1 bits 2 to 6 are 0.
|
||||
|
||||
// Mac command definitions
|
||||
#define MAC_MODE_IDX SHA204_PARAM1_IDX //!< MAC command index for mode
|
||||
#define MAC_KEYID_IDX SHA204_PARAM2_IDX //!< MAC command index for key id
|
||||
#define MAC_CHALLENGE_IDX SHA204_DATA_IDX //!< MAC command index for optional challenge
|
||||
#define MAC_COUNT_SHORT SHA204_CMD_SIZE_MIN //!< MAC command packet size without challenge
|
||||
#define MAC_COUNT_LONG (39) //!< MAC command packet size with challenge
|
||||
#define MAC_MODE_BLOCK2_TEMPKEY ((uint8_t) 0x01) //!< MAC mode bit 0: second SHA block from TempKey
|
||||
#define MAC_MODE_BLOCK1_TEMPKEY ((uint8_t) 0x02) //!< MAC mode bit 1: first SHA block from TempKey
|
||||
#define MAC_MODE_SOURCE_FLAG_MATCH ((uint8_t) 0x04) //!< MAC mode bit 2: match TempKey.SourceFlag
|
||||
#define MAC_MODE_PASSTHROUGH ((uint8_t) 0x07) //!< MAC mode bit 0-2: pass-through mode
|
||||
#define MAC_MODE_INCLUDE_OTP_88 ((uint8_t) 0x10) //!< MAC mode bit 4: include first 88 OTP bits
|
||||
#define MAC_MODE_INCLUDE_OTP_64 ((uint8_t) 0x20) //!< MAC mode bit 5: include first 64 OTP bits
|
||||
#define MAC_MODE_INCLUDE_SN ((uint8_t) 0x40) //!< MAC mode bit 6: include serial number
|
||||
#define MAC_CHALLENGE_SIZE (32) //!< MAC size of challenge
|
||||
#define MAC_MODE_MASK ((uint8_t) 0x77) //!< MAC mode bits 3 and 7 are 0.
|
||||
|
||||
// Nonce command definitions
|
||||
#define NONCE_MODE_IDX SHA204_PARAM1_IDX //!< Nonce command index for mode
|
||||
#define NONCE_PARAM2_IDX SHA204_PARAM2_IDX //!< Nonce command index for 2. parameter
|
||||
#define NONCE_INPUT_IDX SHA204_DATA_IDX //!< Nonce command index for input data
|
||||
#define NONCE_COUNT_SHORT (27) //!< Nonce command packet size for 20 bytes of data
|
||||
#define NONCE_COUNT_LONG (39) //!< Nonce command packet size for 32 bytes of data
|
||||
#define NONCE_MODE_MASK ((uint8_t) 3) //!< Nonce mode bits 2 to 7 are 0.
|
||||
#define NONCE_MODE_SEED_UPDATE ((uint8_t) 0x00) //!< Nonce mode: update seed
|
||||
#define NONCE_MODE_NO_SEED_UPDATE ((uint8_t) 0x01) //!< Nonce mode: do not update seed
|
||||
#define NONCE_MODE_INVALID ((uint8_t) 0x02) //!< Nonce mode 2 is invalid.
|
||||
#define NONCE_MODE_PASSTHROUGH ((uint8_t) 0x03) //!< Nonce mode: pass-through
|
||||
#define NONCE_NUMIN_SIZE (20) //!< Nonce data length
|
||||
#define NONCE_NUMIN_SIZE_PASSTHROUGH (32) //!< Nonce data length in pass-through mode (mode = 3)
|
||||
|
||||
// Pause command definitions
|
||||
#define PAUSE_SELECT_IDX SHA204_PARAM1_IDX //!< Pause command index for Selector
|
||||
#define PAUSE_PARAM2_IDX SHA204_PARAM2_IDX //!< Pause command index for 2. parameter
|
||||
#define PAUSE_COUNT SHA204_CMD_SIZE_MIN //!< Pause command packet size
|
||||
|
||||
// Random command definitions
|
||||
#define RANDOM_MODE_IDX SHA204_PARAM1_IDX //!< Random command index for mode
|
||||
#define RANDOM_PARAM2_IDX SHA204_PARAM2_IDX //!< Random command index for 2. parameter
|
||||
#define RANDOM_COUNT SHA204_CMD_SIZE_MIN //!< Random command packet size
|
||||
#define RANDOM_SEED_UPDATE ((uint8_t) 0x00) //!< Random mode for automatic seed update
|
||||
#define RANDOM_NO_SEED_UPDATE ((uint8_t) 0x01) //!< Random mode for no seed update
|
||||
|
||||
// Read command definitions
|
||||
#define READ_ZONE_IDX SHA204_PARAM1_IDX //!< Read command index for zone
|
||||
#define READ_ADDR_IDX SHA204_PARAM2_IDX //!< Read command index for address
|
||||
#define READ_COUNT SHA204_CMD_SIZE_MIN //!< Read command packet size
|
||||
#define READ_ZONE_MASK ((uint8_t) 0x83) //!< Read zone bits 2 to 6 are 0.
|
||||
#define READ_ZONE_MODE_32_BYTES ((uint8_t) 0x80) //!< Read mode: 32 bytes
|
||||
|
||||
// UpdateExtra command definitions
|
||||
#define UPDATE_MODE_IDX SHA204_PARAM1_IDX //!< UpdateExtra command index for mode
|
||||
#define UPDATE_VALUE_IDX SHA204_PARAM2_IDX //!< UpdateExtra command index for new value
|
||||
#define UPDATE_COUNT SHA204_CMD_SIZE_MIN //!< UpdateExtra command packet size
|
||||
#define UPDATE_CONFIG_BYTE_86 ((uint8_t) 0x01) //!< UpdateExtra mode: update Config byte 86
|
||||
|
||||
// Write command definitions
|
||||
#define WRITE_ZONE_IDX SHA204_PARAM1_IDX //!< Write command index for zone
|
||||
#define WRITE_ADDR_IDX SHA204_PARAM2_IDX //!< Write command index for address
|
||||
#define WRITE_VALUE_IDX SHA204_DATA_IDX //!< Write command index for data
|
||||
#define WRITE_MAC_VS_IDX ( 9) //!< Write command index for MAC following short data
|
||||
#define WRITE_MAC_VL_IDX (37) //!< Write command index for MAC following long data
|
||||
#define WRITE_COUNT_SHORT (11) //!< Write command packet size with short data and no MAC
|
||||
#define WRITE_COUNT_LONG (39) //!< Write command packet size with long data and no MAC
|
||||
#define WRITE_COUNT_SHORT_MAC (43) //!< Write command packet size with short data and MAC
|
||||
#define WRITE_COUNT_LONG_MAC (71) //!< Write command packet size with long data and MAC
|
||||
#define WRITE_MAC_SIZE (32) //!< Write MAC size
|
||||
#define WRITE_ZONE_MASK ((uint8_t) 0xC3) //!< Write zone bits 2 to 5 are 0.
|
||||
#define WRITE_ZONE_WITH_MAC ((uint8_t) 0x40) //!< Write zone bit 6: write encrypted with MAC
|
||||
|
||||
// Response size definitions
|
||||
#define CHECKMAC_RSP_SIZE SHA204_RSP_SIZE_MIN //!< response size of DeriveKey command
|
||||
#define DERIVE_KEY_RSP_SIZE SHA204_RSP_SIZE_MIN //!< response size of DeriveKey command
|
||||
#define DEVREV_RSP_SIZE SHA204_RSP_SIZE_VAL //!< response size of DevRev command returns 4 bytes
|
||||
#define GENDIG_RSP_SIZE SHA204_RSP_SIZE_MIN //!< response size of GenDig command
|
||||
#define HMAC_RSP_SIZE SHA204_RSP_SIZE_MAX //!< response size of HMAC command
|
||||
#define LOCK_RSP_SIZE SHA204_RSP_SIZE_MIN //!< response size of Lock command
|
||||
#define MAC_RSP_SIZE SHA204_RSP_SIZE_MAX //!< response size of MAC command
|
||||
#define NONCE_RSP_SIZE_SHORT SHA204_RSP_SIZE_MIN //!< response size of Nonce command with mode[0:1] = 3
|
||||
#define NONCE_RSP_SIZE_LONG SHA204_RSP_SIZE_MAX //!< response size of Nonce command
|
||||
#define PAUSE_RSP_SIZE SHA204_RSP_SIZE_MIN //!< response size of Pause command
|
||||
#define RANDOM_RSP_SIZE SHA204_RSP_SIZE_MAX //!< response size of Random command
|
||||
#define READ_4_RSP_SIZE SHA204_RSP_SIZE_VAL //!< response size of Read command when reading 4 bytes
|
||||
#define READ_32_RSP_SIZE SHA204_RSP_SIZE_MAX //!< response size of Read command when reading 32 bytes
|
||||
#define TEMP_SENSE_RSP_SIZE SHA204_RSP_SIZE_VAL //!< response size of TempSense command returns 4 bytes
|
||||
#define UPDATE_RSP_SIZE SHA204_RSP_SIZE_MIN //!< response size of UpdateExtra command
|
||||
#define WRITE_RSP_SIZE SHA204_RSP_SIZE_MIN //!< response size of Write command
|
||||
|
||||
// command timing definitions for minimum execution times (ms)
|
||||
#define CHECKMAC_DELAY ((uint8_t) (12.0 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
|
||||
#define DERIVE_KEY_DELAY ((uint8_t) (14.0 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
|
||||
#define DEVREV_DELAY ((uint8_t) ( 0.4 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
|
||||
#define GENDIG_DELAY ((uint8_t) (11.0 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
|
||||
#define HMAC_DELAY ((uint8_t) (27.0 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
|
||||
#define LOCK_DELAY ((uint8_t) ( 5.0 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
|
||||
#define MAC_DELAY ((uint8_t) (12.0 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
|
||||
#define NONCE_DELAY ((uint8_t) (22.0 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
|
||||
#define PAUSE_DELAY ((uint8_t) ( 0.4 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
|
||||
#define RANDOM_DELAY ((uint8_t) (11.0 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
|
||||
#define READ_DELAY ((uint8_t) ( 0.4 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
|
||||
#define TEMP_SENSE_DELAY ((uint8_t) ( 4.0 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
|
||||
#define UPDATE_DELAY ((uint8_t) ( 4.0 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
|
||||
#define WRITE_DELAY ((uint8_t) ( 4.0 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
|
||||
|
||||
// command timing definitions for maximum execution times (ms)
|
||||
#define CHECKMAC_EXEC_MAX ((uint8_t) (38.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
|
||||
#define DERIVE_KEY_EXEC_MAX ((uint8_t) (62.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
|
||||
#define DEVREV_EXEC_MAX ((uint8_t) ( 2.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
|
||||
#define GENDIG_EXEC_MAX ((uint8_t) (43.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
|
||||
#define HMAC_EXEC_MAX ((uint8_t) (69.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
|
||||
#define LOCK_EXEC_MAX ((uint8_t) (24.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
|
||||
#define MAC_EXEC_MAX ((uint8_t) (35.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
|
||||
#define NONCE_EXEC_MAX ((uint8_t) (60.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
|
||||
#define PAUSE_EXEC_MAX ((uint8_t) ( 2.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
|
||||
#define RANDOM_EXEC_MAX ((uint8_t) (50.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
|
||||
#define READ_EXEC_MAX ((uint8_t) ( 4.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
|
||||
#define TEMP_SENSE_EXEC_MAX ((uint8_t) (11.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
|
||||
#define UPDATE_EXEC_MAX ((uint8_t) ( 6.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
|
||||
#define WRITE_EXEC_MAX ((uint8_t) (42.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
|
||||
|
||||
/* from sha204_config.h */
|
||||
|
||||
#define CPU_CLOCK_DEVIATION_POSITIVE (1.01)
|
||||
#define CPU_CLOCK_DEVIATION_NEGATIVE (0.99)
|
||||
#define SHA204_RETRY_COUNT (1)
|
||||
#define SWI_RECEIVE_TIME_OUT ((uint16_t) 163) //! #START_PULSE_TIME_OUT in us instead of loop counts
|
||||
#define SWI_US_PER_BYTE ((uint16_t) 313) //! It takes 312.5 us to send a byte (9 single-wire bits / 230400 Baud * 8 flag bits).
|
||||
#define SHA204_SYNC_TIMEOUT ((uint8_t) 85)//! delay before sending a transmit flag in the synchronization routine
|
||||
#define SHA204_RESPONSE_TIMEOUT ((uint16_t) SWI_RECEIVE_TIME_OUT + SWI_US_PER_BYTE) //! SWI response timeout is the sum of receive timeout and the time it takes to send the TX flag.
|
||||
|
||||
/* from sha204_comm.h */
|
||||
|
||||
#define SHA204_COMMAND_EXEC_MAX ((uint8_t) (69.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5)) //! maximum command delay
|
||||
#define SHA204_CMD_SIZE_MIN ((uint8_t) 7) //! minimum number of bytes in command (from count byte to second CRC byte)
|
||||
#define SHA204_CMD_SIZE_MAX ((uint8_t) 84) //! maximum size of command packet (CheckMac)
|
||||
#define SHA204_CRC_SIZE ((uint8_t) 2) //! number of CRC bytes
|
||||
#define SHA204_BUFFER_POS_STATUS (1) //! buffer index of status byte in status response
|
||||
#define SHA204_BUFFER_POS_DATA (1) //! buffer index of first data byte in data response
|
||||
#define SHA204_STATUS_BYTE_WAKEUP ((uint8_t) 0x11) //! command parse error
|
||||
#define SHA204_STATUS_BYTE_PARSE ((uint8_t) 0x03) //! command parse error
|
||||
#define SHA204_STATUS_BYTE_EXEC ((uint8_t) 0x0F) //! command execution error
|
||||
#define SHA204_STATUS_BYTE_COMM ((uint8_t) 0xFF) //! communication error
|
||||
|
||||
/* EEPROM Addresses */
|
||||
/* Configuration Zone */
|
||||
#define ADDRESS_SN03 0 // SN[0:3] are bytes 0->3 of configuration zone
|
||||
#define ADDRESS_RevNum 4 // bytes 4->7 of config zone are RevNum
|
||||
#define ADDRESS_SN47 8 // SN[4:7] are bytes 8->11 of config zone
|
||||
#define ADDRESS_SN8 12 // SN[8] is byte 12 of config zone, should be 0xEE
|
||||
#define ADDRESS_I2CEN 14 // I2C Enable, bit 0 represents I2C enable status
|
||||
#define ADDRESS_I2CADD 16 // Defines I2C address of SHA204
|
||||
#define ADDRESS_OTPMODE 18 // Sets the One-time-programmable mode
|
||||
#define ADDRESS_SELECTOR 19 // Controls writability of Selector
|
||||
|
||||
|
||||
class atsha204Class
|
||||
{
|
||||
private:
|
||||
uint8_t device_pin;
|
||||
volatile uint8_t *device_port_DDR, *device_port_OUT, *device_port_IN;
|
||||
void sha204c_calculate_crc(uint8_t length, uint8_t *data, uint8_t *crc);
|
||||
uint8_t sha204c_check_crc(uint8_t *response);
|
||||
void swi_set_signal_pin(uint8_t is_high);
|
||||
uint8_t swi_receive_bytes(uint8_t count, uint8_t *buffer);
|
||||
uint8_t swi_send_bytes(uint8_t count, uint8_t *buffer);
|
||||
uint8_t swi_send_byte(uint8_t value);
|
||||
uint8_t sha204p_receive_response(uint8_t size, uint8_t *response);
|
||||
uint8_t sha204p_wakeup();
|
||||
uint8_t sha204p_send_command(uint8_t count, uint8_t * command);
|
||||
uint8_t sha204p_sleep();
|
||||
uint8_t sha204p_resync(uint8_t size, uint8_t *response);
|
||||
|
||||
|
||||
public:
|
||||
atsha204Class(uint8_t pin); // Constructor
|
||||
uint8_t sha204c_wakeup(uint8_t *response);
|
||||
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 sha204c_resync(uint8_t size, uint8_t *response);
|
||||
uint8_t sha204m_random(uint8_t * tx_buffer, uint8_t * rx_buffer, uint8_t mode);
|
||||
uint8_t sha204m_dev_rev(uint8_t *tx_buffer, uint8_t *rx_buffer);
|
||||
uint8_t sha204m_read(uint8_t *tx_buffer, uint8_t *rx_buffer, uint8_t zone, uint16_t address);
|
||||
uint8_t sha204m_execute(uint8_t op_code, uint8_t param1, uint16_t param2,
|
||||
uint8_t datalen1, uint8_t *data1, uint8_t datalen2, uint8_t *data2, uint8_t datalen3, uint8_t *data3,
|
||||
uint8_t tx_size, uint8_t *tx_buffer, uint8_t rx_size, uint8_t *rx_buffer);
|
||||
uint8_t sha204m_check_parameters(uint8_t op_code, uint8_t param1, uint16_t param2,
|
||||
uint8_t datalen1, uint8_t *data1, uint8_t datalen2, uint8_t *data2, uint8_t datalen3, uint8_t *data3,
|
||||
uint8_t tx_size, uint8_t *tx_buffer, uint8_t rx_size, uint8_t *rx_buffer);
|
||||
|
||||
uint8_t getSerialNumber(uint8_t *response);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user