Advertisement
creamygoat

Chime Transmitter

Dec 18th, 2014
503
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 112.76 KB | None | 0 0
  1. ;-------------------------------------------------------------------------------
  2. ; Transmitter.S - ATtiny85 dual sensor gate buzzer/doorbell transmitter
  3. ;-------------------------------------------------------------------------------
  4. ;
  5. ; Author: Daniel Neville (creamygoat@gmail.com)
  6. ; Date: 19 December 2014
  7. ; Licence: Public domain
  8. ; Version: 1.0
  9. ;
  10. ; This transmitter reports the combined status of its two sensor inputs to
  11. ; one or more receivers which have been taught the secret AES-CMAC key by
  12. ; the transmitter.
  13. ;
  14. ; In addition to the state of the sensors, a pair of sound indices, one for
  15. ; each sensor, is transmitted with the state. Thus the user can know which
  16. ; sensor is activated or deactivated. The transmitter's Sound Select buttons,
  17. ; one for each sensor, allow the user to cycle through the available sounds
  18. ; to be associated with that sensor.
  19. ;
  20. ; The transmission of the secret key is protected by a shared key unless the
  21. ; self-timer is activated with a long press of the Teach button. (This is
  22. ; useful if the shared key in EEPROM is corrupted.)
  23. ;
  24. ; By default, sensors with normally closed contacts are assumed. A long press
  25. ; of a Sound Select button inverts the sense of the contacts for the sensor
  26. ; associated with that button so that sensors with normally open contacts may
  27. ; be used.
  28. ;
  29. ; A very long press of a Sound Select button activates Pinging Mode to assist
  30. ; with the estimation of the transmitter's range. Pinging Mode stops when a
  31. ; button is pressed or after ten minutes of pinging.
  32. ;
  33. ; The transmitter harvests entropy from the timing of changes of button and
  34. ; sensor states, slowly mutating random data both in EEPROM and in SRAM.
  35. ; This data is used to generate the secret AES-CMAC key and the lower 12
  36. ; bits of the transmitter's serial number when the Teach button is pressed.
  37. ; Further randomisation of the secret key for successive Teach transmissions
  38. ; is suppressed until a Sound Select button is pressed or the power is
  39. ; disconnected.
  40. ;
  41. ; The 128 bit (super-secret) shared key used to protect the secret AES-CMAC key
  42. ; transfer to one or more chimes in Learn Mode is stored in EEPROM at addresses
  43. ; 2 to 17 inclusive. The rest of the EEPROM need not be initalised to any
  44. ; particular value.
  45. ;
  46. ; Weak pullups are provided on the sensor inputs.
  47. ;
  48. ; PIN ASSIGNMENT
  49. ; ____
  50. ; ~RESET 1| AT |8 Vcc
  51. ; SENSOR1 2|tiny|7 ADCBUTTONS
  52. ; SENSOR2 3| 85 |6 ACTIVITYLED
  53. ; GND 4|____|5 RADIOTX
  54. ;
  55. ; ADC BUTTON WIRING
  56. ;
  57. ; Vcc -----*---------------------------
  58. ; |
  59. ; R4 [ ]
  60. ; |
  61. ; *---------*---------*------> ADCBUTTONS
  62. ; | | |
  63. ; R3 [ ] R2 [ ] R1 [ ]
  64. ; | | | R1 = 6.8k ohms
  65. ; | o | o | o R2 = 1.8k ohms
  66. ; TEACH [| SS2 [| SS1 [| R3 = 220 ohms
  67. ; | o | o | o R4 = 3.0k ohms or 3.3k ohms
  68. ; | | |
  69. ; GND -----*---------*---------*------
  70. ;
  71. ;
  72. ; BUTTON FUNCTIONS
  73. ;
  74. ; Button Label Press Action
  75. ;
  76. ; TEACH TEACH/DELAYED Short Generate a new secret key and transmit the
  77. ; key to one or more chimes in Learn Mode.
  78. ; The secret key is encrypted with the fixed,
  79. ; super-secret shared key.
  80. ;
  81. ; Long Generate and transmit without encryption
  82. ; a new secret key after about ten seconds.
  83. ; The activity LED will flash in the manner
  84. ; of a camera's self timer.
  85. ;
  86. ; SS1 SOUND1/INVERT1 Short Select the next sound (or set of sounds)
  87. ; for the primary sensor. Some sound sets
  88. ; include activation, deactivation and
  89. ; prolonged activation reminder sounds.
  90. ; Others have just an activation sound.
  91. ;
  92. ; Long Switch between normally open or normally
  93. ; closed contacts for the primary sensor.
  94. ;
  95. ; Extended Activate pinging mode to assist with
  96. ; radio range estimation.
  97. ;
  98. ; SS2 SOUND2/INVERT2 Short Select the next sound (or set of sounds)
  99. ; for the secondary sensor.
  100. ;
  101. ; Long Switch between normally open or normally
  102. ; closed contacts for the secondary sensor.
  103. ;
  104. ; Extended Activate pinging mode to assist with
  105. ; radio range estimation.
  106. ;
  107. ; TRANSMITTED MESSAGES
  108. ; _ _
  109. ; The data is Manchester encoded so that 0 = |_ and 1 = _| . The leader pulses
  110. ; prime the automatic gain control of the receiver and the Manchester-violating
  111. ; synchronisation pattern low 3, high 3, low 1 appended with a Manchester
  112. ; encoded 1 indicates the beginning of data. Each data byte is transmitted
  113. ; MSB first and with a following parity bit so that the parity of all nine bits
  114. ; is even. There is no special data terminator: The receiver stops listening
  115. ; once the middle of the last Manchester encoded bit (a parity bit) is received
  116. ; and the transmission level can be held low the instant the last encoded bit
  117. ; is sent.
  118. ;
  119. ; _ _ _ ___ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
  120. ; ..._| |_| |_| |___| |__| :_|_:_|_:_|_:_|_:_|_:_|_:_|_:_|_:_|_:_|_:_|_:...
  121. ; Leader | Synch | 7 6 5 4 3 2 1 0 P | 7 6
  122. ; | | First byte and even parity bit |
  123. ;
  124. ; Command message (14 bytes):
  125. ; Serial number (4 bytes, big-endian)
  126. ; Sequence number (4 bytes, big-endian)
  127. ; Command (1 byte)
  128. ; Parameter (1 byte)
  129. ; CMAC (first 4 bytes of the chained cipher in column-major format)
  130. ;
  131. ; Commands:
  132. ; Command Parameter
  133. ; 000000vu jjjjiiii Sensor states u & v, sound sets i & j
  134. ; 000001qz 0000iiii Sound test for sensor q in state z, sound set i
  135. ; 000010qx 000000kk Special sound k for sensor q
  136. ; k = 0 for +sense, 1 for -sense, 2 for ping
  137. ;
  138. ; Teach message (28 bytes):
  139. ; Serial number (4 bytes, big-endian)
  140. ; Sequence number (4 bytes, big-endian)
  141. ; Auxiliary data (2 bytes) - bit 0 of the 2nd byte set => key is unencrypted
  142. ; CMAC Key (16 bytes, column major)
  143. ; CRC-CCITT (2 bytes, big-endian so that the CRC of all 28 bytes is zero.)
  144. ;
  145. ; EXAMPLE EEPROM IMAGE
  146. ;
  147. /*
  148. :200000002FFF337C8BE33D17576A5F7D06C8FF7677BABC1A0000FFFFB68BEB75C758988D77
  149. :200020002469350721BCFB2FDC0C8C273C16DD4A1150C91A6CBB33AB6F2172C965085C827D
  150. :20004000E158A879C609FB9FCEB98FBB7CE90DB17EFF9C5477DEE447AF92F534995D0C810F
  151. :200060001C1DC1F84F584982777777777777777777777777777777777777777777777777F4
  152. :20008000777777777777777777777777777777777777777777777777777777777777777780
  153. :2000A0007777777777777777777777777777777777777777777777771100000011000000F6
  154. :2000C000110000001100000011000000110000001100000011000000110000001100000098
  155. :2000E000110000001100000011000000110000001100000011000000110000001100000078
  156. :20010000110000001100000011000000110000001100000011000000110000001100000057
  157. :20012000110000001100000011000000110000001100000011000000110000001100000037
  158. :20014000110000001100000011000000110000001100000011000000110000001100000017
  159. :200160001100000011000000110000001100000011000000110000001100000011000000F7
  160. :200180001100000011000000110000001100000011000000110000001100000011000000D7
  161. :2001A0001100000011000000110000001100000011000000110000001100000011000000B7
  162. :2001C000110000001100000011000000110000001100000011000000110000001100000097
  163. :2001E000110000001100000011000000110000001100000011000000FFFFFFFFFFFFFFFFA1
  164. :00000001FF
  165. */
  166. ;
  167. ;-------------------------------------------------------------------------------
  168. ; Notes
  169. ;-------------------------------------------------------------------------------
  170. ;
  171. ; Fuses:
  172. ; Low fuse: 0xe2 (4:SUT0, 3-0:CKSEL=8MHz)
  173. ; High fuse: 0xdf (5:SPIEN) 0xd7 (6:SPIEN, 3:EESAVE)
  174. ; Extended fuse: 0xff
  175. ;
  176. ; Fuse programming
  177. ; avrdude -p t85 -c usbasp -U lfuse:w:0xe2:m
  178. ; avrdude -p t85 -c usbasp -U hfuse:w:0xd7:m
  179. ; avrdude -p t85 -c usbasp -U efuse:w:0xfe:m
  180. ;
  181. ; Compiling, inspecting and programming:
  182. ;
  183. ; avr-gcc -mmcu=attiny85 -o Transmitter.o Transmitter.S
  184. ; avr-objdump -C -d Transmitter.o
  185. ; avr-ld -o Transmitter.elf Transmitter.o
  186. ; avr-objcopy -O ihex Transmitter.elf Transmitter.hex
  187. ; avrdude -p t85 -c usbasp -U flash:w:Transmitter.hex:i
  188. ; avrdude -p t85 -c usbasp -U eeprom:w:Transmitter.eep:i
  189. ;
  190. ; Key generation:
  191. ;
  192. ; head </dev/random -c 16|hexdump -v -e '/1 "%02X"'; echo
  193. ;
  194. ;-------------------------------------------------------------------------------
  195.  
  196.  
  197. ; Imports
  198. ; Exports
  199. ; Constants
  200. ; Structures
  201. ; EEPROM addresses
  202. ; Macros
  203. ;
  204. ; Interrupt handlers
  205. ;
  206. ; Basic routines
  207. ; Xor16B
  208. ; Copy16B
  209. ; Copy8B
  210. ; DelayNCycles
  211. ; Delay10Cycles
  212. ; Delay8Cycles
  213. ; CalculateCRC_CCITT
  214. ; DebounceSensor
  215. ;
  216. ; EEPROM routines
  217. ; ReadEEPROMByte
  218. ; ReadEEPROMBlock
  219. ; WriteEEPROMByte
  220. ; WriteEEPROMBlock
  221. ;
  222. ; AES routines
  223. ; AES_SubstituteAndShift
  224. ; AES_MixColumn
  225. ; AES_AdvanceRoundKey
  226. ; AES_AdvanceCMACSubKey
  227. ; AES_Encrypt
  228. ;
  229. ; Application routines
  230. ; FindCurrentEWLDataSlot
  231. ; LazilyUpdateEWLData
  232. ; FullyUpdateEWLData
  233. ; MutateRandomData
  234. ; RandomiseCMACKey
  235. ; BuildTeachMessage
  236. ;
  237. ; Initialisation
  238. ; InitialiseRegisterConstants
  239. ; InitialiseHardware
  240. ; ClearGlobals
  241. ; LoadEverythingFromEEPROM
  242. ;
  243. ; main
  244. ; main_Loop
  245. ; main_Synchronise
  246. ; main_Update32kHzCounter
  247. ; main_UpdateTransmitPin
  248. ; main_TimeShare32By8
  249. ; main_T0_TransmitPacket
  250. ; main_TxState_Idle
  251. ; main_TxState_Begin
  252. ; main_TxState_Sync
  253. ; main_TxState_Data
  254. ; main_TxState_Data_Bit
  255. ; main_TxState_Data_Parity
  256. ; main_TxState_Data_ModulateBit
  257. ; main_TxState_Terminator
  258. ; main_TxState_Rest
  259. ; main_Tx_BufferMarkSpace
  260. ; main_T1_Authentication
  261. ; main_AES_Mixcolumn
  262. ; main_AES_SubAndShift
  263. ; main_AES_AddRoundKey
  264. ; main_AES_AdvanceRoundKey
  265. ; main_AES_AdvanceRoundKey_RudeEntryForRound10
  266. ; main_AES_StartEncryption
  267. ; main_AES_IdleOrStartAES
  268. ; main_AES_Idle
  269. ; main_Auth_Idle
  270. ; main_Auth_CmdMsg_XorK2
  271. ; main_Auth_CmdMsg_LoadK
  272. ; main_Auth_K2_Begin
  273. ; main_Auth_K2_Clear
  274. ; main_AES_Finished
  275. ; main_Auth_K2_GenK1
  276. ; main_Auth_K2_GenK2
  277. ; main_Auth_End
  278. ; main_Auth_CmdMsg_Begin
  279. ; main_Auth_CmdMsg_WriteCMAC
  280. ; main_Copy16BAndLoop
  281. ; main_T2_TeachAndSoundSelectTasks
  282. ; main_T2_TASSTasks_T0_ADCInputAndTASSTimers
  283. ; main_T2_TASSTasks_T1_ButtonLogic
  284. ; main_T2_TASSTasks_T2_SaveAndTransmit
  285. ; main_T2_TASSTasks_T3
  286. ; main_T3_SensorInputConditioningAndEntropyHarvesting
  287. ; main_T4_SensorStateTxBurstsAndEWLUpdates
  288. ; main_T5_RefreshEEPROM
  289. ; main_T6
  290. ; main_T7
  291. ;
  292. ; Data in program memory
  293. ;
  294. ; PM_AES_SBox
  295. ;
  296. ; Globals in SRAM
  297. ; TxRunLengthsRingBuffer
  298. ; AES_Matrix_M
  299. ; AES_Matrix_K
  300. ; AES_Matrix_W
  301. ; AuthenticationData
  302. ; EWLState
  303. ; EntropyHarvester
  304.  
  305.  
  306. ;-------------------------------------------------------------------------------
  307. ; Imports
  308. ;-------------------------------------------------------------------------------
  309.  
  310.  
  311. #include <avr/common.h>
  312. #include <avr/io.h>
  313.  
  314.  
  315. ;-------------------------------------------------------------------------------
  316. ; Exports
  317. ;-------------------------------------------------------------------------------
  318.  
  319.  
  320. .global main
  321. .global __vector_default
  322.  
  323.  
  324. ;-------------------------------------------------------------------------------
  325. ; Constants
  326. ;-------------------------------------------------------------------------------
  327.  
  328.  
  329. ; Inputs and outputs
  330. OUTPUT_BIT_RADIO = 0
  331. OUTPUT_BIT_ACTIVITY_LED = 1
  332. INPUT_BIT_BUTTONS = 2
  333. INPUT_BIT_PRIMARY_SENSOR = 3
  334. INPUT_BIT_SECONDARY_SENSOR = 4
  335. BUTTONS_DIGITAL_INPUT_DISABLE_BIT = ADC1D; ADC1 is on Port B bit 2 (pin 7).
  336. BUTTONS_ADC_MUX_SELECTOR = 0b0001 ; 00xx = ADCn in single-ended mode.
  337.  
  338. ; Sensor debounce times in quarter-milliseconds, up to 127 (31.75ms)
  339. SENSOR_DB_DELAY_CONTACTS_CLOSED = 234 ; 60ms
  340. SENSOR_DB_DELAY_CONTACTS_OPEN = 156 ; 40ms
  341. ; Button debounce times in milliseconds, up to 255 (0.255 seconds)
  342. BUTTON_DB_DELAY_ADC = 65 ; 65ms
  343.  
  344. ; Teach and Sound Select times in multiples of 64 milliseconds
  345. TEACH_BUTTON_LONG_PRESS_TIME = 31 ; 2 seconds
  346. SOUND_SELECT_BUTTON_LONG_PRESS_TIME = 47 ; 3 seconds
  347. SOUND_SELECT_BUTTON_VERY_LONG_PRESS_TIME = 125 ; 8 seconds
  348. ACTIVATION_SOUND_TO_DEACTIVATION_SOUND_DELAY = 31 ; 2 seconds
  349. SENSE_INVERSION_DELAY = 23 ; 1.5 seconds
  350. PING_START_DELAY = 16 ; 1 second
  351. PING_INTERVAL_DOUBLED = 125 ; 8 seconds (a ping every 4 seconds)
  352.  
  353. ; Transmitter signal timing in 32kHz ticks
  354. TX_TIME_UNIT = 4 ; Minimum is 4, good for 8000 baud
  355. TX_RLB_REST_TIME = 240; Last entry to put in the run length buffer
  356. TX_TASK_REST_TIME = 200; 50ms in 4kHz ticks
  357. TX_NUMBER_OF_LEADER_PULSES = 24
  358.  
  359. ; Ring buffer for run lengths of the transmit pin state
  360. TX_RING_BUFFER_INDEX_BITS = 4
  361. TX_RING_BUFFER_INDEX_RANGE = 1 << TX_RING_BUFFER_INDEX_BITS
  362. TX_RING_BUFFER_INDEX_MASK = TX_RING_BUFFER_INDEX_RANGE - 1
  363.  
  364. ; Transmitter state
  365. TX_STATE_IDLE = 0
  366. TX_STATE_BEGIN = 1
  367. TX_STATE_SYNC = 2
  368. TX_STATE_DATA = 3
  369. TX_STATE_TERMINATOR = 4
  370. TX_STATE_REST = 5
  371.  
  372. ; State for AES-CMAC message authenticator
  373. AUTH_STATE_IDLE = 0
  374. AUTH_STATE_CMDMSG_BEGIN = 1
  375. AUTH_STATE_CMDMSG_LOAD_K = 2
  376. AUTH_STATE_CMDMSG_XOR_K2 = 3
  377. AUTH_STATE_CMDMSG_CMAC = 4
  378. AUTH_STATE_K2_BEGIN = 5
  379. AUTH_STATE_K2_CLEAR = 6
  380. AUTH_STATE_K2_GEN_K1 = 7
  381. AUTH_STATE_K2_GEN_K2 = 8
  382.  
  383. ; Important states for AES encrpytion
  384. AES_STATE_IDLE = 0xFF
  385. AES_STATE_BEGIN = 0xA2
  386. AES_STATE_FINISHED = 0x00
  387.  
  388. ; Task flag bits, set 1
  389. bTASK1_SEND_CMD_MESSAGE = 0
  390. bTASK1_SEND_TEACH_MESSAGE = 1
  391. bTASK1_SAVE_SOUND_INDICES = 2
  392. bTASK1_SEND_PRIMARY_SOUND_A = 4
  393. bTASK1_SEND_PRIMARY_SOUND_B = 5
  394. bTASK1_SEND_SECONDARY_SOUND_A = 6
  395. bTASK1_SEND_SECONDARY_SOUND_B = 7
  396.  
  397. ; Task flag masks, set 1
  398. mTASK1_SEND_CMD_MESSAGE = 1 << bTASK1_SEND_CMD_MESSAGE
  399. mTASK1_SEND_TEACH_MESSAGE = 1 << bTASK1_SEND_TEACH_MESSAGE
  400. mTASK1_SAVE_SOUND_INDICES = 1 << bTASK1_SAVE_SOUND_INDICES
  401. mTASK1_SEND_PRIMARY_SOUND_A = 1 << bTASK1_SEND_PRIMARY_SOUND_A
  402. mTASK1_SEND_PRIMARY_SOUND_B = 1 << bTASK1_SEND_PRIMARY_SOUND_B
  403. mTASK1_SEND_SECONDARY_SOUND_A = 1 << bTASK1_SEND_SECONDARY_SOUND_A
  404. mTASK1_SEND_SECONDARY_SOUND_B = 1 << bTASK1_SEND_SECONDARY_SOUND_B
  405.  
  406. ; Task flag bits, set 2
  407. bTASK2_SEND_PRIMARY_SENSE_NORMAL = 0
  408. bTASK2_SEND_PRIMARY_SENSE_INVERTED = 1
  409. bTASK2_SEND_SECONDARY_SENSE_NORMAL = 2
  410. bTASK2_SEND_SECONDARY_SENSE_INVERTED = 3
  411. bTASK2_SAVE_SENSOR_ACTIVATION_SENSES = 4
  412. bTASK2_SEND_PING = 5
  413.  
  414. ; Task flag masks, set 2
  415. mTASK2_SEND_PRIMARY_SENSE_NORMAL = 1 << bTASK2_SEND_PRIMARY_SENSE_NORMAL
  416. mTASK2_SEND_PRIMARY_SENSE_INVERTED = 1 << bTASK2_SEND_PRIMARY_SENSE_INVERTED
  417. mTASK2_SEND_SECONDARY_SENSE_NORMAL = 1 << bTASK2_SEND_SECONDARY_SENSE_NORMAL
  418. mTASK2_SEND_SECONDARY_SENSE_INVERTED = 1 << bTASK2_SEND_SECONDARY_SENSE_INVERTED
  419. mTASK2_SAVE_SENSOR_ACTIVATION_SENSES = 1 << bTASK2_SAVE_SENSOR_ACTIVATION_SENSES
  420. mTASK2_SEND_PING = 1 << bTASK2_SEND_PING
  421.  
  422. ; Slow clock bits
  423. bCLOCK_CMD_MSG_BURST = 0
  424. bCLOCK_TASS = 1
  425. bCLOCK_EEPROM_REFRESH = 2
  426.  
  427. ; Teach and Sound Select states
  428. TASS_STATE_IDLE = 0
  429. TASS_STATE_TEACH_PRESSED = 1
  430. TASS_STATE_TEACH_LONG_PRESSED = 2
  431. TASS_STATE_DELAYED_TEACH = 3
  432. TASS_STATE_SILLY_WALK_FOR_PING = 4
  433. TASS_STATE_PINGING = 5
  434. TASS_STATE_WAIT_FOR_RELEASE = 6
  435.  
  436. ; Entropy harvesting data mutation
  437. ; 6 bits for the mutation index is the minimum needed to maintain the purity
  438. ; of the CMAC key and to provide auxiliary random data.
  439. EH_MUTATION_INDEX_BITS = 6
  440. EH_MUTATION_INDEX_RANGE = 1 << EH_MUTATION_INDEX_BITS
  441. EH_MUTATION_INDEX_MASK = EH_MUTATION_INDEX_RANGE - 1
  442. EH_MUTATION_INDEX_ADVANCE = 23
  443. EH_AUX_RANDOM_DATA_START_INDEX = 32 ; Clear of the CMAC stuff.
  444. EH_UPDATE_INDEX_ADVANCE = 1
  445. EH_UPDATE_COUNTER_BITS = 1
  446.  
  447. ; EEPROM wear levelling
  448. EWL_COUNTS_BETWEEN_WRITES = 8
  449. EWL_INDEX_RANGE = 80
  450. EWL_DATA_SLOT_SIZE = 4
  451. EWL_DATA_RING_SIZE = EWL_INDEX_RANGE * EWL_DATA_SLOT_SIZE
  452.  
  453.  
  454. ;-------------------------------------------------------------------------------
  455. ; Structures
  456. ;-------------------------------------------------------------------------------
  457.  
  458.  
  459. ; Command message (big endian)
  460. CmdMsg_SerialNumber = 0
  461. CmdMsg_SequenceNumber = 4
  462. CmdMsg_Command = 8
  463. CmdMsg_Parameter = 9
  464. CmdMsg_CMAC = 10
  465. CmdMsgSize = 14
  466.  
  467. ; Teach message (big-endian)
  468. TeachMsg_SerialNumber = 0
  469. TeachMsg_SequenceNumber = 4
  470. TeachMsg_AuxData = 8
  471. TeachMsg_EncryptedCMACKey = 10
  472. TeachMsg_MessageCRC = 26
  473. TeachMsgSize = 28
  474.  
  475. ; Packet size constants
  476. TX_COMMAND_PACKET_LENGTH = CmdMsgSize
  477. TX_TEACH_PACKET_LENGTH = TeachMsgSize
  478. .ifgt TX_TEACH_PACKET_LENGTH - TX_COMMAND_PACKET_LENGTH
  479. TX_MAX_PACKET_LENGTH = TeachMsgSize
  480. .else
  481. TX_MAX_PACKET_LENGTH = CmdMsgSize
  482. .endif
  483.  
  484.  
  485. ; Transmit run length buffer state
  486. TxBit_HeadIx = 0
  487. TxBit_TailIx = 1
  488. TxBitSize = 2
  489.  
  490. ;Transmitter
  491. Tx_State = 0
  492. Tx_Counter = 1
  493. Tx_NumBytesSent = 2
  494. Tx_NumBytesToSend = 3
  495. Tx_Parity = 4
  496. Tx_ShiftRegister = 5
  497. Tx_TxBit = 6
  498. Tx_Data = Tx_TxBit + TxBitSize
  499. TxSize = Tx_Data + TX_MAX_PACKET_LENGTH
  500.  
  501. ; EEPROM wear levelling state (kept in SRAM)
  502. EWLS_SlotIndex = 0
  503. EWLS_SlotValue = 1
  504. EWLS_UpdateCountdown = 2
  505. EWLS_NumBytesToWrite = 3
  506. EWLS_NewSequenceNumber = 4
  507. EWLSSize = 8
  508.  
  509. ; Entropy harvester
  510. EH_MutationIndex = 0
  511. EH_MutationCounter = 1
  512. EH_EEPROMUpdateIndex = 2
  513. EH_EEPROMUpdatePending = 3
  514. EH_RandomData = 4
  515. EHSize = EH_RandomData + EH_MUTATION_INDEX_RANGE
  516.  
  517. ; Authentication data
  518. AD_SerialNumber = 0
  519. AD_SequenceNumber = 4
  520. AD_CMACKey = 8
  521. AD_CMACSubkeyK2 = 24
  522. AD_HaveK2 = 40
  523. ADSize = 41
  524.  
  525. ; Analogue to Digital Converter buttons
  526. ADCB_MutexState = 0
  527. ADCB_State = 1
  528. ADCB_ProvisionalState = 2
  529. ADCB_AcceptanceCountdown = 3
  530. ADCBSize = 4
  531.  
  532. ; Teach and sound select buttons
  533. TASS_TeachOrPingState = 0
  534. TASS_LastButtonsState = 1
  535. TASS_LongPressCountdown = 2
  536. TASS_NewSensorActivationSenses = 3
  537. TASS_Sensor1InversionCountdown = 4
  538. TASS_Sensor2InversionCountdown = 5
  539. TASS_SS1LongPressCountdown = 6
  540. TASS_SS2LongPressCountdown = 7
  541. TASS_PrimarySoundTestCountdown = 8
  542. TASS_SecondarySoundTestCountdown = 9
  543. TASS_NumTeachMessagesToSend = 10
  544. TASS_SuppressKeyRandomisation = 11
  545. TASS_SuppressKeyEncryption = 12
  546. TASS_NumPingsToSend = 13
  547. TASS_PingIntervalCountdown = 14
  548. TASSSize = 15
  549.  
  550. ; Globals
  551. G_CurrentTimer0Match = 0
  552. G_SlowClocks = 1
  553. G_SoundIndices = 2
  554. G_SensorActivationSenses = 3
  555. G_TaskFlags1 = 4
  556. G_TaskFlags2 = 5
  557. G_PrimarySensorIntegral = 6
  558. G_SecondarySensorIntegral = 7
  559. G_SensorsState = 8
  560. G_TransmittedSensorsState = 9
  561. G_AuthenticationState = 10
  562. G_AESState = 11
  563. G_AESRoundConstantByte = 12
  564. G_LastADCButtonsState = 13
  565. G_CmdTxDelayRandomByte = 14
  566. G_CmdTxNumRepeatsToSend = 15
  567. G_CmdTxRepeatSchedule = 16
  568. G_EEPROMRefreshCounter = G_CmdTxRepeatSchedule + 8
  569. G_ADCButtons = G_EEPROMRefreshCounter + 2
  570. G_EWLState = G_ADCButtons + ADCBSize
  571. G_Transmitter = G_EWLState + EWLSSize
  572. GSize = G_Transmitter + TxSize
  573.  
  574.  
  575. ;-------------------------------------------------------------------------------
  576. ; EEPROM addresses
  577. ;-------------------------------------------------------------------------------
  578.  
  579.  
  580. EEPROM_InvSoundIndices = 0
  581. EEPROM_SensorActivationSenses = 1
  582. EEPROM_SharedKey = 2
  583. EEPROM_SerialNumber = 18
  584. EEPROM_CMACKey = 24
  585. EEPROM_RandomData = 40
  586. EEPROM_EWLStatusRing = EEPROM_RandomData + EH_MUTATION_INDEX_RANGE
  587. EEPROM_EWLDataRing = EEPROM_EWLStatusRing + EWL_INDEX_RANGE
  588. EEPROM_EWLDataRingEnd = EEPROM_EWLDataRing + EWL_DATA_RING_SIZE
  589. EEPROM_End = EEPROM_EWLDataRingEnd
  590.  
  591.  
  592. .ifgt EEPROM_End - 512
  593. .error "There is not enough space in the EEPROM."
  594. .endif
  595.  
  596.  
  597. ;-------------------------------------------------------------------------------
  598. ; Macros
  599. ;-------------------------------------------------------------------------------
  600.  
  601.  
  602. ; Conditional execution of the following one-word instruction
  603.  
  604. .macro ifcc
  605. brcs . + 2
  606. .endm
  607. .macro ifcs
  608. brcc . + 2
  609. .endm
  610. .macro ifne
  611. breq . + 2
  612. .endm
  613. .macro ifeq
  614. brne . + 2
  615. .endm
  616. .macro ifpl
  617. brmi . + 2
  618. .endm
  619. .macro ifmi
  620. brpl . + 2
  621. .endm
  622. .macro ifvc
  623. brvs . + 2
  624. .endm
  625. .macro ifvs
  626. brvc . + 2
  627. .endm
  628. .macro iflt
  629. brge . + 2
  630. .endm
  631. .macro ifge
  632. brlt . + 2
  633. .endm
  634. .macro ifhc
  635. brhs . + 2
  636. .endm
  637. .macro ifhs
  638. brhc . + 2
  639. .endm
  640. .macro iftc
  641. brts . + 2
  642. .endm
  643. .macro ifts
  644. brtc . + 2
  645. .endm
  646. .macro ifid
  647. brie . + 2
  648. .endm
  649. .macro ifie
  650. brid . + 2
  651. .endm
  652. .macro iflo
  653. brsh . + 2
  654. .endm
  655. .macro ifsh
  656. brlo . + 2
  657. .endm
  658. .macro ifbs
  659. brbc . + 2
  660. .endm
  661. .macro ifbc
  662. brbs . + 2
  663. .endm
  664.  
  665.  
  666. ;-------------------------------------------------------------------------------
  667.  
  668.  
  669. ; Positive-sense register and I/O bit tests
  670.  
  671. .macro ifbrc a:req, b:req
  672. sbrs \a, \b
  673. .endm
  674. .macro ifbrs a:req, b:req
  675. sbrc \a, \b
  676. .endm
  677. .macro ifbic a:req, b:req
  678. sbis \a, \b
  679. .endm
  680. .macro ifbis a:req, b:req
  681. sbic \a, \b
  682. .endm
  683.  
  684.  
  685. ;-------------------------------------------------------------------------------
  686.  
  687.  
  688. ; Load high & low 8-bit registers with one 16-bit word
  689.  
  690. .macro ldhl a:req, b:req, c:req
  691. ldi \b, lo8(\c)
  692. ldi \a, hi8(\c)
  693. .endm
  694.  
  695.  
  696. ;-------------------------------------------------------------------------------
  697.  
  698.  
  699. ; Load immediate word
  700.  
  701. .macro ldiw a:req, b:req
  702. .ifc \a, r17:r16
  703. ldhl r17, r16, \b
  704. .else
  705. .ifc \a, r19:r18
  706. ldhl r19, r18, \b
  707. .else
  708. .ifc \a, r21:r20
  709. ldhl r21, r20, \b
  710. .else
  711. .ifc \a, r23:r22
  712. ldhl r23, r22, \b
  713. .else
  714. .ifc \a, r25:r24
  715. ldhl r25, r24, \b
  716. .else
  717. .ifc \a, r27:r26
  718. ldhl XH, XL, \b
  719. .else
  720. .ifc \a, r29:r28
  721. ldhl YH, YL, \b
  722. .else
  723. .ifc \a, r31:r30
  724. ldhl ZH, ZL, \b
  725. .else
  726. .ifc \a, X
  727. ldhl XH, XL, \b
  728. .else
  729. .ifc \a, Y
  730. ldhl YH, YL, \b
  731. .else
  732. .ifc \a, Z
  733. ldhl ZH, ZL, \b
  734. .else
  735. .error "Expected LDIW R, x where R is X, Y, Z or a register pair."
  736. .endif
  737. .endif
  738. .endif
  739. .endif
  740. .endif
  741. .endif
  742. .endif
  743. .endif
  744. .endif
  745. .endif
  746. .endif
  747. .endm
  748.  
  749.  
  750. ;-------------------------------------------------------------------------------
  751. .section .text
  752. ;-------------------------------------------------------------------------------
  753.  
  754. ;-------------------------------------------------------------------------------
  755. ; Interrupt handlers
  756. ;-------------------------------------------------------------------------------
  757.  
  758.  
  759. __vector_default:
  760.  
  761. reti
  762.  
  763.  
  764. ;-------------------------------------------------------------------------------
  765. ; Basic routines
  766. ;-------------------------------------------------------------------------------
  767.  
  768.  
  769. Xor16B:
  770. ; In: Z = key
  771. ; X = state
  772.  
  773. ld r0, X
  774. ldd r7, Z + 0
  775. eor r0, r7
  776. st X+, r0
  777. ld r0, X
  778. ldd r7, Z + 1
  779. eor r0, r7
  780. st X+, r0
  781. ld r0, X
  782. ldd r7, Z + 2
  783. eor r0, r7
  784. st X+, r0
  785. ld r0, X
  786. ldd r7, Z + 3
  787. eor r0, r7
  788. st X+, r0
  789. ld r0, X
  790. ldd r7, Z + 4
  791. eor r0, r7
  792. st X+, r0
  793. ld r0, X
  794. ldd r7, Z + 5
  795. eor r0, r7
  796. st X+, r0
  797. ld r0, X
  798. ldd r7, Z + 6
  799. eor r0, r7
  800. st X+, r0
  801. ld r0, X
  802. ldd r7, Z + 7
  803. eor r0, r7
  804. st X+, r0
  805. ld r0, X
  806. ldd r7, Z + 8
  807. eor r0, r7
  808. st X+, r0
  809. ld r0, X
  810. ldd r7, Z + 9
  811. eor r0, r7
  812. st X+, r0
  813. ld r0, X
  814. ldd r7, Z + 10
  815. eor r0, r7
  816. st X+, r0
  817. ld r0, X
  818. ldd r7, Z + 11
  819. eor r0, r7
  820. st X+, r0
  821. ld r0, X
  822. ldd r7, Z + 12
  823. eor r0, r7
  824. st X+, r0
  825. ld r0, X
  826. ldd r7, Z + 13
  827. eor r0, r7
  828. st X+, r0
  829. ld r0, X
  830. ldd r7, Z + 14
  831. eor r0, r7
  832. st X+, r0
  833. ld r0, X
  834. ldd r7, Z + 15
  835. eor r0, r7
  836. st X+, r0
  837. ; 112 cycles
  838. ret
  839.  
  840.  
  841. ;-------------------------------------------------------------------------------
  842.  
  843.  
  844. Copy16B:
  845. ; In: Z = source
  846. ; X = destination
  847.  
  848. 1: ld r0, Z+
  849. st X+, r0
  850. ld r0, Z+
  851. st X+, r0
  852. ld r0, Z+
  853. st X+, r0
  854. ld r0, Z+
  855. st X+, r0
  856. ld r0, Z+
  857. st X+, r0
  858. ld r0, Z+
  859. st X+, r0
  860. ld r0, Z+
  861. st X+, r0
  862. ld r0, Z+
  863. st X+, r0
  864. Copy8B:
  865. com r1
  866. brne 1b
  867. ; 2(35)-1 = 69 cycles
  868. ret
  869.  
  870.  
  871. ;-------------------------------------------------------------------------------
  872.  
  873.  
  874. DelayNCycles:
  875. ; In: r24 = Number of cycles to delay, including the time taken to call
  876. ; A precise delay is possible for 28..255 cycles. 15 cycles is the minimum.
  877.  
  878. cpi r24, 28
  879. brcc 3f
  880. cpi r24, 16
  881. brcs 2f
  882. subi r24, 12
  883. nop
  884. lsr r24
  885. lsr r24
  886. 1: nop
  887. dec r24
  888. brne 1b
  889. ret
  890. 2: nop
  891. nop
  892. ret
  893. 3: subi r24, 24
  894. mov r22, r24
  895. com r22
  896. andi r22, 3
  897. lsr r24
  898. lsr r24
  899. ldiw Z, 4f
  900. lsr ZH
  901. ror ZL
  902. add ZL, r22
  903. adc ZH, r1
  904. ijmp
  905. 4: nop
  906. nop
  907. nop
  908. 5: nop
  909. dec r24
  910. brne 5b
  911. ret
  912.  
  913.  
  914. ;-------------------------------------------------------------------------------
  915.  
  916.  
  917. Delay10Cycles:
  918.  
  919. nop
  920. nop
  921.  
  922. Delay8Cycles:
  923.  
  924. ret
  925.  
  926.  
  927. ;-------------------------------------------------------------------------------
  928.  
  929.  
  930. DebounceSensor:
  931. ; In: r24: Debounce state (0: released, 1..254: uncertain 255: pressed)
  932. ; r22: Raw input (0: released, 1..255: pressed)
  933. ; Out: r24: Updated debounce state to use in Schmitt trigger logic
  934.  
  935. tst r22
  936. breq 1f
  937. nop
  938. cpi r24, 255 - SENSOR_DB_DELAY_CONTACTS_CLOSED
  939. ifcs
  940. ldi r24, 255 - SENSOR_DB_DELAY_CONTACTS_CLOSED
  941. add r24, r2
  942. sbc r24, r1
  943. ret
  944. 1: cpi r24, SENSOR_DB_DELAY_CONTACTS_OPEN
  945. ifcc
  946. ldi r24, SENSOR_DB_DELAY_CONTACTS_OPEN
  947. sub r24, r2
  948. adc r24, r1
  949. 4: ret
  950.  
  951. ; 16 cycles, including call
  952.  
  953.  
  954. ;-------------------------------------------------------------------------------
  955.  
  956.  
  957. CalculateCRC_CCITT:
  958. ; In: X = Data to checksum
  959. ; r17:r16 = number of bytes
  960. ; Out: X = End of data
  961. ; r17:r16 = CRC
  962. ; If the resulting 16-bit checksum is appended to the data high-byte first,
  963. ; the CRC of augmented data will be zero.
  964.  
  965. clr r7
  966. inc r7
  967. mov r8, r16
  968. mov r9, r17
  969. ser r16
  970. ser r17
  971. ldi r18, 0x21
  972. ldi r19, 0x10
  973. 1: ld r0, X+
  974. eor r17, r0
  975. com r1
  976. 2: lsl r16
  977. rol r17
  978. brcc 3f
  979. eor r16, r18
  980. eor r17, r19
  981. 3: lsr r1
  982. brne 2b
  983. sub r8, r7
  984. sbc r9, r1
  985. brne 1b
  986. ret
  987.  
  988.  
  989. ;-------------------------------------------------------------------------------
  990. ; EEPROM routines
  991. ;-------------------------------------------------------------------------------
  992.  
  993.  
  994. ReadEEPROMByte:
  995. ; In: X = address in EEPROM
  996. ; Out: r0 = byte
  997.  
  998. sbic _SFR_IO_ADDR(EECR), EEPE
  999. rjmp . - 4
  1000. out _SFR_IO_ADDR(EEARH), XH
  1001. out _SFR_IO_ADDR(EEARL), XL
  1002. sbi _SFR_IO_ADDR(EECR), EERE
  1003. in r0, _SFR_IO_ADDR(EEDR)
  1004. ret
  1005.  
  1006. ; 18 cycles including call and 4 cycle CPU halt, if EEPROM was ready
  1007.  
  1008.  
  1009. ;-------------------------------------------------------------------------------
  1010.  
  1011.  
  1012. ReadEEPROMBlock:
  1013. ; In: X = source in EEPROM
  1014. ; Z = destination in SRAM
  1015. ; r16 = number of bytes to read
  1016. tst r16
  1017. breq 2f
  1018. 1: rcall ReadEEPROMByte
  1019. adiw XL, 1
  1020. st Z+, r0
  1021. dec r16
  1022. brne 1b
  1023. 2: ret
  1024.  
  1025.  
  1026. ;-------------------------------------------------------------------------------
  1027.  
  1028.  
  1029. WriteEEPROMByte:
  1030. ; In: X = address in EEPROM
  1031. ; r0 = byte to write
  1032.  
  1033. push r16
  1034. ldi r16, (0 << EEPM1) | (0 << EEPM0) ; Erase and write
  1035. sbic _SFR_IO_ADDR(EECR), EEPE
  1036. rjmp . - 4
  1037. out _SFR_IO_ADDR(EECR), r16
  1038. out _SFR_IO_ADDR(EEARH), XH
  1039. out _SFR_IO_ADDR(EEARL), XL
  1040. out _SFR_IO_ADDR(EEDR), r0
  1041. sbi _SFR_IO_ADDR(EECR), EEMPE
  1042. sbi _SFR_IO_ADDR(EECR), EEPE
  1043. pop r16
  1044. ret
  1045.  
  1046. ; 23 cycles including call and 2 cycle CPU halt, if EEPROM was ready
  1047.  
  1048.  
  1049. ;-------------------------------------------------------------------------------
  1050.  
  1051.  
  1052. WriteEEPROMBlock:
  1053. ; In: X = destination in EEPROM
  1054. ; Z = source in SRAM
  1055. ; r16 = number of bytes to write
  1056.  
  1057. tst r16
  1058. breq 2f
  1059. 1: ld r0, Z+
  1060. rcall WriteEEPROMByte
  1061. adiw XL, 1
  1062. dec r16
  1063. brne 1b
  1064. 2: ret
  1065.  
  1066.  
  1067. ;-------------------------------------------------------------------------------
  1068. ; AES routines
  1069. ;-------------------------------------------------------------------------------
  1070.  
  1071.  
  1072. AES_SubstituteAndShift:
  1073. ; In: Y = address of 4x4 byte column-major state
  1074.  
  1075. ldi ZH, hi8(PM_AES_SBox)
  1076. ; First row
  1077. ldd ZL, Y + 0
  1078. lpm r8, Z
  1079. ldd ZL, Y + 4
  1080. lpm r9, Z
  1081. ldd ZL, Y + 8
  1082. lpm r10, Z
  1083. ldd ZL, Y + 12
  1084. lpm r11, Z
  1085. std Y + 0, r8
  1086. std Y + 4, r9
  1087. std Y + 8, r10
  1088. std Y + 12, r11
  1089. ; Second row
  1090. ldd ZL, Y + 1
  1091. lpm r8, Z
  1092. ldd ZL, Y + 5
  1093. lpm r9, Z
  1094. ldd ZL, Y + 9
  1095. lpm r10, Z
  1096. ldd ZL, Y + 13
  1097. lpm r11, Z
  1098. std Y + 1, r9
  1099. std Y + 5, r10
  1100. std Y + 9, r11
  1101. std Y + 13, r8
  1102. ; Third row
  1103. ldd ZL, Y + 2
  1104. lpm r8, Z
  1105. ldd ZL, Y + 6
  1106. lpm r9, Z
  1107. ldd ZL, Y + 10
  1108. lpm r10, Z
  1109. ldd ZL, Y + 14
  1110. lpm r11, Z
  1111. std Y + 2, r10
  1112. std Y + 6, r11
  1113. std Y + 10, r8
  1114. std Y + 14, r9
  1115. ; Fourth row
  1116. ldd ZL, Y + 3
  1117. lpm r8, Z
  1118. ldd ZL, Y + 7
  1119. lpm r9, Z
  1120. ldd ZL, Y + 11
  1121. lpm r10, Z
  1122. ldd ZL, Y + 15
  1123. lpm r11, Z
  1124. std Y + 3, r11
  1125. std Y + 7, r8
  1126. std Y + 11, r9
  1127. std Y + 15, r10
  1128. ; 1 + 4(28) = 113 cycles
  1129. ret
  1130.  
  1131.  
  1132. ;-------------------------------------------------------------------------------
  1133.  
  1134.  
  1135. AES_MixColumn:
  1136. ; In: X = address of column in 4x4 byte column-major state
  1137.  
  1138. ldi r16, 0x1b
  1139. ld r8, X+
  1140. ld r9, X+
  1141. ld r10, X+
  1142. ld r11, X+
  1143. ; Fourth element [3 1 1 2]
  1144. mov r7, r9
  1145. eor r7, r10
  1146. ; gmul2
  1147. mov r0, r11
  1148. lsl r0
  1149. ifcs
  1150. eor r0, r16
  1151. eor r7, r0
  1152. ; gmul3
  1153. mov r0, r8
  1154. lsl r0
  1155. ifcs
  1156. eor r0, r16
  1157. eor r0, r8
  1158. eor r7, r0
  1159. st -X, r7
  1160. ; Third element [1 1 2 3]
  1161. mov r7, r8
  1162. eor r7, r9
  1163. ; gmul2
  1164. mov r0, r10
  1165. lsl r0
  1166. ifcs
  1167. eor r0, r16
  1168. eor r7, r0
  1169. ; gmul3
  1170. mov r0, r11
  1171. lsl r0
  1172. ifcs
  1173. eor r0, r16
  1174. eor r0, r11
  1175. eor r7, r0
  1176. st -X, r7
  1177. ; Second element [1 2 3 1]
  1178. mov r7, r8
  1179. eor r7, r11
  1180. ; gmul2
  1181. mov r0, r9
  1182. lsl r0
  1183. ifcs
  1184. eor r0, r16
  1185. eor r7, r0
  1186. ; gmul3
  1187. mov r0, r10
  1188. lsl r0
  1189. ifcs
  1190. eor r0, r16
  1191. eor r0, r10
  1192. eor r7, r0
  1193. st -X, r7
  1194. ; First element [2 3 1 1]
  1195. mov r7, r10
  1196. eor r7, r11
  1197. ; gmul2
  1198. mov r0, r8
  1199. lsl r0
  1200. ifcs
  1201. eor r0, r16
  1202. eor r7, r0
  1203. ; gmul3
  1204. mov r0, r9
  1205. lsl r0
  1206. ifcs
  1207. eor r0, r16
  1208. eor r0, r9
  1209. eor r7, r0
  1210. st -X, r7
  1211. ; 8 + 4(15) = 68 cycles
  1212. ret
  1213.  
  1214.  
  1215. ;-------------------------------------------------------------------------------
  1216.  
  1217.  
  1218. AES_AdvanceRoundKey:
  1219. ; In: Y = key
  1220. ; r24 = most significant byte of the round constant
  1221.  
  1222. ldi ZH, hi8(PM_AES_SBox)
  1223. ldd ZL, Y + 13
  1224. lpm r8, Z
  1225. eor r8, r24
  1226. ldd ZL, Y + 14
  1227. lpm r9, Z
  1228. ldd ZL, Y + 15
  1229. lpm r10, Z
  1230. ldd ZL, Y + 12
  1231. lpm r11, Z
  1232. 1: ld r0, Y
  1233. eor r8, r0
  1234. st Y+, r8
  1235. ld r0, Y
  1236. eor r9, r0
  1237. st Y+, r9
  1238. ld r0, Y
  1239. eor r10, r0
  1240. st Y+, r10
  1241. ld r0, Y
  1242. eor r11, r0
  1243. st Y+, r11
  1244. ld r0, Y
  1245. eor r8, r0
  1246. st Y+, r8
  1247. ld r0, Y
  1248. eor r9, r0
  1249. st Y+, r9
  1250. ld r0, Y
  1251. eor r10, r0
  1252. st Y+, r10
  1253. ld r0, Y
  1254. eor r11, r0
  1255. st Y+, r11
  1256. com r1
  1257. brne 1b
  1258. ; 22 + 2(43)-1 = 107
  1259. ret
  1260.  
  1261.  
  1262. ;-------------------------------------------------------------------------------
  1263.  
  1264.  
  1265. AES_AdvanceCMACSubKey:
  1266. ; In: X = Either an AES-encrypted block of zeros or the
  1267. ; result of a previous call to this routine
  1268. ; Out: Z = Output
  1269. ; This routine is for generating the subkeys K1 and K2 from
  1270. ; an encryption key K. First, a block of zeros is encrypted
  1271. ; with K and advanced with this routine to yield K1. Calling
  1272. ; this routine a second time yields K2. AES in the CMAC mode
  1273. ; of operation requires the last block in the chained cipher
  1274. ; to be XORed with K1 or K2 before that block is encrypted.
  1275. ; If the message occupies all 128 bits in the last block, K1
  1276. ; is used, otherwise the message is appended with padding
  1277. ; consisting of a bit 1 followed by as many bit zeros as will
  1278. ; fit and K2 is used instead.
  1279.  
  1280. adiw ZL, 15
  1281. adiw XL, 15
  1282. ld r7, X
  1283. lsl r7
  1284. ldi r16, 3
  1285. 1: ld r0, -X
  1286. rol r0
  1287. st -Z, r0
  1288. ld r0, -X
  1289. rol r0
  1290. st -Z, r0
  1291. ld r0, -X
  1292. rol r0
  1293. st -Z, r0
  1294. ld r0, -X
  1295. rol r0
  1296. st -Z, r0
  1297. ld r0, -X
  1298. rol r0
  1299. st -Z, r0
  1300. dec r16
  1301. brne 1b
  1302. ldi r16, 0x87
  1303. ifcs
  1304. eor r7, r16
  1305. std Z + 15, r7
  1306. ; 8 + 3(28)-1 + 5 = 96 cycles
  1307. ret
  1308.  
  1309.  
  1310. ;-------------------------------------------------------------------------------
  1311.  
  1312.  
  1313. AES_Encrypt:
  1314. ; In: Z = key
  1315. ; X = state
  1316. ; r25:24 = subkey working space (16 bytes)
  1317.  
  1318. push YH
  1319. push YL
  1320. movw r20, r24
  1321. movw r22, XL
  1322. ; W := K
  1323. movw XL, r20
  1324. rcall Copy16B ; (Z, X)
  1325. ; Preprocessing step
  1326. movw ZL, r20
  1327. movw XL, r22
  1328. rcall Xor16B ; (Z, X)
  1329. ldi r18, 10
  1330. ldi r19, 0x8D
  1331. 1: movw YL, r22
  1332. rcall AES_SubstituteAndShift ; (Y)
  1333. dec r18
  1334. breq 2f
  1335. movw XL, r22
  1336. rcall AES_MixColumn ; (X)
  1337. adiw XL, 4
  1338. rcall AES_MixColumn ; (X)
  1339. adiw XL, 4
  1340. rcall AES_MixColumn ; (X)
  1341. adiw XL, 4
  1342. rcall AES_MixColumn ; (X)
  1343. 2: movw YL, r20
  1344. ldi r16, 0x1B
  1345. lsl r19
  1346. ifcs
  1347. eor r19, r16
  1348. mov r24, r19
  1349. rcall AES_AdvanceRoundKey ; (Y, r24)
  1350. movw ZL, r20
  1351. movw XL, r22
  1352. rcall Xor16B ; (Z, X)
  1353. tst r18
  1354. brne 1b
  1355. pop YL
  1356. pop YH
  1357. ret
  1358.  
  1359.  
  1360. ;-------------------------------------------------------------------------------
  1361. ; Application routines
  1362. ;-------------------------------------------------------------------------------
  1363.  
  1364.  
  1365. FindCurrentEWLDataSlot:
  1366. ; In: X = Status ring in EEPROM
  1367. ; Z = Data ring in EEPROM
  1368. ; Out: r16 = Index of current slot
  1369. ; r17 = Slot status value
  1370. ; Z = Address of current slot in EPPROM
  1371. ; This routine implements a variation of Atmel's recommendation. The data
  1372. ; (4 bytes in our case) is read from a slot in the Data Ring and written to
  1373. ; a different slot in that ring each time. The parallel Status Ring, filled
  1374. ; with values decreasing by one going backwards in memory indicates which
  1375. ; slot index is the current one: Where a decrement of one fails to occur
  1376. ; indicates the boundary between the current slot index and the next slot
  1377. ; index to use. (if S[(i - 1) mod N] != S[i] - 1, the current slot index is i
  1378. ; and the next slot index to use is (i - 1) mod N. Backwards counting is used
  1379. ; to minimise EEPROM wear and backwards traversal is to make the loop
  1380. ; termination easy. The EEPROM does not need to have any particular initial
  1381. ; state for this routine to work.
  1382.  
  1383. ; Traverse both the status and data rings backwards from the end, with
  1384. ; a previous status value taken from the first item in the status ring.
  1385. ldiw r17:r16, EWL_DATA_RING_SIZE - EWL_DATA_SLOT_SIZE
  1386. add ZL, r16
  1387. adc ZH, r17
  1388. rcall ReadEEPROMByte ; (X)
  1389. mov r17, r0 ; Previous value
  1390. clr r16 ; Previous index
  1391. ; Go backward from the last index.
  1392. ldi r18, EWL_INDEX_RANGE - 1 ; Current index
  1393. add XL, r18
  1394. adc ZH, r1
  1395. 1: rcall ReadEEPROMByte ; (X)
  1396. mov r19, r0 ; Current value
  1397. mov r20, r17 ; Compare with previous value.
  1398. sub r20, r19
  1399. cpi r20, 1
  1400. brne 2f ; A discontinuity! Return the previous index.
  1401. movw r16, r18 ; The previous index and value is now current.
  1402. sbiw XL, 1
  1403. sbiw ZL, EWL_DATA_SLOT_SIZE
  1404. dec r18
  1405. brne 1b
  1406. 2: ret
  1407.  
  1408.  
  1409. ;-------------------------------------------------------------------------------
  1410.  
  1411.  
  1412. LazilyUpdateEWLData:
  1413. ; Monitor the sequence number changes-until-update countdown and update the
  1414. ; EEPROM Wear Levelling data both in SRAM and in EEPROM.
  1415.  
  1416. clr r1 ; Just to be sure
  1417. ldd r17, Y + G_EWLState + EWLS_NumBytesToWrite
  1418. tst r17
  1419. brne 1f
  1420. ; No EWL updating is in progress.
  1421. ; See if the EWL needs updating.
  1422. ldd r0, Y + G_EWLState + EWLS_UpdateCountdown
  1423. cpse r0, r1
  1424. rjmp 4f
  1425. ; This transmitter has sent enough messages that its
  1426. ; Next Sequence Number should be saved to EEPROM (with
  1427. ; wear levelling) in case power is lost.
  1428. ldiw Z, AuthenticationData
  1429. ldd r0, Z + AD_SequenceNumber + 0
  1430. std Y + G_EWLState + EWLS_NewSequenceNumber + 0, r0
  1431. ldd r0, Z + AD_SequenceNumber + 1
  1432. std Y + G_EWLState + EWLS_NewSequenceNumber + 1, r0
  1433. ldd r0, Z + AD_SequenceNumber + 2
  1434. std Y + G_EWLState + EWLS_NewSequenceNumber + 2, r0
  1435. ldd r0, Z + AD_SequenceNumber + 3
  1436. std Y + G_EWLState + EWLS_NewSequenceNumber + 3, r0
  1437. ldi r17, EWL_COUNTS_BETWEEN_WRITES
  1438. std Y + G_EWLState + EWLS_UpdateCountdown, r17
  1439. ldi r17, 5 ; 4 for the NSN and 1 for the status ring
  1440. std Y + G_EWLState + EWLS_NumBytesToWrite, r17
  1441. ; 33 cycles so far
  1442. rjmp 4f
  1443. 1: ; 6 cycles so far
  1444. ; Either a byte of the new NSN or the EWL status value is to be written.
  1445. ; Only proceed if the EEPROM is not busy.
  1446. sbic _SFR_IO_ADDR(EECR), EEPE
  1447. rjmp 4f
  1448. ; Get the next EWL slot index and value ready.
  1449. ldd r20, Y + G_EWLState + EWLS_SlotIndex
  1450. ldd r21, Y + G_EWLState + EWLS_SlotValue
  1451. dec r20
  1452. cpi r20, EWL_INDEX_RANGE
  1453. ifcc
  1454. ldi r20, EWL_INDEX_RANGE - 1
  1455. dec r21
  1456. ; 17 cycles so far
  1457. ; Update the byte counter early.
  1458. dec r17
  1459. std Y + G_EWLState + EWLS_NumBytesToWrite, r17
  1460. breq 2f
  1461. cpi r17, 5
  1462. brcc 6f
  1463. ; Write a byte of the new Next Sequence Number.
  1464. dec r17
  1465. ldiw Z, Globals + G_EWLState + EWLS_NewSequenceNumber
  1466. add ZL, r17
  1467. adc ZH, r1
  1468. mov r0, r20
  1469. lsl r0
  1470. lsl r0
  1471. add r0, r17
  1472. ldiw X, EEPROM_EWLDataRing
  1473. add XL, r0
  1474. adc XH, r1
  1475. ld r0, Z
  1476. ; 38 cycles so far
  1477. rjmp 3f
  1478. 2: ; 22 cycles so far
  1479. ; Update the EWL slot data in SRAM.
  1480. std Y + G_EWLState + EWLS_SlotIndex, r20
  1481. std Y + G_EWLState + EWLS_SlotValue, r21
  1482. ; Write to the EWL status ring.
  1483. ldiw X, EEPROM_EWLStatusRing
  1484. add XL, r20
  1485. adc XH, r1
  1486. mov r0, r21
  1487. ; 31 cycles so far
  1488. 3: ; 40 or 31 cycles so far
  1489. rjmp WriteEEPROMByte ; 23 - 8 + 2 cycles
  1490. 4: ret
  1491. 6: ; Too many bytes to write. Ignore.
  1492. std Y + G_EWLState + EWLS_NumBytesToWrite, r1
  1493. ret
  1494.  
  1495. ; Max 65 cycles, including call
  1496.  
  1497.  
  1498. ;-------------------------------------------------------------------------------
  1499.  
  1500.  
  1501. FullyUpdateEWLData:
  1502. ; Update the EWL data so that the sequence number is fully committed to EEPROM,
  1503. ; however long it takes.
  1504.  
  1505. std Y + G_EWLState + EWLS_UpdateCountdown, r1
  1506. 1: rcall LazilyUpdateEWLData
  1507. ldd r0, Y + G_EWLState + EWLS_UpdateCountdown
  1508. tst r0
  1509. breq 1b
  1510. ret
  1511.  
  1512.  
  1513. ;-------------------------------------------------------------------------------
  1514.  
  1515.  
  1516. MutateRandomData:
  1517. ; In: r6:r4 = 32kHz counter
  1518. ; Out: r0 = byte written to the random data pool
  1519.  
  1520. movw r14, YL
  1521. ldiw Y, EntropyHarvester
  1522. ; Select the next byte of the random data to mutate.
  1523. ldd r16, Y + EH_MutationIndex
  1524. subi r16, -EH_MUTATION_INDEX_ADVANCE
  1525. andi r16, EH_MUTATION_INDEX_MASK
  1526. std Y + EH_MutationIndex, r16
  1527. ldiw Z, EntropyHarvester + EH_RandomData
  1528. add ZL, r16
  1529. adc ZH, r1
  1530. ; Mutate with the help of the 32kHz counter
  1531. ld r0, Z
  1532. add r0, r5 ; Timer bits 8 to 10 are adequate.
  1533. ror r0
  1534. adc r0, r4 ; Timer bits 3 to 7 are useful.
  1535. st Z, r0
  1536. movw YL, r14
  1537. ; 21 cycles so far
  1538.  
  1539. ret
  1540.  
  1541. ; 29 cycles including call
  1542.  
  1543.  
  1544. ;-------------------------------------------------------------------------------
  1545.  
  1546.  
  1547. RandomiseCMACKey:
  1548.  
  1549. ; Abuse the key part of the random data a little, in case
  1550. ; an insufficient amount of entropy was harvested between
  1551. ; transmissions of the secret key.
  1552. ldiw Z, EntropyHarvester + EH_RandomData + 0
  1553. ldd r8, Z + 0
  1554. ldd r9, Z + 1
  1555. ldd r10, Z + 2
  1556. ldd r11, Z + 3
  1557. ldiw X, EntropyHarvester + EH_RandomData + 16
  1558. movw ZL, XL
  1559. ldd r0, Z + 0
  1560. add r0, r8
  1561. std Z + 0, r0
  1562. ldd r8, Z + 7
  1563. add r8, r5
  1564. ldd r0, Z + 2
  1565. sbc r0, r9
  1566. dec r0
  1567. std Z + 7, r0
  1568. ldd r0, Z + 12
  1569. sbc r0, r10
  1570. std Z + 2, r0
  1571. ror r8
  1572. adc r8, r11
  1573. std Z + 12, r8
  1574. rcall AES_AdvanceCMACSubKey
  1575. ; Mutilate the existing CMAC key
  1576. ldiw Z, EntropyHarvester + EH_RandomData + 0
  1577. ldiw X, AuthenticationData + AD_CMACKey
  1578. rcall Xor16B
  1579. ; Random data and a random key should be effective in
  1580. ; producing a nice new key.
  1581. ldiw Z, EntropyHarvester + EH_RandomData + 16
  1582. ldiw X, AuthenticationData + AD_CMACKey
  1583. ldiw r25:r24, AES_Matrix_W
  1584. rcall AES_Encrypt
  1585. ; Now for the subkey K2
  1586. ldiw Z, AuthenticationData + AD_CMACKey
  1587. ldiw X, AuthenticationData + AD_CMACSubkeyK2 + 16
  1588. ldiw r25:r24, AES_Matrix_W
  1589. ldi r16, 16
  1590. 1: st -X, r1
  1591. dec r16
  1592. brne 1b
  1593. rcall AES_Encrypt
  1594. ldiw X, AuthenticationData + AD_CMACSubkeyK2
  1595. movw ZL, XL
  1596. rcall AES_AdvanceCMACSubKey
  1597. ldiw X, AuthenticationData + AD_CMACSubkeyK2
  1598. movw ZL, XL
  1599. rjmp AES_AdvanceCMACSubKey
  1600.  
  1601.  
  1602. ;-------------------------------------------------------------------------------
  1603.  
  1604.  
  1605. BuildTeachMessage:
  1606. ; In: r24 = 0 if the shared key is be used to encrypt the secret key (normal) or
  1607. ; 1 if the secret key is to be unprotected (timed delay mode).
  1608.  
  1609. ; The message is in big-endian format.
  1610. ; Copy the serial number and sequence number together.
  1611. ldiw X, AuthenticationData + AD_SerialNumber
  1612. ldiw Z, Globals + G_Transmitter + Tx_Data + TeachMsg_SerialNumber
  1613. 1: ld r8, X+
  1614. ld r9, X+
  1615. ld r10, X+
  1616. ld r11, X+
  1617. st Z+, r11
  1618. st Z+, r10
  1619. st Z+, r9
  1620. st Z+, r8
  1621. com r1
  1622. brne 1b
  1623. ldiw Z, Globals + G_Transmitter + Tx_Data + TeachMsg_AuxData
  1624. std Z + 0, r1
  1625. std Z + 1, r1
  1626. sbrc r24, 0
  1627. std Z + 1, r2 ; Mark the teach message as unencrypted.
  1628. ldiw Z, AuthenticationData + AD_CMACKey
  1629. ldiw X, Globals + G_Transmitter + Tx_Data + TeachMsg_EncryptedCMACKey
  1630. rcall Copy16B
  1631. ldiw X, EEPROM_SharedKey
  1632. ldiw Z, AES_Matrix_W
  1633. ldi r16, 16
  1634. rcall ReadEEPROMBlock
  1635. ldiw Z, AES_Matrix_W
  1636. ldiw X, Globals + G_Transmitter + Tx_Data + TeachMsg_EncryptedCMACKey
  1637. sbrs r24, 0
  1638. rcall Xor16B
  1639. ldiw X, Globals + G_Transmitter + Tx_Data
  1640. ldi r16, TeachMsgSize - 2
  1641. clr r17
  1642. rcall CalculateCRC_CCITT
  1643. ; Store the CRC in big-endian format, not just because other elements
  1644. ; in the message big-endian, but because the CCITT CRC of a message
  1645. ; appended with its own CRC stored high-byte-first is zero.
  1646. st X+, r17
  1647. st X+, r16
  1648. ret
  1649.  
  1650.  
  1651. ;-------------------------------------------------------------------------------
  1652. ; Initialisation
  1653. ;-------------------------------------------------------------------------------
  1654.  
  1655.  
  1656. InitialiseRegisterConstants:
  1657. ; Out: r1 = 0
  1658. ; r2 = 1
  1659. ; r3 = 255
  1660. ; Y = Globals
  1661.  
  1662. ; r1 = 0
  1663. clr r1
  1664.  
  1665. ; r2 = 1, handy for carry-changing inc/dec via add/sub.
  1666. clr r2
  1667. inc r2
  1668.  
  1669. ; r3 = 255 for sign extension.
  1670. clr r3
  1671. dec r3
  1672.  
  1673. ldiw Y, Globals
  1674.  
  1675. ret
  1676.  
  1677.  
  1678. ;-------------------------------------------------------------------------------
  1679.  
  1680.  
  1681. InitialiseHardware:
  1682.  
  1683. ; No interrupts!
  1684. cli
  1685.  
  1686. ; Clear the watchdog reset flag so that it doesn't disable the
  1687. ; the watchdog timer.
  1688. in r16, _SFR_IO_ADDR(MCUSR)
  1689. andi r16, ~(1 << WDRF)
  1690. out _SFR_IO_ADDR(MCUSR), r16
  1691.  
  1692. ; Start the watchdog timer and have it force a reset of the CPU if
  1693. ; the timer isn't reset at least once every 0.5 seconds.
  1694. ldi r16, (1 << WDCE) | (1 << WDE)
  1695. out _SFR_IO_ADDR(WDTCR), r16
  1696. ldi r16, (0 << WDCE) | (1 << WDE) | (0 << WDP3) | (0b101 << WDP0)
  1697. out _SFR_IO_ADDR(WDTCR), r16
  1698.  
  1699. ; Halt and configure Timer/Counter 0 to run at 8MHz.
  1700. ldi r18, (1 << TSM) | (1 << PSR0)
  1701. out _SFR_IO_ADDR(GTCCR), r18
  1702. ldi r18, (0 << WGM02) | (0b001 << CS00)
  1703. out _SFR_IO_ADDR(TCCR0B), r18
  1704. out _SFR_IO_ADDR(TCNT0), r1
  1705.  
  1706. ; Start the counting.
  1707. out _SFR_IO_ADDR(GTCCR), r1
  1708.  
  1709. ; Set Data Direction and pull-ups
  1710. ldi r18, (1 << INPUT_BIT_PRIMARY_SENSOR) |\
  1711. (1 << INPUT_BIT_SECONDARY_SENSOR) |\
  1712. (0 << INPUT_BIT_BUTTONS)
  1713. ldi r19, (1 << OUTPUT_BIT_ACTIVITY_LED) |\
  1714. (1 << OUTPUT_BIT_RADIO)
  1715. out _SFR_IO_ADDR(PORTB), r18
  1716. out _SFR_IO_ADDR(DDRB), r19
  1717.  
  1718. ; 03 ADCSRB [ BIN ACME IPR --- --- ADTS2 ADTS1 ADTS0 ]
  1719. ; 04 ADCL [ ADC Data Register Low Byte ]
  1720. ; 05 ADCH [ ADC Data Register High Byte ]
  1721. ; 06 ADCSRA [ ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0 ]
  1722. ; 07 ADMUX [ REFS1 REFS0 ADLAR REFS2 MUX3 MUX2 MUX1 MUX0 ]
  1723. ; 08 ACSR [ ACD ACBG ACO ACI ACIE --- ACIS1 ACIS0 ]
  1724. ; 14 DIDR0 [ --- --- ADC0D ADC2D ADC3D ADC1D AIN1D AIN0D ]
  1725.  
  1726. ; Disable the digital input buffer for the pin on which
  1727. ; we are to receive analogue input.
  1728. ldi r18, 1 << BUTTONS_DIGITAL_INPUT_DISABLE_BIT
  1729. out _SFR_IO_ADDR(DIDR0), r18
  1730. ldi r18, 0x00
  1731. out _SFR_IO_ADDR(ADCSRB), r18
  1732. ldi r18, (1 << ADLAR) | (BUTTONS_ADC_MUX_SELECTOR << MUX0)
  1733. out _SFR_IO_ADDR(ADMUX), r18
  1734. ; Single-shot mode
  1735. ; Start the conversion early to avoid spurious button readings.
  1736. ldi r18, (1 << ADEN) | (1 << ADSC) | (0 << ADATE) | (0 << ADIF) |\
  1737. (0b110 << ADPS0) ; CK/64 => 125kHz ADC clock
  1738. out _SFR_IO_ADDR(ADCSRA), r18
  1739.  
  1740. ret
  1741.  
  1742.  
  1743. ;-------------------------------------------------------------------------------
  1744.  
  1745.  
  1746. ClearGlobals:
  1747.  
  1748. movw ZL, YL
  1749. ldi r18, (VariablesEnd - Globals) / 2
  1750. 1: st Z+, r1
  1751. st Z+, r1
  1752. dec r18
  1753. brne 1b
  1754.  
  1755. ret
  1756.  
  1757.  
  1758. ;-------------------------------------------------------------------------------
  1759.  
  1760.  
  1761. LoadEverythingFromEEPROM:
  1762.  
  1763. ; Load the sound indices, stored complemented in EEPROM.
  1764. ; Bits 0 to 3 is the sound index for the primary sensor.
  1765. ; Bits 4 to 7 is the sound index for the secondary sensor.
  1766. ldiw X, EEPROM_InvSoundIndices
  1767. rcall ReadEEPROMByte
  1768. com r0
  1769. std Y + G_SoundIndices, r0
  1770.  
  1771. ; Load the activation senses
  1772. ; Bits 0 and 1 are for the primary and secondary sensors respectively.
  1773. ; A sensor activation bit value of 0 means that the input at the
  1774. ; sensor's pin on the MCU is active high and a value of 1 means
  1775. ; that the pin is active low.
  1776. ldiw X, EEPROM_SensorActivationSenses
  1777. rcall ReadEEPROMByte
  1778. ldi r16, 0x03
  1779. and r16, r0
  1780. std Y + G_SensorActivationSenses, r16
  1781. sts TASSState + TASS_NewSensorActivationSenses, r16
  1782.  
  1783. ; Load the authentication data which allows this transmitter to
  1784. ; be associated with one or more receivers.
  1785. ldiw Z, AuthenticationData + AD_SerialNumber
  1786. ldiw X, EEPROM_SerialNumber
  1787. ldi r16, 4
  1788. rcall ReadEEPROMBlock
  1789. ldiw Z, AuthenticationData + AD_CMACKey
  1790. ldiw X, EEPROM_CMACKey
  1791. ldi r16, 16
  1792. rcall ReadEEPROMBlock
  1793. ldiw Z, AuthenticationData
  1794. std Z + AD_HaveK2, r1
  1795.  
  1796. ; Load the EEPROM Wear Levelling state and the sequence number
  1797. ; necessary for the authentication system to maintain synchronisation.
  1798. ldiw X, EEPROM_EWLStatusRing
  1799. ldiw Z, EEPROM_EWLDataRing
  1800. rcall FindCurrentEWLDataSlot
  1801. std Y + G_EWLState + EWLS_SlotIndex, r16
  1802. std Y + G_EWLState + EWLS_SlotValue, r17
  1803. movw XL, ZL
  1804. ldiw Z, AuthenticationData + AD_SequenceNumber
  1805. ldi r16, 4
  1806. rcall ReadEEPROMBlock
  1807.  
  1808. ; Advance the sequence number in case the power was lost before
  1809. ; the EWL data could be updated.
  1810. ldiw Z, AuthenticationData
  1811. ldd r16, Z + AD_SequenceNumber + 0
  1812. ldd r17, Z + AD_SequenceNumber + 1
  1813. ldd r18, Z + AD_SequenceNumber + 2
  1814. ldd r19, Z + AD_SequenceNumber + 3
  1815. ldi r20, EWL_COUNTS_BETWEEN_WRITES + 2 ; (+2 for good measure)
  1816. add r16, r20
  1817. adc r17, r1
  1818. adc r18, r1
  1819. adc r19, r1
  1820. std Z + AD_SequenceNumber + 0, r16
  1821. std Z + AD_SequenceNumber + 1, r17
  1822. std Z + AD_SequenceNumber + 2, r18
  1823. std Z + AD_SequenceNumber + 3, r19
  1824. ldi r16, 1
  1825. std Y + G_EWLState + EWLS_UpdateCountdown, r16
  1826.  
  1827. ; Load the random data harvested so far.
  1828. ldiw Z, EntropyHarvester + EH_RandomData
  1829. ldiw X, EEPROM_RandomData
  1830. ldi r16, EH_MUTATION_INDEX_RANGE
  1831. rcall ReadEEPROMBlock
  1832. ; Add a bit of extra wear levelling of the random data.
  1833. ldiw Z, EntropyHarvester
  1834. ldd r16, Z + EH_RandomData + EH_AUX_RANDOM_DATA_START_INDEX
  1835. andi r16, EH_MUTATION_INDEX_MASK
  1836. std Z + EH_EEPROMUpdateIndex, r16
  1837.  
  1838. ret
  1839.  
  1840.  
  1841. ;-------------------------------------------------------------------------------
  1842. ; main
  1843. ;-------------------------------------------------------------------------------
  1844.  
  1845.  
  1846. main:
  1847.  
  1848. rcall InitialiseRegisterConstants
  1849. rcall InitialiseHardware
  1850. rcall ClearGlobals
  1851. wdr
  1852. rcall LoadEverythingFromEEPROM
  1853.  
  1854. ldi r18, 127
  1855. std Y + G_PrimarySensorIntegral, r18
  1856. std Y + G_SecondarySensorIntegral, r18
  1857.  
  1858. ; Initialise the AES-CMAC authenticator state.
  1859. ldi r18, AUTH_STATE_IDLE
  1860. std Y + G_AuthenticationState, r18
  1861. ldi r18, AES_STATE_IDLE
  1862. std Y + G_AESState, r18
  1863.  
  1864. ; Reset the 32kHz counter
  1865. clr r4
  1866. clr r5
  1867. clr r6
  1868.  
  1869. main_Loop:
  1870.  
  1871. ; Time share
  1872. ;
  1873. ; 32kHz:
  1874. ; Reset watchdog (1)
  1875. ; Synchronise (35)
  1876. ; Update 32kHz counter (3)
  1877. ; Update transmit pin (28)
  1878. ; Time share 32kHz by 8 into 4kHz tasks (11)
  1879. ; 0: Transmit packet (138)
  1880. ; 1: Authentication (146)
  1881. ; 2: Teach And Sound Select tasks
  1882. ; Time share 4kHz by 4 into 1kHz tasks (Max 7)
  1883. ; 0: ADC button input and TASS timers (121)
  1884. ; 1: Button logic (118)
  1885. ; 2: Transmission tasks scheduling (122+)
  1886. ; 3:
  1887. ; 3: Sensor input conditioning and entropy harvesting (148)
  1888. ; 4: Sensor state transmission bursts and EWL updating (153)
  1889. ; 5: Refresh EEPROM (67)
  1890. ; 6:
  1891. ; 7:
  1892.  
  1893. wdr
  1894.  
  1895. main_Synchronise:
  1896.  
  1897. ; 32kHz implies a period of 31.25us, 250 counts of a 8MHz counter.
  1898. ; The timer match value should be therefore be 250 counts ahead
  1899. ; of the previous value.
  1900. ldd r24, Y + G_CurrentTimer0Match
  1901. subi r24, -250 ; "addi r24, 244" but with an opcode which exists
  1902. std Y + G_CurrentTimer0Match, r24
  1903. in r0, _SFR_IO_ADDR(TCNT0)
  1904. sub r24, r0
  1905. rcall DelayNCycles
  1906.  
  1907. ; 7 + 28 = 35 cycles
  1908.  
  1909. ;; We have too much spare time!
  1910. ;ldi r24, 200
  1911. ;rcall DelayNCycles
  1912.  
  1913. main_Update32kHzCounter:
  1914.  
  1915. ; r6:r4 = 32kHz counter value
  1916. ; f = 16000 * 2^-b Hz
  1917. ; T = 2^b / 16000 s
  1918. ; b = log2(16000 / f)
  1919. ; b = log2(16000 * T))
  1920.  
  1921. ; Bit Edge f Edge T
  1922. ; 0 32kHz 31.25us
  1923. ; 1 16kHz 62.5us
  1924. ; 2 8kHz 125us
  1925. ; 3 4kHz 250us
  1926. ; 4 2kHz 500us
  1927. ; 5 1kHz 1ms
  1928. ; 6 500Hz 2ms
  1929. ; 7 250Hz 4ms
  1930. ; 8 125Hz 8ms
  1931. ; 9 62.5Hz 16ms
  1932. ; 10 31.25Hz 32ms
  1933. ; 11 15.625Hz 64ms
  1934. ; 12 7.8125Hz 128ms
  1935. ; 13 3.9106Hz 256ms
  1936. ; 14 1.9531Hz 512ms
  1937. ; 15 0.9766Hz 1024ms
  1938. ; 16 2.05s
  1939. ; 17 4.10s
  1940. ; 18 8.19s
  1941. ; 19 16.38s
  1942. ; 20 32.77s
  1943. ; 21 65.54s
  1944. ; 22 131.07s
  1945. ; 23 262.14s
  1946. ; Clocked 524.29s
  1947.  
  1948. add r4, r2
  1949. adc r5, r1
  1950. adc r6, r1
  1951.  
  1952. ; 3 cycles
  1953.  
  1954. main_UpdateTransmitPin:
  1955.  
  1956. ; See if there's anything in the buffer.
  1957. ldd r18, Y + G_Transmitter + Tx_TxBit + TxBit_HeadIx
  1958. ldd r19, Y + G_Transmitter + Tx_TxBit + TxBit_TailIx
  1959. cp r18, r19
  1960. brne 1f
  1961. rcall Delay10Cycles
  1962. rcall Delay10Cycles
  1963. rjmp 3f
  1964. 1: ; The output ring buffer is arranged such that even offsets represent
  1965. ; marks and odd offsets represent spaces.
  1966. ; Update the transmission data pin while the timing is exact.
  1967. in r20, _SFR_IO_ADDR(PORTB)
  1968. mov r0, r18
  1969. com r0
  1970. bst r0, 0
  1971. bld r20, OUTPUT_BIT_RADIO
  1972. out _SFR_IO_ADDR(PORTB), r20
  1973. ; The buffer still has something in it.
  1974. ldiw X, TxRunLengthsRingBuffer
  1975. add XL, r18
  1976. adc XH, r1
  1977. ld r0, X
  1978. dec r0
  1979. st X, r0
  1980. breq 2f
  1981. nop
  1982. adiw XL, 0
  1983. rjmp 3f
  1984. 2: ; Advance to the next mark or space.
  1985. inc r18
  1986. andi r18, TX_RING_BUFFER_INDEX_MASK
  1987. std Y + G_Transmitter + Tx_TxBit + TxBit_HeadIx, r18
  1988. 3:
  1989. ; 28 cycles
  1990.  
  1991. main_TimeShare32By8:
  1992.  
  1993. sbrc r4, 2
  1994. rjmp 4f
  1995. nop
  1996. sbrc r4, 1
  1997. rjmp 2f
  1998. nop
  1999. sbrc r4, 0
  2000. rjmp 1f
  2001. nop
  2002. rjmp main_T0_TransmitPacket
  2003. 1: rjmp main_T1_Authentication
  2004. 2: sbrc r4, 0
  2005. rjmp 3f
  2006. nop
  2007. rjmp main_T2_TeachAndSoundSelectTasks
  2008. 3: rjmp main_T3_SensorInputConditioningAndEntropyHarvesting
  2009. 4: sbrc r4, 1
  2010. rjmp 6f
  2011. nop
  2012. sbrc r4, 0
  2013. rjmp 5f
  2014. nop
  2015. rjmp main_T4_SensorStateTxBurstsAndEWLUpdates
  2016. 5: rjmp main_T5_RefreshEEPROM
  2017. 6: sbrc r4, 0
  2018. rjmp 7f
  2019. nop
  2020. rjmp main_T6
  2021. 7: rjmp main_T7
  2022.  
  2023. ; 11 cycles
  2024.  
  2025. main_T0_TransmitPacket:
  2026.  
  2027. ; Find how many mark-space pairs are free.
  2028. ldd r18, Y + G_Transmitter + Tx_TxBit + TxBit_HeadIx
  2029. ldd r19, Y + G_Transmitter + Tx_TxBit + TxBit_TailIx
  2030. sub r18, r19
  2031. dec r18
  2032. andi r18, TX_RING_BUFFER_INDEX_MASK
  2033. lsr r18
  2034.  
  2035. ; Jump to the handler for the current state.
  2036. ldd r20, Y + G_Transmitter + Tx_State
  2037. cpi r20, TX_STATE_DATA
  2038. breq main_TxState_Data ; 13 cycles
  2039. brcc 1f
  2040. cpi r20, TX_STATE_BEGIN
  2041. breq main_TxState_Begin ; 16 cycles
  2042. brcc main_TxState_Sync ; 17 cycles
  2043. rjmp main_TxState_Idle ; 18 cycles
  2044. 1: cpi r20, TX_STATE_TERMINATOR
  2045. ifne
  2046. rjmp main_TxState_Rest ; 21 cycles
  2047. rjmp main_TxState_Terminator ; 22 cycles
  2048.  
  2049. main_TxState_Idle:
  2050.  
  2051. ; 18 cycles so far
  2052.  
  2053. rjmp main_Loop
  2054.  
  2055. ; 20 cycles
  2056.  
  2057. main_TxState_Begin:
  2058.  
  2059. ; 16 cycles so far
  2060.  
  2061. ldd r0, Y + G_Transmitter + Tx_Data + 0
  2062. std Y + G_Transmitter + Tx_ShiftRegister, r0
  2063. std Y + G_Transmitter + Tx_Parity, r1
  2064. std Y + G_Transmitter + Tx_NumBytesSent, r1
  2065.  
  2066. ldi r20, TX_STATE_SYNC
  2067. std Y + G_Transmitter + Tx_State, r20
  2068. ldi r20, TX_NUMBER_OF_LEADER_PULSES + 1
  2069. std Y + G_Transmitter + Tx_Counter, r20
  2070.  
  2071. ; Fall through to main_TxState_Sync.
  2072.  
  2073. ; 30 cycles so far
  2074.  
  2075. main_TxState_Sync:
  2076.  
  2077. ; 17 or 30 cycles so far
  2078.  
  2079. ; Limit the number of mark-space pairs to be buffered in one turn.
  2080. ldi r23, 2
  2081. cp r18, r23
  2082. ifcc
  2083. mov r18, r23
  2084.  
  2085. ldd r22, Y + G_Transmitter + Tx_Counter
  2086. cp r22, r18
  2087. ifcs
  2088. mov r18, r22
  2089. tst r18
  2090. breq 5f
  2091.  
  2092. 1: ; The last two mark-space pairs are modified to include a long sync
  2093. ; pulse which maintains a minimal DC bias.
  2094. ; The synchronisation pattern is 101010...1010101000111001.
  2095. cpi r22, 2
  2096. breq 2f
  2097. brcc 3f
  2098. ; End of synchronisation: Long mark followed by a space that is
  2099. ; twice the length of a short space.
  2100. ldi r20, 3 * TX_TIME_UNIT
  2101. ldi r21, 2 * TX_TIME_UNIT
  2102. rjmp 4f
  2103. 2: ; The last leader pulse has a long space to maintain DC balance.
  2104. ldi r20, TX_TIME_UNIT
  2105. ldi r21, 3 * TX_TIME_UNIT
  2106. rjmp 4f
  2107. 3: ; The leader pattern makes the radio receiver AGC happy.
  2108. ldi r20, TX_TIME_UNIT
  2109. ldi r21, TX_TIME_UNIT
  2110. nop
  2111. 4: dec r22
  2112. rcall main_Tx_BufferMarkSpace
  2113. dec r18
  2114. brne 1b
  2115. std Y + G_Transmitter + Tx_Counter, r22
  2116.  
  2117. 5: ; (17 or 26) + (12 or 12+(41n)-1+2) cycles
  2118. ; Are there any more synchronisation pulses to buffer?
  2119. cpse r22, r1
  2120. rjmp main_Loop ; 33..124 cycles
  2121.  
  2122. ; Begin data transmission.
  2123. ldi r20, TX_STATE_DATA
  2124. std Y + G_Transmitter + Tx_State, r20
  2125. ldi r20, 8
  2126. std Y + G_Transmitter + Tx_Counter, r20
  2127. ; Start the current run length of the second half of the bit 1 which
  2128. ; follows the long space-mark which terminates the leader.
  2129. ldiw X, TxRunLengthsRingBuffer
  2130. add XL, r19
  2131. adc XH, r1
  2132. ldi r20, TX_TIME_UNIT
  2133. st X, r20
  2134.  
  2135. rjmp main_Loop
  2136.  
  2137. ; Max 142 cycles
  2138.  
  2139. main_TxState_Data:
  2140.  
  2141. ; 13 cycles so far
  2142.  
  2143. ; Proceed only if there is room for two run entries (1 pair).
  2144. tst r18
  2145. ifeq
  2146. rjmp main_Loop ; 17 cycles
  2147.  
  2148. ldd r20, Y + G_Transmitter + Tx_NumBytesToSend
  2149. tst r20
  2150. breq main_TxState_Terminator ; 21 cycles
  2151.  
  2152. ldd r21, Y + G_Transmitter + Tx_NumBytesSent
  2153.  
  2154. ldd r22, Y + G_Transmitter + Tx_Counter
  2155. tst r22
  2156. breq main_TxState_Data_Parity ; 27 cycles
  2157.  
  2158. ; Fall through to main_TxState_Data_Bit.
  2159.  
  2160. main_TxState_Data_Bit:
  2161.  
  2162. ; 26 cycles so far
  2163.  
  2164. dec r22
  2165. std Y + G_Transmitter + Tx_Counter, r22
  2166. ; Fetch the current data byte.
  2167. ldd r0, Y + G_Transmitter + Tx_ShiftRegister
  2168. ; Rotate-left-circular the current data byte, storing a bit into T.
  2169. bst r0, 7
  2170. add r0, r0
  2171. adc r0, r1
  2172. std Y + G_Transmitter + Tx_ShiftRegister, r0
  2173. ; Update the parity for this byte.
  2174. ldd r0, Y + G_Transmitter + Tx_Parity
  2175. ifts
  2176. inc r0
  2177. std Y + G_Transmitter + Tx_Parity, r0
  2178.  
  2179. rjmp main_TxState_Data_ModulateBit ; 44 cycles
  2180.  
  2181. main_TxState_Data_Parity:
  2182.  
  2183. ; 27 cycles so far
  2184.  
  2185. dec r20
  2186. std Y + G_Transmitter + Tx_NumBytesToSend, r20
  2187. inc r21
  2188. std Y + G_Transmitter + Tx_NumBytesSent, r21
  2189. movw XL, YL
  2190. adiw XL, G_Transmitter + Tx_Data
  2191. add XL, r21
  2192. adc XH, r1
  2193. ld r0, X
  2194. std Y + G_Transmitter + Tx_ShiftRegister, r0
  2195. ldi r22, 8
  2196. std Y + G_Transmitter + Tx_Counter, r22
  2197. ldd r0, Y + G_Transmitter + Tx_Parity
  2198. std Y + G_Transmitter + Tx_Parity, r1
  2199. ; Even parity is used.
  2200. bst r0, 0
  2201. ; 50 cycles so far
  2202.  
  2203. ; Fall through to main_TxState_Data_ModulateBit.
  2204.  
  2205. main_TxState_Data_ModulateBit:
  2206.  
  2207. ; 44 or 51 cycles so far
  2208.  
  2209. ; From the T flag, prepare the Manchester-encoded bits
  2210. ; in the first two bits of r18. Bit 0 first, Bit 1 second.
  2211. ;
  2212. ; Data bit First Second
  2213. ; 0 0 1
  2214. ; 1 1 0
  2215. mov r18, r1
  2216. bld r18, 0
  2217. inc r18
  2218. bld r18, 1
  2219.  
  2220. ; Submit the Manchester bits to the run length ring buffer.
  2221.  
  2222. ; Manchester bit duration in 32kHz ticks
  2223. ldi r23, TX_TIME_UNIT
  2224. ; The run length counter is just past the end of the ring buffer.
  2225. ldiw X, TxRunLengthsRingBuffer
  2226. add XL, r19
  2227. adc XH, r1
  2228. clr r20
  2229. ; 54 or 61 cycles so far
  2230. 1: ; See if the run state is to change.
  2231. mov r0, r18
  2232. eor r0, r19
  2233. lsr r0
  2234. brcc 2f
  2235. ; Increase run length.
  2236. ld r0, X
  2237. add r0, r23
  2238. st X, r0
  2239. adiw XL, 0
  2240. rjmp 3f
  2241. 2: ; Queue the current run length.
  2242. inc r19
  2243. andi r19, TX_RING_BUFFER_INDEX_MASK
  2244. ; Start a new run.
  2245. ldiw X, TxRunLengthsRingBuffer
  2246. add XL, r19
  2247. adc XH, r1
  2248. st X, r23
  2249. ; Next Manchester bit.
  2250. 3: lsr r18
  2251. ; 14 cycles in loop so far
  2252. com r20
  2253. brne 1b
  2254. std Y + G_Transmitter + Tx_TxBit + TxBit_TailIx, r19
  2255. rjmp main_Loop
  2256.  
  2257. ; 89 or 96 cycles
  2258.  
  2259. main_TxState_Terminator:
  2260.  
  2261. ; 22 cycles so far
  2262.  
  2263. ; There is no real terminator to transmit in this encoding scheme.
  2264. ; However, the current run length needs to be enqueued if it's for
  2265. ; a high state. Then a long space is to be enqueued.
  2266.  
  2267. ldiw X, TxRunLengthsRingBuffer
  2268. add XL, r19
  2269. adc XH, r1
  2270. sbrc r19, 0
  2271. rjmp 1f
  2272. inc r19
  2273. andi r19, TX_RING_BUFFER_INDEX_MASK
  2274. ldiw X, TxRunLengthsRingBuffer
  2275. add XL, r19
  2276. adc XH, r1
  2277. 1: ldi r20, TX_RLB_REST_TIME
  2278. st X, r20
  2279. inc r19
  2280. andi r19, TX_RING_BUFFER_INDEX_MASK
  2281. std Y + G_Transmitter + Tx_TxBit + TxBit_TailIx, r19
  2282.  
  2283. ldi r20, TX_STATE_REST
  2284. std Y + G_Transmitter + Tx_State, r20
  2285. ldi r20, TX_TASK_REST_TIME
  2286. std Y + G_Transmitter + Tx_Counter, r20
  2287.  
  2288. rjmp main_Loop
  2289.  
  2290. ; 44 or 49 cycles
  2291.  
  2292. main_TxState_Rest:
  2293.  
  2294. ; 21 cycles so far
  2295.  
  2296. ldd r20, Y + G_Transmitter + Tx_Counter
  2297. tst r20
  2298. breq 1f
  2299. dec r20
  2300. std Y + G_Transmitter + Tx_Counter, r20
  2301.  
  2302. rjmp main_Loop ; 30 cycles
  2303.  
  2304. 1: ldd r18, Y + G_Transmitter + Tx_TxBit + TxBit_HeadIx
  2305. ldd r19, Y + G_Transmitter + Tx_TxBit + TxBit_TailIx
  2306. cp r18, r19
  2307. brne 2f
  2308. ldi r20, TX_STATE_IDLE
  2309. std Y + G_Transmitter + Tx_State, r20
  2310. 2:
  2311. rjmp main_Loop
  2312.  
  2313. ; 35 or 37 cycles
  2314.  
  2315. main_Tx_BufferMarkSpace:
  2316. ; r19: Transmit run length ring buffer tail index
  2317. ; r20: Mark length in 32kHz ticks
  2318. ; r21: Space length in 32kHz ticks
  2319. ; Y: Global variables
  2320.  
  2321. clr r0
  2322. 1: ldiw X, TxRunLengthsRingBuffer
  2323. add XL, r19
  2324. adc XH, r1
  2325. st X, r20
  2326. inc r19
  2327. andi r19, TX_RING_BUFFER_INDEX_MASK
  2328. mov r20, r21
  2329. com r0
  2330. brne 1b
  2331. std Y + G_Transmitter + Tx_TxBit + TxBit_TailIx, r19
  2332. ret
  2333.  
  2334. ; 30 cycles including call
  2335.  
  2336. main_T1_Authentication:
  2337.  
  2338. ldd r20, Y + G_AESState
  2339. cpi r20, AES_STATE_BEGIN
  2340. brcc main_AES_IdleOrStartAES
  2341. sub r20, r2
  2342. brcs main_Trampoline_AES_Finished
  2343. ifhs
  2344. andi r20, 0xF6
  2345. std Y + G_AESState, r20
  2346. mov r21, r20
  2347. andi r21, 0x0F
  2348. breq main_AES_AddRoundKey
  2349. dec r21
  2350. breq main_AES_AdvanceRoundKey
  2351. cpi r21, 0x05
  2352. brcc main_AES_SubAndShift
  2353. dec r21
  2354. ; Fall though to main_AES_Mixcolumn.
  2355.  
  2356. main_AES_Mixcolumn:
  2357.  
  2358. ; 18 cycles so far
  2359. ; Mix a single column.
  2360. cpi r20, 0x05
  2361. brne 1f
  2362. ; Skip MixColumns in the final round.
  2363. std Y + G_AESState, r2
  2364. ldi r24, 0x36
  2365. rjmp main_AES_AdvanceRoundKey_RudeEntryForRound10
  2366. 1: lsl r21
  2367. lsl r21
  2368. ldiw X, AES_Matrix_M
  2369. add XL, r21
  2370. adc XH, r1
  2371. ; 27 cycles so far
  2372. rcall AES_MixColumn ; 68 + 8 cycles
  2373. rjmp main_Loop
  2374. ; 105 cycles
  2375.  
  2376. main_AES_SubAndShift:
  2377.  
  2378. ; 18 cycles so far
  2379. ; Substitute bytes and shift rows.
  2380. ldiw Y, AES_Matrix_M
  2381. ; 20 cycles so far
  2382. rcall AES_SubstituteAndShift ; 113 + 8 cycles
  2383. ldiw Y, Globals
  2384. rjmp main_Loop
  2385. ; 145 cycles
  2386.  
  2387. main_AES_AddRoundKey:
  2388.  
  2389. ; 14 cycles so far
  2390. ; Add the round key.
  2391. ldiw Z, AES_Matrix_W
  2392. ldiw X, AES_Matrix_M
  2393. ; 18 cycles so far
  2394. rcall Xor16B ; 112 + 8 cycles
  2395. rjmp main_Loop
  2396. ; 140 cycles
  2397.  
  2398. main_AES_AdvanceRoundKey:
  2399.  
  2400. ; 16 cycles so far
  2401. ; Advance the round key.
  2402. ldi r18, 0x1B
  2403. ldd r24, Y + G_AESRoundConstantByte
  2404. lsl r24
  2405. ifcs
  2406. eor r24, r18
  2407. std Y + G_AESRoundConstantByte, r24
  2408. main_AES_AdvanceRoundKey_RudeEntryForRound10:
  2409. ; 24 or 25 cycles so far
  2410. ldiw Y, AES_Matrix_W
  2411. rcall AES_AdvanceRoundKey ; 107 + 8 cycles
  2412. ldiw Y, Globals
  2413. rjmp main_Loop
  2414. ; 145 or 146 cycles
  2415.  
  2416. main_AES_StartEncryption:
  2417.  
  2418. ; 7 or 54 cycles so far
  2419. ldi r20, 0x8D
  2420. std Y + G_AESRoundConstantByte, r20
  2421. ldi r20, 0xA1
  2422. std Y + G_AESState, r20
  2423. ldiw Z, AES_Matrix_K
  2424. ldiw X, AES_Matrix_W
  2425. rjmp main_Copy16BAndLoop ; +73 cycles
  2426. ; 90 or 137 cycles
  2427.  
  2428. main_Trampoline_AES_Finished:
  2429.  
  2430. ; 7 cycles so far
  2431. rjmp main_AES_Finished
  2432.  
  2433. main_AES_IdleOrStartAES:
  2434.  
  2435. ; 5 cycles so far
  2436. breq main_AES_StartEncryption
  2437. ; Fall though to main_Auth_AES_Idle.
  2438.  
  2439. main_AES_Idle:
  2440.  
  2441. ; 6 cycles so far
  2442. ldd r20, Y + G_AuthenticationState
  2443. cpi r20, AUTH_STATE_CMDMSG_XOR_K2
  2444. breq main_Auth_CmdMsg_XorK2 ; 11 cycles
  2445. cpi r20, AUTH_STATE_CMDMSG_LOAD_K
  2446. breq main_Auth_CmdMsg_LoadK ; 13 cycles
  2447. cpi r20, AUTH_STATE_K2_CLEAR
  2448. breq main_Auth_K2_Clear ; 15 cycles
  2449. cpi r20, AUTH_STATE_CMDMSG_BEGIN
  2450. breq main_Trampoline_Auth_CmdMsg_Begin ; 17 cycles
  2451. cpi r20, AUTH_STATE_K2_BEGIN
  2452. breq main_Auth_K2_Begin ; 19 cycles
  2453. ; 18 cycles so far
  2454. ; Fall though to main_Auth_Idle.
  2455.  
  2456. main_Auth_Idle:
  2457.  
  2458. ; 18 cycles so far
  2459. ldiw Z, AuthenticationData
  2460. ldd r0, Z + AD_HaveK2
  2461. tst r0
  2462. breq main_Auth_K2_Begin ; 25 cycles
  2463. rjmp main_Loop ; 26 cycles
  2464.  
  2465. main_Auth_CmdMsg_XorK2:
  2466.  
  2467. ; 11 cycles so far
  2468. ldiw Z, AuthenticationData + AD_CMACSubkeyK2
  2469. ldiw X, AES_Matrix_M
  2470. rcall Xor16B ; 112 + 8 cycles
  2471. ldi r20, AUTH_STATE_CMDMSG_CMAC
  2472. std Y + G_AuthenticationState, r20
  2473. ldi r20, AES_STATE_BEGIN
  2474. std Y + G_AESState, r20
  2475. rjmp main_Loop
  2476. ; 143 cycles
  2477.  
  2478. main_Auth_CmdMsg_LoadK:
  2479.  
  2480. ; 13 cycles so far
  2481. ; For a final block that was short before padding, AES-CMAC
  2482. ; requires xoring with the subkey K2.
  2483. ldi r20, AUTH_STATE_CMDMSG_XOR_K2
  2484. std Y + G_AuthenticationState, r20
  2485. ; Right now though, load K with the (secret) CMAC key.
  2486. ldiw Z, AuthenticationData + AD_CMACKey
  2487. ldiw X, AES_Matrix_K
  2488. rjmp main_Copy16BAndLoop ; 69 cycles
  2489. ; 91 cycles
  2490.  
  2491. main_Trampoline_Auth_CmdMsg_Begin:
  2492.  
  2493. ; 17 cycles so far
  2494. rjmp main_Auth_CmdMsg_Begin
  2495.  
  2496. main_Auth_K2_Begin:
  2497.  
  2498. ; 19 or 25 cycles so far
  2499. ldi r20, AUTH_STATE_K2_CLEAR
  2500. std Y + G_AuthenticationState, r20
  2501. ldiw Z, AuthenticationData + AD_CMACKey
  2502. ldiw X, AES_Matrix_K
  2503. rjmp main_Copy16BAndLoop ; +73 cycles
  2504. ; 82 or 88 cycles
  2505.  
  2506. main_Auth_K2_Clear:
  2507.  
  2508. ; 15 cycles so far
  2509. ldiw X, AES_Matrix_M
  2510. st X+, r1
  2511. st X+, r1
  2512. st X+, r1
  2513. st X+, r1
  2514. st X+, r1
  2515. st X+, r1
  2516. st X+, r1
  2517. st X+, r1
  2518. st X+, r1
  2519. st X+, r1
  2520. st X+, r1
  2521. st X+, r1
  2522. st X+, r1
  2523. st X+, r1
  2524. st X+, r1
  2525. st X+, r1
  2526. ldi r20, AUTH_STATE_K2_GEN_K1
  2527. std Y + G_AuthenticationState, r20
  2528. ; 52 cycles so far
  2529. rjmp main_AES_StartEncryption
  2530. ; 139 cycles
  2531.  
  2532. main_AES_Finished:
  2533.  
  2534. ; 9 cycles so far
  2535. ldd r20, Y + G_AuthenticationState
  2536. cpi r20, AUTH_STATE_CMDMSG_CMAC
  2537. ifeq
  2538. rjmp main_Auth_CmdMsg_WriteCMAC ; 15 cycles
  2539. cpi r20, AUTH_STATE_K2_GEN_K2
  2540. breq main_Auth_K2_GenK2 ; 17 cycles
  2541. cpi r20, AUTH_STATE_K2_GEN_K1
  2542. brne main_Auth_End ; 19 cycles
  2543. ; Fall through to main_Auth_K2_GenK1.
  2544.  
  2545. main_Auth_K2_GenK1:
  2546.  
  2547. ; 18 cycles so far
  2548. ldiw X, AES_Matrix_M
  2549. movw ZL, XL
  2550. rcall AES_AdvanceCMACSubKey ; 96 + 8 cycles
  2551. ldi r20, AUTH_STATE_K2_GEN_K2
  2552. std Y + G_AuthenticationState, r20
  2553. rjmp main_Loop
  2554. ; 130 cycles
  2555.  
  2556. main_Auth_K2_GenK2:
  2557.  
  2558. ; 17 cycles so far
  2559. ldiw X, AES_Matrix_M
  2560. ldiw Z, AuthenticationData + AD_CMACSubkeyK2
  2561. std Z + AD_HaveK2 - AD_CMACSubkeyK2, r2
  2562. rcall AES_AdvanceCMACSubKey ; 96 + 8 cycles
  2563. ; 127 cycles so far
  2564. ; Fall though to main_Auth_End.
  2565.  
  2566. main_Auth_End:
  2567.  
  2568. ; 127 or 19 cycles so far
  2569. ldi r20, AUTH_STATE_IDLE
  2570. std Y + G_AuthenticationState, r20
  2571. ldi r20, AES_STATE_IDLE
  2572. std Y + G_AESState, r20
  2573. rjmp main_Loop
  2574. ; 135 or 27 cycles
  2575.  
  2576. main_Auth_CmdMsg_Begin:
  2577.  
  2578. ; 19 cycles so far
  2579. ldiw Z, AuthenticationData
  2580. ; Compose the message, leaving the CMAC to be computed and written
  2581. ; while the transmission routine is still sending the payload.
  2582. ldd r8, Z + AD_SerialNumber + 0
  2583. ldd r9, Z + AD_SerialNumber + 1
  2584. ldd r10, Z + AD_SerialNumber + 2
  2585. ldd r11, Z + AD_SerialNumber + 3
  2586. std Y + G_Transmitter + Tx_Data + CmdMsg_SerialNumber + 0, r11
  2587. std Y + G_Transmitter + Tx_Data + CmdMsg_SerialNumber + 1, r10
  2588. std Y + G_Transmitter + Tx_Data + CmdMsg_SerialNumber + 2, r9
  2589. std Y + G_Transmitter + Tx_Data + CmdMsg_SerialNumber + 3, r8
  2590. ldd r16, Z + AD_SequenceNumber + 0
  2591. ldd r17, Z + AD_SequenceNumber + 1
  2592. ldd r18, Z + AD_SequenceNumber + 2
  2593. ldd r19, Z + AD_SequenceNumber + 3
  2594. std Y + G_Transmitter + Tx_Data + CmdMsg_SequenceNumber + 0, r19
  2595. std Y + G_Transmitter + Tx_Data + CmdMsg_SequenceNumber + 1, r18
  2596. std Y + G_Transmitter + Tx_Data + CmdMsg_SequenceNumber + 2, r17
  2597. std Y + G_Transmitter + Tx_Data + CmdMsg_SequenceNumber + 3, r16
  2598. ldd r20, Y + G_Transmitter + Tx_Data + CmdMsg_Command
  2599. ldd r21, Y + G_Transmitter + Tx_Data + CmdMsg_Parameter
  2600. ; Leave CmdMsg_Command and CmdMsg_Parameter as they are.
  2601. ; 47 cycles so far
  2602. ; AES-CMAC requires a short message block to be padded to the
  2603. ; full 16 bytes with a bit one followed by however many bit
  2604. ; zeros will fit.
  2605. ldiw X, AES_Matrix_M
  2606. st X+, r11
  2607. st X+, r10
  2608. st X+, r9
  2609. st X+, r8
  2610. st X+, r19
  2611. st X+, r18
  2612. st X+, r17
  2613. st X+, r16
  2614. st X+, r20
  2615. st X+, r21
  2616. ldi r20, 0x80
  2617. st X+, r20
  2618. st X+, r1
  2619. st X+, r1
  2620. st X+, r1
  2621. st X+, r1
  2622. st X+, r1
  2623. ; 73 cycles so far
  2624. ; Advance the sequence number to foil replay attacks.
  2625. add r16, r2
  2626. adc r17, r1
  2627. adc r18, r1
  2628. adc r19, r1
  2629. std Z + AD_SequenceNumber + 0, r16
  2630. std Z + AD_SequenceNumber + 1, r17
  2631. std Z + AD_SequenceNumber + 2, r18
  2632. std Z + AD_SequenceNumber + 3, r19
  2633. ldd r16, Y + G_EWLState + EWLS_UpdateCountdown
  2634. sub r16, r2
  2635. adc r16, r1
  2636. std Y + G_EWLState + EWLS_UpdateCountdown, r16
  2637. ldi r20, 14
  2638. std Y + G_Transmitter + Tx_NumBytesToSend, r20
  2639. ldi r20, TX_STATE_BEGIN
  2640. std Y + G_Transmitter + Tx_State, r20
  2641. ldi r20, AUTH_STATE_CMDMSG_LOAD_K
  2642. std Y + G_AuthenticationState, r20
  2643. rjmp main_Loop
  2644. ; 102 cycles
  2645.  
  2646. main_Auth_CmdMsg_WriteCMAC:
  2647.  
  2648. ; 15 cycles so far
  2649. ldi r20, AUTH_STATE_IDLE
  2650. std Y + G_AuthenticationState, r20
  2651. ldi r20, AES_STATE_IDLE
  2652. std Y + G_AESState, r20
  2653. ldiw X, AES_Matrix_M
  2654. ldiw Z, Globals + G_Transmitter + Tx_Data
  2655. ld r0, X+
  2656. std Z + CmdMsg_CMAC + 0, r0
  2657. ld r0, X+
  2658. std Z + CmdMsg_CMAC + 1, r0
  2659. ld r0, X+
  2660. std Z + CmdMsg_CMAC + 2, r0
  2661. ld r0, X+
  2662. std Z + CmdMsg_CMAC + 3, r0
  2663. ; 41 cycles
  2664. rjmp main_Auth_End
  2665. ; 43 cycles
  2666.  
  2667. main_Copy16BAndLoop:
  2668.  
  2669. 1: ld r0, Z+
  2670. st X+, r0
  2671. ld r0, Z+
  2672. st X+, r0
  2673. ld r0, Z+
  2674. st X+, r0
  2675. ld r0, Z+
  2676. st X+, r0
  2677. ld r0, Z+
  2678. st X+, r0
  2679. ld r0, Z+
  2680. st X+, r0
  2681. ld r0, Z+
  2682. st X+, r0
  2683. ld r0, Z+
  2684. st X+, r0
  2685. com r1
  2686. brne 1b
  2687. rjmp main_Loop
  2688.  
  2689. ; Max 146 cycles
  2690.  
  2691. main_T2:
  2692.  
  2693. rjmp main_Loop
  2694.  
  2695. main_T3:
  2696.  
  2697. rjmp main_Loop
  2698.  
  2699. main_T2_TeachAndSoundSelectTasks:
  2700.  
  2701. sbrs r4, 4
  2702. rjmp 1f
  2703. sbrc r4, 3
  2704. rjmp main_T2_TASSTasks_T0_ADCInputAndTASSTimers ; 5 cycles
  2705. rjmp main_T2_TASSTasks_T1_ButtonLogic ; 6 cycles
  2706. 1: sbrc r4, 3
  2707. rjmp main_T2_TASSTasks_T2_SaveAndTransmit ; 6 cycles
  2708. rjmp main_T2_TASSTasks_T3 ; 7 cycles
  2709.  
  2710. ; Max 7 cycles
  2711.  
  2712.  
  2713. main_T2_TASSTasks_T0_ADCInputAndTASSTimers:
  2714.  
  2715. ; The three buttons wired to ADC1 on pin 7 are connected to resistors.
  2716. ;
  2717. ; Vcc -----*---------------------------
  2718. ; |
  2719. ; R4 [ ]
  2720. ; |
  2721. ; *---------*---------*------> ADC input
  2722. ; | | |
  2723. ; R3 [ ] R2 [ ] R1 [ ]
  2724. ; | | | R1 = 6.8k ohms
  2725. ; | o | o | o R2 = 1.8k ohms
  2726. ; TEACH [| SS2 [| SS1 [| R3 = 220 ohms
  2727. ; | o | o | o R4 = 3.0k ohms or 3.3k ohms
  2728. ; | | |
  2729. ; GND -----*---------*---------*------
  2730. ;
  2731. ; As power supply fluctuations and contact resistance can affect the
  2732. ; ADC readings, it is best to require only single-button combinations
  2733. ; be interpreted.
  2734. ;
  2735. ; TEACH SS2 SS1 ADC ADCH Range
  2736. ; 0 0 0 100% 255 216..255
  2737. ; 0 0 1 69% 177 137..215
  2738. ; 0 1 0 37% 96 57..136
  2739. ; 1 x x <7% <18 0..56
  2740.  
  2741. in r17, _SFR_IO_ADDR(ADCH)
  2742. sbi _SFR_IO_ADDR(ADCSRA), ADSC
  2743. cpi r17, 137
  2744. brcs 1f
  2745. ldi r16, 0b000
  2746. cpi r17, 216
  2747. adc r16, r1
  2748. rjmp 2f
  2749. 1: ldi r16, 0b010
  2750. cpi r17, 57
  2751. ifcs
  2752. ldi r16, 0b100
  2753. 2: ; 9 cycles so far
  2754. ldd r0, Y + G_ADCButtons + ADCB_ProvisionalState
  2755. ldd r17, Y + G_ADCButtons + ADCB_AcceptanceCountdown
  2756. std Y + G_ADCButtons + ADCB_ProvisionalState, r16
  2757. cpse r0, r16
  2758. ldi r17, BUTTON_DB_DELAY_ADC
  2759. sub r17, r2
  2760. adc r17, r1
  2761. std Y + G_ADCButtons + ADCB_AcceptanceCountdown, r17
  2762. ldd r17, Y + G_ADCButtons + ADCB_State
  2763. brne . + 2
  2764. mov r17, r16
  2765. std Y + G_ADCButtons + ADCB_State, r17
  2766. ldd r0, Y + G_ADCButtons + ADCB_MutexState
  2767. tst r17
  2768. breq 3f
  2769. tst r0
  2770. ifeq
  2771. 3: mov r0, r17
  2772. std Y + G_ADCButtons + ADCB_MutexState, r0
  2773.  
  2774. ; Max 36 cycles so far
  2775.  
  2776. ldiw Z, TASSState
  2777. ldd r8, Y + G_SlowClocks
  2778. mov r7, r8
  2779. bst r5, 3 ; Counting at 15.625Hz
  2780. bld r8, bCLOCK_TASS
  2781. std Y + G_SlowClocks, r8
  2782. eor r7, r8
  2783. bst r7, bCLOCK_TASS
  2784. clr r7
  2785. bld r7, 0
  2786. ldd r16, Z + TASS_LongPressCountdown
  2787. sub r16, r7
  2788. adc r16, r1
  2789. ldd r10, Z + TASS_SS1LongPressCountdown
  2790. sub r10, r7
  2791. adc r10, r1
  2792. ldd r11, Z + TASS_SS2LongPressCountdown
  2793. sub r11, r7
  2794. adc r11, r1
  2795. ldd r24, Y + G_TaskFlags1
  2796. ldd r25, Y + G_TaskFlags2
  2797. ldd r22, Z + TASS_PrimarySoundTestCountdown
  2798. tst r22
  2799. breq 1f
  2800. sub r22, r7
  2801. ifeq
  2802. ori r24, mTASK1_SEND_PRIMARY_SOUND_B
  2803. 1: ldd r23, Z + TASS_SecondarySoundTestCountdown
  2804. tst r23
  2805. breq 2f
  2806. sub r23, r7
  2807. ifeq
  2808. ori r24, mTASK1_SEND_SECONDARY_SOUND_B
  2809. 2: ldd r18, Y + G_SensorActivationSenses
  2810. ldd r19, Z + TASS_NewSensorActivationSenses
  2811. ldd r20, Z + TASS_Sensor1InversionCountdown
  2812. ldd r21, Z + TASS_Sensor2InversionCountdown
  2813. tst r20
  2814. breq 3f
  2815. sub r20, r7
  2816. brne 3f
  2817. bst r19, 0
  2818. bld r18, 0
  2819. 3: tst r21
  2820. breq 4f
  2821. sub r21, r7
  2822. brne 4f
  2823. bst r19, 1
  2824. bld r18, 1
  2825. 4: ldd r9, Z + TASS_PingIntervalCountdown
  2826. sub r9, r7
  2827. adc r9, r1
  2828. std Z + TASS_PingIntervalCountdown, r9
  2829. std Y + G_SensorActivationSenses, r18
  2830. std Z + TASS_Sensor1InversionCountdown, r20
  2831. std Z + TASS_Sensor2InversionCountdown, r21
  2832. std Z + TASS_LongPressCountdown, r16
  2833. std Z + TASS_SS1LongPressCountdown, r10
  2834. std Z + TASS_SS2LongPressCountdown, r11
  2835. std Z + TASS_PrimarySoundTestCountdown, r22
  2836. std Z + TASS_SecondarySoundTestCountdown, r23
  2837. std Y + G_TaskFlags1, r24
  2838. std Y + G_TaskFlags2, r25
  2839. rjmp main_Loop
  2840.  
  2841. ; Max 36 + 91 = 127 cycles
  2842.  
  2843. main_T2_TASSTasks_T1_ButtonLogic:
  2844.  
  2845. ; Handle the Teach and Sound Select logic, along with the
  2846. ; special functions. Special functions include sensor activation
  2847. ; sense inversion, the self-timer for a delayed and unencrypted
  2848. ; teach message transmission and pinging mode.
  2849. ldiw Z, TASSState
  2850. ldd r0, Y + G_ADCButtons + ADCB_MutexState
  2851. ldd r7, Z + TASS_LastButtonsState
  2852. std Z + TASS_LastButtonsState, r0
  2853. ldd r24, Y + G_TaskFlags1
  2854. ldd r25, Y + G_TaskFlags2
  2855. ldd r16, Z + TASS_LongPressCountdown
  2856. ldd r10, Z + TASS_SS1LongPressCountdown
  2857. ldd r11, Z + TASS_SS2LongPressCountdown
  2858. ldd r22, Z + TASS_PrimarySoundTestCountdown
  2859. ldd r23, Z + TASS_SecondarySoundTestCountdown
  2860. ldd r17, Z + TASS_TeachOrPingState
  2861. cpse r17, r1
  2862. rjmp 9f
  2863. ; No particular mode is active.
  2864. sbrc r0, 2
  2865. rjmp 11f ; The Teach button has just been pressed.
  2866. ; The Teach button is not currently pressed.
  2867. ; 28 cycles so far
  2868. ldi r18, SOUND_SELECT_BUTTON_VERY_LONG_PRESS_TIME
  2869. mov r9, r18
  2870. ldi r18, SOUND_SELECT_BUTTON_VERY_LONG_PRESS_TIME - \
  2871. SOUND_SELECT_BUTTON_LONG_PRESS_TIME
  2872. mov r12, r18
  2873. ldi r16, TEACH_BUTTON_LONG_PRESS_TIME
  2874. cpse r0, r1
  2875. rjmp 2f
  2876. cpse r7, r1
  2877. rjmp 2f
  2878. ; No button is being pressed and a button release did not just occur.
  2879. ; Flash the LED during a transmission.
  2880. ldd r8, Y + G_Transmitter + Tx_NumBytesSent
  2881. com r8
  2882. ldd r18, Y + G_Transmitter + Tx_State
  2883. cpi r18, TX_STATE_SYNC
  2884. breq 1f
  2885. cpi r18, TX_STATE_DATA
  2886. breq 1f
  2887. clr r8
  2888. 1: bst r8, 0
  2889. in r8, _SFR_IO_ADDR(PORTB)
  2890. bld r8, OUTPUT_BIT_ACTIVITY_LED
  2891. out _SFR_IO_ADDR(PORTB), r8
  2892. mov r10, r9
  2893. mov r11, r9
  2894. rjmp 8f ; 55 cycles
  2895. 2: ; At least one of the Sound Select buttons is currently pressed
  2896. ; or has just been released.
  2897. ; Max 38 cycles so far
  2898. std Z + TASS_NumTeachMessagesToSend, r1
  2899. std Z + TASS_SuppressKeyRandomisation, r1
  2900. ; See if a sound select button has been pressed for a very long time.
  2901. ; That is the silly walk to active pinging mode.
  2902. tst r10
  2903. ifeq
  2904. rjmp 15f
  2905. tst r11
  2906. ifeq
  2907. rjmp 15f
  2908. ; Flash the activity LED if one or both sound select buttons
  2909. ; is held down for long, else keep it lit.
  2910. bst r5, 3
  2911. cp r10, r12
  2912. brcs 3f
  2913. cp r11, r12
  2914. brcs 3f
  2915. set
  2916. 3: in r8, _SFR_IO_ADDR(PORTB)
  2917. bld r8, OUTPUT_BIT_ACTIVITY_LED
  2918. out _SFR_IO_ADDR(PORTB), r8
  2919. ; Prepare to advance a sound index or toggle a sensor sense.
  2920. ; Max 57 cycles so far
  2921. ldd r8, Z + TASS_NewSensorActivationSenses
  2922. ldd r18, Y + G_SoundIndices
  2923. com r7
  2924. or r7, r0
  2925. ; Max 63 cycles so far
  2926. ; See if the primary sound select button has just been released.
  2927. sbrc r7, 0
  2928. rjmp 5f
  2929. cp r10, r12
  2930. brcc 4f
  2931. ; Toggle the primary sensor sense.
  2932. eor r8, r2
  2933. ldi r19, SENSE_INVERSION_DELAY
  2934. std Z + TASS_Sensor1InversionCountdown, r19
  2935. sbrs r8, 0
  2936. ori r25, mTASK2_SAVE_SENSOR_ACTIVATION_SENSES |\
  2937. mTASK2_SEND_PRIMARY_SENSE_NORMAL
  2938. sbrc r8, 0
  2939. ori r25, mTASK2_SAVE_SENSOR_ACTIVATION_SENSES |\
  2940. mTASK2_SEND_PRIMARY_SENSE_INVERTED
  2941. rjmp 5f
  2942. 4: ; Advance the primary sound index.
  2943. add r18, r2
  2944. ifhs
  2945. subi r18, 16
  2946. ori r24, mTASK1_SAVE_SOUND_INDICES | mTASK1_SEND_PRIMARY_SOUND_A
  2947. ldi r22, ACTIVATION_SOUND_TO_DEACTIVATION_SOUND_DELAY
  2948. 5: sbrs r0, 0
  2949. mov r10, r9
  2950. ; Max 79 cycles so far
  2951. ; See if the secondary sound select button has just been released.
  2952. sbrc r7, 1
  2953. rjmp 7f
  2954. cp r11, r12
  2955. brcc 6f
  2956. ; Toggle the secondary sensor sense.
  2957. ldi r19, 2
  2958. eor r8, r19
  2959. ldi r19, SENSE_INVERSION_DELAY
  2960. std Z + TASS_Sensor2InversionCountdown, r19
  2961. sbrs r8, 1
  2962. ori r25, mTASK2_SAVE_SENSOR_ACTIVATION_SENSES |\
  2963. mTASK2_SEND_SECONDARY_SENSE_NORMAL
  2964. sbrc r8, 1
  2965. ori r25, mTASK2_SAVE_SENSOR_ACTIVATION_SENSES |\
  2966. mTASK2_SEND_SECONDARY_SENSE_INVERTED
  2967. rjmp 7f
  2968. 6: ; Advance the secondary sound index.
  2969. subi r18, -16
  2970. ori r24, mTASK1_SAVE_SOUND_INDICES | mTASK1_SEND_SECONDARY_SOUND_A
  2971. ldi r23, ACTIVATION_SOUND_TO_DEACTIVATION_SOUND_DELAY
  2972. 7: sbrs r0, 1
  2973. mov r11, r9
  2974. std Y + G_SoundIndices, r18
  2975. std Z + TASS_NewSensorActivationSenses, r8
  2976. ; Max 100 cycles so far
  2977. ; Fall through...
  2978. 8: std Z + TASS_LongPressCountdown, r16
  2979. std Z + TASS_SS1LongPressCountdown, r10
  2980. std Z + TASS_SS2LongPressCountdown, r11
  2981. std Z + TASS_TeachOrPingState, r17
  2982. std Z + TASS_PrimarySoundTestCountdown, r22
  2983. std Z + TASS_SecondarySoundTestCountdown, r23
  2984. std Y + G_TaskFlags1, r24
  2985. std Y + G_TaskFlags2, r25
  2986. rjmp main_Loop ; Max 118 cycles
  2987. 9: ; A special mode is active.
  2988. ; 27 cycles so far
  2989. mov r10, r3
  2990. mov r11, r3
  2991. cpi r17, TASS_STATE_TEACH_PRESSED
  2992. breq 11f
  2993. cpi r17, TASS_STATE_TEACH_LONG_PRESSED
  2994. breq 12f
  2995. cpi r17, TASS_STATE_DELAYED_TEACH
  2996. breq 13f
  2997. cpi r17, TASS_STATE_SILLY_WALK_FOR_PING
  2998. breq 15f
  2999. cpi r17, TASS_STATE_PINGING
  3000. breq 16f
  3001. ; Assume TASS_STATE_WAIT_FOR_RELEASE and fall through.
  3002. 10: ; To lessen the chance of accidental input, wait for all buttons
  3003. ; to be released.
  3004. ; 39 cycles so far
  3005. sbi _SFR_IO_ADDR(PORTB), OUTPUT_BIT_ACTIVITY_LED
  3006. cpse r0, r1
  3007. rjmp 8b
  3008. cbi _SFR_IO_ADDR(PORTB), OUTPUT_BIT_ACTIVITY_LED
  3009. ldi r17, TASS_STATE_IDLE
  3010. ser r16
  3011. mov r10, r16
  3012. mov r11, r16
  3013. rjmp 8b ; 49 cycles
  3014. 11: ; The Teach button is pressed, but not for very long yet.
  3015. ; 32 or 29 cycles so far
  3016. ldi r17, TASS_STATE_TEACH_PRESSED
  3017. std Z + TASS_NumTeachMessagesToSend, r1
  3018. std Z + TASS_SuppressKeyEncryption, r1
  3019. sbi _SFR_IO_ADDR(PORTB), OUTPUT_BIT_ACTIVITY_LED
  3020. tst r16
  3021. ifeq
  3022. ldi r17, TASS_STATE_TEACH_LONG_PRESSED
  3023. cpse r0, r1
  3024. rjmp 8b ; Max 44 cycles
  3025. rjmp 18f ; Max 45 cycles
  3026. 12: ; The Teach button is being subject to a long press.
  3027. ; 34 cycles so far
  3028. bst r5, 3
  3029. in r8, _SFR_IO_ADDR(PORTB)
  3030. bld r8, OUTPUT_BIT_ACTIVITY_LED
  3031. out _SFR_IO_ADDR(PORTB), r8
  3032. cpse r0, r1
  3033. rjmp 8b ; 41 cycles
  3034. cbi _SFR_IO_ADDR(PORTB), OUTPUT_BIT_ACTIVITY_LED
  3035. ldi r17, TASS_STATE_DELAYED_TEACH
  3036. ldi r16, 176 ; About 11 seconds
  3037. std Z + TASS_SuppressKeyEncryption, r2
  3038. rjmp 8b ; 47 cycles
  3039. 13: ; The self-timer for the delayed teach function is counting down.
  3040. ; 36 cycles so far
  3041. tst r0
  3042. brne 17f
  3043. tst r16
  3044. breq 18f
  3045. ; Flash the self-timer LED.
  3046. mov r18, r16
  3047. ldi r19, 0x0F
  3048. cpi r18, 32
  3049. brcc 14f
  3050. ldi r19, 0x03
  3051. sbrs r18, 4
  3052. lsr r19
  3053. 14: clt
  3054. and r18, r19
  3055. ifeq
  3056. set
  3057. in r8, _SFR_IO_ADDR(PORTB)
  3058. bld r8, OUTPUT_BIT_ACTIVITY_LED
  3059. out _SFR_IO_ADDR(PORTB), r8
  3060. rjmp 8b ; Max 56 cycles
  3061. 15: ; The silly walk to activate pinging mode is in progress.
  3062. ; Max 49 cycles so far
  3063. ldi r17, TASS_STATE_SILLY_WALK_FOR_PING
  3064. bst r5, 2
  3065. in r8, _SFR_IO_ADDR(PORTB)
  3066. bld r8, OUTPUT_BIT_ACTIVITY_LED
  3067. out _SFR_IO_ADDR(PORTB), r8
  3068. cpse r0, r1
  3069. rjmp 8b ; Max 57 cycles
  3070. cbi _SFR_IO_ADDR(PORTB), OUTPUT_BIT_ACTIVITY_LED
  3071. ldi r18, PING_START_DELAY
  3072. std Z + TASS_PingIntervalCountdown, r18
  3073. ldi r18, 150 ; 150 pings 4 seconds apart (10 minutes)
  3074. std Z + TASS_NumPingsToSend, r18
  3075. ldi r17, TASS_STATE_PINGING
  3076. rjmp 8b ; Max 66 cycles
  3077. 16: ; Pinging mode is active.
  3078. ; 40 cycles so far
  3079. tst r0
  3080. brne 17f
  3081. bst r5, 7
  3082. in r8, _SFR_IO_ADDR(PORTB)
  3083. bld r8, OUTPUT_BIT_ACTIVITY_LED
  3084. out _SFR_IO_ADDR(PORTB), r8
  3085. ldd r18, Z + TASS_NumPingsToSend
  3086. tst r18
  3087. breq 17f ; 51 cycles
  3088. ldd r19, Z + TASS_PingIntervalCountdown
  3089. cpse r19, r1
  3090. rjmp 8b ; 55 cycles
  3091. ldi r19, PING_INTERVAL_DOUBLED >> 1
  3092. .if PING_INTERVAL_DOUBLED & 1
  3093. sbrc r6, 1
  3094. inc r19
  3095. .endif
  3096. std Z + TASS_PingIntervalCountdown, r19
  3097. ori r25, mTASK2_SEND_PING
  3098. dec r18
  3099. std Z + TASS_NumPingsToSend, r18
  3100. breq 17f ; 65 cycles
  3101. rjmp 8b ; 66 cycles
  3102. 17: ; 65 or 39 cycles so far
  3103. ldi r17, TASS_STATE_WAIT_FOR_RELEASE
  3104. rjmp 8b ; Max 68 cycles
  3105. 18: ; Issue the teach message!
  3106. ; 45 or 41 cycles so far
  3107. cbi _SFR_IO_ADDR(PORTB), OUTPUT_BIT_ACTIVITY_LED
  3108. ser r16
  3109. ldi r17, TASS_STATE_IDLE
  3110. clr r22
  3111. clr r23
  3112. ori r24, mTASK1_SEND_TEACH_MESSAGE
  3113. andi r24, ~(mTASK1_SEND_PRIMARY_SOUND_A |\
  3114. mTASK1_SEND_PRIMARY_SOUND_B |\
  3115. mTASK1_SEND_SECONDARY_SOUND_A |\
  3116. mTASK1_SEND_SECONDARY_SOUND_B)
  3117. ldi r18, 5
  3118. std Z + TASS_NumTeachMessagesToSend, r18
  3119. ; Max 55 cycles so far
  3120. rjmp 8b
  3121.  
  3122. ; Max 118 cycles
  3123.  
  3124. main_T2_TASSTasks_T2_SaveAndTransmit:
  3125.  
  3126. ldd r24, Y + G_TaskFlags1
  3127. ldd r25, Y + G_TaskFlags2
  3128.  
  3129. sbic _SFR_IO_ADDR(EECR), EEPE
  3130. rjmp 2f
  3131.  
  3132. sbrs r24, bTASK1_SAVE_SOUND_INDICES
  3133. rjmp 1f
  3134. ldiw X, EEPROM_InvSoundIndices
  3135. ldd r0, Y + G_SoundIndices
  3136. com r0
  3137. rcall WriteEEPROMByte ; 23 cycles
  3138. andi r24, ~(mTASK1_SAVE_SOUND_INDICES)
  3139. rjmp 2f ; 39 cycles
  3140.  
  3141. 1: sbrs r25, bTASK2_SAVE_SENSOR_ACTIVATION_SENSES
  3142. rjmp 2f
  3143. ldiw X, EEPROM_SensorActivationSenses
  3144. lds r0, TASSState + TASS_NewSensorActivationSenses
  3145. andi r25, ~(mTASK2_SAVE_SENSOR_ACTIVATION_SENSES)
  3146. rcall WriteEEPROMByte ; 23 cycles
  3147. ; Max 39 cycles so far
  3148. ; Fall through
  3149.  
  3150. 2: ; Max 39 cycles so far
  3151. ldd r16, Y + G_Transmitter + Tx_State
  3152. cpi r16, TX_STATE_IDLE
  3153. brne 8f
  3154. ldd r16, Y + G_AuthenticationState
  3155. cpi r16, AUTH_STATE_IDLE
  3156. brne 8f
  3157. ldd r16, Y + G_AESState
  3158. cpi r16, AES_STATE_IDLE
  3159. brne 8f
  3160. ; Max 51 cycles so far
  3161. ldd r17, Y + G_SoundIndices
  3162. sbrc r24, bTASK1_SEND_PRIMARY_SOUND_A
  3163. rjmp 3f
  3164. sbrc r24, bTASK1_SEND_PRIMARY_SOUND_B
  3165. rjmp 4f
  3166. sbrc r24, bTASK1_SEND_SECONDARY_SOUND_A
  3167. rjmp 5f
  3168. sbrc r24, bTASK1_SEND_SECONDARY_SOUND_B
  3169. rjmp 6f
  3170. sbrc r24, bTASK1_SEND_TEACH_MESSAGE
  3171. rjmp 14f
  3172. sbrc r25, bTASK2_SEND_PRIMARY_SENSE_NORMAL
  3173. rjmp 9f
  3174. sbrc r25, bTASK2_SEND_PRIMARY_SENSE_INVERTED
  3175. rjmp 10f
  3176. sbrc r25, bTASK2_SEND_SECONDARY_SENSE_NORMAL
  3177. rjmp 11f
  3178. sbrc r25, bTASK2_SEND_SECONDARY_SENSE_INVERTED
  3179. rjmp 12f
  3180. sbrc r25, bTASK2_SEND_PING
  3181. rjmp 13f
  3182. rjmp 8f
  3183.  
  3184. 3: ; Activation sound for primary sensor
  3185. ; Max 56 cycles so far
  3186. andi r24, ~(mTASK1_SEND_PRIMARY_SOUND_A)
  3187. ldi r16, 0b0101
  3188. rjmp 7f
  3189.  
  3190. 4: ; Deactivation sound for primary sensor
  3191. ; Max 58 cycles so far
  3192. andi r24, ~(mTASK1_SEND_PRIMARY_SOUND_B)
  3193. ldi r16, 0b0100
  3194. rjmp 7f
  3195.  
  3196. 5: ; Activation sound for secondary sensor
  3197. ; Max 60 cycles so far
  3198. andi r24, ~(mTASK1_SEND_SECONDARY_SOUND_A)
  3199. ldi r16, 0b0111
  3200. swap r17
  3201. rjmp 7f
  3202.  
  3203. 6: ; Deactivation sound for secondary sensor
  3204. ; Max 62 cycles so far
  3205. andi r24, ~(mTASK1_SEND_SECONDARY_SOUND_B)
  3206. ldi r16, 0b0110
  3207. swap r17
  3208. ; Fall through to transmission initiation.
  3209.  
  3210. 7: ; Max 65 cycles so far
  3211. ; Max 79 cycles
  3212. andi r17, 0x0F
  3213. std Y + G_Transmitter + Tx_Data + CmdMsg_Command, r16
  3214. std Y + G_Transmitter + Tx_Data + CmdMsg_Parameter, r17
  3215. ldi r16, AUTH_STATE_CMDMSG_BEGIN
  3216. std Y + G_AuthenticationState, r16
  3217. rcall MutateRandomData ; 21 + 8 cycles
  3218. ; Max 116 cycles so far
  3219. ; Fall through to the final part of the routine.
  3220.  
  3221. 8: ; Max 116 cycles so far
  3222. std Y + G_TaskFlags1, r24
  3223. std Y + G_TaskFlags2, r25
  3224. rjmp main_Loop ; Max 122 cycles
  3225.  
  3226. 9: ; Report that the primary sensor is to be active high.
  3227. ; Max 66 cycles so far
  3228. andi r25, ~(mTASK2_SEND_PRIMARY_SENSE_NORMAL)
  3229. ldi r16, 0b1000
  3230. ldi r17, 0
  3231. rjmp 7b
  3232.  
  3233. 10: ; Report that the primary sensor is to be active low.
  3234. ; Max 68 cycles so far
  3235. andi r25, ~(mTASK2_SEND_PRIMARY_SENSE_INVERTED)
  3236. ldi r16, 0b1001
  3237. ldi r17, 1
  3238. rjmp 7b
  3239.  
  3240. 11: ; Report that the secondary sensor is to be active high.
  3241. ; Max 70 cycles so far
  3242. andi r25, ~(mTASK2_SEND_SECONDARY_SENSE_NORMAL)
  3243. ldi r16, 0b1010
  3244. ldi r17, 0
  3245. rjmp 7b
  3246.  
  3247. 12: ; Report that the secondary sensor is to be active low.
  3248. ; Max 72 cycles so far
  3249. andi r25, ~(mTASK2_SEND_SECONDARY_SENSE_INVERTED)
  3250. ldi r16, 0b1011
  3251. ldi r17, 1
  3252. rjmp 7b
  3253.  
  3254. 13: ; Ping the chime(s) to assist with radio range assessment.
  3255. ; Max 74 cycles so far
  3256. andi r25, ~(mTASK2_SEND_PING)
  3257. ldi r16, 0b1000
  3258. ldi r17, 2
  3259. rjmp 7b ; Max 79 cycles
  3260.  
  3261. 14: ; Send the teach message, perhaps after generating a new secret key.
  3262. ; Max 64 cycles so far
  3263. std Y + G_TaskFlags2, r25
  3264. push r24
  3265. lds r0, TASSState + TASS_SuppressKeyRandomisation
  3266. tst r0
  3267. brne 15f
  3268. rcall RandomiseCMACKey
  3269. ldiw Z, AuthenticationData + AD_CMACKey
  3270. ldiw X, EEPROM_CMACKey
  3271. ldi r16, 16
  3272. rcall WriteEEPROMBlock
  3273. ; Randomise the random part of the serial number.
  3274. ldiw Z, EntropyHarvester +\
  3275. EH_RandomData + EH_AUX_RANDOM_DATA_START_INDEX + 1
  3276. ld r16, Z+
  3277. ld r17, Z+
  3278. add r17, r4
  3279. ror r16
  3280. st -Z, r16
  3281. st -Z, r17
  3282. swap r17
  3283. add r16, r5
  3284. add r16, r6
  3285. andi r17, 0x0F
  3286. ldiw Z, AuthenticationData
  3287. ldd r0, Z + AD_SerialNumber + 0
  3288. eor r0, r16
  3289. std Z + AD_SerialNumber + 0, r0
  3290. ldd r16, Z + AD_SerialNumber + 1
  3291. andi r16, 0xF0
  3292. or r16, r17
  3293. std Z + AD_SerialNumber + 1, r16
  3294. ; Save the new serial number.
  3295. ldiw Z, AuthenticationData + AD_SerialNumber
  3296. ldiw X, EEPROM_SerialNumber
  3297. ldi r16, 4
  3298. rcall WriteEEPROMBlock
  3299. ; Update all of the random data while we're at it.
  3300. ldiw Z, EntropyHarvester + EH_RandomData
  3301. ldiw X, EEPROM_RandomData
  3302. ldi r16, EH_MUTATION_INDEX_RANGE
  3303. rcall WriteEEPROMBlock
  3304. sts TASSState + TASS_SuppressKeyRandomisation, r2
  3305. 15: rcall FullyUpdateEWLData
  3306. clr r24
  3307. lds r0, TASSState + TASS_SuppressKeyEncryption
  3308. cpse r0, r1
  3309. ldi r24, 1
  3310. rcall BuildTeachMessage
  3311. pop r24
  3312. ldi r16, TeachMsgSize
  3313. ldiw Z, TASSState
  3314. std Y + G_Transmitter + Tx_NumBytesToSend, r16
  3315. ldi r16, TX_STATE_BEGIN
  3316. std Y + G_Transmitter + Tx_State, r16
  3317. andi r24, ~(mTASK1_SEND_TEACH_MESSAGE)
  3318. ldd r16, Z + TASS_NumTeachMessagesToSend
  3319. sub r16, r2
  3320. adc r16, r1
  3321. std Z + TASS_NumTeachMessagesToSend, r16
  3322. ifne
  3323. ori r24, mTASK1_SEND_TEACH_MESSAGE
  3324. std Y + G_TaskFlags1, r24
  3325. rjmp main_Loop
  3326.  
  3327. ; Max 122 cycles if the teach procedure is not performed.
  3328.  
  3329. main_T2_TASSTasks_T3:
  3330.  
  3331. rjmp main_Loop
  3332.  
  3333. main_T3_SensorInputConditioningAndEntropyHarvesting:
  3334.  
  3335. ; Debounce sensor inputs.
  3336. ldd r24, Y + G_SecondarySensorIntegral
  3337. clr r22
  3338. sbis _SFR_IO_ADDR(PINB), INPUT_BIT_SECONDARY_SENSOR ; Active low!
  3339. ser r22
  3340. rcall DebounceSensor
  3341. std Y + G_SecondarySensorIntegral, r24
  3342. mov r16, r24
  3343. ldd r24, Y + G_PrimarySensorIntegral
  3344. clr r22
  3345. sbis _SFR_IO_ADDR(PINB), INPUT_BIT_PRIMARY_SENSOR ; Active low!
  3346. ser r22
  3347. rcall DebounceSensor
  3348. std Y + G_PrimarySensorIntegral, r24
  3349. ; 51 cycles so far
  3350. ; Set or clear the sensor state bits.
  3351. ldd r18, Y + G_SensorsState
  3352. mov r19, r18
  3353. cp r24, r1
  3354. ifeq
  3355. andi r18, ~(1 << 0)
  3356. cp r24, r3
  3357. ifeq
  3358. ori r18, (1 << 0)
  3359. cp r16, r1
  3360. ifeq
  3361. andi r18, ~(1 << 1)
  3362. cp r16, r3
  3363. ifeq
  3364. ori r18, (1 << 1)
  3365. ldd r0, Y + G_SensorActivationSenses
  3366. eor r18, r0
  3367. std Y + G_SensorsState, r18
  3368. ; 70 cycles so far
  3369. cp r19, r18
  3370. breq 2f
  3371. ; The sensors state has changed.
  3372. ; Harvest some entropy.
  3373. rcall MutateRandomData ; 21 + 8 cycles
  3374. std Y + G_CmdTxDelayRandomByte, r0
  3375. ldiw Z, EntropyHarvester
  3376. ; 105 cycles so far
  3377. ; Lazily write the random data to EEPROM.
  3378. ldd r0, Z + EH_EEPROMUpdatePending
  3379. tst r0
  3380. brne 1f
  3381. ldd r16, Z + EH_MutationCounter
  3382. inc r16
  3383. std Z + EH_MutationCounter, r16
  3384. andi r16, (1 << EH_UPDATE_COUNTER_BITS) - 1
  3385. brne 2f
  3386. std Z + EH_EEPROMUpdatePending, r2
  3387. 1: sbic _SFR_IO_ADDR(EECR), EEPE
  3388. rjmp 2f
  3389. std Z + EH_EEPROMUpdatePending, r1
  3390. ldd r16, Z + EH_EEPROMUpdateIndex
  3391. subi r16, -EH_UPDATE_INDEX_ADVANCE
  3392. andi r16, EH_MUTATION_INDEX_MASK
  3393. std Z + EH_EEPROMUpdateIndex, r16
  3394. adiw ZL, EH_RandomData
  3395. add ZL, r16
  3396. adc ZH, r1
  3397. ldiw X, EEPROM_RandomData
  3398. add XL, r16
  3399. adc XH, r1
  3400. ld r0, Z
  3401. ; 138 cycles so far
  3402. ldi r16, (0 << EEPM1) | (0 << EEPM0)
  3403. out _SFR_IO_ADDR(EECR), r16
  3404. out _SFR_IO_ADDR(EEARH), XH
  3405. out _SFR_IO_ADDR(EEARL), XL
  3406. out _SFR_IO_ADDR(EEDR), r0
  3407. sbi _SFR_IO_ADDR(EECR), EEMPE
  3408. sbi _SFR_IO_ADDR(EECR), EEPE ; The CPU is halted for 2 cycles.
  3409. ; Max 147 cycles so far
  3410. 2: rjmp main_Loop
  3411.  
  3412. ; Max 149 cycles
  3413.  
  3414. main_T4_SensorStateTxBurstsAndEWLUpdates:
  3415.  
  3416. ldd r24, Y + G_TaskFlags1
  3417. ldd r18, Y + G_SensorsState
  3418. ldd r19, Y + G_TransmittedSensorsState
  3419. ldiw Z, Globals + G_CmdTxRepeatSchedule
  3420. cp r18, r19
  3421. breq 1f
  3422. std Y + G_TransmittedSensorsState, r18
  3423. ; One of the sensors has changed state.
  3424. ; Prepare the repeat schedule and submit a request
  3425. ; for transmission right now.
  3426. ; 10 cycles so far
  3427. ldd r7, Y + G_CmdTxDelayRandomByte
  3428. ldi r16, 1
  3429. std Z + 5, r16
  3430. ldi r16, 3
  3431. std Z + 4, r16
  3432. ldi r16, 8
  3433. mov r17, r7
  3434. andi r17, 0x03
  3435. add r16, r17
  3436. std Z + 3, r16
  3437. ldi r16, 15
  3438. sub r16, r17
  3439. mov r17, r7
  3440. lsr r17
  3441. lsr r17
  3442. andi r17, 0x03
  3443. add r16, r17
  3444. std Z + 2, r16
  3445. ldi r16, 24
  3446. sub r17, r17
  3447. swap r7
  3448. mov r17, r7
  3449. andi r17, 0x03
  3450. add r16, r17
  3451. std Z + 1, r16
  3452. ldi r16, 34
  3453. sub r17, r17
  3454. mov r17, r7
  3455. lsr r17
  3456. andi r17, 0x06
  3457. add r16, r17
  3458. std Z + 0, r16
  3459. ldi r16, 6
  3460. std Y + G_CmdTxNumRepeatsToSend, r16
  3461. ori r24, mTASK1_SEND_CMD_MESSAGE
  3462. ; 53 cycles so far
  3463. rjmp 2f
  3464. 1: ; Update the slow clock for the transmission repeat delay.
  3465. ; 11 cycles so far
  3466. ldd r0, Y + G_SlowClocks
  3467. mov r7, r0
  3468. bst r5, 3
  3469. bld r0, bCLOCK_CMD_MSG_BURST
  3470. std Y + G_SlowClocks, r0
  3471. eor r7, r0
  3472. bst r7, bCLOCK_CMD_MSG_BURST
  3473. clr r0
  3474. bld r0, 0
  3475. ; See if a command transmission is already pending.
  3476. sbrc r24, bTASK1_SEND_CMD_MESSAGE
  3477. rjmp 2f
  3478. ; Follow the transmission repeat schedule.
  3479. ldd r16, Y + G_CmdTxNumRepeatsToSend
  3480. dec r16
  3481. brmi 2f
  3482. add ZL, r16
  3483. adc ZH, r1
  3484. ld r7, Z
  3485. sub r7, r0
  3486. adc r7, r1
  3487. st Z, r7
  3488. brne 2f
  3489. std Y + G_CmdTxNumRepeatsToSend, r16
  3490. ori r24, mTASK1_SEND_CMD_MESSAGE
  3491. ; 40 cycles so far
  3492. 2: ; 40 or 55 cycles so far
  3493. sbrs r24, bTASK1_SEND_CMD_MESSAGE
  3494. rjmp 3f
  3495. ; Send the command message as soon as the resources are available.
  3496. ldd r16, Y + G_Transmitter + Tx_State
  3497. cpi r16, TX_STATE_IDLE
  3498. brne 3f
  3499. ldd r16, Y + G_AuthenticationState
  3500. cpi r16, AUTH_STATE_IDLE
  3501. brne 3f
  3502. ldd r16, Y + G_AESState
  3503. cpi r16, AES_STATE_IDLE
  3504. brne 3f
  3505. ; Send the command now.
  3506. andi r18, 0x03
  3507. ori r18, 0x00 ; Just to make the hex file easy to edit
  3508. ldd r19, Y + G_SoundIndices
  3509. std Y + G_Transmitter + Tx_Data + CmdMsg_Command, r18
  3510. std Y + G_Transmitter + Tx_Data + CmdMsg_Parameter, r19
  3511. ldi r16, AUTH_STATE_CMDMSG_BEGIN
  3512. std Y + G_AuthenticationState, r16
  3513. andi r24, ~(mTASK1_SEND_CMD_MESSAGE)
  3514. ; Max 83 cycles so far
  3515. 3: std Y + G_TaskFlags1, r24
  3516. rcall LazilyUpdateEWLData ; 66 cycles
  3517. rjmp main_Loop
  3518.  
  3519. ; Max 153 cycles
  3520.  
  3521. main_T5_RefreshEEPROM:
  3522.  
  3523. ldd r8, Y + G_SlowClocks
  3524. mov r7, r8
  3525. bst r6, 7 ; Cycling once every 524.29s
  3526. bld r8, bCLOCK_EEPROM_REFRESH
  3527. std Y + G_SlowClocks, r8
  3528. com r8
  3529. and r7, r8
  3530. bst r7, bCLOCK_EEPROM_REFRESH
  3531. brtc 1f
  3532. sbic _SFR_IO_ADDR(EECR), EEPE
  3533. rjmp 1f ; Busy! Better luck next time!
  3534. ldd XL, Y + G_EEPROMRefreshCounter + 0
  3535. ldd XH, Y + G_EEPROMRefreshCounter + 1
  3536. add XL, r2
  3537. adc XH, r1
  3538. andi XH, 0x01
  3539. std Y + G_EEPROMRefreshCounter + 0, XL
  3540. std Y + G_EEPROMRefreshCounter + 1, XH
  3541. rcall ReadEEPROMByte ; 18 cycles
  3542. rcall WriteEEPROMByte ; 23 cycles
  3543. 1: rjmp main_Loop
  3544.  
  3545. ; Max 67 cycles
  3546.  
  3547. main_T6:
  3548.  
  3549. rjmp main_Loop
  3550.  
  3551. main_T7:
  3552.  
  3553. rjmp main_Loop
  3554.  
  3555.  
  3556. ;-------------------------------------------------------------------------------
  3557. ; Data in program memory
  3558. ;-------------------------------------------------------------------------------
  3559.  
  3560.  
  3561. ; As the AES round constant high bytes are easy to generate, they needn't be
  3562. ; stored. Each round constant byte is the previous one shifted to the left
  3563. ; and XORed with 0x1B if the shift set the carry flag. The RCon high byte for
  3564. ; Round 1 is 0x01 and for Round 10, it is 0x36. If the advance occurs before
  3565. ; each use, the start value should be 0x8D.
  3566. ;
  3567. ;PM_AES_RoundConstantBytes:
  3568. ; .byte 0x8D, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40
  3569. ; .byte 0x80, 0x1B, 0x36, 0x6C, 0xD8, 0xAB, 0x4D, 0x9A
  3570.  
  3571. .balign 256
  3572. PM_AES_SBox:
  3573. .byte 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5
  3574. .byte 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76
  3575. .byte 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0
  3576. .byte 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0
  3577. .byte 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC
  3578. .byte 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15
  3579. .byte 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A
  3580. .byte 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75
  3581. .byte 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0
  3582. .byte 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84
  3583. .byte 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B
  3584. .byte 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF
  3585. .byte 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85
  3586. .byte 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8
  3587. .byte 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5
  3588. .byte 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2
  3589. .byte 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17
  3590. .byte 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73
  3591. .byte 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88
  3592. .byte 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB
  3593. .byte 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C
  3594. .byte 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79
  3595. .byte 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9
  3596. .byte 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08
  3597. .byte 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6
  3598. .byte 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A
  3599. .byte 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E
  3600. .byte 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E
  3601. .byte 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94
  3602. .byte 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF
  3603. .byte 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68
  3604. .byte 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
  3605.  
  3606.  
  3607. ;-------------------------------------------------------------------------------
  3608. ; Globals in SRAM
  3609. ;-------------------------------------------------------------------------------
  3610.  
  3611. ;-------------------------------------------------------------------------------
  3612. .section .bss
  3613. ;-------------------------------------------------------------------------------
  3614.  
  3615.  
  3616. Globals:
  3617. .fill GSize
  3618. TASSState:
  3619. .fill TASSSize
  3620. .balign 2
  3621. TxRunLengthsRingBuffer:
  3622. .fill TX_RING_BUFFER_INDEX_RANGE
  3623. AES_Matrix_M:
  3624. .fill 16
  3625. AES_Matrix_K:
  3626. .fill 16
  3627. AES_Matrix_W:
  3628. .fill 16
  3629. AuthenticationData:
  3630. .fill ADSize
  3631. EWLState:
  3632. .fill EWLSSize
  3633. EntropyHarvester:
  3634. .fill EHSize
  3635. .balign 2
  3636. VariablesEnd:
  3637.  
  3638.  
  3639. ;-------------------------------------------------------------------------------
  3640. .end
  3641. ;-------------------------------------------------------------------------------
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement