Subversion Repositories HomeAutomation

Rev

Rev 463 | Rev 563 | Go to most recent revision | 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
9
 *
10
 */
11
 
12
/*-----------------------------------------------------------------------------
13
 * Includes
14
 *---------------------------------------------------------------------------*/
15
/* system files */
16
#include <avr/io.h>
481 eqlazer 17
#include <inttypes.h>
179 eqlazer 18
#include <avr/interrupt.h>
19
#include <stdio.h>
20
/* lib files */
332 eqlazer 21
#include <bios.h>
481 eqlazer 22
#include <config.h>
179 eqlazer 23
#include <lcd_HD44780.h>
196 eqlazer 24
/* funcdefs */
481 eqlazer 25
#include <funcdefs/funcdefs.h>
179 eqlazer 26
 
349 eqlazer 27
/*-----------------------------------------------------------------------------
28
 * Defines
29
 *---------------------------------------------------------------------------*/
344 eqlazer 30
#define SIZE_X	20
31
#define SIZE_Y	4
348 eqlazer 32
#define SIZE_LCD LCD_SIZE_20x4
344 eqlazer 33
 
348 eqlazer 34
#define BUFFER_SIZE SIZE_X
332 eqlazer 35
#define TRUE 1
36
#define FALSE 0
179 eqlazer 37
 
344 eqlazer 38
#define LEFT	0x01
39
#define RIGHT	0x02
40
 
481 eqlazer 41
volatile Can_Message_t rxMsg;
256 eqlazer 42
 
348 eqlazer 43
char incoming_text[ BUFFER_SIZE ];
481 eqlazer 44
uint8_t rxMsgFull;
335 eqlazer 45
 
46
 
349 eqlazer 47
char buffer[ BUFFER_SIZE ];
344 eqlazer 48
 
348 eqlazer 49
void send_dimensions();
481 eqlazer 50
void rotenc();
348 eqlazer 51
 
481 eqlazer 52
// CAN message reception callback
53
// This function runs with interrupts disabled, keep it as short as possible
344 eqlazer 54
void can_receive(Can_Message_t *msg){
481 eqlazer 55
	if(!rxMsgFull){
56
		memcpy((void*)&rxMsg, msg, sizeof(rxMsg));
57
		rxMsgFull = 1;
348 eqlazer 58
	}
344 eqlazer 59
}
60
 
481 eqlazer 61
ISR( PCINT2_vect ){
62
// For ROTENC_A and ROTENC_B FIXME är inte riktigt rätt
463 eqlazer 63
	rotenc();
64
}
65
 
481 eqlazer 66
ISR( PCINT0_vect ){
67
// For ROTENC_BTN
68
rotenc();
463 eqlazer 69
}
70
 
179 eqlazer 71
/*-----------------------------------------------------------------------------
72
 * Main Program
73
 *---------------------------------------------------------------------------*/
74
int main(void) {
481 eqlazer 75
	uint32_t act;
76
	uint8_t m, act_type, lcd_action, lcd_size;
179 eqlazer 77
 
481 eqlazer 78
	sei();
79
 
335 eqlazer 80
	/*
81
	 * Initialize rotaryencoders and buttons
82
	 */
481 eqlazer 83
	// Set as input
344 eqlazer 84
	DDRD &= ~(1<<DDD2);
85
	DDRB &= ~((1<<DDB7)|(1<<DDB0));
481 eqlazer 86
	// Enable pull-up
344 eqlazer 87
	PORTD |= (1<<PD2);
88
	PORTB |= (1<<PB7)|(1<<PB0);
481 eqlazer 89
	// Enable IO-pin interrupt
344 eqlazer 90
	PCICR |= (1<<PCIE2)|(1<<PCIE0);
481 eqlazer 91
	// Unmask PB7, PB0 and PD2
344 eqlazer 92
	PCMSK2 |= (1<<PCINT18);
93
	PCMSK0 |= (1<<PCINT7)|(1<<PCINT0);
179 eqlazer 94
 
481 eqlazer 95
	// Contrast
348 eqlazer 96
	TCCR0A |= (1<<COM0B1)|(1<<WGM01)|(1<<WGM00);
97
	TCCR0B |= (1<<CS00);
481 eqlazer 98
	OCR0B = 0x10;
348 eqlazer 99
	DDRD |= (1<<DDD5);
100
 
481 eqlazer 101
	// Backlight
348 eqlazer 102
	TCCR1A |= (1<<COM1A1)|(1<<WGM11);
103
	TCCR1B |= (1<<WGM13)|(1<<WGM12)|(1<<CS10);
104
	ICR1 = 0xFF; // Make it 8 bits
481 eqlazer 105
	OCR1A = 0x80;
348 eqlazer 106
	DDRB |= (1<<DDB1);
107
 
463 eqlazer 108
	Can_Message_t txMsg;
344 eqlazer 109
	txMsg.ExtendedFlag=1;
110
	txMsg.RemoteFlag=0;
481 eqlazer 111
// FIXME skicka app startad
463 eqlazer 112
	BIOS_CanCallback = &can_receive;
256 eqlazer 113
 
332 eqlazer 114
	lcd_init( LCD_DISP_ON );
115
	lcd_clrscr();
348 eqlazer 116
	lcd_puts("HomeAutomation\n");
179 eqlazer 117
 
344 eqlazer 118
	send_dimensions();
348 eqlazer 119
	lcd_puts("Very nice!\n");
179 eqlazer 120
 
121
    /* main loop */
332 eqlazer 122
	while(1){
123
        /* check if any messages have been received */
481 eqlazer 124
		if(rxMsgFull){
344 eqlazer 125
 
481 eqlazer 126
			if( ((rxMsg.Id & CLASS_MASK)>> CLASS_MASK_BITS) == CLASS_ACT ){ // FIXME ett jäkla herk, städa upp
127
				act = (rxMsg.Id & TYPE_MASK) >> TYPE_MASK_BITS;
128
				act_type = (act & ACT_TYPE_MASK) >> ACT_TYPE_BITS;
129
				lcd_action = (act & LCD_ACTION_MASK) >> LCD_ACTION_BITS;
130
				lcd_size = (act & LCD_SIZE_MASK) >> LCD_SIZE_BITS;
131
 
132
				if( act_type == ACT_TYPE_LCD && (lcd_size == SIZE_LCD || lcd_size == LCD_SIZE_ALL)){
133
					switch( lcd_action ){
134
					case LCD_ACTION_CLR:
135
						// Clear LCD
136
						lcd_clrscr();
137
					break;
138
					case LCD_ACTION_CURS:
139
						// Move cursor
140
						lcd_gotoxy( rxMsg.Data.bytes[0],rxMsg.Data.bytes[1] );
141
					break;
142
					case LCD_ACTION_GET_SIZE:
143
						// Request LCD dimension
144
						send_dimensions();
145
					break;
146
					case LCD_ACTION_TEXT:
147
						// Print text to LCD
148
						for(m=0;m<rxMsg.DataLength;m++){
149
							lcd_putc( (char)rxMsg.Data.bytes[m] );
150
						}
151
					break;
152
					case LCD_ACTION_SET_CONT:
153
						// Set contrast
154
						if(rxMsg.DataLength == 1){
155
							OCR0B = rxMsg.Data.bytes[0];
156
						}
157
					break;
158
					case LCD_ACTION_SET_BLIGHT:
159
						// Set backlight
160
						if(rxMsg.DataLength == 1){
161
							OCR1AL = rxMsg.Data.bytes[0];
162
						}
163
					break;
164
					case LCD_ACTION_GET_CONT:
165
						// Get contrast
166
						txMsg.DataLength = 1;
167
						txMsg.Id = ( CLASS_ACT<<CLASS_MASK_BITS )|( ACT_TYPE_LCD<<ACT_TYPE_BITS )|( LCD_ACTION_SEND_CONT<<LCD_ACTION_BITS )|NODE_ID;
168
						txMsg.Data.bytes[0] = OCR0B;
169
						BIOS_CanSend(&txMsg);
170
					break;
171
					case LCD_ACTION_GET_BLIGHT:
172
						// Get backlight
173
						txMsg.DataLength = 1;
174
						txMsg.Id = ( CLASS_ACT<<CLASS_MASK_BITS )|( ACT_TYPE_LCD<<ACT_TYPE_BITS )|( LCD_ACTION_SEND_BLIGHT<<LCD_ACTION_BITS )|NODE_ID;
175
						txMsg.Data.bytes[0] = OCR1AL;
176
						BIOS_CanSend(&txMsg);
177
					break;
178
					default:
179
					// Take over the world
180
					break;
181
					}
182
				}
183
			}
184
			rxMsgFull = 0;
334 eqlazer 185
		}
332 eqlazer 186
	}
179 eqlazer 187
}
344 eqlazer 188
 
189
void send_dimensions(){
463 eqlazer 190
	Can_Message_t txMsg;
481 eqlazer 191
 
463 eqlazer 192
	txMsg.ExtendedFlag=1;
193
	txMsg.RemoteFlag=0;
344 eqlazer 194
	txMsg.Id=0xA000001;
195
	txMsg.Data.bytes[0] = SIZE_X;
196
	txMsg.Data.bytes[1] = SIZE_Y;
197
	txMsg.DataLength = 2;
481 eqlazer 198
 
463 eqlazer 199
	BIOS_CanSend(&txMsg);
344 eqlazer 200
}
481 eqlazer 201
 
202
void rotenc(){
203
	uint8_t rot_data = 0;
204
	static uint8_t rot_lastdir = 0, rot_laststate = 0; // FIXME måste flyttas ut igen?
205
 
206
	Can_Message_t txMsg;
207
	txMsg.ExtendedFlag=1;
208
	txMsg.RemoteFlag=0;
209
	txMsg.Id = ( CLASS_SNS<<CLASS_MASK_BITS )|( SNS_ACT_BUTTON<<SNS_TYPE_BITS )|( 0x01<<SNS_ID_BITS )| NODE_ID;
210
	txMsg.DataLength=2;
211
 
212
	if(PINB&(1<<PB0)){
213
		rot_data |= 0x01;
214
	}
215
	if(PIND&(1<<PD2)){
216
		rot_data |= 0x02;
217
	}
218
 
219
	if( rot_data==0 || rot_data==3 ){
220
		if( rot_data==0 && rot_laststate!=rot_data ){
221
			if( rot_lastdir&0x01 ){
222
				// Moving right
223
				txMsg.Data.bytes[0]=RIGHT;
224
				txMsg.Data.bytes[1] = (PINB&(1<<PB7))?0:1;
225
				txMsg.DataLength=2;
226
				BIOS_CanSend(&txMsg);
227
				// For testing TODO remove
228
				if(OCR1A<0xFF){
229
					OCR1A++;
230
				}
231
				if(OCR0B>0){
232
					OCR0B--;
233
				}
234
			}else{
235
				// Moving left
236
				txMsg.Data.bytes[0]=LEFT;
237
				txMsg.Data.bytes[1] = (PINB&(1<<PB7))?0:1;
238
				txMsg.DataLength=2;
239
				BIOS_CanSend(&txMsg);
240
				// For testing TODO remove
241
				if(OCR1A>0){
242
					OCR1A--;
243
				}
244
				if(OCR0B<0xFF){
245
					OCR0B++;
246
				}
247
			}
248
		}
249
		rot_laststate = rot_data;
250
	}else{
251
		rot_lastdir = rot_data;
252
	}
253
}
254