Subversion Repositories HomeAutomation

Rev

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

Rev Author Line No. Line
238 arune 1
#include "bios_funs.h"
2
#include "avr_cfg.h"
3
#include <inttypes.h>
4
#include <avr/io.h>
5
#include <avr/interrupt.h>
6
#include <avr/wdt.h>
7
#include <avr/pgmspace.h>
8
#include <stdio.h>
9
#include "flash.h"
10
#include "vectors.h" // Must be included after sfr_defs.h
11
 
12
 
13
 
14
/**
15
 * This is a test-bootloader with ihex parser, since it takes a while to program
16
 * a page in flash the serial port must to be slow, change to 2400baud in bios.h
17
 * Also, rename this file to bios.c for simplicity
18
 */
19
 
20
 
21
 
22
//---------------------------------------------------------------------------
23
// Globals
24
 
25
volatile long gMilliSecTick;
26
 
27
//---------------------------------------------------------------------------
28
// Function definitions for the exported interface
29
 
30
void reset(void) {
31
    //Just loop and let the watchdog reset
32
    cli();
33
    while(1);
34
};
35
 
36
void bios_putchar(char c) {
37
    UART_PUTCHAR(c);
38
};
39
 
40
char bios_getchar(void) {
41
    char c;
42
    UART_GETCHAR(c)
43
    return c;
44
};
45
 
46
long timebase_get(void) {
47
    uint8_t sreg;
48
    long res;
49
 
50
    //Disable interrupts while reading tick count
51
    sreg=SREG;
52
    cli();
53
 
54
    res = gMilliSecTick;
55
 
56
    SREG=sreg;
57
 
58
    return res;
59
}
60
 
61
//---------------------------------------------------------------------------
62
// Function definitions for the private functions
63
 
64
static int console_getchar(FILE *stream) {
65
    return bios_getchar();
66
}
67
 
68
static int console_putchar(char c, FILE *stream) {
69
    bios_putchar(c);
70
    return 0;
71
}
72
 
73
static FILE bios_stdio = FDEV_SETUP_STREAM(console_putchar, console_getchar,
74
                                         _FDEV_SETUP_RW);
75
 
76
 
77
//---------------------------------------------------------------------------
78
// Interrupt Service Routines
79
// Read app_vectors.h!
80
 
81
ISR(TIMEBASE_VECTOR) {
82
    TIMEBASE_COUNTER -= TIMEBASE_RELOAD;
83
    gMilliSecTick++;
84
    wdt_reset();
85
}
86
 
87
uint8_t asciitoint(uint8_t data) {
88
    data = data - 48;
89
    if (data > 9)
90
        data = data - 7;    //asume A-F (uppercase)
91
    return data;
92
}
93
 
94
int main() {
95
    void (*app_reset)(void) = 0;
96
 
97
    // Setup USART for debug channel
98
    UART_INIT();
99
    stdout = &bios_stdio;
100
    stdin = &bios_stdio;
101
 
102
    // Initialize a suitable hardware timer to create a 1KHz interrupt.
103
    TIMEBASE_INIT();
104
 
105
    // Enable watchdog timer to protect against an application locking the
106
    // node by leaving interrupts disabled. 
107
    wdt_enable(WDTO_500MS);
108
 
109
    // Move interrupt vectors to start of bootloader section and enable interrupts
110
    IVSEL_REG = _BV(IVCE);
111
    IVSEL_REG = _BV(IVSEL);
112
    sei();
113
 
114
    printf("AVR BIOS\n");
115
    flash_init();
116
 
117
    uint16_t addr;
118
    uint16_t prgword;
119
    uint8_t state = 0;
120
    uint8_t i = 0;
121
    uint8_t nibblecnt = 0;
122
    uint8_t hexdatacnt;
123
 
124
/*      uint8_t tmp = 48;
125
        tmp = 48+ hexdatacnt;
126
        UART_PUTCHAR(tmp);*/
127
    for (i=1; i<100; i++) {
128
        uint8_t data = bios_getchar();
129
        if (i == 1) {
130
            //Wait for Start code ':'
131
            if (data != ':') {
132
                i = 0;
133
            }
134
        }
135
        //Read two digits for Byte count
136
        if (i == 2) {
137
            data = asciitoint(data);
138
            hexdatacnt = data<<4;
139
        }
140
        if (i == 3) {
141
            data = asciitoint(data);
142
            hexdatacnt |= data;
143
        }
144
        //Read four digits for Address
145
        if (i == 4) {
146
            data = asciitoint(data);
147
            addr = data<<12;
148
        }
149
        if (i == 5) {
150
            data = asciitoint(data);
151
            addr |= data<<8;
152
        }
153
        if (i == 6) {
154
            data = asciitoint(data);
155
            addr |= data<<4;
156
        }
157
        if (i == 7) {
158
            data = asciitoint(data);
159
            addr |= data;
160
        }
161
        //Record type = 01, End Of File record
162
        if (i == 9) {
163
            if (data == '1') {
164
                i = 100;
165
                state = 1;
166
            }
167
        }
168
        //If data but uneven number of bytes (half a word)
169
        if ((i>9) && (state==0) && (hexdatacnt == 1)) {
170
            prgword |= data;
171
            prgword |= 0xFF00;
172
            flash_write_word(addr, prgword);
173
            i = 0;
174
        }
175
        //If data, until byte counter = 0
176
        if ((i>9) && (state == 0)) {
177
            data = asciitoint(data);
178
            nibblecnt++;
179
            if (nibblecnt == 1) {
180
                prgword = data<<4;
181
            } else if (nibblecnt == 2) {
182
                prgword |= data;
183
            } else if (nibblecnt == 3) {
184
                prgword |= data<<12;
185
            } else if (nibblecnt == 4) {
186
                prgword |= data<<8;
187
                nibblecnt = 0;
188
 
189
                flash_write_word(addr, prgword);
190
                addr = addr + 2;
191
                hexdatacnt = hexdatacnt-2;
192
            }
193
            if (hexdatacnt == 0) {
194
                i = 0;
195
            }
196
        }
197
    }
198
    //flash last page
199
    flash_flush_buffer();
200
 
201
 
202
    if (pgm_read_word(0) != 0xffff) {
203
        printf("Starting application.\n");
204
        app_reset();
205
    }
206
 
207
    printf("No application found.\n");
208
    return 0;
209
}