From 9fbddf67bf59f49e7c8e84a23513d2ce7adfcb83 Mon Sep 17 00:00:00 2001 From: mlalondesvn Date: Sat, 9 Feb 2008 05:35:11 +0000 Subject: [PATCH] ADDED - HDQ Library git-svn-id: svn+ssh://oldsvn/home/mlalondesvn/svn/cral@136 3ee9b42a-b53c-0410-a25e-f0b6218d5d5b --- HDQ/hdq.cpp | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++ HDQ/hdq.h | 101 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 228 insertions(+) create mode 100644 HDQ/hdq.cpp create mode 100644 HDQ/hdq.h diff --git a/HDQ/hdq.cpp b/HDQ/hdq.cpp new file mode 100644 index 0000000..50c7559 --- /dev/null +++ b/HDQ/hdq.cpp @@ -0,0 +1,127 @@ +extern "C" { + #include + #include + #include + #include + #include + #include + + #include "wiring_private.h" + #include "wiring.h" + #include "WConstants.h" + #include + + #include "pins_arduino.h" +} + +#include "avrmacros.h" +#include "hdq.h" + +#define _HDQ_readPin() (*inputReg & bitmask)>>pin /* Change me to inline!*/ + +HDQ::HDQ(uint8_t pinArg) +{ + pin = pinArg; + port = digitalPinToPort(pin); + bitmask = digitalPinToBitMask(pin); + outputReg = portOutputRegister(port); + inputReg = portInputRegister(port); + modeReg = portModeRegister(port); +} + +void HDQ::doBreak(void) +{ + sbi(*modeReg, pin); // Set pin as output + cbi(*outputReg, pin); // Bring pin low + + // Wait the minimum break time + delayMicroseconds(HDQ_DELAY_TB); + + sbi(*outputReg, pin); // Bring the pin high again + + // Wait the minimum break time + delayMicroseconds(HDQ_DELAY_TBR); +} + +void HDQ::writeByte(uint8_t payload) +{ + + for (uint8_t ii = 0; ii < 8; ii++) + { + sbi(*modeReg, pin); // Set pin as output + cbi(*outputReg, pin); // Bring pin low + // Wait the minimum break time + delayMicroseconds(HDQ_DELAY_BIT_START); + + // Toggle the pin for this bit, LSB first + if (payload>>ii & 0x01) { + sbi(*outputReg, pin); + } + else { + cbi(*outputReg, pin); + } + + delayMicroseconds(HDQ_DELAY_BIT_WRITE); + + sbi(*outputReg, pin); + + delayMicroseconds(HDQ_DELAY_BIT_END); + } + + return; +} + +boolean HDQ::write(uint8_t reg, uint8_t payload, boolean verif) +{ + HDQ::write(reg, payload); + + if (payload == HDQ::read(reg)) return true; + + return false; +} + +boolean HDQ::write(uint8_t reg, uint8_t payload) +{ + HDQ::doBreak(); + + HDQ::writeByte((reg |= HDQ_ADDR_MASK_WRITE)); + + delayMicroseconds((HDQ_DELAY_TRSPS_MAX - HDQ_DELAY_BIT_TOTAL) / 2); + + HDQ::writeByte(payload); + + return false; +} + +uint8_t HDQ::read(uint8_t reg) +{ + uint8_t result = 0; + uint8_t maxTries = HDQ_DELAY_FAIL_TRIES; // ~128uS at 8Mhz with 8 instructions per loop + uint8_t ii; + + HDQ::doBreak(); + + HDQ::writeByte((reg |= HDQ_ADDR_MASK_READ)); + + for (ii = 0; ii < 8; ii++) + { + // Wait for the slave to toggle a low + maxTries = HDQ_DELAY_FAIL_TRIES; + while (_HDQ_readPin() != 0 && maxTries-- > 0) + if (maxTries == 1) return 0xFF; + + delayMicroseconds(HDQ_DELAY_BIT_WRITE / 2 + HDQ_DELAY_BIT_START); // 100 / 2 + 30 + + result |= _HDQ_readPin()< 0) + if (maxTries == 1) return 0xFF; + + } + + return result; +} diff --git a/HDQ/hdq.h b/HDQ/hdq.h new file mode 100644 index 0000000..2f759df --- /dev/null +++ b/HDQ/hdq.h @@ -0,0 +1,101 @@ +#ifndef _HDQ_H_ +#define _HDQ_H_ + + /** + * Default pin to use if none is specified to the constructor + **/ + #define HDQ_DEFAULT_PIN 7 /* Arduino pin 7 */ + + /** + * Read/write command mask + **/ + #define HDQ_ADDR_MASK_READ 0x00 + #define HDQ_ADDR_MASK_WRITE 0x80 /* B10000000 */ + + /** + * HDQ bit timings + **/ + #define HDQ_DELAY_BIT_START 30 + #define HDQ_DELAY_BIT_WRITE 100 + #define HDQ_DELAY_BIT_END 70 + #define HDQ_DELAY_BIT_TOTAL 200 + + /** + * This is the number of times the slave wait loop + * will run before we time out. + * As far as I can tell the loop uses ~6 instructions + * thus giving about 200uS delay which is a full bit write + **/ + #define HDQ_DELAY_FAIL_TRIES 225 + + /** + * HDQ Default timings + **/ + #define HDQ_DELAY_TB 250 /* Min: 190uS */ + #define HDQ_DELAY_TBR 50 /* Min: 40uS */ + #define HDQ_DELAY_TSTRH 1 /* Min: 5nS */ + #define HDQ_DELAY_TDSU 50 /* Max: 50uS */ + #define HDQ_DELAY_TDH 100 /* Min: 100uS */ + #define HDQ_DELAY_TSSU 145 /* Max: 145uS */ + #define HDQ_DELAY_TCYCH 190 /* Min: 190uS */ + #define HDQ_DELAY_TSTRB 32 /* Min: 32uS */ + #define HDQ_DELAY_TDSUB 50 /* Max: 50uS */ + #define HDQ_DELAY_TDV 80 /* Min 80uS */ + #define HDQ_DELAY_TSSUB 145 /* Max: 145uS */ + #define HDQ_DELAY_TCYCB_MIN 190 /* Min: 190uS */ + #define HDQ_DELAY_TCYCB_MAX 250 /* Max: 250uS */ + #define HDQ_DELAY_TRSPS_MIN 190 /* Min: 190uS */ + #define HDQ_DELAY_TRSPS_MAX 320 /* Max: 320uS */ + #define HDQ_DELAY_TRSPS_DIFF 130 /* HDQ_DELAY_TRSPS_MAX - HDQ_DELAY_TRSPS_MIN */ + + class HDQ + { + public: + /** + * Constructor + * @param pin: pin number to attach to + **/ + HDQ(uint8_t pinArg = HDQ_DEFAULT_PIN); + + /** + * sendBreak: writes a break to the HDQ line + **/ + void doBreak(void); + + /** + * write: send a payload to the device + * @param reg: the address of the register to write to + * @param payload: data to be sent + * @return: false, unless if verif is set, then + * it will read back the register and + * return true if it matches the payload + **/ + boolean write(uint8_t reg, uint8_t payload, boolean verif); + boolean write(uint8_t reg, uint8_t payload); + + /** + * read: read from the device + * @param register: address of the register to read + * @return a uint8_t integer + **/ + uint8_t read(uint8_t reg); + + private: + /** + * Port variables definition + **/ + uint8_t pin; + uint8_t port; + uint8_t bitmask; + volatile uint8_t *outputReg; + volatile uint8_t *inputReg; + volatile uint8_t *modeReg; + + /** + * writeByte: write a raw byte of data to the bus + * @param payload: the byte to send + * + **/ + void writeByte(uint8_t payload); +}; +#endif