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 }

Generated on Tue Sep 4 19:17:55 2007 for AVR463 Charging NiMH Batteries with ATAVRBC100 by  doxygen 1.5.2