Root/atusb/fw/flash.c

1/*
2 * fw/flash.c - Board-specific flash functions
3 *
4 * Written 2011, 2013-2015 by Werner Almesberger
5 * Copyright 2011, 2013-2015 Werner Almesberger
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13
14#include <stdbool.h>
15#include <stdint.h>
16
17#include <avr/boot.h>
18#include <avr/pgmspace.h>
19
20#include "dfu.h"
21#include "board.h"
22
23
24static uint32_t payload;
25
26
27static void flash_start(void)
28{
29    payload = 0;
30}
31
32
33static bool flash_can_write(uint16_t size)
34{
35    return payload+size <= BOOT_ADDR;
36}
37
38
39static void flash_write(const uint8_t *buf, uint16_t size)
40{
41    static uint8_t last;
42    const uint8_t *p;
43
44    for (p = buf; p != buf+size; p++) {
45        if (!(payload & (SPM_PAGESIZE-1))) {
46            boot_page_erase(payload);
47            boot_spm_busy_wait();
48        }
49
50        if (payload & 1)
51            boot_page_fill(payload, last | (*p << 8));
52        else
53            last = *p;
54        payload++;
55
56        if (!(payload & (SPM_PAGESIZE-1))) {
57            boot_page_write(payload-SPM_PAGESIZE);
58            boot_spm_busy_wait();
59        }
60    }
61}
62
63
64static void flash_end_write(void)
65{
66    if (payload & (SPM_PAGESIZE-1)) {
67        boot_page_write(payload & ~(SPM_PAGESIZE-1));
68        boot_spm_busy_wait();
69    }
70    boot_rww_enable();
71}
72
73
74static uint16_t flash_read(uint8_t *buf, uint16_t size)
75{
76    uint16_t got = 0;
77
78    while (size && payload != (uint32_t) FLASHEND+1) {
79        *buf++ = pgm_read_byte(payload);
80        payload++;
81        size--;
82        got++;
83    }
84    return got;
85}
86
87
88static const struct dfu_flash_ops flash_ops = {
89    .start = flash_start,
90    .can_write = flash_can_write,
91    .write = flash_write,
92    .end_write = flash_end_write,
93    .read = flash_read,
94};
95
96
97const struct dfu_flash_ops *dfu_flash_ops = &flash_ops;
98

Archive Download this file



interactive