Subversion Repositories HomeAutomation

Rev

Rev 223 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

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