<|start_filename|>Firmware/Source/bakebit_v1.0.0/FastLED-FastLED3.1/lib8tion/math8.h<|end_filename|>
#ifndef __INC_LIB8TION_MATH_H
#define __INC_LIB8TION_MATH_H

///@ingroup lib8tion

///@defgroup Math Basic math operations
/// Fast, efficient 8-bit math functions specifically
/// designed for high-performance LED programming.
///
/// Because of the AVR(Arduino) and ARM assembly language
/// implementations provided, using these functions often
/// results in smaller and faster code than the equivalent
/// program using plain "C" arithmetic and logic.
///@{


/// add one byte to another, saturating at 0xFF
/// @param i - first byte to add
/// @param j - second byte to add
/// @returns the sum of i & j, capped at 0xFF
LIB8STATIC uint8_t qadd8( uint8_t i, uint8_t j)
{
#if QADD8_C == 1
    unsigned int t = i + j;
    if( t > 255) t = 255;
    return t;
#elif QADD8_AVRASM == 1
    asm volatile(
         /* First, add j to i, conditioning the C flag */
         "add %0, %1    \n\t"

         /* Now test the C flag.
           If C is clear, we branch around a load of 0xFF into i.
           If C is set, we go ahead and load 0xFF into i.
         */
         "brcc L_%=     \n\t"
         "ldi %0, 0xFF  \n\t"
         "L_%=: "
         : "+a" (i)
         : "a"  (j) );
    return i;
#elif QADD8_ARM_DSP_ASM == 1
    asm volatile( "uqadd8 %0, %0, %1" : "+r" (i) : "r" (j));
    return i;
#else
#error "No implementation for qadd8 available."
#endif
}

/// Add one byte to another, saturating at 0x7F
/// @param i - first byte to add
/// @param j - second byte to add
/// @returns the sum of i & j, capped at 0xFF
LIB8STATIC int8_t qadd7( int8_t i, int8_t j)
{
#if QADD7_C == 1
    int16_t t = i + j;
    if( t > 127) t = 127;
    return t;
#elif QADD7_AVRASM == 1
    asm volatile(
         /* First, add j to i, conditioning the V flag */
         "add %0, %1    \n\t"

         /* Now test the V flag.
          If V is clear, we branch around a load of 0x7F into i.
          If V is set, we go ahead and load 0x7F into i.
          */
         "brvc L_%=     \n\t"
         "ldi %0, 0x7F  \n\t"
         "L_%=: "
         : "+a" (i)
         : "a"  (j) );

    return i;
#elif QADD7_ARM_DSP_ASM == 1
    asm volatile( "qadd8 %0, %0, %1" : "+r" (i) : "r" (j));
    return i;
#else
#error "No implementation for qadd7 available."
#endif
}

/// subtract one byte from another, saturating at 0x00
/// @returns i - j with a floor of 0
LIB8STATIC uint8_t qsub8( uint8_t i, uint8_t j)
{
#if QSUB8_C == 1
    int t = i - j;
    if( t < 0) t = 0;
    return t;
#elif QSUB8_AVRASM == 1

    asm volatile(
         /* First, subtract j from i, conditioning the C flag */
         "sub %0, %1    \n\t"

         /* Now test the C flag.
          If C is clear, we branch around a load of 0x00 into i.
          If C is set, we go ahead and load 0x00 into i.
          */
         "brcc L_%=     \n\t"
         "ldi %0, 0x00  \n\t"
         "L_%=: "
         : "+a" (i)
         : "a"  (j) );

    return i;
#else
#error "No implementation for qsub8 available."
#endif
}

/// add one byte to another, with one byte result
LIB8STATIC uint8_t add8( uint8_t i, uint8_t j)
{
#if ADD8_C == 1
    int t = i + j;
    return t;
#elif ADD8_AVRASM == 1
    // Add j to i, period.
    asm volatile( "add %0, %1" : "+a" (i) : "a" (j));
    return i;
#else
#error "No implementation for add8 available."
#endif
}


/// subtract one byte from another, 8-bit result
LIB8STATIC uint8_t sub8( uint8_t i, uint8_t j)
{
#if SUB8_C == 1
    int t = i - j;
    return t;
#elif SUB8_AVRASM == 1
    // Subtract j from i, period.
    asm volatile( "sub %0, %1" : "+a" (i) : "a" (j));
    return i;
#else
#error "No implementation for sub8 available."
#endif
}

/// Calculate an integer average of two unsigned
///       8-bit integer values (uint8_t).
///       Fractional results are rounded down, e.g. avg8(20,41) = 30
LIB8STATIC uint8_t avg8( uint8_t i, uint8_t j)
{
#if AVG8_C == 1
    return (i + j) >> 1;
#elif AVG8_AVRASM == 1
    asm volatile(
         /* First, add j to i, 9th bit overflows into C flag */
         "add %0, %1    \n\t"
         /* Divide by two, moving C flag into high 8th bit */
         "ror %0        \n\t"
         : "+a" (i)
         : "a"  (j) );
    return i;
#else
#error "No implementation for avg8 available."
#endif
}


/// Calculate an integer average of two signed 7-bit
///       integers (int8_t)
///       If the first argument is even, result is rounded down.
///       If the first argument is odd, result is result up.
LIB8STATIC int8_t avg7( int8_t i, int8_t j)
{
#if AVG7_C == 1
    return ((i + j) >> 1) + (i & 0x1);
#elif AVG7_AVRASM == 1
    asm volatile(
                 "asr %1        \n\t"
                 "asr %0        \n\t"
                 "adc %0, %1    \n\t"
                 : "+a" (i)
                 : "a"  (j) );
    return i;
#else
#error "No implementation for avg7 available."
#endif
}

///       Calculate the remainder of one unsigned 8-bit
///       value divided by anoter, aka A % M.
///       Implemented by repeated subtraction, which is
///       very compact, and very fast if A is 'probably'
///       less than M.  If A is a large multiple of M,
///       the loop has to execute multiple times.  However,
///       even in that case, the loop is only two
///       instructions long on AVR, i.e., quick.
LIB8STATIC uint8_t mod8( uint8_t a, uint8_t m)
{
#if defined(__AVR__)
    asm volatile (
                  "L_%=:  sub %[a],%[m]    \n\t"
                  "       brcc L_%=        \n\t"
                  "       add %[a],%[m]    \n\t"
                  : [a] "+r" (a)
                  : [m] "r"  (m)
                  );
#else
    while( a >= m) a -= m;
#endif
    return a;
}

///          Add two numbers, and calculate the modulo
///          of the sum and a third number, M.
///          In other words, it returns (A+B) % M.
///          It is designed as a compact mechanism for
///          incrementing a 'mode' switch and wrapping
///          around back to 'mode 0' when the switch
///          goes past the end of the available range.
///          e.g. if you have seven modes, this switches
///          to the next one and wraps around if needed:
///            mode = addmod8( mode, 1, 7);
///          See 'mod8' for notes on performance.
LIB8STATIC uint8_t addmod8( uint8_t a, uint8_t b, uint8_t m)
{
#if defined(__AVR__)
    asm volatile (
                  "       add %[a],%[b]    \n\t"
                  "L_%=:  sub %[a],%[m]    \n\t"
                  "       brcc L_%=        \n\t"
                  "       add %[a],%[m]    \n\t"
                  : [a] "+r" (a)
                  : [b] "r"  (b), [m] "r" (m)
                  );
#else
    a += b;
    while( a >= m) a -= m;
#endif
    return a;
}

/// 8x8 bit multiplication, with 8 bit result
LIB8STATIC uint8_t mul8( uint8_t i, uint8_t j)
{
#if MUL8_C == 1
    return ((int)i * (int)(j) ) & 0xFF;
#elif MUL8_AVRASM == 1
    asm volatile(
         /* Multiply 8-bit i * 8-bit j, giving 16-bit r1,r0 */
         "mul %0, %1          \n\t"
         /* Extract the LOW 8-bits (r0) */
         "mov %0, r0          \n\t"
         /* Restore r1 to "0"; it's expected to always be that */
         "clr __zero_reg__    \n\t"
         : "+a" (i)
         : "a"  (j)
         : "r0", "r1");

    return i;
#else
#error "No implementation for mul8 available."
#endif
}


/// saturating 8x8 bit multiplication, with 8 bit result
/// @returns the product of i * j, capping at 0xFF
LIB8STATIC uint8_t qmul8( uint8_t i, uint8_t j)
{
#if QMUL8_C == 1
    int p = ((int)i * (int)(j) );
    if( p > 255) p = 255;
    return p;
#elif QMUL8_AVRASM == 1
    asm volatile(
                 /* Multiply 8-bit i * 8-bit j, giving 16-bit r1,r0 */
                 "  mul %0, %1          \n\t"
                 /* If high byte of result is zero, all is well. */
                 "  tst r1              \n\t"
                 "  breq Lnospill_%=    \n\t"
                 /* If high byte of result > 0, saturate low byte to 0xFF */
                 "  ldi %0,0xFF         \n\t"
                 "  rjmp Ldone_%=       \n\t"
                 "Lnospill_%=:          \n\t"
                 /* Extract the LOW 8-bits (r0) */
                 "  mov %0, r0          \n\t"
                 "Ldone_%=:             \n\t"
                 /* Restore r1 to "0"; it's expected to always be that */
                 "  clr __zero_reg__    \n\t"
                 : "+a" (i)
                 : "a"  (j)
                 : "r0", "r1");

    return i;
#else
#error "No implementation for qmul8 available."
#endif
}


/// take abs() of a signed 8-bit uint8_t
LIB8STATIC int8_t abs8( int8_t i)
{
#if ABS8_C == 1
    if( i < 0) i = -i;
    return i;
#elif ABS8_AVRASM == 1


    asm volatile(
         /* First, check the high bit, and prepare to skip if it's clear */
         "sbrc %0, 7 \n"

         /* Negate the value */
         "neg %0     \n"

         : "+r" (i) : "r" (i) );
    return i;
#else
#error "No implementation for abs8 available."
#endif
}

///         square root for 16-bit integers
///         About three times faster and five times smaller
///         than Arduino's general sqrt on AVR.
LIB8STATIC uint8_t sqrt16(uint16_t x)
{
    if( x <= 1) {
        return x;
    }

    uint8_t low = 1; // lower bound
    uint8_t hi, mid;

    if( x > 7904) {
        hi = 255;
    } else {
        hi = (x >> 5) + 8; // initial estimate for upper bound
    }

    do {
        mid = (low + hi) >> 1;
        if ((uint16_t)(mid * mid) > x) {
            hi = mid - 1;
        } else {
            if( mid == 255) {
                return 255;
            }
            low = mid + 1;
        }
    } while (hi >= low);

    return low - 1;
}

///@}
#endif


<|start_filename|>Firmware/Source/bakebit_v1.0.0/FastLED-FastLED3.1/platforms/arm/common/m0clockless.h<|end_filename|>
#ifndef __INC_M0_CLOCKLESS_H
#define __INC_M0_CLOCKLESS_H

struct M0ClocklessData {
  uint8_t d[3];
  uint8_t s[3];
  uint8_t e[3];
  uint8_t adj;
};


template<int HI_OFFSET, int LO_OFFSET, int T1, int T2, int T3, EOrder RGB_ORDER, int WAIT_TIME>int
showLedData(volatile uint32_t *_port, uint32_t _bitmask, const uint8_t *_leds, uint32_t num_leds, struct M0ClocklessData *pData) {
  // Lo register variables
  register uint32_t scratch=0;
  register struct M0ClocklessData *base = pData;
  register volatile uint32_t *port = _port;
  register uint32_t d=0;
  register uint32_t counter=num_leds;
  register uint32_t bn=0;
  register uint32_t b=0;
  register uint32_t bitmask = _bitmask;

  // high register variable
  register const uint8_t *leds = _leds;

  asm __volatile__ (
    ///////////////////////////////////////////////////////////////////////////
    //
    // asm macro definitions - used to assemble the clockless output
    //
    ".ifnotdef fl_delay_def;"
#ifdef FASTLED_ARM_M0_PLUS
    "  .set fl_is_m0p, 1;"
    "  .macro m0pad;"
    "    nop;"
    "  .endm;"
#else
    "  .set fl_is_m0p, 0;"
    "  .macro m0pad;"
    "  .endm;"
#endif
    "  .set fl_delay_def, 1;"
    "  .set fl_delay_mod, 4;"
    "  .if fl_is_m0p == 1;"
    "    .set fl_delay_mod, 3;"
    "  .endif;"
    "  .macro fl_delay dtime, reg=r0;"
    "    .if (\\dtime > 0);"
    "      .set dcycle, (\\dtime / fl_delay_mod);"
    "      .set dwork, (dcycle * fl_delay_mod);"
    "      .set drem, (\\dtime - dwork);"
    "      .rept (drem);"
    "        nop;"
    "      .endr;"
    "      .if dcycle > 0;"
    "        mov \\reg, #dcycle;"
    "        delayloop_\\@:;"
    "        sub \\reg, #1;"
    "        bne delayloop_\\@;"
    "	     .if fl_is_m0p == 0;"
    "          nop;"
    "        .endif;"
    "      .endif;"
    "    .endif;"
    "  .endm;"

    "  .macro mod_delay dtime,b1,b2,reg;"
    "    .set adj, (\\b1 + \\b2);"
    "    .if adj < \\dtime;"
    "      .set dtime2, (\\dtime - adj);"
    "      fl_delay dtime2, \\reg;"
    "    .endif;"
    "  .endm;"

    // check the bit and drop the line low if it isn't set
    "  .macro qlo4 b,bitmask,port,loff	;"
    "    lsl \\b, #1			;"
    "    bcs skip_\\@			;"
    "    str \\bitmask, [\\port, \\loff]	;"
    "    skip_\\@:			;"
    "    m0pad;"
    "  .endm				;"

    // set the pin hi or low (determined by the offset passed in )
    "  .macro qset2 bitmask,port,loff;"
    "    str \\bitmask, [\\port, \\loff];"
    "    m0pad;"
    "  .endm;"

    // Load up the next led byte to work with, put it in bn
    "  .macro loadleds3 leds, bn, rled, scratch;"
    "    mov \\scratch, \\leds;"
    "    ldrb \\bn, [\\scratch, \\rled];"
    "  .endm;"

    // check whether or not we should dither
    "  .macro loaddither7 bn,d,base,rdither;"
    "    ldrb \\d, [\\base, \\rdither];"
    "    lsl \\d, #24;"  //; shift high for the qadd w/bn
    "    lsl \\bn, #24;" //; shift high for the qadd w/d
    "    bne chkskip_\\@;" //; if bn==0, clear d;"
    "    eor \\d, \\d;" //; clear d;"
    "    m0pad;"
    "    chkskip_\\@:;"
    "  .endm;"

    // Do the qadd8 for dithering -- there's two versions of this.  The m0 version
    // takes advantage of the 3 cycle branch to do two things after the branch,
    // while keeping timing constant.  The m0+, however, branches in 2 cycles, so
    // we have to work around that a bit more.  This is one of the few times
    // where the m0 will actually be _more_ efficient than the m0+
    "  .macro dither5 bn,d;"
    "  .syntax unified;"
    "    .if fl_is_m0p == 0;"
    "      adds \\bn, \\d;"         // do the add
    "      bcc dither5_1_\\@;"
    "      mvns \\bn, \\bn;"        // set the low 24bits ot 1's
    "      lsls \\bn, \\bn, #24;"   // move low 8 bits to the high bits
    "      dither5_1_\\@:;"
    "      nop;"                    // nop to keep timing in line
    "    .else;"
    "      adds \\bn, \\d;"         // do the add"
    "      bcc dither5_2_\\@;"
    "      mvns \\bn, \\bn;"        // set the low 24bits ot 1's
    "      dither5_2_\\@:;"
    "      bcc dither5_3_\\@;"
    "      lsls \\bn, \\bn, #24;"   // move low 8 bits to the high bits
    "      dither5_3_\\@:;"
    "    .endif;"
    "  .syntax divided;"
    "  .endm;"

    // Do our scaling
    "  .macro scale4 bn, base, scale, scratch;"
    "    ldrb \\scratch, [\\base, \\scale];"
    "    lsr \\bn, \\bn, #24;"                  // bring bn back down to its low 8 bits
    "    mul \\bn, \\scratch;"                  // do the multiply
    "  .endm;"

    // swap bn into b
    "  .macro swapbbn1 b,bn;"
    "    lsl \\b, \\bn, #16;"  // put the 8 bits we want for output high
    "  .endm;"

    // adjust the dithering value for the next time around (load e from memory
    // to do the math)
    "  .macro adjdither7 base,d,rled,eoffset,scratch;"
    "    ldrb \\d, [\\base, \\rled];"
    "    ldrb \\scratch,[\\base,\\eoffset];"          // load e
    "    .syntax unified;"
    "    subs \\d, \\scratch, \\d;"                   // d=e-d
    "    .syntax divided;"
    "    strb \\d, [\\base, \\rled];"                 // save d
    "  .endm;"

    // increment the led pointer (base+9 has what we're incrementing by)
    "  .macro incleds3   leds, base, scratch;"
    "    ldrb \\scratch, [\\base, #9];"               // load incremen
    "    add \\leds, \\leds, \\scratch;"              // update leds pointer
    "  .endm;"

    // compare and loop
    "  .macro cmploop5 counter,label;"
    "    .syntax unified;"
    "    subs \\counter, #1;"
    "    .syntax divided;"
    "    beq done_\\@;"
    "    m0pad;"
    "    b \\label;"
    "    done_\\@:;"
    "  .endm;"

    " .endif;"
  );

#define M0_ASM_ARGS     :             \
      [leds] "+h" (leds),             \
      [counter] "+l" (counter),       \
      [scratch] "+l" (scratch),       \
      [d] "+l" (d),                   \
      [bn] "+l" (bn),                 \
      [b] "+l" (b)                    \
    :                                 \
      [port] "l" (port),              \
      [base] "l" (base),              \
      [bitmask] "l" (bitmask),        \
      [hi_off] "I" (HI_OFFSET),       \
      [lo_off] "I" (LO_OFFSET),       \
      [led0] "I" (RO(0)),             \
      [led1] "I" (RO(1)),             \
      [led2] "I" (RO(2)),             \
      [scale0] "I" (3+RO(0)),         \
      [scale1] "I" (3+RO(1)),         \
      [scale2] "I" (3+RO(2)),         \
      [e0] "I" (6+RO(0)),             \
      [e1] "I" (6+RO(1)),             \
      [e2] "I" (6+RO(2)),             \
      [T1] "I" (T1),                  \
      [T2] "I" (T2),                  \
      [T3] "I" (T3)                   \
    :

    /////////////////////////////////////////////////////////////////////////
    // now for some convinience macros to make building our lines a bit cleaner
#define LOOP            "  loop_%=:"
#define HI2             "  qset2 %[bitmask], %[port], %[hi_off];"
#define D1              "  mod_delay %c[T1],2,0,%[scratch];"
#define QLO4            "  qlo4 %[b],%[bitmask],%[port], %[lo_off];"
#define LOADLEDS3(X)    "  loadleds3 %[leds], %[bn], %[led" #X "] ,%[scratch];"
#define D2(ADJ)         "  mod_delay %c[T2],4," #ADJ ",%[scratch];"
#define LO2             "  qset2 %[bitmask], %[port], %[lo_off];"
#define D3(ADJ)         "  mod_delay %c[T3],2," #ADJ ",%[scratch];"
#define LOADDITHER7(X)  "  loaddither7 %[bn], %[d], %[base], %[led" #X "];"
#define DITHER5         "  dither5 %[bn], %[d];"
#define SCALE4(X)       "  scale4 %[bn], %[base], %[scale" #X "], %[scratch];"
#define SWAPBBN1        "  swapbbn1 %[b], %[bn];"
#define ADJDITHER7(X)   "  adjdither7 %[base],%[d],%[led" #X "],%[e" #X "],%[scratch];"
#define INCLEDS3        "  incleds3 %[leds],%[base],%[scratch];"
#define CMPLOOP5        "  cmploop5 %[counter], loop_%=;"
#define NOTHING         ""

#if !(defined(SEI_CHK) && (FASTLED_ALLOW_INTERRUPTS == 1))
    // We're not allowing interrupts - run the entire loop in asm to keep things
    // as tight as possible.  In an ideal world, we should be pushing out ws281x
    // leds (or other 3-wire leds) with zero gaps between pixels.
    asm __volatile__ (
      // pre-load byte 0
    LOADLEDS3(0) LOADDITHER7(0) DITHER5 SCALE4(0) ADJDITHER7(0) SWAPBBN1

    // loop over writing out the data
    LOOP
      // Write out byte 0, prepping byte 1
      HI2 D1 QLO4 NOTHING         D2(0) LO2 D3(0)
      HI2 D1 QLO4 LOADLEDS3(1)    D2(3) LO2 D3(0)
      HI2 D1 QLO4 LOADDITHER7(1)  D2(7) LO2 D3(0)
      HI2 D1 QLO4 DITHER5         D2(5) LO2 D3(0)
      HI2 D1 QLO4 SCALE4(1)       D2(4) LO2 D3(0)
      HI2 D1 QLO4 ADJDITHER7(1)   D2(7) LO2 D3(0)
      HI2 D1 QLO4 NOTHING         D2(0) LO2 D3(0)
      HI2 D1 QLO4 SWAPBBN1        D2(1) LO2 D3(0)

      // Write out byte 1, prepping byte 2
      HI2 D1 QLO4 NOTHING         D2(0) LO2 D3(0)
      HI2 D1 QLO4 LOADLEDS3(2)    D2(3) LO2 D3(0)
      HI2 D1 QLO4 LOADDITHER7(2)  D2(7) LO2 D3(0)
      HI2 D1 QLO4 DITHER5         D2(5) LO2 D3(0)
      HI2 D1 QLO4 SCALE4(2)       D2(4) LO2 D3(0)
      HI2 D1 QLO4 ADJDITHER7(2)   D2(7) LO2 D3(0)
      HI2 D1 QLO4 INCLEDS3        D2(3) LO2 D3(0)
      HI2 D1 QLO4 SWAPBBN1        D2(1) LO2 D3(0)

      // Write out byte 2, prepping byte 0
      HI2 D1 QLO4 NOTHING         D2(0) LO2 D3(0)
      HI2 D1 QLO4 LOADLEDS3(0)    D2(3) LO2 D3(0)
      HI2 D1 QLO4 LOADDITHER7(0)  D2(7) LO2 D3(0)
      HI2 D1 QLO4 DITHER5         D2(5) LO2 D3(0)
      HI2 D1 QLO4 SCALE4(0)       D2(4) LO2 D3(0)
      HI2 D1 QLO4 ADJDITHER7(0)   D2(7) LO2 D3(0)
      HI2 D1 QLO4 NOTHING         D2(0) LO2 D3(0)
      HI2 D1 QLO4 SWAPBBN1        D2(1) LO2 D3(5) CMPLOOP5

      M0_ASM_ARGS
    );
#else
    // We're allowing interrupts - track the loop outside the asm code, to allow
    // inserting the interrupt overrun checks.
    asm __volatile__ (
      // pre-load byte 0
      LOADLEDS3(0) LOADDITHER7(0) DITHER5 SCALE4(0) ADJDITHER7(0) SWAPBBN1
      M0_ASM_ARGS);

    do {
      asm __volatile__ (
      // Write out byte 0, prepping byte 1
      HI2 D1 QLO4 NOTHING         D2(0) LO2 D3(0)
      HI2 D1 QLO4 LOADLEDS3(1)    D2(3) LO2 D3(0)
      HI2 D1 QLO4 LOADDITHER7(1)  D2(7) LO2 D3(0)
      HI2 D1 QLO4 DITHER5         D2(5) LO2 D3(0)
      HI2 D1 QLO4 SCALE4(1)       D2(4) LO2 D3(0)
      HI2 D1 QLO4 ADJDITHER7(1)   D2(7) LO2 D3(0)
      HI2 D1 QLO4 NOTHING         D2(0) LO2 D3(0)
      HI2 D1 QLO4 SWAPBBN1        D2(1) LO2 D3(0)

      // Write out byte 1, prepping byte 2
      HI2 D1 QLO4 NOTHING         D2(0) LO2 D3(0)
      HI2 D1 QLO4 LOADLEDS3(2)    D2(3) LO2 D3(0)
      HI2 D1 QLO4 LOADDITHER7(2)  D2(7) LO2 D3(0)
      HI2 D1 QLO4 DITHER5         D2(5) LO2 D3(0)
      HI2 D1 QLO4 SCALE4(2)       D2(4) LO2 D3(0)
      HI2 D1 QLO4 ADJDITHER7(2)   D2(7) LO2 D3(0)
      HI2 D1 QLO4 INCLEDS3        D2(3) LO2 D3(0)
      HI2 D1 QLO4 SWAPBBN1        D2(1) LO2 D3(0)

      // Write out byte 2, prepping byte 0
      HI2 D1 QLO4 NOTHING         D2(0) LO2 D3(0)
      HI2 D1 QLO4 LOADLEDS3(0)    D2(3) LO2 D3(0)
      HI2 D1 QLO4 LOADDITHER7(0)  D2(7) LO2 D3(0)
      HI2 D1 QLO4 DITHER5         D2(5) LO2 D3(0)
      HI2 D1 QLO4 SCALE4(0)       D2(4) LO2 D3(0)
      HI2 D1 QLO4 ADJDITHER7(0)   D2(7) LO2 D3(0)
      HI2 D1 QLO4 NOTHING         D2(0) LO2 D3(0)
      HI2 D1 QLO4 SWAPBBN1        D2(1) LO2 D3(5)

      M0_ASM_ARGS
      );
      SEI_CHK; INNER_SEI; --counter; CLI_CHK;
    } while(counter);
#endif
    return num_leds;
}

#endif


<|start_filename|>Firmware/Source/bakebit_v1.0.0/FastLED-FastLED3.1/platforms/arm/d21/led_sysdefs_arm_d21.h<|end_filename|>
#ifndef __INC_LED_SYSDEFS_ARM_D21_H
#define __INC_LED_SYSDEFS_ARM_D21_H


#define FASTLED_ARM
#define FASTLED_ARM_M0_PLUS

#ifndef INTERRUPT_THRESHOLD
#define INTERRUPT_THRESHOLD 1
#endif

// Default to allowing interrupts
#ifndef FASTLED_ALLOW_INTERRUPTS
#define FASTLED_ALLOW_INTERRUPTS 0
#endif

#if FASTLED_ALLOW_INTERRUPTS == 1
#define FASTLED_ACCURATE_CLOCK
#endif

// reuseing/abusing cli/sei defs for due
#define cli()  __disable_irq();
#define sei() __enable_irq();


#endif


<|start_filename|>Software/C/bakebit_digital_write.c<|end_filename|>
//BakeBit Example for using the digital write command
#include "bakebit.h"
//gcc bakebit_digital_write.c bakebit.c -Wall

int main(void)
{		
	//Exit on failure to start communications with the BakeBit
	if(init()==-1)
		exit(1);
	
	//Set pin mode to output
	pinMode(4,1);
	while(1)
	{
		digitalWrite(4,1);
		pi_sleep(500);
		digitalWrite(4,0);
		pi_sleep(500);
	}
   	return 1;
}


<|start_filename|>Software/C/bakebit_digital_read.c<|end_filename|>
// BakeBit Example for using the digital read command

#include "bakebit.h"
//gcc bakebit_digital_read.c bakebit.c -Wall
int main(void)
{		
	int dval;
	
	//Exit on failure to start communications with the BakeBit
	if(init()==-1)
		exit(1);
	
	//Set pin mode to input
	pinMode(4,0);
	while(1)
	{
		dval=digitalRead(2);
		printf("Digital read %d\n", dval);
		//Sleep for 50ms
		pi_sleep(50);
	}
   	return 1;
}


<|start_filename|>Software/C/bakebit_analog_read.c<|end_filename|>
// BakeBit Example for using the analog read.

#include "bakebit.h"

int main(void)
{		
	int adata;
	
	//Exit on failure to start communications with the BakeBit
	if(init()==-1)
		exit(1);
	
	while(1)
	{
		adata=analogRead(0);
		printf("analog read %d\n",adata);
		if(adata==-1)
			printf("IO Error");
	}
   	return 1;
}


<|start_filename|>Firmware/Source/bakebit_v1.0.0/FastLED-FastLED3.1/platforms/arm/d21/fastpin_arm_d21.h<|end_filename|>
#ifndef __INC_FASTPIN_ARM_SAM_H
#define __INC_FASTPIN_ARM_SAM_H

FASTLED_NAMESPACE_BEGIN

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

#else

/// 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, uint8_t _BIT, uint32_t _MASK, int _GRP> class _ARMPIN {
public:
  typedef volatile uint32_t * port_ptr_t;
  typedef uint32_t port_t;

  #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->Group[_GRP].OUTSET.reg = _MASK; }
  inline static void lo() __attribute__ ((always_inline)) { PORT->Group[_GRP].OUTCLR.reg = _MASK; }
  // inline static void lo() __attribute__ ((always_inline)) { PORT->Group[_GRP].BSRR = (_MASK<<16); }
  inline static void set(register port_t val) __attribute__ ((always_inline)) { PORT->Group[_GRP].OUT.reg = val; }

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

  inline static void toggle() __attribute__ ((always_inline)) { PORT->Group[_GRP].OUTTGL.reg = _MASK; }

  inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); }
  inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); }
  inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; }

  inline static port_t hival() __attribute__ ((always_inline)) { return PORT->Group[_GRP].OUT.reg | _MASK; }
  inline static port_t loval() __attribute__ ((always_inline)) { return PORT->Group[_GRP].OUT.reg & ~_MASK; }
  inline static port_ptr_t port() __attribute__ ((always_inline)) { return &PORT->Group[_GRP].OUT.reg; }
  inline static port_ptr_t sport() __attribute__ ((always_inline)) { return &PORT->Group[_GRP].OUTSET.reg; }
  inline static port_ptr_t cport() __attribute__ ((always_inline)) { return &PORT->Group[_GRP].OUTCLR.reg; }
  inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; }
};

#define _R(T) struct __gen_struct_ ## T
#define _RD32(T) struct __gen_struct_ ## T { static __attribute__((always_inline)) inline volatile PortGroup * r() { return T; } };

#define _IO32(L) _RD32(GPIO ## L)

#define _DEFPIN_ARM(PIN, L, BIT) template<> class FastPin<PIN> : public _ARMPIN<PIN, BIT, 1 << BIT, L> {};

// Actual pin definitions
#if defined(ARDUINO_SAMD_ZERO)

#define MAX_PIN 42
_DEFPIN_ARM( 0,0,10); _DEFPIN_ARM( 1,0,11); _DEFPIN_ARM( 2,0, 8); _DEFPIN_ARM( 3,0, 9);
_DEFPIN_ARM( 4,0,14); _DEFPIN_ARM( 5,0,15); _DEFPIN_ARM( 6,0,20); _DEFPIN_ARM( 7,0,21);
_DEFPIN_ARM( 8,0, 6); _DEFPIN_ARM( 9,0, 7); _DEFPIN_ARM(10,0,18); _DEFPIN_ARM(11,0,16);
_DEFPIN_ARM(12,0,19); _DEFPIN_ARM(13,0,17); _DEFPIN_ARM(14,0, 2); _DEFPIN_ARM(15,1, 8);
_DEFPIN_ARM(16,1, 9); _DEFPIN_ARM(17,0, 4); _DEFPIN_ARM(18,0, 5); _DEFPIN_ARM(19,1, 2);
_DEFPIN_ARM(20,0,22); _DEFPIN_ARM(21,0,23); _DEFPIN_ARM(22,0,12); _DEFPIN_ARM(23,1,11);
_DEFPIN_ARM(24,1,10); _DEFPIN_ARM(25,1, 3); _DEFPIN_ARM(26,0,27); _DEFPIN_ARM(27,0,28);
_DEFPIN_ARM(28,0,24); _DEFPIN_ARM(29,0,25); _DEFPIN_ARM(30,1,22); _DEFPIN_ARM(31,1,23);
_DEFPIN_ARM(32,0,22); _DEFPIN_ARM(33,0,23); _DEFPIN_ARM(34,0,19); _DEFPIN_ARM(35,0,16);
_DEFPIN_ARM(36,0,18); _DEFPIN_ARM(37,0,17); _DEFPIN_ARM(38,0,13); _DEFPIN_ARM(39,0,21);
_DEFPIN_ARM(40,0, 6); _DEFPIN_ARM(41,0, 7); _DEFPIN_ARM(42,0, 3);

#define SPI_DATA 24
#define SPI_CLOCK 23

#define HAS_HARDWARE_PIN_SUPPORT

#endif



#endif // FASTLED_FORCE_SOFTWARE_PINS

FASTLED_NAMESPACE_END


#endif // __INC_FASTPIN_ARM_SAM_H


<|start_filename|>Firmware/Source/bakebit_v1.0.0/FastLED-FastLED3.1/platforms/arm/k20/octows2811_controller.h<|end_filename|>
#ifndef __INC_OCTOWS2811_CONTROLLER_H
#define __INC_OCTOWS2811_CONTROLLER_H

#ifdef USE_OCTOWS2811

// #include "OctoWS2811.h"

FASTLED_NAMESPACE_BEGIN

template<EOrder RGB_ORDER = GRB, boolean SLOW=false>
class COctoWS2811Controller : public CLEDController {
  OctoWS2811  *pocto;
  uint8_t *drawbuffer,*framebuffer;

  void _init(int nLeds) {
    if(pocto == NULL) {
      drawbuffer = (uint8_t*)malloc(nLeds * 8 * 3);
      framebuffer = (uint8_t*)malloc(nLeds * 8 * 3);

      // byte ordering is handled in show by the pixel controller
      int config = WS2811_RGB;
      if(SLOW) {
        config |= WS2811_400kHz;
      }

      pocto = new OctoWS2811(nLeds, framebuffer, drawbuffer, config);

      pocto->begin();
    }
  }
public:
  COctoWS2811Controller() { pocto = NULL; }


  virtual void init() { /* do nothing yet */ }

  virtual void clearLeds(int nLeds) {
    _init(nLeds);
    showColor(CRGB(0,0,0),nLeds,CRGB(0,0,0));
  }

  virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) {
    _init(nLeds);
    // Get our pixel values
    PixelController<RGB_ORDER> pixels(data, nLeds, scale, getDither());
    uint8_t ball[3][8];
    memset(ball[0],pixels.loadAndScale0(),8);
    memset(ball[1],pixels.loadAndScale1(),8);
    memset(ball[2],pixels.loadAndScale2(),8);

    uint8_t bout[24];
    transpose8x1_MSB(ball[0],bout);
    transpose8x1_MSB(ball[1],bout+8);
    transpose8x1_MSB(ball[2],bout+16);

    uint8_t *pdata = drawbuffer;
    while(nLeds--) {
      memcpy(pdata,bout,24);
      pdata += 24;
    }

    pocto->show();
  }

  typedef union {
    uint8_t bytes[8];
    uint32_t raw[2];
  } Lines;

  virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale) {
    _init(nLeds);
    MultiPixelController<8,0xFF,RGB_ORDER> pixels(rgbdata,nLeds, scale, getDither() );

    uint8_t *pData = drawbuffer;
    while(nLeds--) {
      Lines b;

      for(int i = 0; i < 8; i++) { b.bytes[i] = pixels.loadAndScale0(i); }
      transpose8x1_MSB(b.bytes,pData); pData += 8;
      for(int i = 0; i < 8; i++) { b.bytes[i] = pixels.loadAndScale1(i); }
      transpose8x1_MSB(b.bytes,pData); pData += 8;
      for(int i = 0; i < 8; i++) { b.bytes[i] = pixels.loadAndScale2(i); }
      transpose8x1_MSB(b.bytes,pData); pData += 8;
      pixels.stepDithering();
      pixels.advanceData();
    }

    pocto->show();
  }
};

FASTLED_NAMESPACE_END

#endif

#endif


<|start_filename|>Firmware/Source/bakebit_v1.0.0/FastLED-FastLED3.1/platforms/arm/k20/clockless_block_arm_k20.h<|end_filename|>
#ifndef __INC_BLOCK_CLOCKLESS_ARM_K20_H
#define __INC_BLOCK_CLOCKLESS_ARM_K20_H

// Definition for a single channel clockless controller for the k20 family of chips, like that used in the teensy 3.0/3.1
// See clockless.h for detailed info on how the template parameters are used.
#if defined(FASTLED_TEENSY3)
#define FASTLED_HAS_BLOCKLESS 1

#define PORTC_FIRST_PIN 15
#define PORTD_FIRST_PIN 2
#define HAS_PORTDC 1

#define PORT_MASK (((1<<LANES)-1) & ((FIRST_PIN==2) ? 0xFF : 0xFFF))

#define MIN(X,Y) (((X)<(Y)) ? (X):(Y))
#define LANES ((FIRST_PIN==2) ? MIN(__LANES,8) : MIN(__LANES,12))

#include "kinetis.h"

FASTLED_NAMESPACE_BEGIN

template <uint8_t __LANES, int FIRST_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = GRB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 40>
class InlineBlockClocklessController : public CLEDController {
	typedef typename FastPin<FIRST_PIN>::port_ptr_t data_ptr_t;
	typedef typename FastPin<FIRST_PIN>::port_t data_t;

	data_t mPinMask;
	data_ptr_t mPort;
	CMinWait<WAIT_TIME> mWait;
public:
	virtual void init() {
		if(FIRST_PIN == PORTC_FIRST_PIN) { // PORTC
			switch(LANES) {
				case 12: FastPin<30>::setOutput();
				case 11: FastPin<29>::setOutput();
				case 10: FastPin<27>::setOutput();
				case 9: FastPin<28>::setOutput();
				case 8: FastPin<12>::setOutput();
				case 7: FastPin<11>::setOutput();
				case 6: FastPin<13>::setOutput();
				case 5: FastPin<10>::setOutput();
				case 4: FastPin<9>::setOutput();
				case 3: FastPin<23>::setOutput();
				case 2: FastPin<22>::setOutput();
				case 1: FastPin<15>::setOutput();
			}
		} else if(FIRST_PIN == PORTD_FIRST_PIN) { // PORTD
			switch(LANES) {
				case 8: FastPin<5>::setOutput();
				case 7: FastPin<21>::setOutput();
				case 6: FastPin<20>::setOutput();
				case 5: FastPin<6>::setOutput();
				case 4: FastPin<8>::setOutput();
				case 3: FastPin<7>::setOutput();
				case 2: FastPin<14>::setOutput();
				case 1: FastPin<2>::setOutput();
			}
		}
		mPinMask = FastPin<FIRST_PIN>::mask();
		mPort = FastPin<FIRST_PIN>::port();
	}

	virtual uint16_t getMaxRefreshRate() const { return 400; }

	virtual void clearLeds(int nLeds) {
		showColor(CRGB(0, 0, 0), nLeds, 0);
	}

	// set all the leds on the controller to a given color
	virtual void showColor(const struct CRGB & rgbdata, int nLeds, CRGB scale) {
		MultiPixelController<LANES,PORT_MASK,RGB_ORDER> pixels(rgbdata,nLeds, scale, getDither() );
		mWait.wait();
		uint32_t clocks = showRGBInternal(pixels,nLeds);
		#if FASTLED_ALLOW_INTTERUPTS == 0
		// Adjust the timer
		long microsTaken = CLKS_TO_MICROS(clocks);
		MS_COUNTER += (1 + (microsTaken / 1000));
		#endif

		mWait.mark();
	}

	virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale) {
		MultiPixelController<LANES,PORT_MASK,RGB_ORDER> pixels(rgbdata,nLeds, scale, getDither() );
		mWait.wait();
		uint32_t clocks = showRGBInternal(pixels,nLeds);
		#if FASTLED_ALLOW_INTTERUPTS == 0
		// Adjust the timer
		long microsTaken = CLKS_TO_MICROS(clocks);
		MS_COUNTER += (1 + (microsTaken / 1000));
		#endif

		mWait.mark();
	}

#ifdef SUPPORT_ARGB
	virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale) {
		MultiPixelController<LANES,PORT_MASK,RGB_ORDER> pixels(rgbdata,nLeds, scale, getDither() );
		mWait.wait();
		uint32_t clocks = showRGBInternal(pixels,nLeds);

		#if FASTLED_ALLOW_INTTERUPTS == 0
		// Adjust the timer
		long microsTaken = CLKS_TO_MICROS(clocks);
		MS_COUNTER += (1 + (microsTaken / 1000));
		#endif

		mWait.mark();
	}
#endif


	typedef union {
		uint8_t bytes[12];
		uint16_t shorts[6];
		uint32_t raw[3];
	} Lines;

	template<int BITS,int PX> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register Lines & b, MultiPixelController<LANES, PORT_MASK, RGB_ORDER> &pixels) { // , register uint32_t & b2)  {
		register Lines b2;
		if(LANES>8) {
			transpose8<1,2>(b.bytes,b2.bytes);
			transpose8<1,2>(b.bytes+8,b2.bytes+1);
		} else {
			transpose8x1(b.bytes,b2.bytes);
		}
		register uint8_t d = pixels.template getd<PX>(pixels);
		register uint8_t scale = pixels.template getscale<PX>(pixels);

		for(register uint32_t i = 0; i < (LANES/2); i++) {
			while(ARM_DWT_CYCCNT < next_mark);
			next_mark = ARM_DWT_CYCCNT + (T1+T2+T3)-3;
			*FastPin<FIRST_PIN>::sport() = PORT_MASK;

			while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+(2*(F_CPU/24000000))));
			if(LANES>8) {
				*FastPin<FIRST_PIN>::cport() = ((~b2.shorts[i]) & PORT_MASK);
			} else {
				*FastPin<FIRST_PIN>::cport() = ((~b2.bytes[7-i]) & PORT_MASK);
			}

			while((next_mark - ARM_DWT_CYCCNT) > (T3));
			*FastPin<FIRST_PIN>::cport() = PORT_MASK;

			b.bytes[i] = pixels.template loadAndScale<PX>(pixels,i,d,scale);
			b.bytes[i+(LANES/2)] = pixels.template loadAndScale<PX>(pixels,i+(LANES/2),d,scale);
		}

		// if folks use an odd numnber of lanes, get the last byte's value here
		if(LANES & 0x01) {
			b.bytes[LANES-1] = pixels.template loadAndScale<PX>(pixels,LANES-1,d,scale);
		}

		for(register uint32_t i = LANES/2; i < 8; i++) {
			while(ARM_DWT_CYCCNT < next_mark);
			next_mark = ARM_DWT_CYCCNT + (T1+T2+T3)-3;
			*FastPin<FIRST_PIN>::sport() = PORT_MASK;
			while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+(2*(F_CPU/24000000))));
			if(LANES>8) {
				*FastPin<FIRST_PIN>::cport() = ((~b2.shorts[i]) & PORT_MASK);
			} else {
				// b2.bytes[0] = 0;
				*FastPin<FIRST_PIN>::cport() = ((~b2.bytes[7-i]) & PORT_MASK);
			}

			while((next_mark - ARM_DWT_CYCCNT) > (T3));
			*FastPin<FIRST_PIN>::cport() = PORT_MASK;

		}


		// while(ARM_DWT_CYCCNT < next_mark);
		// next_mark = ARM_DWT_CYCCNT + (T1+T2+T3)-3;
		// *FastPin<FIRST_PIN>::sport() = PORT_MASK;
		//
		// while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+6));
		// if(LANES>8) {
		// 	*FastPin<FIRST_PIN>::cport() = ((~b2.shorts[7]) & PORT_MASK);
		// } else {
		// 	*FastPin<FIRST_PIN>::cport() = PORT_MASK; // ((~b2.bytes[7-i]) & PORT_MASK);
		// }
		//
		// while((next_mark - ARM_DWT_CYCCNT) > (T3));
		// *FastPin<FIRST_PIN>::cport() = PORT_MASK;
	}



	// 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(MultiPixelController<LANES, PORT_MASK, RGB_ORDER> &allpixels, int nLeds) {
		// Get access to the clock
		ARM_DEMCR    |= ARM_DEMCR_TRCENA;
		ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
		ARM_DWT_CYCCNT = 0;

		// Setup the pixel controller and load/scale the first byte
		allpixels.preStepFirstByteDithering();
		register Lines b0;

		allpixels.preStepFirstByteDithering();
		for(int i = 0; i < LANES; i++) {
			b0.bytes[i] = allpixels.loadAndScale0(i);
		}

		cli();
		uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3);

		while(nLeds--) {
			#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-5)*CLKS_PER_US)) { sei(); return ARM_DWT_CYCCNT; }
			}
			#endif
			allpixels.stepDithering();

			// Write first byte, read next byte
			writeBits<8+XTRA0,1>(next_mark, b0, allpixels);

			// Write second byte, read 3rd byte
			writeBits<8+XTRA0,2>(next_mark, b0, allpixels);
			allpixels.advanceData();

			// Write third byte
			writeBits<8+XTRA0,0>(next_mark, b0, allpixels);
			#if (FASTLED_ALLOW_INTERRUPTS == 1)
			sei();
			#endif
		};

		return ARM_DWT_CYCCNT;
	}
};

#define DLANES (MIN(__LANES,16))
#define PMASK ((1<<(DLANES))-1)
#define PMASK_HI (PMASK>>8 & 0xFF)
#define PMASK_LO (PMASK & 0xFF)

template <uint8_t __LANES, int T1, int T2, int T3, EOrder RGB_ORDER = GRB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50>
class SixteenWayInlineBlockClocklessController : public CLEDController {
	typedef typename FastPin<PORTC_FIRST_PIN>::port_ptr_t data_ptr_t;
	typedef typename FastPin<PORTC_FIRST_PIN>::port_t data_t;

	data_t mPinMask;
	data_ptr_t mPort;
	CMinWait<WAIT_TIME> mWait;
public:
	virtual void init() {
				// FastPin<30>::setOutput();
				// FastPin<29>::setOutput();
				// FastPin<27>::setOutput();
				// FastPin<28>::setOutput();
				switch(DLANES) {
					case 16: FastPin<12>::setOutput();
					case 15: FastPin<11>::setOutput();
					case 14: FastPin<13>::setOutput();
					case 13: FastPin<10>::setOutput();
					case 12: FastPin<9>::setOutput();
					case 11: FastPin<23>::setOutput();
					case 10: FastPin<22>::setOutput();
					case 9:  FastPin<15>::setOutput();

					case 8:  FastPin<5>::setOutput();
					case 7:  FastPin<21>::setOutput();
					case 6:  FastPin<20>::setOutput();
					case 5:  FastPin<6>::setOutput();
					case 4:  FastPin<8>::setOutput();
					case 3:  FastPin<7>::setOutput();
					case 2:  FastPin<14>::setOutput();
					case 1:  FastPin<2>::setOutput();
				}
	}

	virtual void clearLeds(int nLeds) {
		showColor(CRGB(0, 0, 0), nLeds, 0);
	}

	// set all the leds on the controller to a given color
	virtual void showColor(const struct CRGB & rgbdata, int nLeds, CRGB scale) {
		MultiPixelController<DLANES,PMASK,RGB_ORDER> pixels(rgbdata,nLeds, scale, getDither() );
		mWait.wait();
		showRGBInternal(pixels,nLeds);
		mWait.mark();
	}

	virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale) {
		MultiPixelController<DLANES,PMASK,RGB_ORDER> pixels(rgbdata,nLeds, scale, getDither() );
		mWait.wait();
		showRGBInternal(pixels,nLeds);
		mWait.mark();
	}

#ifdef SUPPORT_ARGB
	virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale) {
		MultiPixelController<DLANES,PMASK,RGB_ORDER> pixels(rgbdata,nLeds, scale, getDither() );
		mWait.wait();
		showRGBInternal(pixels,nLeds);
		mWait.mark();
	}
#endif


	typedef union {
		uint8_t bytes[16];
		uint16_t shorts[8];
		uint32_t raw[4];
	} Lines;

	template<int BITS,int PX> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register Lines & b, MultiPixelController<DLANES, PMASK, RGB_ORDER> &pixels) { // , register uint32_t & b2)  {
		register Lines b2;
		transpose8x1(b.bytes,b2.bytes);
		transpose8x1(b.bytes+8,b2.bytes+8);
		register uint8_t d = pixels.template getd<PX>(pixels);
		register uint8_t scale = pixels.template getscale<PX>(pixels);

		for(register uint32_t i = 0; (i < DLANES) && (i < 8); i++) {
			while(ARM_DWT_CYCCNT < next_mark);
			next_mark = ARM_DWT_CYCCNT + (T1+T2+T3)-3;
			*FastPin<PORTD_FIRST_PIN>::sport() = PMASK_LO;
			*FastPin<PORTC_FIRST_PIN>::sport() = PMASK_HI;

			while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+6));
			*FastPin<PORTD_FIRST_PIN>::cport() = ((~b2.bytes[7-i]) & PMASK_LO);
			*FastPin<PORTC_FIRST_PIN>::cport() = ((~b2.bytes[15-i]) & PMASK_HI);

			while((next_mark - ARM_DWT_CYCCNT) > (T3));
			*FastPin<PORTD_FIRST_PIN>::cport() = PMASK_LO;
			*FastPin<PORTC_FIRST_PIN>::cport() = PMASK_HI;

			b.bytes[i] = pixels.template loadAndScale<PX>(pixels,i,d,scale);
			if(DLANES==16 || (DLANES>8 && ((i+8) < DLANES))) {
				b.bytes[i+8] = pixels.template loadAndScale<PX>(pixels,i+8,d,scale);
			}
		}
	}



	// 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(MultiPixelController<DLANES, PMASK, RGB_ORDER> &allpixels, int nLeds) {
		// Get access to the clock
		ARM_DEMCR    |= ARM_DEMCR_TRCENA;
		ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
		ARM_DWT_CYCCNT = 0;

		// Setup the pixel controller and load/scale the first byte
		allpixels.preStepFirstByteDithering();
		register Lines b0;

		allpixels.preStepFirstByteDithering();
		for(int i = 0; i < DLANES; i++) {
			b0.bytes[i] = allpixels.loadAndScale0(i);
		}

		cli();
		uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3);

		while(nLeds--) {
			allpixels.stepDithering();
			#if 0 && (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 ARM_DWT_CYCCNT; }
			}
			#endif

			// Write first byte, read next byte
			writeBits<8+XTRA0,1>(next_mark, b0, allpixels);

			// Write second byte, read 3rd byte
			writeBits<8+XTRA0,2>(next_mark, b0, allpixels);
			allpixels.advanceData();

			// Write third byte
			writeBits<8+XTRA0,0>(next_mark, b0, allpixels);

			#if 0 && (FASTLED_ALLOW_INTERRUPTS == 1)
			sei();
			#endif
		};
		sei();

		return ARM_DWT_CYCCNT;
	}
};

FASTLED_NAMESPACE_END

#endif

#endif


<|start_filename|>Firmware/Source/bakebit_v1.0.0/FastLED-FastLED3.1/fastspi_bitbang.h<|end_filename|>
#ifndef __INC_FASTSPI_BITBANG_H
#define __INC_FASTSPI_BITBANG_H

#include "fastled_delay.h"

FASTLED_NAMESPACE_BEGIN

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Software SPI (aka bit-banging) support - with aggressive optimizations for when the clock and data pin are on the same port
//
// TODO: Replace the select pin definition with a set of pins, to allow using mux hardware for routing in the future
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, uint8_t SPI_SPEED>
class AVRSoftwareSPIOutput {
	// The data types for pointers to the pin port - typedef'd here from the Pin definition because on avr these
	// are pointers to 8 bit values, while on arm they are 32 bit
	typedef typename FastPin<DATA_PIN>::port_ptr_t data_ptr_t;
	typedef typename FastPin<CLOCK_PIN>::port_ptr_t clock_ptr_t;

	// The data type for what's at a pin's port - typedef'd here from the Pin definition because on avr the ports
	// are 8 bits wide while on arm they are 32.
	typedef typename FastPin<DATA_PIN>::port_t data_t;
	typedef typename FastPin<CLOCK_PIN>::port_t clock_t;
	Selectable 	*m_pSelect;

public:
	AVRSoftwareSPIOutput() { m_pSelect = NULL; }
	AVRSoftwareSPIOutput(Selectable *pSelect) { m_pSelect = pSelect; }
	void setSelect(Selectable *pSelect) { m_pSelect = pSelect; }

	void init() {
		// set the pins to output and make sure the select is released (which apparently means hi?  This is a bit
		// confusing to me)
		FastPin<DATA_PIN>::setOutput();
		FastPin<CLOCK_PIN>::setOutput();
		release();
	}

	// stop the SPI output.  Pretty much a NOP with software, as there's no registers to kick
	static void stop() { }

	// wait until the SPI subsystem is ready for more data to write.  A NOP when bitbanging
	static void wait() __attribute__((always_inline)) { }
	static void waitFully() __attribute__((always_inline)) { wait(); }

	static void writeByteNoWait(uint8_t b) __attribute__((always_inline)) { writeByte(b); }
	static void writeBytePostWait(uint8_t b) __attribute__((always_inline)) { writeByte(b); wait(); }

	static void writeWord(uint16_t w) __attribute__((always_inline)) { writeByte(w>>8); writeByte(w&0xFF); }

	// naive writeByte implelentation, simply calls writeBit on the 8 bits in the byte.
	static void writeByte(uint8_t b) {
		writeBit<7>(b);
		writeBit<6>(b);
		writeBit<5>(b);
		writeBit<4>(b);
		writeBit<3>(b);
		writeBit<2>(b);
		writeBit<1>(b);
		writeBit<0>(b);
	}

private:
	// writeByte implementation with data/clock registers passed in.
	static void writeByte(uint8_t b, clock_ptr_t clockpin, data_ptr_t datapin)  {
		writeBit<7>(b, clockpin, datapin);
		writeBit<6>(b, clockpin, datapin);
		writeBit<5>(b, clockpin, datapin);
		writeBit<4>(b, clockpin, datapin);
		writeBit<3>(b, clockpin, datapin);
		writeBit<2>(b, clockpin, datapin);
		writeBit<1>(b, clockpin, datapin);
		writeBit<0>(b, clockpin, datapin);
	}

	// writeByte implementation with the data register passed in and prebaked values for data hi w/clock hi and
	// low and data lo w/clock hi and lo.  This is to be used when clock and data are on the same GPIO register,
	// can get close to getting a bit out the door in 2 clock cycles!
	static void writeByte(uint8_t b, data_ptr_t datapin,
						  data_t hival, data_t loval,
						  clock_t hiclock, clock_t loclock) {
		writeBit<7>(b, datapin, hival, loval, hiclock, loclock);
		writeBit<6>(b, datapin, hival, loval, hiclock, loclock);
		writeBit<5>(b, datapin, hival, loval, hiclock, loclock);
		writeBit<4>(b, datapin, hival, loval, hiclock, loclock);
		writeBit<3>(b, datapin, hival, loval, hiclock, loclock);
		writeBit<2>(b, datapin, hival, loval, hiclock, loclock);
		writeBit<1>(b, datapin, hival, loval, hiclock, loclock);
		writeBit<0>(b, datapin, hival, loval, hiclock, loclock);
	}

	// writeByte implementation with not just registers passed in, but pre-baked values for said registers for
	// data hi/lo and clock hi/lo values.  Note: weird things will happen if this method is called in cases where
	// the data and clock pins are on the same port!  Don't do that!
	static void writeByte(uint8_t b, clock_ptr_t clockpin, data_ptr_t datapin,
						  data_t hival, data_t loval,
						  clock_t hiclock, clock_t loclock) {
		writeBit<7>(b, clockpin, datapin, hival, loval, hiclock, loclock);
		writeBit<6>(b, clockpin, datapin, hival, loval, hiclock, loclock);
		writeBit<5>(b, clockpin, datapin, hival, loval, hiclock, loclock);
		writeBit<4>(b, clockpin, datapin, hival, loval, hiclock, loclock);
		writeBit<3>(b, clockpin, datapin, hival, loval, hiclock, loclock);
		writeBit<2>(b, clockpin, datapin, hival, loval, hiclock, loclock);
		writeBit<1>(b, clockpin, datapin, hival, loval, hiclock, loclock);
		writeBit<0>(b, clockpin, datapin, hival, loval, hiclock, loclock);
	}

public:
	#define SPI_DELAY delaycycles<1+((SPI_SPEED-2) / 2)>();
	#define SPI_DELAY_HALF delaycycles<1+ ((SPI_SPEED-4) / 4)>();

	// write the BIT'th bit out via spi, setting the data pin then strobing the clcok
	template <uint8_t BIT> __attribute__((always_inline, hot)) inline static void writeBit(uint8_t b) {
		if(b & (1 << BIT)) {
			FastPin<DATA_PIN>::hi();
			FastPin<CLOCK_PIN>::hi(); SPI_DELAY;
			FastPin<CLOCK_PIN>::lo(); SPI_DELAY;
		} else {
			FastPin<DATA_PIN>::lo();
			FastPin<CLOCK_PIN>::hi(); SPI_DELAY;
			FastPin<CLOCK_PIN>::lo(); SPI_DELAY;
		}
	}

private:
	// write the BIT'th bit out via spi, setting the data pin then strobing the clock, using the passed in pin registers to accelerate access if needed
	template <uint8_t BIT> __attribute__((always_inline)) inline static void writeBit(uint8_t b, clock_ptr_t clockpin, data_ptr_t datapin) {
		if(b & (1 << BIT)) {
			FastPin<DATA_PIN>::hi(datapin);
			FastPin<CLOCK_PIN>::hi(clockpin); SPI_DELAY;
			FastPin<CLOCK_PIN>::lo(clockpin); SPI_DELAY;
		} else {
			FastPin<DATA_PIN>::lo(datapin);
			FastPin<CLOCK_PIN>::hi(clockpin); SPI_DELAY;
			FastPin<CLOCK_PIN>::lo(clockpin); SPI_DELAY;
		}

	}

	// the version of write to use when clock and data are on separate pins with precomputed values for setting
	// the clock and data pins
	template <uint8_t BIT> __attribute__((always_inline)) inline static void writeBit(uint8_t b, clock_ptr_t clockpin, data_ptr_t datapin,
													data_t hival, data_t loval, clock_t hiclock, clock_t loclock) {
		// // only need to explicitly set clock hi if clock and data are on different ports
		if(b & (1 << BIT)) {
			FastPin<DATA_PIN>::fastset(datapin, hival);
			FastPin<CLOCK_PIN>::fastset(clockpin, hiclock); SPI_DELAY;
			FastPin<CLOCK_PIN>::fastset(clockpin, loclock); SPI_DELAY;
		} else {
			// NOP;
			FastPin<DATA_PIN>::fastset(datapin, loval);
			FastPin<CLOCK_PIN>::fastset(clockpin, hiclock); SPI_DELAY;
			FastPin<CLOCK_PIN>::fastset(clockpin, loclock); SPI_DELAY;
		}
	}

	// the version of write to use when clock and data are on the same port with precomputed values for the various
	// combinations
	template <uint8_t BIT> __attribute__((always_inline)) inline static void writeBit(uint8_t b, data_ptr_t clockdatapin,
													data_t datahiclockhi, data_t dataloclockhi,
													data_t datahiclocklo, data_t dataloclocklo) {
#if 0
		writeBit<BIT>(b);
#else
		if(b & (1 << BIT)) {
			FastPin<DATA_PIN>::fastset(clockdatapin, datahiclocklo); SPI_DELAY_HALF;
			FastPin<DATA_PIN>::fastset(clockdatapin, datahiclockhi); SPI_DELAY;
			FastPin<DATA_PIN>::fastset(clockdatapin, datahiclocklo); SPI_DELAY_HALF;
		} else {
			// NOP;
			FastPin<DATA_PIN>::fastset(clockdatapin, dataloclocklo); SPI_DELAY_HALF;
			FastPin<DATA_PIN>::fastset(clockdatapin, dataloclockhi); SPI_DELAY;
			FastPin<DATA_PIN>::fastset(clockdatapin, dataloclocklo); SPI_DELAY_HALF;
		}
#endif
	}
public:

	// select the SPI output (TODO: research whether this really means hi or lo.  Alt TODO: move select responsibility out of the SPI classes
	// entirely, make it up to the caller to remember to lock/select the line?)
	void select() { if(m_pSelect != NULL) { m_pSelect->select(); } } // FastPin<SELECT_PIN>::hi(); }

	// release the SPI line
	void release() { if(m_pSelect != NULL) { m_pSelect->release(); } } // FastPin<SELECT_PIN>::lo(); }

	// Write out len bytes of the given value out over SPI.  Useful for quickly flushing, say, a line of 0's down the line.
	void writeBytesValue(uint8_t value, int len) {
		select();
		writeBytesValueRaw(value, len);
		release();
	}

	static void writeBytesValueRaw(uint8_t value, int len) {
#ifdef FAST_SPI_INTERRUPTS_WRITE_PINS
		// TODO: Weird things may happen if software bitbanging SPI output and other pins on the output reigsters are being twiddled.  Need
		// to allow specifying whether or not exclusive i/o access is allowed during this process, and if i/o access is not allowed fall
		// back to the degenerative code below
		while(len--) {
			writeByte(value);
		}
#else
		register data_ptr_t datapin = FastPin<DATA_PIN>::port();

		if(FastPin<DATA_PIN>::port() != FastPin<CLOCK_PIN>::port()) {
			// If data and clock are on different ports, then writing a bit will consist of writing the value foor
			// the bit (hi or low) to the data pin port, and then two writes to the clock port to strobe the clock line
			register clock_ptr_t clockpin = FastPin<CLOCK_PIN>::port();
			register data_t datahi = FastPin<DATA_PIN>::hival();
			register data_t datalo = FastPin<DATA_PIN>::loval();
			register clock_t clockhi = FastPin<CLOCK_PIN>::hival();
			register clock_t clocklo = FastPin<CLOCK_PIN>::loval();
			while(len--) {
				writeByte(value, clockpin, datapin, datahi, datalo, clockhi, clocklo);
			}

		} else {
			// If data and clock are on the same port then we can combine setting the data and clock pins
			register data_t datahi_clockhi = FastPin<DATA_PIN>::hival() | FastPin<CLOCK_PIN>::mask();
			register data_t datalo_clockhi = FastPin<DATA_PIN>::loval() | FastPin<CLOCK_PIN>::mask();
			register data_t datahi_clocklo = FastPin<DATA_PIN>::hival() & ~FastPin<CLOCK_PIN>::mask();
			register data_t datalo_clocklo = FastPin<DATA_PIN>::loval() & ~FastPin<CLOCK_PIN>::mask();

			while(len--) {
				writeByte(value, datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo);
			}
		}
#endif
	}

	// write a block of len uint8_ts out.  Need to type this better so that explicit casts into the call aren't required.
	// note that this template version takes a class parameter for a per-byte modifier to the data.
	template <class D> void writeBytes(register uint8_t *data, int len) {
		select();
#ifdef FAST_SPI_INTERRUPTS_WRITE_PINS
		uint8_t *end = data + len;
		while(data != end) {
			writeByte(D::adjust(*data++));
		}
#else
		register clock_ptr_t clockpin = FastPin<CLOCK_PIN>::port();
		register data_ptr_t datapin = FastPin<DATA_PIN>::port();

		if(FastPin<DATA_PIN>::port() != FastPin<CLOCK_PIN>::port()) {
			// If data and clock are on different ports, then writing a bit will consist of writing the value foor
			// the bit (hi or low) to the data pin port, and then two writes to the clock port to strobe the clock line
			register data_t datahi = FastPin<DATA_PIN>::hival();
			register data_t datalo = FastPin<DATA_PIN>::loval();
			register clock_t clockhi = FastPin<CLOCK_PIN>::hival();
			register clock_t clocklo = FastPin<CLOCK_PIN>::loval();
			uint8_t *end = data + len;

			while(data != end) {
				writeByte(D::adjust(*data++), clockpin, datapin, datahi, datalo, clockhi, clocklo);
			}

		} else {
			// FastPin<CLOCK_PIN>::hi();
			// If data and clock are on the same port then we can combine setting the data and clock pins
			register data_t datahi_clockhi = FastPin<DATA_PIN>::hival() | FastPin<CLOCK_PIN>::mask();
			register data_t datalo_clockhi = FastPin<DATA_PIN>::loval() | FastPin<CLOCK_PIN>::mask();
			register data_t datahi_clocklo = FastPin<DATA_PIN>::hival() & ~FastPin<CLOCK_PIN>::mask();
			register data_t datalo_clocklo = FastPin<DATA_PIN>::loval() & ~FastPin<CLOCK_PIN>::mask();

			uint8_t *end = data + len;

			while(data != end) {
				writeByte(D::adjust(*data++), datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo);
			}
			// FastPin<CLOCK_PIN>::lo();
		}
#endif
		D::postBlock(len);
		release();
	}

	// default version of writing a block of data out to the SPI port, with no data modifications being made
	void writeBytes(register uint8_t *data, int len) { writeBytes<DATA_NOP>(data, len); }


	// write a block of uint8_ts out in groups of three.  len is the total number of uint8_ts to write out.  The template
	// parameters indicate how many uint8_ts to skip at the beginning of each grouping, as well as a class specifying a per
	// byte of data modification to be made.  (See DATA_NOP above)
	template <uint8_t FLAGS, class D, EOrder RGB_ORDER>  __attribute__((noinline)) void writePixels(PixelController<RGB_ORDER> pixels) {
		select();
		int len = pixels.mLen;

#ifdef FAST_SPI_INTERRUPTS_WRITE_PINS
		// If interrupts or other things may be generating output while we're working on things, then we need
		// to use this block
		while(pixels.has(1)) {
			if(FLAGS & FLAG_START_BIT) {
				writeBit<0>(1);
			}
			writeByte(D::adjust(pixels.loadAndScale0()));
			writeByte(D::adjust(pixels.loadAndScale1()));
			writeByte(D::adjust(pixels.loadAndScale2()));
			pixels.advanceData();
			pixels.stepDithering();
		}
#else
		// If we can guaruntee that no one else will be writing data while we are running (namely, changing the values of the PORT/PDOR pins)
		// then we can use a bunch of optimizations in here
		register data_ptr_t datapin = FastPin<DATA_PIN>::port();

		if(FastPin<DATA_PIN>::port() != FastPin<CLOCK_PIN>::port()) {
			register clock_ptr_t clockpin = FastPin<CLOCK_PIN>::port();
			// If data and clock are on different ports, then writing a bit will consist of writing the value foor
			// the bit (hi or low) to the data pin port, and then two writes to the clock port to strobe the clock line
			register data_t datahi = FastPin<DATA_PIN>::hival();
			register data_t datalo = FastPin<DATA_PIN>::loval();
			register clock_t clockhi = FastPin<CLOCK_PIN>::hival();
			register clock_t clocklo = FastPin<CLOCK_PIN>::loval();

			while(pixels.has(1)) {
				if(FLAGS & FLAG_START_BIT) {
					writeBit<0>(1, clockpin, datapin, datahi, datalo, clockhi, clocklo);
				}
				writeByte(D::adjust(pixels.loadAndScale0()), clockpin, datapin, datahi, datalo, clockhi, clocklo);
				writeByte(D::adjust(pixels.loadAndScale1()), clockpin, datapin, datahi, datalo, clockhi, clocklo);
				writeByte(D::adjust(pixels.loadAndScale2()), clockpin, datapin, datahi, datalo, clockhi, clocklo);
				pixels.advanceData();
				pixels.stepDithering();
			}

		} else {
			// If data and clock are on the same port then we can combine setting the data and clock pins
			register data_t datahi_clockhi = FastPin<DATA_PIN>::hival() | FastPin<CLOCK_PIN>::mask();
			register data_t datalo_clockhi = FastPin<DATA_PIN>::loval() | FastPin<CLOCK_PIN>::mask();
			register data_t datahi_clocklo = FastPin<DATA_PIN>::hival() & ~FastPin<CLOCK_PIN>::mask();
			register data_t datalo_clocklo = FastPin<DATA_PIN>::loval() & ~FastPin<CLOCK_PIN>::mask();

			while(pixels.has(1)) {
				if(FLAGS & FLAG_START_BIT) {
					writeBit<0>(1, datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo);
				}
				writeByte(D::adjust(pixels.loadAndScale0()), datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo);
				writeByte(D::adjust(pixels.loadAndScale1()), datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo);
				writeByte(D::adjust(pixels.loadAndScale2()), datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo);
				pixels.advanceData();
				pixels.stepDithering();
			}
		}
#endif
		D::postBlock(len);
		release();
	}
};

FASTLED_NAMESPACE_END

#endif


<|start_filename|>Software/C/bakebit_analog_write.c<|end_filename|>
// BakeBit Example for using the analog write 

#include "bakebit.h"
//gcc bakebit_analog_write.c bakebit.c -Wall
int main(void)
{		
	int i;
	
	//Exit on failure to start communications with the BakeBit
	if(init()==-1)
		exit(1);
	
	while(1)
	{
		for(i=0;i<256;i++)
		{
			printf("%d\n", i);
			//Write the PWM value
			analogWrite(3,i);
			//Sleep for 10ms
			pi_sleep(10);
		}
	}
   	return 1;
}


<|start_filename|>Firmware/Source/bakebit_v1.0.0/FastLED-FastLED3.1/platforms/arm/nrf51/led_sysdefs_arm_nrf51.h<|end_filename|>
#ifndef __LED_SYSDEFS_ARM_NRF51
#define __LED_SYSDEFS_ARM_NRF51

#ifndef NRF51
#define NRF51
#endif

#define LED_TIMER NRF_TIMER1
#define FASTLED_NO_PINMAP
#define FASTLED_HAS_CLOCKLESS

#define FASTLED_ARM
#define FASTLED_ARM_M0

#ifndef F_CPU
#define F_CPU 16000000
#endif

#include <stdint.h>
#include "nrf51.h"
#include "core_cm0.h"

typedef volatile uint32_t RoReg;
typedef volatile uint32_t RwReg;
typedef uint32_t prog_uint32_t;
typedef uint8_t boolean;

#define PROGMEM
#define NO_PROGMEM
#define NEED_CXX_BITS

// Default to NOT using PROGMEM here
#ifndef FASTLED_USE_PROGMEM
#define FASTLED_USE_PROGMEM 0
#endif

#ifndef FASTLED_ALLOW_INTERRUPTS
#define FASTLED_ALLOW_INTERRUPTS 1
#endif

#define cli()  __disable_irq();
#define sei() __enable_irq();

#endif
