- Main Page
- Related Pages
- Data Structures
- Files

# OWI.c

Go to the documentation of this file.

    00001 /* This file has been prepared for Doxygen automatic documentation generation.*/
    00036 #include <ioavr.h>
    00037 #include <inavr.h>
    00038
    00039 #include "OWI.h"
    00040
    00041
    00042 //******************************************************************************
    00043 // Functions
    00044 //******************************************************************************
    00052 void OWI_Init(unsigned char pins){
    00053         OWI_RELEASE_BUS(pins);
    00054         // The first rising edge can be interpreted by a slave as the end of a
    00055         // Reset-pulse. Delay for the required reset recovery time (H) to be
    00056         // sure that the real reset is interpreted correctly.
    00057         __delay_cycles(OWI_DELAY_H_STD_MODE);
    00058 }
    00059
    00060
    00068 void OWI_WriteBit1(unsigned char pins){
    00069         unsigned char intState;
    00070
    00071         // Disable interrupts.
    00072         intState = __save_interrupt();
    00073         __disable_interrupt();
    00074
    00075         // Drive bus low and delay.
    00076         OWI_PULL_BUS_LOW(pins);
    00077         __delay_cycles(OWI_DELAY_A_STD_MODE);
    00078
    00079         // Release bus and delay.
    00080         OWI_RELEASE_BUS(pins);
    00081         __delay_cycles(OWI_DELAY_B_STD_MODE);
    00082
    00083         // Restore interrupts.
    00084         __restore_interrupt(intState);
    00085 }
    00086
    00094 void OWI_WriteBit0(unsigned char pins)
    00095 {
    00096         unsigned char intState;
    00097
    00098         // Disable interrupts.
    00099         intState = __save_interrupt();
    00100         __disable_interrupt();
    00101
    00102         // Drive bus low and delay.
    00103         OWI_PULL_BUS_LOW(pins);
    00104         __delay_cycles(OWI_DELAY_C_STD_MODE);
    00105
    00106         // Release bus and delay.
    00107         OWI_RELEASE_BUS(pins);
    00108         __delay_cycles(OWI_DELAY_D_STD_MODE);
    00109
    00110         // Restore interrupts.
    00111         __restore_interrupt(intState);
    00112 }
    00113
    00122 unsigned char OWI_ReadBit(unsigned char pins)
    00123 {
    00124         unsigned char intState;
    00125         unsigned char bitsRead;
    00126
    00127         // Disable interrupts.
    00128         intState = __save_interrupt();
    00129         __disable_interrupt();
    00130
    00131         // Drive bus low and delay.
    00132         OWI_PULL_BUS_LOW(pins);
    00133         __delay_cycles(OWI_DELAY_A_STD_MODE);
    00134
    00135         // Release bus and delay.
    00136         OWI_RELEASE_BUS(pins);
    00137         __delay_cycles(OWI_DELAY_E_STD_MODE);
    00138
    00139         // Sample bus and delay.
    00140         bitsRead = OWI_PIN & pins;
    00141         __delay_cycles(OWI_DELAY_F_STD_MODE);
    00142
    00143         // Restore interrupts.
    00144         __restore_interrupt(intState);
    00145
    00146         return bitsRead;
    00147 }
    00148
    00149
    00160 unsigned char OWI_DetectPresence(unsigned char pins)
    00161 {
    00162         unsigned char intState;
    00163         unsigned char presenceDetected;
    00164
    00165         // Disable interrupts.
    00166         intState = __save_interrupt();
    00167         __disable_interrupt();
    00168
    00169         // Drive bus low and delay.
    00170         OWI_PULL_BUS_LOW(pins);
    00171         __delay_cycles(OWI_DELAY_H_STD_MODE);
    00172
    00173         // Release bus and delay.
    00174         OWI_RELEASE_BUS(pins);
    00175         __delay_cycles(OWI_DELAY_I_STD_MODE);
    00176
    00177         // Sample bus to detect presence signal and delay.
    00178         presenceDetected = ((~OWI_PIN) & pins);
    00179         __delay_cycles(OWI_DELAY_J_STD_MODE);
    00180
    00181         // Restore interrupts.
    00182         __restore_interrupt(intState);
    00183
    00184         return presenceDetected;
    00185 }
    00186
    00187
    00197 void OWI_SendByte(unsigned char data, unsigned char pins)
    00198 {
    00199         unsigned char temp;
    00200         unsigned char i;
    00201
    00202         // Do once for each bit
    00203         for (i = 0; i < 8; i++) {
    00204                 // Determine if LSB is '0' or '1' and transmit corresponding
    00205                 // waveform on the bus.
    00206                 temp = data & 0x01;
    00207
    00208                 if (temp) {
    00209                         OWI_WriteBit1(pins);
    00210                 } else {
    00211                         OWI_WriteBit0(pins);
    00212                 }
    00213
    00214                 data >>= 1;  // Right shift the data to get next bit.
    00215         }
    00216 }
    00217
    00218
    00228 unsigned char OWI_ReceiveByte(unsigned char pin)
    00229 {
    00230         unsigned char data;
    00231         unsigned char i;
    00232
    00233         // Clear the temporary input variable.
    00234         data = 0x00;
    00235
    00236         // Do once for each bit
    00237         for (i = 0; i < 8; i++) {
    00238                 // Shift temporary input variable right.
    00239                 data >>= 1;
    00240
    00241                 // Set the MSB if a '1' value is read from the bus.
    00242                 // Leave as it is ('0') else.
    00243                 if (OWI_ReadBit(pin)) {
    00244                         data |= 0x80;
    00245                 }
    00246         }
    00247
    00248         return data;
    00249 }
    00250
    00251
    00256 void OWI_SkipRom(unsigned char pins)
    00257 {
    00258         // Send the SKIP ROM command on the bus.
    00259         OWI_SendByte(OWI_ROM_SKIP, pins);
    00260 }
    00261
    00262
    00269 void OWI_ReadRom(unsigned char * romValue, unsigned char pin)
    00270 {
    00271         unsigned char bytesLeft = 8;
    00272
    00273         // Send the READ ROM command on the bus.
    00274         OWI_SendByte(OWI_ROM_READ, pin);
    00275
    00276         // Do 8 times.
    00277         while (bytesLeft > 0) {
    00278                 // Place the received data in memory.
    00279                 *romValue++ = OWI_ReceiveByte(pin);
    00280                 bytesLeft--;
    00281         }
    00282 }
    00283
    00284
    00291 void OWI_MatchRom(unsigned char * romValue, unsigned char pins)
    00292 {
    00293         unsigned char bytesLeft = 8;
    00294
    00295         // Send the MATCH ROM command.
    00296         OWI_SendByte(OWI_ROM_MATCH, pins);
    00297
    00298         // Do once for each byte.
    00299         while (bytesLeft > 0) {
    00300                 // Transmit 1 byte of the ID to match.
    00301                 OWI_SendByte(*romValue++, pins);
    00302                 bytesLeft--;
    00303         }
    00304 }
    00305
    00306
    00333 unsigned char OWI_SearchRom(unsigned char * bitPattern,
    00334                                                 unsigned char lastDeviation, unsigned char pin)
    00335 {
    00336         unsigned char currentBit = 1;
    00337         unsigned char newDeviation = 0;
    00338         unsigned char bitMask = 0x01;
    00339         unsigned char bitA;
    00340         unsigned char bitB;
    00341
    00342         // Send SEARCH ROM command on the bus.
    00343         OWI_SendByte(OWI_ROM_SEARCH, pin);
    00344
    00345         // Walk through all 64 bits.
    00346         while (currentBit <= 64) {
    00347                 // Read bit from bus twice.
    00348                 bitA = OWI_ReadBit(pin);
    00349                 bitB = OWI_ReadBit(pin);
    00350
    00351                 if (bitA && bitB) {
    00352                         // Both bits 1 (Error).
    00353                         newDeviation = OWI_ROM_SEARCH_FAILED;
    00354                         return newDeviation;
    00355                 } else if (bitA ^ bitB) {
    00356                         // Bits A and B are different. All devices have the same bit here.
    00357                         // Set the bit in bitPattern to this value.
    00358                         if (bitA) {
    00359                                 (*bitPattern) |= bitMask;
    00360                         } else {
    00361                                 (*bitPattern) &= ~bitMask;
    00362                         }
    00363                 } else {
    00364                         // If this is where a choice was made the last time,
    00365                         // a '1' bit is selected this time.
    00366                         if (currentBit == lastDeviation) {
    00367                                 (*bitPattern) |= bitMask;
    00368                         }
    00369
    00370                         // For the rest of the id, '0' bits are selected when
    00371                         // discrepancies occur.
    00372                         else if (currentBit > lastDeviation) {
    00373                                 (*bitPattern) &= ~bitMask;
    00374                                 newDeviation = currentBit;
    00375                         }
    00376
    00377                         // If current bit in bit pattern = 0, then this is
    00378                         // out new deviation.
    00379                         else if ( !(*bitPattern & bitMask)) {
    00380                                 newDeviation = currentBit;
    00381                         }
    00382
    00383                 // IF the bit is already 1, do nothing.
    00384                         else {
    00385                         }
    00386                 }
    00387
    00388                 // Send the selected bit to the bus.
    00389                 if ((*bitPattern) & bitMask) {
    00390                         OWI_WriteBit1(pin);
    00391                 } else {
    00392                         OWI_WriteBit0(pin);
    00393                 }
    00394
    00395                 // Increment current bit.
    00396                 currentBit++;
    00397
    00398                 // Adjust bitMask and bitPattern pointer.
    00399                 bitMask <<= 1;
    00400                 if (!bitMask) {
    00401                         bitMask = 0x01;
    00402                         bitPattern++;
    00403                 }
    00404         }
    00405
    00406         return newDeviation;
    00407 }
    00408
    00409
    00410 /* Functions for handling CRC */
    00428 unsigned char OWI_ComputeCRC8(unsigned char inData, unsigned char seed)
    00429 {
    00430         unsigned char bitsLeft;
    00431         unsigned char temp;
    00432
    00433         for (bitsLeft = 8; bitsLeft > 0; bitsLeft--) {
    00434                 temp = ((seed ^ inData) & 0x01);
    00435
    00436                 if (temp == 0) {
    00437                 seed >>= 1;
    00438                 } else {
    00439                         seed ^= 0x18;
    00440                         seed >>= 1;
    00441                         seed |= 0x80;
    00442                 }
    00443
    00444                 inData >>= 1;
    00445         }
    00446         return seed;
    00447 }
    00448
    00449
    00467 unsigned int OWI_ComputeCRC16(unsigned char inData, unsigned int seed)
    00468 {
    00469         unsigned char bitsLeft;
    00470         unsigned char temp;
    00471
    00472         for (bitsLeft = 8; bitsLeft > 0; bitsLeft--) {
    00473                 temp = ((seed ^ inData) & 0x01);
    00474
    00475                 if (temp == 0) {
    00476                         seed >>= 1;
    00477           } else {
    00478                         seed ^= 0x4002;
    00479                         seed >>= 1;
    00480                         seed |= 0x8000;
    00481                 }
    00482
    00483                 inData >>= 1;
    00484         }
    00485
    00486         return seed;
    00487 }
    00488
    00489
    00501 unsigned char OWI_CheckRomCRC(unsigned char *romValue)
    00502 {
    00503         unsigned char i;
    00504         unsigned char crc8 = 0;
    00505
    00506         for (i = 0; i < 7; i++) {
    00507                 crc8 = OWI_ComputeCRC8(*romValue, crc8);
    00508                 romValue++;
    00509         }
    00510
    00511         if (crc8 == (*romValue)) {
    00512                 return OWI_CRC_OK;
    00513         }
    00514
    00515         return OWI_CRC_ERROR;
    00516 }