adafruit / ArduinoCore-samd

116 stars 119 forks source link

Built-in neopixel on QT Py M0 (and probably feather M4 CAN) shows incorrect colors #311

Closed WestfW closed 2 years ago

WestfW commented 2 years ago

On QTPy M0 boards running Arduino code, the onboard neopixel can show colors that are "red shifted" (actually, lacking in blue) from what they ought to be. This appears to be because the neopixel on those boards is powered by a SAMD output pin, and by default that pin leaves the neopixel under-powered.

Workaround: add

      PORT->Group[0].PINCFG[15].bit.DRVSTR = 1;  // turn up neopixel power

to setup() in your sketch. (for QTPy)

The Feather M4 CAN board seems to have the same "powered by a pin" scheme, and so it probably has the same bug.

I have some concern that at maximum brightness levels, the power consumption of the neopixel may exceed even the "high current" drive of a SAMD output pin.

https://forums.adafruit.com/viewtopic.php?f=47&t=186027

(Hmm. This may also be a problem no the RP2040 boards with IO-powered neopixels; I think they have a similar "drive strength" setting.)

ladyada commented 2 years ago

oh we should have DRVSTR up all the way anyways @hathach can you check if we turn on DRVSTR on gpio for samd21/samd51?

WestfW commented 2 years ago

I checked, and didn't see it set anywhere. (Probably the assumption that it was set was what led to the problem.)

> pwd
/Volumes/MacOS/HD-Users/BillW/src/adafruit-samd

> gid DRVSTR
bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/component/port.h:245:    uint32_t DRVSTR:1;         /*!< bit:     22  Output Driver Strength Selection   */
bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/component/port.h:344:    uint8_t  DRVSTR:1;         /*!< bit:      6  Output Driver Strength Selection   */
bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/component/port.h:245:    uint32_t DRVSTR:1;         /*!< bit:     22  Output Driver Strength Selection   */
bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/component/port.h:344:    uint8_t  DRVSTR:1;         /*!< bit:      6  Output Driver Strength Selection   */
variants/feather_m4_can/variant.cpp:159:  port->PINCFG[bitnum].bit.DRVSTR = 1;  // turn up neopixel power
variants/qtpy_m0/variant.cpp:89:  port->PINCFG[bitnum].bit.DRVSTR = 1;  // turn up neopixel power

(The occurrances in variants are my patch. PR imminent, if you'd like...)

ladyada commented 2 years ago

sure, however, we should turn on drvstr for all gpio pins

WestfW commented 2 years ago

The "DRVSTR for all pins" idea has been brought up multiple times, and I've never seen a negative argument, but it hasn't happened yet, perhaps out of desire for the "third-party" forks to remain compatible with the main arduino fork? :-(

https://github.com/arduino/ArduinoCore-samd/issues/158

ladyada commented 2 years ago

we def use it for circuitpython, not sure why upstream doesnt do it. but we want to! cc @dhalbert

hathach commented 2 years ago