MCPcopy Create free account
hub / github.com/FastLED/FastLED / AVRHardwareSPIOutput

Class AVRHardwareSPIOutput

src/platforms/avr/fastspi_avr.h:349–520  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

347
348template <u8 _DATA_PIN, u8 _CLOCK_PIN, u32 _SPI_CLOCK_DIVIDER>
349class AVRHardwareSPIOutput {
350 Selectable *mPSelect;
351
352public:
353 AVRHardwareSPIOutput() { mPSelect = nullptr; }
354 AVRHardwareSPIOutput(Selectable *pSelect) { mPSelect = pSelect; }
355 void setSelect(Selectable *pSelect) { mPSelect = pSelect; }
356
357 void init() FL_NOEXCEPT {
358 FastPin<_CLOCK_PIN>::setOutput();
359 FastPin<_DATA_PIN>::setOutput();
360
361 // Configure PORTMUX for SPI (varies by chip family)
362 // megaAVR 0-series (ATmega4809) uses PORTMUX_TWISPIROUTEA
363 // tinyAVR 0/1-series (ATtiny1604 etc) uses PORTMUX.CTRLB
364#if defined(PORTMUX_TWISPIROUTEA)
365 // Arduino Nano Every documentation lists SPI pins in ALT2 portmux position
366 PORTMUX_TWISPIROUTEA = PORTMUX_SPI01_bm;
367#elif defined(PORTMUX_CTRLB)
368 // tinyAVR 0/1-series: use default SPI pin positions (no portmux change needed)
369 // PORTMUX.CTRLB bits are for SPI0 pin swap - we use default (0)
370#endif
371
372 // Set SPI master mode and clock scaler.
373 SPI0_CTRLA = SPI_MASTER_bm;
374 if(_SPI_CLOCK_DIVIDER >= 128) { SPI0_CTRLA |= SPI_PRESC1_bm|SPI_PRESC0_bm; }
375 else if (_SPI_CLOCK_DIVIDER >= 64) { SPI0_CTRLA |= SPI_PRESC1_bm; }
376 else if (_SPI_CLOCK_DIVIDER >= 32) { SPI0_CTRLA |= SPI_PRESC1_bm|SPI_CLK2X_bm; }
377 else if (_SPI_CLOCK_DIVIDER >= 16) { SPI0_CTRLA |= SPI_PRESC0_bm; }
378 else if (_SPI_CLOCK_DIVIDER >= 8) { SPI0_CTRLA |= SPI_PRESC0_bm|SPI_CLK2X_bm; }
379 else if (_SPI_CLOCK_DIVIDER >= 4) { /* default rate */ }
380 else { SPI0_CTRLA |= SPI_CLK2X_bm; }
381
382 // Set mode 0 and disable slave select.
383 SPI0_CTRLB = SPI_SSD_bm;
384
385 // Enable SPI.
386 SPI0_CTRLA |= SPI_ENABLE_bm;
387 }
388
389 void setSPIRate() FL_NOEXCEPT {
390 SPI0_CTRLA &= ~ ( (1<<SPI_PRESC1_bp)|(1<<SPI_PRESC0_bp)|(1<<SPI_CLK2X_bp) ); // clear pre-scaler and clock multiplier bits
391
392 if(_SPI_CLOCK_DIVIDER >= 128) { SPI0_CTRLA |= SPI_PRESC1_bm|SPI_PRESC0_bm; }
393 else if (_SPI_CLOCK_DIVIDER >= 64) { SPI0_CTRLA |= SPI_PRESC1_bm; }
394 else if (_SPI_CLOCK_DIVIDER >= 32) { SPI0_CTRLA |= SPI_PRESC1_bm|SPI_CLK2X_bm; }
395 else if (_SPI_CLOCK_DIVIDER >= 16) { SPI0_CTRLA |= SPI_PRESC0_bm; }
396 else if (_SPI_CLOCK_DIVIDER >= 8) { SPI0_CTRLA |= SPI_PRESC0_bm|SPI_CLK2X_bm; }
397 else if (_SPI_CLOCK_DIVIDER >= 4) { /* default rate */ }
398 else { SPI0_CTRLA |= SPI_CLK2X_bm; }
399 }
400
401 static void stop() FL_NOEXCEPT {
402 SPI0_CTRLA &= ~(SPI_ENABLE_bm);
403 }
404
405 static bool shouldWait(bool wait = false) FL_NOEXCEPT __attribute__((always_inline)) {
406 static bool sWait=false;

Callers

nothing calls this directly

Calls 5

releaseFunction · 0.85
setOutputFunction · 0.50
loFunction · 0.50
selectMethod · 0.45
releaseMethod · 0.45

Tested by

no test coverage detected