############################################################################### # # # IAR Atmel AVR C/C++ Compiler V4.30F/W32 12/Mar/2008 23:01:38 # # Copyright 1996-2007 IAR Systems. All rights reserved. # # # # Source file = C:\home\kevin\pub\src\bc100_cal\IAR\OWI.c # # Command line = C:\home\kevin\pub\src\bc100_cal\IAR\OWI.c --cpu=tiny861 # # -ms -o C:\home\kevin\pub\src\bc100_cal\IAR\Debug\Obj\ # # -lC C:\home\kevin\pub\src\bc100_cal\IAR\Debug\List\ -lB # # C:\home\kevin\pub\src\bc100_cal\IAR\Debug\List\ # # --initializers_in_flash -z2 --no_cse --no_inline # # --no_code_motion --no_cross_call --no_clustering # # --no_tbaa --debug -DENABLE_BIT_DEFINITIONS -e # # --require_prototypes -I "C:\Program Files\IAR # # Systems\Embedded Workbench 4.0\avr\INC\" -I "C:\Program # # Files\IAR Systems\Embedded Workbench 4.0\avr\INC\CLIB\" # # --eeprom_size 512 # # List file = C:\home\kevin\pub\src\bc100_cal\IAR\Debug\List\OWI.lst # # Object file = C:\home\kevin\pub\src\bc100_cal\IAR\Debug\Obj\OWI.r90 # # # # # ############################################################################### C:\home\kevin\pub\src\bc100_cal\IAR\OWI.c 1 /* This file has been prepared for Doxygen automatic documentation generation.*/ 2 /*! \file ******************************************************************** 3 * 4 * \brief 5 * Functions for 1-Wire(R) bus communication 6 * 7 * High level functions for transmission of full bytes on the 1-Wire(R) 8 * bus and implementations of ROM commands.\n 9 * Polled software only implementation of the basic bit-level signalling 10 * in the 1-Wire(R) protocol.\n 11 * Includes functions for computing and checking CRC8 & 16 values of data 12 * sets, and of 64 bit ROM identifiers. 13 * Supported devices: All AVRs. 14 * 15 * \par Application Note: 16 * AVR458: Charging Li-Ion Batteries with BC100\n 17 * AVR463: Charging NiMH Batteries with BC100\n 18 * One-wire protocol based on AVR318 - Dallas 1-Wire(R) master. 19 * 20 * \par Documentation: 21 * For comprehensive code documentation, supported compilers, compiler 22 * settings and supported devices see readme.html 23 * 24 * \author 25 * Atmel Corporation: http://www.atmel.com \n 26 * Support email: avr@atmel.com \n 27 * Original author: \n 28 * 29 * $Name$ 30 * $Revision: 2299 $ 31 * $RCSfile$ 32 * $URL: http://svn.norway.atmel.com/AppsAVR8/avr458_Charging_Li-Ion_Batteries_with_BC100/tag/20070904_release_1.0/code/IAR/OWI.c $ 33 * $Date: 2007-08-23 12:55:51 +0200 (to, 23 aug 2007) $\n 34 ****************************************************************************/ 35 36 #include \ In segment ABSOLUTE, at 0x3b \ volatile __io _A_PORTA \ _A_PORTA: \ 00000000 DS 1 \ In segment ABSOLUTE, at 0x3a \ volatile __io _A_DDRA \ _A_DDRA: \ 00000000 DS 1 \ In segment ABSOLUTE, at 0x39 \ volatile __io _A_PINA \ _A_PINA: \ 00000000 DS 1 37 #include 38 39 #include "OWI.h" 40 41 42 //****************************************************************************** 43 // Functions 44 //****************************************************************************** 45 /*! \brief Initialization of the one wire bus(es). (Software only driver) 46 * 47 * This function initializes the 1-Wire bus(es) by releasing it and 48 * waiting until any presence signals are finished. 49 * 50 * \param pins A bitmask of the buses to initialize. 51 */ \ In segment CODE, align 2, keep-with-next 52 void OWI_Init(unsigned char pins){ \ OWI_Init: 53 OWI_RELEASE_BUS(pins); \ 00000000 2F10 MOV R17, R16 \ 00000002 9510 COM R17 \ 00000004 B32A IN R18, 0x1A \ 00000006 2321 AND R18, R17 \ 00000008 BB2A OUT 0x1A, R18 \ 0000000A 2F10 MOV R17, R16 \ 0000000C 9510 COM R17 \ 0000000E B32B IN R18, 0x1B \ 00000010 2321 AND R18, R17 \ 00000012 BB2B OUT 0x1B, R18 54 // The first rising edge can be interpreted by a slave as the end of a 55 // Reset-pulse. Delay for the required reset recovery time (H) to be 56 // sure that the real reset is interpreted correctly. 57 __delay_cycles(OWI_DELAY_H_STD_MODE); \ 00000014 EB2C LDI R18, 188 \ 00000016 E033 LDI R19, 3 \ 00000018 5021 SUBI R18, 1 \ 0000001A 4030 SBCI R19, 0 \ 0000001C F7E9 BRNE $-4 \ 0000001E C000 RJMP $+2 58 } \ 00000020 9508 RET \ 00000022 REQUIRE _A_PORTA \ 00000022 REQUIRE _A_DDRA 59 60 61 /*! \brief Write a '1' bit to the bus(es). (Software only driver) 62 * 63 * Generates the waveform for transmission of a '1' bit on the 1-Wire 64 * bus. 65 * 66 * \param pins A bitmask of the buses to write to. 67 */ \ In segment CODE, align 2, keep-with-next 68 void OWI_WriteBit1(unsigned char pins){ \ OWI_WriteBit1: 69 unsigned char intState; 70 71 // Disable interrupts. 72 intState = __save_interrupt(); \ 00000000 B72F IN R18, 0x3F \ 00000002 2F12 MOV R17, R18 73 __disable_interrupt(); \ 00000004 94F8 CLI 74 75 // Drive bus low and delay. 76 OWI_PULL_BUS_LOW(pins); \ 00000006 B32A IN R18, 0x1A \ 00000008 2B20 OR R18, R16 \ 0000000A BB2A OUT 0x1A, R18 \ 0000000C 2F20 MOV R18, R16 \ 0000000E 9520 COM R18 \ 00000010 B33B IN R19, 0x1B \ 00000012 2332 AND R19, R18 \ 00000014 BB3B OUT 0x1B, R19 77 __delay_cycles(OWI_DELAY_A_STD_MODE); \ 00000016 E02B LDI R18, 11 \ 00000018 952A DEC R18 \ 0000001A F7F1 BRNE $-2 \ 0000001C C000 RJMP $+2 78 79 // Release bus and delay. 80 OWI_RELEASE_BUS(pins); \ 0000001E 2F20 MOV R18, R16 \ 00000020 9520 COM R18 \ 00000022 B33A IN R19, 0x1A \ 00000024 2332 AND R19, R18 \ 00000026 BB3A OUT 0x1A, R19 \ 00000028 2F20 MOV R18, R16 \ 0000002A 9520 COM R18 \ 0000002C B33B IN R19, 0x1B \ 0000002E 2332 AND R19, R18 \ 00000030 BB3B OUT 0x1B, R19 81 __delay_cycles(OWI_DELAY_B_STD_MODE); \ 00000032 EA26 LDI R18, 166 \ 00000034 952A DEC R18 \ 00000036 F7F1 BRNE $-2 \ 00000038 0000 NOP 82 83 // Restore interrupts. 84 __restore_interrupt(intState); \ 0000003A BF1F OUT 0x3F, R17 85 } \ 0000003C 9508 RET \ 0000003E REQUIRE _A_PORTA \ 0000003E REQUIRE _A_DDRA 86 87 /*! \brief Write a '0' to the bus(es). (Software only driver) 88 * 89 * Generates the waveform for transmission of a '0' bit on the 1-Wire(R) 90 * bus. 91 * 92 * \param pins A bitmask of the buses to write to. 93 */ \ In segment CODE, align 2, keep-with-next 94 void OWI_WriteBit0(unsigned char pins) \ OWI_WriteBit0: 95 { 96 unsigned char intState; 97 98 // Disable interrupts. 99 intState = __save_interrupt(); \ 00000000 B72F IN R18, 0x3F \ 00000002 2F12 MOV R17, R18 100 __disable_interrupt(); \ 00000004 94F8 CLI 101 102 // Drive bus low and delay. 103 OWI_PULL_BUS_LOW(pins); \ 00000006 B32A IN R18, 0x1A \ 00000008 2B20 OR R18, R16 \ 0000000A BB2A OUT 0x1A, R18 \ 0000000C 2F20 MOV R18, R16 \ 0000000E 9520 COM R18 \ 00000010 B33B IN R19, 0x1B \ 00000012 2332 AND R19, R18 \ 00000014 BB3B OUT 0x1B, R19 104 __delay_cycles(OWI_DELAY_C_STD_MODE); \ 00000016 E92B LDI R18, 155 \ 00000018 952A DEC R18 \ 0000001A F7F1 BRNE $-2 \ 0000001C C000 RJMP $+2 105 106 // Release bus and delay. 107 OWI_RELEASE_BUS(pins); \ 0000001E 2F20 MOV R18, R16 \ 00000020 9520 COM R18 \ 00000022 B33A IN R19, 0x1A \ 00000024 2332 AND R19, R18 \ 00000026 BB3A OUT 0x1A, R19 \ 00000028 2F20 MOV R18, R16 \ 0000002A 9520 COM R18 \ 0000002C B33B IN R19, 0x1B \ 0000002E 2332 AND R19, R18 \ 00000030 BB3B OUT 0x1B, R19 108 __delay_cycles(OWI_DELAY_D_STD_MODE); \ 00000032 E126 LDI R18, 22 \ 00000034 952A DEC R18 \ 00000036 F7F1 BRNE $-2 \ 00000038 0000 NOP 109 110 // Restore interrupts. 111 __restore_interrupt(intState); \ 0000003A BF1F OUT 0x3F, R17 112 } \ 0000003C 9508 RET \ 0000003E REQUIRE _A_PORTA \ 0000003E REQUIRE _A_DDRA 113 114 /*! \brief Read a bit from the bus(es). (Software only driver) 115 * 116 * Generates the waveform for reception of a bit on the 1-Wire(R) bus(es). 117 * 118 * \param pins A bitmask of the bus(es) to read from. 119 * 120 * \return A bitmask of the buses where a '1' was read. 121 */ \ In segment CODE, align 2, keep-with-next 122 unsigned char OWI_ReadBit(unsigned char pins) \ OWI_ReadBit: 123 { \ 00000000 2F10 MOV R17, R16 124 unsigned char intState; 125 unsigned char bitsRead; 126 127 // Disable interrupts. 128 intState = __save_interrupt(); \ 00000002 B73F IN R19, 0x3F \ 00000004 2F23 MOV R18, R19 129 __disable_interrupt(); \ 00000006 94F8 CLI 130 131 // Drive bus low and delay. 132 OWI_PULL_BUS_LOW(pins); \ 00000008 B33A IN R19, 0x1A \ 0000000A 2B31 OR R19, R17 \ 0000000C BB3A OUT 0x1A, R19 \ 0000000E 2F31 MOV R19, R17 \ 00000010 9530 COM R19 \ 00000012 B34B IN R20, 0x1B \ 00000014 2343 AND R20, R19 \ 00000016 BB4B OUT 0x1B, R20 133 __delay_cycles(OWI_DELAY_A_STD_MODE); \ 00000018 E03B LDI R19, 11 \ 0000001A 953A DEC R19 \ 0000001C F7F1 BRNE $-2 \ 0000001E C000 RJMP $+2 134 135 // Release bus and delay. 136 OWI_RELEASE_BUS(pins); \ 00000020 2F31 MOV R19, R17 \ 00000022 9530 COM R19 \ 00000024 B34A IN R20, 0x1A \ 00000026 2343 AND R20, R19 \ 00000028 BB4A OUT 0x1A, R20 \ 0000002A 2F31 MOV R19, R17 \ 0000002C 9530 COM R19 \ 0000002E B34B IN R20, 0x1B \ 00000030 2343 AND R20, R19 \ 00000032 BB4B OUT 0x1B, R20 137 __delay_cycles(OWI_DELAY_E_STD_MODE); \ 00000034 E133 LDI R19, 19 \ 00000036 953A DEC R19 \ 00000038 F7F1 BRNE $-2 \ 0000003A C000 RJMP $+2 138 139 // Sample bus and delay. 140 bitsRead = OWI_PIN & pins; \ 0000003C B339 IN R19, 0x19 \ 0000003E 2331 AND R19, R17 \ 00000040 2F03 MOV R16, R19 141 __delay_cycles(OWI_DELAY_F_STD_MODE); \ 00000042 E83E LDI R19, 142 \ 00000044 953A DEC R19 \ 00000046 F7F1 BRNE $-2 \ 00000048 0000 NOP 142 143 // Restore interrupts. 144 __restore_interrupt(intState); \ 0000004A BF2F OUT 0x3F, R18 145 146 return bitsRead; \ 0000004C 9508 RET \ 0000004E REQUIRE _A_PORTA \ 0000004E REQUIRE _A_DDRA \ 0000004E REQUIRE _A_PINA 147 } 148 149 150 /*! \brief Send a Reset signal and listen for Presence signal. (software 151 * only driver) 152 * 153 * Generates the waveform for transmission of a Reset pulse on the 154 * 1-Wire(R) bus and listens for presence signals. 155 * 156 * \param pins A bitmask of the buses to send the Reset signal on. 157 * 158 * \return A bitmask of the buses where a presence signal was detected. 159 */ \ In segment CODE, align 2, keep-with-next 160 unsigned char OWI_DetectPresence(unsigned char pins) \ OWI_DetectPresence: 161 { \ 00000000 2F10 MOV R17, R16 162 unsigned char intState; 163 unsigned char presenceDetected; 164 165 // Disable interrupts. 166 intState = __save_interrupt(); \ 00000002 B73F IN R19, 0x3F \ 00000004 2F23 MOV R18, R19 167 __disable_interrupt(); \ 00000006 94F8 CLI 168 169 // Drive bus low and delay. 170 OWI_PULL_BUS_LOW(pins); \ 00000008 B33A IN R19, 0x1A \ 0000000A 2B31 OR R19, R17 \ 0000000C BB3A OUT 0x1A, R19 \ 0000000E 2F31 MOV R19, R17 \ 00000010 9530 COM R19 \ 00000012 B34B IN R20, 0x1B \ 00000014 2343 AND R20, R19 \ 00000016 BB4B OUT 0x1B, R20 171 __delay_cycles(OWI_DELAY_H_STD_MODE); \ 00000018 EB4C LDI R20, 188 \ 0000001A E053 LDI R21, 3 \ 0000001C 5041 SUBI R20, 1 \ 0000001E 4050 SBCI R21, 0 \ 00000020 F7E9 BRNE $-4 \ 00000022 C000 RJMP $+2 172 173 // Release bus and delay. 174 OWI_RELEASE_BUS(pins); \ 00000024 2F31 MOV R19, R17 \ 00000026 9530 COM R19 \ 00000028 B34A IN R20, 0x1A \ 0000002A 2343 AND R20, R19 \ 0000002C BB4A OUT 0x1A, R20 \ 0000002E 2F31 MOV R19, R17 \ 00000030 9530 COM R19 \ 00000032 B34B IN R20, 0x1B \ 00000034 2343 AND R20, R19 \ 00000036 BB4B OUT 0x1B, R20 175 __delay_cycles(OWI_DELAY_I_STD_MODE); \ 00000038 EB36 LDI R19, 182 \ 0000003A 953A DEC R19 \ 0000003C F7F1 BRNE $-2 \ 0000003E 0000 NOP 176 177 // Sample bus to detect presence signal and delay. 178 presenceDetected = ((~OWI_PIN) & pins); \ 00000040 B339 IN R19, 0x19 \ 00000042 9530 COM R19 \ 00000044 2331 AND R19, R17 \ 00000046 2F03 MOV R16, R19 179 __delay_cycles(OWI_DELAY_J_STD_MODE); \ 00000048 E340 LDI R20, 48 \ 0000004A E053 LDI R21, 3 \ 0000004C 5041 SUBI R20, 1 \ 0000004E 4050 SBCI R21, 0 \ 00000050 F7E9 BRNE $-4 \ 00000052 C000 RJMP $+2 180 181 // Restore interrupts. 182 __restore_interrupt(intState); \ 00000054 BF2F OUT 0x3F, R18 183 184 return presenceDetected; \ 00000056 9508 RET \ 00000058 REQUIRE _A_PORTA \ 00000058 REQUIRE _A_DDRA \ 00000058 REQUIRE _A_PINA 185 } 186 187 188 /*! \brief Sends one byte of data on the 1-Wire(R) bus(es). 189 * 190 * This function automates the task of sending a complete byte 191 * of data on the 1-Wire bus(es). 192 * 193 * \param data The data to send on the bus(es). 194 * 195 * \param pins A bitmask of the buses to send the data to. 196 */ \ In segment CODE, align 2, keep-with-next 197 void OWI_SendByte(unsigned char data, unsigned char pins) \ OWI_SendByte: 198 { \ 00000000 .... RCALL ?PROLOGUE4_L09 \ 00000002 2FA0 MOV R26, R16 \ 00000004 2F91 MOV R25, R17 199 unsigned char temp; 200 unsigned char i; 201 202 // Do once for each bit 203 for (i = 0; i < 8; i++) { \ 00000006 E080 LDI R24, 0 \ ??OWI_SendByte_0: \ 00000008 3088 CPI R24, 8 \ 0000000A F468 BRCC ??OWI_SendByte_1 204 // Determine if LSB is '0' or '1' and transmit corresponding 205 // waveform on the bus. 206 temp = data & 0x01; \ 0000000C 2F0A MOV R16, R26 \ 0000000E 7001 ANDI R16, 0x01 \ 00000010 2FB0 MOV R27, R16 207 208 if (temp) { \ 00000012 23BB TST R27 \ 00000014 F019 BREQ ??OWI_SendByte_2 209 OWI_WriteBit1(pins); \ 00000016 2F09 MOV R16, R25 \ 00000018 .... RCALL OWI_WriteBit1 \ 0000001A C002 RJMP ??OWI_SendByte_3 210 } else { 211 OWI_WriteBit0(pins); \ ??OWI_SendByte_2: \ 0000001C 2F09 MOV R16, R25 \ 0000001E .... RCALL OWI_WriteBit0 212 } 213 214 data >>= 1; // Right shift the data to get next bit. \ ??OWI_SendByte_3: \ 00000020 95A6 LSR R26 215 } \ 00000022 9583 INC R24 \ 00000024 CFF1 RJMP ??OWI_SendByte_0 216 } \ ??OWI_SendByte_1: \ 00000026 E0E4 LDI R30, 4 \ 00000028 .... RJMP ?EPILOGUE_B4_L09 217 218 219 /*! \brief Receives one byte of data from the 1-Wire(R) bus. 220 * 221 * This function automates the task of receiving a complete byte 222 * of data from the 1-Wire bus. 223 * 224 * \param pin A bitmask of the bus to read from. 225 * 226 * \return The byte read from the bus. 227 */ \ In segment CODE, align 2, keep-with-next 228 unsigned char OWI_ReceiveByte(unsigned char pin) \ OWI_ReceiveByte: 229 { \ 00000000 .... RCALL ?PROLOGUE3_L09 \ 00000002 2FA0 MOV R26, R16 230 unsigned char data; 231 unsigned char i; 232 233 // Clear the temporary input variable. 234 data = 0x00; \ 00000004 E090 LDI R25, 0 235 236 // Do once for each bit 237 for (i = 0; i < 8; i++) { \ 00000006 E080 LDI R24, 0 \ ??OWI_ReceiveByte_0: \ 00000008 3088 CPI R24, 8 \ 0000000A F448 BRCC ??OWI_ReceiveByte_1 238 // Shift temporary input variable right. 239 data >>= 1; \ 0000000C 9596 LSR R25 240 241 // Set the MSB if a '1' value is read from the bus. 242 // Leave as it is ('0') else. 243 if (OWI_ReadBit(pin)) { \ 0000000E 2F0A MOV R16, R26 \ 00000010 .... RCALL OWI_ReadBit \ 00000012 2300 TST R16 \ 00000014 F011 BREQ ??OWI_ReceiveByte_2 244 data |= 0x80; \ 00000016 6890 ORI R25, 0x80 \ 00000018 E001 LDI R16, 1 245 } 246 } \ ??OWI_ReceiveByte_2: \ 0000001A 9583 INC R24 \ 0000001C CFF5 RJMP ??OWI_ReceiveByte_0 247 248 return data; \ ??OWI_ReceiveByte_1: \ 0000001E 2F09 MOV R16, R25 \ 00000020 E0E3 LDI R30, 3 \ 00000022 .... RJMP ?EPILOGUE_B3_L09 249 } 250 251 252 /*! \brief Sends the SKIP ROM command to the 1-Wire bus(es). 253 * 254 * \param pins A bitmask of the buses to send the SKIP ROM command to. 255 */ \ In segment CODE, align 2, keep-with-next 256 void OWI_SkipRom(unsigned char pins) \ OWI_SkipRom: 257 { \ 00000000 938A ST -Y, R24 \ 00000002 2F80 MOV R24, R16 258 // Send the SKIP ROM command on the bus. 259 OWI_SendByte(OWI_ROM_SKIP, pins); \ 00000004 2F18 MOV R17, R24 \ 00000006 EC0C LDI R16, 204 \ 00000008 .... RCALL OWI_SendByte 260 } \ 0000000A 9189 LD R24, Y+ \ 0000000C 9508 RET 261 262 263 /*! \brief Sends the READ ROM command and reads back the ROM id. 264 * 265 * \param romValue A pointer where the id will be placed. 266 * 267 * \param pin A bitmask of the bus to read from. 268 */ \ In segment CODE, align 2, keep-with-next 269 void OWI_ReadRom(unsigned char * romValue, unsigned char pin) \ OWI_ReadRom: 270 { \ 00000000 .... RCALL ?PROLOGUE4_L09 \ 00000002 01D8 MOVW R27:R26, R17:R16 \ 00000004 2F92 MOV R25, R18 271 unsigned char bytesLeft = 8; \ 00000006 E088 LDI R24, 8 272 273 // Send the READ ROM command on the bus. 274 OWI_SendByte(OWI_ROM_READ, pin); \ 00000008 2F19 MOV R17, R25 \ 0000000A E303 LDI R16, 51 \ 0000000C .... RCALL OWI_SendByte 275 276 // Do 8 times. 277 while (bytesLeft > 0) { \ ??OWI_ReadRom_0: \ 0000000E 3081 CPI R24, 1 \ 00000010 F030 BRCS ??OWI_ReadRom_1 278 // Place the received data in memory. 279 *romValue++ = OWI_ReceiveByte(pin); \ 00000012 2F09 MOV R16, R25 \ 00000014 .... RCALL OWI_ReceiveByte \ 00000016 930C ST X, R16 \ 00000018 9611 ADIW R27:R26, 1 280 bytesLeft--; \ 0000001A 958A DEC R24 \ 0000001C CFF8 RJMP ??OWI_ReadRom_0 281 } 282 } \ ??OWI_ReadRom_1: \ 0000001E E0E4 LDI R30, 4 \ 00000020 .... RJMP ?EPILOGUE_B4_L09 283 284 285 /*! \brief Sends the MATCH ROM command and the ROM id to match against. 286 * 287 * \param romValue A pointer to the ID to match against. 288 * 289 * \param pins A bitmask of the buses to perform the MATCH ROM command on. 290 */ \ In segment CODE, align 2, keep-with-next 291 void OWI_MatchRom(unsigned char * romValue, unsigned char pins) \ OWI_MatchRom: 292 { \ 00000000 .... RCALL ?PROLOGUE4_L09 \ 00000002 01D8 MOVW R27:R26, R17:R16 \ 00000004 2F92 MOV R25, R18 293 unsigned char bytesLeft = 8; \ 00000006 E088 LDI R24, 8 294 295 // Send the MATCH ROM command. 296 OWI_SendByte(OWI_ROM_MATCH, pins); \ 00000008 2F19 MOV R17, R25 \ 0000000A E505 LDI R16, 85 \ 0000000C .... RCALL OWI_SendByte 297 298 // Do once for each byte. 299 while (bytesLeft > 0) { \ ??OWI_MatchRom_0: \ 0000000E 3081 CPI R24, 1 \ 00000010 F030 BRCS ??OWI_MatchRom_1 300 // Transmit 1 byte of the ID to match. 301 OWI_SendByte(*romValue++, pins); \ 00000012 2F19 MOV R17, R25 \ 00000014 910C LD R16, X \ 00000016 .... RCALL OWI_SendByte \ 00000018 9611 ADIW R27:R26, 1 302 bytesLeft--; \ 0000001A 958A DEC R24 \ 0000001C CFF8 RJMP ??OWI_MatchRom_0 303 } 304 } \ ??OWI_MatchRom_1: \ 0000001E E0E4 LDI R30, 4 \ 00000020 .... RJMP ?EPILOGUE_B4_L09 305 306 307 /*! \brief Sends the SEARCH ROM command and returns 1 id found on the 308 * 1-Wire(R) bus. 309 * 310 * \param bitPattern A pointer to an 8 byte char array where the 311 * discovered identifier will be placed. When 312 * searching for several slaves, a copy of the 313 * last found identifier should be supplied in 314 * the array, or the search will fail. 315 * 316 * \param lastDeviation The bit position where the algorithm made a 317 * choice the last time it was run. This argument 318 * should be 0 when a search is initiated. Supplying 319 * the return argument of this function when calling 320 * repeatedly will go through the complete slave 321 * search. 322 * 323 * \param pin A bit-mask of the bus to perform a ROM search on. 324 * 325 * \return The last bit position where there was a discrepancy between slave 326 * addresses the last time this function was run. Returns OWI_ROM_SEARCH_FAILED 327 * if an error was detected (e.g. a device was connected to the bus during the 328 * search), or OWI_ROM_SEARCH_FINISHED when there are no more devices to be 329 * discovered. 330 * 331 * \note See main.c for an example of how to utilize this function. 332 */ \ In segment CODE, align 2, keep-with-next 333 unsigned char OWI_SearchRom(unsigned char * bitPattern, \ OWI_SearchRom: 334 unsigned char lastDeviation, unsigned char pin) 335 { \ 00000000 .... RCALL ?PROLOGUE9_L09 \ 00000002 REQUIRE ?Register_R4_is_cg_reg \ 00000002 REQUIRE ?Register_R5_is_cg_reg \ 00000002 REQUIRE ?Register_R6_is_cg_reg \ 00000002 REQUIRE ?Register_R7_is_cg_reg \ 00000002 REQUIRE ?Register_R8_is_cg_reg \ 00000002 0128 MOVW R5:R4, R17:R16 \ 00000004 2E82 MOV R8, R18 \ 00000006 2FB3 MOV R27, R19 336 unsigned char currentBit = 1; \ 00000008 E081 LDI R24, 1 337 unsigned char newDeviation = 0; \ 0000000A E0A0 LDI R26, 0 338 unsigned char bitMask = 0x01; \ 0000000C E091 LDI R25, 1 339 unsigned char bitA; 340 unsigned char bitB; 341 342 // Send SEARCH ROM command on the bus. 343 OWI_SendByte(OWI_ROM_SEARCH, pin); \ 0000000E 2F1B MOV R17, R27 \ 00000010 EF00 LDI R16, 240 \ 00000012 .... RCALL OWI_SendByte 344 345 // Walk through all 64 bits. 346 while (currentBit <= 64) { \ ??OWI_SearchRom_0: \ 00000014 3481 CPI R24, 65 \ 00000016 F008 BRCS $+2+2 \ 00000018 C04B RJMP ??OWI_SearchRom_1 347 // Read bit from bus twice. 348 bitA = OWI_ReadBit(pin); \ 0000001A 2F0B MOV R16, R27 \ 0000001C .... RCALL OWI_ReadBit \ 0000001E 2E60 MOV R6, R16 349 bitB = OWI_ReadBit(pin); \ 00000020 2F0B MOV R16, R27 \ 00000022 .... RCALL OWI_ReadBit \ 00000024 2E70 MOV R7, R16 350 351 if (bitA && bitB) { \ 00000026 2066 TST R6 \ 00000028 F029 BREQ ??OWI_SearchRom_2 \ 0000002A 2077 TST R7 \ 0000002C F019 BREQ ??OWI_SearchRom_2 352 // Both bits 1 (Error). 353 newDeviation = OWI_ROM_SEARCH_FAILED; \ 0000002E EFAF LDI R26, 255 354 return newDeviation; \ 00000030 2F0A MOV R16, R26 \ 00000032 C03F RJMP ??OWI_SearchRom_3 355 } else if (bitA ^ bitB) { \ ??OWI_SearchRom_2: \ 00000034 2D07 MOV R16, R7 \ 00000036 2506 EOR R16, R6 \ 00000038 2300 TST R16 \ 0000003A F071 BREQ ??OWI_SearchRom_4 356 // Bits A and B are different. All devices have the same bit here. 357 // Set the bit in bitPattern to this value. 358 if (bitA) { \ 0000003C 2066 TST R6 \ 0000003E F029 BREQ ??OWI_SearchRom_5 359 (*bitPattern) |= bitMask; \ 00000040 01F2 MOVW R31:R30, R5:R4 \ 00000042 8100 LD R16, Z \ 00000044 2B09 OR R16, R25 \ 00000046 8300 ST Z, R16 \ 00000048 C01E RJMP ??OWI_SearchRom_6 360 } else { 361 (*bitPattern) &= ~bitMask; \ ??OWI_SearchRom_5: \ 0000004A 2F09 MOV R16, R25 \ 0000004C 9500 COM R16 \ 0000004E 01F2 MOVW R31:R30, R5:R4 \ 00000050 8110 LD R17, Z \ 00000052 2310 AND R17, R16 \ 00000054 8310 ST Z, R17 \ 00000056 C017 RJMP ??OWI_SearchRom_6 362 } 363 } else { 364 // If this is where a choice was made the last time, 365 // a '1' bit is selected this time. 366 if (currentBit == lastDeviation) { \ ??OWI_SearchRom_4: \ 00000058 1588 CP R24, R8 \ 0000005A F429 BRNE ??OWI_SearchRom_7 367 (*bitPattern) |= bitMask; \ 0000005C 01F2 MOVW R31:R30, R5:R4 \ 0000005E 8100 LD R16, Z \ 00000060 2B09 OR R16, R25 \ 00000062 8300 ST Z, R16 \ 00000064 C010 RJMP ??OWI_SearchRom_6 368 } 369 370 // For the rest of the id, '0' bits are selected when 371 // discrepancies occur. 372 else if (currentBit > lastDeviation) { \ ??OWI_SearchRom_7: \ 00000066 1688 CP R8, R24 \ 00000068 F440 BRCC ??OWI_SearchRom_8 373 (*bitPattern) &= ~bitMask; \ 0000006A 2F09 MOV R16, R25 \ 0000006C 9500 COM R16 \ 0000006E 01F2 MOVW R31:R30, R5:R4 \ 00000070 8110 LD R17, Z \ 00000072 2310 AND R17, R16 \ 00000074 8310 ST Z, R17 374 newDeviation = currentBit; \ 00000076 2FA8 MOV R26, R24 \ 00000078 C006 RJMP ??OWI_SearchRom_6 375 } 376 377 // If current bit in bit pattern = 0, then this is 378 // out new deviation. 379 else if ( !(*bitPattern & bitMask)) { \ ??OWI_SearchRom_8: \ 0000007A 01F2 MOVW R31:R30, R5:R4 \ 0000007C 8100 LD R16, Z \ 0000007E 2309 AND R16, R25 \ 00000080 2300 TST R16 \ 00000082 F409 BRNE ??OWI_SearchRom_6 380 newDeviation = currentBit; \ 00000084 2FA8 MOV R26, R24 381 } 382 383 // IF the bit is already 1, do nothing. 384 else { 385 } 386 } 387 388 // Send the selected bit to the bus. 389 if ((*bitPattern) & bitMask) { \ ??OWI_SearchRom_6: \ 00000086 01F2 MOVW R31:R30, R5:R4 \ 00000088 8100 LD R16, Z \ 0000008A 2309 AND R16, R25 \ 0000008C 2300 TST R16 \ 0000008E F019 BREQ ??OWI_SearchRom_9 390 OWI_WriteBit1(pin); \ 00000090 2F0B MOV R16, R27 \ 00000092 .... RCALL OWI_WriteBit1 \ 00000094 C002 RJMP ??OWI_SearchRom_10 391 } else { 392 OWI_WriteBit0(pin); \ ??OWI_SearchRom_9: \ 00000096 2F0B MOV R16, R27 \ 00000098 .... RCALL OWI_WriteBit0 393 } 394 395 // Increment current bit. 396 currentBit++; \ ??OWI_SearchRom_10: \ 0000009A 9583 INC R24 397 398 // Adjust bitMask and bitPattern pointer. 399 bitMask <<= 1; \ 0000009C 0F99 LSL R25 400 if (!bitMask) { \ 0000009E 2399 TST R25 \ 000000A0 F009 BREQ $+2+2 \ 000000A2 CFB8 RJMP ??OWI_SearchRom_0 401 bitMask = 0x01; \ 000000A4 E091 LDI R25, 1 402 bitPattern++; \ 000000A6 E001 LDI R16, 1 \ 000000A8 0E40 ADD R4, R16 \ 000000AA E000 LDI R16, 0 \ 000000AC 1E50 ADC R5, R16 \ 000000AE CFB2 RJMP ??OWI_SearchRom_0 403 } 404 } 405 406 return newDeviation; \ ??OWI_SearchRom_1: \ 000000B0 2F0A MOV R16, R26 \ ??OWI_SearchRom_3: \ 000000B2 E0E9 LDI R30, 9 \ 000000B4 .... RJMP ?EPILOGUE_B9_L09 407 } 408 409 410 /* Functions for handling CRC */ 411 /*! \brief Compute the CRC8 value of a data set. 412 * 413 * This function will compute the CRC8 or DOW-CRC of inData using seed 414 * as inital value for the CRC. 415 * 416 * \param inData One byte of data to compute CRC from. 417 * 418 * \param seed The starting value of the CRC. 419 * 420 * \return The CRC8 of inData with seed as initial value. 421 * 422 * \note Setting seed to 0 computes the crc8 of the inData. 423 * 424 * \note Constantly passing the return value of this function 425 * As the seed argument computes the CRC8 value of a 426 * longer string of data. 427 */ \ In segment CODE, align 2, keep-with-next 428 unsigned char OWI_ComputeCRC8(unsigned char inData, unsigned char seed) \ OWI_ComputeCRC8: 429 { \ 00000000 2F30 MOV R19, R16 \ 00000002 2F01 MOV R16, R17 430 unsigned char bitsLeft; 431 unsigned char temp; 432 433 for (bitsLeft = 8; bitsLeft > 0; bitsLeft--) { \ 00000004 E018 LDI R17, 8 \ ??OWI_ComputeCRC8_0: \ 00000006 3011 CPI R17, 1 \ 00000008 F098 BRCS ??OWI_ComputeCRC8_1 434 temp = ((seed ^ inData) & 0x01); \ 0000000A 2F50 MOV R21, R16 \ 0000000C 7051 ANDI R21, 0x01 \ 0000000E 2F23 MOV R18, R19 \ 00000010 7021 ANDI R18, 0x01 \ 00000012 2725 EOR R18, R21 \ 00000014 7021 ANDI R18, 0x01 \ 00000016 2F42 MOV R20, R18 435 436 if (temp == 0) { \ 00000018 2344 TST R20 \ 0000001A F411 BRNE ??OWI_ComputeCRC8_2 437 seed >>= 1; \ 0000001C 9506 LSR R16 \ 0000001E C005 RJMP ??OWI_ComputeCRC8_3 438 } else { 439 seed ^= 0x18; \ ??OWI_ComputeCRC8_2: \ 00000020 E128 LDI R18, 24 \ 00000022 2702 EOR R16, R18 440 seed >>= 1; \ 00000024 9506 LSR R16 441 seed |= 0x80; \ 00000026 6800 ORI R16, 0x80 \ 00000028 E021 LDI R18, 1 442 } 443 444 inData >>= 1; \ ??OWI_ComputeCRC8_3: \ 0000002A 9536 LSR R19 445 } \ 0000002C 951A DEC R17 \ 0000002E CFEB RJMP ??OWI_ComputeCRC8_0 446 return seed; \ ??OWI_ComputeCRC8_1: \ 00000030 9508 RET 447 } 448 449 450 /*! \brief Compute the CRC16 value of a data set. 451 * 452 * This function will compute the CRC16 of inData using seed 453 * as inital value for the CRC. 454 * 455 * \param inData One byte of data to compute CRC from. 456 * 457 * \param seed The starting value of the CRC. 458 * 459 * \return The CRC16 of inData with seed as initial value. 460 * 461 * \note Setting seed to 0 computes the crc16 of the inData. 462 * 463 * \note Constantly passing the return value of this function 464 * As the seed argument computes the CRC16 value of a 465 * longer string of data. 466 */ \ In segment CODE, align 2, keep-with-next 467 unsigned int OWI_ComputeCRC16(unsigned char inData, unsigned int seed) \ OWI_ComputeCRC16: 468 { \ 00000000 2F50 MOV R21, R16 469 unsigned char bitsLeft; 470 unsigned char temp; 471 472 for (bitsLeft = 8; bitsLeft > 0; bitsLeft--) { \ 00000002 E048 LDI R20, 8 \ ??OWI_ComputeCRC16_0: \ 00000004 3041 CPI R20, 1 \ 00000006 F0C0 BRCS ??OWI_ComputeCRC16_1 473 temp = ((seed ^ inData) & 0x01); \ 00000008 2F12 MOV R17, R18 \ 0000000A 7011 ANDI R17, 0x01 \ 0000000C 2F05 MOV R16, R21 \ 0000000E 7001 ANDI R16, 0x01 \ 00000010 2701 EOR R16, R17 \ 00000012 7001 ANDI R16, 0x01 \ 00000014 2F60 MOV R22, R16 474 475 if (temp == 0) { \ 00000016 2366 TST R22 \ 00000018 F419 BRNE ??OWI_ComputeCRC16_2 476 seed >>= 1; \ 0000001A 9536 LSR R19 \ 0000001C 9527 ROR R18 \ 0000001E C009 RJMP ??OWI_ComputeCRC16_3 477 } else { 478 seed ^= 0x4002; \ ??OWI_ComputeCRC16_2: \ 00000020 E002 LDI R16, 2 \ 00000022 E410 LDI R17, 64 \ 00000024 2720 EOR R18, R16 \ 00000026 2731 EOR R19, R17 479 seed >>= 1; \ 00000028 9536 LSR R19 \ 0000002A 9527 ROR R18 480 seed |= 0x8000; \ 0000002C 6830 ORI R19, 0x80 \ 0000002E E001 LDI R16, 1 \ 00000030 E010 LDI R17, 0 481 } 482 483 inData >>= 1; \ ??OWI_ComputeCRC16_3: \ 00000032 9556 LSR R21 484 } \ 00000034 954A DEC R20 \ 00000036 CFE6 RJMP ??OWI_ComputeCRC16_0 485 486 return seed; \ ??OWI_ComputeCRC16_1: \ 00000038 0189 MOVW R17:R16, R19:R18 \ 0000003A 9508 RET 487 } 488 489 490 /*! \brief Calculate and check the CRC of a 64 bit ROM identifier. 491 * 492 * This function computes the CRC8 value of the first 56 bits of a 493 * 64 bit identifier. It then checks the calculated value against the 494 * CRC value stored in ROM. 495 * 496 * \param *romValue A pointer to an array holding a 64 bit identifier. 497 * 498 * \retval OWI_CRC_OK The CRC's matched. 499 * \retval OWI_CRC_ERROR Calculated and stored CRC did not match. 500 */ \ In segment CODE, align 2, keep-with-next 501 unsigned char OWI_CheckRomCRC(unsigned char *romValue) \ OWI_CheckRomCRC: 502 { \ 00000000 .... RCALL ?PROLOGUE4_L09 \ 00000002 01D8 MOVW R27:R26, R17:R16 503 unsigned char i; 504 unsigned char crc8 = 0; \ 00000004 E090 LDI R25, 0 505 506 for (i = 0; i < 7; i++) { \ 00000006 E080 LDI R24, 0 \ ??OWI_CheckRomCRC_0: \ 00000008 3087 CPI R24, 7 \ 0000000A F440 BRCC ??OWI_CheckRomCRC_1 507 crc8 = OWI_ComputeCRC8(*romValue, crc8); \ 0000000C 2F19 MOV R17, R25 \ 0000000E 01FD MOVW R31:R30, R27:R26 \ 00000010 8100 LD R16, Z \ 00000012 .... RCALL OWI_ComputeCRC8 \ 00000014 2F90 MOV R25, R16 508 romValue++; \ 00000016 9611 ADIW R27:R26, 1 509 } \ 00000018 9583 INC R24 \ 0000001A CFF6 RJMP ??OWI_CheckRomCRC_0 510 511 if (crc8 == (*romValue)) { \ ??OWI_CheckRomCRC_1: \ 0000001C 910C LD R16, X \ 0000001E 1790 CP R25, R16 \ 00000020 F411 BRNE ??OWI_CheckRomCRC_2 512 return OWI_CRC_OK; \ 00000022 E000 LDI R16, 0 \ 00000024 C001 RJMP ??OWI_CheckRomCRC_3 513 } 514 515 return OWI_CRC_ERROR; \ ??OWI_CheckRomCRC_2: \ 00000026 E001 LDI R16, 1 \ ??OWI_CheckRomCRC_3: \ 00000028 E0E4 LDI R30, 4 \ 0000002A .... RJMP ?EPILOGUE_B4_L09 516 } Maximum stack usage in bytes: Function CSTACK RSTACK -------- ------ ------ OWI_CheckRomCRC 4 2 -> OWI_ComputeCRC8 4 2 OWI_ComputeCRC16 0 2 OWI_ComputeCRC8 0 2 OWI_DetectPresence 0 2 OWI_Init 0 2 OWI_MatchRom 4 2 -> OWI_SendByte 4 2 -> OWI_SendByte 4 2 OWI_ReadBit 0 2 OWI_ReadRom 4 2 -> OWI_SendByte 4 2 -> OWI_ReceiveByte 4 2 OWI_ReceiveByte 3 2 -> OWI_ReadBit 3 2 OWI_SearchRom 9 2 -> OWI_SendByte 9 2 -> OWI_ReadBit 9 2 -> OWI_ReadBit 9 2 -> OWI_WriteBit1 9 2 -> OWI_WriteBit0 9 2 OWI_SendByte 4 2 -> OWI_WriteBit1 4 2 -> OWI_WriteBit0 4 2 OWI_SkipRom 1 2 -> OWI_SendByte 1 2 OWI_WriteBit0 0 2 OWI_WriteBit1 0 2 Segment part sizes: Function/Label Bytes -------------- ----- _A_PORTA 1 _A_DDRA 1 _A_PINA 1 OWI_Init 34 OWI_WriteBit1 62 OWI_WriteBit0 62 OWI_ReadBit 78 OWI_DetectPresence 88 OWI_SendByte 42 OWI_ReceiveByte 36 OWI_SkipRom 14 OWI_ReadRom 34 OWI_MatchRom 34 OWI_SearchRom 182 OWI_ComputeCRC8 50 OWI_ComputeCRC16 60 OWI_CheckRomCRC 44 3 bytes in segment ABSOLUTE 820 bytes in segment CODE 820 bytes of CODE memory 0 bytes of DATA memory (+ 3 bytes shared) Errors: none Warnings: none