Subversion Repositories HomeAutomation

Rev

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

Rev Author Line No. Line
29 jimmy 1
/******************************************************************************
2
 *
3
 * Controller Area Network (CAN) Demo-Application
4
 * Atmel AVR with Microchip MCP2515
5
 *
6
 * Copyright (C) 2005 Martin THOMAS, Kaiserslautern, Germany
7
 * <eversmith@heizung-thomas.de>
8
 * http://www.siwawi.arubi.uni-kl.de/avr_projects
9
 *
10
 *****************************************************************************
11
 *
12
 * File    : main.c
13
 * Version : 0.9
14
 *
15
 * Summary : Application Entry
16
 *           Test-Platform: Atmel ATmega + Microchip MCP2515
17
 *           Here the MCP2515 is clocked by the AVR (see clock_init()).
18
 *
19
 * This application uses Peter Fleury's free AVR-U(S)ART library which
20
 * has been slightly extended. See comments in uart.c.
21
 *
22
 *****************************************************************************/
23
 
24
#include <avr/io.h>
25
#include <avr/interrupt.h>
26
#include <avr/wdt.h>
27
#include <avr/eeprom.h>
28
 
29
#include "uart.h"
30
#include "spi.h"
31
#include "can.h"
32
#include "delay.h"
33
#include "termio.h"
34
#include "terminal.h"
35
#include "gpio.h"
36
#include "timebase.h"
37
#include "debughelper.h"
38
 
30 jimmy 39
#define VERBOSE (1)
29 jimmy 40
 
41
#define OSCAL_READEEPROM (1)
42
 
43
#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega16__)
44
#define OSCAL_EEPROMADDR ((void*)0x1ff)
45
#elif defined(__AVR_ATmega32__)
46
#define OSCAL_EEPROMADDR ((void*)0x3ff)
47
#else
48
#error "eeprom addr. undefined for this target"
49
#endif
50
 
51
#define OSCAL_VALUE (0xA5)
52
 
53
#define BAUD 19200
54
 
55
#define AUTOSENDPORT PORTD
56
#define AUTOSENDDDR  DDRD
57
#define AUTOSENDPIN  PIND
58
#define AUTOSENDBIT  PD7
59
 
60
#if 0
61
void clock_init_tc2(void)
62
// to clock the MCP2515
63
// - CTC Mode of Timer-Counter 2
64
// - Freq at OC2 (datasheet): f=f_c/(2*N*(1+OCR2))
65
//   with: f_c=system clock=8MHz, N=prescaler=1, OCR2=0 -> 4MHz @ Pin D7
66
{
67
    // set OC2-Pin (PD7 on ATmega16) as output
68
    DDRD |= _BV(DDD7);
69
    // CTC limit in OCR2
70
    OCR2=0;
71
    // Clear Timer on Compare Match (CTC) mode; toogle OC2(PD7) on compare match;
72
    //  clock select (timer2 prescaler) to clk/1 (no prescaling CS20=1)
73
    TCCR2=_BV(WGM21)|_BV(COM20)|_BV(CS20);
74
}
75
#endif
76
 
77
void clock_init_tc1a(void)
78
// to clock the MCP2515 on Mega8/Mega32
79
// - CTC Mode of Timer-Counter 1 use OC1A as clock-pin
80
// - Freq at OC2 (datasheet): f=f_c/(2*N*(1+OCR2))
81
//   with: f_c=system clock=8MHz, N=prescaler=1, OCR1A=0 -> 4MHz 
82
//   @ Pin B1 Mega8
83
//   @ Pin D5 Mega32
84
{
85
    #if defined(__AVR_ATmega8__)
86
    // set OC2-Pin (PB1 on ATmega8) as output
87
    DDRB |= _BV(DDB1);
88
    #elif defined(__AVR_ATmega32__) || defined(__AVR_ATmega16__)
89
    // set OC2-Pin (PD5 on ATmega32) as output
90
    DDRD |= _BV(DDD5);
91
    #else
92
    #error "OCR1A pin undefined for this target"
93
    #endif
94
 
95
    // CTC limit in OCR1A
96
    OCR1A=0;
97
    // Clear Timer on Compare Match (CTC) mode; toogle OC1A(PB1) on compare match; 
98
    TCCR1A=_BV(COM1A0);
99
    // clock select (timer2 prescaler) 
100
    TCCR1B=_BV(CS10)|_BV(WGM12); // to clk/1 (no prescaling CS10=1)
101
}
102
 
103
static void process_CANMessages(void)
104
{
105
    CanMessage msg;
106
    uint8_t data2;
107
 
108
#ifdef VERBOSE
109
    term_puts_P("AutoProcessing\n");
110
#endif
111
    while ( can_readMessage(&msg) == CAN_OK ) {
112
        data2 = msg.dta[2];
113
        if ( data2<3 ) {
114
            gpio_toggle_led( (1<<data2) );
115
#ifdef VERBOSE
116
            Debug_ByteToUart_P("data2",data2);
117
#endif
118
        }
119
    }  
120
}
121
 
122
int main(void)
123
{
124
    uint8_t res, flag;
125
    uint8_t shellstate;
126
    uint16_t timebuf;
127
 
128
#if OSCAL_READEEPROM
129
    res = eeprom_read_byte(OSCAL_EEPROMADDR);
130
    if (res != 0xff) OSCCAL = res;
131
    else OSCCAL = OSCAL_VALUE; // take default from define
132
#else
133
    OSCCAL = OSCAL_VALUE;
134
#endif
135
 
136
    gpio_init();
137
    gpio_set_led(LED1);
138
 
139
    timebase_init();
140
 
141
    uart_init((UART_BAUD_SELECT((BAUD),F_OSC)));
142
 
143
    sei();
144
 
145
    term_puts_P( "\n\nMCP2515 Interface Demo  (c) Martin Thomas\n" );
146
    Debug_ByteToUart_P("OSCCAL", OSCCAL);
147
 
148
    term_puts_P("\nSetting up MCP clock to FOSC/2\n");
149
    clock_init_tc1a();  // init MCP2515 clock-source (=AVR FOSC/2)
150
    // old:  clock_init(); */
151
 
152
    term_puts_P("SPI init\n");
153
    spi_init();     // init SPI-Interface (as "Master")
154
 
155
    term_puts_P("CAN init ");
156
    // res = can_init(CAN_125KBPS);
157
    res = can_init(CAN_20KBPS);
158
    if (res == CAN_OK) term_puts_P("- OK\n");
159
    else term_puts_P("- FAIL\n");
160
 
161
 
162
    term_puts_P("Autosend (\"Autosendbit\"-State) : ");
163
    AUTOSENDDDR &= ~(1<<AUTOSENDBIT); // as input
164
    AUTOSENDPORT |= (1<<AUTOSENDBIT); // int pullup on
165
    if ( AUTOSENDPIN & (1<<AUTOSENDBIT) ) {
166
        gTimedSend = CANAUTOOFF;
167
        term_puts_P("off");
168
    }
169
    else {
170
        gTimedSend = CANAUTOON;
171
        term_puts_P("on");
172
    }
173
    term_puts_P("\n");
174
 
175
    can_debug1();
176
 
177
    shellstate = COMMANDSHELL_MODEINIT;
178
 
179
    flag = 0;
180
    timebuf = timebase_actTime();
181
 
182
#if 0
183
    for (;;) {
184
        if (timebase_passedTimeMS(timebuf)>=1000) {
185
            timebuf = timebase_actTime();
186
            term_puts_P("(.)");
187
        }
188
    }
189
#endif
190
 
191
    for (;;) {
192
        CommandShell(&shellstate);
193
        if ( shellstate == COMMANDSHELL_MODEEXIT ) {
194
            term_puts_P("I have no operation system to exit to :-( -> WD-Reset");
195
            wdt_enable ( WDTO_500MS );
196
            while(1);
197
        }
198
 
199
        if ( ( can_checkReceive() == CAN_MSGAVAIL ) ) {
200
            if (!flag) {
201
#ifdef VERBOSE
202
                term_puts_P("\nAt least one CAN-Message available!\n");
203
                shellstate = COMMANDSHELL_REDRAW;
204
#endif
205
                flag = 1;
206
            }
207
            if ( gCANAutoProcess == CANAUTOON ) {
208
                process_CANMessages();
209
#ifdef VERBOSE
210
                shellstate = COMMANDSHELL_REDRAW;
211
#endif
212
            }
213
        }
214
        else {
215
            flag = 0;
216
        }
217
 
218
        if (timebase_passedTimeMS(timebuf)>=1000) {
219
            timebuf = timebase_actTime();
220
            if (gTimedSend == CANAUTOON) {
221
                if ( can_testTransmit(CAN_STDID, 1) != CAN_OK ) {
222
                    term_puts_P("\nAuto-Transmit (debug) failed\n");
223
                    can_dumpStatus();
224
                    shellstate = COMMANDSHELL_REDRAW;
225
                }
226
            }
227
            if ( can_checkError() != CAN_OK ) {
228
                can_dumpStatus();
229
            }
230
        }
231
 
232
        // else term_puts_P("Checking\n");
233
    }
234
 
235
    return 0;
236
}