-
Notifications
You must be signed in to change notification settings - Fork 305
/
FlashPROM.cpp
53 lines (41 loc) · 1.59 KB
/
FlashPROM.cpp
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
/*
* SPDX-License-Identifier: MIT
* SPDX-FileCopyrightText: Copyright (c) 2021 Jason Skuby (mytechtoybox.com)
*/
#include "FlashPROM.h"
uint8_t FlashPROM::writeCache[EEPROM_SIZE_BYTES];
volatile static alarm_id_t flashWriteAlarm = 0;
volatile static spin_lock_t *flashLock = nullptr;
int64_t writeToFlash(alarm_id_t id, void *flashCache)
{
while (is_spin_locked(flashLock));
multicore_lockout_start_blocking();
uint32_t interrupts = spin_lock_blocking(flashLock);
flash_range_erase((intptr_t)EEPROM_ADDRESS_START - (intptr_t)XIP_BASE, EEPROM_SIZE_BYTES);
flash_range_program((intptr_t)EEPROM_ADDRESS_START - (intptr_t)XIP_BASE, reinterpret_cast<uint8_t *>(flashCache), EEPROM_SIZE_BYTES);
flashWriteAlarm = 0;
multicore_lockout_end_blocking();
spin_unlock(flashLock, interrupts);
return 0;
}
void FlashPROM::start()
{
if (flashLock == nullptr)
flashLock = spin_lock_instance(spin_lock_claim_unused(true));
memcpy(writeCache, reinterpret_cast<uint8_t *>(EEPROM_ADDRESS_START), EEPROM_SIZE_BYTES);
}
/* We don't have an actual EEPROM, so we need to be extra careful about minimizing writes. Instead
of writing when a commit is requested, we update a time to actually commit. That way, if we receive multiple requests
to commit in that timeframe, we'll hold off until the user is done sending changes. */
void FlashPROM::commit()
{
while (is_spin_locked(flashLock));
if (flashWriteAlarm != 0)
cancel_alarm(flashWriteAlarm);
flashWriteAlarm = add_alarm_in_ms(EEPROM_WRITE_WAIT, writeToFlash, writeCache, true);
}
void FlashPROM::reset()
{
memset(writeCache, 0, EEPROM_SIZE_BYTES);
commit();
}