Tiny-WS2812  1.0.0
A tiny cross-platform WS2812 LED Strip driver
Macros | Functions
ws2812_stm8s.c File Reference

Driver code for STM8S chips. More...

#include <stm8s.h>
#include <stddef.h>
#include <stdbool.h>
#include <ws2812_common.h>
#include <ws2812_stm8s.h>
Include dependency graph for ws2812_stm8s.c:

Go to the source code of this file.

Macros

#define TICKS_PER_LOOP   2
 Number of CPU ticks per loop in delay_us function.
 
#define LOOPS_PER_US   (F_CPU / TICKS_PER_LOOP / 1000000UL)
 Number for loops required for 1 us to pass.
 
#define LDW_OVERHEAD   2
 Number of CPU ticks for the LDW instruction.
 

Functions

uint8_t ws2812_config (ws2812 *dev, ws2812_cfg *cfg)
 Configures a WS2812 device struct. More...
 
void ws2812_prep_tx (ws2812 *dev)
 Prepares the host device for data transmission. More...
 
void ws2812_wait_rst (ws2812 *dev)
 Waits for the WS2812 device to reset. More...
 
void ws2812_tx (ws2812 *dev, ws2812_rgb *leds, size_t n_leds)
 Transmits RGB values to the provided WS2812 device. More...
 
void ws2812_close_tx (ws2812 *dev)
 Closes a WS2812 transmission. More...
 

Detailed Description

Driver code for STM8S chips.

Author
Patrick Pedersen
Date
2022-10-26

The following file holds the Tiny-WS2812 library code to drive WS2812 devices on STM8S chips.

Definition in file ws2812_stm8s.c.

Function Documentation

◆ ws2812_close_tx()

void ws2812_close_tx ( ws2812 dev)

Closes a WS2812 transmission.

The following function should be called after ending data transmission with a WS2812 device. The exact closing procedure is platform specific but will typically involve restoring stashed registers to their previous states, re-enable interrupts, wait for the WS2812 to reset by calling ws2812_wait_rst(), and potentially alter fields of the provided WS2812 device struct.

Definition at line 263 of file ws2812_stm8s.c.

264 {
265  if (_prep == false)
266  return;
267 
268  _prep = false;
269  ws2812_wait_rst(dev);
270 }
void ws2812_wait_rst(ws2812 *dev)
Waits for the WS2812 device to reset.
Definition: ws2812_stm8s.c:119

◆ ws2812_config()

uint8_t ws2812_config ( ws2812 dev,
ws2812_cfg cfg 
)

Configures a WS2812 device struct.

The following function initializes/configures a WS2812 device struct using a ws2812_cfg configuration struct.

Definition at line 83 of file ws2812_stm8s.c.

84 {
85  dev->port_baseaddr = cfg->port_baseaddr;
86  dev->rst_time_us = cfg->rst_time_us;
87 
88  GPIO_TypeDef *port = (GPIO_TypeDef *)dev->port_baseaddr;
89 
90  uint8_t pin_msk = 0;
91 
92  for (uint8_t i = 0; i < cfg->n_dev; i++) {
93  pin_msk |= cfg->pins[i];
94  GPIO_Init(port, cfg->pins[i], GPIO_MODE_OUT_PP_LOW_FAST);
95  }
96 
97  dev->maskhi = pin_msk;
98  dev->masklo = ~pin_msk;
99 
100  _ws2812_get_rgbmap(&dev->rgbmap, cfg->order);
101 
102  return 0;
103 }
uint8_t n_dev
Number of WS2812 device to drive.
Definition: ws2812_avr.h:78
uint8_t rst_time_us
Time required for the WS2812 device(s) to reset in us.
Definition: ws2812_avr.h:76
uint16_t port_baseaddr
Base address of the port used to drive WS2812 devices (ex. GPIOA_BASE, GPIOB_BASE,...
Definition: ws2812_stm8s.h:69
ws2812_order order
CoColor order of the WS2812 device(s) (ex. rgb, grb, bgr...)
Definition: ws2812_avr.h:77
uint8_t * pins
Array of pins used to program WS2812 devices (Must share the same PORT! (ex. PB0, PB1,...
Definition: ws2812_avr.h:69
uint16_t port_baseaddr
Base address of the port used to drive WS2812 devices (ex. GPIOA_BASE, GPIOB_BASE,...
Definition: ws2812_stm8s.h:102
uint8_t rgbmap[3]
RGB map to map/convert RGB values to another color order.
Definition: ws2812_avr.h:112
uint8_t rst_time_us
Time required for WS2812 to reset in us.
Definition: ws2812_avr.h:109
uint8_t masklo
PORT masks to toggle the data pins low.
Definition: ws2812_avr.h:111
uint8_t maskhi
PORT masks to toggle the data pins high.
Definition: ws2812_avr.h:110
void _ws2812_get_rgbmap(uint8_t(*rgbmap)[3], ws2812_order order)
Initializes a rgb map for a given color order.
Definition: ws2812_common.c:43

◆ ws2812_prep_tx()

void ws2812_prep_tx ( ws2812 dev)

Prepares the host device for data transmission.

The following function prepares the host device for data transmission. The exact preperation procedure is platform specific, but typically will involve disabling interrupts, stashing registers that may be modified when communicating to the WS2812 device and potentially preparing the passed WS2812 device struct for data transmission. For a more detailed understanding, please refer to the platform specific code of this function.

Warning
Always call this function before making any calls to ws2812_tx()! Not doing so may result in undefined behaivour!

Definition at line 106 of file ws2812_stm8s.c.

107 {
108  if (_prep == true)
109  return;
110 
111  _port_odr_addr = dev->port_baseaddr;
112  _mask_hi = dev->maskhi;
113  _mask_lo = dev->masklo;
114 
115  _prep = true;
116 }

◆ ws2812_tx()

void ws2812_tx ( ws2812 dev,
ws2812_rgb pxls,
size_t  n_pxls 
)

Transmits RGB values to the provided WS2812 device.

The following function transmits RGB values to the provided WS2812 device. Calling this function consecutively for the same device will continue programming LEDs after the position where the last transmission has ended. In other words, calling the function consecutively for the same device will NOT program the device from the first LED, but rather take off from where it last ended. If this is not desired, call ws2812_wait_rst() after each transmission.

Definition at line 252 of file ws2812_stm8s.c.

253 {
254  for (size_t i = 0; i < n_leds; i++) {
255  for (uint8_t j = 0; j < sizeof(dev->rgbmap); j++) {
256  uint8_t *pxl = (uint8_t *) &(leds[i]);
257  ws2812_tx_byte(pxl[dev->rgbmap[j]]);
258  }
259  }
260 }
void ws2812_tx_byte(ws2812 *dev, uint8_t byte)
Transmits a byte of data to the WS2812 device.
Definition: ws2812_avr.c:192

◆ ws2812_wait_rst()

void ws2812_wait_rst ( ws2812 dev)

Waits for the WS2812 device to reset.

The following function waits for the WS2812 device to reset, thus allowing it to be overwritten from the first LED again. The reset time is configuredin the ws2812_cfg object used to initialize/configure the passed WS2812 device struct, and is recommended to be 50us according to the WS2812 datasheet, but may be set significantly lower for some WS2812 devices. Call this function if you wish to overwritte the WS2812 device after a previous ws2812_tx() call.

Note
This function does not have to be called prior calling #ws2812_end_tx() as it already contains a call to ws2812_wait_rst().

Definition at line 119 of file ws2812_stm8s.c.

120 {
121  if (dev->rst_time_us)
122  delay_us(dev->rst_time_us);
123 }
void delay_us(uint8_t us)
Halts the program for a given ammount of microseconds.
Definition: ws2812_avr.c:116