//====================================================== // (c)2008-11 Matthew Ford // Forward Computing and Control Pty. Ltd. // www.forward.com.au // All rights reserved // // You may freely copy and distribute this program for // commercial and non-commercial use provided:- // i) this copyright notice remains attached // ii) you clearly mark any changes you make to the code //====================================================== // // pfodLedDriver.asm // // Main: ATtiny84 // mode: ISP mode // // Program: ATtiny84 // Flash - Input HEX File: yourdir/PODLedDriver.hex // EEPROM - not used // // Fuses: // SPIEN ticked // BODLEVEL Brown Out detection at VCC = 1.8V // CKDIV8 ticked // SUT_CKSEL Int RC Osc. 8Mhz; .... 6CK/14CK +64mS // Auto Read ticked // Smart Warnings ticked // Verify After programming ticked // then Progam the fuses // // LockBits: // LB no lock features enabled // // Advanced: // Calibrate of frequency 8.0Mhz // Do Not write any value to the Cal byte. startup handles this // // HW Setting // VTarget 5.1 // VREF 5.1 (not used) // Clock Generator 3.686Mhz (max) // // Auto: // Erase Device // Check Signature // Program FLASH // Verify FLASH //--------------------------------------------------------- // // The constants N and C determine the data rate. C selects clock frequency // the following expression yields the data rate: // // Clk_freq // BAUD = ------ x 1/N // C // // // Absolute minimum value for N*C is about 10 (which causes the // timer to interrupt to be set again before the interrupt is finished). // Absolute maximum is 170. // (Caused by the 1.5bit-lenght that is necessary to receive bits correctly.) // // The RS232 uses SERIAL_OUT_PIN as the transmit pin // The receive pin is SERIAL_IN_PIN // You need to adjust the other .equ to match the pins you choose. // // // Since this RS232 module is half duplex, it can either send or recieve data. // It can't do both simoutaneausly. // // To use first call RS232_INIT. (with interrupts disabled) // Then either call RS232_SET_TO_RECEIVE to wait for a character to arrive // or RS232_TRANSMIT to transmit the bytes to have previously stored in the // RS232_BUFFER_?? To transmit you also need to set the RS232_SEND_COUNT // which is the number of bytes to be send from 1 to RS232_MAX_SEND_BUFFER // // //************************************************************************* // 1 -- Copy from BluetoothLedDriverDecimal // 2 -- Added 5sec timer for ADC reading and changed reading to % // 3 -- Added BRANCH_IF_TRANSMITTING macro and BRANCH_IF_RS232_BUSY // 4 -- Added error msg and send Amps also but amps not working // 5 -- Fixed error msg and send Amps // 6 -- Removed IamAlive and added i,I for amps // 7 -- Added macros for NEW_LINE and LOAD_CHARS_FROM // 8 -- Used macros for all msg loads // 9 -- Added Level setpoint lookup. Still need to do 0,1,2,3 settings // 10 -- Added 0,1,2,3 settings // 11 -- Adjusted levels for percived brightness changes // 12 -- Minor formatting // 13 -- Corrections to Comments // 14 -- Added menus for POD support // 15 -- Added On/Off toggle cmd // 19 -- Added fade on/off menu item // 20 -- Added fade timer // 21 -- fade on/off works but up/down does not // 22 -- fixed up/down and menu update // 23 -- 40 level fade // 24 -- added up/down steps by 4 levels // 25 -- replaced LOAD_CHARS_FROM macro with LOAD_CHARS routine reduces size by 172 bytes // 26 -- simplified sending streaming cmd // 27 -- added BRANCH_IF_TORCH_OFF_OR_FADING_DOWN macro // 28 -- added Navigation menu and sub_menu .include "tn84def.inc" // start interrupt routine .macro SAVE_SREG push Temp in Temp, SREG // save the SREG push Temp .endmacro // end interrupt routine .macro RESTORE_SREG pop Temp out SREG, Temp // restore the SREG pop Temp .endmacro //-------------------------------------------------------- // NEW_LINE // --------THIS IS NOT USED IN THIS CODE--------------- // insert a new line in the Tx buffer // either Cr or CrLf or just Lf // edit this macro to suit // Assumes XH:XL has been set to point to the RS232 Buffer // Decrements XH:XL before storing each char //-------------------------------------------------------- .macro NEW_LINE ldi Temp, 13 // Cr st -X, Temp // store leading Cr // ldi Temp, 10 // Lf // st -X, Temp // store leading Lf .endmacro //------------------------ // BRANCH_IF_TRANSMITTING // usage // BRANCH_IF_TRANSMITTING labelToBranchToIfTransmitting // else just continue to next statement after this macro // uses Temp register // ----------------------- .macro BRANCH_IF_TRANSMITTING // one argument lds Temp, RS232_STATUS // select just the busy and send bits andi Temp, (1< low -> high on pin input (ie 1 -> 0) idle is 1 // So check for port input == 1 at top and just return if not. // Otherwise start the timer to sample in 1.5 bits // Disable this pin interrupt and clear the interrupt flag // // RS232_STATUS_SET_TO_RECEIVE is cleared by this routine // RS232_STATUS_BUSY is set by this routine // RS232_STATUS_SEND is cleared by this routine // // When receive completes RS232_STATUS_DATA_RECEIVED will be set // Clear this flag when you have handled the data // //************************************************************************* PIN_CHANGE_INT: SAVE_SREG // save Temp and SREG // see if pin low or high sbic SERIAL_IN_PORTIN, SERIAL_IN_PIN // if SERIAL_IN_PIN low == 1 (set) just return rjmp END_PIN_CHANGE_INT // else want to get the timer started as close as possible // to the leading edge on the input // start it with divide by 8 // this assumes that OCR0A is set to some resonably high value // and that timer0 is cleared, RS232_INIT and RS232_STOP should do this in Temp, TCCR0B sbr Temp, (1< 9 stop // else set up to send next bit cpi RS232BitCount, 9 breq TIMER0_CMP_A_STOP_BIT // == 9 send stop bit brsh TIMER0_CMP_A_STOP_SEND // > 9 stop // else set next bit to next bit in byte // the code below takes the same time for either 0 or 1 next bit lds Temp, RS232_SEND_BYTE sbrc Temp,0 sbr RS232StatusReg,(1<9999 are output as 9999 // Numbers <-9999 are output as -9999 // // On return ZH:ZL is zero and XH:XL is updated to point to // the last char stored // // all used registers pushed and popped (saved and restored) //----------------------------------------------------- #define CONVERT_13BITS_PERCENT_LEFT //#define CONVERT_13BITS_PERCENT_RIGHT //#define CONVERT_13BITS_PERCENT_ZEROS // register defines for CONVERT_13BITS_PERCENT .def LeadingDigit = r17 .def Negative = r18 CONVERT_13BITS_PERCENT: push Temp push LeadingDigit push Negative clr Negative // no neg clr LeadingDigit // no leading digit yet // check if number to be converted is neg // if so prepend - and negate clr Temp cp ZL, Temp cpc ZH, Temp brpl CONVERT_13BITS_PERCENT_PAD_NEG_SIGN // else negate the input // Temp zero from above //clr Temp sub Temp, ZL mov ZL, Temp clr Temp sbc Temp, ZH mov ZH, Temp ldi Temp, 45 // '-' st -X, Temp // store - ldi Negative, 1 // set negative flag rjmp CONVERT_13BITS_PERCENT_CHECK_MAX_NUMBER CONVERT_13BITS_PERCENT_PAD_NEG_SIGN: #ifndef CONVERT_13BITS_PERCENT_LEFT // store a space if you want to padd the '-' position of +ve number ldi Temp, 32 st -X, Temp // store space #endif CONVERT_13BITS_PERCENT_CHECK_MAX_NUMBER: // check against max value push XH push XL mov XH, ZH mov XL, ZL subi XL, low(9999) sbci XH, high(9999) pop XL pop XH brsh CONVERT_13BITS_PERCENT_STORE_9999 rjmp CONVERT_13BITS_PERCENT_START_CONVERSION CONVERT_13BITS_PERCENT_STORE_9999: ldi Temp, 48 + 9 // '0' + 9 st -X, Temp st -X, Temp st -X, Temp st -X, Temp rjmp END_CONVERT_13BITS_PERCENT CONVERT_13BITS_PERCENT_START_CONVERSION: clr Temp CONVERT_13BITS_PERCENT_LOOP_1000: subi ZL, low(1000) sbci ZH, high(1000) brmi CONVERT_13BITS_PERCENT_ADD_BACK_1000 inc Temp // else inc temp rjmp CONVERT_13BITS_PERCENT_LOOP_1000 // try again CONVERT_13BITS_PERCENT_ADD_BACK_1000: subi ZL, low(-1000) sbci ZH, high(-1000) CONVERT_13BITS_PERCENT_STORE_1000: rcall CONVERT_13BITS_PERCENT_STORE_DIGIT clr Temp CONVERT_13BITS_PERCENT_LOOP_100: subi ZL, low(100) sbci ZH, high(100) brmi CONVERT_13BITS_PERCENT_ADD_BACK_100 inc Temp // else inc temp rjmp CONVERT_13BITS_PERCENT_LOOP_100 // try again CONVERT_13BITS_PERCENT_ADD_BACK_100: subi ZL, low(-100) sbci ZH, high(-100) CONVERT_13BITS_PERCENT_STORE_100: rcall CONVERT_13BITS_PERCENT_STORE_DIGIT ldi LeadingDigit, 1 // force last two digits even if 0 clr Temp CONVERT_13BITS_PERCENT_LOOP_10: sbiw Z, 10 // use word subtraction for < 64 brmi CONVERT_13BITS_PERCENT_ADD_BACK_10 inc Temp // else inc temp rjmp CONVERT_13BITS_PERCENT_LOOP_10 // try again CONVERT_13BITS_PERCENT_ADD_BACK_10: adiw Z, 10 // use word addition for < 64 CONVERT_13BITS_PERCENT_STORE_10: rcall CONVERT_13BITS_PERCENT_STORE_DIGIT ldi Temp, 46 // '.' st -X, Temp // store decimal point clr Temp CONVERT_13BITS_PERCENT_LOOP_1: sbiw Z, 1 // use word subtraction for < 64 brmi CONVERT_13BITS_PERCENT_ADD_BACK_1 inc Temp // else inc temp rjmp CONVERT_13BITS_PERCENT_LOOP_1 // try again CONVERT_13BITS_PERCENT_ADD_BACK_1: adiw Z, 1 // use word addition for < 64 CONVERT_13BITS_PERCENT_STORE_1: // always store last digit even if 0 subi Temp, -48 // temp - (-48) st -X, Temp // store 0 or 1's ldi Temp, 37 // '%' st -X, Temp // store the % END_CONVERT_13BITS_PERCENT: pop Negative pop LeadingDigit pop Temp ret //-------------------------- // CONVERT_13BITS_PERCENT_STORE_DIGIT // Checks Temp against 0 and if not 0 // add 48 '0' and store in location // pointed to by XH:XL (decremented first) // see code comments for how to store // leading zeros or padding blanks //-------------------------- CONVERT_13BITS_PERCENT_STORE_DIGIT: //------------------------------ #ifdef CONVERT_13BITS_PERCENT_ZEROS // this section stores leading zeros CONVERT_13BITS_PERCENT_STORE_NEXT_DIGIT: subi Temp, -48 // temp - (-48) st -X, Temp // store rjmp END_CONVERT_13BITS_PERCENT_STORE_DIGIT #endif //CONVERT_13BITS_PERCENT_ZEROS //------------------------------ //------------------------------ #ifdef CONVERT_13BITS_PERCENT_LEFT // this section has no padding tst LeadingDigit // zero if no leading digit stored yet brne CONVERT_13BITS_PERCENT_STORE_NEXT_DIGIT // always store if have leading digit tst Temp breq END_CONVERT_13BITS_PERCENT_STORE_DIGIT // skip zero CONVERT_13BITS_PERCENT_STORE_NEXT_DIGIT: ldi LeadingDigit, 1 // have leading digit now subi Temp, -48 // temp - (-48) st -X, Temp // store rjmp END_CONVERT_13BITS_PERCENT_STORE_DIGIT #endif //CONVERT_13BITS_PERCENT_LEFT //------------------------------ //------------------------------ #ifdef CONVERT_13BITS_PERCENT_RIGHT // this section padds with leading spaces tst LeadingDigit // zero if no leading digit stored yet brne CONVERT_13BITS_PERCENT_STORE_NEXT_DIGIT // always store if have leading digit tst Temp breq CONVERT_13BITS_PERCENT_STORE_ZERO_DIGIT // handle zero CONVERT_13BITS_PERCENT_STORE_NEXT_DIGIT: ldi LeadingDigit, 1 // have leading digit now subi Temp, -48 // temp - (-48) st -X, Temp // store rjmp END_CONVERT_13BITS_PERCENT_STORE_DIGIT CONVERT_13BITS_PERCENT_STORE_ZERO_DIGIT: // if negative move the - to the right tst Negative brne CONVERT_13BITS_PERCENT_STORE_PADDING // negative store over neg // else no negative dec X before store sbiw X, 1 CONVERT_13BITS_PERCENT_STORE_PADDING: ldi Temp, 32 // ' ' st X, Temp // restore neg if there is one tst Negative breq END_CONVERT_13BITS_PERCENT_STORE_DIGIT // not negative nothing to do // store neg in next location ldi Temp, 45 // '-' st -X, Temp // store - //rjmp END_CONVERT_13BITS_PERCENT_STORE_DIGIT drop throught #endif // CONVERT_13BITS_PERCENT_RIGHT //------------------------------ END_CONVERT_13BITS_PERCENT_STORE_DIGIT: ret .undef LeadingDigit .undef Negative //======================================================================= //----------------------------------------------------- // CONVERT_13BITS // Converts the, possiably signed, 13bit number in ZH:ZL // (actually -9999 to +9999) // and save acsii char in global SRAM whose start is pointed // to by XH:XL, // XH:XL decremented BEFORE each store of a char // If ZH:ZL is negative a leading '-' is stored // // Format of number is determined by uncommenting // one of the 3 #defines // #define CONVERT_13BITS_LEFT // left justifies the result eg |-21 and |2 // #define CONVERT_13BITS_RIGHT // right justifies the result eg | -21 and | 2 // #define CONVERT_13BITS_ZEROS // right justifies with leading zeros eg |-0021 and | 0002 // if you uncomment more then one you will get a compile error (duplicate label) // // Numbers >9999 are output as 9999 // Numbers <-9999 are output as -9999 // // On return ZH:ZL is zero and XH:XL is updated to point to // the last char stored // // all used registers pushed and popped (saved and restored) //----------------------------------------------------- #define CONVERT_13BITS_LEFT //#define CONVERT_13BITS_RIGHT //#define CONVERT_13BITS_ZEROS // register defines for CONVERT_13BITS .def LeadingDigit = r17 .def Negative = r18 CONVERT_13BITS: push Temp push LeadingDigit push Negative clr Negative // no neg clr LeadingDigit // no leading digit yet // check if number to be converted is neg // if so prepend - and negate clr Temp cp ZL, Temp cpc ZH, Temp brpl CONVERT_13BITS_PAD_NEG_SIGN // else negate the input // Temp zero from above //clr Temp sub Temp, ZL mov ZL, Temp clr Temp sbc Temp, ZH mov ZH, Temp ldi Temp, 45 // '-' st -X, Temp // store - ldi Negative, 1 // set negative flag rjmp CONVERT_13BITS_CHECK_MAX_NUMBER CONVERT_13BITS_PAD_NEG_SIGN: #ifndef CONVERT_13BITS_LEFT // store a space if you want to padd the '-' position of +ve number ldi Temp, 32 st -X, Temp // store space #endif CONVERT_13BITS_CHECK_MAX_NUMBER: // check against max value push XH push XL mov XH, ZH mov XL, ZL subi XL, low(9999) sbci XH, high(9999) pop XL pop XH brsh CONVERT_13BITS_STORE_9999 rjmp CONVERT_13BITS_START_CONVERSION CONVERT_13BITS_STORE_9999: ldi Temp, 48 + 9 // '0' + 9 st -X, Temp st -X, Temp st -X, Temp st -X, Temp rjmp END_CONVERT_13BITS CONVERT_13BITS_START_CONVERSION: clr Temp CONVERT_13BITS_LOOP_1000: subi ZL, low(1000) sbci ZH, high(1000) brmi CONVERT_13BITS_ADD_BACK_1000 inc Temp // else inc temp rjmp CONVERT_13BITS_LOOP_1000 // try again CONVERT_13BITS_ADD_BACK_1000: subi ZL, low(-1000) sbci ZH, high(-1000) CONVERT_13BITS_STORE_1000: rcall CONVERT_13BITS_STORE_DIGIT clr Temp CONVERT_13BITS_LOOP_100: subi ZL, low(100) sbci ZH, high(100) brmi CONVERT_13BITS_ADD_BACK_100 inc Temp // else inc temp rjmp CONVERT_13BITS_LOOP_100 // try again CONVERT_13BITS_ADD_BACK_100: subi ZL, low(-100) sbci ZH, high(-100) CONVERT_13BITS_STORE_100: rcall CONVERT_13BITS_STORE_DIGIT clr Temp CONVERT_13BITS_LOOP_10: sbiw Z, 10 // use word subtraction for < 64 brmi CONVERT_13BITS_ADD_BACK_10 inc Temp // else inc temp rjmp CONVERT_13BITS_LOOP_10 // try again CONVERT_13BITS_ADD_BACK_10: adiw Z, 10 // use word addition for < 64 CONVERT_13BITS_STORE_10: rcall CONVERT_13BITS_STORE_DIGIT clr Temp CONVERT_13BITS_LOOP_1: sbiw Z, 1 // use word subtraction for < 64 brmi CONVERT_13BITS_ADD_BACK_1 inc Temp // else inc temp rjmp CONVERT_13BITS_LOOP_1 // try again CONVERT_13BITS_ADD_BACK_1: adiw Z, 1 // use word addition for < 64 CONVERT_13BITS_STORE_1: // always store last digit even if 0 subi Temp, -48 // temp - (-48) st -X, Temp // store 0 or 1's END_CONVERT_13BITS: pop Negative pop LeadingDigit pop Temp ret //-------------------------- // CONVERT_13BITS_STORE_DIGIT // Checks Temp against 0 and if not 0 // add 48 '0' and store in location // pointed to by XH:XL (decremented first) // see code comments for how to store // leading zeros or padding blanks //-------------------------- CONVERT_13BITS_STORE_DIGIT: //------------------------------ #ifdef CONVERT_13BITS_ZEROS // this section stores leading zeros CONVERT_13BITS_STORE_NEXT_DIGIT: subi Temp, -48 // temp - (-48) st -X, Temp // store rjmp END_CONVERT_13BITS_STORE_DIGIT #endif //CONVERT_13BITS_ZEROS //------------------------------ //------------------------------ #ifdef CONVERT_13BITS_LEFT // this section has no padding tst LeadingDigit // zero if no leading digit stored yet brne CONVERT_13BITS_STORE_NEXT_DIGIT // always store if have leading digit tst Temp breq END_CONVERT_13BITS_STORE_DIGIT // skip zero CONVERT_13BITS_STORE_NEXT_DIGIT: ldi LeadingDigit, 1 // have leading digit now subi Temp, -48 // temp - (-48) st -X, Temp // store rjmp END_CONVERT_13BITS_STORE_DIGIT #endif //CONVERT_13BITS_LEFT //------------------------------ //------------------------------ #ifdef CONVERT_13BITS_RIGHT // this section padds with leading spaces tst LeadingDigit // zero if no leading digit stored yet brne CONVERT_13BITS_STORE_NEXT_DIGIT // always store if have leading digit tst Temp breq CONVERT_13BITS_STORE_ZERO_DIGIT // handle zero CONVERT_13BITS_STORE_NEXT_DIGIT: ldi LeadingDigit, 1 // have leading digit now subi Temp, -48 // temp - (-48) st -X, Temp // store rjmp END_CONVERT_13BITS_STORE_DIGIT CONVERT_13BITS_STORE_ZERO_DIGIT: // if negative move the - to the right tst Negative brne CONVERT_13BITS_STORE_PADDING // negative store over neg // else no negative dec X before store sbiw X, 1 CONVERT_13BITS_STORE_PADDING: ldi Temp, 32 // ' ' st X, Temp // restore neg if there is one tst Negative breq END_CONVERT_13BITS_STORE_DIGIT // not negative nothing to do // store neg in next location ldi Temp, 45 // '-' st -X, Temp // store - //rjmp END_CONVERT_13BITS_STORE_DIGIT drop throught #endif // CONVERT_13BITS_RIGHT //------------------------------ END_CONVERT_13BITS_STORE_DIGIT: ret .undef LeadingDigit .undef Negative //======================================================================= // // END of number format routines // // //----------------------------------------------------------------------- //----------------------------------------------------------------------- //************************************************************************* // // TIMER1_CMP_A_INT // called every 2mS // //************************************************************************* TIMER1_COMPARE_A_INT: SAVE_SREG // Temp not used here but leave extra push in as standard interrupt preamble sbr TRIGGER_Flags, (1<= setpoint (signed comparison) // else ADC < setpoint CURRENT_LOW: // ADC < setpoint ==> make output high sbi PORTB, uC_OUTPUT_B // set output high rjmp END_LED_CONTROL CURRENT_HIGH: // ADC > setpoint ==> make output low cbi PORTB, uC_OUTPUT_B // set output low rjmp END_LED_CONTROL // all paths jmp to here END_LED_CONTROL: pop ADCHigh pop ADCLow ret //------------------------------- #undef ADCLow #undef ADCHigh //-------------------------- // TIMER1_2mS // called each main loop // but only call Switch_Debounce if trigger // has been set by timer interrupt //------------------------- TIMER1_2mS: sbrs TRIGGER_Flags, TRIGGER_Timer1 rjmp END_TIMER1_2mS // else changed clear trigger now cbr Trigger_Flags, (1< 0.5 sec up and 1sec fade down //------------------------- TIMER_FADE: lds Temp, FADE_COUNTER dec Temp brpl END_TIMER_FADE // else == 0 ldi Temp, 1 // for next dec unless updated below cpi Torch_State, Torch_State_FADE brlo END_TIMER_FADE // not fade just load 1 in counter // else set trigger sbr TRIGGER_Flags, (1< off PROCESS_SWDown_TRIGGER_TORCH_HIGH: // high -> off, variable -> off ldi New_TORCH_State, Torch_State_OFF rjmp END_PROCESS_SWDown_TRIGGER PROCESS_SWDown_TRIGGER_TORCH_OFF: // off -> low ldi New_TORCH_State, Torch_State_LOW rjmp END_PROCESS_SWDown_TRIGGER PROCESS_SWDown_TRIGGER_TORCH_LOW: // low -> med ldi New_TORCH_State, Torch_State_MED rjmp END_PROCESS_SWDown_TRIGGER PROCESS_SWDown_TRIGGER_TORCH_MED: // med -> high ldi New_TORCH_State, Torch_State_HIGH // rjmp END_PROCESS_SWDown_TRIGGER drop through END_PROCESS_SWDown_TRIGGER: ret //------------------------------------- //------------------------------------- //UPDATE_TORCH_STATE // Set the new torch state and load current setpoint //------------------------------------- UPDATE_TORCH_STATE: mov TORCH_State, New_TORCH_State // update state to new state rcall LOAD_CURRENT_SETPOINT // load new setpoint ret //------------------------------------- //------------------------------------- //LOAD_CURRENT_SETPOINT // Loads the current setpoint base on the torch state // Also set SW_LedOn depending on TORCH_State //------------------------------------- LOAD_CURRENT_SETPOINT: push Temp cpi TORCH_State, Torch_State_OFF breq SET_TORCH_OFF // else cpi TORCH_State, TORCH_State_LOW breq SET_TORCH_LOW // else cpi TORCH_State, TORCH_State_MED breq SET_TORCH_MED // else cpi TORCH_State, TORCH_State_HIGH breq SET_TORCH_HIGH cpi Torch_State, Torch_State_INVALID brmi END_LOAD_CURRENT_SETPOINT // some other valid level just load current level INVALID_STATE: // else invalid turn off ldi TORCH_State, TORCH_State_OFF // set valid state // drop through to set off SET_TORCH_OFF: ldi Temp, 0; mov Level, Temp; rjmp END_LOAD_CURRENT_SETPOINT SET_TORCH_LOW: ldi Temp, LEVEL_LOW; mov Level, Temp; rjmp END_LOAD_CURRENT_SETPOINT SET_TORCH_MED: ldi Temp, LEVEL_MED; mov Level, Temp; rjmp END_LOAD_CURRENT_SETPOINT SET_TORCH_HIGH: ldi Temp, LEVEL_HIGH; mov Level, Temp; rjmp END_LOAD_CURRENT_SETPOINT END_LOAD_CURRENT_SETPOINT: rcall LOAD_SETPOINT_FROM_LEVEL pop Temp ret //------------------------------------- //------------------------------------- //PROCESS_RECEIVED_CHAR // { char } // save first char after { // process it on receiving } // // char in Temp //------------------------------------- PROCESS_RECEIVED_CHAR: cpi Temp, '{' // breq PROCESS_RECEIVED_START_CMD cpi Temp, '}' // breq PROCESS_RECEIVED_END_CMD // else save last char tst commandCharacter brne RET_PROCESS_RECEIVED_CHAR // else save the first mov commandCharacter,Temp; rjmp RET_PROCESS_RECEIVED_CHAR PROCESS_RECEIVED_START_CMD: clr commandCharacter // clear on msg start rjmp RET_PROCESS_RECEIVED_CHAR PROCESS_RECEIVED_END_CMD: mov Temp, commandCharacter rcall PROCESS_CMD_CHAR // process the cmd ldi commandCharacter, -1 // finished processing RET_PROCESS_RECEIVED_CHAR: ret //------------------------------------- //------------------------------------- // PROCESS_CMD_CHAR // once the } is received // PROCESS_CMD_CHAR: cpi Temp, 'o' // turn on/off breq PROCESS_RECEIVED_ON_OFF cpi Temp, 'f' // fade on/off breq PROCESS_RECEIVED_FADE_ON_OFF cpi Temp, 'a' // show data menu breq PROCESS_RECEIVED_DATA_MENU // else cpi Temp, 'l' // breq PROCESS_RECEIVED_SET_MENU // else cpi Temp, '.' // breq PROCESS_RECEIVED_MAIN_MENU // else cpi Temp, 'm' // breq PROCESS_RECEIVED_SUB_MAIN // else cpi Temp, '0' // breq PROCESS_RECEIVED_CHAR_TORCH_OFF // else cpi Temp, '1' // breq PROCESS_RECEIVED_CHAR_TORCH_LOW // else cpi Temp, '2' // breq PROCESS_RECEIVED_CHAR_TORCH_MED // else cpi Temp, '3' // breq PROCESS_RECEIVED_CHAR_TORCH_HIGH // else cpi Temp, 'u' // breq PROCESS_RECEIVED_CHAR_TORCH_UP cpi Temp, 'd' // breq PROCESS_RECEIVED_CHAR_TORCH_DOWN cpi Temp, 'i' // breq PROCESS_RECEIVED_CHAR_SEND_ADC_READING cpi Temp, 'v' // breq PROCESS_RECEIVED_CHAR_SEND_LIGHT_LEVEL // else invalid char so just ignore // send back {} rjmp PROCESS_RECEIVED_CHAR_SEND_EMPTY_CMD PROCESS_RECEIVED_FADE_ON_OFF: // if on or fade on fade off on turn off else turn on BRANCH_IF_TORCH_OFF_OR_FADING_DOWN PROCESS_RECEIVED_FADE_TO_ON // EQ so was FADE_DOWN => fade up rjmp PROCESS_RECEIVED_FADE_TO_OFF // not off or fade down so => fade down PROCESS_RECEIVED_FADE_TO_ON: ldi New_Torch_State, Torch_State_FADE_UP inc Level // increase level now so state not cleared to Off rjmp PROCESS_RECEIVED_FADE_UPDATE PROCESS_RECEIVED_FADE_TO_OFF: ldi New_Torch_State, Torch_State_FADE_DOWN dec Level // decrease level now so state not cleared to MAX //rjmp PROCESS_RECEIVED_FADE_UPDATE // drop through PROCESS_RECEIVED_FADE_UPDATE: sbr CMDS, (1< turn on // else // drop through // rjmp PROCESS_RECEIVED_TURN_OFF PROCESS_RECEIVED_TURN_OFF: ldi New_TORCH_State,Torch_State_OFF sbr CMDS, (1< off // 1 => low, 2 => med, 3 => high // f => fade on / fade off // o => on / off // u increase level // d decrease level // i show current reading // v show level and light setting // //************************************************************************* RESET: cli // disable interrupts // set clock to 8Mhz i.e. remove div8 that is set by programmer ldi Temp, (1< send on //else on send off menu //rjmp SEND_MAIN_MENU_ON drop through BRANCH_IF_TORCH_NOT_MAX SEND_MAIN_MENU_ON SEND_MAIN_MENU_MAX: push ZH push ZL ldi ZH, high(2*Main_Menu_Max) ldi ZL, low(2*Main_Menu_Max) // Set pointer to RAM data rcall LOAD_CHARS pop ZL pop ZH rjmp SEND_ONOFF_UPDATE_FINISHED SEND_MAIN_MENU_ON: push ZH push ZL ldi ZH, high(2*Main_Menu_On) ldi ZL, low(2*Main_Menu_On) // Set pointer to RAM data rcall LOAD_CHARS pop ZL pop ZH rjmp SEND_MAIN_MENU_FINISH SEND_MAIN_MENU_OFF: // else on load off msg push ZH push ZL ldi ZH, high(2*Main_Menu_Off) ldi ZL, low(2*Main_Menu_Off) // Set pointer to RAM data rcall LOAD_CHARS pop ZL pop ZH // rjmp SEND_MAIN_MENU_FINISH drop through SEND_MAIN_MENU_FINISH: // calculate number of chars to send ldi Temp, low(RS232_BUFFER_1+1) sub Temp, XL // only need to do the low byte as buffer size < 255 // and sub result above will wrap round to the correct difference sts RS232_SEND_COUNT, Temp // set number of chars to send // restore registers pop XL pop XH pop Temp rcall RS232_TRANSMIT END_SEND_MAIN_MENU: ret //--------------------------------------------------------- //------------------------------------------------------- // SEND_ONOFF_UPDATE // send back menu update // //------------------------------------------------------- SEND_ONOFF_UPDATE: sbrs CMDS, CMDS_OnOffUpdate rjmp END_SEND_ONOFF_UPDATE // check if still busy transmitting last buffer // or busy receiving byte // do not clear trigger yet BRANCH_IF_RS232_BUSY END_SEND_ONOFF_UPDATE // busy sending so keep trigger and try later // else not busy sending so send this light % reading // clear this trigger now as now sending main menu cbr CMDS, (1< send on // else on => send off //rjmp SEND_ONOFF_UPDATE_OFF drop through BRANCH_IF_TORCH_NOT_MAX SEND_ONOFF_UPDATE_ON SEND_ONOFF_UPDATE_MAX: push ZH push ZL ldi ZH, high(2*Main_Menu_UpdateMsg_Max) ldi ZL, low(2*Main_Menu_UpdateMsg_Max) // Set pointer to RAM data rcall LOAD_CHARS pop ZL pop ZH rjmp SEND_ONOFF_UPDATE_FINISHED SEND_ONOFF_UPDATE_OFF: push ZH push ZL ldi ZH, high(2*Main_Menu_UpdateMsg_Off) ldi ZL, low(2*Main_Menu_UpdateMsg_Off) // Set pointer to RAM data rcall LOAD_CHARS pop ZL pop ZH rjmp SEND_ONOFF_UPDATE_FINISHED SEND_ONOFF_UPDATE_ON: push ZH push ZL ldi ZH, high(2*Main_Menu_UpdateMsg_On) ldi ZL, low(2*Main_Menu_UpdateMsg_On) // Set pointer to RAM data rcall LOAD_CHARS pop ZL pop ZH rjmp SEND_ONOFF_UPDATE_FINISHED SEND_ONOFF_UPDATE_FINISHED: // calculate number of chars to send ldi Temp, low(RS232_BUFFER_1+1) sub Temp, XL // only need to do the low byte as buffer size < 255 // and sub result above will wrap round to the correct difference sts RS232_SEND_COUNT, Temp // set number of chars to send // restore registers pop XL pop XH pop Temp rcall RS232_TRANSMIT END_SEND_ONOFF_UPDATE: ret //--------------------------------------------------------- //------------------------------------------------------- // SEND_SET_MENU // send set menu // //------------------------------------------------------- SEND_SET_MENU: sbrs CMDS, CMDS_SetMenu rjmp END_SEND_SET_MENU // check if still busy transmitting last buffer // or busy receiving byte // do not clear trigger yet BRANCH_IF_RS232_BUSY END_SEND_SET_MENU // busy sending so keep trigger and try later // else not busy sending so send this light % reading // clear this trigger now as now sending main menu cbr CMDS, (1<|a~Data->}" Empty_Cmd_Msg: // .db line must have an even number of chars // first value is the number of chars to load .db 3, "{} " Streaming_Msg: // this msg is used for both streaming current and level // .db line must have an even number of chars // first value is the number of chars to load .db 3, "{=}" Set_Menu_Msg: // .db line must have an even number of chars // first value is the number of chars to load .db 31, "{.|1~Low|2~Medium|3~High|0~Off}" Data_Menu_Msg: // .db line must have an even number of chars // first value is the number of chars to load .db 31, "{.|v~Light Level|i~Led Current}" // ========= Streaming data messages ========== Level_Msg: // .db line must have an even number of chars // first value is the number of chars to load .db 7, 13, "Level " Light_Msg: // .db line must have an even number of chars // first value is the number of chars to load .db 7, 13,"Light " Amps_Msg: // .db line must have an even number of chars // first value is the number of chars to load .db 7, 13," Amps "