Skip to content

Commit

Permalink
L I N T LINT LINT
Browse files Browse the repository at this point in the history
  • Loading branch information
SpenceKonde committed Oct 3, 2023
1 parent 3cc0e11 commit 58580c2
Show file tree
Hide file tree
Showing 33 changed files with 127 additions and 72 deletions.
2 changes: 1 addition & 1 deletion ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ Changes listed here are checked in to GitHub ("master" branch unless specificall
* Performance enhancement: From @MX682X, the discovery that an appropriately timed kick to the compiler's groin would cause it to place pointers into base registers when it otherwise would not. Doing this increases efficiency dramatically in some cases, allowing the use of load and store with displacement in several places where it had previously used a truckload of LDS and/or STS instructions. This resulted in smaller, faster binaries due to more efficient initialiaation code for a number of peripherals (which impacted even users who weren't doing anything special, since the biggest beneficiaries were the ADC and timer initialization code, which happen as long as main() is not overridden). This also includes the addition of a number of macros to implement such kicks to permit this method to be readily generalized if other areas of the core are found which could benefit from it.
* Organizational enhancement: Move all of the dirty performance enhancement macros like the ones above from Arduino.h to newly added dirty_tricks.h. Change names of many macros to make them easier to type. Document these functions in [the dirty_tricks reference](megaavr/extras/Ref_dirty_tricks.md).
* Docs: General day-to-day maintenance
* Add what little support was needed for analogWrite() to work if there were tools submenu to use differerent subsets of pins to wiring_analog.c. Varaiant files however still require significant work, however!
* Add what little support was needed for analogWrite() to work if there were tools submenu to use differerent subsets of pins to wiring_analog.c. Variant files however still require significant work, however!

#### Known issues
* Optimization level menu is not displayed.
Expand Down
2 changes: 1 addition & 1 deletion ContributionGuidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ Some general themes of these decisions others may disagree with:
## Azduino Code Style
We have a largely self-consistent code style used throughout the core and associated files based on a number of principles.

1. Readbility is paramount, and if adhering to particular code styling guidelines would result in hideous looking unreadable code, don't do it.
1. Readability is paramount, and if adhering to particular code styling guidelines would result in hideous looking unreadable code, don't do it.
a. astyle is only run in libraries and variants, not the core itself because it would need to be disabled on all files anyway.
2. Always use the integer types that explicitly specify the datatype size. That means, avoid 'int' 'byte' 'char' 'long' etc. Types should be things like:

Expand Down
31 changes: 23 additions & 8 deletions README.md

Large diffs are not rendered by default.

40 changes: 35 additions & 5 deletions megaavr/bootloaders/hex/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,43 @@
# Here live the bootloader hex files.
# Here live the bootloader hex files

## .lst and .elf files

Additionally, there is a tar'ed BZip'ed copy of all the assembly listings and elf files produced compiling all of these bootloaders, these are in listings.tar.bz2 and elves.tar.bz2.
We include .lst files, and the .elf files in case you for some strange reason need them, these are in listings.tar.bz2 and elves.tar.bz2.

## megaAVR 0-series parts

There is a tar'ed bzipped archive containing bootloaders for the mega0-series built to the same specifications

## Build logs
Build logs are now included - both normal output and error output.

## Filename encoding
The filenames consist of three or four sections, separated by an _

* "optiboot" - identifies the bootloader
* A string identifying the chip or board:
* "txyz": Any 0/1-series tinyAVR except the 8-pin ones.
* "txy2": Any 0/1-series tinyAVR with 8 pins.
* "tx2z": Any 2-series tinyAVR
* If it is set to use anything other than USART0 on default pins, a third parameter appears here:
* (omitted): USART0, default mapping.
* "alt": USART0, alternate mapping.
* "u1alt": USART1, alternate mapping.
* There is no option to use USART1 on default mapping, because the default USART1 mapping is the same as the alternate USART0 mapping.
* Finally the entry conditions are described:
* "extr": Upon external, software, or UPDI reset (UPDI reset means you just uploaded the bootloader (most likely) so you'd like to see the bootloader run so you know it's there).
* "extr8sec": As above, but wait 8 seconds for upload.
* "extronly": Only upon external or UPDI reset. Note that this requires that you configure fuses to have a reset pin or it won't be much fun.
* "poronly8sec: POR or UPDI reset only, and wait 8 seconds (for plug/unplug to enter bootloader)
* "all8sec": Maximum ease of bootloader entry. Enter bootloader on any reset, except for a WDR (which is impossible for technical reasons), or a BOR (indicative of an unstable power supply. That's not when you want to be writing to flash is it?), 8 second wait.
* "swronly8sec": Only upon a software or UPDI reset, 8 second timeout. Note that this fails to adhere to the prime directive. An application which does not fire a software reset will not enter the bootloader after the first time it was programmed, however, there are a surprising number of people who are doing weird stuff like that, and are okay with the possible need to take drastic actions (some of them have failsafes in their sketch)


## What is that technical reason?
Optiboot exits using the WDR to make sure everything is cleanly reset for app - since only the RSTRF persists across reset and we can only clear the bits never set them, there is no way to tell if a WDRF came from itself or the app, and so, since assuming it was from the app would result in the bootloader never exiting.

## Related to above
Since a startup *without* a hardware reset is guaranteed not to work (GNTW), and means that the prime directive of a bootloader is violated ("Survive any behavior that the application could manifest, no matter how perverse."), because an application that smashes the stack, or fires an interrupt that doesn't exist, or manually jumps to 0 would end up at 0, and the bootloader (in order to fit in flash) assumes the chip is in reset state (ie, that it is clocked at 3.33 MHz or 2.66 MHz, and that the USART is not currently enabled and so on). Hence we have no choice but to ensure that we can detect that case and fire an SWR to reset cleanly (likely into the bootloader) when we start up with no reset flags. Jumping to 0x0000 is prohibited.

Build logs are now included of both normal output and error output.
The minimum needed to avoid GNTW behavior without removing any functionality is what we implement:
* Either in the bootloader or if none is used, the start of the application, we must read the reset flags.
* If they are zero, we must issue a software reset.
* If it's not an entry condition, we clear the flags, write the value they held to GPIOR0 (so the app can see them without hving to fish something our of r2, which cannot be guaranteed to even be possible for any given sketch; this method minimizes the cost, and since we never *read* GPIO0, you may freely trash the value in it if you don't need the reset cause flags.)
Binary file removed megaavr/bootloaders/hex/mega0.tar
Binary file not shown.
Binary file added megaavr/bootloaders/hex/mega0.tar.bz2
Binary file not shown.
2 changes: 1 addition & 1 deletion megaavr/cores/megatinycore/Arduino.h
Original file line number Diff line number Diff line change
Expand Up @@ -912,7 +912,7 @@ inline __attribute__((always_inline)) void check_valid_digital_pin(pin_size_t pi
// Microchip can add one more binary option >.> */


/* External defintitions */
/* External definitions */
/* Actual implementation is in wiring_extra.c (or .cpp, if I find that I'm not able tomake it work with .c)
* Because of the incrutable rules of C++ scoping, you can define an inline function or a template function in a header....
* and not in the body of a separate file, while the opposite is true for ANY OTHER KIND OF FUNCTION. */
Expand Down
2 changes: 1 addition & 1 deletion megaavr/cores/megatinycore/HardwareSerial.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
* is atomic, but significantly hurts performance. (theoretical worst case
* is 94 clocks, real-world is usually far less, but I'll only say "less"
* The functions in question have considerable register pressure). But,
* it unquestionably would impact USART performance at high speeeds.
* it unquestionably would impact USART performance at high speeds.
*
* * The USE_ASM_* options can be disabled by defining them as 0 either in variant pins_arduino.h
* The buffer sizes can be overridden in by defining SERIAL_TX_BUFFER either in variant file (
Expand Down
2 changes: 1 addition & 1 deletion megaavr/cores/megatinycore/WInterrupts.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@
* For each of the ones that we do have a flag for, we load that pointer into Z with postincrement, subtract 0 from it and look at zero flag to make sure it's not null.
* assuming it's not, we fire icall to call the user function. Either way we then repeat the loop until out of flags.
* which at latest will happen when we're also at end of the ports intfunc array....
* Then, with the initial flags still in 15 and the the VPORT adderess in r16 copy that once more to a pointer register, 0 the high byte, and store the flags value we read to clear it.
* Then, with the initial flags still in 15 and the the VPORT address in r16 copy that once more to a pointer register, 0 the high byte, and store the flags value we read to clear it.
* then it's just a matter of making sure we pop everything we pushed onto the stack in the reverse order, including r16 followed by the reti to exit the interrupt..
*/

Expand Down
4 changes: 2 additions & 2 deletions megaavr/cores/megatinycore/WInterrupts_PA.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
intFunc[0] = intFunc_A;
}
/* It is the act of referencing attachPortAEnable() in this file that the compiler to also include the ISR.
* (ISRs can't be asssigned at runtime - the only way things like attachInterruprt look like they can is
* (ISRs can't be assigned at runtime - the only way things like attachInterruprt look like they can is
* by having the ISR call a function pointer (ie, icall). After saving every call used plus SREG and RAMPZ.
* Beyond being slow, these lengthy prologues and epilogs slow take up flash. This can be like 80+ bytes
* per vector... That's ugly, particlarly on small flash parts. See the discussion in WInterrupts.c about
* per vector... That's ugly, particularly on small flash parts. See the discussion in WInterrupts.c about
* what this actually does.
*/
ISR(PORTA_PORT_vect, ISR_NAKED) {
Expand Down
2 changes: 1 addition & 1 deletion megaavr/cores/megatinycore/core_devices.h
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@
* Provide a define indicating which revision of EVSYS this is. 1 and 2 differ only in naming of strobe register.
* 3 separates the decision of which pin(s) within a port will be used as event input and which of those to use
* with the former being configured with PORTx.EVGENCTRL. This allows the number of generators to drop from 8/port to 2/port, and the number of RTC generators to likewise drop to 2 from 16 with 8 available per channel
* In exchange for this, we achieve our longtime dream: Equality between all generator channels, because the redused number of
* In exchange for this, we achieve our longtime dream: Equality between all generator channels, because the reduced number of
* generators allows them to add both options for all ports and both RTC options to all generator channels
* Too bad they released so many parts with the other versions :-/ */

Expand Down
4 changes: 2 additions & 2 deletions megaavr/cores/megatinycore/dirty_tricks.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
*
* Many of these hinge upon bullying the compiler into assigning registers less stupidly. These do not at all prevent the register allocator from
* smacking down the whole thing with a gigantic wad of fail if it thinks it has to (ie, when you're out of pointer registers). These should be used only with one eye
* on the compiler listings to spot this, because at that point they are usually causeing harm instead of good.
* on the compiler listings to spot this, because at that point they are usually causing harm instead of good.
*
* List of dirty trick macros
* Not dirty - cycle counting macros:
Expand Down Expand Up @@ -306,7 +306,7 @@ Not enabled. Ugly ways to get delays at very small flash cost.
*
* Very similar to the above. Passed a pointer as two bytes, the high byte constant and the low byte not, this finds use in the same sort
* of situatios as high/low math. See the I/O headers: each class of peripherals often has the same high byte for all addresses. Ports (0x0400, 0x0420, 0x0440
* and so on. The most freqently used functions get special attention paid to this as a small gain adds up for the most commonly called functions
* and so on. The most frequently used functions get special attention paid to this as a small gain adds up for the most commonly called functions
* usage is typically sdmething like
* lowbyte = (_SWAP(usartnbr)); // passed from,elsewhere io the code, which must be free of bugs!
* lowbyte <<= 1;
Expand Down
2 changes: 1 addition & 1 deletion megaavr/cores/megatinycore/wiring_analog.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ void DACReference(__attribute__ ((unused))uint8_t mode) {
* uint8_t gain=0)
* Enhanced analogRead(). Still single-ended, res is resolution in bits,
* which range from 8 to the largest value that can be obtained from using
* the accumlation feature and a single "start" command to oversample x4
* the accumulation feature and a single "start" command to oversample x4
* per extra bit, followed by decimation/2 per extra bit (the math is
* described in Microchip/Atmel app notes). This maximum is 13 bits for
* 0/1-series parts, and 17 bits for 2-series parts.
Expand Down
2 changes: 1 addition & 1 deletion megaavr/extras/Ref_BestPractices.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Before deployment, be sure to run down this checklist for any circuit you design
* Assuming this is a custom PCB, fill both layers with ground pours. Tie the two ground pours together with vias.
* To avoid delays, make sure you can get all the parts you're using. Order the parts you need ASAP if they seem to be in short supply (almost everything is now)
* Read the bloody errata, especially if on a DA, DB, or tiny 0/1. Those things have many relevant errata.
* Choose pins wisely. Make a list of how many pins you need with what functionality. Depending on your application pins 2 and 6 in each port may need to be valued differently, as they can respond to very brief interrupts and wake the chip on rising/failling because they are "fully async" - however, they are more vulnerable to electromagnetic noise for the same reason.
* Choose pins wisely. Make a list of how many pins you need with what functionality. Depending on your application pins 2 and 6 in each port may need to be valued differently, as they can respond to very brief interrupts and wake the chip on rising/failing because they are "fully async" - however, they are more vulnerable to electromagnetic noise for the same reason.
* Determining the crystal loading a priori can be very difficult - you need to knowe stray capacitances (which you almost certainly don't have a tool precise enough to measure) and the whole thing is full of black magic. On the classic AVRs, the crystals were power hogs, but it wasn't hard to make them work. Now, they may not be power hogs, but short of very expensive, high precision lab equipment (you need a FET probe for your scope, which I was told cost in the area of 1 grand, and even the soldering to get the adjustable caps on insstead of normal ones can be a job. People argue over what the rule of thumb is (if you ask around, you'll get three different answers, the largest at least 4x the smallest). I have been unable to determine why a given capacitor value (which by all accounts should not have worked, did, while all the other values (which were closer to what the formulas said) wouldn't oscillate). The only thing I can suggest is to get an assortment of small caps in the appropriate range of values, and then use trial and error to find a good working value (unless you have an incredibly well outfitted lab).
* If a voltage in excess of Vdd or below ground might ever be applied to any pin, you MUST take measures to limit the current and ensure that it stays within the range given in the datasheet. Often this can be achieved with a

Expand Down
2 changes: 1 addition & 1 deletion megaavr/extras/Ref_Defines.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ If your sketch requires a certain timer NOT be used for millis, or that a certai
```

### Testing if millis enabled
The names of these two functions are #defined as themselves if the function can be used. On DxCore, `millis` is never defined if `micros` is not, since there are no timekeeping options which suppory millis but not micros. On megaTinyCore, if the RTC is used, millis, but not micros, will be available, so `defined(micros)` is false but `defined(millis)` is true.
The names of these two functions are #defined as themselves if the function can be used. On DxCore, `millis` is never defined if `micros` is not, since there are no timekeeping options which support millis but not micros. On megaTinyCore, if the RTC is used, millis, but not micros, will be available, so `defined(micros)` is false but `defined(millis)` is true.

## Identifying part family within sketch
When writing code that may be compiled for a variety of target chips, it is often useful to detect which chip it is running on.Defines of the form `__AVR_partname__` are provided by the toolchain. However, it is often MORE useful to not have to have a giant block of #ifdefs, and have the part numbers distilled down to something more that can be checked more intuitively, since what you care about is the family, number of pins, or occasionally size of the flash.
Expand Down
Loading

0 comments on commit 58580c2

Please sign in to comment.