-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1523 from facchinm/uno_r4_support
renesas: initial porting for UNO R4
- Loading branch information
Showing
6 changed files
with
273 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
#ifndef __INC_CLOCKLESS_ARM_RENESAS | ||
#define __INC_CLOCKLESS_ARM_RENESAS | ||
|
||
FASTLED_NAMESPACE_BEGIN | ||
|
||
// Definition for a single channel clockless controller for RA4M1 (Cortex M4) | ||
// See clockless.h for detailed info on how the template parameters are used. | ||
#define ARM_DEMCR (*(volatile uint32_t *)0xE000EDFC) // Debug Exception and Monitor Control | ||
#define ARM_DEMCR_TRCENA (1 << 24) // Enable debugging & monitoring blocks | ||
#define ARM_DWT_CTRL (*(volatile uint32_t *)0xE0001000) // DWT control register | ||
#define ARM_DWT_CTRL_CYCCNTENA (1 << 0) // Enable cycle count | ||
#define ARM_DWT_CYCCNT (*(volatile uint32_t *)0xE0001004) // Cycle count register | ||
|
||
|
||
#define FASTLED_HAS_CLOCKLESS 1 | ||
|
||
template <int DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50> | ||
class ClocklessController : public CPixelLEDController<RGB_ORDER> { | ||
typedef typename FastPin<DATA_PIN>::port_ptr_t data_ptr_t; | ||
typedef typename FastPin<DATA_PIN>::port_t data_t; | ||
|
||
data_t mPinMask; | ||
data_ptr_t mPort; | ||
CMinWait<WAIT_TIME> mWait; | ||
|
||
public: | ||
virtual void init() { | ||
FastPin<DATA_PIN>::setOutput(); | ||
mPinMask = FastPin<DATA_PIN>::mask(); | ||
mPort = FastPin<DATA_PIN>::port(); | ||
} | ||
|
||
virtual uint16_t getMaxRefreshRate() const { return 400; } | ||
|
||
protected: | ||
virtual void showPixels(PixelController<RGB_ORDER> & pixels) { | ||
mWait.wait(); | ||
if(!showRGBInternal(pixels)) { | ||
sei(); delayMicroseconds(WAIT_TIME); cli(); | ||
showRGBInternal(pixels); | ||
} | ||
mWait.mark(); | ||
} | ||
|
||
template<int BITS> __attribute__ ((always_inline)) inline static void writeBits(FASTLED_REGISTER uint32_t & next_mark, FASTLED_REGISTER data_ptr_t port, FASTLED_REGISTER data_t hi, FASTLED_REGISTER data_t lo, FASTLED_REGISTER uint8_t & b) { | ||
for(FASTLED_REGISTER uint32_t i = BITS-1; i > 0; --i) { | ||
while(ARM_DWT_CYCCNT < next_mark); | ||
next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); | ||
FastPin<DATA_PIN>::fastset(port, hi); | ||
if(b&0x80) { | ||
while((next_mark - ARM_DWT_CYCCNT) > (T3+(2*(F_CPU/24000000)))); | ||
FastPin<DATA_PIN>::fastset(port, lo); | ||
} else { | ||
while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+(2*(F_CPU/24000000)))); | ||
FastPin<DATA_PIN>::fastset(port, lo); | ||
} | ||
b <<= 1; | ||
} | ||
|
||
while(ARM_DWT_CYCCNT < next_mark); | ||
next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); | ||
FastPin<DATA_PIN>::fastset(port, hi); | ||
|
||
if(b&0x80) { | ||
while((next_mark - ARM_DWT_CYCCNT) > (T3+(2*(F_CPU/24000000)))); | ||
FastPin<DATA_PIN>::fastset(port, lo); | ||
} else { | ||
while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+(2*(F_CPU/24000000)))); | ||
FastPin<DATA_PIN>::fastset(port, lo); | ||
} | ||
} | ||
|
||
// This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then | ||
// gcc will use register Y for the this pointer. | ||
static uint32_t showRGBInternal(PixelController<RGB_ORDER> pixels) { | ||
// Get access to the clock | ||
ARM_DEMCR |= ARM_DEMCR_TRCENA; | ||
ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA; | ||
ARM_DWT_CYCCNT = 0; | ||
|
||
FASTLED_REGISTER data_ptr_t port = FastPin<DATA_PIN>::port(); | ||
FASTLED_REGISTER data_t hi = *port | FastPin<DATA_PIN>::mask(); | ||
FASTLED_REGISTER data_t lo = *port & ~FastPin<DATA_PIN>::mask(); | ||
*port = lo; | ||
|
||
// Setup the pixel controller and load/scale the first byte | ||
pixels.preStepFirstByteDithering(); | ||
FASTLED_REGISTER uint8_t b = pixels.loadAndScale0(); | ||
|
||
cli(); | ||
uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); | ||
|
||
while(pixels.has(1)) { | ||
pixels.stepDithering(); | ||
#if (FASTLED_ALLOW_INTERRUPTS == 1) | ||
cli(); | ||
// if interrupts took longer than 45µs, punt on the current frame | ||
if(ARM_DWT_CYCCNT > next_mark) { | ||
if((ARM_DWT_CYCCNT-next_mark) > ((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US)) { sei(); return 0; } | ||
} | ||
|
||
hi = *port | FastPin<DATA_PIN>::mask(); | ||
lo = *port & ~FastPin<DATA_PIN>::mask(); | ||
#endif | ||
// Write first byte, read next byte | ||
writeBits<8+XTRA0>(next_mark, port, hi, lo, b); | ||
b = pixels.loadAndScale1(); | ||
|
||
// Write second byte, read 3rd byte | ||
writeBits<8+XTRA0>(next_mark, port, hi, lo, b); | ||
b = pixels.loadAndScale2(); | ||
|
||
// Write third byte, read 1st byte of next pixel | ||
writeBits<8+XTRA0>(next_mark, port, hi, lo, b); | ||
b = pixels.advanceAndLoadAndScale0(); | ||
#if (FASTLED_ALLOW_INTERRUPTS == 1) | ||
sei(); | ||
#endif | ||
}; | ||
|
||
sei(); | ||
return ARM_DWT_CYCCNT; | ||
} | ||
}; | ||
|
||
FASTLED_NAMESPACE_END | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#ifndef __INC_FASTLED_ARM_RENESAS_H | ||
#define __INC_FASTLED_ARM_RENESAS_H | ||
|
||
#include "fastpin_arm_renesas.h" | ||
#include "../../fastspi_ardunio_core.h" | ||
#include "clockless_arm_renesas.h" | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
#ifndef __INC_FASTPIN_ARM_RENESAS_H | ||
#define __INC_FASTPIN_ARM_RENESAS_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 | ||
|
||
#include "bsp_api.h" | ||
|
||
/// Template definition for STM32 style ARM pins, providing direct access to the various GPIO registers. Note that this | ||
/// uses the full port GPIO registers. In theory, in some way, bit-band register access -should- be faster, however I have found | ||
/// that something about the way gcc does register allocation results in the bit-band code being slower. It will need more fine tuning. | ||
/// The registers are data output, set output, clear output, toggle output, input, and direction | ||
|
||
template<uint8_t PIN, bsp_io_port_pin_t bspPin, uint32_t _PORT> class _ARMPIN { | ||
public: | ||
|
||
typedef volatile uint16_t * port_ptr_t; | ||
typedef uint16_t port_t; | ||
|
||
#define PORT ((R_PORT0_Type*)(_PORT)) | ||
#define digitalBspPinToPort(P) (P >> 8) | ||
#define digitalBspPinToBitMask(P) (1 << (P & 0xFF)) | ||
|
||
#if 0 | ||
inline static void setOutput() { | ||
if(_BIT<8) { | ||
_CRL::r() = (_CRL::r() & (0xF << (_BIT*4)) | (0x1 << (_BIT*4)); | ||
} else { | ||
_CRH::r() = (_CRH::r() & (0xF << ((_BIT-8)*4))) | (0x1 << ((_BIT-8)*4)); | ||
} | ||
} | ||
inline static void setInput() { /* TODO */ } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; } | ||
#endif | ||
|
||
inline static void setOutput() { pinMode(PIN, OUTPUT); } // TODO: perform MUX config { _PDDR::r() |= _MASK; } | ||
inline static void setInput() { pinMode(PIN, INPUT); } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; } | ||
|
||
inline static void hi() __attribute__ ((always_inline)) { PORT->POSR = digitalBspPinToBitMask(bspPin); } | ||
inline static void lo() __attribute__ ((always_inline)) { PORT->PORR = digitalBspPinToBitMask(bspPin); } | ||
inline static void set(FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) { PORT->PODR = val; } | ||
|
||
inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); } | ||
|
||
inline static void toggle() __attribute__ ((always_inline)) { PORT->PODR & digitalBspPinToBitMask(bspPin) ? lo() : hi(); } | ||
|
||
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 port_t val) __attribute__ ((always_inline)) { *port = val; } | ||
|
||
inline static port_t hival() __attribute__ ((always_inline)) { return PORT->PODR | digitalBspPinToBitMask(bspPin); } | ||
inline static port_t loval() __attribute__ ((always_inline)) { return PORT->PODR & ~digitalBspPinToBitMask(bspPin); } | ||
inline static port_ptr_t port() __attribute__ ((always_inline)) { return &PORT->PODR; } | ||
inline static port_ptr_t sport() __attribute__ ((always_inline)) { return &PORT->POSR; } | ||
inline static port_ptr_t cport() __attribute__ ((always_inline)) { return &PORT->PORR; } | ||
inline static port_t mask() __attribute__ ((always_inline)) { return digitalBspPinToBitMask(bspPin); } | ||
|
||
}; | ||
|
||
#define _FL_DEFPIN(PIN, bspPin, PORT) template<> class FastPin<PIN> : public _ARMPIN<PIN, bspPin, PORT> {}; | ||
|
||
// Actual pin definitions | ||
#if defined(ARDUINO_UNOR4_WIFI) | ||
|
||
#define MAX_PIN 21 | ||
// D0-D13 | ||
_FL_DEFPIN( 0, BSP_IO_PORT_03_PIN_01, R_PORT3_BASE ); _FL_DEFPIN( 1, BSP_IO_PORT_03_PIN_02, R_PORT3_BASE ); _FL_DEFPIN( 2, BSP_IO_PORT_01_PIN_04, R_PORT1_BASE ); | ||
_FL_DEFPIN( 3, BSP_IO_PORT_01_PIN_05, R_PORT1_BASE ); _FL_DEFPIN( 4, BSP_IO_PORT_01_PIN_06, R_PORT1_BASE ); _FL_DEFPIN( 5, BSP_IO_PORT_01_PIN_07, R_PORT1_BASE ); | ||
_FL_DEFPIN( 6, BSP_IO_PORT_01_PIN_11, R_PORT1_BASE ); _FL_DEFPIN( 7, BSP_IO_PORT_01_PIN_12, R_PORT1_BASE ); _FL_DEFPIN( 8, BSP_IO_PORT_03_PIN_04, R_PORT3_BASE ); | ||
_FL_DEFPIN( 9, BSP_IO_PORT_03_PIN_03, R_PORT3_BASE ); _FL_DEFPIN(10, BSP_IO_PORT_01_PIN_03, R_PORT1_BASE ); _FL_DEFPIN(11, BSP_IO_PORT_04_PIN_11, R_PORT4_BASE ); | ||
_FL_DEFPIN(12, BSP_IO_PORT_04_PIN_10, R_PORT4_BASE ); _FL_DEFPIN(13, BSP_IO_PORT_01_PIN_02, R_PORT1_BASE ); | ||
// A0-A5 | ||
_FL_DEFPIN(14, BSP_IO_PORT_00_PIN_14, R_PORT0_BASE ); _FL_DEFPIN(15, BSP_IO_PORT_00_PIN_00, R_PORT0_BASE ); _FL_DEFPIN(16, BSP_IO_PORT_00_PIN_01, R_PORT0_BASE ); | ||
_FL_DEFPIN(17, BSP_IO_PORT_00_PIN_02, R_PORT0_BASE ); _FL_DEFPIN(18, BSP_IO_PORT_01_PIN_01, R_PORT1_BASE ); _FL_DEFPIN(19, BSP_IO_PORT_01_PIN_00, R_PORT1_BASE ); | ||
|
||
#elif defined(ARDUINO_UNOR4_MINIMA) | ||
|
||
#define MAX_PIN 21 | ||
// D0-D13 | ||
_FL_DEFPIN( 0, BSP_IO_PORT_03_PIN_01, R_PORT3_BASE ); _FL_DEFPIN( 1, BSP_IO_PORT_03_PIN_02, R_PORT3_BASE ); _FL_DEFPIN( 2, BSP_IO_PORT_01_PIN_05, R_PORT1_BASE ); | ||
_FL_DEFPIN( 3, BSP_IO_PORT_01_PIN_04, R_PORT1_BASE ); _FL_DEFPIN( 4, BSP_IO_PORT_01_PIN_03, R_PORT1_BASE ); _FL_DEFPIN( 5, BSP_IO_PORT_01_PIN_02, R_PORT1_BASE ); | ||
_FL_DEFPIN( 6, BSP_IO_PORT_01_PIN_06, R_PORT1_BASE ); _FL_DEFPIN( 7, BSP_IO_PORT_01_PIN_07, R_PORT1_BASE ); _FL_DEFPIN( 8, BSP_IO_PORT_03_PIN_04, R_PORT3_BASE ); | ||
_FL_DEFPIN( 9, BSP_IO_PORT_03_PIN_03, R_PORT3_BASE ); _FL_DEFPIN(10, BSP_IO_PORT_01_PIN_12, R_PORT1_BASE ); _FL_DEFPIN(11, BSP_IO_PORT_01_PIN_09, R_PORT1_BASE ); | ||
_FL_DEFPIN(12, BSP_IO_PORT_01_PIN_10, R_PORT1_BASE ); _FL_DEFPIN(13, BSP_IO_PORT_01_PIN_11, R_PORT1_BASE ); | ||
// A0-A5 | ||
_FL_DEFPIN(14, BSP_IO_PORT_00_PIN_14, R_PORT0_BASE ); _FL_DEFPIN(15, BSP_IO_PORT_00_PIN_00, R_PORT0_BASE ); _FL_DEFPIN(16, BSP_IO_PORT_00_PIN_01, R_PORT0_BASE ); | ||
_FL_DEFPIN(17, BSP_IO_PORT_00_PIN_02, R_PORT0_BASE ); _FL_DEFPIN(18, BSP_IO_PORT_01_PIN_01, R_PORT1_BASE ); _FL_DEFPIN(19, BSP_IO_PORT_01_PIN_00, R_PORT1_BASE ); | ||
#endif | ||
|
||
#define SPI_DATA 12 | ||
#define SPI_CLOCK 13 | ||
|
||
#define HAS_HARDWARE_PIN_SUPPORT 1 | ||
|
||
#endif // FASTLED_FORCE_SOFTWARE_PINS | ||
|
||
FASTLED_NAMESPACE_END | ||
|
||
|
||
#endif // __INC_FASTPIN_ARM_RENESAS_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#ifndef __INC_LED_SYSDEFS_ARM_RENESAS_H | ||
#define __INC_LED_SYSDEFS_ARM_RENESAS_H | ||
|
||
#define FASTLED_ARM | ||
|
||
#ifndef INTERRUPT_THRESHOLD | ||
#define INTERRUPT_THRESHOLD 1 | ||
#endif | ||
|
||
// Default to allowing interrupts | ||
#ifndef FASTLED_ALLOW_INTERRUPTS | ||
#define FASTLED_ALLOW_INTERRUPTS 1 | ||
#endif | ||
|
||
#if FASTLED_ALLOW_INTERRUPTS == 1 | ||
#define FASTLED_ACCURATE_CLOCK | ||
#endif | ||
|
||
// reusing/abusing cli/sei defs for due | ||
#define cli() __disable_irq(); | ||
#define sei() __enable_irq(); | ||
|
||
#define FASTLED_NO_PINMAP | ||
|
||
typedef volatile uint32_t RoReg; | ||
typedef volatile uint32_t RwReg; | ||
|
||
#endif |