1 | void init_port_b ( void )
|
2 | {
|
3 | ATOMIC_BLOCK( ATOMIC_RESTORESTATE )
|
4 | {
|
5 | DDRB |= (1<<PB0); // Set line 0 of port B as output
|
6 | DDRB |= (1<<PB1); // Set line 1 of port B as output
|
7 | DDRB |= (1<<PB2); // Set line 2 of port B as output
|
8 | DDRB |= (1<<PB3); // Set line 3 of port B as output
|
9 | DDRB |= (1<<PB4); // Set line 4 of port B as output
|
10 |
|
11 | // Heartbeat LED: Line 0 -> Switch off initially
|
12 |
|
13 | PORTB &= ~( 1<<PB0 );
|
14 |
|
15 | asm volatile ( "nop" ); // Give the AVR time to settle
|
16 | }
|
17 |
|
18 | return;
|
19 | }
|
20 |
|
21 | void set_error_led( void )
|
22 | {
|
23 | PORTB = PINB | (1 << PB0);
|
24 | }
|
25 |
|
26 | void clear_error_led( void )
|
27 | {
|
28 | PORTB = PINB & ~(1 << PB0);
|
29 | }
|
30 |
|
31 | void dit(void)
|
32 | {
|
33 | clear_error_led();
|
34 | set_error_led();
|
35 | _delay_ms( 100 );
|
36 | clear_error_led();
|
37 | }
|
38 |
|
39 | void dah( void )
|
40 | {
|
41 | clear_error_led();
|
42 | set_error_led();
|
43 | _delay_ms( 250 );
|
44 | clear_error_led();
|
45 | }
|
46 |
|
47 | void roger( void )
|
48 | {
|
49 | dit();
|
50 | dah();
|
51 | dit();
|
52 | }
|
53 |
|
54 | void init_io_timer ( void )
|
55 | {
|
56 | ATOMIC_BLOCK( ATOMIC_RESTORESTATE )
|
57 | {
|
58 | // We use timer 1 (16 bit Timer) in CTC mode. This timer shall
|
59 | // generate an interrupt every PSU_IO_UPDATE_INTERVAL seconds.
|
60 | // Prescaler has to be set to 1 !
|
61 |
|
62 | OCR1A = (unsigned short)
|
63 | ((unsigned long) F_CPU / PSU_IO_IRQS_PER_SECOND /
|
64 | PSU_IO_TIMER_PRESCALE - 1); // Load the timer compare value
|
65 |
|
66 | TCNT1 = 0; // Reset counter value
|
67 | TCCR1A = 0; // No PWM
|
68 | TCCR1B = _BV( WGM12 ) | _BV( CS11 ); // Set CTC mode
|
69 | TIMSK0 |= _BV( OCIE1A ); // Output Compare A Interrupt
|
70 | }
|
71 | }
|
72 |
|
73 | rc_t greet( unsigned long nDelayMilliSeconds )
|
74 | {
|
75 | rc_t nRC = RC_OK;
|
76 |
|
77 | // Line 1: Title
|
78 | display_format( 1, strcpy_P( (char *) &acBuffer[0], PSTR( "* PSU + DARC *" )));
|
79 |
|
80 | // Line 2: Model
|
81 | display_format( 2, strcpy_P( (char *) &acBuffer[0], PSTR( ">%6s< by DG1SBG" )), PSU_MODEL );
|
82 |
|
83 | // Line 3 Serial Nr and Version
|
84 | display_format( 3, strcpy_P( (char *) &acBuffer[0], PSTR( "# %s - %s")), PSU_SERIAL_NR, PSU_VERSION );
|
85 |
|
86 | roger();
|
87 |
|
88 | if( nDelayMilliSeconds > 0 )
|
89 | _delay_ms( nDelayMilliSeconds );
|
90 |
|
91 | return nRC;
|
92 | }
|
93 |
|
94 | ISR( TIMER1_COMPA_vect ) // Routine triggered by Timer 1 to
|
95 | { // interact with the user
|
96 |
|
97 | heart_beat();
|
98 |
|
99 | update_lamps(); // Update the lamp on/off to match relays
|
100 | update_i2c_io(); // Read digital inputs and write relays
|
101 |
|
102 | // sample_voltages();
|
103 |
|
104 | debounce(); // Debounce pushbuttons
|
105 |
|
106 | darc_get_command(); // Read command from DARC channel
|
107 | }
|
108 |
|
109 |
|
110 | int main ( void )
|
111 | {
|
112 | rc_t nRC = RC_OK;
|
113 |
|
114 | // Status engine: Still outside of it
|
115 |
|
116 | nCmdFromISR = NO_CMD;
|
117 | bInStatusNetEngine = FALSE;
|
118 | bPBsEnabled = FALSE;
|
119 |
|
120 | // Delay 2 seconds for all devices to settle
|
121 |
|
122 | _delay_ms( 2000 );
|
123 |
|
124 | // Do basic inits as fast as possible
|
125 |
|
126 | init();
|
127 | execute_cmd_from_isr();
|
128 |
|
129 | // Display the reason why the controller is booting
|
130 |
|
131 | analyse_reset_reason( 1000 );
|
132 | execute_cmd_from_isr();
|
133 | blink_error_led_fast();
|
134 |
|
135 | // Say hello on LCD
|
136 |
|
137 | greet( 1000 );
|
138 | execute_cmd_from_isr();
|
139 |
|
140 | // Make error logging in EEPROM possible
|
141 |
|
142 | show_last_logged_error( 2000 );
|
143 | execute_cmd_from_isr();
|
144 |
|
145 | // Kick off status net - THIS IS THE MAIN LOOP ...
|
146 |
|
147 | bInStatusNetEngine = TRUE;
|
148 |
|
149 | clear_display();
|
150 |
|
151 | switch_status( PSU_STATUS_ID_PSU_BOOTING );
|
152 |
|
153 | while( nRC == RC_OK )
|
154 | {
|
155 | nRC = goto_next_status( nNextStatus );
|
156 | }
|
157 |
|
158 | // When this point is reached it most likely means that a reset is
|
159 | // required !
|
160 |
|
161 | if( IS_ERROR( nRC ) )
|
162 | log_error( nRC, __LINE__ );
|
163 |
|
164 | reset(); // Reboot PSU Controller !!!
|
165 |
|
166 | // This point never reached ...
|
167 | return 1;
|
168 | }
|