*********************************************************************** * Software License Agreement * * The software supplied herewith by Microchip Technology Incorporated * * (the "Company") is intended and supplied to you, the Company's * * customer, for use solely and exclusively on Microchip products. * * * * The software is owned by the Company and/or its supplier, and is * * protected under applicable copyright laws. All rights are reserved. * * Any use in violation of the foregoing restrictions may subject the * * user to criminal sanctions under applicable laws, as well as to * * civil liability for the breach of the terms and conditions of this * * license. * * * * THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES, * * WHETHER EXPRESS, IMPLIED OR STATU-TORY, INCLUDING, BUT NOT LIMITED * * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT, * * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR * * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. * * * *********************************************************************** This file contains general design notes for the functions, tasks, state machines, timing, priority control, communications and command structures of the LumiLED LED driver software. This file is for the Buck configuration driver. ************************************************************************************************ Software Functions 1. Generate a PWM output for intensity control 2. Decode key press 3. Decode key push 4. Decode key hold 5. Intensity control 6. Mode select 7. EEPROM reader 8. Intensity command 9. Time command 10. Repeat command 11. Goto command 12. Power up configure 13. Power down configure 14. Battery monitoring 15. Intensity correction for battery voltage Task list Timer task 1. PWM for intensity control 2. System Timing Key task 1. Decode Key press 2. Decode key push 3. Decode key hold Command task 1. Power up read and configure 2. Power down store and shut down 3. Intensity Control 4. Mode Select Auto sequence Task 1. Intensity command 2. Time command 3. Repeat command 4. Goto command Eprom Task (handled as macros in the command and Auto Sequence tasks, no state machine created) 1. Read eeprom 2. Write eeprom ADC task 1. Battery monitoring 2. Intensity correction **************************************************************************************************************** Inter-Task Communications Item Source Destination Communications 1. Command Auto Seq Bright both for command feedback and flash lite mode 2, Auto Seq ADC Inten_chng Notifies ADC of change in intensity 3. Cmd/Tmr Cmd/Tmr Timing for Mode select, 3 second timer start/done 4. Key Command press, push, hold intesity and mode select flags 5. CMD/EEPROM EEPROM/CMD System State Save mode & intensity on pwrdn, retrieve on Pwrup 6. Command Auto Seq Mode Mode select, 1,2,3,4 or 5. 1 is do nothing 7. AuSq/EEPROM EEPROM/AuSq Commands given an address, return the command 8. AuSq/TMR TMR/AuSq Time delay for Time delay command, time, start, done 9. Auto Seq ADC Intensity in modes 2-5, intensity setting per command 10. Auto Seq ADC Inten_chng notifies ADC of change in intensity 11. ADC Timer Final duty cycle corrected for battery sag **************************************************************************************************************** System Timing skip timer Timer 1kHz 1 msec 1:1 Key 100 Hz or faster 10 msec 10:1 Command 100 Hz 10 msec 10:1 Auto Sequence 10 Hz +/- 10% 100 msec 100:1 ADC 10 Hz 100 msec 100:1 Minimum Tick = 1 msec **************************************************************************************************************** System Priorities System States Mode/Intensity Select 1. Key 2. Command 3. Timer 4. ADC Auto Sequence 1. Auto sequence 2. Timer 3. ADC Flash Light 1. Key 2. Timer 3. ADC 4. Command Power up/down 1. Command 2. EEPROM Auto Sequence only needed in Auto Sequence mode Key and Timer are optional in power up and down Command becomes important when key detects activity ADC needed only when actual intensity output is performed *************************************************************************************************************** Timer State machine design Not a true state machine, rather is a timer system with a PWM pulse generator as part of the execution path. Timing algorithm Wait for TMR0 roll over switch (duty cycle) { case 0%: output low return case 100%: output high return case 1-50%: generate high output pulse return case 50-100%: generate low output pulse return } if (key_skip_timer-- == 0) { do_key = true key_skip_timer = 10 } if (cmd_skip_timer-- == 0) { do_cmd = true cmd_skip_timer = 5 } if (auto_skip_timer-- == 0) { do_auto = true auto_skip_timer = 100 } if (adc_skip_timer-- == 0) { do_adc = true adc_skip_timer = 100 } *************************************************************************************************************** Key State machine design Execution indexed state machine State 0 Idle no key pressed 1 press key held < 1.5 sec 2 push key held < 3.0 sec 3 hold key held > 3.0 sec 4 delay auto repeat delay for hold 5 default error state 6 default error state 7 default error state STATE TO STATE TRANSITIONS From Conditional if True if False comments ----------------------------------------------------------------------------------------- Idle if key press detected press Idle no key press if keypress = 0 Idle press key stable at open press press is time > 1.5 sec push press if held > 1.5 s then push push if keypress = 0 Idle push key stable at open Push push if time > 3.0 sec hold push if held > 3.0 s then hold hold if keypress = 0 Idle hold key stable at open hold hold delay ---- goto delay for auto repeat delay if keypress = 0 Idle delay key stable at open delay delay if time = 3.0 sec hold delay auto repeat ACTIONS Idle none press if release send press command push if release send push command hold send hold command delay delay 3.0 seconds then return to hold Code segment prior to state variable decoder, monitors the button and debounces with keypress as an output. (Algorithm) if (key == 0) and (bcounter < 7) then bcounter++ if (key == 1) and (bcounter > 0) then bcounter-- if bcounter == 6 then keypress = 1 if bcounter == 2 then keypress = 0 INPUT/OUTPUT input output Idle keypress ---- press keypress press cmd push keypress push cmd hold keypress hold cmd delay keypress ---- *************************************************************************************************************** Command State machine design Hybrid Execution and Data indexed state machine State 0 Incint Intensity increment mode 1 Decint Intensity decrement mode 2 Modesel Mode select mode 3 Display data indexed state machine for mode number display Note: no default state needed STATE TO STATE TRANSITIONS From Conditional if True if False comments ------------------------------------------------------------------------------------------------------------------- Incint if push command Decint Incint change from inc to dec Incint if hold command Modesel Incint change to mode select Decint if push command Incint Decint change from dec to inc Decint if hold command Modesel Decint change to mode select Modesel if keypress = 0 Incint Modesel key is released go back to keypress Modesel if hold command Display Modesel display next mode number Display if display complete Modesel Display display routine completes if started. ACTIONS Incint if (Push == 1) and (old_push == 1) then power off if (Push == 1) then old_push = 1 if (Press == 1) or (Hold == 1) old_push = 0 clear Push if (Press == 1) and (intensity < max) then intensity++ and store in eeprom clear Press Decint if (Push == 1) and (old_push == 1) then power off if (Push == 1) then old_push = 1 if (Press == 1) or (Hold == 1) old_push = 0 clear Push if (Press == 1) and (intensity > 0) then intensity-- and store in eeprom clear Press Modesel set asq_hold if keypress = 0 clear asq_hold set new_mode flag mode++ if mode = number_of_modes+2 mode = 1 Display flash .5 second off with 1 second gap for mode index 1-5 (i.e. 1 to 5 flashes) INPUT/OUTPUT input output Incint press, push, hold intensity Decint press, push, hold intensity Modesel hold, keypress Mode Display ---- intensity DISPLAY SEQUENCE counter = 0 pointer = mode * 2 loop if counter == 0 if pointer is odd counter = 20 intensity = 1/2 else counter = 10 intensity = full pointer-- if pointer == 0 goto Modesel_state counter-- *************************************************************************************************************** Auto Sequence State machine design Hybrid Execution and Data indexed state machine Auto sequence Task D7 D6 D5 D4-0 1. Intensity command 0 0 Intensity 2. Time command 0 1 Time delay 3. Repeat command 1 0 repeat count Return at the end 1 0 0 0000 4. Goto command 1 1 destination shut down command 1 1 0 0000 if asq_hold is true, this state machine is idle if new_mode, state is reset to asq_change sequence numbers 1-63, zero causes shut down State 0 Decode Fetch a command and decode it 1 Set_Intens Intensity set command 2 Time_Delay Time Delay command 3 Jump goto different step number 4 Repeat repeat section command 5 Delay used for time command 6 ASQ_change auto sequence, sequence change. Reset of system for next sequence 7 flash_lite no sequence, continuous mode only STATE TO STATE TRANSITIONS From Conditional if True if False Decode if command = Intensity Set_Intens Decode Decode if command = Time Time_delay Decode Decode if command = Jump Jump Decode Decode if command = Repeat Repeat Decode Set_Itens none Decode Time_Delay none Delay Jump none Decode Repeat none Decode Delay if timer == 0 Decode Delay ASQ_change mode = 1 flash_lite Decode ACTIONS Decode get command(addr_next) addr_next++ decode command & 0xC0 ASQ_data = command & 0x3F Set_Intens intensity = ASQ_data set int_chng Time_Delay Timer = ASQ_data Jump addr_next = ASQ_data Repeat addr_next++ if ASQ_data == 0 ; indicates a return to a repeat pop ret_addr pop counter ; retrieve counter and return address counter-- ; count this pass if counter == 0 break (return) else push counter push ret_addr addr_next = ret_addr else ; not a return push ASQ_data push addr_next Delay Decrement timer ASQ_change reset repeat stack clear new_mode flag if mode > 1 addr_next = eeprom(start,mode) flash_lite intensity = eeprom(EE_intensity) set int_chng *************************************************************************************************************** ADC State machine design Execution indexed state machine State 0 Idle wait state 1 Convert do battery voltage conversion 2 Calculate correct intensity for battery voltage 3 LowBattery shut down state STATE TO STATE TRANSITIONS From Conditional if True if False comments ------------------------------------------------------------------------------------------------------------------- Idle if intensity change Calculate Idle waiting Idle if convert timer timeout Convert Idle Idle if intensity change Calculate Idle Convert none Calculate Calculate none Idle LowBattery shutdown ACTIONS Idle none Convert set PWM output high and convert battery voltage Calculate using ADC of battery convert intensity to duty cycle LowBattery shutdown INPUT/OUTPUT input output Idle ADC_skip_timer, Intensity_change none Convert ADC, dutycycle ADRESH Calculate Intensity, ADRESH dutycycle LowBattery none none Math functions DATA For Buck system VDC ADC Max PWM CF 4.0 2E .337 100% 4.5 29 .385 91% 5.0 25 .435 80% 5.5 21 .483 72% 6.0 1E .535 65% Maximum intensity @ 350 mV Conversion factor = (ADC*6 - 0B) Duty cycle = Scaling value * Intensity * 2 / 256 *************************************************************************************************************** Error recovery handler Error State machine Reason for error Response pwm_err Timer routine PWM value to large reset dutycycle to 7F adc_err ADC routine state variable wrong reset to idle state cmd_err Command state variable wrong reset to idle state asq_err Autosequence state variable wrong reset to change state key_err Key default state reached reset to idle state