summaryrefslogtreecommitdiff
path: root/libraries
diff options
context:
space:
mode:
authorxengineering <mail2xengineering@protonmail.com>2021-01-26 16:05:27 +0100
committerxengineering <mail2xengineering@protonmail.com>2021-01-26 16:05:27 +0100
commit60849a62e04769aff854781e6cafa67b7025ed73 (patch)
treeabe07c2472e3b43795fb7dec611f36d5df23f95f /libraries
parent17857f69f675141a814c80975545afb7c13dc675 (diff)
downloadstm32f103c8-examples-60849a62e04769aff854781e6cafa67b7025ed73.tar
stm32f103c8-examples-60849a62e04769aff854781e6cafa67b7025ed73.tar.zst
stm32f103c8-examples-60849a62e04769aff854781e6cafa67b7025ed73.zip
Update ws2812 Lib and ExampleHEADmain
Diffstat (limited to 'libraries')
-rw-r--r--libraries/ws2812.c88
-rw-r--r--libraries/ws2812.h52
2 files changed, 77 insertions, 63 deletions
diff --git a/libraries/ws2812.c b/libraries/ws2812.c
index aa64031..5fbdf6c 100644
--- a/libraries/ws2812.c
+++ b/libraries/ws2812.c
@@ -1,16 +1,8 @@
+// vim: tabstop=4 shiftwidth=4 noexpandtab
/*
-
-# WS2812 Library for libopencm3
-
-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 72 MHz
-- You have to setup the clock and gpio yourself
-
+ Documentation is in ws2812.h
*/
@@ -21,6 +13,8 @@ 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
+// public API functions:
+
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;
@@ -29,47 +23,65 @@ void ws2812_init(WS2812_ARRAY *control_struct, uint32_t port, uint16_t pin, uint
control_struct->array_length = array_length;
ws2812_clear_buffer(control_struct);
ws2812_send_reset(control_struct);
+ ws2812_write_buffer_to_leds(control_struct);
}
+void ws2812_clear_buffer(WS2812_ARRAY *control_struct)
+{
+ for (uint32_t i=0; i<(control_struct->array_length*3); i++){
+ control_struct->array_buffer[i] = 0x00;
+ }
+}
+
+void ws2812_write_buffer_to_leds(WS2812_ARRAY *control_struct)
+{
+ for (uint32_t i=0; i<(control_struct->array_length); i++)
+ {
+ ws2812_send_byte(control_struct, control_struct->array_buffer[i*3+1]); // green first
+ ws2812_send_byte(control_struct, control_struct->array_buffer[i*3+0]); // red second
+ ws2812_send_byte(control_struct, control_struct->array_buffer[i*3+2]); // blue third
+ }
+ ws2812_send_reset(control_struct);
+}
+
+
+// internal functions:
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++) {
+ for (uint16_t i = 0; i < NUMBER_NOPS_RESET; i++) {
__asm__("nop");
}
}
-
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++) {
+ for (uint8_t i = 0; i < NUMBER_NOPS_SHORT; i++) {
__asm__("nop");
}
gpio_clear(control_struct->gpio_port, control_struct->gpio_pin);
- for (int i = 0; i < NUMBER_NOPS_LONG; i++) {
+ for (uint8_t i = 0; i < NUMBER_NOPS_LONG; i++) {
__asm__("nop");
}
}
-
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++) {
+ for (uint8_t i = 0; i < NUMBER_NOPS_LONG; i++) {
__asm__("nop");
}
gpio_clear(control_struct->gpio_port, control_struct->gpio_pin);
- for (int i = 0; i < NUMBER_NOPS_SHORT; i++) {
+ for (uint8_t i = 0; i < NUMBER_NOPS_SHORT; i++) {
__asm__("nop");
}
}
-
void ws2812_send_byte(WS2812_ARRAY *control_struct, uint8_t data)
{
- for (int i=7; i>=0; i--){
+ for (int8_t i=7; i>=0; i--){
if ( (data >> i) & 0x01 ){
ws2812_send_one(control_struct);
}
@@ -78,41 +90,3 @@ 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)
-{
- ws2812_send_byte(control_struct, green);
- ws2812_send_byte(control_struct, red);
- ws2812_send_byte(control_struct, blue);
-}
-
-
-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->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_ARRAY *control_struct, uint32_t index, uint8_t red, uint8_t green, uint8_t 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_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 c6c85d9..f738137 100644
--- a/libraries/ws2812.h
+++ b/libraries/ws2812.h
@@ -1,3 +1,42 @@
+// vim: tabstop=4 shiftwidth=4 noexpandtab
+
+
+/*
+ ws2812
+
+ This low-level library gives you access to ws2812 LEDs and
+ LED strips via libopencm3. Please use it like this:
+
+ - connect the data pin (DIN) of the ws2812 to a GPIO of
+ your MCU
+ - initialize clock to a sysclock speed of 72 MHz
+ - initialize the GPIO pin with GPIO_MODE_OUTPUT_50_MHZ and
+ GPIO_CNF_OUTPUT_PUSHPULL
+ - create a WS2812_ARRAY control struct
+ - create a uint8_t[ARRAY_LENGTH * 3] buffer
+ - call ws2812_init() with your control struct and buffer
+ - adjust values on the buffer
+ - use ws2812_write_buffer_to_leds() to set the LEDs
+
+ The uint8_t buffer has the following structure:
+
+ ----------------------------------------------------- ...
+ | | | | | | | | | | ...
+ | R | G | B | R | G | B | R | G | B | ...
+ | | | | | | | | | | ...
+ ----------------------------------------------------- ...
+ first led second led third led ...
+
+ Please mention that this library will never have features
+ to make fancy animations and so on. It is designed just to
+ access the LEDs on a physical layer. To avoid bad code
+ quality due to unnecessary features it will never do more
+ than this ...
+
+ Technical note: This library is based on delays. This is not
+ the best way. Maybe it will change to interrupt or DMA use in
+ the future.
+*/
#ifndef WS2812_H
@@ -20,18 +59,19 @@ typedef struct WS2812_ARRAY{
}WS2812_ARRAY;
+// public API functions:
+
void ws2812_init(WS2812_ARRAY *control_struct, uint32_t port, uint16_t pin, uint8_t *buffer_ptr, uint32_t array_length);
+void ws2812_clear_buffer(WS2812_ARRAY *control_struct);
+void ws2812_write_buffer_to_leds(WS2812_ARRAY *control_struct);
+
+
+// internal functions:
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_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_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 */