serial_lcd.elf: file format elf32-avr Sections: Idx Name Size VMA LMA File off Algn 0 .text 000002aa 00000000 00000000 00000074 2**1 CONTENTS, ALLOC, LOAD, READONLY, CODE 1 .noinit 00000030 00800060 00800060 0000031e 2**0 ALLOC 2 .stab 0000069c 00000000 00000000 00000320 2**2 CONTENTS, READONLY, DEBUGGING 3 .stabstr 00000082 00000000 00000000 000009bc 2**0 CONTENTS, READONLY, DEBUGGING 4 .debug_aranges 00000050 00000000 00000000 00000a3e 2**0 CONTENTS, READONLY, DEBUGGING 5 .debug_pubnames 0000003a 00000000 00000000 00000a8e 2**0 CONTENTS, READONLY, DEBUGGING 6 .debug_info 00000765 00000000 00000000 00000ac8 2**0 CONTENTS, READONLY, DEBUGGING 7 .debug_abbrev 0000026d 00000000 00000000 0000122d 2**0 CONTENTS, READONLY, DEBUGGING 8 .debug_line 0000068a 00000000 00000000 0000149a 2**0 CONTENTS, READONLY, DEBUGGING 9 .debug_frame 00000080 00000000 00000000 00001b24 2**2 CONTENTS, READONLY, DEBUGGING 10 .debug_str 00000298 00000000 00000000 00001ba4 2**0 CONTENTS, READONLY, DEBUGGING 11 .debug_loc 000001cd 00000000 00000000 00001e3c 2**0 CONTENTS, READONLY, DEBUGGING 12 .debug_ranges 000000a8 00000000 00000000 00002009 2**0 CONTENTS, READONLY, DEBUGGING Disassembly of section .text: 00000000 <__vectors>: 0: 18 c0 rjmp .+48 ; 0x32 <__ctors_end> 2: 1d c0 rjmp .+58 ; 0x3e <__bad_interrupt> 4: 1c c0 rjmp .+56 ; 0x3e <__bad_interrupt> 6: 1b c0 rjmp .+54 ; 0x3e <__bad_interrupt> 8: 1a c0 rjmp .+52 ; 0x3e <__bad_interrupt> a: 19 c0 rjmp .+50 ; 0x3e <__bad_interrupt> c: 18 c0 rjmp .+48 ; 0x3e <__bad_interrupt> e: 42 c0 rjmp .+132 ; 0x94 <__vector_7> 10: 16 c0 rjmp .+44 ; 0x3e <__bad_interrupt> 12: 15 c0 rjmp .+42 ; 0x3e <__bad_interrupt> 14: 14 c0 rjmp .+40 ; 0x3e <__bad_interrupt> 16: 13 c0 rjmp .+38 ; 0x3e <__bad_interrupt> 18: 12 c0 rjmp .+36 ; 0x3e <__bad_interrupt> 1a: 18 c1 rjmp .+560 ; 0x24c <__vector_13> 1c: 10 c0 rjmp .+32 ; 0x3e <__bad_interrupt> 1e: 0f c0 rjmp .+30 ; 0x3e <__bad_interrupt> 20: 0e c0 rjmp .+28 ; 0x3e <__bad_interrupt> 22: 0d c0 rjmp .+26 ; 0x3e <__bad_interrupt> 24: 0c c0 rjmp .+24 ; 0x3e <__bad_interrupt> 00000026 : 26: 07 17 2f 5f ../_ 0000002a : 2a: 10 11 4a 55 5d ee 7f ff ..JU]... 00000032 <__ctors_end>: 32: 11 24 eor r1, r1 34: 1f be out 0x3f, r1 ; 63 36: cf ed ldi r28, 0xDF ; 223 38: cd bf out 0x3d, r28 ; 61 3a: 5c d0 rcall .+184 ; 0xf4
3c: 34 c1 rjmp .+616 ; 0x2a6 <_exit> 0000003e <__bad_interrupt>: 3e: e0 cf rjmp .-64 ; 0x0 <__vectors> 00000040 : LCD_CONTROL_PORT &= ~(1< ENABLE_WAIT(); LCDStatus = LCD_DATA_PIN_REG; 4e: 00 c0 rjmp .+0 ; 0x50 50: 96 b3 in r25, 0x16 ; 22 LCD_CONTROL_PORT &= ~(1< LCD_CONTROL_PORT &= ~(1<: LCD_CONTROL_PORT &= ~(1< LCD_CONTROL_PORT |= (1< ENABLE_WAIT(); LCD_CONTROL_PORT &= ~(1< 74: 96 98 cbi 0x12, 6 ; 18 } 76: 1f 91 pop r17 78: 08 95 ret 0000007a : } } MAIN_FUNC_LAST(); } void LcdWriteCmd (unsigned char Cmd) { 7a: 1f 93 push r17 7c: 18 2f mov r17, r24 LcdBusyWait(); 7e: e0 df rcall .-64 ; 0x40 LCD_DATA_PORT = Cmd; // BusyWait leaves RS low in "Register mode" 80: 18 bb out 0x18, r17 ; 24 NOP(); 82: 00 00 nop LCD_CONTROL_PORT |= (1< ENABLE_WAIT(); LCD_CONTROL_PORT &= ~(1< 8a: 96 98 cbi 0x12, 6 ; 18 NOP(); 8c: 00 00 nop LCD_CONTROL_PORT |= (1<: #pragma interrupt_handler usart_rx_handler:iv_USART0_RXC void usart_rx_handler(void) #else ISR(USART_RX_vect) #endif { 94: 1f 92 push r1 96: 0f 92 push r0 98: 0f b6 in r0, 0x3f ; 63 9a: 0f 92 push r0 9c: 11 24 eor r1, r1 9e: 8f 93 push r24 a0: ef 93 push r30 a2: ff 93 push r31 UartStoreRx(UDR); a4: 8c b1 in r24, 0x0c ; 12 INLINE_FUNC_DECLARE(static void UartStoreRx (uint8_t rx)); static inline void UartStoreRx (uint8_t rx) { unsigned char tmphead; if (UCSRA & (1< // some applications may benefit from addind error notification for serial port data overruns } #endif // Calculate next buffer position. tmphead = sUartRxHead; aa: e5 2d mov r30, r5 if (tmphead == UART_RX_BUFFER_SIZE-1) ac: ef 32 cpi r30, 0x2F ; 47 ae: 11 f4 brne .+4 ; 0xb4 <__vector_7+0x20> b0: e0 e0 ldi r30, 0x00 ; 0 b2: 01 c0 rjmp .+2 ; 0xb6 <__vector_7+0x22> tmphead = 0; else tmphead++; b4: ef 5f subi r30, 0xFF ; 255 // store in buffer if there is room if (tmphead != sUartRxTail) { b6: e6 15 cp r30, r6 b8: 29 f0 breq .+10 ; 0xc4 <__vector_7+0x30> sUartRxHead = tmphead; // Store new index. ba: 5e 2e mov r5, r30 sUartRxBuf[tmphead] = rx; bc: f0 e0 ldi r31, 0x00 ; 0 be: e0 5a subi r30, 0xA0 ; 160 c0: ff 4f sbci r31, 0xFF ; 255 c2: 80 83 st Z, r24 #else ISR(USART_RX_vect) #endif { UartStoreRx(UDR); } c4: ff 91 pop r31 c6: ef 91 pop r30 c8: 8f 91 pop r24 ca: 0f 90 pop r0 cc: 0f be out 0x3f, r0 ; 63 ce: 0f 90 pop r0 d0: 1f 90 pop r1 d2: 18 95 reti 000000d4 : static unsigned char WaitRxChar (void) { // waits for next RX character, then return it unsigned char tail; do { tail = sUartRxTail; // explicitly set order of volatile variable access d4: 86 2d mov r24, r6 wdt_reset(); } while (sUartRxHead == tail); // while buffer is empty d6: 95 2d mov r25, r5 static unsigned char WaitRxChar (void) { // waits for next RX character, then return it unsigned char tail; do { tail = sUartRxTail; // explicitly set order of volatile variable access wdt_reset(); d8: a8 95 wdr } while (sUartRxHead == tail); // while buffer is empty da: 98 17 cp r25, r24 dc: e9 f3 breq .-6 ; 0xd8 // CTS inactive if byte fills buffer after we remove current byte cli(); #endif // increment tail position if (tail == UART_RX_BUFFER_SIZE-1) de: 8f 32 cpi r24, 0x2F ; 47 e0: 11 f4 brne .+4 ; 0xe6 <__stack+0x7> sUartRxTail = 0; e2: 66 24 eor r6, r6 e4: 01 c0 rjmp .+2 ; 0xe8 <__stack+0x9> else sUartRxTail++; e6: 63 94 inc r6 #if USE_CTS CTS_PORT |= (1<: LcdWriteCmd (LCD_ON); // Power up the display LcdWriteCmd (LCD_CLR); // Power up the display } MAIN_FUNC() { MCUSR = 0; // clear all reset flags f4: 14 be out 0x34, r1 ; 52 wdt_reset(); f6: a8 95 wdr #if defined(__CODEVISIONAVR__) #pragma optsize- #endif WDTCSR |= (1< _delay_us(15000); LCD_CONTROL_PORT |= (1< 13c: 8a e0 ldi r24, 0x0A ; 10 13e: 9b e3 ldi r25, 0x3B ; 59 140: 01 97 sbiw r24, 0x01 ; 1 142: f1 f7 brne .-4 ; 0x140 _delay_us(4100); LcdWriteData (DATA_8); 144: 80 e3 ldi r24, 0x30 ; 48 146: 8d df rcall .-230 ; 0x62 148: 80 e7 ldi r24, 0x70 ; 112 14a: 91 e0 ldi r25, 0x01 ; 1 14c: 01 97 sbiw r24, 0x01 ; 1 14e: f1 f7 brne .-4 ; 0x14c _delay_us(100); LcdWriteData (DATA_8); 150: 80 e3 ldi r24, 0x30 ; 48 152: 87 df rcall .-242 ; 0x62 LCD_CONTROL_PORT |= (1< LcdWriteCmd (LCD_ON); // Power up the display 15a: 8c e0 ldi r24, 0x0C ; 12 15c: 8e df rcall .-228 ; 0x7a LcdWriteCmd (LCD_CLR); // Power up the display 15e: 81 e0 ldi r24, 0x01 ; 1 160: 8c df rcall .-232 ; 0x7a INLINE_FUNC_DECLARE(static void UsartInit (void)); static inline void UsartInit(void) { // Initialize USART UCSRB = 0; // Disable while setting baud rate 162: 1a b8 out 0x0a, r1 ; 10 UCSRA = 0; 164: 1b b8 out 0x0b, r1 ; 11 UCSRC = (1<> BAUD_J1); return PGM_READ_BYTE (&BaudLookupTable[BaudSelectJumpersValue]); 16e: e6 95 lsr r30 170: e6 95 lsr r30 172: f0 e0 ldi r31, 0x00 ; 0 174: ea 5d subi r30, 0xDA ; 218 176: ff 4f sbci r31, 0xFF ; 255 178: e4 91 lpm r30, Z+ static inline void UsartInit(void) { // Initialize USART UCSRB = 0; // Disable while setting baud rate UCSRA = 0; UCSRC = (1< 18e: 41 c0 rjmp .+130 ; 0x212 unsigned char rx_byte = WaitRxChar(); 190: a1 df rcall .-190 ; 0xd4 // avoid use of switch statement as ImageCraft and GCC produce signifcantly // more code for a switch statement than a sequence of if/else if if (rx_byte == LED_SW_OFF) { 192: 8d 3f cpi r24, 0xFD ; 253 194: 21 f4 brne .+8 ; 0x19e } } INLINE_FUNC_DECLARE(static void LedPwmSwitchOff (void)); static inline void LedPwmSwitchOff (void) { LED_PORT &= ~(1< // avoid use of switch statement as ImageCraft and GCC produce signifcantly // more code for a switch statement than a sequence of if/else if if (rx_byte == LED_SW_OFF) { LedPwmSwitchOff(); } else if (rx_byte == LED_SW_ON) { 19e: 8c 3f cpi r24, 0xFC ; 252 1a0: 29 f4 brne .+10 ; 0x1ac LedTimerStop(); } INLINE_FUNC_DECLARE(static void LedPwmSwitchOn (void)); static inline void LedPwmSwitchOn (void) { BACKLIGHT_ON(); 1a2: a0 9a sbi 0x14, 0 ; 20 if (ledPwmPattern == 0xFF) { // maximum brightness, no need for PWM 1a4: 83 b3 in r24, 0x13 ; 19 1a6: 8f 3f cpi r24, 0xFF ; 255 1a8: 59 f5 brne .+86 ; 0x200 1aa: 25 c0 rjmp .+74 ; 0x1f6 // more code for a switch statement than a sequence of if/else if if (rx_byte == LED_SW_OFF) { LedPwmSwitchOff(); } else if (rx_byte == LED_SW_ON) { LedPwmSwitchOn(); } else if (rx_byte == LED_SET_BRIGHTNESS) { 1ac: 8b 3f cpi r24, 0xFB ; 251 1ae: 51 f5 brne .+84 ; 0x204 rx_byte = WaitRxChar(); // read next byte which will be brightness 1b0: 91 df rcall .-222 ; 0xd4 INLINE_FUNC_DECLARE(static void LedPwmSetBrightness (unsigned char brightness)); static inline void LedPwmSetBrightness (unsigned char brightness) { unsigned char ledPwmPos; if (brightness == 0) { // turn backlight off for 0 brightness 1b2: 88 23 and r24, r24 1b4: 39 f4 brne .+14 ; 0x1c4 if (IS_BACKLIGHT_ON()) { 1b6: a0 9b sbis 0x14, 0 ; 20 1b8: e8 cf rjmp .-48 ; 0x18a #else // Using a platform that has proper inline functions INLINE_FUNC_DECLARE(static void LedTimerStop (void)); static inline void LedTimerStop (void) { TCCR0B = 0; 1ba: 13 be out 0x33, r1 ; 51 unsigned char ledPwmPos; if (brightness == 0) { // turn backlight off for 0 brightness if (IS_BACKLIGHT_ON()) { LedTimerStop(); ledPwmPattern = 0; 1bc: 13 ba out 0x13, r1 ; 19 ledPwmCycling = 0; 1be: 77 24 eor r7, r7 LED_PORT &= ~(1< } return; } ledPwmPos = (brightness * (LED_BRIGHTNESS_LEVELS-1) + (unsigned int) 127) >> 8; 1c4: 90 e0 ldi r25, 0x00 ; 0 1c6: 67 e0 ldi r22, 0x07 ; 7 1c8: 70 e0 ldi r23, 0x00 ; 0 1ca: 5b d0 rcall .+182 ; 0x282 <__mulhi3> 1cc: 81 58 subi r24, 0x81 ; 129 1ce: 9f 4f sbci r25, 0xFF ; 255 1d0: 89 2f mov r24, r25 1d2: 99 27 eor r25, r25 1d4: 98 2f mov r25, r24 1d6: 88 30 cpi r24, 0x08 ; 8 1d8: 08 f0 brcs .+2 ; 0x1dc 1da: 97 e0 ldi r25, 0x07 ; 7 // Below is probably not required, but ensures we don't exceed array if (ledPwmPos > LED_BRIGHTNESS_LEVELS - 1) ledPwmPos = LED_BRIGHTNESS_LEVELS - 1; ledPwmPattern = PGM_READ_BYTE (&ledPwmPatterns[ledPwmPos]); 1dc: e9 2f mov r30, r25 1de: f0 e0 ldi r31, 0x00 ; 0 1e0: e6 5d subi r30, 0xD6 ; 214 1e2: ff 4f sbci r31, 0xFF ; 255 1e4: e4 91 lpm r30, Z+ 1e6: e3 bb out 0x13, r30 ; 19 ledPwmCount = 0; 1e8: 44 24 eor r4, r4 ledPwmCycling = ledPwmPattern; 1ea: 83 b3 in r24, 0x13 ; 19 1ec: 78 2e mov r7, r24 if (ledPwmPos >= LED_BRIGHTNESS_LEVELS-1) { // maximum brightness 1ee: 97 30 cpi r25, 0x07 ; 7 1f0: 29 f4 brne .+10 ; 0x1fc // don't need PWM for continuously on if (IS_BACKLIGHT_ON()) { 1f2: a0 9b sbis 0x14, 0 ; 20 1f4: ca cf rjmp .-108 ; 0x18a #else // Using a platform that has proper inline functions INLINE_FUNC_DECLARE(static void LedTimerStop (void)); static inline void LedTimerStop (void) { TCCR0B = 0; 1f6: 13 be out 0x33, r1 ; 51 ledPwmCycling = ledPwmPattern; if (ledPwmPos >= LED_BRIGHTNESS_LEVELS-1) { // maximum brightness // don't need PWM for continuously on if (IS_BACKLIGHT_ON()) { LedTimerStop(); LED_PORT |= (1< } } else { if (IS_BACKLIGHT_ON()) { 1fc: a0 9b sbis 0x14, 0 ; 20 1fe: c5 cf rjmp .-118 ; 0x18a TCCR0B = 0; } INLINE_FUNC_DECLARE(static void LedTimerStart (void)); static inline void LedTimerStart (void) { TCCR0B = (1< } else if (rx_byte == LED_SW_ON) { LedPwmSwitchOn(); } else if (rx_byte == LED_SET_BRIGHTNESS) { rx_byte = WaitRxChar(); // read next byte which will be brightness LedPwmSetBrightness(rx_byte); } else if (rx_byte == REG_MODE) { 204: 8e 3f cpi r24, 0xFE ; 254 206: 19 f4 brne .+6 ; 0x20e LcdWriteCmd (WaitRxChar()); // Send LCD command character 208: 65 df rcall .-310 ; 0xd4 20a: 37 df rcall .-402 ; 0x7a 20c: be cf rjmp .-132 ; 0x18a } else { LcdWriteData (rx_byte); // Send LCD data character 20e: 29 df rcall .-430 ; 0x62 210: bc cf rjmp .-136 ; 0x18a } } else { // No characters waiting in RX buffer cli(); 212: f8 94 cli wdt_reset(); 214: a8 95 wdr MCUSR &= ~(1< 0000024c <__vector_13>: #pragma interrupt_handler timer0_compa_handler:iv_TIMER0_COMPA void timer0_compa_handler(void) #else ISR(TIMER0_COMPA_vect) #endif { 24c: 1f 92 push r1 24e: 0f 92 push r0 250: 0f b6 in r0, 0x3f ; 63 252: 0f 92 push r0 254: 11 24 eor r1, r1 256: 8f 93 push r24 sei(); // Okay to allow USART interrupts while controlling LED PWM 258: 78 94 sei // Set current LED state based on cycling variable if (ledPwmCycling & 0x01) { 25a: 70 fe sbrs r7, 0 25c: 02 c0 rjmp .+4 ; 0x262 <__vector_13+0x16> LED_PORT |= (1< } else { LED_PORT &= ~(1<= LED_BRIGHTNESS_LEVELS-1) { 264: 86 e0 ldi r24, 0x06 ; 6 266: 84 15 cp r24, r4 268: 20 f4 brcc .+8 ; 0x272 <__vector_13+0x26> ledPwmCount = 0; 26a: 44 24 eor r4, r4 ledPwmCycling = ledPwmPattern; 26c: 83 b3 in r24, 0x13 ; 19 26e: 78 2e mov r7, r24 270: 02 c0 rjmp .+4 ; 0x276 <__vector_13+0x2a> } else { ledPwmCount++; 272: 43 94 inc r4 ledPwmCycling >>= 1; 274: 76 94 lsr r7 } } 276: 8f 91 pop r24 278: 0f 90 pop r0 27a: 0f be out 0x3f, r0 ; 63 27c: 0f 90 pop r0 27e: 1f 90 pop r1 280: 18 95 reti 00000282 <__mulhi3>: 282: 55 27 eor r21, r21 284: 00 24 eor r0, r0 00000286 <__mulhi3_loop>: 286: 80 ff sbrs r24, 0 288: 02 c0 rjmp .+4 ; 0x28e <__mulhi3_skip1> 28a: 06 0e add r0, r22 28c: 57 1f adc r21, r23 0000028e <__mulhi3_skip1>: 28e: 66 0f add r22, r22 290: 77 1f adc r23, r23 292: 61 15 cp r22, r1 294: 71 05 cpc r23, r1 296: 21 f0 breq .+8 ; 0x2a0 <__mulhi3_exit> 298: 96 95 lsr r25 29a: 87 95 ror r24 29c: 00 97 sbiw r24, 0x00 ; 0 29e: 99 f7 brne .-26 ; 0x286 <__mulhi3_loop> 000002a0 <__mulhi3_exit>: 2a0: 95 2f mov r25, r21 2a2: 80 2d mov r24, r0 2a4: 08 95 ret 000002a6 <_exit>: 2a6: f8 94 cli 000002a8 <__stop_program>: 2a8: ff cf rjmp .-2 ; 0x2a8 <__stop_program>