Subversion Repositories HomeAutomation

Rev

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
}