Subversion Repositories HomeAutomation

Rev

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

Rev Author Line No. Line
181 andfri 1
#include "bios_funs.h"
223 andfri 2
#include "avr_cfg.h"
181 andfri 3
#include <inttypes.h>
4
#include <avr/interrupt.h>
223 andfri 5
#include <avr/wdt.h>
6
#include <avr/boot.h>
181 andfri 7
#include <avr/pgmspace.h>
8
#include <avr/io.h>
9
#include <stdio.h>
223 andfri 10
#include "app_vectors.h"
181 andfri 11
 
12
//---------------------------------------------------------------------------
223 andfri 13
// Globals
14
 
15
volatile long gMilliSecTick;
16
 
17
//---------------------------------------------------------------------------
181 andfri 18
// Function definitions for the exported interface
19
 
223 andfri 20
void reset(void) {
21
    //Just loop and let the watchdog reset
22
    cli();
23
    while(1);
24
};
25
 
26
void bios_putchar(char c) {
181 andfri 27
    loop_until_bit_is_set(UCSRA, UDRE);
28
    UDR = c;
29
};
30
 
223 andfri 31
char bios_getchar(void) {
181 andfri 32
    loop_until_bit_is_set(UCSRA, RXC);
33
    return UDR;
34
};
35
 
223 andfri 36
long timebase_get(void) {
37
    uint8_t sreg;
38
    long res;
39
 
40
    //Disable interrupts while reading tick count
41
    sreg=SREG;
42
    cli();
43
 
44
    res = gMilliSecTick;
45
 
46
    SREG=sreg;
47
 
48
    return res;
49
}
181 andfri 50
 
51
//---------------------------------------------------------------------------
52
// Function definitions for the private functions
223 andfri 53
 
54
static uint16_t flash_prev_addr;
55
 
56
void flash_flush_buffer() {
181 andfri 57
    uint8_t sreg;
223 andfri 58
 
181 andfri 59
    // Disable interrupts.
223 andfri 60
 
181 andfri 61
    sreg = SREG;
62
    cli();
223 andfri 63
 
64
    eeprom_busy_wait();
65
 
66
    boot_page_erase(flash_prev_addr);
67
    boot_spm_busy_wait();      // Wait until the memory is erased.
68
 
69
    boot_page_write(flash_prev_addr);     // Store buffer in flash page.
181 andfri 70
    boot_spm_busy_wait();       // Wait until the memory is written.
71
 
72
    // Reenable RWW-section again. We need this if we want to jump back
73
    // to the application after bootloading.
74
 
75
    boot_rww_enable ();
76
 
77
    // Re-enable interrupts (if they were ever enabled).
78
 
79
    SREG = sreg;
80
}
81
 
223 andfri 82
void flash_load_buffer(uint16_t addr) {
83
    //TODO: Load current flash page contents into temporary buffer to implement
84
    // flash read-modify-writes with word granularity. (If possible, the data
85
    // sheet is a little fuzzy about this.)
86
}
87
 
88
void flash_write_word(uint16_t addr, uint16_t word) {
89
 
90
    if ((addr / SPM_PAGESIZE) != (flash_prev_addr / SPM_PAGESIZE)) {
91
        flash_flush_buffer();
92
        flash_load_buffer(addr);
93
    }
94
 
95
    boot_page_fill(addr, word);
96
    flash_prev_addr = addr;
97
}    
98
 
99
void flash_init() {
100
    flash_prev_addr = 0xffff;
101
}
102
 
103
static int console_getchar(FILE *stream) {
104
    return bios->can_receive();
105
}
106
 
107
static int console_putchar(char c, FILE *stream) {
108
    bios->can_send(c);
109
    return 0;
110
}
111
 
112
static FILE bios_stdio = FDEV_SETUP_STREAM(console_putchar, console_getchar,
181 andfri 113
                                         _FDEV_SETUP_RW);
114
 
223 andfri 115
 
116
//---------------------------------------------------------------------------
117
// Interrupt Service Routines
118
// Read app_vectors.h!
119
 
120
ISR(TIMEBASE_VECTOR) {
121
    TIMEBASE_COUNTER -= TIMEBASE_RELOAD;
122
    gMilliSecTick++;
123
    wdt_reset();
124
}
125
 
181 andfri 126
int main() {
127
    void (*app_reset)(void) = 0;
223 andfri 128
 
181 andfri 129
    // Setup USART for debug channel
130
    UCSRB = _BV(RXEN)|_BV(TXEN);
131
    UBRRL = (F_CPU / 16 / F_BAUD) - 1;
132
    stdout = &bios_stdio;
133
    stdin = &bios_stdio;
134
 
223 andfri 135
    // Initialize a suitable hardware timer to create a 1KHz interrupt.
136
    TIMEBASE_INIT();
137
 
138
    // Enable watchdog timer to protect against an application locking the
139
    // node by leaving interrupts disabled. 
140
    wdt_enable(WDTO_500MS);
141
 
142
    // Move interrupt vectors to start of bootloader section and enable interrupts
143
    GICR = _BV(IVCE);
144
    GICR = _BV(IVSEL);
145
    sei();
146
 
181 andfri 147
    printf("AVR BIOS\n");
148
 
223 andfri 149
    if (pgm_read_word(0) != 0xffff) {
150
        printf("Starting application.\n");
151
        app_reset();
152
    }
153
 
154
    printf("No application found.\n");
181 andfri 155
    return 0;
156
}