main.c 5.4 KB
Newer Older
1
2
#include <stdio.h>
#include <stddef.h>
schneider's avatar
schneider committed
3
4
5
#include <stdbool.h>
#include <string.h>

6
7
8
#include "mxc_config.h"
#include "mxc_sys.h"
#include "mxc_delay.h"
schneider's avatar
schneider committed
9
10
11
#include "flc.h"
#include "icc.h"
#include "crc.h"
12
13
#include "board.h"
#include "led.h"
schneider's avatar
schneider committed
14
#include "ff.h"
15
16
#include "crc16-ccitt.h"

17

schneider's avatar
schneider committed
18
19
#define GPIO_PORT_IN                PORT_1
#define GPIO_PIN_IN                 PIN_6
20
21


schneider's avatar
schneider committed
22
#define PARTITION_START (0x10000000 + 64 * 1024)
23
24
25
26
27
//#define PARTITION_END (0x10000000 + 512 * 1024 - 1) /* TODO: check if 1 MB also works. Might have to enable the second bank */
#define PARTITION_END (0x10000000 + 1024 * 1024 - 1)

//#define PARTITION_START (0x10080000)
//#define PARTITION_END (0x10000000 + 1024 * 1024 - 1) /* TODO: check if 1 MB also works. Might have to enable the second bank */
28

schneider's avatar
schneider committed
29
extern void run_usbmsc(void);
30
31

DIR dir;
schneider's avatar
schneider committed
32
FATFS FatFs;
33

schneider's avatar
schneider committed
34
bool mount(void)
35
{
schneider's avatar
schneider committed
36
37
38
39
40
    FRESULT res;
    res=f_mount(&FatFs,"/",0);
    if(res != FR_OK) {
        printf("f_mount error %d\n", res);
        return false;
41
42
    }

schneider's avatar
schneider committed
43
44
45
46
    res = f_opendir(&dir, "0:");
    if(res != FR_OK) {
        printf("f_opendir error %d\n", res);
        return false;
47
48
    }

schneider's avatar
schneider committed
49
50
    return true;
}
51

schneider's avatar
schneider committed
52
53
54
55
56
57
58
59
60
61
62
63
64
bool check_integrity(void)
{
    FIL file;
    UINT readbytes;
    char *filename = "card10.bin";
    uint8_t data[512];
    FRESULT res;

    res=f_open(&file, filename, FA_OPEN_EXISTING|FA_READ);
    if(res != FR_OK) {
        printf("f_open error %d\n", res);
        return false;
    }
65

66
    uint16_t crcval = 0;
schneider's avatar
schneider committed
67
68
69
70
71
72
    do {
        res = f_read(&file, data, sizeof(data), &readbytes);
        if(res != FR_OK) {
            printf("f_read error %d\n", res);
            crcval = 1; // Make sure to fail the test
            break;
73
        }
74
        crcval = crc16_ccitt(crcval, data, readbytes);
schneider's avatar
schneider committed
75
    } while (readbytes == sizeof(data));
76

schneider's avatar
schneider committed
77
78
79
80
81
82
83
    f_close(&file);

    if(crcval == 0) {
        return true;
    } else {
        printf("CRC check failed. Final CRC: %d\n", crcval);
        return false;
84
85
86
    }
}

schneider's avatar
schneider committed
87
bool is_update_needed(void)
88
{
schneider's avatar
schneider committed
89
90
91
92
93
94
95
96
97
98
    FIL file;
    UINT readbytes;
    char *filename = "card10.bin";
    uint8_t data[512];
    FRESULT res;

    res=f_open(&file, filename, FA_OPEN_EXISTING|FA_READ);
    if(res != FR_OK) {
        printf("f_open error %d\n", res);
        return false;
99
100
    }

schneider's avatar
schneider committed
101
102
103
104
105
106
107
108
109
110
111
112
113
114
    uint8_t *partition = (uint8_t *)(intptr_t)PARTITION_START;
    bool different = false;
    do {
        res = f_read(&file, data, sizeof(data), &readbytes);
        if(res != FR_OK) {
            printf("f_read error %d\n", res);
            break; /* Going to return false, don't want to use this file */
        }
        if(memcmp(partition, data, readbytes)) {
            different = true;
            break;
        }
        partition += readbytes;
    } while (readbytes == sizeof(data));
115

schneider's avatar
schneider committed
116
    f_close(&file);
117

schneider's avatar
schneider committed
118
    return different;
119
120
}

schneider's avatar
schneider committed
121
void erase_partition(void)
122
{
schneider's avatar
schneider committed
123
124
125
126
    int ret = FLC_MultiPageErase(PARTITION_START, PARTITION_END);
    if(ret != E_NO_ERROR) {
        printf("FLC_MultiPageErase failed with %d\n", ret);
        while(1);
127
128
129
    }
}

schneider's avatar
schneider committed
130
void flash_partition(void)
131
{
schneider's avatar
schneider committed
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
    FIL file;
    UINT readbytes;
    char *filename = "card10.bin";
    uint8_t data[512];
    FRESULT res;

    res=f_open(&file, filename, FA_OPEN_EXISTING|FA_READ);
    if(res != FR_OK) {
        printf("f_open error %d\n", res);
        while(1);
    }

    uint32_t partition = PARTITION_START;

    ICC_Disable();
    do {
        res = f_read(&file, data, sizeof(data), &readbytes);
        if(res != FR_OK) {
            printf("f_read error %d\n", res);
            break; /* Going to return false, don't want to use this file */
        }
        int ret = FLC_Write(partition, readbytes, (uint32_t *)data); /* wild cast. not sure if this works */
        if(ret != E_NO_ERROR) {
            printf("FLC_Write failed with %d\n", ret);
            while(1);
        }
        partition += readbytes;
    } while (readbytes == sizeof(data));
    ICC_Enable();

    f_close(&file);
163
164
}

schneider's avatar
schneider committed
165
166
167
168
169
170
171
172
173
174
175
176
177
static inline void boot(const void * vtable){
    SCB->VTOR = (uintptr_t) vtable;

	// Reset stack pointer & branch to the new reset vector.
	__asm(  "mov r0, %0\n"
			"ldr sp, [r0]\n"
			"ldr r0, [r0, #4]\n"
			"bx r0\n"
			:
			: "r"(vtable)
			: "%sp", "r0");
};

178
179

/******************************************************************************/
schneider's avatar
schneider committed
180
int main(void)
181
{
schneider's avatar
schneider committed
182
183
184

    printf("\n\nBootloader\n");
    // If the button is pressed, we go into MSC mode.
185
    if (PB_Get(0) || PB_Get(1)) {
schneider's avatar
schneider committed
186
187
188
189
190
191
        run_usbmsc();

        // If we return, don't try to boot. Maybe rather trigger a software reset.
        // Reason: Not sure in which state the USB peripheral is and what kind
        // of interrupts are active.
        while(1);
192
193
    }

194
195
    //MXC_FLC0->clkdiv = 96;
    //MXC_FLC0->clkdiv = 96;
196

schneider's avatar
schneider committed
197
198
    if(mount()) {
        if(check_integrity()) {
199
            printf("Found valid application image\n");
schneider's avatar
schneider committed
200
            if(is_update_needed()) {
201
                printf("Trying to update application from external flash\n");
schneider's avatar
schneider committed
202
203
204
205
206
207
208
209
                erase_partition();
                flash_partition();
            } else {
                printf("No update needed\n");
            }
        } else {
            printf("Integrity check failed\n");
        }
210
211
    } else {
        printf("Failed to mount the external flash\n");
schneider's avatar
schneider committed
212
213
214
215
216
217
218
219
220
221
    }


    printf("Trying to boot\n");
    // boot partition
    boot((uintptr_t *) PARTITION_START);

    while (1) {
        // Should never be reached.
    }
222
223
224
225
226
227
228
}

/******************************************************************************/
void SysTick_Handler(void)
{
    mxc_delay_handler();
}