Subversion Repositories HomeAutomation

Rev

Rev 627 | Details | Compare with Previous | Last modification | View Log | SVN | RSS feed

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