/* --------------------------------------------------------------------- ** Figure 18.20: Declarations for the skylight controller: skylight.h. ** Figure 18.21: A skylight controller. ** Figure 18.22: Operations for the skylight controller. ** --------------------------------------------------------------------- */ #include "tools.h" /* ----------------------------------------------------------------- ** Definitions of the registers on the multifunction chip */ typedef struct REG_BYTE { unsigned int : 4; unsigned int fully_open : 1; unsigned int fully_closed : 1; unsigned int motor_power : 1; unsigned int motor_direction : 1; } reg_byte; typedef volatile reg_byte* device_pointer; /* ----------------------------------------------------------------- ** Definitions of the codes for the multifunction chip */ enum power_values { motor_off = 0, motor_on = 1 }; enum direction_values { motor_forward = 0, motor_reverse = 1 }; string position_labels[] = { "fully closed", "partially open", "fully open" }; typedef enum { fully_closed, part_open, fully_open } position; /* ----------------------------------------------------------------- ** Attach to hardware addresses and create initialization constants. */ device_pointer const DR = (device_pointer)0xffff7100; device_pointer const DDR = (device_pointer)0xffff7101; const reg_byte DDR_mask = {0,0,1,1}; /* select output bits */ const reg_byte DR_init = {0,0,0,0}; /* initialize motor off */ /* ----------------------------------------------------------------- ** Prototypes for the control operations. */ position skylight_status( void ); void open_skylight( void ); void close_skylight( void ); /* ---------------------------------------------------------------- */ void main( void ) { char choice; string menu[] = { "O: Open skylight", "C: Close skylight", "R: Report on position", "Q: Quit" }; /* Initialize chip registers used by application. ------ */ *DDR = DDR_mask; /* Designate input and output bits. */ *DR = DR_init; /* Make sure motor is turned off. */ for (;;) { choice = toupper( menu_c( " Select operation:", 4, menu ) ); if (choice == 'Q') break; switch (choice) { case 'O': open_skylight(); break; case 'C': close_skylight(); break; case 'R': /* Report on position */ printf ( " Louver is %s\n", position_labels[skylight_status()] ); break; default: puts( " Incorrect choice, try again." ); } } puts( " Skylight controller terminated.\n" ); } /* ----------------------------------------------------------------- ** Return skylight position */ position skylight_status( void ) { if (DR->fully_closed) return fully_closed; else if (DR->fully_open) return fully_open; else return part_open; } /* ---------------------------------------------------------------- ** Open skylight */ void open_skylight( void ) { reg_byte dr = { 0, 0, motor_on, motor_forward }; if (DR->fully_open) return; /* don't start motor if already open */ *DR = dr; while (!(DR->fully_open)); /* delay until open */ dr.motor_power = motor_off; *DR = dr; } /* ---------------------------------------------------------------- ** Close skylight */ void close_skylight( void ) { reg_byte dr = { 0, 0, motor_on, motor_reverse }; if (DR->fully_closed) return; /* don't start motor if already closed */ *DR = dr; while (!(DR->fully_closed)); /* delay until closed */ dr.motor_power = motor_off; *DR = dr; } /* ------------------------ (used by emacs) ----------------------- *\ Local Variables: mode:C tab-width:4 End: \* ---------------------------------------------------------------- */