Subversion Repositories HomeAutomation

Rev

Rev 181 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 181 Rev 223
Line 1... Line 1...
1
#include "bios_funs.h"
1
#include "bios_funs.h"
-
 
2
#include "avr_cfg.h"
2
#include <inttypes.h>
3
#include <inttypes.h>
3
#include <avr/interrupt.h>
4
#include <avr/interrupt.h>
-
 
5
#include <avr/wdt.h>
-
 
6
#include <avr/boot.h>
4
#include <avr/pgmspace.h>
7
#include <avr/pgmspace.h>
5
#include <avr/io.h>
8
#include <avr/io.h>
6
#include <stdio.h>
9
#include <stdio.h>
-
 
10
#include "app_vectors.h"
-
 
11
 
-
 
12
//---------------------------------------------------------------------------
-
 
13
// Globals
-
 
14
 
-
 
15
volatile long gMilliSecTick;
7
 
16
 
8
//---------------------------------------------------------------------------
17
//---------------------------------------------------------------------------
9
// Function definitions for the exported interface
18
// Function definitions for the exported interface
10
 
19
 
-
 
20
void reset(void) {
-
 
21
    //Just loop and let the watchdog reset
-
 
22
    cli();
-
 
23
    while(1);
-
 
24
};
-
 
25
 
11
int bios_putchar(char c, FILE *stream) {
26
void bios_putchar(char c) {
12
    loop_until_bit_is_set(UCSRA, UDRE);
27
    loop_until_bit_is_set(UCSRA, UDRE);
13
    UDR = c;
28
    UDR = c;
14
    return 0;
-
 
15
};
29
};
16
 
30
 
17
int bios_getchar(FILE *stream) {
31
char bios_getchar(void) {
18
    loop_until_bit_is_set(UCSRA, RXC);
32
    loop_until_bit_is_set(UCSRA, RXC);
19
    return UDR;
33
    return UDR;
20
};
34
};
21
 
35
 
22
void bios_reset(void) {
36
long timebase_get(void) {
23
    bios_putchar('\n', 0);
37
    uint8_t sreg;
-
 
38
    long res;
24
};
39
   
-
 
40
    //Disable interrupts while reading tick count
-
 
41
    sreg=SREG;
-
 
42
    cli();
25
 
43
   
26
unsigned bios_version(void) {
44
    res = gMilliSecTick;
-
 
45
   
-
 
46
    SREG=sreg;
-
 
47
   
27
    return BIOS_VERSION;
48
    return res;
28
};
49
}
29
 
50
 
30
//---------------------------------------------------------------------------
51
//---------------------------------------------------------------------------
31
// Function definitions for the private functions
52
// Function definitions for the private functions
32
   
53
 
33
void program_page (uint32_t page, uint8_t *buf)
54
static uint16_t flash_prev_addr;
34
{
55
 
35
    uint16_t i;
56
void flash_flush_buffer() {
36
    uint8_t sreg;
57
    uint8_t sreg;
37
 
58
   
38
    // Disable interrupts.
59
    // Disable interrupts.
39
 
60
   
40
    sreg = SREG;
61
    sreg = SREG;
41
    cli();
62
    cli();
42
   
63
   
43
    eeprom_busy_wait ();
64
    eeprom_busy_wait();
44
 
65
   
45
    boot_page_erase (page);
66
    boot_page_erase(flash_prev_addr);
46
    boot_spm_busy_wait ();      // Wait until the memory is erased.
67
    boot_spm_busy_wait();      // Wait until the memory is erased.
47
 
68
   
48
    for (i=0; i<SPM_PAGESIZE; i+=2)
-
 
49
    {
-
 
50
        // Set up little-endian word.
-
 
51
       
-
 
52
        uint16_t w = *buf++;
-
 
53
        w += (*buf++) << 8;
-
 
54
       
-
 
55
        boot_page_fill (page + i, w);
-
 
56
    }
-
 
57
 
-
 
58
    boot_page_write (page);     // Store buffer in flash page.
69
    boot_page_write(flash_prev_addr);     // Store buffer in flash page.
59
    boot_spm_busy_wait();       // Wait until the memory is written.
70
    boot_spm_busy_wait();       // Wait until the memory is written.
60
 
71
 
61
    // Reenable RWW-section again. We need this if we want to jump back
72
    // Reenable RWW-section again. We need this if we want to jump back
62
    // to the application after bootloading.
73
    // to the application after bootloading.
63
 
74
 
Line 66... Line 77...
66
    // Re-enable interrupts (if they were ever enabled).
77
    // Re-enable interrupts (if they were ever enabled).
67
 
78
 
68
    SREG = sreg;
79
    SREG = sreg;
69
}
80
}
70
 
81
 
-
 
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
 
71
static FILE bios_stdio = FDEV_SETUP_STREAM(bios_putchar, bios_getchar,
112
static FILE bios_stdio = FDEV_SETUP_STREAM(console_putchar, console_getchar,
72
                                         _FDEV_SETUP_RW);
113
                                         _FDEV_SETUP_RW);
73
   
114
   
-
 
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
 
74
int main() {
126
int main() {
75
    void (*app_reset)(void) = 0;
127
    void (*app_reset)(void) = 0;
-
 
128
   
76
    // Setup USART for debug channel
129
    // Setup USART for debug channel
77
    UCSRB = _BV(RXEN)|_BV(TXEN);
130
    UCSRB = _BV(RXEN)|_BV(TXEN);
78
    UBRRL = (F_CPU / 16 / F_BAUD) - 1;
131
    UBRRL = (F_CPU / 16 / F_BAUD) - 1;
79
    stdout = &bios_stdio;
132
    stdout = &bios_stdio;
80
    stdin = &bios_stdio;
133
    stdin = &bios_stdio;
81
   
134
   
-
 
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);
82
    bios->reset();
145
    sei();
-
 
146
   
83
    printf("AVR BIOS\n");
147
    printf("AVR BIOS\n");
-
 
148
   
-
 
149
    if (pgm_read_word(0) != 0xffff) {
-
 
150
        printf("Starting application.\n");
84
    app_reset();
151
        app_reset();
-
 
152
    }
85
   
153
   
-
 
154
    printf("No application found.\n");
86
    return 0;
155
    return 0;
87
}
156
}