Rev 745 | Details | Compare with Previous | Last modification | View Log | SVN | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 731 | eqlazer | 1 | /** |
| 745 | eqlazer | 2 | * Antenna Display. |
| 731 | eqlazer | 3 | * For controlling of the cAntenna bus using one |
| 745 | eqlazer | 4 | * HD44780 LCD display and som buttons. |
| 731 | eqlazer | 5 | * |
| 745 | eqlazer | 6 | * |
| 7 | * |
||
| 8 | * @date 2007-11-19 |
||
| 731 | eqlazer | 9 | * @author Erik Larsson |
| 10 | * |
||
| 11 | */ |
||
| 12 | |||
| 13 | /*----------------------------------------------------------------------------- |
||
| 14 | * Includes |
||
| 15 | *---------------------------------------------------------------------------*/ |
||
| 16 | /* system files */ |
||
| 17 | #include <avr/io.h> |
||
| 18 | #include <inttypes.h> |
||
| 19 | #include <avr/interrupt.h> |
||
| 20 | #include <stdio.h> |
||
| 21 | #include <stdlib.h> |
||
| 22 | |||
| 23 | /* lib files */ |
||
| 745 | eqlazer | 24 | #include <bios.h> |
| 25 | #include <config.h> |
||
| 731 | eqlazer | 26 | #include <drivers/timer/timer.h> |
| 27 | #include <drivers/lcd/clcd/lcd_HD44780.h> |
||
| 28 | |||
| 29 | #include <string.h> //for memcpy |
||
| 30 | |||
| 31 | /*----------------------------------------------------------------------------- |
||
| 32 | * Defines |
||
| 745 | eqlazer | 33 | *---------------------------------------------------------------------------*/ |
| 731 | eqlazer | 34 | #define SIZE_X 16 |
| 35 | #define SIZE_Y 2 |
||
| 36 | |||
| 37 | #define BUFFER_SIZE SIZE_X |
||
| 38 | |||
| 39 | #define STOP 0 |
||
| 40 | #define AZIMUTH 1 |
||
| 41 | #define ELEVATION 2 |
||
| 42 | #define SCREEN_NORMAL 3 |
||
| 43 | #define SCREEN_CAL 4 |
||
| 44 | |||
| 45 | #define NORMAL_MODE 0x01 |
||
| 46 | #define CAL_MODE 0x02 |
||
| 47 | |||
| 48 | #define AZIMUTH_PLUS 0x05 |
||
| 49 | #define AZIMUTH_MINUS 0x06 |
||
| 50 | #define ELEVATION_PLUS 0x07 |
||
| 51 | #define ELEVATION_MINUS 0x08 |
||
| 52 | #define AZIMUTH_STOP 0x09 |
||
| 53 | #define ELEVATION_STOP 0x0a |
||
| 54 | #define GET_CAL 0x0b |
||
| 55 | #define SET_CAL 0x0c |
||
| 745 | eqlazer | 56 | |
| 57 | |||
| 58 | #define APP_TYPE 0x1234 |
||
| 59 | #define APP_VERSION 0x0001 |
||
| 731 | eqlazer | 60 | |
| 61 | volatile Can_Message_t rxMsg; |
||
| 62 | |||
| 745 | eqlazer | 63 | //char incoming_text[ BUFFER_SIZE ]; |
| 731 | eqlazer | 64 | uint8_t rxMsgFull=0; |
| 65 | |||
| 745 | eqlazer | 66 | uint8_t mode = NORMAL_MODE; |
| 67 | |||
| 731 | eqlazer | 68 | // Buttons |
| 69 | uint8_t azimuth_plus = 0, azimuth_minus = 0; |
||
| 70 | uint8_t elevation_plus = 0, elevation_minus = 0; |
||
| 71 | uint8_t calibration = 0; |
||
| 745 | eqlazer | 72 | |
| 73 | |||
| 74 | //void send_dimensions(void); |
||
| 75 | //void rotenc(void); |
||
| 731 | eqlazer | 76 | |
| 745 | eqlazer | 77 | //void button(void); |
| 731 | eqlazer | 78 | |
| 745 | eqlazer | 79 | void IO_init( void ); |
| 731 | eqlazer | 80 | |
| 81 | void print_screen( uint8_t type, uint16_t data ); |
||
| 82 | |||
| 83 | void send_message( uint8_t type, uint16_t data ); |
||
| 84 | |||
| 85 | void calibrate( void ); |
||
| 86 | |||
| 87 | // CAN message reception callback |
||
| 88 | // This function runs with interrupts disabled, keep it as short as possible |
||
| 89 | void can_receive(Can_Message_t *msg){ |
||
| 90 | if(!rxMsgFull){ |
||
| 91 | memcpy((void*)&rxMsg, msg, sizeof(rxMsg)); |
||
| 92 | rxMsgFull = 1; |
||
| 93 | } |
||
| 94 | } |
||
| 745 | eqlazer | 95 | |
| 96 | void read_buttons(uint8_t timer) { |
||
| 97 | // Periodicly read buttons |
||
| 98 | // Read buttons |
||
| 99 | calibration = (PIND & (1<<PD2))?0:1; |
||
| 100 | azimuth_plus = (PINB & (1<<PB0))?0:1; |
||
| 101 | azimuth_minus = (PINB & (1<<PB7))?0:1; |
||
| 102 | elevation_plus = (PINC & (1<<PC1))?0:1; |
||
| 103 | elevation_minus = (PINC & (1<<PC0))?0:1; |
||
| 104 | } |
||
| 731 | eqlazer | 105 | |
| 745 | eqlazer | 106 | |
| 731 | eqlazer | 107 | /*----------------------------------------------------------------------------- |
| 108 | * Main Program |
||
| 109 | *---------------------------------------------------------------------------*/ |
||
| 110 | int main( void ) { |
||
| 111 | uint8_t autostop = 0; |
||
| 112 | |||
| 113 | sei(); |
||
| 114 | |||
| 115 | Timer_Init(); |
||
| 116 | |||
| 117 | IO_init(); |
||
| 118 | |||
| 119 | Can_Message_t txMsg; |
||
| 120 | |||
| 121 | txMsg.Id = (CAN_NMT_APP_START << CAN_SHIFT_NMT_TYPE) | (NODE_ID << CAN_SHIFT_NMT_SID); |
||
| 122 | txMsg.ExtendedFlag=1; |
||
| 123 | txMsg.RemoteFlag=0; |
||
| 124 | txMsg.DataLength = 4; |
||
| 125 | |||
| 126 | txMsg.Data.words[0] = APP_TYPE; |
||
| 127 | txMsg.Data.words[1] = APP_VERSION; |
||
| 128 | |||
| 129 | // Send startup message |
||
| 130 | BIOS_CanSend(&txMsg); |
||
| 131 | |||
| 132 | BIOS_CanCallback = &can_receive; |
||
| 745 | eqlazer | 133 | |
| 134 | lcd_init( LCD_DISP_ON ); |
||
| 135 | |||
| 136 | print_screen( SCREEN_NORMAL, 0 ); |
||
| 731 | eqlazer | 137 | |
| 745 | eqlazer | 138 | // Timer for reading buttons |
| 731 | eqlazer | 139 | Timer_SetTimeout(0, 50, TimerTypeFreeRunning, &read_buttons); |
| 140 | Timer_SetTimeout(1, 500, TimerTypeFreeRunning, 0); |
||
| 141 | |||
| 142 | /* main loop */ |
||
| 143 | while(1){ |
||
| 144 | |||
| 145 | /* check if any messages have been received */ |
||
| 146 | if( rxMsgFull ){ |
||
| 147 | |||
| 148 | if( rxMsg.Id == 0x1f8f0100 ){ |
||
| 149 | print_screen( AZIMUTH, rxMsg.Data.words[0] ); |
||
| 150 | }else if( rxMsg.Id == 0x1f8f0200 ){ |
||
| 151 | print_screen( ELEVATION, rxMsg.Data.words[0] ); |
||
| 152 | } |
||
| 153 | |||
| 154 | rxMsgFull = 0; |
||
| 155 | } |
||
| 745 | eqlazer | 156 | |
| 731 | eqlazer | 157 | if (Timer_Expired(1)) { |
| 158 | |||
| 159 | // Perhaps someone pressed a button |
||
| 160 | if( calibration || azimuth_plus || azimuth_minus || elevation_plus || elevation_minus ){ |
||
| 161 | if( calibration ){ |
||
| 745 | eqlazer | 162 | // send all stop |
| 731 | eqlazer | 163 | send_message( AZIMUTH_STOP, 0); |
| 164 | send_message( ELEVATION_STOP, 0); |
||
| 165 | |||
| 166 | // Start calibration |
||
| 167 | calibrate(); |
||
| 168 | |||
| 169 | }else{ |
||
| 170 | if( azimuth_plus ){ |
||
| 745 | eqlazer | 171 | //send rotate aximuth plus |
| 731 | eqlazer | 172 | send_message( AZIMUTH_PLUS, 0 ); |
| 173 | }else if( azimuth_minus ){ |
||
| 745 | eqlazer | 174 | //send rotate azimuth minus |
| 731 | eqlazer | 175 | send_message( AZIMUTH_MINUS, 0 ); |
| 176 | }else{ |
||
| 745 | eqlazer | 177 | // send azimuth stop |
| 731 | eqlazer | 178 | send_message( AZIMUTH_STOP, 0 ); |
| 179 | } |
||
| 180 | |||
| 181 | if( elevation_plus ){ |
||
| 745 | eqlazer | 182 | //send elevate plus |
| 731 | eqlazer | 183 | send_message( ELEVATION_PLUS, 0 ); |
| 184 | }else if( elevation_minus ){ |
||
| 745 | eqlazer | 185 | //send elevate minus |
| 731 | eqlazer | 186 | send_message( ELEVATION_MINUS, 0 ); |
| 187 | }else{ |
||
| 745 | eqlazer | 188 | //send elevation stop |
| 731 | eqlazer | 189 | send_message( ELEVATION_STOP, 0 ); |
| 190 | } |
||
| 191 | |||
| 192 | autostop = 1; // Stop all rotors when no button is pressed |
||
| 193 | } |
||
| 194 | |||
| 195 | }else if ( autostop ){ |
||
| 745 | eqlazer | 196 | // send all stop |
| 731 | eqlazer | 197 | send_message( AZIMUTH_STOP, 0); |
| 198 | send_message( ELEVATION_STOP, 0); |
||
| 199 | |||
| 200 | autostop = 0; |
||
| 201 | } |
||
| 202 | } |
||
| 203 | } |
||
| 204 | } |
||
| 205 | |||
| 206 | void send_message( uint8_t type, uint16_t data ){ |
||
| 207 | Can_Message_t txMsg; |
||
| 208 | |||
| 209 | txMsg.ExtendedFlag=1; |
||
| 210 | txMsg.RemoteFlag=0; |
||
| 211 | |||
| 212 | switch(type){ |
||
| 213 | |||
| 214 | case AZIMUTH_PLUS: |
||
| 215 | txMsg.Id = 0x11100005UL; |
||
| 216 | txMsg.Data.bytes[0] = 0x01; |
||
| 217 | txMsg.DataLength = 1; |
||
| 218 | break; |
||
| 219 | |||
| 220 | case AZIMUTH_MINUS: |
||
| 221 | txMsg.Id = 0x11100005UL; |
||
| 222 | txMsg.Data.bytes[0] = 0x02; |
||
| 223 | txMsg.DataLength = 1; |
||
| 224 | break; |
||
| 225 | |||
| 226 | case AZIMUTH_STOP: |
||
| 227 | txMsg.Id = 0x11100005UL; |
||
| 228 | txMsg.Data.bytes[0] = 0x00; |
||
| 229 | txMsg.DataLength = 1; |
||
| 230 | break; |
||
| 231 | |||
| 232 | case ELEVATION_PLUS: |
||
| 233 | txMsg.Id = 0x11100015UL; |
||
| 234 | txMsg.Data.bytes[0] = 0x01; |
||
| 235 | txMsg.DataLength = 1; |
||
| 236 | break; |
||
| 237 | |||
| 238 | case ELEVATION_MINUS: |
||
| 239 | txMsg.Id = 0x111000015UL; |
||
| 240 | txMsg.Data.bytes[0] = 0x02; |
||
| 241 | txMsg.DataLength = 1; |
||
| 242 | break; |
||
| 243 | |||
| 244 | case ELEVATION_STOP: |
||
| 245 | txMsg.Id = 0x11100015UL; |
||
| 246 | txMsg.Data.bytes[0] = 0x00; |
||
| 247 | txMsg.DataLength = 1; |
||
| 248 | break; |
||
| 249 | |||
| 250 | case GET_CAL: |
||
| 745 | eqlazer | 251 | txMsg.Id = 0x11100002UL; // MSG_CAL_GET |
| 731 | eqlazer | 252 | txMsg.DataLength = 0; |
| 253 | break; |
||
| 254 | |||
| 255 | case SET_CAL: |
||
| 745 | eqlazer | 256 | txMsg.Id = 0x11100001UL; // MSG_CAL_SET |
| 731 | eqlazer | 257 | txMsg.DataLength = 2; |
| 258 | txMsg.Data.words[0] = data; |
||
| 259 | break; |
||
| 260 | |||
| 261 | default: |
||
| 745 | eqlazer | 262 | // Stop rotating |
| 731 | eqlazer | 263 | txMsg.Id = 0x11100005UL; |
| 264 | txMsg.Data.bytes[0] = 0x00; |
||
| 265 | txMsg.DataLength = 1; |
||
| 266 | break; |
||
| 267 | } |
||
| 268 | |||
| 269 | BIOS_CanSend(&txMsg); |
||
| 270 | } |
||
| 271 | |||
| 272 | void print_screen(uint8_t type, uint16_t data){ |
||
| 273 | char buffer[ BUFFER_SIZE ]; |
||
| 274 | |||
| 745 | eqlazer | 275 | if( SCREEN_NORMAL == type){ // rotation |
| 731 | eqlazer | 276 | lcd_clrscr(); |
| 745 | eqlazer | 277 | lcd_puts("Azimuth ---*\n"); |
| 278 | lcd_puts("Elevation ---*\n"); |
||
| 731 | eqlazer | 279 | |
| 745 | eqlazer | 280 | }else if( SCREEN_CAL == type){ // calibration |
| 281 | lcd_clrscr(); |
||
| 282 | lcd_puts("Cal Azimuth ---*\n"); |
||
| 283 | lcd_puts("Cal Elevat. ---*\n"); |
||
| 731 | eqlazer | 284 | |
| 745 | eqlazer | 285 | }else if( AZIMUTH == type ){ // azimuth position |
| 731 | eqlazer | 286 | lcd_gotoxy(12,0); |
| 287 | lcd_puts(" *"); |
||
| 288 | lcd_gotoxy(12,0); |
||
| 289 | |||
| 745 | eqlazer | 290 | /* if( data&0x8000 ){ //Negative position, -360 - 0 |
| 291 | // |
||
| 292 | lcd_gotoxy(0,1); |
||
| 293 | lcd_puts(" "); |
||
| 294 | lcd_gotoxy(0,1); |
||
| 295 | snprintf(buffer, BUFFER_SIZE, "%i", data); |
||
| 296 | lcd_puts(buffer); |
||
| 297 | // |
||
| 298 | lcd_gotoxy(12,0); |
||
| 299 | lcd_puts("-"); |
||
| 300 | data = -data; |
||
| 301 | snprintf(buffer, BUFFER_SIZE-1, "%i", data); |
||
| 302 | lcd_puts(buffer); |
||
| 303 | }else{*/ //Positive position, 0 - 360 |
||
| 304 | snprintf(buffer, BUFFER_SIZE, "%i", data); |
||
| 305 | lcd_puts(buffer); |
||
| 306 | //} |
||
| 731 | eqlazer | 307 | |
| 745 | eqlazer | 308 | }else if( ELEVATION == type ){ // elevation position |
| 731 | eqlazer | 309 | lcd_gotoxy(12,1); |
| 310 | lcd_puts(" *"); |
||
| 311 | lcd_gotoxy(12,1); |
||
| 312 | |||
| 745 | eqlazer | 313 | if( data&0x80 ){ //Negative position, -360 - 0 |
| 314 | lcd_puts("-"); |
||
| 315 | data = -data; |
||
| 316 | snprintf(buffer, BUFFER_SIZE-1, "%i", data); |
||
| 317 | lcd_puts(buffer); |
||
| 318 | }else{ //Positive position, 0 - 360 |
||
| 319 | snprintf(buffer, BUFFER_SIZE, "%i", data); |
||
| 320 | lcd_puts(buffer); |
||
| 321 | } |
||
| 731 | eqlazer | 322 | } |
| 323 | } |
||
| 324 | |||
| 325 | void IO_init( void ) |
||
| 326 | { |
||
| 745 | eqlazer | 327 | /* |
| 328 | * Enable buttons and display light |
||
| 329 | */ |
||
| 330 | |||
| 731 | eqlazer | 331 | // Set as inputs |
| 745 | eqlazer | 332 | DDRD &= ~( 1<<DDD2 ); // Calibration |
| 333 | DDRB &= ~(( 1<<DDB0 )|( 1<<DDB7 )); // Azimuth |
||
| 334 | DDRC &= ~(( 1<<DDC0 )|( 1<<DDC1 )); // Elevation |
||
| 731 | eqlazer | 335 | |
| 336 | // Enable pull up |
||
| 337 | PORTD |= ( 1<<PD2 ); |
||
| 338 | PORTB |= ( 1<<PB0 )|( 1<<PB7 ); |
||
| 339 | PORTC |= ( 1<<PC0 )|( 1<<PC1 ); |
||
| 340 | |||
| 341 | // Contrast |
||
| 342 | TCCR0A |= (1<<COM0B1)|(1<<WGM01)|(1<<WGM00); |
||
| 343 | TCCR0B |= (1<<CS00); |
||
| 344 | OCR0B = 0x02; |
||
| 345 | DDRD |= (1<<DDD5); |
||
| 346 | |||
| 347 | // Backlight |
||
| 348 | TCCR1A |= (1<<COM1A1)|(1<<WGM11); |
||
| 349 | TCCR1B |= (1<<WGM13)|(1<<WGM12)|(1<<CS10); |
||
| 350 | ICR1 = 0xFF; // Make it 8 bits |
||
| 351 | OCR1A = 0xC0; |
||
| 352 | DDRB |= (1<<DDB1); |
||
| 353 | } |
||
| 354 | |||
| 355 | |||
| 356 | void calibrate( void ){ |
||
| 357 | int16_t calib_value_az = 0, calib_value_elv = 0; |
||
| 358 | |||
| 745 | eqlazer | 359 | // flags |
| 731 | eqlazer | 360 | uint8_t received_cal = 0, calibration_mode = 0; |
| 361 | |||
| 362 | print_screen( SCREEN_CAL, 0 ); |
||
| 363 | |||
| 364 | send_message( GET_CAL, 0 ); |
||
| 365 | |||
| 366 | while ( 1 ) { |
||
| 367 | |||
| 745 | eqlazer | 368 | /* check if any messages have been received */ |
| 731 | eqlazer | 369 | if( rxMsgFull ){ |
| 745 | eqlazer | 370 | if( rxMsg.Id == 0x111000f2 && rxMsg.DataLength == 2 ){ // MSG_CAL_RET |
| 731 | eqlazer | 371 | calib_value_az = rxMsg.Data.words[0]; |
| 372 | |||
| 373 | received_cal = 1; |
||
| 374 | print_screen( AZIMUTH, calib_value_az ); |
||
| 745 | eqlazer | 375 | } |
| 731 | eqlazer | 376 | |
| 377 | rxMsgFull = 0; |
||
| 378 | } |
||
| 379 | |||
| 380 | if ( Timer_Expired(1) && received_cal ) { |
||
| 745 | eqlazer | 381 | if ( !calibration ){// wait for released button |
| 731 | eqlazer | 382 | calibration_mode = 1; |
| 383 | |||
| 384 | if(azimuth_plus){ |
||
| 385 | calib_value_az++; |
||
| 386 | print_screen( AZIMUTH, calib_value_az ); |
||
| 387 | |||
| 388 | }else if(azimuth_minus){ |
||
| 389 | calib_value_az--; |
||
| 390 | print_screen( AZIMUTH, calib_value_az ); |
||
| 391 | } |
||
| 745 | eqlazer | 392 | |
| 731 | eqlazer | 393 | if(elevation_plus){ |
| 394 | calib_value_elv++; |
||
| 395 | |||
| 396 | }else if(elevation_minus){ |
||
| 397 | calib_value_elv--; |
||
| 398 | } |
||
| 399 | |||
| 400 | }else if( calibration && calibration_mode ){ |
||
| 745 | eqlazer | 401 | // Send calibration value to antenna node |
| 731 | eqlazer | 402 | send_message( SET_CAL, calib_value_az ); |
| 745 | eqlazer | 403 | // return to normal state |
| 731 | eqlazer | 404 | print_screen( SCREEN_NORMAL, 0 ); |
| 405 | |||
| 406 | return; |
||
| 407 | } |
||
| 408 | } |
||
| 409 | } |
||
| 410 | } |