Subversion Repositories HomeAutomation

Rev

Details | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
63 jimmy 1
/**
2
 * CAN test program.
3
 *
4
 * @target  AVR
5
 * @date    2006-10-29
6
 * @author  Jimmy Myhrman
7
 *  
8
 */
9
 
10
/*-----------------------------------------------------------------------------
11
 * Includes
12
 *---------------------------------------------------------------------------*/
13
/* system files */
14
#include <avr/io.h>
15
#include <avr/interrupt.h>
16
#include <avr/wdt.h>
356 andfri 17
#include <avr/eeprom.h>
63 jimmy 18
#include <stdio.h>
19
/* lib files */
20
#include <can.h>
149 jimmy 21
#include <serial.h>
63 jimmy 22
#include <uart.h>
23
#include <timebase.h>
24
 
25
 
26
/*-----------------------------------------------------------------------------
27
 * Defines
28
 *---------------------------------------------------------------------------*/
29
#define UART_START_BYTE 253
30
#define UART_END_BYTE 250
31
 
356 andfri 32
const uint8_t days[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
63 jimmy 33
 
356 andfri 34
union {
35
    uint32_t packed;
36
    struct date_t {
37
        unsigned ss:6;
38
        unsigned mm:6;
39
        unsigned hh:5;
40
        unsigned DD:5;
41
        unsigned MM:4;
42
        unsigned YY:6;
43
    } unpacked;
44
} date;
45
 
46
void IncTime(void) {
47
    static uint8_t YY=07, MM=03, DD=02, hh=23, mm=58, ss=00;
48
 
49
    if (ss++ > 59) {
50
        ss=0;
51
        if (mm++ > 59) {
52
            mm=0;
53
            if (hh++ > 23) {
54
                hh=0;
55
                if (DD++ > days[MM-1] + ((YY%4) & (MM==2)) ? 1 : 0))) {
56
                    DD=1;
57
                    if (MM++ > 12) {
58
                        MM=1; YY++;
59
                    }
60
                }
61
            }
62
        }
63
    }
64
    date.unpacked.YY = YY;
65
    date.unpacked.MM = MM;
66
    date.unpacked.DD = DD;
67
    date.unpacked.hh = hh;
68
    date.unpacked.mm = mm;
69
    date.unpacked.ss = ss;
70
}
63 jimmy 71
/*-----------------------------------------------------------------------------
72
 * Functions
73
 *---------------------------------------------------------------------------*/
74
/**
75
 * Parses an incoming UART byte by maintaining a state machine. The UART
76
 * bytes will build up a CAN message according to the protocol described here:
77
 *
78
 * http://www.arune.se/projekt/doku.php?id=homeautomation:pc-mjukvara
79
 *
80
 * @param c
81
 *      The received UART byte.
82
 */
83
void UartParseByte(uint8_t c) {
127 jimmy 84
    static Can_Message_t cm;
63 jimmy 85
    static uint8_t waitingMessage = 0;
86
    static uint32_t startTime = 0;
87
    static int8_t count = 0;
88
 
89
    /* 50ms timeout */
127 jimmy 90
    if (waitingMessage && Timebase_PassedTimeMillis(startTime) > 50) {
63 jimmy 91
        waitingMessage = 0;
69 jimmy 92
    }
63 jimmy 93
 
94
    if (waitingMessage) {
95
        /* save start time */
127 jimmy 96
        startTime = Timebase_CurrentTime();
63 jimmy 97
        /* UART END */
98
        if (count >= 15) {
69 jimmy 99
            if (c == UART_END_BYTE) {
100
                PORTC ^= (1<<PC0);
127 jimmy 101
                Can_Send(&cm);
69 jimmy 102
            }
63 jimmy 103
            waitingMessage = 0;
104
            return;
105
        }
106
        /* data */
107
        else if (count >= 7) {
108
            cm.Data.bytes[count-7] = c;
109
            count++;
110
            return;
111
        }
112
        /* data length */
113
        else if (count >= 6) {
114
            cm.DataLength = c;
115
            count++;
116
            return;
117
        }
118
        /* remote request flag */
119
        else if (count >= 5) {
120
            cm.RemoteFlag = c;
121
            count++;
122
            return;
123
        }
124
        /* extended */
125
        else if (count >= 4) {
126
            cm.ExtendedFlag = c;
127
            count++;
128
            return;
129
        }
130
        /* ident */
131
        else if (count >= 0) {
132
            cm.Id += ((uint32_t)c << (count*8));
133
            count++;
134
            return;
135
        }
136
    }
137
 
138
    if (c == UART_START_BYTE && !waitingMessage) {
139
        waitingMessage = 1;
127 jimmy 140
        startTime = Timebase_CurrentTime();
63 jimmy 141
        count = 0;
142
        cm.Id = 0;
143
        return;
144
    }
145
}
146
 
147
 
148
/*-----------------------------------------------------------------------------
149
 * Main Program
150
 *---------------------------------------------------------------------------*/
151
int main(void) {
356 andfri 152
    OSCCAL = eeprom_read_byte(0);
127 jimmy 153
    Timebase_Init();
149 jimmy 154
    Serial_Init();
127 jimmy 155
    Can_Init();
63 jimmy 156
 
157
    DDRC = 1<<PC1 | 1<<PC0;
158
    PORTC = (1<<PC1) | (1<<PC0);
159
 
160
    sei();
161
 
127 jimmy 162
    Can_Message_t rxMsg;
356 andfri 163
    Can_Message_t timeMsg;
164
    uint32_t time = Timebase_CurrentTime();
165
    uint32_t time1 = time;
166
    uint32_t unixtime = 0;
63 jimmy 167
    uint16_t rxByte;
168
    uint8_t i = 0;
169
 
356 andfri 170
    timeMsg.ExtendedFlag = 1;
171
    timeMsg.RemoteFlag = 0;
172
    //timeMsg.Id = (CAN_NMT << CAN_SHIFT_CLASS) | (CAN_NMT_TIME << CAN_SHIFT_NMT_TYPE);
173
    timeMsg.Id = 0; //Same thing, and lib's can.h is not updated.
174
    timeMsg.DataLength = 8;
175
 
63 jimmy 176
    /* main loop */
177
    while (1) {
142 jimmy 178
        /* service the CAN routines */
179
        Can_Service();
180
 
63 jimmy 181
        /* any new CAN messages received? */
127 jimmy 182
        if (Can_Receive(&rxMsg) == CAN_OK) {
63 jimmy 183
            PORTC ^= (1<<PC1);
184
            /* send message to CanWatcher */
185
            uart_putc(UART_START_BYTE);
186
            uart_putc((uint8_t)rxMsg.Id);
187
            uart_putc((uint8_t)(rxMsg.Id>>8));
188
            uart_putc((uint8_t)(rxMsg.Id>>16));
189
            uart_putc((uint8_t)(rxMsg.Id>>24));
190
            uart_putc(rxMsg.ExtendedFlag);
191
            uart_putc(rxMsg.RemoteFlag);
192
            uart_putc(rxMsg.DataLength);
193
            for (i=0; i<8; i++) {
194
                uart_putc(rxMsg.Data.bytes[i]);
195
            }
196
            uart_putc(UART_END_BYTE);
197
        }
198
 
199
        /* any UART bytes received? */
200
        rxByte = uart_getc();
201
        while (rxByte != UART_NO_DATA) {
202
            /* parse byte! */
203
            UartParseByte((uint8_t)(rxByte & 0x00FF));
204
            /* receive next */
205
            rxByte = uart_getc();
206
        }
356 andfri 207
 
208
        time1 = Timebase_CurrentTime();
209
        if ((time1 - time) > 1000) {
210
            time = time1;
211
            timeMsg.Data.dwords[0] = ++unixtime;
212
            IncTime();
213
            timeMsg.Data.dwords[1] = date.packed;
214
            Can_Send(&timeMsg);
215
        }
63 jimmy 216
    }
217
 
218
    return 0;
219
}