;************************************************************** ;* This stationery serves as the framework for a * ;* user application. For a more comprehensive program that * ;* demonstrates the more advanced functionality of this * ;* processor, please see the demonstration applications * ;* located in the examples subdirectory of the * ;* Freescale CodeWarrior for the HC12 Program directory * ;************************************************************** ; Include derivative-specific definitions INCLUDE 'derivative.inc' XREF __SEG_END_SSTACK ; symbol defined by the linker for the end of the stack ; LCD References XREF init_LCD ; export symbols ; we use export 'Entry' as symbol. This allows us to ; reference 'Entry' either in the linker .prm file ; or from C/C++ later on XDEF Entry,_Startup,disp,CRGFLG ;==================== variables ================================= ;password XDEF password,new_password,pw_prompt_shown,pw_check,pw_correct,pw_set,pw_incorrect,entered_password,pw_required ;keypad XDEF pressed_key,pressed_num,await_key_release,await_key_press ;menu XDEF menu_active,toast_timer,menu_option_num,menu_timer,display_timeout ;watering (menu option 1) XDEF is_watering,watering_timer,sprinkler_event,sprinkler_timer,sprinkler_arr_i ;temperature (menu option 2) XDEF show_temperature,fan_speed,circulation_count,dc_on ;wall clock (menu option 3) XDEF current_year,current_month,current_day,current_hour,current_minute,current_second XDEF display_time,wall_timer,clock_event,second_passed,ms_counter ;adjust clock (menu option 4) XDEF change_time ;reset password (menu option 5) XDEF pw_reset ;================== constants ================================= ;ports and peripherals XDEF PSR_U,PDR_U,PORT_U,DDR_T,PORT_T,DDR_P,PORT_P,DDR_S,PORT_S ;keypad XDEF KVS,SEQUENCE ;stepper motor XDEF SPRINKLER_ARR ;===================== subroutines ============================= ; Potentiometer References XREF display_string XREF pot_value ;subroutines XREF Password,Menu,Keypad,Water,Circulation,Wall,Growlights ;================= debugging =================================== XDEF word_out,byte_out ; ================= general notes ===================== ; - routines should generally be asynchronous ; - need a way to marshall values into single characters ; like the pot. resistance display from lab ; - use two seperate routines, one for each song ; - set all the flags with the 1 ms RTI ; - reading the password asychronously will be a ; pain in the ass, maybe skip that ; - think about the last lab and skipping the await ;====================================================== ;================ flow of the program ================= ; 1. Prompt for the password. Nothing will happen until the password is set. ; 2. Acknowlege the password, wait, then show help, wait, then show menu ; 3. Show help, wait (press 0 to show help) ; 4. Show main menu, start air circulation, and start grow light control ;====================================================== ;==================== main menu ======================= ; 1. water the plants ; 2. show temperature (adjusts when the pot is turned) ; 3. show time ; 4. set time (passord protected) ; 5. change password (password protected) ;====================================================== ; variable/data section my_variable: SECTION disp ds.b 33 ;the character string to output to the LCD (given) ;password variables password: ds.b 8 ;the byte array that stores the password entered_password ds.b 8 ;will be check against the password new_password ds.b 8 ;overwrite the old password with a new one pw_prompt_shown ds.b 1 ;only print the initial password prompt once pw_check ds.b 1 ;require the password before continueing pw_correct ds.b 1 ;check the correctness of the password pw_set ds.b 1 ;flag to fire after the password has been entered pw_incorrect ds.b 1 ;will determine if the password needs to be tried again pw_required ds.b 1 ;flag to set if a password is required to enter a screen ;keypad variables pressed_key ds.b 1 ;the keypad value in the LUT pressed_num ds.b 1 ;the numeral of the pressed key or the index of PRESSED in the LUT await_key_release ds.b 1 ;whether or not to await the keypad release await_key_press ds.b 1 ;================== state variables ===================== ; Primary UI menu_active ds.b 1 ;show the main menu toast_timer ds.w 1 ;(counter) used to delay the screen outputs so that the user can read them menu_option_num ds.b 1 ;which menu option is displayed menu_timer ds.w 1 ;timer to check the menu cycle display_timeout ds.b 1 ;(flag) to go back to the menu when an input is made ; menu item 1 (watering state) is_watering ds.b 1 ;flag that sets the state to watering (spin the motor, play the tune, and ;show "Watering in \nprogress..." on the LCD ;also one or more LED's should illuminate ;also the stepper motor should spin like a sprinkler ;also this should only run for a period of time watering_timer ds.w 1 ;(counter) to time the watering, stop after some time sprinkler_event ds.b 1 ;event to fire to spin stepper motor like a sprinkler sprinkler_timer ds.b 1 ;(counter) time delay for sprinkler sprinkler_arr_i ds.b 1 ;sprinkler array index ; menu item 2 (air circulation state, show temperature) show_temperature ds.b 1 ;display the current temperature fan_speed ds.b 1 ;reads the potentiometer circulation_count ds.b 1 ;counter to spin the DC motor dc_on ds.b 1 ;event pulse for DC motor ; menu item 3 (display time) display_time ds.b 1 ;show the time on the screen current_year ds.w 1 ;what year is it current_month ds.b 1 ;what month is it (a number) current_day ds.b 1 ;day of the month current_hour ds.b 1 ;hour of the day (military time) current_minute ds.b 1 ;... current_second ds.b 1 ;... wall_timer ds.w 1 ;timeout for the clock display clock_event ds.b 1 ;event that will fire every 4 milliseconds ms_counter ds.w 1 ;counter for the milliseconds second_passed ds.b 1 ;event that fires when a second has passed setting_wall ds.b 1 ;will flag when the clock is being set by the user ; menu item 4 (change time) change_time ds.b 1 ;the user has elected to change the date and the time ;all or nothing on this; everything must be entered ; menu item 5 (change password) pw_reset ds.b 1 ;flag to trigger that a password should be reset ;this should be done in an async manner when prompted by the user ;(in an emergency, this process should be synchronous) ;in order to not stop the air or watering or grow lights ; menu item 6 (plant seeds) ; menu option 7 (show plot) ; debugging word_out ds.w 1 byte_out ds.b 1 ;=============================== END state variables ===================================== my_constant: SECTION ;ports DDR_U equ $26A PSR_U equ $26D PDR_U equ $26C PORT_U equ $268 DDR_T equ $242 ;the DIP switches and DC motor PORT_T equ $240 PORT_P equ $258 ;stepper motor DDR_P equ $25A DDR_S equ $24A ;LED's PORT_S equ $248 ;keypad ;key value pairs from 4.3 KVS dc.b $EB,$77,$7B,$7D,$B7,$BB,$BD,$D7,$DB,$DD,$E7,$ED,$7E,$BE,$DE,$EE ;given sequence from lab instructions (with trailing zero) SEQUENCE dc.b $70,$B0,$D0,$E0,$00 ;stepper motor SPRINKLER_ARR dc.b $0A,$12,$14,$12,$14,$0C,$14,$0C MyCode: SECTION _Startup: Entry: lds #__SEG_END_SSTACK ;keypad stuff BSET DDR_U,#$F0 ;bits 1-3 in bits 4-7 out BSET PSR_U,#$F0 ;pins 1-3 pull up BSET PDR_U,#$0F ;pull up pins 1-3 CLR await_key_release ;do not await by default MOVB #$FF,await_key_press;await presses by default ;LED stuff BSET DDR_S,#$FF ;all outputs on LED port MOVB #$00,PORT_S ;off initally ;switch and DC motor stuff MOVB #$08,DDR_T ;needs to be set for the motor to spin ;LCD stuff JSR init_LCD ;event loop stuff MOVB #$80,CRGINT ;enable real-time interrupts MOVB #$60,RTICTL ;set RTI interval to 4 ms; "#$40,RTICTL" would be 1 ms ;MOVB #$40,RTICTL CLI ;enable interrupts ;state variable stuff (password MOVB #$FF,password ;this password will never be correct, it needs to be changed MOVB #$FF,password+1 MOVB #$FF,password+2 MOVB #$FF,password+3 MOVB #$FF,password+4 MOVB #$FF,password+5 MOVB #$FF,password+6 MOVB #$FF,password+7 CLR pw_set ;the password is not inititally set CLR pw_incorrect ;the password will not start out as incorrect because it hasn't been set CLR pw_correct ;menu stuff CLR menu_active ;menu is not inititally active MOVB #$01,menu_option_num;start on option '1' CLR menu_timer ;set the menu timer at '0' this will be incremented in the event loop ;watering and stepper motor stuff CLR is_watering ;watering CLR watering_timer ;duration of watering CLR sprinkler_event ;fired to the stepper motor CLR sprinkler_timer ;duration of delay among items of the stepper array sequence MOVB #$1E,DDR_P ;DDR setting for the stepper MOVB #$00,sprinkler_arr_i;start at the beginning of the array ;other menu items CLR show_temperature ;menu item CLR change_time ;menu item CLR pw_reset ;menu item ;circulation CLR fan_speed CLR circulation_count ;wall clock MOVW #1970,current_year ;UNIX time MOVB #1,current_month ;start on Jan. 1 MOVB #1,current_day ;... CLR current_hour ;start at 00:00:00 CLR current_minute ;... CLR current_second ;... CLR wall_timer ;the timer that sets whether or not the clock displays CLR clock_event ;event is not initially fired CLR second_passed ;event that will fire each time one second has passed CLR ms_counter ;count milliseconds in the event loop CLR display_time Init: ;run any password related things first JSR Password ;do nothing until the password is set LDAA pw_set CMPA #$FF BNE Init ;activate the menu after the password is set MOVB #$FF,menu_active ;hide evey other display element ;set the keypress to an impossible value ;this clears the value from the password ;before reading the keypress in the menu MOVB #$FF,pressed_num Main: ;go to the menu when the password is set JSR Menu ;call each subroutine ;subroutines are controlled by events fired in the RTI JSR Circulation JSR Water JSR Growlights; <- should be uncommented (using LED's for debugging) JSR Wall JSR Password ;read the keypad when the menu is showing ;make the keypad read not branch from the password leftover pressed value ;the keypad being the primary means of controlling the program, ;we have it running in main (for now) ;get user menu selection (do not await presses or releases) MOVB #$00,await_key_release MOVB #$00,await_key_press JSR Keypad ;return to the main loop BRA Main