Skip to content

[WIP] Attempts to fix Arduino Nano Every build#1719

Merged
zackees merged 9 commits into
FastLED:masterfrom
ngyl88-arduino:fix-nano-every-build
Sep 18, 2024
Merged

[WIP] Attempts to fix Arduino Nano Every build#1719
zackees merged 9 commits into
FastLED:masterfrom
ngyl88-arduino:fix-nano-every-build

Conversation

@ngyl88
Copy link
Copy Markdown
Contributor

@ngyl88 ngyl88 commented Sep 18, 2024

It's highly likely the pin 18 and 19 are incorrectly defined , when added in fastpin_avr.h . Probably a copy-and-paste mistake, unsure if this is causing the failure for example Apa102HD.ino or other cause. 😅

The original reference: https://github.com/FastLED/FastLED/blob/avrmega/platforms/avrmega/fastpin_avrmega.h#L107

ngyl88 and others added 8 commits September 18, 2024 17:47
- suspect some examples might never work because Nano Every is using atmega4809
- ATmega4809 is a new feature, incremental changes was added since issue FastLED#716
- ci workflows files are only added after FastLED#716

squashed trials in order
1. enable GH actions on Nano Every build branches
2. temporary commented from Apa102HD examples from compile to isolate build failure
3. temporary commented VPORT optimisation in fastpin_avr.h and to try out missing DDR next
4. Revert "temporary commented from Apa102HD examples from compile to isolate build failure"
This reverts commit d345abf.
5. temporary commented flat names section to isolate the failure of build
6. revert all temporary changes as the failure of build is likely caused by other issue
- suspected the compilation has never fully functional since the support is added (atmega is WIP)
@ngyl88 ngyl88 force-pushed the fix-nano-every-build branch from 31dba2a to 79e1628 Compare September 18, 2024 12:16
@ngyl88
Copy link
Copy Markdown
Contributor Author

ngyl88 commented Sep 18, 2024

Status Update

Default examples to fix:

  • Apa102HD
  • Apa102HDOverride
  • ColorPalette

Examples to confirm the compilation is working:

  • ColorTemperature
  • Cylon
  • DemoReel100
  • Fire2012
  • FirstLight
  • Multiple/MultipleStripsInOneArray
  • Multiple/ArrayOfLedArrays
  • Noise
  • NoisePlayground
  • NoisePlusPalette
  • Pacifica
  • Pride2015
  • RGBCalibrate
  • RGBW
  • RGBWEmulated
  • TwinkleFox
  • XYMatrix

@ngyl88
Copy link
Copy Markdown
Contributor Author

ngyl88 commented Sep 18, 2024

Feel free to take this forward to complete the support on Nano Every.

Next step to the actual fix :

For the context, this block was added after we start adding the support of ATmega4809.

#if defined(__AVR_ATtinyxy7__) || defined(__AVR_ATtinyxy6__) || defined(__AVR_ATtinyxy4__) || defined(__AVR_ATtinyxy2__)

// ATtiny series 0/1 and ATmega series 0
#define _FL_IO(L,C) _RD8(PORT ## L ## _DIR); _RD8(PORT ## L ## _OUT); _RD8(PORT ## L ## _IN); _FL_DEFINE_PORT3(L, C, _R(PORT ## L ## _OUT));
#define _FL_DEFPIN(_PIN, BIT, L) template<> class FastPin<_PIN> : public _AVRPIN<_PIN, 1<<BIT, _R(PORT ## L ## _OUT), _R(PORT ## L ## _DIR), _R(PORT ## L ## _IN)> {};

#elif defined(__AVR_ATmega4809__)

// ATmega series 0
// Optimize Nano Every: Leverage VPORTs instead of PORTs for faster access
#define _FL_IO(L,C) _RD8(VPORT ## L ## _DIR); _RD8(VPORT ## L ## _OUT); _RD8(VPORT ## L ## _IN); _FL_DEFINE_PORT3(L, C, _R(VPORT ## L ## _OUT));
#define _FL_DEFPIN(_PIN, BIT, L) template<> class FastPin<_PIN> : public _AVRPIN<_PIN, 1<<BIT, _R(VPORT ## L ## _OUT), _R(VPORT ## L ## _DIR), _R(VPORT ## L ## _IN)> {};

#else

...

#endif

@zackees zackees merged commit 450a979 into FastLED:master Sep 18, 2024
@zackees
Copy link
Copy Markdown
Member

zackees commented Sep 18, 2024

Wow! Thanks for this!!! YOU ROCK!!!

nano_every

I'm going to add this to the release_notes.md

Feel free to issue a PR if there is anything more that users should know!

@zackees
Copy link
Copy Markdown
Member

zackees commented Sep 18, 2024

Hi, i checked out your commits more closely and it looks like you took out the APA102HD test for nano every. That test is still failing.

I'm going to revert this so that all tests are running. I don't like having a major test type failing. Either the underlying cause needs to be fixed or if that's not possible, #ifdef'd so that the right pins are selected.

Again, thanks for pushing the needle on this.

@zackees
Copy link
Copy Markdown
Member

zackees commented Sep 18, 2024

I put the code into the latest chat gpt and it outputted this truncated version of fastpin_avr.h for just nano every. It compiles fine, though I don't know if it works in the runtime.

#ifndef __INC_FASTPIN_AVR_H
#define __INC_FASTPIN_AVR_H

#include <avr/io.h>

FASTLED_NAMESPACE_BEGIN

#if defined(FASTLED_FORCE_SOFTWARE_PINS)
#warning "Software pin support forced, pin access will be slightly slower."
#define NO_HARDWARE_PIN_SUPPORT
#undef HAS_HARDWARE_PIN_SUPPORT

#else

#define AVR_PIN_CYCLES(_PIN) ((((int)FastPin<_PIN>::port()) - 0x20 < 64) ? 1 : 2)

typedef volatile uint8_t& reg8_t;

#define _R(T) struct __gen_struct_##T
#define _RD8(T) struct __gen_struct_##T { static inline reg8_t& r() { return T; } };

template<uint8_t PIN, uint8_t _MASK, typename _PORT, typename _DDR, typename _PIN>
class _AVRPIN {
public:
    typedef volatile uint8_t* port_ptr_t;
    typedef uint8_t port_t;

    inline static void setOutput() { _DDR::r() |= _MASK; }
    inline static void setInput() { _DDR::r() &= ~_MASK; }

    inline static void hi() __attribute__((always_inline)) { _PORT::r() |= _MASK; }
    inline static void lo() __attribute__((always_inline)) { _PORT::r() &= ~_MASK; }
    inline static void set(FASTLED_REGISTER uint8_t val) __attribute__((always_inline)) { _PORT::r() = val; }

    inline static void strobe() __attribute__((always_inline)) { toggle(); toggle(); }

    inline static void toggle() __attribute__((always_inline)) { _PIN::r() = _MASK; }

    inline static void hi(FASTLED_REGISTER port_ptr_t /*port*/) __attribute__((always_inline)) { hi(); }
    inline static void lo(FASTLED_REGISTER port_ptr_t /*port*/) __attribute__((always_inline)) { lo(); }
    inline static void fastset(FASTLED_REGISTER port_ptr_t /*port*/, FASTLED_REGISTER uint8_t val) __attribute__((always_inline)) { set(val); }

    inline static port_t hival() __attribute__((always_inline)) { return _PORT::r() | _MASK; }
    inline static port_t loval() __attribute__((always_inline)) { return _PORT::r() & ~_MASK; }
    inline static port_ptr_t port() __attribute__((always_inline)) { return &_PORT::r(); }

    inline static port_t mask() __attribute__((always_inline)) { return _MASK; }
};

#define _CONCAT2(a, b) a##b
#define _CONCAT3(a, b, c) a##b##c

#if defined(ARDUINO_AVR_NANO_EVERY)

// Use VPORTx registers for direct port manipulation
#define _FL_IO(L, C)                                                                                  \
    struct _CONCAT3(__gen_struct_VPORT, L, _DIR) { static inline reg8_t& r() { return VPORT##L.DIR; } }; \
    struct _CONCAT3(__gen_struct_VPORT, L, _OUT) { static inline reg8_t& r() { return VPORT##L.OUT; } }; \
    struct _CONCAT3(__gen_struct_VPORT, L, _IN) { static inline reg8_t& r() { return VPORT##L.IN; } };   \
    _FL_DEFINE_PORT3(L, C, _CONCAT3(__gen_struct_VPORT, L, _OUT));

#define _FL_DEFPIN(_PIN, BIT, L)                                                                        \
    template<> class FastPin<_PIN> : public _AVRPIN<_PIN, 1 << BIT,                                     \
        _CONCAT3(__gen_struct_VPORT, L, _OUT),                                                          \
        _CONCAT3(__gen_struct_VPORT, L, _DIR),                                                          \
        _CONCAT3(__gen_struct_VPORT, L, _IN)> {};

#else

#define _FL_IO(L, C) _RD8(DDR##L); _RD8(PORT##L); _RD8(PIN##L); _FL_DEFINE_PORT3(L, C, _R(PORT##L));
#define _FL_DEFPIN(_PIN, BIT, L) template<> class FastPin<_PIN> : public _AVRPIN<_PIN, 1 << BIT, _R(PORT##L), _R(DDR##L), _R(PIN##L)> {};

#endif

// Pre-do all the port definitions
#ifdef VPORTA
_FL_IO(A, 0)
#endif
#ifdef VPORTB
_FL_IO(B, 1)
#endif
#ifdef VPORTC
_FL_IO(C, 2)
#endif
#ifdef VPORTD
_FL_IO(D, 3)
#endif
#ifdef VPORTE
_FL_IO(E, 4)
#endif
#ifdef VPORTF
_FL_IO(F, 5)
#endif
#ifdef VPORTG
_FL_IO(G, 6)
#endif
#ifdef VPORTH
_FL_IO(H, 7)
#endif
#ifdef VPORTI
_FL_IO(I, 8)
#endif
#ifdef VPORTJ
_FL_IO(J, 9)
#endif
#ifdef VPORTK
_FL_IO(K, 10)
#endif
#ifdef VPORTL
_FL_IO(L, 11)
#endif
#ifdef VPORTM
_FL_IO(M, 12)
#endif
#ifdef VPORTN
_FL_IO(N, 13)
#endif

// Define pins for the Nano Every
#if defined(ARDUINO_AVR_NANO_EVERY)

#define MAX_PIN 22
_FL_DEFPIN(0, 5, C); _FL_DEFPIN(1, 4, C); _FL_DEFPIN(2, 0, A); _FL_DEFPIN(3, 5, F);
_FL_DEFPIN(4, 6, C); _FL_DEFPIN(5, 2, B); _FL_DEFPIN(6, 4, F); _FL_DEFPIN(7, 1, A);
_FL_DEFPIN(8, 3, E); _FL_DEFPIN(9, 0, B); _FL_DEFPIN(10, 1, B); _FL_DEFPIN(11, 0, E);
_FL_DEFPIN(12, 1, E); _FL_DEFPIN(13, 2, E); _FL_DEFPIN(14, 3, D); _FL_DEFPIN(15, 2, D);
_FL_DEFPIN(16, 1, D); _FL_DEFPIN(17, 0, D);
_FL_DEFPIN(18, 2, F); _FL_DEFPIN(19, 3, F);
_FL_DEFPIN(20, 4, D); _FL_DEFPIN(21, 5, D); _FL_DEFPIN(22, 2, A);

#define SPI_DATA 11
#define SPI_CLOCK 13
#define SPI_SELECT 8
#define AVR_HARDWARE_SPI 1
#define HAS_HARDWARE_PIN_SUPPORT 1

#endif // ARDUINO_AVR_NANO_EVERY

// Rest of the AVR pin definitions...

#endif // FASTLED_FORCE_SOFTWARE_PINS

FASTLED_NAMESPACE_END

#endif // __INC_FASTPIN_AVR_H

@zackees
Copy link
Copy Markdown
Member

zackees commented Sep 18, 2024

Okay, i got the APA102HD test to compile with the AI suggestions. To make this easier I've split out the arduino nano pin definitions into it's own file:

484cc3c

@ngyl88
Copy link
Copy Markdown
Contributor Author

ngyl88 commented Sep 19, 2024

Hi @zackees , thanks for merging this to master and fixing the build. Sorry for the confusion with the PR title, I put a prefix [WIP] to indicate it's a work-in-progress. But the PR was created before completion because I think this will help the fix progress. 😄

For your context, I discussed with @kriegsman about the codes for AVR platform has grown to support AVR mega and AVR tiny, especially this fastpin_avr.h. However we didn't act on the refactoring, because the wider ATmega and ATtiny support has been dragging for long. #1061 (comment)

Your commit 484cc3c has given me a light on how to make the fastpin_avr.h cleaner. I will be creating another PR to move the other Nano Every. https://github.com/FastLED/FastLED/blob/master/src/platforms/avr/fastpin_avr.h#L40-L45

I think we don't have a workflow files for ATmega4809 ( Arduino Uno Wifi Rev 2 ) , while the Arduino UNO WiFi is using ATmega328 . We also don't have much CI coverage for the ATtiny series . The AVR platform is quite complicated and the current source in https://github.com/FastLED/FastLED/tree/master/src/platforms/avr includes ATmega ( Arduino Uno, Nano Every ) and ATtiny . I hope this context will be helpful for the refactoring or code organisation, directly on the master branch hopefully. 😅

@zackees
Copy link
Copy Markdown
Member

zackees commented Sep 19, 2024

I'm refactoring as I'm going. This codebase needs it. As soon as I separated the pin definitions I was able to instruct an AI to define the pins. I just did this same refactoring to support the stm32 bluepin and maple_mini.

Feel free to use the same pattern whenever appropriate.

@ngyl88
Copy link
Copy Markdown
Contributor Author

ngyl88 commented Sep 19, 2024

@zackees I think we need a few build file for ATmega and more ATtiny, but I'm not yet familiar about how to create one. Feel free to @ me when you are adding one for new issues related to these platforms. Because we never have CI workflows in the historical time. 😅

@zackees
Copy link
Copy Markdown
Member

zackees commented Sep 19, 2024

You can tell me your boards and I can add them.

Adding a build is not hard at all, see this:

baf10fb

@ngyl88
Copy link
Copy Markdown
Contributor Author

ngyl88 commented Sep 19, 2024

I only have an Arduino WiFi Rev2 ( using ATmega ) which I didn't use recently. My work is fully software in the recent years.

I thought there will be more changes to the configuration eg. the json config in the boards folder or more lines to be added onto ci-compile.py file. 😅

Thanks for sharing an example commit to add a board into CI. I will add one when I'm messing with hardware again. 😄

@zackees
Copy link
Copy Markdown
Member

zackees commented Sep 19, 2024

There was a lot of code, i've abstracted it all away so it's easy now.

I thought there will be more changes to the configuration eg. the json config in the boards folder or more lines to be added onto ci-compile.py file. 😅

The tough parts come with the corner cases like new boards that get released. But you don't have to worry about that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants