Skip to content

Commit

Permalink
Maybe fix compile examples. adjust #480
Browse files Browse the repository at this point in the history
  • Loading branch information
SpenceKonde committed Sep 23, 2023
1 parent 3dac697 commit f63394c
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/compile-examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ jobs:
- name: Compile examples (rated max speed, nothing weird)
uses: arduino/compile-sketches@main
with:
cli-version: 0.33.1
fqbn: ${{ env.platform-name }}:avr${{ matrix.device-family }}:chip=avr${{ matrix.flash-class }}${{ matrix.device-family }}${{ matrix.pincount }},clock=${{matrix.int-osc}}${{ matrix.clocksource }},wiremode=mands,flmap=lockdefault
sketch-paths: |
# It's necessary to jump through some hoops to dynamically generate the env object keys to define the non-universal sketch paths
Expand All @@ -348,6 +349,7 @@ jobs:
- name: Compile examples (overclocked to the max, tcb1 millis, minimal printf, old attachInterrupt, full appspm)
uses: arduino/compile-sketches@main
with:
cli-version: 0.33.1
fqbn: ${{ env.platform-name }}:avr${{ matrix.device-family }}:chip=avr${{ matrix.flash-class }}${{ matrix.device-family }}${{ matrix.pincount }},clock=${{ matrix.overclock-osc }}${{ matrix.clocksource }},millis=tcb1,printf=minimal,wiremode=mors,attach=oldversion,appspm=full,flmap=lockdefault
sketch-paths: |
# It's necessary to jump through some hoops to dynamically generate the env object keys to define the non-universal sketch paths
Expand Down Expand Up @@ -400,6 +402,7 @@ jobs:
if: matrix.device-family != 'ea' && matrix.device-family != 'eb'
uses: arduino/compile-sketches@main
with:
cli-version: 0.33.1
fqbn: ${{ env.platform-name }}:avr${{ matrix.device-family }}opti:chip=avr${{ matrix.flash-class }}${{ matrix.device-family }}${{ matrix.pincount }},clock=8${{ matrix.clocksource }},millis=tca0,printf=full,attach=manual,wiremode=mands,flmap=unlock
sketch-paths: |
# It's necessary to jump through some hoops to dynamically generate the env object keys to define the non-universal sketch paths
Expand Down
4 changes: 4 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ These items are in addition to what was listed under changes already in release.
## Planned changes implemented in github
These are typically planned for release in a future version (usually the next one) as noted.

### Planned 1.5.10
* Enhancement/bugfix - add digitalPinToCanon() - given a pin number, it returns port * 8 + bit_position. This is to be used in some other fixes and enhancements.
* Attempt to workaround Arduino CLI regression impacting CI testing.

## Releases
### 1.5.9
* Bugfix: Correct Flash.h issues.
Expand Down
41 changes: 40 additions & 1 deletion megaavr/cores/dxcore/Arduino.h
Original file line number Diff line number Diff line change
Expand Up @@ -762,7 +762,7 @@ See Ref_Analog.md for more information of the representations of "analog pins".
#define portOutputRegister(P) ((volatile uint8_t *)(&portToPortStruct(P)->OUT))
#define portInputRegister(P) ((volatile uint8_t *)(&portToPortStruct(P)->IN ))
#define portModeRegister(P) ((volatile uint8_t *)(&portToPortStruct(P)->DIR))
#if defined(PORTA_EVGENCTRL) //Ex-series only - this all may belong in the Event library anyway, but since the conditional is never met, this code is never used.
#if defined(PORTA_EVGENCTRL) //Ex-series only - this all may belong in the Event library anyway, but since the conditional is never met, this code is never used.
#define portEventRegister(p) ((volatile uint8_t *)(&portToPortStruct(P)->EVGENCTRL))
uint8_t _setRTCEventChan(uint8_t val, uint8_t chan);
uint8_t _setEventPin(uint8_t pin, uint8_t number); // preliminary thought - pass a pin number, it looks up port, and from there the event control register and sets it.
Expand All @@ -771,7 +771,46 @@ See Ref_Analog.md for more information of the representations of "analog pins".
uint8_t _setRTCEventChan(uint8_t vail, uint8_t chan); // number is 0, 1 or 255 like above, div is log(2) of the divisor (ie, for 2^5, his would be 5).
uint8_t _getRTCEventConfig(); //simply returns the RTC channel configuration. Will likely return 255 if called on non Ex
uint8_t _RTCPrescaleToVal(uint16_t prescale);
#endif

/* The Variant file must do one of the following */
/* 1. Use the same pin order as this core's default pin mapping (recommended)
* 2. Number each pin (port * 8) + bit_position, and define HYPERRATIONAL_PIN_NUMBERS (also recommended)
* 3. Define NONCANONICAL_PIN_NUMBERS and use any pin numbering. (recommended if you must use a layout that departs significantly from the above)
* 4. Define SPECIAL_PIN_NUMBERS, and provide a _digitalPinToCanon(pin) macro that takes an Arduino pin number, and returns (port * 8) + bit_position
* (Only if you can do it better than the stanard noncanonical implementation - that implementation is not grotesque, but it's also not great.

Check failure on line 781 in megaavr/cores/dxcore/Arduino.h

View workflow job for this annotation

GitHub Actions / spellcheck

stanard ==> standard
* each table lookup takes the form lds lds add adc ld, 7 words and 10 clocks, so the whole thing is probably on the order of 20 and 26)
* This change permits underlying logic to be written with a single byte to represent a pin, which is present in some obscure parts of the code
* mostly involving interrupts.
* Note that for constant pins known at compile time, these should all be able to be constant folded, it's only compiletime unknown pins

Check failure on line 785 in megaavr/cores/dxcore/Arduino.h

View workflow job for this annotation

GitHub Actions / spellcheck

compiletime ==> compile time
* where this applies. And only for the rare cases where we end up doing this, often interrupt related.
* A lot of this comes back to the question of whether to leave "holes" for missing pins in the numbering. There are two forces pulling in
* opposite directions here: each ghost pin takes up 4b for it's entries in the pin table (and it's sort of absurd for a 28-pin part to have
* 47 logical pins because they were missing PB, PE, and 4 pins of PC and PF, but they make this sort of conversion (and a number of
* similar ones) much easier.
*/

#if defined(NONCANONICAL_PIN_NUMBERS)
#define _digitalPinToCanon(pin) ((pin < NUM_TOTAL_PINS) ? ((digital_pin_to_port[pin] << 3) + digital_pin_to_bit_position[pin] ) : NOT_A_PIN)
#elif defined(HYPERRATIONAL_PIN_NUMBERS) /* Variant must number pins in order, and must skip numbers of pins not present on the chip. */
#define _digitalPinToCanon(pin) ((pin < NUM_TOTAL_PINS) ? pin : NOT_A_PIN)
#elif !defined(SPECIAL_PIN_NUMBERS)
#if __AVR_PINCOUNT == 64
#define _digitalPinToCanon(pin) ((pin < NUM_TOTAL_PINS) ? ((pin < PIN_PG0) ? (pin) : (((pin) > PIN_PG7) ? (pin) - 8 : (pin) + 2 )) : NOT_A_PIN)
#elif __AVR_PINCOUNT == 48
#define _digitalPinToCanon(pin) ((pin < NUM_TOTAL_PINS) ? ((pin < PIN_PC0) ? (pin) : (pin) + 2 ) : NOT_A_PIN)
#elif __AVR_PINCOUNT == 32
#define _digitalPinToCanon(pin) ((pin < NUM_TOTAL_PINS) ? ((pin <= PIN_PA7) ? (pin) : (((pin) < PIN_PD0) ? (pin) + 8 : (((pin) < PIN_PF0) ? (pin) + 12 : (pin) + 20 ))) : NOT_A_PIN)
#elif __AVR_PINCOUNT == 28
#define _digitalPinToCanon(pin) ((pin <= PIN_PF1) ? ((pin <= PIN_PA7) ? (pin) : (((pin) < PIN_PD0) ? (pin) + 8 : (((pin) < PIN_PF0) ? (pin) + 12 : (pin) + 20 ))) : (((pin) < NUM_TOTAL_PINS) ? (pin) + 16 : NOT_A_PIN))
#elif __AVR_PINCOUNT == 20 || __AVR_PINCOUNT == 14
#define _digitalPinToCanon(pin) ((pin < PIN_PF6) ? ((pin <= PIN_PC0) ? (pin) : (((pin) < PIN_PD0) ? (pin) + 8 : (pin) + 12)) : (((pin) < NUM_TOTAL_PINS) ? (pin) + 26 : NOT_A_PIN))
#endif
#else
#if !defined(_digitalPinToCanon)
#error "Your custom variant says it provides a _digitalPinToCanon (SPECIAL_PIN_NUMBERS defined) but you don't provide one. \n Define NONCANONICAL_PIN_NUMBERS instead to use a possibly slower handler for the general case"
#endif
#endif
#ifdef __cplusplus
} // extern "C"
#endif
Expand Down
2 changes: 1 addition & 1 deletion megaavr/extras/Ref_Analog.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ The hardware supports increasing the resolution of analogRead() to the limit of
## A warning about the DAC (well, 2)
First, as described in the errata for the DA and DB, if the output buffer is not enabled, it will suffer accuracy drift over the life of the device. This is rarely an issue since almost all applications of the DAC require the buffer anyway. Just don't forget and leave it on doing nothing for a month or something.

Secondly, the DAC can source only a minuscule amount of current; 1mA or less. Perhaps more importantly, it can sink no more than 1uA (that's not a typo - 1 uA MAX of sink current is the correct value - see the AVRxxDBxx data sheet, section 39.19 for the table entry for Vout - also see Section 39.19 Footnote 2 regarding the need for a pulldown resistor). To get good performance with a falling DAC signal you will need a pulldown resistor to ground. In a 5V system and with 1mA of max source current, that means that the pull down resistor should not be less than 5K. Higher values of resistance may be OK, provided that external circuit that makes use of the DAC output is not capacitive and does not inject current back into the DAC pin. The pull down is not necessary if you are using a DB with one of the OPAMPs in voltage follower mode, which we highly recommend for all cases where you need to generate analog voltages for more that a near-zero-current reference.
Secondly, the DAC can source only a minuscule amount of current; 1mA or less. Perhaps more importantly, it can sink no more than 1uA (that's not a typo - 1 uA MAX of sink current is the real value! (See Datasheet, Electrical Characteristics, DAC - 39.19 for the AVR DB - and note the footnote about "limited" sink capabilities). To get good performance with a falling DAC signal you will need a pulldown resistor to ground (but not too strong of one, remember, only sources < 1mA). In a 5V system and with 1mA of max source current, that means that the pull down resistor should not be less than 5K; they should likely be more like 10k. The value needed will depend on both the external circuit (a capacitive circuit will slow down the change of the DAC) and it's operating conditions. Some (one might even say many) applications will dissappoint without an opamp set up as a voltage follower; in that case you don't need the pulldown. Doing that is of course most convenient when using a DB-series with the on-chip programmable OPAMPs, making this the preferred part for generating analog voltages at currents of up to 30mA.

## ADC Sampling Speed
DxCore takes advantage of the improvements in the ADC on the newer AVR parts to improve the speed of analogRead() by more than a factor of three over classic AVRs. The ADC clock which was - on the classic AVRs - constrained to the range 50-200kHz - can be cranked up as high as 2 MHz (up to 3 MHz for 2-series w tiny or EA with internal ref, twice that on external or Vdd reference at full resolution. We use use 1.0 to 1.5 MHz on Dx, and will target 2-2.5 by default on EA unless someone provides information that suggests I shouldn't. I tried to get answers out of Microchip, but I think their employees have been instructed to never give quantitative advice on ADC settings, since one has to imagine that (especially for 2-series tinyAVRs, with so many dials to turn), "So I have a signal of such-and-such impedance, and I'm running at this speed, what settings should I run the ADC at to avoid inaccurate readings?" is not an uncommon question.
Expand Down

0 comments on commit f63394c

Please sign in to comment.