Simple neopixel code for SAM D21.
1 files changed, 98 insertions(+), 0 deletions(-)

A => neopixel.c
A => neopixel.c +98 -0
@@ 0,0 1,98 @@ 
+/*
+ * Neopixel routines
+ *
+ * Permissive open source ISC license.
+ *
+ * Copyright (c) 2016 Tero Koskinen <tero.koskinen@iki.fi>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/* Include the file directly to your SAM D code */
+/* Assumes 48MHz CPU speed */
+
+#define my_delay_850ns asm("nop; nop; nop; nop; nop; nop; nop; nop;nop; nop; nop; nop; nop; nop; nop; nop;nop; nop; nop; nop; nop; nop; nop; nop;nop; nop; nop;")
+#define my_delay_800ns asm("nop; nop; nop; nop; nop; nop; nop; nop;nop; nop; nop; nop; nop; nop; nop; nop;nop; nop; nop; nop; nop; nop; nop; nop;nop; nop;")
+#define my_delay_500ns asm("nop; nop; nop; nop; nop; nop; nop; nop;nop; nop; nop; nop; nop; nop;")
+#define my_delay_400ns asm("nop; nop; nop; nop; nop; nop; nop; nop;nop; nop; nop; nop; ")
+
+#define WAIT_T0L my_delay_850ns
+#define WAIT_T0H my_delay_400ns
+#define WAIT_T1L my_delay_500ns
+#define WAIT_T1H my_delay_800ns
+
+static inline __attribute__((always_inline)) void send_one(void)
+{
+  PORT_IOBUS->Group[SAMD_PORT(ARDUINO_D7)].OUTSET.reg = (1 << SAMD_PIN(ARDUINO_D7));
+  WAIT_T1H;
+  PORT_IOBUS->Group[SAMD_PORT(ARDUINO_D7)].OUTCLR.reg = (1 << SAMD_PIN(ARDUINO_D7));
+  WAIT_T1L;
+}
+
+static inline __attribute__((always_inline)) void send_zero(void)
+{
+  PORT_IOBUS->Group[SAMD_PORT(ARDUINO_D7)].OUTSET.reg = (1 << SAMD_PIN(ARDUINO_D7));
+  WAIT_T0H;
+  PORT_IOBUS->Group[SAMD_PORT(ARDUINO_D7)].OUTCLR.reg = (1 << SAMD_PIN(ARDUINO_D7));
+  WAIT_T0L;
+}
+
+#define HIGHEST_BIT 0b10000000
+
+static inline __attribute__((always_inline)) void send_byte(uint8_t b)
+{
+  for (uint8_t i = 0;i <8;++i)
+  {
+    if (b & HIGHEST_BIT)
+      send_one();
+    else
+      send_zero();
+    b *= 2;
+  }
+}
+
+static inline __attribute__((always_inline)) void send_pixel(uint8_t r, uint8_t b, uint8_t g)
+{
+  send_byte(g);
+  send_byte(r);
+  send_byte(b);
+}
+
+void wait_reset(void)
+{
+  platform_spin_delay_us(51);
+}
+
+void show_color(uint8_t r, uint8_t g, uint8_t b)
+{
+  for (uint8_t i = 0;i < NEOPIXEL_COUNT;++i)
+  {
+    send_pixel(r, g, b);
+  }
+  wait_reset();
+}
+
+void show_one(uint8_t index, uint8_t r, uint8_t g, uint8_t b)
+{
+  for (uint8_t i = 0;i < NEOPIXEL_COUNT;++i)
+  {
+    if (index == i) {
+      send_pixel(r, g, b);
+    } else {
+      send_pixel(0, 0, 0);
+    }
+  }
+  wait_reset();
+}
+