1+ #include < cstdint>
2+ #include " flash_os.hpp"
3+
4+ /* *
5+ * @brief Smallest amount of data that can be programmed
6+ *
7+ * <PageSize> = 2 ^ Shift. Shift = 3 => <PageSize> = 2^3 = 8 bytes
8+ *
9+ */
10+ #define PAGE_SIZE_SHIFT (2 )
11+
12+ /* *
13+ * @brief If value is false the device does not support native read. This
14+ * makes the loader use the read function instead of using memory mapped
15+ * io.
16+ *
17+ */
18+ #define NATIVE_READ (false )
19+
20+ /* *
21+ * @brief Marks if the device supports a chip erase. This can speed up erasing
22+ * a chip.
23+ *
24+ */
25+ #define CHIP_ERASE (false )
26+
27+ /* *
28+ * @brief If value is true only uniform sectors are allowed on the device.
29+ * Speeds up erasing as it can erase multiple sectors at once.
30+ *
31+ */
32+ #define UNIFORM_SECTORS (true )
33+
34+ /* *
35+ * @brief Sector size shift for when using uniform sector erase
36+ *
37+ * <SectorSize> = 2 ^ Shift. Shift = 12 => <SectorSize> = 2 ^ 12 = 4096 bytes
38+ *
39+ */
40+ #define SECTOR_SIZE_SHIFT (2 )
41+
42+ /* *
43+ * @brief Device specific infomation
44+ *
45+ */
46+ extern " C" {
47+ const __attribute__ ((section(" DevDscr" ), __used__)) flash_device FlashDevice = {
48+ flash_drv_version, // driver version
49+ " test device" , // device name
50+ device_type::on_chip, // device type
51+ 0xA0000000 , // base address
52+ 0x00000400 , // flash size
53+ 4 , // page size
54+ 0 , // reserved
55+ 0xff , // blank value
56+ 100 , // page program timeout
57+ 3000 , // sector erase timeout
58+
59+ // flash sectors
60+ {
61+ {0x00000400 , 0x00000000 },
62+ end_of_sectors
63+ }
64+ };
65+ }
66+
67+ // function overrides when parts are not in use
68+ #if NATIVE_READ
69+ #define VERIFY_FUNC nullptr
70+ #define BLANK_CHECK_FUNC nullptr
71+ #define OPEN_READ_FUNC nullptr
72+ #else
73+ #define VERIFY_FUNC Verify
74+ #define BLANK_CHECK_FUNC BlankCheck
75+ #define OPEN_READ_FUNC SEGGER_OPEN_Read
76+ #endif
77+
78+ #if CHIP_ERASE
79+ #define CHIP_ERASE_FUNC EraseChip
80+ #else
81+ #define CHIP_ERASE_FUNC nullptr
82+ #endif
83+
84+ #if UNIFORM_SECTORS
85+ #define UNIFORM_ERASE_FUNC SEGGER_OPEN_Erase
86+ #else
87+ #define UNIFORM_ERASE_FUNC nullptr
88+ #endif
89+
90+ /* *
91+ * @brief array with all the functions for the segger software
92+ *
93+ */
94+ extern " C" {
95+ const uint32_t SEGGER_OFL_Api[13 ] __attribute__ ((section (" PrgCode" ), __used__)) = {
96+ reinterpret_cast <uint32_t >(FeedWatchdog),
97+ reinterpret_cast <uint32_t >(Init),
98+ reinterpret_cast <uint32_t >(UnInit),
99+ reinterpret_cast <uint32_t >(EraseSector),
100+ reinterpret_cast <uint32_t >(ProgramPage),
101+ reinterpret_cast <uint32_t >(BLANK_CHECK_FUNC),
102+ reinterpret_cast <uint32_t >(CHIP_ERASE_FUNC),
103+ reinterpret_cast <uint32_t >(VERIFY_FUNC),
104+ reinterpret_cast <uint32_t >(nullptr ), // SEGGER_OPEN_CalcCRC
105+ reinterpret_cast <uint32_t >(OPEN_READ_FUNC),
106+ reinterpret_cast <uint32_t >(SEGGER_OPEN_Program),
107+ reinterpret_cast <uint32_t >(UNIFORM_ERASE_FUNC),
108+ reinterpret_cast <uint32_t >(nullptr ), // SEGGER_OPEN_Start for turbo mode
109+ };
110+ }
111+
112+ void __attribute__ ((noinline)) FeedWatchdog(void ) {
113+ // TODO: implement something to keep the watchdog happy
114+ return ;
115+ }
116+
117+ int __attribute__ ((noinline)) Init(const uint32_t address, const uint32_t frequency, const uint32_t function) {
118+ // TODO: implement init
119+
120+ return 0 ;
121+ }
122+
123+ int UnInit (const uint32_t function) {
124+ // TODO: implement uninit
125+
126+ return 0 ;
127+ }
128+
129+ int __attribute__ ((noinline)) EraseSector(const uint32_t sector_address) {
130+ // TODO: implement sector erase
131+
132+ return 0 ;
133+ }
134+
135+ int __attribute__ ((noinline)) ProgramPage(const uint32_t address, const uint32_t size, const uint8_t *const data) {
136+ // TODO: implement program page
137+
138+ return 0 ;
139+ }
140+
141+ int __attribute__ ((noinline)) SEGGER_OPEN_Program(uint32_t address, uint32_t size, uint8_t *data) {
142+ // get the amount of pages to write
143+ const uint32_t pages = size >> PAGE_SIZE_SHIFT;
144+
145+ for (uint32_t i = 0 ; i < pages; i++) {
146+ // program a page
147+ int r = ProgramPage (address + (i * PAGE_SIZE_SHIFT), (0x1 << PAGE_SIZE_SHIFT), &data[i * PAGE_SIZE_SHIFT]);
148+
149+ // check if something went wrong
150+ if (r) {
151+ // return a error
152+ return 1 ;
153+ }
154+ }
155+
156+ // return everything went oke
157+ return 0 ;
158+ }
159+
160+ #if CHIP_ERASE == true
161+ int EraseChip (void ) {
162+ // TODO: implement chip erase
163+ return 0 ;
164+ }
165+ #endif
166+
167+ #if UNIFORM_SECTORS
168+ int SEGGER_OPEN_Erase (uint32_t SectorAddr, uint32_t SectorIndex, uint32_t NumSectors) {
169+ // feed the watchdog
170+ FeedWatchdog ();
171+
172+ for (uint32_t i = 0 ; i < NumSectors; i++) {
173+ // erase a sector
174+ int r = EraseSector (SectorAddr);
175+
176+ // check for errors
177+ if (r) {
178+ // return we have a error
179+ return 1 ;
180+ }
181+ }
182+
183+ // return everything went oke
184+ return 0 ;
185+ }
186+ #endif
187+
188+ #if !NATIVE_READ
189+ uint32_t Verify (uint32_t Addr, uint32_t NumBytes, uint8_t *pBuff) {
190+ // TODO: implement verify
191+
192+ return 0 ;
193+ }
194+
195+ int __attribute__ ((noinline)) BlankCheck(const uint32_t address, const uint32_t size, const uint8_t blank_value) {
196+ // TODO: implement blankcheck
197+
198+ return 0 ;
199+ }
200+
201+ int SEGGER_OPEN_Read (const uint32_t address, const uint32_t size, uint8_t *const data) {
202+ // TODO: add read implementation
203+
204+ return size;
205+ }
206+ #endif
0 commit comments