Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error Fixes #509

Merged
merged 4 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/check-links.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ jobs:
uses: gaurav-nelson/github-action-markdown-link-check@v1
with:
use-verbose-mode: yes
config-file: './.github/workflows/mlc_config.json'
4 changes: 4 additions & 0 deletions .github/workflows/compile-examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ jobs:
-
verbose: false
enable-deltas-report: true
github-token: ${{ secrets.GITHUB_TOKEN }}
enable-warnings-report: true
sketches-report-path: sketches-reports
- name: Compile examples (overclocked to the max, tcb1 millis, minimal printf, old attachInterrupt, full appspm)
Expand Down Expand Up @@ -376,6 +377,7 @@ jobs:
-
verbose: false
enable-deltas-report: true
github-token: ${{ secrets.GITHUB_TOKEN }}
enable-warnings-report: true
sketches-report-path: sketches-reports
- name: Compile examples (20 MHz, disable millis, sized appspm, flmap L0, wire mors)
Expand All @@ -401,6 +403,7 @@ jobs:
-
verbose: false
enable-deltas-report: true
github-token: ${{ secrets.GITHUB_TOKEN }}
enable-warnings-report: true
sketches-report-path: sketches-reports
- name: Compile examples (8 MHz, optiboot (if available), tca0 millis, full printf, and manual attachInterrupt)
Expand Down Expand Up @@ -428,5 +431,6 @@ jobs:
-
verbose: false
enable-deltas-report: true
github-token: ${{ secrets.GITHUB_TOKEN }}
enable-warnings-report: true
sketches-report-path: sketches-reports
3 changes: 3 additions & 0 deletions .github/workflows/mlc_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"aliveStatusCodes": [429, 403, 200]
}
6 changes: 3 additions & 3 deletions megaavr/boards.txt
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ avrdb.name=AVR DB-series (no bootloader)
avrdd.name=AVR DD-series (no bootloader)
#avrdu.name=AVR DU-series (no bootloader)
avrea.name=AVR EA-series (no bootloader)
avreb.name=AVR EB-series (no bootloader)
#avreb.name=AVR EB-series (no bootloader)
avrdaopti.name=AVR DA-series (Optiboot)
avrdbopti.name=AVR DB-series (Optiboot)
avrddopti.name=AVR DD-series (Optiboot)
Expand Down Expand Up @@ -2512,8 +2512,8 @@ avrdaopti.menu.bootloaderusart.ser5_alt.bootloader.port=_ser5_alt
avrdaopti.menu.bootloaderusart.ser5_alt.bootloader.portname=Serial5
avrdaopti.menu.bootloaderusart.ser5_alt.bootloader.portswap=1

avrdaopti.menu.bootloadermode.turbo=Optiboot Dx Turbo
avrdaopti.menu,bootloadermode.compatible=Optiboot Dx not-turbo
#avrdaopti.menu.bootloadermode.turbo=Optiboot Dx Turbo
#avrdaopti.menu.bootloadermode.compatible=Optiboot Dx not-turbo

##########################################################################
# #
Expand Down
6 changes: 3 additions & 3 deletions megaavr/libraries/EEPROM/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ void loop() {

```

The library provides a global variable named `EEPROM`, you use this variable to access the library functions (As of library verspm 2.1.4 we have eliminated unused variable warnings. The methods provided in the EEPROM class are listed below.
The library provides a global variable named `EEPROM`, you use this variable to access the library functions (As of library version 2.1.4 we have eliminated unused variable warnings. The methods provided in the EEPROM class are listed below.


## EEPROM Sizes
Expand All @@ -51,7 +51,7 @@ The library provides a global variable named `EEPROM`, you use this variable to
Specifying an address beyond the size of the EEPROM will wrap around to the beginning. The addresses passed to EEPROM functions are a `uint8_t` (aka byte) on parts with up to 256b of flash and a `uint16_t` (word or unsigned int) on parts with more.


You can view all the examples [here](examples/); disclosure and disclaimer I did not write the examples, and and have some doubts
You can view all the examples [here](examples/); disclosure and disclaimer I did not write the examples, and have some doubts

## Warning: Using EEPROM right at startup
On the modern tinAVR devices (but not with any Dx-series parts) we have received at multiple reports from users of erratic failures to correctly interact with the EEPROM immediately upon startup. There is considerable evidence that the cause of the problem was a slow-rising power supply, coupled with the specific brownout detection configuration. This issue is still not entirely understood, but it is suspected that it ends up doing the write very close to it's minimum voltage, when the chip may be running out of spec because the chip had by that point switched to it's full clock speed (and BOD is forced on during NVMCTRL operations. Try to avoid writing to the EEPROM immediately upon startup - maybe pick a longer SUT (startup tme), or simply wait until later into execution to perform the write, etc. Many times the impacted individuals found that even a delay of a few milliseconds was sufficient to ensure that it worked (Issue #452). A more rigorous approach is to measure the voltage before writing and make sure it is within the intended operational range.
Expand Down Expand Up @@ -182,7 +182,7 @@ During an Interrupt Service Routine (ISR), like a function that is executed as a
#### On DxCore and with the current version
This library verifies that there is no EEPROM write in progress, disables interrupts, and then writes to the EEPROM and restores SREG turning interrupts back on unless they were already disabled globally. Hence, there will never be any millis time lost when writing a single byte, nor when writing more than one byte at a time (ex, using put with a multibyte value) outside of an ISR. Put simply it now cannot happen if all EEPROM writes are made from a normal (non-interrupt, interrupts not disabled) context. If the main application is writing to the EEPROM and, an extremely poorly timed interrupt that *also* writes to the EEPROM is triggered within an extremely narrow window, this could result in losing up to 10ms (DxCore, if we trust the 11ms figure) or 3ms (megaTinyCore) (this window is around 3 clock cycles, in the middle of EEPROM.write() between when we check the NVMCTRL.STATUS, and when we disable interrupts).

When more than 1 byte is written from a single interrupt (regardless of whether the bytes are done as part of a larger value or not), it will always lose time - up to 11ms or 4ms per byte after the first, less 1-2 times the millis resolution (typically 1ms, see the detailed [timer usage documentation](https://) for details).
When more than 1 byte is written from a single interrupt (regardless of whether the bytes are done as part of a larger value or not), it will always lose time - up to 11ms or 4ms per byte after the first, less 1-2 times the millis resolution (typically 1ms, see the detailed [timer usage documentation](https://github.com/SpenceKonde/DxCore/blob/master/megaavr/extras/Ref_Timers.md) for details).

Regardless of whether it was caused by an interrupt writing more than one byte, or an interrupt that writes one byte happening while the main code is attempting to write to the EEPROM, it will impact both millis() and micros(), but will never produce backwards time travel relative to values from before the interrupt fired. Immediately upon that interrupt and hence interrupts becoming available again, the millis timekeeping interrupt will fire and try to sort things out, and micros will jump ahead by the millis resolution (ie, by 1000 if millis resolution is 1ms, regardless of how long it was blocked from running while the EEPROM-writing interrupt was running), and timekeeping will proceed normally.

Expand Down
2 changes: 1 addition & 1 deletion megaavr/libraries/EEPROM/library.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ version=2.1.4
author=Arduino, Christopher Andrews, Spence Konde
maintainer=Spence Konde <spencekonde@gmail.com>
sentence=Enables reading and writing to the permanent board storage.
paragraph=This library allows to read and write data in the on-chip EEPROM. EEPROM memory contents are not lost when the board is reset or powercycled, and is optionally retained even when a new sketch is uploaded (when using Optiboot, uploading new code never erases the EEPROM). The amount of on-chip EEPROM available depends on the microcontroller. External EEPROM chips are available, but those must use a different library (ex, 24-series I2C EEPROM and 25-series SPI EEPROM - both families made by over a dozen companies with similar part numbers and nearly identical specs. I prefer the I2C ones).<br/>2.1.4 - Fix spurrious warning if EEPROM libray is used eithout referemce to EEPROM. 2.1.3 - 2.1.2's changes to eliminate differences between DxCore and megaTinyCore went too far, and broke support for parts with >256b of EEPROM, this is corrected. 2.1.2 - harmonize code with DxCore, replace eeprom_write_byte() with hand-reimplementation to correct theoretical weakness that could cause EEPROM corruption if interrupts were not disabled and millis timekeeping drift if they were. Correct formatting and generalize examples. Examples no longer depend on 0 being a valid analog pin; we use A7 (PIN_PA7 on tinyAVR, PIN_PD7 on Dx/Ex) which is available on 0/1/2-series as well as all pincounts of all current and announced modern AVR (AVRxt) parts. 2.1.1 - Ensure that indexes beyond the end wrap correctly. 2.1 - Port to DxCore; avr-libc eeprom write functions were busted.
paragraph=This library allows reading and writing data to the on-chip EEPROM. EEPROM memory contents are not lost when the board is reset or power-cycled, and is optionally retained even when a new sketch is uploaded (when using Optiboot, uploading new code never erases the EEPROM). The amount of on-chip EEPROM available depends on the microcontroller. External EEPROM chips are available, but those must use a different library (ex, 24-series I2C EEPROM and 25-series SPI EEPROM - both families made by over a dozen companies with similar part numbers and nearly identical specs. I prefer the I2C ones).<br/>2.1.4 - Fix spurious warning if EEPROM library is used eithout reference to EEPROM. 2.1.3 - 2.1.2's changes to eliminate differences between DxCore and megaTinyCore went too far, and broke support for parts with >256b of EEPROM, this is corrected. 2.1.2 - harmonize code with DxCore, replace eeprom_write_byte() with hand-reimplementation to correct theoretical weakness that could cause EEPROM corruption if interrupts were not disabled and millis timekeeping drift if they were. Correct formatting and generalize examples. Examples no longer depend on 0 being a valid analog pin; we use A7 (PIN_PA7 on tinyAVR, PIN_PD7 on Dx/Ex) which is available on 0/1/2-series as well as all pincounts of all current and announced modern AVR (AVRxt) parts. 2.1.1 - Ensure that indexes beyond the end wrap correctly. 2.1 - Port to DxCore; avr-libc eeprom write functions were busted.
category=Data Storage
url=https://docs.arduino.cc/learn/built-in-libraries/eeprom
architectures=megaavr
2 changes: 1 addition & 1 deletion megaavr/libraries/EEPROM/src/EEPROM.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,5 +268,5 @@ struct EEPROMClass {
}
};

static EEPROMClass __attribute__ ((unused) EEPROM;
static EEPROMClass __attribute__((unused)) EEPROM;
#endif
Loading