From 0314c77fd9fd9372bdef8c190cef7e78dc2ae5b2 Mon Sep 17 00:00:00 2001
From: xengineering <mail2xengineering@protonmail.com>
Date: Sat, 31 Oct 2020 20:49:22 +0100
Subject: ws2812: No usage of Heap anymore

---
 libraries/ws2812.c | 41 +++++++++++++++++------------------------
 libraries/ws2812.h | 29 ++++++++++++++---------------
 ws2812/main.c      | 44 +++++++++++++++++++++++---------------------
 3 files changed, 54 insertions(+), 60 deletions(-)

diff --git a/libraries/ws2812.c b/libraries/ws2812.c
index 41d4fb5..aa64031 100644
--- a/libraries/ws2812.c
+++ b/libraries/ws2812.c
@@ -8,7 +8,7 @@ Please mind these restrictions:
 
 - Only usable with libopencm3
 - Newer versions of libopencm3 may be not compatibel (libopencm3 api is not stable yet)
-- Just usable with a clock frequency of 80 MHz
+- Just usable with a clock frequency of 72 MHz
 - You have to setup the clock and gpio yourself
 
 */
@@ -21,19 +21,18 @@ Please mind these restrictions:
 #define NUMBER_NOPS_SHORT 6  // 0.35 µs = 25.2 cycles @ 72 MHz = 6.3 nops --> 16.7 ns timing error
 
 
-void ws2812_init(ws2812_init_typedef *control_struct, uint32_t port, uint16_t pin, uint32_t array_length, uint32_t matrix_width)
+void ws2812_init(WS2812_ARRAY *control_struct, uint32_t port, uint16_t pin, uint8_t *buffer_ptr, uint32_t array_length)
 {
 	control_struct->gpio_port = port;
 	control_struct->gpio_pin = pin;
+	control_struct->array_buffer = buffer_ptr;
 	control_struct->array_length = array_length;
-	control_struct->matrix_width = matrix_width;
-	control_struct->led_array = malloc(sizeof(uint8_t[array_length][3]));
 	ws2812_clear_buffer(control_struct);
 	ws2812_send_reset(control_struct);
 }
 
 
-void ws2812_send_reset(ws2812_init_typedef *control_struct)
+void ws2812_send_reset(WS2812_ARRAY *control_struct)
 {
 	gpio_clear(control_struct->gpio_port, control_struct->gpio_pin);
 	for (int i = 0; i < NUMBER_NOPS_RESET; i++) {
@@ -42,7 +41,7 @@ void ws2812_send_reset(ws2812_init_typedef *control_struct)
 }
 
 
-void ws2812_send_zero(ws2812_init_typedef *control_struct)
+void ws2812_send_zero(WS2812_ARRAY *control_struct)
 {
 	gpio_set(control_struct->gpio_port, control_struct->gpio_pin);
 	for (int i = 0; i < NUMBER_NOPS_SHORT; i++) {
@@ -55,7 +54,7 @@ void ws2812_send_zero(ws2812_init_typedef *control_struct)
 }
 
 
-void ws2812_send_one(ws2812_init_typedef *control_struct)
+void ws2812_send_one(WS2812_ARRAY *control_struct)
 {
 	gpio_set(control_struct->gpio_port, control_struct->gpio_pin);
 	for (int i = 0; i < NUMBER_NOPS_LONG; i++) {
@@ -68,7 +67,7 @@ void ws2812_send_one(ws2812_init_typedef *control_struct)
 }
 
 
-void ws2812_send_byte(ws2812_init_typedef *control_struct, uint8_t data)
+void ws2812_send_byte(WS2812_ARRAY *control_struct, uint8_t data)
 {
 	for (int i=7; i>=0; i--){
 		if ( (data >> i) & 0x01 ){
@@ -81,7 +80,7 @@ void ws2812_send_byte(ws2812_init_typedef *control_struct, uint8_t data)
 }
 
 
-void ws2812_send_led(ws2812_init_typedef *control_struct, uint8_t red, uint8_t green, uint8_t blue)
+void ws2812_send_led(WS2812_ARRAY *control_struct, uint8_t red, uint8_t green, uint8_t blue)
 {
 	ws2812_send_byte(control_struct, green);
 	ws2812_send_byte(control_struct, red);
@@ -89,35 +88,29 @@ void ws2812_send_led(ws2812_init_typedef *control_struct, uint8_t red, uint8_t g
 }
 
 
-void ws2812_write_leds(ws2812_init_typedef *control_struct)
+void ws2812_write_leds(WS2812_ARRAY *control_struct)
 {
 	for(uint32_t i=0; i<(control_struct->array_length); i++){
 		ws2812_send_led(
 			control_struct,
-			control_struct->led_array[i][0],  // red
-			control_struct->led_array[i][1],  // green
-			control_struct->led_array[i][2]   // blue
+			control_struct->array_buffer[i * WS2812_NUMBER_OF_COLORS + 0],  // red
+			control_struct->array_buffer[i * WS2812_NUMBER_OF_COLORS + 1],  // green
+			control_struct->array_buffer[i * WS2812_NUMBER_OF_COLORS + 2]   // blue
 		);
 	}
 	ws2812_send_reset(control_struct);
 }
 
 
-void ws2812_set_array_led(ws2812_init_typedef *control_struct, uint32_t index, uint8_t red, uint8_t green, uint8_t blue)
+void ws2812_set_array_led(WS2812_ARRAY *control_struct, uint32_t index, uint8_t red, uint8_t green, uint8_t blue)
 {
-	control_struct->led_array[index][0] = red;
-	control_struct->led_array[index][1] = green;
-	control_struct->led_array[index][2] = blue;
+	control_struct->array_buffer[index * WS2812_NUMBER_OF_COLORS + 0] = red;
+	control_struct->array_buffer[index * WS2812_NUMBER_OF_COLORS + 1] = green;
+	control_struct->array_buffer[index * WS2812_NUMBER_OF_COLORS + 2] = blue;
 }
 
 
-void ws2812_set_matrix_led(ws2812_init_typedef *control_struct, uint32_t x, uint32_t y, uint8_t red, uint8_t green, uint8_t blue)
-{
-	ws2812_set_array_led(control_struct, (x + y * (control_struct->matrix_width)), red, green, blue);
-}
-
-
-void ws2812_clear_buffer(ws2812_init_typedef *control_struct)
+void ws2812_clear_buffer(WS2812_ARRAY *control_struct)
 {
 	for (uint32_t i=0; i<control_struct->array_length; i++){
 		ws2812_set_array_led(control_struct, i, 0, 0, 0);
diff --git a/libraries/ws2812.h b/libraries/ws2812.h
index e4f0754..c6c85d9 100644
--- a/libraries/ws2812.h
+++ b/libraries/ws2812.h
@@ -7,32 +7,31 @@
 #include <stdlib.h>
 #include <libopencm3/stm32/gpio.h>
 
+#define WS2812_NUMBER_OF_COLORS 3
 
-typedef struct ws2812_init_typedef{
+
+typedef struct WS2812_ARRAY{
 
 	uint32_t gpio_port;
     uint16_t gpio_pin;
+    uint8_t *array_buffer;
     uint32_t array_length;
-    uint32_t matrix_width;
-    uint8_t (*led_array)[3];
-
-}ws2812_init_typedef;
 
+}WS2812_ARRAY;
 
-void ws2812_init(ws2812_init_typedef *control_struct, uint32_t port, uint16_t pin, uint32_t array_length, uint32_t matrix_width);
 
-void ws2812_send_reset(ws2812_init_typedef *control_struct);
-void ws2812_send_zero(ws2812_init_typedef *control_struct);
-void ws2812_send_one(ws2812_init_typedef *control_struct);
+void ws2812_init(WS2812_ARRAY *control_struct, uint32_t port, uint16_t pin, uint8_t *buffer_ptr, uint32_t array_length);
 
-void ws2812_send_byte(ws2812_init_typedef *control_struct, uint8_t data);
-void ws2812_send_led(ws2812_init_typedef *control_struct, uint8_t red, uint8_t green, uint8_t blue);
-void ws2812_write_leds(ws2812_init_typedef *control_struct);
+void ws2812_send_reset(WS2812_ARRAY *control_struct);
+void ws2812_send_zero(WS2812_ARRAY *control_struct);
+void ws2812_send_one(WS2812_ARRAY *control_struct);
 
-void ws2812_set_array_led(ws2812_init_typedef *control_struct, uint32_t index, uint8_t red, uint8_t green, uint8_t blue);
-void ws2812_set_matrix_led(ws2812_init_typedef *control_struct, uint32_t x, uint32_t y, uint8_t red, uint8_t green, uint8_t blue);
+void ws2812_send_byte(WS2812_ARRAY *control_struct, uint8_t data);
+void ws2812_send_led(WS2812_ARRAY *control_struct, uint8_t red, uint8_t green, uint8_t blue);
 
-void ws2812_clear_buffer(ws2812_init_typedef *control_struct);
+void ws2812_write_leds(WS2812_ARRAY *control_struct);
+void ws2812_set_array_led(WS2812_ARRAY *control_struct, uint32_t index, uint8_t red, uint8_t green, uint8_t blue);
+void ws2812_clear_buffer(WS2812_ARRAY *control_struct);
 
 
 #endif  /* WS2812_H */
diff --git a/ws2812/main.c b/ws2812/main.c
index 926cd68..323d03c 100644
--- a/ws2812/main.c
+++ b/ws2812/main.c
@@ -6,8 +6,9 @@
 #include "ws2812.h"
 
 
-#define DELAY 30000  // 18,000,000 nops are one second
-#define BRIGHTNESS 100
+#define DELAY 90000  // 18,000,000 nops are one second @ 72 MHz (one nop --> 4 clock cycles)
+#define BRIGHTNESS 30
+#define LED_ARRAY_LENGTH 3
 
 
 void clock_init(void);
@@ -15,31 +16,32 @@ void gpio_init(void);
 void delay(void);
 
 
-ws2812_init_typedef ws2812;
-
-
 int main(void)
 {
 	clock_init();
 	gpio_init();
-	ws2812_init(&ws2812, GPIOB, GPIO13, 1, 1);
-
-	while(1){
-		/*ws2812_send_led(&ws2812, BRIGHTNESS, 0, 0);
-		delay();
-		ws2812_send_led(&ws2812, 0, BRIGHTNESS, 0);
-		delay();
-		ws2812_send_led(&ws2812, 0, 0, BRIGHTNESS);
-		delay();
-		ws2812_send_led(&ws2812, BRIGHTNESS, BRIGHTNESS, BRIGHTNESS);
-		delay();*/
-
-		for (uint16_t i=0; i<=255; i++){
-			ws2812_send_led(&ws2812, i, 0, 0);
+	uint8_t led_array_buffer[LED_ARRAY_LENGTH*WS2812_NUMBER_OF_COLORS];
+	WS2812_ARRAY led_panel;
+	ws2812_init(&led_panel, GPIOB, GPIO13, (uint8_t *)led_array_buffer, LED_ARRAY_LENGTH);
+
+	while(1)
+	{
+		for (uint16_t i=0; i<=BRIGHTNESS; i++)
+		{
+			ws2812_set_array_led(&led_panel, 0, i, 0, 0);
+			ws2812_set_array_led(&led_panel, 1, 0, i, 0);
+			ws2812_set_array_led(&led_panel, 2, 0, 0, i);
+
+			ws2812_write_leds(&led_panel);
 			delay();
 		}
-		for (uint16_t i=255; i>0; i--){
-			ws2812_send_led(&ws2812, i, 0, 0);
+		for (uint16_t i=BRIGHTNESS; i>0; i--)
+		{
+			ws2812_set_array_led(&led_panel, 0, i, 0, 0);
+			ws2812_set_array_led(&led_panel, 1, 0, i, 0);
+			ws2812_set_array_led(&led_panel, 2, 0, 0, i);
+
+			ws2812_write_leds(&led_panel);
 			delay();
 		}
 	}
-- 
cgit v1.2.3-70-g09d2