root/HDQ/hdq.cpp

Revision 138, 4.6 KB (checked in by mlalondesvn, 11 months ago)

MODIF - More commenting and headers

Line 
1/**
2 * Texas Instruments HDQ implementation for the Arduino API
3 * (cleft) Matthieu Lalonde 2008 (matth@mlalonde.net)
4 * Creative Commons BY-SA-NC
5 *
6 * http://trac.mlalonde.net/cral/browser/HDQ/
7 *
8 * Revision 1
9 *
10**/
11
12/* ***************** *
13 * HDQ Usage example *
14** ***************** *
15
16#include "hdq.h"
17HDQ HDQ(HDQ_DEFAULT_PIN);
18
19uint8_t r;
20
21for (uint8_t jj = 0; jj < 0x10; jj++) {
22    r = HDQ.read(jj);
23
24    Serial.print("Register 0x");
25    Serial.print(jj, HEX);
26    Serial.print(": ");
27    Serial.print(r, BIN);
28    Serial.print(" 0x");
29    Serial.println(r, HEX);
30}
31
32r = HDQ.read(0x1e);
33
34Serial.print("Register 0x1e: ");
35Serial.print(r, BIN);
36Serial.print(" 0x");
37Serial.println(r, HEX);
38
39r = HDQ.read(0x7e);
40
41Serial.print("Register 0x7e: ");
42Serial.print(r, BIN);
43Serial.print(" 0x");
44Serial.println(r, HEX);
45
46HDQ.write(0x05, B11011101);
47
48r = HDQ.read(0x05);
49
50Serial.print("Register 0x05: ");
51Serial.print(r, BIN);
52Serial.print(" 0x");
53Serial.println(r, HEX);
54
55HDQ.write(0x05, B00111001);
56
57r = HDQ.read(0x05);
58
59Serial.print("Register 0x05: ");
60Serial.print(r, BIN);
61Serial.print(" 0x");
62Serial.println(r, HEX);
63
64*/
65
66extern "C" {
67    #include "WConstants.h"
68    #include "pins_arduino.h"
69}
70
71#include "avrmacros.h"
72#include "hdq.h"
73
74#define _HDQ_readPin() (*inputReg & bitmask)>>pin   /* Change me to inline!*/
75
76/**
77 * Constructor
78 * @param pinArg: pin number to attach to
79**/
80HDQ::HDQ(uint8_t pinArg)
81{
82    pin         = pinArg;
83    port        = digitalPinToPort(pin);
84    bitmask     = digitalPinToBitMask(pin);
85    outputReg   = portOutputRegister(port);
86    inputReg    = portInputRegister(port);
87    modeReg     = portModeRegister(port);
88}
89
90/**
91 * sendBreak: writes a break to the HDQ line
92**/
93void HDQ::doBreak(void)
94{
95    sbi(*modeReg, pin);     // Set pin as output
96   
97    // Singal a break on the line
98    cbi(*outputReg, pin);   // Bring pin low
99    delayMicroseconds(HDQ_DELAY_TB);
100   
101    // Make sure we leave enough time for the slave to recover
102    cbi(*modeReg, pin);     // Release pin
103    delayMicroseconds(HDQ_DELAY_TBR);
104}
105
106/**
107 * writeByte: write a raw byte of data to the bus
108 * @param payload: the byte to send
109 *
110**/
111void HDQ::writeByte(uint8_t payload)
112{
113    sbi(*modeReg, pin);     // Set pin as output
114   
115    for (uint8_t ii = 0; ii < 8; ii++)
116    {
117        // Start bit
118        cbi(*outputReg, pin);   // Bring pin low
119        delayMicroseconds(HDQ_DELAY_BIT_START);
120       
121        // Toggle the pin for this bit, LSB first
122        if (payload>>ii & 0x01) {
123            sbi(*outputReg, pin); // High
124        }
125        else {
126            cbi(*outputReg, pin); // Low
127        }
128       
129        // Bit time
130        delayMicroseconds(HDQ_DELAY_BIT_WRITE);
131       
132        // Stop bit
133        sbi(*outputReg, pin);   // Bring the pin high
134        delayMicroseconds(HDQ_DELAY_BIT_END);
135    }
136   
137    return;
138}
139
140/**
141 * write: send a payload to the device
142 * @param reg: the address of the register to write to
143 * @param payload: data to be sent
144 * @return: false, unless if verif is set, then
145 *          it will read back the register and
146 *          return true if it matches the payload
147**/
148boolean HDQ::write(uint8_t reg, uint8_t payload)
149{
150    // Singal a break
151    HDQ::doBreak();
152   
153    // Write the register to write
154    HDQ::writeByte((reg |= HDQ_ADDR_MASK_WRITE));
155   
156    // Wait for the slave to finish reading the register
157    delayMicroseconds((HDQ_DELAY_TRSPS_MAX - HDQ_DELAY_BIT_TOTAL) / 2);
158   
159    // Write the payload
160    HDQ::writeByte(payload);
161   
162    // Wait for the slave to finish writing the payload
163    delayMicroseconds((HDQ_DELAY_TRSPS_MAX - HDQ_DELAY_BIT_TOTAL) / 2);
164   
165    cbi(*modeReg, pin);     // Release pin
166   
167    return true;
168}
169
170/**
171 * Write with verification
172**/
173boolean HDQ::write(uint8_t reg, uint8_t payload, boolean verif)
174{
175    // Write the payload
176    HDQ::write(reg, payload);
177
178    // Verify the write
179    if (payload == HDQ::read(reg)) return true;
180
181    return false;
182}
183
184
185/**
186 * read: read from the device
187 * @param register: address of the register to read
188 * @return a uint8_t integer
189**/
190uint8_t HDQ::read(uint8_t reg)
191{
192    uint8_t result      = 0;
193    uint8_t maxTries    = HDQ_DELAY_FAIL_TRIES; // ~128uS at 8Mhz with 8 instructions per loop
194    uint8_t ii;
195   
196    // Singal a break
197    HDQ::doBreak();
198   
199    // Write the register to read
200    HDQ::writeByte((reg |= HDQ_ADDR_MASK_READ));
201   
202    for (ii = 0; ii < 8; ii++)
203    {
204        // Wait for the slave to toggle a low, or fail
205        maxTries = HDQ_DELAY_FAIL_TRIES;
206        while (_HDQ_readPin() != 0 && maxTries-- > 0)
207            if (maxTries == 1) return 0xFF;
208       
209        // Wait until Tdsub and half or one bit has passed
210        delayMicroseconds(HDQ_DELAY_BIT_WRITE / 2 + HDQ_DELAY_BIT_START);
211       
212        // Read the bit
213        result |= _HDQ_readPin()<<ii;
214       
215        // Wait until Tssub has passed
216        delayMicroseconds(HDQ_DELAY_TSSUB - (HDQ_DELAY_BIT_WRITE / 2 + HDQ_DELAY_BIT_START) + 10);
217       
218        // Wait for the slave to toggle a high, or fail
219        maxTries = HDQ_DELAY_FAIL_TRIES;
220        while (_HDQ_readPin() != 1 && maxTries-- > 0)
221            if (maxTries == 1) return 0xFF;
222    }
223   
224    return result;
225}
Note: See TracBrowser for help on using the browser.