Subversion Repositories HomeAutomation

Rev

Go to most recent revision | Details | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
179 eqlazer 1
/**
348 eqlazer 2
 * CanCLCD. Simple version.
179 eqlazer 3
 * For HD44780- and KS0073-based LCD displays
4
 *
5
 * @date    2006-12-11
6
 * @author  Erik Larsson
7
 *
8
 */
9
 
10
/*-----------------------------------------------------------------------------
11
 * Includes
12
 *---------------------------------------------------------------------------*/
13
/* system files */
14
#include <avr/io.h>
15
#include <avr/interrupt.h>
16
#include <stdio.h>
17
/* lib files */
332 eqlazer 18
#include <bios.h>
179 eqlazer 19
#include <lcd_HD44780.h>
196 eqlazer 20
/* funcdefs */
348 eqlazer 21
#include <funcdefs.h>
179 eqlazer 22
 
23
/* defines */
344 eqlazer 24
#define SIZE_X  20
25
#define SIZE_Y  4
348 eqlazer 26
#define SIZE_LCD LCD_SIZE_20x4
344 eqlazer 27
 
348 eqlazer 28
#define BUFFER_SIZE SIZE_X
332 eqlazer 29
#define TRUE 1
30
#define FALSE 0
179 eqlazer 31
 
344 eqlazer 32
#define LEFT    0x01
33
#define RIGHT   0x02
34
 
35
Can_Message_t txMsg;
256 eqlazer 36
 
348 eqlazer 37
char incoming_text[ BUFFER_SIZE ];
38
uint8_t msg_received = FALSE;
335 eqlazer 39
 
40
uint8_t rot_lastdir = 0,
41
        rot_laststate = 0;
42
 
348 eqlazer 43
    char buffer[ BUFFER_SIZE ];
344 eqlazer 44
 
348 eqlazer 45
void send_dimensions();
46
 
344 eqlazer 47
void can_receive(Can_Message_t *msg){
348 eqlazer 48
    uint32_t act;
49
    uint8_t m, act_type, lcd_action, lcd_size;
50
    if( ((msg->Id & CLASS_MASK)>> CLASS_MASK_BITS) == CLASS_ACT ){
51
        act = (msg->Id & TYPE_MASK) >> TYPE_MASK_BITS;
52
        act_type = (act & ACT_TYPE_MASK) >> ACT_TYPE_BITS;
53
        lcd_action = (act & LCD_ACTION_MASK) >> LCD_ACTION_BITS;
54
        lcd_size = (act & LCD_SIZE_MASK) >> LCD_SIZE_BITS;
55
    }
56
 
57
    if( act_type == ACT_TYPE_LCD && (lcd_size == SIZE_LCD || lcd_size == LCD_SIZE_ALL)){
58
        switch( lcd_action ){
59
            case LCD_ACTION_CLR:
60
                    // Clear LCD
61
                    lcd_clrscr();
62
                break;
63
            case LCD_ACTION_CURS:
64
                    // Move cursor
65
                    lcd_gotoxy( msg->Data.bytes[0],msg->Data.bytes[1] );
66
                break;
67
            case LCD_ACTION_GET_SIZE:
68
                    // Request LCD dimension
69
                    send_dimensions();
70
                break;
71
            case LCD_ACTION_TEXT:
72
                // Print text to LCD
73
                for(m=0;m<msg->DataLength;m++){
74
                    lcd_putc( (char)msg->Data.bytes[m] );
75
                }
76
                break;
77
            case LCD_ACTION_SET_CONT:
78
                // Set contrast
79
                if(msg->DataLength == 1){
80
                    OCR0B = msg->Data.bytes[0];
81
                }
82
                break;
83
            case LCD_ACTION_SET_BLIGHT:
84
                // Set backlight
85
                if(msg->DataLength == 1){
86
                    OCR1AL = msg->Data.bytes[0];
87
                }
88
                break;
89
            case LCD_ACTION_GET_CONT:
90
                // Get contrast
91
                txMsg.DataLength = 1;
92
                txMsg.Id = ( CLASS_ACT<<CLASS_MASK_BITS )|( ACT_TYPE_LCD<<ACT_TYPE_BITS )|( LCD_ACTION_SEND_CONT<<LCD_ACTION_BITS )|NODE_ID;
93
                txMsg.Data.bytes[0] = OCR0B;
94
                bios->can_send(&txMsg);
95
                break;
96
            case LCD_ACTION_GET_BLIGHT:
97
                // Get backlight
98
                txMsg.DataLength = 1;
99
                txMsg.Id = ( CLASS_ACT<<CLASS_MASK_BITS )|( ACT_TYPE_LCD<<ACT_TYPE_BITS )|( LCD_ACTION_SEND_BLIGHT<<LCD_ACTION_BITS )|NODE_ID;
100
                txMsg.Data.bytes[0] = OCR1AL;
101
                bios->can_send(&txMsg);
102
                break;
103
            default:
104
                // Take over the world
105
                break;
106
        }
107
    }
344 eqlazer 108
}
109
 
110
 
111
ISR( PCINT0_vect ){ // For ROTENC_A and ROTENC_B
335 eqlazer 112
    uint8_t rot_data = 0;
256 eqlazer 113
 
348 eqlazer 114
    txMsg.Id = ( CLASS_SNS<<CLASS_MASK_BITS )|( SNS_ACT_BUTTON<<SNS_TYPE_BITS )|( 0x01<<SNS_ID_BITS )| NODE_ID;
344 eqlazer 115
    txMsg.DataLength=2;
116
 
117
    if(PINB&(1<<PB7)){
335 eqlazer 118
        rot_data |= 0x01;
119
    }
344 eqlazer 120
    if(PINB&(1<<PB0)){
335 eqlazer 121
        rot_data |= 0x02;
122
    }
123
 
344 eqlazer 124
    if( rot_data==0 || rot_data==3 ){
125
        if( rot_data==0 && rot_laststate!=rot_data ){
126
            if( rot_lastdir&0x01 ){
127
                // Moving right
128
                txMsg.Data.bytes[0]=RIGHT;
129
                txMsg.Data.bytes[1] = (PIND&(1<<PD2))?0:1;
130
                bios->can_send(&txMsg);
348 eqlazer 131
                // For testing TODO remove
132
                if(OCR1A<0xFF){
133
                    OCR1A++;
134
                }
344 eqlazer 135
            }else{
136
                // Moving left
137
                txMsg.Data.bytes[0]=LEFT;
138
                txMsg.Data.bytes[1] = (PIND&(1<<PD2))?0:1;
139
                bios->can_send(&txMsg);
348 eqlazer 140
                // For testing TODO remove
141
                if(OCR1A>0){
142
                    OCR1A--;
143
                }
335 eqlazer 144
            }
145
        }
344 eqlazer 146
        rot_laststate = rot_data;
147
    }else{
335 eqlazer 148
        rot_lastdir = rot_data;
149
    }
332 eqlazer 150
}
179 eqlazer 151
 
344 eqlazer 152
ISR( PCINT2_vect ){ // For ROTENC_BTN
348 eqlazer 153
    txMsg.Id = ( CLASS_SNS<<CLASS_MASK_BITS )|( SNS_ACT_BUTTON<<SNS_TYPE_BITS )|( 0x02<<SNS_ID_BITS )| NODE_ID;
154
    txMsg.Data.bytes[0] = (PIND&(1<<PD2))?0:1; // Check if buton is pressed or not
155
    txMsg.DataLength=1;
156
    bios->can_send(&txMsg);
332 eqlazer 157
}
158
 
159
 
179 eqlazer 160
/*-----------------------------------------------------------------------------
161
 * Main Program
162
 *---------------------------------------------------------------------------*/
163
int main(void) {
164
 
335 eqlazer 165
    /*
166
     * Initialize rotaryencoders and buttons
167
     */
168
    /* Set as input */
344 eqlazer 169
    DDRD &= ~(1<<DDD2);
170
    DDRB &= ~((1<<DDB7)|(1<<DDB0));
171
    /* Enable pull-up */
172
    PORTD |= (1<<PD2);
173
    PORTB |= (1<<PB7)|(1<<PB0);
335 eqlazer 174
    /* Enable IO-pin interrupt */
344 eqlazer 175
    PCICR |= (1<<PCIE2)|(1<<PCIE0);
176
    /* Unmask PB7, PB0 and PD2 */
177
    PCMSK2 |= (1<<PCINT18);
178
    PCMSK0 |= (1<<PCINT7)|(1<<PCINT0);
179 eqlazer 179
 
348 eqlazer 180
    /* Contrast */
181
    TCCR0A |= (1<<COM0B1)|(1<<WGM01)|(1<<WGM00);
182
    TCCR0B |= (1<<CS00);
183
    OCR0B = 0x20;
184
    DDRD |= (1<<DDD5);
185
 
186
    /* Backlight */
187
    TCCR1A |= (1<<COM1A1)|(1<<WGM11);
188
    TCCR1B |= (1<<WGM13)|(1<<WGM12)|(1<<CS10);
189
    ICR1 = 0xFF; // Make it 8 bits
190
    OCR1A = 0x20;
191
    DDRB |= (1<<DDB1);
192
 
193
 
344 eqlazer 194
    txMsg.ExtendedFlag=1;
195
    txMsg.RemoteFlag=0;
196
 
335 eqlazer 197
    sei();
332 eqlazer 198
    bios->can_callback = &can_receive;
256 eqlazer 199
 
332 eqlazer 200
    lcd_init( LCD_DISP_ON );
201
    lcd_clrscr();
348 eqlazer 202
    lcd_puts("HomeAutomation\n");
179 eqlazer 203
 
344 eqlazer 204
    send_dimensions();
348 eqlazer 205
    lcd_puts("Very nice!\n");
179 eqlazer 206
 
207
    /* main loop */
332 eqlazer 208
    while(1){
209
        /* check if any messages have been received */
210
        if(msg_received){
344 eqlazer 211
 
334 eqlazer 212
            msg_received = FALSE;
213
        }
332 eqlazer 214
    }
179 eqlazer 215
}
344 eqlazer 216
 
217
void send_dimensions(){
218
    txMsg.Id=0xA000001;
219
    txMsg.Data.bytes[0] = SIZE_X;
220
    txMsg.Data.bytes[1] = SIZE_Y;
221
    txMsg.DataLength = 2;
222
    bios->can_send(&txMsg);
223
}