diff --git a/.cproject b/.cproject
index 4ae66d1..371d3d3 100644
--- a/.cproject
+++ b/.cproject
@@ -105,42 +105,11 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -250,285 +219,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/App/App.cpp b/App/App.cpp
index ddcb009..f481d60 100644
--- a/App/App.cpp
+++ b/App/App.cpp
@@ -6,6 +6,7 @@
*/
#include
+#include
#include "main.h"
#include "dma.h"
@@ -15,35 +16,11 @@
#include
#include
#include "Config.h"
-#include "Pixel.h"
-#include "LedBuffers.h"
+#include "WS28xxStrip.h"
#include "Sparkle.h"
+WS28xxStrip g_strip( { DEFAULT_COLOR } );
Sparkle g_sparkles[NUMSPARKLES];
-volatile uint8_t g_spi_idle = 0;
-volatile uint8_t g_buffer_in_transmit;
-volatile uint16_t g_pixels_converted = 0;
-
-volatile uint32_t g_tick = 0;
-
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-
-void convert(uint8_t *src, uint8_t *dst, uint16_t src_size)
-{
- static uint16_t const bits[16] = { // due to LE-ness the bit order is 1 0 3 2
- 0b1000100010001000, 0b1000111010001000, 0b1110100010001000, 0b1110111010001000,
- 0b1000100010001110, 0b1000111010001110, 0b1110100010001110, 0b1110111010001110,
- 0b1000100011101000, 0b1000111011101000, 0b1110100011101000, 0b1110111011101000,
- 0b1000100011101110, 0b1000111011101110, 0b1110100011101110, 0b1110111011101110
- };
-
- uint16_t *dstptr = (uint16_t*)dst;
- while(src_size--) {
- uint8_t tmp =*src++;
- *dstptr++ = bits[tmp >> 4];
- *dstptr++ = bits[tmp & 0x0f];
- }
-}
inline uint16_t rr(uint16_t top)
{
@@ -59,7 +36,7 @@ uint16_t ChoosePixel()
do {
chosen = rr(NUMPIXELS);
for(spi=0; spi(g_sparkles[spi]) && static_cast(g_sparkles[spi]) == &g_pixels[chosen])
+ if(static_cast(g_sparkles[spi]) && static_cast(g_sparkles[spi]) == &g_strip[chosen])
break;
}
} while(spi < NUMSPARKLES);
@@ -72,92 +49,39 @@ uint16_t ChoosePixel()
void StartSparkle( Sparkle &s )
{
#ifndef DBG_CHOSEN_PIXEL
- s.Start(g_pixels+ChoosePixel(), rr(32), Pixel(255,255,255), Pixel(rr(8)+3,rr(8)+3,rr(8)+3));
+ s.Start(&g_strip[ChoosePixel()], rr(32), { 255,255,255 },
+ { static_cast(rr(8)+3), static_cast(rr(8)+3), static_cast(rr(8)+3) });
#else
- s.Start(g_pixels+ChoosePixel(), 0, Pixel(255,255,255), Pixel(1, 1, 1));
+ s.Start(g_pixels+ChoosePixel(), 0, { 255,255,255 }, { 1, 1, 1 });
#endif
}
-extern "C" void HandleSystick()
-{
- ++ g_tick;
-}
-
extern "C" uint32_t GetTick()
{
return g_tick;
}
-
extern "C" void HandleSpiDmaIrq()
{
- static bool endframe = false;
- static bool endprev = false;
-
- if(LL_DMA_IsActiveFlag_TE3(DMA1)) {
- LL_DMA_ClearFlag_TE3(DMA1);
- }
- else if(LL_DMA_IsActiveFlag_HT3(DMA1) || LL_DMA_IsActiveFlag_TC3(DMA1))
- {
- if(LL_DMA_IsActiveFlag_HT3(DMA1))
- {
- LL_DMA_ClearFlag_HT3(DMA1);
- g_buffer_in_transmit = 1;
- if(endframe)
- LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_3, LL_DMA_MODE_NORMAL);
- }
- else if(LL_DMA_IsActiveFlag_TC3(DMA1))
- {
- LL_DMA_ClearFlag_TC3(DMA1);
- g_buffer_in_transmit = 0;
- if(endframe && endprev) {
- LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_3);
- LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_3, LL_DMA_MODE_CIRCULAR);
- g_spi_idle = true;
- endframe = endprev = false;
- return;
- }
- }
-
- endprev = endframe;
-
- uint8_t convert_now = MIN(NUMPIXELS - g_pixels_converted, SPIBUFFER_PIXELS);
-
- if(convert_now)
- {
- LL_GPIO_TogglePin(GPIOC, LL_GPIO_PIN_13);
- convert((uint8_t*)&g_pixels[g_pixels_converted],
- g_spibuffer[g_buffer_in_transmit ^ 1],
- convert_now * sizeof(pixel_t));
- LL_GPIO_TogglePin(GPIOC, LL_GPIO_PIN_13);
- g_pixels_converted += convert_now;
- }
-
- if(convert_now < SPIBUFFER_PIXELS) {
- memset(g_spibuffer[g_buffer_in_transmit ^ 1] + convert_now * SPIBUFFER_PIXEL_SIZE,
- 0, SPIBUFFER_SIZE - convert_now * SPIBUFFER_PIXEL_SIZE);
- endframe = true;
- }
- }
+ g_strip.SpiDmaIsr();
}
-
extern "C" void App()
{
uint32_t lastTick = GetTick();
- for(uint16_t px = 0; px < NUMPIXELS; ++px)
- g_pixels[px] = Pixel(DEFAULT_COLOR);
-
LL_SYSTICK_EnableIT();
LL_SPI_Enable(SPI1);
LL_SPI_EnableDMAReq_TX(SPI1);
while(1)
{
- while(GetTick() - lastTick < FRAMETIME );
+ while(GetTick() - lastTick < FRAMETIME )
+ DoNothing();
lastTick += FRAMETIME;
+ LL_GPIO_TogglePin(GPIOC, LL_GPIO_PIN_13);
+
for(int16_t spi = 0; spi < NUMSPARKLES; ++spi) {
if(static_cast(g_sparkles[spi]))
g_sparkles[spi].Step();
@@ -165,24 +89,6 @@ extern "C" void App()
StartSparkle(g_sparkles[spi]);
}
- g_pixels_converted = 0;
-
- convert((uint8_t*)g_pixels, g_spibuffer[0], SPIBUFFER_PIXELS * sizeof(pixel_t));
- g_pixels_converted += SPIBUFFER_PIXELS;
- convert((uint8_t*)&g_pixels[g_pixels_converted], g_spibuffer[1], SPIBUFFER_PIXELS * sizeof(pixel_t));
- g_pixels_converted += SPIBUFFER_PIXELS;
-
- g_buffer_in_transmit = 0;
- g_spi_idle = false;
-
- LL_DMA_ConfigAddresses(DMA1, LL_DMA_CHANNEL_3, (uint32_t)g_spibuffer, LL_SPI_DMA_GetRegAddr(SPI1), LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
- LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_3, sizeof(g_spibuffer));
- LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_3);
- LL_DMA_EnableIT_HT(DMA1, LL_DMA_CHANNEL_3);
- LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_3);
- LL_DMA_EnableIT_TE(DMA1, LL_DMA_CHANNEL_3);
-
- while(!g_spi_idle);
-
+ g_strip.Update();
}
}
diff --git a/App/LedBuffers.cpp b/App/LedBuffers.cpp
deleted file mode 100644
index 45a7f83..0000000
--- a/App/LedBuffers.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * LedBuffers.c
- *
- * Created on: Dec 16, 2018
- * Author: abody
- */
-#include "LedBuffers.h"
-
-pixel_t g_pixels[NUMPIXELS];
-
-uint8_t g_spibuffer[2][SPIBUFFER_SIZE];
diff --git a/App/LedBuffers.h b/App/LedBuffers.h
deleted file mode 100644
index c0ad896..0000000
--- a/App/LedBuffers.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * LedBuffers.h
- *
- * Created on: Dec 16, 2018
- * Author: abody
- */
-
-#ifndef LEDBUFFERS_H_
-#define LEDBUFFERS_H_
-
-#include "Config.h"
-#include "Pixel.h"
-
-extern pixel_t g_pixels[NUMPIXELS];
-
-#define SPIBUFFER_PIXEL_SIZE ( sizeof(pixel_t) * 4) // each raw pixel bit represented by 4 bits in SPI transfer
-#define SPIBUFFER_SIZE (SPIBUFFER_PIXELS * SPIBUFFER_PIXEL_SIZE)
-
-extern uint8_t g_spibuffer[2][SPIBUFFER_SIZE];
-
-#endif /* LEDBUFFERS_H_ */
diff --git a/App/Pixel.h b/App/Pixel.h
deleted file mode 100644
index 79fe085..0000000
--- a/App/Pixel.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Pixel.h
- *
- * Created on: Dec 16, 2018
- * Author: abody
- */
-
-#ifndef PIXEL_H_
-#define PIXEL_H_
-
-#include
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct {
- uint8_t g;
- uint8_t r;
- uint8_t b;
-} pixel_t;
-
-#ifdef __cplusplus
-}
-#endif
-
-#ifdef __cplusplus
-struct Pixel : public pixel_t {
- Pixel(uint8_t _r, uint8_t _g, uint8_t _b) {
- g =_g;
- r = _r;
- b = _b;
- }
-};
-#endif
-
-#endif /* PIXEL_H_ */
diff --git a/App/Sparkle.h b/App/Sparkle.h
index 86922a8..d7b5da3 100644
--- a/App/Sparkle.h
+++ b/App/Sparkle.h
@@ -8,7 +8,7 @@
#ifndef SPARKLE_H_
#define SPARKLE_H_
#include
-#include "Pixel.h"
+#include "WS28xxStrip.h"
class Sparkle {
public:
diff --git a/App/WS28xxStrip.h b/App/WS28xxStrip.h
new file mode 100644
index 0000000..b8dfe0c
--- /dev/null
+++ b/App/WS28xxStrip.h
@@ -0,0 +1,167 @@
+/*
+ * WS28xxStrip.h
+ *
+ * Created on: Dec 2, 2020
+ * Author: compi
+ */
+
+#ifndef WS28XXSTRIP_H_
+#define WS28XXSTRIP_H_
+
+#include
+#include
+#include
+#include
+
+struct pixel_t {
+ uint8_t g;
+ uint8_t r;
+ uint8_t b;
+};
+
+extern "C" void HandleSpiDmaIrq();
+
+template class WS28xxStrip {
+public:
+ WS28xxStrip(pixel_t defcolor);
+
+ pixel_t& operator[](int16_t index);
+
+ friend void HandleSpiDmaIrq();
+ void Update();
+
+private:
+ void SpiDmaIsr();
+ void Refill();
+ void Convert(uint8_t *src, uint8_t *dst, uint16_t src_size);
+ template T Min(T a, T b) { return a < b ? a : b; }
+
+ static constexpr const unsigned int SPI_PIXEL_SIZE = sizeof(pixel_t) * 4;
+ static constexpr const unsigned int SPI_BUFFER_SIZE = spi_pixels * SPI_PIXEL_SIZE;
+
+ pixel_t m_pixels[pixels];
+ uint8_t m_spi_buffer[2][SPI_BUFFER_SIZE];
+
+ volatile uint8_t m_spi_idle = 0;
+ volatile uint8_t m_buffer_in_transmit;
+ volatile uint16_t m_pixels_converted = 0;
+ volatile bool m_endframe = false;
+ volatile bool m_endprev = false;
+ volatile bool m_need_refill = false;
+};
+
+template WS28xxStrip::WS28xxStrip(pixel_t defcolor)
+{
+ for(uint16_t p=0; p < pixels; ++p)
+ m_pixels[p] = defcolor;
+}
+
+template pixel_t& WS28xxStrip::operator[](int16_t index)
+{
+ return m_pixels[index];
+}
+
+template void WS28xxStrip::SpiDmaIsr()
+{
+ if(LL_DMA_IsActiveFlag_TE3(DMA1)) {
+ LL_DMA_ClearFlag_TE3(DMA1);
+ }
+ else if(LL_DMA_IsActiveFlag_HT3(DMA1) || LL_DMA_IsActiveFlag_TC3(DMA1))
+ {
+ if(LL_DMA_IsActiveFlag_HT3(DMA1))
+ {
+ LL_DMA_ClearFlag_HT3(DMA1);
+ m_buffer_in_transmit = 1;
+ if(m_endframe)
+ LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_3, LL_DMA_MODE_NORMAL);
+ }
+ else if(LL_DMA_IsActiveFlag_TC3(DMA1))
+ {
+ LL_DMA_ClearFlag_TC3(DMA1);
+ m_buffer_in_transmit = 0;
+ if(m_endframe && m_endprev) {
+ LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_3);
+ LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_3, LL_DMA_MODE_CIRCULAR);
+ m_spi_idle = true;
+ m_endframe = m_endprev = false;
+ return;
+ }
+ }
+
+ m_need_refill = true;
+ }
+}
+
+
+template void WS28xxStrip::Refill()
+{
+ m_need_refill = false;
+ m_endprev = m_endframe;
+
+ uint8_t convert_now = Min((uint8_t)(pixels - m_pixels_converted), spi_pixels);
+
+ if(convert_now)
+ {
+ LL_GPIO_TogglePin(GPIOC, LL_GPIO_PIN_13);
+ Convert((uint8_t*)&m_pixels[m_pixels_converted],
+ m_spi_buffer[m_buffer_in_transmit ^ 1],
+ convert_now * sizeof(pixel_t));
+ LL_GPIO_TogglePin(GPIOC, LL_GPIO_PIN_13);
+ m_pixels_converted += convert_now;
+ }
+
+ if(convert_now < spi_pixels) {
+ memset(m_spi_buffer[m_buffer_in_transmit ^ 1] + convert_now * SPI_PIXEL_SIZE,
+ 0, SPI_BUFFER_SIZE - convert_now * SPI_PIXEL_SIZE);
+ m_endframe = true;
+ }
+
+}
+
+
+template void WS28xxStrip::Update()
+{
+ m_pixels_converted = 0;
+
+ Convert((uint8_t*)m_pixels, m_spi_buffer[0], spi_pixels * sizeof(pixel_t));
+ m_pixels_converted += spi_pixels;
+ Convert((uint8_t*)&m_pixels[m_pixels_converted], m_spi_buffer[1], spi_pixels * sizeof(pixel_t));
+ m_pixels_converted += spi_pixels;
+
+ m_buffer_in_transmit = 0;
+ m_spi_idle = false;
+
+ LL_DMA_ConfigAddresses(DMA1, LL_DMA_CHANNEL_3, (uint32_t)m_spi_buffer, LL_SPI_DMA_GetRegAddr(SPI1), LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
+ LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_3, sizeof(m_spi_buffer));
+ LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_3);
+ LL_DMA_EnableIT_HT(DMA1, LL_DMA_CHANNEL_3);
+ LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_3);
+ LL_DMA_EnableIT_TE(DMA1, LL_DMA_CHANNEL_3);
+
+ while(!m_spi_idle) {
+ while(!m_spi_idle && !m_need_refill);
+ if(m_need_refill)
+ Refill();
+ }
+}
+
+
+template void WS28xxStrip::Convert(uint8_t *src, uint8_t *dst, uint16_t src_size)
+{
+ static uint16_t const bits[16] = { // due to LE-ness the bit order is 1 0 3 2
+ 0b1000100010001000, 0b1000111010001000, 0b1110100010001000, 0b1110111010001000,
+ 0b1000100010001110, 0b1000111010001110, 0b1110100010001110, 0b1110111010001110,
+ 0b1000100011101000, 0b1000111011101000, 0b1110100011101000, 0b1110111011101000,
+ 0b1000100011101110, 0b1000111011101110, 0b1110100011101110, 0b1110111011101110
+ };
+
+ uint16_t *dstptr = (uint16_t*)dst;
+ while(src_size--) {
+ uint8_t tmp =*src++;
+ *dstptr++ = bits[tmp >> 4];
+ *dstptr++ = bits[tmp & 0x0f];
+ }
+}
+
+
+#endif /* WS28XXSTRIP_H_ */
diff --git a/Inc/main.h b/Inc/main.h
index 6175e12..40afecc 100644
--- a/Inc/main.h
+++ b/Inc/main.h
@@ -51,6 +51,7 @@ extern "C" {
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
+extern volatile uint32_t g_tick;
/* USER CODE END ET */
@@ -68,6 +69,7 @@ extern "C" {
void Error_Handler(void);
/* USER CODE BEGIN EFP */
+void DoNothing();
/* USER CODE END EFP */
diff --git a/Src/main.c b/Src/main.c
index bf566a5..ce0a0d6 100644
--- a/Src/main.c
+++ b/Src/main.c
@@ -26,8 +26,6 @@
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include
-#include "App/Pixel.h"
-#include "App/LedBuffers.h"
/* USER CODE END Includes */
@@ -49,6 +47,7 @@
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
+volatile uint32_t g_tick = 0;
/* USER CODE END PV */
@@ -61,6 +60,11 @@ void App();
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
+void DoNothing()
+{
+ static volatile uint32_t cntr = 0;
+ ++ cntr;
+}
/* USER CODE END 0 */
@@ -106,12 +110,14 @@ int main(void)
MX_SPI1_Init();
/* USER CODE BEGIN 2 */
+ LL_SYSTICK_EnableIT();
+
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while(1) {
- App();
+ App();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
diff --git a/Src/stm32f1xx_it.c b/Src/stm32f1xx_it.c
index 09e085c..1c8ed59 100644
--- a/Src/stm32f1xx_it.c
+++ b/Src/stm32f1xx_it.c
@@ -184,7 +184,7 @@ void PendSV_Handler(void)
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
- HandleSystick();
+ ++g_tick;
/* USER CODE END SysTick_IRQn 0 */
/* USER CODE BEGIN SysTick_IRQn 1 */