forked from joepasquariello/FlasherX
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFlashTxx.h
165 lines (147 loc) · 7.41 KB
/
FlashTxx.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
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
163
164
165
//******************************************************************************
// Flash write/erase functions (TLC/T3x/T4x/TMM), LMEM cache functions for T3.6
//******************************************************************************
// WARNING: you can destroy your MCU with flash erase or write!
// This code may or may not protect you from that.
//
// Original by Niels A. Moseley, 2015.
// Modifications for OTA updates by Jon Zeeff, Deb Hollenback
// Paul Stoffregen's T4.x flash routines from Teensy4 core added by Jon Zeeff
// Frank Boesing's T3.x flash routines adapted for OTA by Joe Pasquariello
// This code is released into the public domain.
//******************************************************************************
#ifndef _FLASHTXX_H_
#define _FLASHTXX_H_
#include <stdint.h> // uint32_t, etc.
/* --------------------------------------------------------------------------------------------
* USE_RAM_FOR_FLASHING def
*
* Size in KB to store the firmware in memory, if defined, otherwise it will be stored in flash.
* Once firmware is stored in either flash or memory, it will ultimately end up in a certain
* address in flash and the device will reboot.
*
* When building your program, something like this is printed to the output:
*
* Memory Usage on Teensy 4.1:
* FLASH: code:171304, data:51148, headers:8968 free for files:7895044
* RAM1: variables:55136, code:167976, padding:28632 free for local variables:272544
* RAM2: variables:79616 free for malloc/new:444672
*
* The number after "free for malloc/new:" is the available RAM usage before your program runs.
* You shouldn't request anything more than this. Remember, 1 KB is 1,024 bytes.
*
* Default is to store in flash. Uncomment USE_RAM_FOR_FLASHING to store in RAM.
*
*/
//#define USE_RAM_FOR_FLASHING 275
#if defined(__MKL26Z64__)
#define FLASH_ID "fw_teensyLC" // target ID (in code)
#define FLASH_SIZE (0x10000) // 64KB program flash
#define FLASH_SECTOR_SIZE (0x400) // 1KB sector size
#define FLASH_WRITE_SIZE (4) // 4-byte/32-bit writes
#define FLASH_RESERVE (2*FLASH_SECTOR_SIZE) // reserve top of flash
#define FLASH_BASE_ADDR (0) // code starts here
#elif defined(__MK20DX128__)
#define FLASH_ID "fw_teensy30" // target ID (in code)
#define FLASH_SIZE (0x20000) // 128KB program flash
#define FLASH_SECTOR_SIZE (0x400) // 1KB sector size
#define FLASH_WRITE_SIZE (4) // 4-byte/32-bit writes
#define FLASH_RESERVE (0*FLASH_SECTOR_SIZE) // reserve top of flash
#define FLASH_BASE_ADDR (0) // code starts here
#elif defined(__MK20DX256__)
#define FLASH_ID "fw_teensy32" // target ID (in code)
#define FLASH_SIZE (0x40000) // 256KB program flash
#define FLASH_SECTOR_SIZE (0x800) // 2KB sectors
#define FLASH_WRITE_SIZE (4) // 4-byte/32-bit writes
#define FLASH_RESERVE (0*FLASH_SECTOR_SIZE) // reserve top of flash
#define FLASH_BASE_ADDR (0) // code starts here
#elif defined(__MK64FX512__)
#define FLASH_ID "fw_teensy35" // target ID (in code)
#define FLASH_SIZE (0x80000) // 512KB program flash
#define FLASH_SECTOR_SIZE (0x1000) // 4KB sector size
#define FLASH_WRITE_SIZE (8) // 8-byte/64-bit writes
#define FLASH_RESERVE (0*FLASH_SECTOR_SIZE) // reserve to of flash
#define FLASH_BASE_ADDR (0) // code starts here
#elif defined(__MK66FX1M0__)
#define FLASH_ID "fw_teensy36" // target ID (in code)
#define FLASH_SIZE (0x100000) // 1MB program flash
#define FLASH_SECTOR_SIZE (0x1000) // 4KB sector size
#define FLASH_WRITE_SIZE (8) // 8-byte/64-bit writes
#define FLASH_RESERVE (2*FLASH_SECTOR_SIZE) // reserve top of flash
#define FLASH_BASE_ADDR (0) // code starts here
#elif defined(__IMXRT1062__) && defined(ARDUINO_TEENSY40)
#define FLASH_ID "fw_teensy40" // target ID (in code)
#define FLASH_SIZE (0x200000) // 2MB program flash
#define FLASH_SECTOR_SIZE (0x1000) // 4KB sector size
#define FLASH_WRITE_SIZE (4) // 4-byte/32-bit writes
#define FLASH_RESERVE (4*FLASH_SECTOR_SIZE) // reserve top of flash
#define FLASH_BASE_ADDR (0x60000000) // code starts here
#elif defined(__IMXRT1062__) && defined(ARDUINO_TEENSY41)
#define FLASH_ID "fw_teensy41" // target ID (in code)
#define FLASH_ID_LEN (11) // target ID (in code)
#define FLASH_SIZE (0x800000) // 8MB
#define FLASH_SECTOR_SIZE (0x1000) // 4KB sector size
#define FLASH_WRITE_SIZE (4) // 4-byte/32-bit writes
#define FLASH_RESERVE (4*FLASH_SECTOR_SIZE) // reserve top of flash
#define FLASH_BASE_ADDR (0x60000000) // code starts here
#elif defined(__IMXRT1062__) && defined(ARDUINO_TEENSY_MICROMOD)
#define FLASH_ID "fw_teensyMM" // target ID (in code)
#define FLASH_SIZE (0x1000000) // 16MB
#define FLASH_SECTOR_SIZE (0x1000) // 4KB sector size
#define FLASH_WRITE_SIZE (4) // 4-byte/32-bit writes
#define FLASH_RESERVE (4*FLASH_SECTOR_SIZE) // reserve top of flash
#define FLASH_BASE_ADDR (0x60000000) // code starts here
#else
#error MCU NOT SUPPORTED
#endif
#if defined(FLASH_ID)
#ifdef USE_RAM_FOR_FLASHING
#define RAM_BUFFER_SIZE ((USE_RAM_FOR_FLASHING) * 1024)
#else
#define RAM_BUFFER_SIZE (0*1024)
#endif
#define IN_FLASH(a) ((a) >= FLASH_BASE_ADDR && (a) < FLASH_BASE_ADDR + FLASH_SIZE)
#endif
// reboot is the same for all ARM devices
#define CPU_RESTART_ADDR ((uint32_t *)0xE000ED0C)
#define CPU_RESTART_VAL (0x5FA0004)
#define REBOOT (*CPU_RESTART_ADDR = CPU_RESTART_VAL)
#define NO_BUFFER_TYPE (0)
#define FLASH_BUFFER_TYPE (1)
#define RAM_BUFFER_TYPE (2)
// apparently better - thanks to Frank Boesing
#define RAMFUNC __attribute__ ((section(".fastrun"), noinline, noclone, optimize("Os") ))
#if defined(KINETISK) || defined(KINETISL)
// T3.x flash primitives (must be in RAM)
RAMFUNC int flash_word( uint32_t address, uint32_t value, int aFSEC, int oFSEC );
RAMFUNC int flash_phrase( uint32_t address, uint64_t value, int aFSEC, int oFSEC );
RAMFUNC int flash_erase_sector( uint32_t address, int aFSEC );
RAMFUNC int flash_sector_not_erased( uint32_t address );
// Cache control functions for T3.6 only
#if defined(__MK66FX1M0__)
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
*/
void LMEM_EnableCodeCache(bool enable);
void LMEM_CodeCacheInvalidateAll(void);
void LMEM_CodeCachePushAll(void);
void LMEM_CodeCacheClearAll(void);
#endif // __MK66FX1M0__
#elif defined(__IMXRT1062__)
RAMFUNC int flash_sector_not_erased( uint32_t address );
// from cores\Teensy4\eeprom.c -- use these functions at your own risk!!!
void eepromemu_flash_write(void *addr, const void *data, uint32_t len);
void eepromemu_flash_erase_sector(void *addr);
void eepromemu_flash_erase_32K_block(void *addr);
void eepromemu_flash_erase_64K_block(void *addr);
#endif // __IMXRT1062__
// functions used to move code from buffer to program flash (must be in RAM)
RAMFUNC void flash_move( uint32_t dst, uint32_t src, uint32_t size );
// functions that can be in flash
int flash_write_block( uint32_t addr, char *data, uint32_t count );
int flash_erase_block( uint32_t address, uint32_t size );
int check_flash_id( uint32_t buffer, uint32_t size );
int firmware_buffer_init( uint32_t *buffer_addr, uint32_t *buffer_size );
void firmware_buffer_free( uint32_t buffer_addr, uint32_t buffer_size );
#endif // _FLASHTXX_H_