From e2f45251a09cc80292ddebd9f50feed73567e36e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=B8rch?= Date: Thu, 10 Dec 2015 17:11:37 +0100 Subject: [PATCH] Bringing back AVR specific code, for time critical operations --- libraries/sha204/sha204_library.cpp | 63 ++++++++++++++++++----------- libraries/sha204/sha204_library.h | 18 +++++++++ 2 files changed, 57 insertions(+), 24 deletions(-) diff --git a/libraries/sha204/sha204_library.cpp b/libraries/sha204/sha204_library.cpp index d06c6d4..079524f 100644 --- a/libraries/sha204/sha204_library.cpp +++ b/libraries/sha204/sha204_library.cpp @@ -5,11 +5,25 @@ // 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 +// For AVR ARCH, 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 +// For others it will only store the pin number which is used in subsequent functions + atsha204Class::atsha204Class(uint8_t pin) { - device_pin = pin; // Find the bit value of the pin +#if defined(ARDUINO_ARCH_AVR) + 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 } /* Puts a the ATSHA204's unique, 4-byte serial number in the response array @@ -73,12 +87,14 @@ uint16_t atsha204Class::calculateAndUpdateCrc(uint8_t length, uint8_t *data, uin void atsha204Class::swi_set_signal_pin(uint8_t is_high) { - pinMode(device_pin, OUTPUT); + SHA204_SET_OUTPUT(); + if (is_high) { + SHA204_SET_HIGH(); + } + else { + SHA204_SET_LOW(); + } - if (is_high) - digitalWrite(device_pin, HIGH); - else - digitalWrite(device_pin, LOW); } uint8_t atsha204Class::swi_send_bytes(uint8_t count, uint8_t *buffer) @@ -89,9 +105,8 @@ uint8_t atsha204Class::swi_send_bytes(uint8_t count, uint8_t *buffer) noInterrupts(); //swi_disable_interrupts(); // Set signal pin as output. - pinMode(device_pin, OUTPUT); - digitalWrite(device_pin, HIGH); - + SHA204_SET_HIGH(); + SHA204_SET_OUTPUT(); // Wait turn around time. delayMicroseconds(RX_TX_DELAY); //RX_TX_DELAY; @@ -101,22 +116,22 @@ uint8_t atsha204Class::swi_send_bytes(uint8_t count, uint8_t *buffer) { if (bit_mask & buffer[i]) { - digitalWrite(device_pin, LOW); + SHA204_SET_LOW(); delayMicroseconds(BIT_DELAY); //BIT_DELAY_1; - digitalWrite(device_pin, HIGH); + SHA204_SET_HIGH(); delayMicroseconds(7*BIT_DELAY); //BIT_DELAY_7; } else { // Send a zero bit. - digitalWrite(device_pin, LOW); + SHA204_SET_LOW(); delayMicroseconds(BIT_DELAY); //BIT_DELAY_1; - digitalWrite(device_pin, HIGH); + SHA204_SET_HIGH(); delayMicroseconds(BIT_DELAY); //BIT_DELAY_1; - digitalWrite(device_pin, LOW); + SHA204_SET_LOW(); delayMicroseconds(BIT_DELAY); //BIT_DELAY_1; - digitalWrite(device_pin, HIGH); - delayMicroseconds(5*BIT_DELAY); //BIT_DELAY_5; + SHA204_SET_HIGH(); + delayMicroseconds(5*BIT_DELAY); //BIT_DELAY_5; } } } @@ -140,9 +155,9 @@ uint8_t atsha204Class::swi_receive_bytes(uint8_t count, uint8_t *buffer) // Disable interrupts while receiving. noInterrupts(); //swi_disable_interrupts(); - // Configure signal pin as input. - pinMode(device_pin,INPUT); - + // Configure signal pin as input + SHA204_SET_INPUT(); + // Receive bits and store in buffer. for (i = 0; i < count; i++) { @@ -159,7 +174,7 @@ uint8_t atsha204Class::swi_receive_bytes(uint8_t count, uint8_t *buffer) while (--timeout_count > 0) { // Wait for falling edge. - if (digitalRead(device_pin) == 0) + if (SHA204_READ_PIN() == 0) break; } @@ -172,7 +187,7 @@ uint8_t atsha204Class::swi_receive_bytes(uint8_t count, uint8_t *buffer) do { // Wait for rising edge. - if (digitalRead(device_pin) != 0) + if (SHA204_READ_PIN() != 0) { // For an Atmel microcontroller this might be faster than "pulse_count++". pulse_count = 1; @@ -195,7 +210,7 @@ uint8_t atsha204Class::swi_receive_bytes(uint8_t count, uint8_t *buffer) // Detect possible edge indicating zero bit. do { - if (digitalRead(device_pin) == 0) + if (SHA204_READ_PIN() == 0) { // For an Atmel microcontroller this might be faster than "pulse_count++". pulse_count = 2; @@ -209,7 +224,7 @@ uint8_t atsha204Class::swi_receive_bytes(uint8_t count, uint8_t *buffer) { do { - if (digitalRead(device_pin) != 0) + if (SHA204_READ_PIN() != 0) break; } while (timeout_count-- > 0); } diff --git a/libraries/sha204/sha204_library.h b/libraries/sha204/sha204_library.h index 762c85b..4079e42 100644 --- a/libraries/sha204/sha204_library.h +++ b/libraries/sha204/sha204_library.h @@ -279,11 +279,29 @@ #define ADDRESS_OTPMODE 18 // Sets the One-time-programmable mode #define ADDRESS_SELECTOR 19 // Controls writability of Selector +/* Low level HW access macros */ +/* function calls is not working, as it will have too much overhead */ +#if !defined(ARDUINO_ARCH_AVR) // For everything else than AVR use pinMode / digitalWrite +#define SHA204_SET_OUTPUT() pinMode(device_pin, OUTPUT) +#define SHA204_SET_INPUT() pinMode(device_pin, INPUT) +#define SHA204_SET_HIGH() digitalWrite(device_pin, HIGH) +#define SHA204_SET_LOW() digitalWrite(device_pin, LOW) +#define SHA204_READ_PIN() digitalRead(device_pin) +#else +#define SHA204_SET_INPUT() *device_port_DDR &= ~device_pin +#define SHA204_SET_OUTPUT() *device_port_DDR |= device_pin +#define SHA204_SET_HIGH() *device_port_OUT |= device_pin +#define SHA204_SET_LOW() *device_port_OUT &= ~device_pin +#define SHA204_READ_PIN() (*device_port_IN & device_pin) +#endif class atsha204Class { private: uint8_t device_pin; + #ifdef ARDUINO_ARCH_AVR + volatile uint8_t *device_port_DDR, *device_port_OUT, *device_port_IN; + #endif 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);