Subversion Repositories HomeAutomation

Rev

Rev 607 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 607 Rev 627
1
/**
1
/**
2
 * CanSimpleCLCD. Simple version.
2
 * CanSimpleCLCD. Simple version.
3
 * For HD44780- and KS0073-based LCD displays
3
 * For HD44780- and KS0073-based LCD displays
4
 *
4
 *
5
 * Contains no intelligence. It just prints what it is told to.
5
 * Contains no intelligence. It just prints what it is told to.
6
 *
6
 *
7
 * @date    2006-12-11
7
 * @date    2006-12-11
8
 * @author  Erik Larsson
8
 * @author  Erik Larsson
-
 
9
 * @author  Martin Norden
9
 *
10
 *
10
 */
11
 */
11
 
12
 
12
/*-----------------------------------------------------------------------------
13
/*-----------------------------------------------------------------------------
13
 * Includes
14
 * Includes
14
 *---------------------------------------------------------------------------*/
15
 *---------------------------------------------------------------------------*/
15
/* system files */
16
/* system files */
16
#include <avr/io.h>
17
#include <avr/io.h>
17
#include <inttypes.h>
18
#include <inttypes.h>
18
#include <avr/interrupt.h>
19
#include <avr/interrupt.h>
19
#include <stdio.h>
20
#include <stdio.h>
20
/* lib files */
21
/* lib files */
21
#include <bios.h>
22
#include <bios.h>
22
#include <config.h>
23
#include <config.h>
23
#include <drivers/lcd/clcd/lcd_HD44780.h>
24
#include <drivers/lcd/clcd/lcd_HD44780.h>
24
 
25
 
25
#include <string.h> //for memcpy
26
#include <string.h> //for memcpy
26
 
27
 
27
 
28
 
28
/* funcdefs */
29
/* funcdefs */
29
//#include <funcdefs/funcdefs.h>
30
//#include <funcdefs/funcdefs.h>
30
 
31
 
31
 
32
 
32
//a lot of crap from previous funcdefs
33
//a lot of crap from previous funcdefs
33
/* ACT LCD 12 bits <ACTION><SIZE> 0xFFFL
34
/* ACT LCD 12 bits <ACTION><SIZE> 0xFFFL
34
 *
35
 *
35
 * <ACTION>, 4 bits = Type och action.
36
 * <ACTION>, 4 bits = Type och action.
36
 * <SIZE>, 8 bits = Size of display.
37
 * <SIZE>, 8 bits = Size of display.
37
 */
38
 */
38
#define LCD_ACTION_MASK 0xF00L /* bit[12..8] */
39
#define LCD_ACTION_MASK 0xF00L /* bit[12..8] */
39
#define LCD_SIZE_MASK 0x0FFL /* bit[7..0] */
40
#define LCD_SIZE_MASK 0x0FFL /* bit[7..0] */
40
 
41
 
41
#define LCD_ACTION_BITS 8
42
#define LCD_ACTION_BITS 8
42
#define LCD_SIZE_BITS 0
43
#define LCD_SIZE_BITS 0
43
 
44
 
44
 
45
 
45
/* <ACTION> 4 bits 0xFL */
46
/* <ACTION> 4 bits 0xFL */
46
 
47
 
47
#define LCD_ACTION_CLR          0x0L
48
#define LCD_ACTION_CLR          0x0L
48
#define LCD_ACTION_CURS         0x1L
49
#define LCD_ACTION_CURS         0x1L
49
#define LCD_ACTION_TEXT         0x2L
50
#define LCD_ACTION_TEXT         0x2L
50
#define LCD_ACTION_GET_SIZE     0x3L
51
#define LCD_ACTION_GET_SIZE     0x3L
51
#define LCD_ACTION_SET_CONT     0x4L
52
#define LCD_ACTION_SET_CONT     0x4L
52
#define LCD_ACTION_SET_BLIGHT   0x5L
53
#define LCD_ACTION_SET_BLIGHT   0x5L
53
#define LCD_ACTION_GET_CONT     0x6L
54
#define LCD_ACTION_GET_CONT     0x6L
54
#define LCD_ACTION_GET_BLIGHT   0x7L
55
#define LCD_ACTION_GET_BLIGHT   0x7L
55
 
56
 
56
#define LCD_ACTION_SEND_CONT    0x8L
57
#define LCD_ACTION_SEND_CONT    0x8L
57
#define LCD_ACTION_SEND_BLIGHT  0x9L
58
#define LCD_ACTION_SEND_BLIGHT  0x9L
58
 
59
 
59
 
60
 
60
 
61
 
61
/* <SIZE> 8 bits 0xFFL */
62
/* <SIZE> 8 bits 0xFFL */
62
#define LCD_SIZE_ALL    0x00L
63
#define LCD_SIZE_ALL    0x00L
63
#define LCD_SIZE_16x2   0x02L
64
#define LCD_SIZE_16x2   0x02L
64
#define LCD_SIZE_20x4   0x10L
65
#define LCD_SIZE_20x4   0x10L
65
 
66
 
66
 
67
 
67
 
68
 
68
/*-----------------------------------------------------------------------------
69
/*-----------------------------------------------------------------------------
69
 * Defines
70
 * Defines
70
 *---------------------------------------------------------------------------*/
71
 *---------------------------------------------------------------------------*/
71
#define SIZE_X  20
72
#define SIZE_X  20
72
#define SIZE_Y  4
73
#define SIZE_Y  4
73
#define SIZE_LCD LCD_SIZE_20x4
74
#define SIZE_LCD LCD_SIZE_20x4
74
 
75
 
75
#define BUFFER_SIZE SIZE_X
76
#define BUFFER_SIZE SIZE_X
76
#define TRUE 1
77
#define TRUE 1
77
#define FALSE 0
78
#define FALSE 0
78
 
79
 
79
#define LEFT    0x01
80
#define LEFT    0x01
80
#define RIGHT   0x02
81
#define RIGHT   0x02
81
 
82
 
82
volatile Can_Message_t rxMsg;
83
volatile Can_Message_t rxMsg;
83
 
84
 
84
char incoming_text[ BUFFER_SIZE ];
85
char incoming_text[ BUFFER_SIZE ];
85
uint8_t rxMsgFull;
86
uint8_t rxMsgFull;
86
 
87
 
87
 
88
 
88
char buffer[ BUFFER_SIZE ];
89
char buffer[ BUFFER_SIZE ];
89
 
90
 
90
void send_dimensions(void);
91
void send_dimensions(void);
91
void rotenc(void);
92
void rotenc(void);
92
 
93
 
93
// CAN message reception callback
94
// CAN message reception callback
94
// This function runs with interrupts disabled, keep it as short as possible
95
// This function runs with interrupts disabled, keep it as short as possible
95
void can_receive(Can_Message_t *msg){
96
void can_receive(Can_Message_t *msg){
96
    if(!rxMsgFull){
97
    if(!rxMsgFull){
97
        memcpy((void*)&rxMsg, msg, sizeof(rxMsg));
98
        memcpy((void*)&rxMsg, msg, sizeof(rxMsg));
98
        rxMsgFull = 1;
99
        rxMsgFull = 1;
99
    }
100
    }
100
}
101
}
101
 
102
 
102
ISR( PCINT2_vect ){
103
ISR( PCINT2_vect ){
103
// For ROTENC_A and ROTENC_B FIXME är inte riktigt rätt
104
// For ROTENC_A and ROTENC_B FIXME Šr inte riktigt rŠtt. Verkar vara bra tycker jag?
104
    rotenc();
105
    rotenc();
105
}
106
}
106
 
107
 
107
ISR( PCINT0_vect ){
108
ISR( PCINT0_vect ){
108
// For ROTENC_BTN
109
// For ROTENC_BTN
109
rotenc();
110
    rotenc();
110
}
111
}
111
 
112
 
112
/*-----------------------------------------------------------------------------
113
/*-----------------------------------------------------------------------------
113
 * Main Program
114
 * Main Program
114
 *---------------------------------------------------------------------------*/
115
 *---------------------------------------------------------------------------*/
115
int main(void) {
116
int main(void) {
116
//  uint32_t act; not used anymoer
117
//  uint32_t act; not used anymoer
117
//  uint8_t act_type, lcd_size; not used anymore
118
//  uint8_t act_type, lcd_size; not used anymore
118
    uint8_t m, lcd_action;
119
    uint8_t m, lcd_action;
119
 
120
 
120
    sei();
121
    sei();
121
 
122
 
122
    /*
123
    /*
123
     * Initialize rotaryencoders and buttons
124
     * Initialize rotaryencoders and buttons
124
     */
125
     */
125
    // Set as input
126
    // Set as input
126
    DDRD &= ~(1<<DDD2);
127
    DDRD &= ~(1<<DDD2);
127
    DDRB &= ~((1<<DDB7)|(1<<DDB0));
128
    DDRB &= ~((1<<DDB7)|(1<<DDB0));
128
    // Enable pull-up
129
    // Enable pull-up
129
    PORTD |= (1<<PD2);
130
    PORTD |= (1<<PD2);
130
    PORTB |= (1<<PB7)|(1<<PB0);
131
    PORTB |= (1<<PB7)|(1<<PB0);
131
    // Enable IO-pin interrupt
132
    // Enable IO-pin interrupt
132
    PCICR |= (1<<PCIE2)|(1<<PCIE0);
133
    PCICR |= (1<<PCIE2)|(1<<PCIE0);
133
    // Unmask PB7, PB0 and PD2
134
    // Unmask PB7, PB0 and PD2
134
    PCMSK2 |= (1<<PCINT18);
135
    PCMSK2 |= (1<<PCINT18);
135
    PCMSK0 |= (1<<PCINT7)|(1<<PCINT0);
136
    PCMSK0 |= (1<<PCINT7)|(1<<PCINT0);
136
 
137
 
137
    // Contrast
138
    // Contrast
138
    TCCR0A |= (1<<COM0B1)|(1<<WGM01)|(1<<WGM00);
139
    TCCR0A |= (1<<COM0B1)|(1<<WGM01)|(1<<WGM00);
139
    TCCR0B |= (1<<CS00);
140
    TCCR0B |= (1<<CS00);
140
    OCR0B = 0x10;
141
    OCR0B = 0x10;
141
    DDRD |= (1<<DDD5);
142
    DDRD |= (1<<DDD5);
142
 
143
 
143
    // Backlight
144
    // Backlight
144
    TCCR1A |= (1<<COM1A1)|(1<<WGM11);
145
    TCCR1A |= (1<<COM1A1)|(1<<WGM11);
145
    TCCR1B |= (1<<WGM13)|(1<<WGM12)|(1<<CS10);
146
    TCCR1B |= (1<<WGM13)|(1<<WGM12)|(1<<CS10);
146
    ICR1 = 0xFF; // Make it 8 bits
147
    ICR1 = 0xFF; // Make it 8 bits
147
    OCR1A = 0xFF;
148
    OCR1A = 0xFF;
148
    DDRB |= (1<<DDB1);
149
    DDRB |= (1<<DDB1);
149
 
150
 
150
 
151
 
151
    Can_Message_t txMsg;
152
    Can_Message_t txMsg;
152
    txMsg.ExtendedFlag=1;
153
    txMsg.ExtendedFlag=1;
153
    txMsg.RemoteFlag=0;
154
    txMsg.RemoteFlag=0;
154
// FIXME skicka app startad
155
// FIXME skicka app startad
155
    BIOS_CanCallback = &can_receive;
156
    BIOS_CanCallback = &can_receive;
156
 
157
 
157
    lcd_init( LCD_DISP_ON );
158
    lcd_init( LCD_DISP_ON );
158
    lcd_clrscr();
159
    lcd_clrscr();
159
    lcd_puts("HomeAutomation\n");
160
    lcd_puts("HomeAutomation\n");
160
 
161
 
161
    send_dimensions();
162
    send_dimensions();
162
    lcd_puts("Very nice!\n");
163
    lcd_puts("CAN Connected!\n");
163
 
164
 
164
    /* main loop */
165
    /* main loop */
165
    while(1){
166
    while(1){
166
        /* check if any messages have been received */
167
        /* check if any messages have been received */
167
        if(rxMsgFull){
168
        if(rxMsgFull){
168
            uint16_t act_type;
169
            uint16_t act_type;
169
            uint8_t lcdid;
170
            uint8_t lcdid;
170
            if ( ((rxMsg.Id & CAN_MASK_CLASS)>>CAN_SHIFT_CLASS) == CAN_ACT){// FIXME ett jäkla herk, städa upp
171
            if ( ((rxMsg.Id & CAN_MASK_CLASS)>>CAN_SHIFT_CLASS) == CAN_ACT){// FIXME ett jŠkla herk, stŠda upp
171
               
172
               
172
               
173
               
173
                act_type =(uint16_t)((rxMsg.Id & CAN_MASK_ACT_TYPE) >> CAN_SHIFT_ACT_TYPE);
174
                act_type =(uint16_t)((rxMsg.Id & CAN_MASK_ACT_TYPE) >> CAN_SHIFT_ACT_TYPE);
174
           
175
           
175
                lcdid = (uint8_t)((rxMsg.Id & CAN_MASK_ACT_ID) >> CAN_SHIFT_ACT_ID);
176
                lcdid = (uint8_t)((rxMsg.Id & CAN_MASK_ACT_ID) >> CAN_SHIFT_ACT_ID);
176
               
177
               
177
 
178
 
178
                if( act_type == ACT_TYPE_LCD ){ //FIXME add id to check here
179
                if( act_type == ACT_TYPE_LCD ){ //FIXME add id to check here
179
                    lcd_action =  rxMsg.Data.bytes[0];
180
                    lcd_action =  rxMsg.Data.bytes[0];
180
                    switch( lcd_action ){
181
                    switch( lcd_action ){
181
                    case LCD_ACTION_CLR:
182
                    case LCD_ACTION_CLR:
182
                        // Clear LCD
183
                        // Clear LCD
183
                        lcd_clrscr();
184
                        lcd_clrscr();
184
                    break;
185
                    break;
185
                    case LCD_ACTION_CURS:
186
                    case LCD_ACTION_CURS:
186
                        // Move cursor
187
                        // Move cursor
187
                        lcd_gotoxy( rxMsg.Data.bytes[1],rxMsg.Data.bytes[2] );
188
                        lcd_gotoxy( rxMsg.Data.bytes[1],rxMsg.Data.bytes[2] );
188
                    break;
189
                    break;
189
                    case LCD_ACTION_GET_SIZE:
190
                    case LCD_ACTION_GET_SIZE:
190
                        // Request LCD dimension
191
                        // Request LCD dimension
191
                        send_dimensions();
192
                        send_dimensions();
192
                    break;
193
                    break;
193
                    case LCD_ACTION_TEXT:
194
                    case LCD_ACTION_TEXT:
194
                        // Print text to LCD
195
                        // Print text to LCD
195
                        for(m=1;m<rxMsg.DataLength;m++){
196
                        for(m=1;m<rxMsg.DataLength;m++){
196
                            lcd_putc( (char)rxMsg.Data.bytes[m] );
197
                            lcd_putc( (char)rxMsg.Data.bytes[m] );
197
                        }
198
                        }
198
                    break;
199
                    break;
199
                    case LCD_ACTION_SET_CONT:
200
                    case LCD_ACTION_SET_CONT:
200
                        // Set contrast
201
                        // Set contrast
201
                        if(rxMsg.DataLength == 1){
202
                        if(rxMsg.DataLength == 1){
202
                            OCR0B = rxMsg.Data.bytes[1];
203
                            OCR0B = rxMsg.Data.bytes[1];
203
                        }
204
                        }
204
                    break;
205
                    break;
205
                    case LCD_ACTION_SET_BLIGHT:
206
                    case LCD_ACTION_SET_BLIGHT:
206
                        // Set backlight
207
                        // Set backlight
207
                        if(rxMsg.DataLength == 2){
208
                        if(rxMsg.DataLength == 2){
208
                            OCR1AL = rxMsg.Data.bytes[1];
209
                            OCR1AL = rxMsg.Data.bytes[1];
209
                        }
210
                        }
210
                    break;
211
                    break;
211
                    case LCD_ACTION_GET_CONT:
212
                    case LCD_ACTION_GET_CONT:
212
                        // Get contrast
213
                        // Get contrast
213
                        txMsg.DataLength = 1;
214
                        txMsg.DataLength = 1;
214
                        //txMsg.Id = ( CLASS_ACT<<CLASS_MASK_BITS )|( ACT_TYPE_LCD<<ACT_TYPE_BITS )|( LCD_ACTION_SEND_CONT<<LCD_ACTION_BITS )|NODE_ID; FIXME
215
                        //txMsg.Id = ( CLASS_ACT<<CLASS_MASK_BITS )|( ACT_TYPE_LCD<<ACT_TYPE_BITS )|( LCD_ACTION_SEND_CONT<<LCD_ACTION_BITS )|NODE_ID; FIXME
215
                        txMsg.Data.bytes[1] = OCR0B;
216
                        txMsg.Data.bytes[1] = OCR0B;
216
                        BIOS_CanSend(&txMsg);
217
                        BIOS_CanSend(&txMsg);
217
                    break;
218
                    break;
218
                    case LCD_ACTION_GET_BLIGHT:
219
                    case LCD_ACTION_GET_BLIGHT:
219
                        // Get backlight
220
                        // Get backlight
220
                        txMsg.DataLength = 1;
221
                        txMsg.DataLength = 1;
221
                        //txMsg.Id = ( CLASS_ACT<<CLASS_MASK_BITS )|( ACT_TYPE_LCD<<ACT_TYPE_BITS )|( LCD_ACTION_SEND_BLIGHT<<LCD_ACTION_BITS )|NODE_ID; FIXME
222
                        //txMsg.Id = ( CLASS_ACT<<CLASS_MASK_BITS )|( ACT_TYPE_LCD<<ACT_TYPE_BITS )|( LCD_ACTION_SEND_BLIGHT<<LCD_ACTION_BITS )|NODE_ID; FIXME
222
                        txMsg.Data.bytes[1] = OCR1AL;
223
                        txMsg.Data.bytes[1] = OCR1AL;
223
                        BIOS_CanSend(&txMsg);
224
                        BIOS_CanSend(&txMsg);
224
                    break;
225
                    break;
225
                    default:
226
                    default:
226
                    // Take over the world
227
                    // Take over the world
227
                    break;
228
                    break;
228
                    }
229
                    }
229
                }
230
                }
230
            }
231
            }
231
            rxMsgFull = 0;
232
            rxMsgFull = 0;
232
        }
233
        }
233
    }
234
    }
234
}
235
}
235
 
236
 
236
void send_dimensions(){
237
void send_dimensions(){
237
    Can_Message_t txMsg;
238
    Can_Message_t txMsg;
238
 
239
 
239
    txMsg.ExtendedFlag=1;
240
    txMsg.ExtendedFlag=1;
240
    txMsg.RemoteFlag=0;
241
    txMsg.RemoteFlag=0;
241
    txMsg.Id=0xA000001;
242
    txMsg.Id=0xA000001;
242
    txMsg.Data.bytes[0] = SIZE_X;
243
    txMsg.Data.bytes[0] = SIZE_X;
243
    txMsg.Data.bytes[1] = SIZE_Y;
244
    txMsg.Data.bytes[1] = SIZE_Y;
244
    txMsg.DataLength = 2;
245
    txMsg.DataLength = 2;
245
 
246
 
246
    BIOS_CanSend(&txMsg);
247
    BIOS_CanSend(&txMsg);
247
}
248
}
248
 
249
 
249
void rotenc(){
250
void rotenc(){
250
    uint8_t rot_data = 0;
251
    uint8_t rot_data = 0;
251
    static uint8_t rot_lastdir = 0, rot_laststate = 0; // FIXME måste flyttas ut igen?
252
    static uint8_t rot_lastdir = 0, rot_laststate = 0, btn_laststate = 0;
252
 
253
 
253
    Can_Message_t txMsg;
254
    Can_Message_t txMsg;
254
    txMsg.ExtendedFlag=1;
255
    txMsg.ExtendedFlag=1;
255
    txMsg.RemoteFlag=0;
256
    txMsg.RemoteFlag=0;
256
    //txMsg.Id = ( CLASS_SNS<<CLASS_MASK_BITS )|( SNS_ACT_BUTTON<<SNS_TYPE_BITS )|( 0x01<<SNS_ID_BITS )| NODE_ID;//FIXME: borttaget
257
    //txMsg.Id = ( CLASS_SNS<<CLASS_MASK_BITS )|( SNS_ACT_BUTTON<<SNS_TYPE_BITS )|( 0x01<<SNS_ID_BITS )| NODE_ID;//FIXME: borttaget
257
    txMsg.DataLength=2;
258
    txMsg.DataLength=2;
258
 
259
 
-
 
260
    //Take care of button push
-
 
261
    if ((PINB&(1<<PB7)) != btn_laststate){ //The buttonstate has changed! Let's send a message!
-
 
262
        btn_laststate = (PINB&(1<<PB7));
-
 
263
        txMsg.Data.bytes[0] = 5;
-
 
264
        txMsg.Data.bytes[1] = (btn_laststate)?0:1;
-
 
265
        txMsg.DataLength=2;
-
 
266
        BIOS_CanSend(&txMsg);
-
 
267
    }
-
 
268
   
-
 
269
    //Take care of rotary encoder movement
259
    if(PINB&(1<<PB0)){
270
    if(PINB&(1<<PB0)){
260
        rot_data |= 0x01;
271
        rot_data |= 0x01;
261
    }
272
    }
262
    if(PIND&(1<<PD2)){
273
    if(PIND&(1<<PD2)){
263
        rot_data |= 0x02;
274
        rot_data |= 0x02;
264
    }
275
    }
265
 
276
 
266
    if( rot_data==0 || rot_data==3 ){
277
    if( rot_data==0 || rot_data==3 ){ // Are both signals high or low?
267
        if( rot_data==0 && rot_laststate!=rot_data ){
278
        if( rot_data==0 && rot_laststate!=rot_data ){ // Are both signals low? In that case we are finished with one turn and should print out the direction it went. 
268
            if( rot_lastdir&0x01 ){
279
            if( rot_lastdir&0x01 ){
269
                // Moving right
280
                // Moving right
270
                txMsg.Data.bytes[0]=RIGHT;
281
                txMsg.Data.bytes[0]=RIGHT;
271
                txMsg.Data.bytes[1] = (PINB&(1<<PB7))?0:1;
282
                txMsg.Data.bytes[1] = (PINB&(1<<PB7))?0:1;
272
                txMsg.DataLength=2;
283
                txMsg.DataLength=2;
273
                BIOS_CanSend(&txMsg);
284
                BIOS_CanSend(&txMsg);
274
                // For testing TODO remove
-
 
275
                if(OCR1A<0xFF){
-
 
276
                    OCR1A++;
-
 
277
                }
-
 
278
                if(OCR0B>0){
-
 
279
                    OCR0B--;
-
 
280
                }
-
 
281
            }else{
285
            }else{
282
                // Moving left
286
                // Moving left
283
                txMsg.Data.bytes[0]=LEFT;
287
                txMsg.Data.bytes[0]=LEFT;
284
                txMsg.Data.bytes[1] = (PINB&(1<<PB7))?0:1;
288
                txMsg.Data.bytes[1] = (PINB&(1<<PB7))?0:1;
285
                txMsg.DataLength=2;
289
                txMsg.DataLength=2;
286
                BIOS_CanSend(&txMsg);
290
                BIOS_CanSend(&txMsg);
287
                // For testing TODO remove
-
 
288
                if(OCR1A>0){
-
 
289
                    OCR1A--;
-
 
290
                }
-
 
291
                if(OCR0B<0xFF){
-
 
292
                    OCR0B++;
-
 
293
                }
-
 
294
            }
291
            }
295
        }
292
        }
296
        rot_laststate = rot_data;
293
        rot_laststate = rot_data;
297
    }else{
-
 
-
 
294
    } else { // No, only one of the signals are high. We can use this to find out what direction we are moving.
298
        rot_lastdir = rot_data;
295
        rot_lastdir = rot_data;
299
    }
296
    }
300
}
297
}
301
 
298
 
302
 
299