summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Steiert <[email protected]>2021-01-10 05:17:49 +0000
committerGreg Steiert <[email protected]>2021-01-10 05:17:49 +0000
commit5ca7c285f58d9ddf6d729571005f3af153f14973 (patch)
tree90b6fde05798c557656a23030b4e3f768f3a10e7
parent9c3bdd621b9040bb331b62e2f652ad1a104c9d70 (diff)
moved neopixel to its own files with additional features
-rw-r--r--hw/bsp/double_m33_express/board.mk2
-rw-r--r--hw/bsp/double_m33_express/double_m33_express.c182
-rw-r--r--hw/bsp/double_m33_express/neopixel.c245
-rw-r--r--hw/bsp/double_m33_express/neopixel.h53
4 files changed, 340 insertions, 142 deletions
diff --git a/hw/bsp/double_m33_express/board.mk b/hw/bsp/double_m33_express/board.mk
index df42ad4cc..7ab9b7bf3 100644
--- a/hw/bsp/double_m33_express/board.mk
+++ b/hw/bsp/double_m33_express/board.mk
@@ -28,6 +28,8 @@ SRC_C += \
$(MCU_DIR)/drivers/fsl_flexcomm.c
INC += \
+ $(TOP)/hw/bsp/ \
+ $(TOP)/hw/bsp/$(BOARD) \
$(TOP)/$(MCU_DIR)/../../CMSIS/Include \
$(TOP)/$(MCU_DIR) \
$(TOP)/$(MCU_DIR)/drivers
diff --git a/hw/bsp/double_m33_express/double_m33_express.c b/hw/bsp/double_m33_express/double_m33_express.c
index 187313a41..41f70453b 100644
--- a/hw/bsp/double_m33_express/double_m33_express.c
+++ b/hw/bsp/double_m33_express/double_m33_express.c
@@ -29,7 +29,9 @@
#include "fsl_gpio.h"
#include "fsl_power.h"
#include "fsl_iocon.h"
+#include "fsl_usart.h"
#include "fsl_sctimer.h"
+#include "neopixel.h"
//--------------------------------------------------------------------+
// Forward USB interrupt events to TinyUSB IRQ Handler
@@ -60,6 +62,7 @@ void USB1_IRQHandler(void)
#define NEOPIXEL_NUMBER 2
#define NEOPIXEL_PORT 0
#define NEOPIXEL_PIN 27
+#define NEOPIXEL_CH 6
// UART
#define UART_DEV USART0
@@ -80,142 +83,10 @@ void USB1_IRQHandler(void)
#define IOCON_PIO_DIG_FUNC4_EN (IOCON_PIO_DIGITAL_EN | IOCON_PIO_FUNC4) /*!<@brief Digital pin function 2 enabled */
#define IOCON_PIO_DIG_FUNC7_EN (IOCON_PIO_DIGITAL_EN | IOCON_PIO_FUNC7) /*!<@brief Digital pin function 2 enabled */
-//--------------------------------------------------------------------+
-// Neopixel Driver
-//--------------------------------------------------------------------+
-#define NEO_SCT SCT0
-#define NEO_MATCH_PERIOD 0
-#define NEO_MATCH_0 1
-#define NEO_MATCH_1 2
-#define NEO_EVENT_RISE 2
-#define NEO_EVENT_FALL_0 0
-#define NEO_EVENT_FALL_1 1
-#define NEO_EVENT_NEXT 3
-#define NEO_EVENT_START 4
-#define NEO_SCT_OUTPUT 6
-#define NEO_STATE_IDLE 24
-//#define NEO_ARRAY_SIZE (3 * NEOPIXEL_NUMBER)
-//volatile uint32_t _neopixel_array[NEO_ARRAY_SIZE] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x60};
-volatile uint32_t _neopixel_array[NEOPIXEL_NUMBER] = {0x404040, 0x202020};
-volatile uint32_t _neopixel_count = 0;
-
-void neopixel_int_handler(void){
- uint32_t eventFlag = NEO_SCT->EVFLAG;
- if (eventFlag & (1 << NEO_EVENT_NEXT)) {
- _neopixel_count += 1;
- if (_neopixel_count < (NEOPIXEL_NUMBER)) {
- NEO_SCT->EV[NEO_EVENT_FALL_0].STATE = 0xFFFFFF & (~_neopixel_array[_neopixel_count]);
- NEO_SCT->CTRL &= ~(SCT_CTRL_HALT_L_MASK);
- }
- }
- NEO_SCT->EVFLAG = eventFlag;
-}
-
-void SCT0_DriverIRQHandler(void){
- neopixel_int_handler();
- SDK_ISR_EXIT_BARRIER;
-}
-
-void neopixel_set(uint32_t pixel, uint32_t color){
- if (pixel < NEOPIXEL_NUMBER) {
- _neopixel_array[pixel] = color;
- }
-}
-
-void neopixel_update(void){
-// while (NEO_SCT->CTRL & SCT_CTRL_HALT_L_MASK);
- _neopixel_count = 0;
- NEO_SCT->EV[NEO_EVENT_FALL_0].STATE = 0xFFFFFF & (~_neopixel_array[0]);
- NEO_SCT->CTRL &= ~(SCT_CTRL_HALT_L_MASK);
-}
-
-
-/*
-void neopixel_int_handler(void){
- uint32_t eventFlag = NEO_SCT->EVFLAG;
-// if ((eventFlag & (1 << NEO_EVENT_NEXT)) && (_neopixel_count < (NEO_ARRAY_SIZE))) {
-// NEO_SCT->EV[NEO_EVENT_FALL_0].STATE = 0xFF & (~_neopixel_array[_neopixel_count]);
- if ((eventFlag & (1 << NEO_EVENT_NEXT)) && (_neopixel_count < (NEOPIXEL_NUMBER))) {
- _neopixel_count += 1;
- NEO_SCT->EV[NEO_EVENT_FALL_0].STATE = 0xFFFFFF & (~_neopixel_array[_neopixel_count]);
- NEO_SCT->EVFLAG = eventFlag;
- NEO_SCT->CTRL &= ~(SCT_CTRL_HALT_L_MASK);
- } else {
- NEO_SCT->EVFLAG = eventFlag;
- }
-}
-
-void SCT0_DriverIRQHandler(void){
- neopixel_int_handler();
- SDK_ISR_EXIT_BARRIER;
-}
-
-void neopixel_update(uint32_t pixel, uint32_t color){
- if (pixel < NEOPIXEL_NUMBER) {
- _neopixel_array[pixel] = color;
- _neopixel_count = 0;
-// NEO_SCT->EV[NEO_EVENT_FALL_0].STATE = 0xFF & (~_neopixel_array[0]);
- NEO_SCT->EV[NEO_EVENT_FALL_0].STATE = 0xFFFFFF & (~_neopixel_array[0]);
- NEO_SCT->CTRL &= ~(SCT_CTRL_HALT_L_MASK);
- }
-}
-*/
-void neopixel_init(void) {
- CLOCK_EnableClock(kCLOCK_Sct0);
- RESET_PeripheralReset(kSCT0_RST_SHIFT_RSTn);
-
- NEO_SCT->CONFIG = (
- SCT_CONFIG_UNIFY(1) |
- SCT_CONFIG_CLKMODE(kSCTIMER_System_ClockMode) |
- SCT_CONFIG_NORELOAD_L(1) );
- NEO_SCT->CTRL = (
- SCT_CTRL_HALT_L(1) |
- SCT_CTRL_CLRCTR_L(1) );
-
- NEO_SCT->MATCH[NEO_MATCH_PERIOD] = 120;
- NEO_SCT->MATCH[NEO_MATCH_0] = 30;
- NEO_SCT->MATCH[NEO_MATCH_1] = 60;
- NEO_SCT->EV[NEO_EVENT_START].STATE = (1 << NEO_STATE_IDLE);
- NEO_SCT->EV[NEO_EVENT_START].CTRL = (
- kSCTIMER_OutputLowEvent | SCT_EV_CTRL_IOSEL(NEO_SCT_OUTPUT) |
- SCT_EV_CTRL_STATELD(1) | SCT_EV_CTRL_STATEV(23));
-// NEO_SCT->EV[NEO_EVENT_RISE].STATE = 0xFE;
- NEO_SCT->EV[NEO_EVENT_RISE].STATE = 0xFFFFFE;
- NEO_SCT->EV[NEO_EVENT_RISE].CTRL = (
- kSCTIMER_MatchEventOnly | SCT_EV_CTRL_MATCHSEL(NEO_MATCH_PERIOD) |
- SCT_EV_CTRL_STATELD(0) | SCT_EV_CTRL_STATEV(31));
- NEO_SCT->EV[NEO_EVENT_FALL_0].STATE = 0x0;
- NEO_SCT->EV[NEO_EVENT_FALL_0].CTRL = (
- kSCTIMER_MatchEventOnly | SCT_EV_CTRL_MATCHSEL(NEO_MATCH_0) |
- SCT_EV_CTRL_STATELD(0) );
-// NEO_SCT->EV[NEO_EVENT_FALL_1].STATE = 0xFF;
- NEO_SCT->EV[NEO_EVENT_FALL_1].STATE = 0xFFFFFF;
- NEO_SCT->EV[NEO_EVENT_FALL_1].CTRL = (
- kSCTIMER_MatchEventOnly | SCT_EV_CTRL_MATCHSEL(NEO_MATCH_1) |
- SCT_EV_CTRL_STATELD(0) );
- NEO_SCT->EV[NEO_EVENT_NEXT].STATE = 0x1;
- NEO_SCT->EV[NEO_EVENT_NEXT].CTRL = (
- kSCTIMER_MatchEventOnly | SCT_EV_CTRL_MATCHSEL(NEO_MATCH_PERIOD) |
- SCT_EV_CTRL_STATELD(1) | SCT_EV_CTRL_STATEV(NEO_STATE_IDLE));
-
- NEO_SCT->LIMIT = (1 << NEO_EVENT_START) | (1 << NEO_EVENT_RISE) | (1 << NEO_EVENT_NEXT);
- NEO_SCT->HALT = (1 << NEO_EVENT_NEXT);
- NEO_SCT->START = (1 << NEO_EVENT_START);
-
- NEO_SCT->OUT[NEO_SCT_OUTPUT].SET = (1 << NEO_EVENT_START) | (1 << NEO_EVENT_RISE);
- NEO_SCT->OUT[NEO_SCT_OUTPUT].CLR = (1 << NEO_EVENT_FALL_0) | (1 << NEO_EVENT_FALL_1) | (1 << NEO_EVENT_NEXT);
-
- NEO_SCT->STATE = NEO_STATE_IDLE;
- NEO_SCT->OUTPUT = 0x0;
- NEO_SCT->RES = SCT_RES_O6RES(0x2);
- NEO_SCT->EVEN = (1 << NEO_EVENT_NEXT);
- EnableIRQ(SCT0_IRQn);
-
- neopixel_set(0, 0x101000);
- neopixel_set(1, 0x101000);
- neopixel_update();
-}
+// Global Variables
+uint32_t pixelData[NEOPIXEL_NUMBER];
+neopixel_config_t neoConfig;
/****************************************************************
@@ -282,7 +153,34 @@ void board_init(void)
/* PORT0 PIN27 configured as SCT0_OUT6 */
IOCON_PinMuxSet(IOCON, NEOPIXEL_PORT, NEOPIXEL_PIN, IOCON_PIO_DIG_FUNC4_EN);
- neopixel_init();
+ neoConfig.pixelData[0] = NULL;
+ neoConfig.pixelCnt[0] = 0;
+ neoConfig.pixelData[1] = NULL;
+ neoConfig.pixelCnt[1] = 0;
+ neoConfig.pixelData[2] = NULL;
+ neoConfig.pixelCnt[2] = 0;
+ neoConfig.pixelData[3] = NULL;
+ neoConfig.pixelCnt[3] = 0;
+ neoConfig.pixelData[4] = NULL;
+ neoConfig.pixelCnt[4] = 0;
+ neoConfig.pixelData[5] = NULL;
+ neoConfig.pixelCnt[5] = 0;
+ neoConfig.pixelData[6] = NULL;
+ neoConfig.pixelCnt[6] = 0;
+ neoConfig.pixelData[7] = NULL;
+ neoConfig.pixelCnt[7] = 0;
+ neoConfig.pixelData[8] = NULL;
+ neoConfig.pixelCnt[8] = 0;
+ neoConfig.pixelData[9] = NULL;
+ neoConfig.pixelCnt[9] = 0;
+ neoConfig.pixelData[NEOPIXEL_CH] = pixelData;
+ neoConfig.pixelCnt[NEOPIXEL_CH] = NEOPIXEL_NUMBER;
+ neoConfig.syncUpdate = true;
+ neopixel_init(&neoConfig);
+ neopixel_setPixel(NEOPIXEL_CH, 0, 0x100010);
+ neopixel_setPixel(NEOPIXEL_CH, 1, 0x100010);
+ neopixel_refresh();
+
// Button
/* PORT0 PIN5 configured as PIO0_5 */
@@ -302,7 +200,7 @@ void board_init(void)
CLOCK_AttachClk(kFRO12M_to_FLEXCOMM0);
usart_config_t uart_config;
USART_GetDefaultConfig(&uart_config);
- uart_config.baudRate_Bps = BOARD_UART_BAUDRATE;
+ uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE;
uart_config.enableTx = true;
uart_config.enableRx = true;
USART_Init(UART_DEV, &uart_config, 12000000);
@@ -359,13 +257,13 @@ void board_led_write(bool state)
{
GPIO_PinWrite(GPIO, LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON));
if (state) {
- neopixel_set(0, 0x100000);
- neopixel_set(1, 0x101010);
+ neopixel_setPixel(NEOPIXEL_CH, 0, 0x100000);
+ neopixel_setPixel(NEOPIXEL_CH, 1, 0x101010);
} else {
- neopixel_set(0, 0x001000);
- neopixel_set(1, 0x000010);
+ neopixel_setPixel(NEOPIXEL_CH, 0, 0x001000);
+ neopixel_setPixel(NEOPIXEL_CH, 1, 0x000010);
}
- neopixel_update();
+ neopixel_refresh();
}
uint32_t board_button_read(void)
diff --git a/hw/bsp/double_m33_express/neopixel.c b/hw/bsp/double_m33_express/neopixel.c
new file mode 100644
index 000000000..8be01d35a
--- /dev/null
+++ b/hw/bsp/double_m33_express/neopixel.c
@@ -0,0 +1,245 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2021 Greg Steiert
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include "neopixel.h"
+#include "board.h"
+#include "fsl_device_registers.h"
+#include "fsl_sctimer.h"
+
+
+//--------------------------------------------------------------------+
+// Neopixel Driver
+//--------------------------------------------------------------------+
+#define NEO_SCT SCT0
+#define NEO_MATCH_RISE 12
+#define NEO_MATCH_PERIOD 13
+#define NEO_MATCH_RESET 15
+#define NEO_MATCH_0 0
+#define NEO_MATCH_1 11
+#define NEO_EVENT_RISE 12
+#define NEO_EVENT_CH_0 0
+#define NEO_EVENT_CH_1 1
+#define NEO_EVENT_CH_2 2
+#define NEO_EVENT_CH_3 3
+#define NEO_EVENT_CH_4 4
+#define NEO_EVENT_CH_5 5
+#define NEO_EVENT_CH_6 6
+#define NEO_EVENT_CH_7 7
+#define NEO_EVENT_CH_8 8
+#define NEO_EVENT_CH_9 9
+#define NEO_EVENT_FALL_1 11
+#define NEO_EVENT_NEXT 13
+#define NEO_EVENT_LAST 14
+#define NEO_EVENT_RESET 15
+#define NEO_SCT_OUTPUT 6
+#define NEO_COUNT_RISE 1
+#define NEO_COUNT_FALL0 31
+#define NEO_COUNT_FALL1 61
+#define NEO_COUNT_PERIOD 120
+#define NEO_COUNT_RESET 8120
+#define NEO_FIRST_BIT 23
+
+neopixel_config_t *neo;
+uint32_t _neopixel_max_count = 0;
+volatile uint32_t _neopixel_count = 0;
+volatile bool _neopixel_busy = false;
+
+void neopixel_int_handler(void){
+ uint32_t eventFlag = NEO_SCT->EVFLAG;
+ if (eventFlag & (1 << NEO_EVENT_RESET)) {
+ _neopixel_busy = false;
+ } else if (eventFlag & (1 << NEO_EVENT_LAST)) {
+ _neopixel_count += 1;
+ if (_neopixel_count < _neopixel_max_count) {
+ NEO_SCT->STATE = NEO_FIRST_BIT;
+ if (_neopixel_count < neo->pixelCnt[0]) {
+ NEO_SCT->EV[NEO_EVENT_CH_0].STATE = (~neo->pixelData[0][_neopixel_count]); }
+ if (_neopixel_count < neo->pixelCnt[1]) {
+ NEO_SCT->EV[NEO_EVENT_CH_1].STATE = (~neo->pixelData[1][_neopixel_count]); }
+ if (_neopixel_count < neo->pixelCnt[2]) {
+ NEO_SCT->EV[NEO_EVENT_CH_2].STATE = (~neo->pixelData[2][_neopixel_count]); }
+ if (_neopixel_count < neo->pixelCnt[3]) {
+ NEO_SCT->EV[NEO_EVENT_CH_3].STATE = (~neo->pixelData[3][_neopixel_count]); }
+ if (_neopixel_count < neo->pixelCnt[4]) {
+ NEO_SCT->EV[NEO_EVENT_CH_4].STATE = (~neo->pixelData[4][_neopixel_count]); }
+ if (_neopixel_count < neo->pixelCnt[5]) {
+ NEO_SCT->EV[NEO_EVENT_CH_5].STATE = (~neo->pixelData[5][_neopixel_count]); }
+ if (_neopixel_count < neo->pixelCnt[6]) {
+ NEO_SCT->EV[NEO_EVENT_CH_6].STATE = (~neo->pixelData[6][_neopixel_count]); }
+ if (_neopixel_count < neo->pixelCnt[7]) {
+ NEO_SCT->EV[NEO_EVENT_CH_7].STATE = (~neo->pixelData[7][_neopixel_count]); }
+ if (_neopixel_count < neo->pixelCnt[8]) {
+ NEO_SCT->EV[NEO_EVENT_CH_8].STATE = (~neo->pixelData[8][_neopixel_count]); }
+ if (_neopixel_count < neo->pixelCnt[9]) {
+ NEO_SCT->EV[NEO_EVENT_CH_9].STATE = (~neo->pixelData[9][_neopixel_count]); }
+ NEO_SCT->CTRL = SCT_CTRL_CLRCTR_L_MASK;
+ } else {
+ NEO_SCT->CTRL = 0x0;
+ }
+ }
+ NEO_SCT->EVFLAG = eventFlag;
+}
+
+void SCT0_DriverIRQHandler(void){
+ neopixel_int_handler();
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void neopixel_setPixel(uint32_t ch, uint32_t pixel, uint32_t color){
+ if (ch < 10) {
+ if (pixel < neo->pixelCnt[ch]) {
+ if (neo->syncUpdate) {
+ while (_neopixel_busy) { __NOP(); }
+ }
+ neo->pixelData[ch][pixel] = color;
+ }
+ }
+}
+
+void neopixel_refresh(void){
+// while (NEO_SCT->CTRL & SCT_CTRL_HALT_L_MASK);
+ while (_neopixel_busy) {__NOP();}
+ _neopixel_busy = true;
+ _neopixel_count = 0;
+ NEO_SCT->STATE = NEO_FIRST_BIT;
+ if (neo->pixelCnt[0]) { NEO_SCT->EV[NEO_EVENT_CH_0].STATE = (~neo->pixelData[0][0]); }
+ if (neo->pixelCnt[1]) { NEO_SCT->EV[NEO_EVENT_CH_0].STATE = (~neo->pixelData[1][0]); }
+ if (neo->pixelCnt[2]) { NEO_SCT->EV[NEO_EVENT_CH_0].STATE = (~neo->pixelData[2][0]); }
+ if (neo->pixelCnt[3]) { NEO_SCT->EV[NEO_EVENT_CH_0].STATE = (~neo->pixelData[3][0]); }
+ if (neo->pixelCnt[4]) { NEO_SCT->EV[NEO_EVENT_CH_0].STATE = (~neo->pixelData[4][0]); }
+ if (neo->pixelCnt[5]) { NEO_SCT->EV[NEO_EVENT_CH_0].STATE = (~neo->pixelData[5][0]); }
+ if (neo->pixelCnt[6]) { NEO_SCT->EV[NEO_EVENT_CH_0].STATE = (~neo->pixelData[6][0]); }
+ if (neo->pixelCnt[7]) { NEO_SCT->EV[NEO_EVENT_CH_0].STATE = (~neo->pixelData[7][0]); }
+ if (neo->pixelCnt[8]) { NEO_SCT->EV[NEO_EVENT_CH_0].STATE = (~neo->pixelData[8][0]); }
+ if (neo->pixelCnt[9]) { NEO_SCT->EV[NEO_EVENT_CH_0].STATE = (~neo->pixelData[9][0]); }
+ NEO_SCT->CTRL = SCT_CTRL_CLRCTR_L_MASK;
+}
+
+void neopixel_init(neopixel_config_t *config) {
+ neo = config;
+ CLOCK_EnableClock(kCLOCK_Sct0);
+ RESET_PeripheralReset(kSCT0_RST_SHIFT_RSTn);
+
+ _neopixel_max_count = 0;
+ for (uint32_t i=0; i < 10; i++) {
+ if (_neopixel_max_count < neo->pixelCnt[i]) {
+ _neopixel_max_count = neo->pixelCnt[i];
+ }
+ }
+
+ NEO_SCT->CONFIG = (
+ SCT_CONFIG_UNIFY(1) |
+ SCT_CONFIG_CLKMODE(kSCTIMER_System_ClockMode) |
+ SCT_CONFIG_NORELOAD_L(1) );
+ NEO_SCT->CTRL = (
+ SCT_CTRL_HALT_L(1) |
+ SCT_CTRL_CLRCTR_L(1) );
+
+ NEO_SCT->MATCH[NEO_MATCH_RISE] = NEO_COUNT_RISE;
+ NEO_SCT->MATCH[NEO_MATCH_PERIOD] = NEO_COUNT_PERIOD;
+ NEO_SCT->MATCH[NEO_MATCH_0] = NEO_COUNT_FALL0;
+ NEO_SCT->MATCH[NEO_MATCH_1] = NEO_COUNT_FALL1;
+ NEO_SCT->MATCH[NEO_MATCH_RESET] = NEO_COUNT_RESET;
+ NEO_SCT->EV[NEO_EVENT_RISE].STATE = 0xFFFFFFFF;
+ NEO_SCT->EV[NEO_EVENT_RISE].CTRL = (
+ kSCTIMER_MatchEventOnly | SCT_EV_CTRL_MATCHSEL(NEO_MATCH_RISE) );
+ NEO_SCT->EV[NEO_EVENT_CH_0].STATE = 0xF0F0F0F0;
+ NEO_SCT->EV[NEO_EVENT_CH_0].CTRL = (
+ kSCTIMER_MatchEventOnly | SCT_EV_CTRL_MATCHSEL(NEO_MATCH_0) );
+ NEO_SCT->EV[NEO_EVENT_CH_1].STATE = 0xF0F0F0F0;
+ NEO_SCT->EV[NEO_EVENT_CH_1].CTRL = (
+ kSCTIMER_MatchEventOnly | SCT_EV_CTRL_MATCHSEL(NEO_MATCH_0) );
+ NEO_SCT->EV[NEO_EVENT_CH_2].STATE = 0xF0F0F0F0;
+ NEO_SCT->EV[NEO_EVENT_CH_2].CTRL = (
+ kSCTIMER_MatchEventOnly | SCT_EV_CTRL_MATCHSEL(NEO_MATCH_0) );
+ NEO_SCT->EV[NEO_EVENT_CH_3].STATE = 0xF0F0F0F0;
+ NEO_SCT->EV[NEO_EVENT_CH_3].CTRL = (
+ kSCTIMER_MatchEventOnly | SCT_EV_CTRL_MATCHSEL(NEO_MATCH_0) );
+ NEO_SCT->EV[NEO_EVENT_CH_4].STATE = 0xF0F0F0F0;
+ NEO_SCT->EV[NEO_EVENT_CH_4].CTRL = (
+ kSCTIMER_MatchEventOnly | SCT_EV_CTRL_MATCHSEL(NEO_MATCH_0) );
+ NEO_SCT->EV[NEO_EVENT_CH_5].STATE = 0xF0F0F0F0;
+ NEO_SCT->EV[NEO_EVENT_CH_5].CTRL = (
+ kSCTIMER_MatchEventOnly | SCT_EV_CTRL_MATCHSEL(NEO_MATCH_0) );
+ NEO_SCT->EV[NEO_EVENT_CH_6].STATE = 0xF0F0F0F0;
+ NEO_SCT->EV[NEO_EVENT_CH_6].CTRL = (
+ kSCTIMER_MatchEventOnly | SCT_EV_CTRL_MATCHSEL(NEO_MATCH_0) );
+ NEO_SCT->EV[NEO_EVENT_CH_7].STATE = 0xF0F0F0F0;
+ NEO_SCT->EV[NEO_EVENT_CH_7].CTRL = (
+ kSCTIMER_MatchEventOnly | SCT_EV_CTRL_MATCHSEL(NEO_MATCH_0) );
+ NEO_SCT->EV[NEO_EVENT_CH_8].STATE = 0xF0F0F0F0;
+ NEO_SCT->EV[NEO_EVENT_CH_8].CTRL = (
+ kSCTIMER_MatchEventOnly | SCT_EV_CTRL_MATCHSEL(NEO_MATCH_0) );
+ NEO_SCT->EV[NEO_EVENT_CH_9].STATE = 0xF0F0F0F0;
+ NEO_SCT->EV[NEO_EVENT_CH_9].CTRL = (
+ kSCTIMER_MatchEventOnly | SCT_EV_CTRL_MATCHSEL(NEO_MATCH_0) );
+ NEO_SCT->EV[NEO_EVENT_FALL_1].STATE = 0xFFFFFFFF;
+ NEO_SCT->EV[NEO_EVENT_FALL_1].CTRL = (
+ kSCTIMER_MatchEventOnly | SCT_EV_CTRL_MATCHSEL(NEO_MATCH_1) );
+ NEO_SCT->EV[NEO_EVENT_NEXT].STATE = 0xFFFFFFFE;
+ NEO_SCT->EV[NEO_EVENT_NEXT].CTRL = (
+ kSCTIMER_MatchEventOnly | SCT_EV_CTRL_MATCHSEL(NEO_MATCH_PERIOD) |
+ SCT_EV_CTRL_STATELD(0) | SCT_EV_CTRL_STATEV(31));
+ NEO_SCT->EV[NEO_EVENT_LAST].STATE = 0x1;
+ NEO_SCT->EV[NEO_EVENT_LAST].CTRL = (
+ kSCTIMER_MatchEventOnly | SCT_EV_CTRL_MATCHSEL(NEO_MATCH_PERIOD) );
+ NEO_SCT->EV[NEO_EVENT_RESET].STATE = 0xFFFFFFFF;
+ NEO_SCT->EV[NEO_EVENT_RESET].CTRL = (
+ kSCTIMER_MatchEventOnly | SCT_EV_CTRL_MATCHSEL(NEO_MATCH_RESET) );
+
+ NEO_SCT->LIMIT = (1 << NEO_EVENT_NEXT) | (1 << NEO_EVENT_RESET);
+ NEO_SCT->HALT = (1 << NEO_EVENT_LAST) | (1 << NEO_EVENT_RESET);
+ NEO_SCT->START = 0x0;
+
+ NEO_SCT->OUT[0].SET = (1 << NEO_EVENT_RISE);
+ NEO_SCT->OUT[0].CLR = (1 << NEO_EVENT_CH_0) | (1 << NEO_EVENT_FALL_1) | (1 << NEO_EVENT_LAST);
+ NEO_SCT->OUT[1].SET = (1 << NEO_EVENT_RISE);
+ NEO_SCT->OUT[1].CLR = (1 << NEO_EVENT_CH_1) | (1 << NEO_EVENT_FALL_1) | (1 << NEO_EVENT_LAST);
+ NEO_SCT->OUT[2].SET = (1 << NEO_EVENT_RISE);
+ NEO_SCT->OUT[2].CLR = (1 << NEO_EVENT_CH_2) | (1 << NEO_EVENT_FALL_1) | (1 << NEO_EVENT_LAST);
+ NEO_SCT->OUT[3].SET = (1 << NEO_EVENT_RISE);
+ NEO_SCT->OUT[3].CLR = (1 << NEO_EVENT_CH_3) | (1 << NEO_EVENT_FALL_1) | (1 << NEO_EVENT_LAST);
+ NEO_SCT->OUT[4].SET = (1 << NEO_EVENT_RISE);
+ NEO_SCT->OUT[4].CLR = (1 << NEO_EVENT_CH_4) | (1 << NEO_EVENT_FALL_1) | (1 << NEO_EVENT_LAST);
+ NEO_SCT->OUT[5].SET = (1 << NEO_EVENT_RISE);
+ NEO_SCT->OUT[5].CLR = (1 << NEO_EVENT_CH_5) | (1 << NEO_EVENT_FALL_1) | (1 << NEO_EVENT_LAST);
+ NEO_SCT->OUT[6].SET = (1 << NEO_EVENT_RISE);
+ NEO_SCT->OUT[6].CLR = (1 << NEO_EVENT_CH_6) | (1 << NEO_EVENT_FALL_1) | (1 << NEO_EVENT_LAST);
+ NEO_SCT->OUT[7].SET = (1 << NEO_EVENT_RISE);
+ NEO_SCT->OUT[7].CLR = (1 << NEO_EVENT_CH_7) | (1 << NEO_EVENT_FALL_1) | (1 << NEO_EVENT_LAST);
+ NEO_SCT->OUT[8].SET = (1 << NEO_EVENT_RISE);
+ NEO_SCT->OUT[8].CLR = (1 << NEO_EVENT_CH_8) | (1 << NEO_EVENT_FALL_1) | (1 << NEO_EVENT_LAST);
+ NEO_SCT->OUT[9].SET = (1 << NEO_EVENT_RISE);
+ NEO_SCT->OUT[9].CLR = (1 << NEO_EVENT_CH_9) | (1 << NEO_EVENT_FALL_1) | (1 << NEO_EVENT_LAST);
+
+ NEO_SCT->OUTPUT = 0x0;
+ NEO_SCT->RES = SCT_RES_O6RES(0x2);
+ NEO_SCT->EVEN = (1 << NEO_EVENT_LAST) | (1 << NEO_EVENT_RESET);
+ EnableIRQ(SCT0_IRQn);
+
+// neopixel_setPixel(0, 0x101000);
+// neopixel_setPixel(1, 0x101000);
+// neopixel_refresh();
+}
diff --git a/hw/bsp/double_m33_express/neopixel.h b/hw/bsp/double_m33_express/neopixel.h
new file mode 100644
index 000000000..a444a354c
--- /dev/null
+++ b/hw/bsp/double_m33_express/neopixel.h
@@ -0,0 +1,53 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2021 Greg Steiert
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#ifndef _SCT_NEOPIXEL_H_
+#define _SCT_NEOPIXEL_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+
+typedef struct _neopixel_config {
+ uint32_t *pixelData[10];
+ uint32_t pixelCnt[10];
+ uint32_t pixelType;
+ bool syncUpdate;
+} neopixel_config_t;
+
+void neopixel_init(neopixel_config_t *config);
+void neopixel_refresh(void);
+void neopixel_setPixel(uint32_t ch, uint32_t pixel, uint32_t color);
+
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif \ No newline at end of file