libtinylor
Single-file header library for controlling Light-O-Rama hardware
Loading...
Searching...
No Matches
tinylor.c File Reference

Protocol encoding functions implementation. More...

#include "tinylor.h"
Include dependency graph for tinylor.c:

Macros

#define LOR_MAX_UNIT_LIST   256
 The size of the unit ID space scanned when encoding a unit list, i.e. one bit per possible lor_unit value (0-255). The protocol's count byte allows at most 255 entries, but valid unit IDs are limited to [1, 0xF0] so a list can never exceed 240 entries in practice.
 

Functions

void lor_unit_set_add (lor_unit_set *s, const lor_unit unit)
 Adds a single unit ID to the set. Adding an ID that is already a member has no effect.
 
void lor_unit_set_all (lor_unit_set *s, const lor_unit *u, const size_t us)
 Adds each unit ID in an array to the set.
 
void lor_unit_set_clear (lor_unit_set *s)
 Removes every unit ID from the set, leaving it empty. Also serves to initialize a set whose storage has not been zeroed.
 
void lor_set_channel (lor_req_s *req, lor_channel c)
 Configures the request to use a single channel, addressed by its 0-based index (index 0 is channel 1 in LOR software). The index is encoded as '0x80 | index' in the single-channel format, so the controller receives it directly.
 
void lor_set_channels (lor_req_s *req, lor_channel first, const uint16_t cbits)
 Configures the request to use a channel set, in the form of a 16-bit bitset of channels, "starting at" the first channel offset used.
 
void lor_set_unit (lor_req_s *req, const lor_unit u)
 Configures the request to be sent to, and accepted by, the specified unit. A unit is required for all requests. A magic value of 0xFF may be used to broadcast the request to all units.
 
void lor_set_units (lor_req_s *req, lor_unit_set *units)
 Configures the request to be sent to, and accepted by, every unit in the provided set, using the LOR_UNIT_ID_LIST addressing form. This replaces any unit previously configured with lor_set_unit. The encoded frame grows by one count byte plus one byte per member.
 
int lor_set_effect (lor_req_s *req, const lor_effect e, const lor_effect_args_u *args)
 Configures the request to apply the specified effect. The effect may require additional arguments, which are provided in the args field as a union. If provided, the args field is copied into the request at which point the caller may safely discard the original args. Any non-NULL arguments will be copied into the request, even if the effect does not require them. This allows future expansion of usable effects without modifying the behavior of the function.
 
void lor_set_intensity (lor_req_s *req, const lor_intensity i)
 Configures the request to set the intensity of the lights to the provided value.
 
void lor_set_fade (lor_req_s *req, const lor_intensity start, const lor_intensity end, const lor_decisec ds)
 Configures the request to fade from one intensity to another over a specified duration in deciseconds.
 
static lor_channel_format lor_get_cset_format (const lor_channel_set *const cset)
 Determines the compressed format of the channel set for encoding.
 
static int lor_encode_channel (uint8_t *const b, const lor_channel_set *const cset)
 Encodes a single-channel set as one byte: the channel's 0-based index with bit 7 set, as expected by the single-channel mode (0x00). Bit 7 carries no information for the controller; it only ensures channel index 0 is not encoded as 0x00, the frame delimiter.
 
static int lor_encode_cset (uint8_t *const b, const lor_channel_set *const cset)
 Encodes a channel set into a buffer.
 
static int lor_encode_decis (uint8_t *b, const lor_decisec ds)
 Encodes a decisecond value.
 
static int lor_encode_fade_rate (uint8_t *b, const lor_effect_args_u *args)
 Encodes a fade effect as an intensity delta relative to the duration of the effect in deciseconds.
 
static int lor_encode_effect (uint8_t *const b, const lor_effect e, const lor_effect_args_u *const d)
 Encodes an effect into a buffer, including any required arguments for the effect type.
 
size_t lor_write (uint8_t *b, const size_t bs, const lor_req_s *r, const size_t rs, size_t *wb)
 Encodes and writes up to rs requests to the provided buffer b as binary data. Requests are first encoded into a scratch buffer to ensure the buffer has enough space to hold the encoded data. The function will attempt to write as many requests as possible to the buffer, up to the provided request count.
 
lor_intensity lor_get_intensity (const uint8_t b)
 Encodes a [0,0xFF] value into a roughly equivalent LOR intensity value (precision is lossy) that is compatible with the protocol.
 

Detailed Description

Protocol encoding functions implementation.

Macro Definition Documentation

◆ LOR_MAX_UNIT_LIST

#define LOR_MAX_UNIT_LIST   256

The size of the unit ID space scanned when encoding a unit list, i.e. one bit per possible lor_unit value (0-255). The protocol's count byte allows at most 255 entries, but valid unit IDs are limited to [1, 0xF0] so a list can never exceed 240 entries in practice.

Function Documentation

◆ lor_encode_channel()

static int lor_encode_channel ( uint8_t *const  b,
const lor_channel_set *const  cset 
)
static

Encodes a single-channel set as one byte: the channel's 0-based index with bit 7 set, as expected by the single-channel mode (0x00). Bit 7 carries no information for the controller; it only ensures channel index 0 is not encoded as 0x00, the frame delimiter.

Parameters
bThe buffer to write the channel byte to.
csetThe channel set to encode. Must have a zero offset and exactly one bit set (see lor_get_cset_format, LOR_FMT_SINGLE).
Returns
The number of bytes written to the buffer, always 1.
Note
Caller is responsible for ensuring buffer is at least 1 byte in size.
Here is the caller graph for this function:

◆ lor_encode_cset()

static int lor_encode_cset ( uint8_t *const  b,
const lor_channel_set *const  cset 
)
static

Encodes a channel set into a buffer.

Parameters
bThe buffer to write the channel set to.
csetThe channel set to encode.
Returns
The number of bytes written to the buffer.
Note
Caller is responsible for ensuring buffer is at least 3 bytes in size.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ lor_encode_decis()

static int lor_encode_decis ( uint8_t *  b,
const lor_decisec  ds 
)
static

Encodes a decisecond value.

Parameters
bThe buffer to write the decisecond value to.
dsThe decisecond value to encode.
Returns
The number of bytes written to the buffer.
Here is the caller graph for this function:

◆ lor_encode_effect()

static int lor_encode_effect ( uint8_t *const  b,
const lor_effect  e,
const lor_effect_args_u *const  d 
)
static

Encodes an effect into a buffer, including any required arguments for the effect type.

Parameters
bThe buffer to write the effect to.
eThe effect to encode.
dOptional effect arguments to encode.
Returns
The number of bytes written to the buffer.
Note
Caller is responsible for ensuring buffer is large enough to hold the encoded effect and arguments.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ lor_encode_fade_rate()

static int lor_encode_fade_rate ( uint8_t *  b,
const lor_effect_args_u *  args 
)
static

Encodes a fade effect as an intensity delta relative to the duration of the effect in deciseconds.

Parameters
bThe buffer to write the fade value to.
Returns
The number of bytes written to the buffer.
Note
This appears to output values equivalent to the stock configuration. tinylor originally encoded deciseconds as an independent value (i.e. not relative to the intensity values), but this did not visually match the intended behavior.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ lor_get_cset_format()

static lor_channel_format lor_get_cset_format ( const lor_channel_set *const  cset)
static

Determines the compressed format of the channel set for encoding.

Parameters
csetThe channel set to determine the format of.
Returns
The format byte header of the channel set for protocol encoding.
Here is the caller graph for this function:

◆ lor_get_intensity()

lor_intensity lor_get_intensity ( uint8_t  b)

Encodes a [0,0xFF] value into a roughly equivalent LOR intensity value (precision is lossy) that is compatible with the protocol.

Note
This is a default implementation of the lor_intensity_fn type. It operates via a known truth table from protocol documentation. Other or custom implementations may be ideal for your specific use case.
Parameters
bThe byte value to convert.
Returns
The scaled intensity value.

◆ lor_set_channel()

void lor_set_channel ( lor_req_s *  req,
lor_channel  c 
)

Configures the request to use a single channel, addressed by its 0-based index (index 0 is channel 1 in LOR software). The index is encoded as '0x80 | index' in the single-channel format, so the controller receives it directly.

Note
The index is reduced modulo 1024. Indices 16 and above are split into a 16-channel bank offset and select the multipart format, which 16-channel controllers do not implement (the request is dropped).
Parameters
reqThe request to configure.
cThe 0-based channel index to apply the effect to, less than 1024.
Here is the caller graph for this function:

◆ lor_set_channels()

void lor_set_channels ( lor_req_s *  req,
lor_channel  first,
uint16_t  cbits 
)

Configures the request to use a channel set, in the form of a 16-bit bitset of channels, "starting at" the first channel offset used.

Note
Any bits within the set that (once re-aligned to a 16-bit boundary) exceed the 16-bit window, will be disregarded. Pre-aligned 16-bit bitsets are recommended for best results. You may set the request's cset offset and cbits fields directly.
Parameters
reqThe request to configure.
firstThe 0-based index of the first channel in the set, i.e. the channel selected by bit 0 of cbits (see lor_channel).
cbitsThe 16-bit bitset of channels to apply the effect to; bit n selects channel index first + n.
Here is the caller graph for this function:

◆ lor_set_effect()

int lor_set_effect ( lor_req_s *  req,
lor_effect  e,
const lor_effect_args_u *  args 
)

Configures the request to apply the specified effect. The effect may require additional arguments, which are provided in the args field as a union. If provided, the args field is copied into the request at which point the caller may safely discard the original args. Any non-NULL arguments will be copied into the request, even if the effect does not require them. This allows future expansion of usable effects without modifying the behavior of the function.

Parameters
reqThe request to configure.
eThe effect to apply.
argsThe effect arguments, required if effect is LOR_SET_INTENSITY, LOR_FADE, LOR_PULSE, or LOR_SET_DMX_INTENSITY. Should likely be NULL for other effect types.
Returns
0 on success, -1 for invalid arguments.
Here is the caller graph for this function:

◆ lor_set_fade()

void lor_set_fade ( lor_req_s *  req,
lor_intensity  start,
lor_intensity  end,
lor_decisec  ds 
)

Configures the request to fade from one intensity to another over a specified duration in deciseconds.

Note
Equivalent to calling lor_set_effect with LOR_FADE and effect arguments set to the provided start and end intensities and duration.
Parameters
reqThe request to configure.
startThe starting intensity.
endThe ending intensity.
dsThe duration of the fade in deciseconds.
Here is the call graph for this function:

◆ lor_set_intensity()

void lor_set_intensity ( lor_req_s *  req,
lor_intensity  i 
)

Configures the request to set the intensity of the lights to the provided value.

Note
Equivalent to calling lor_set_effect with LOR_SET_INTENSITY and effect arguments set to the provided intensity.
Parameters
reqThe request to configure.
iThe intensity to use. This value should likely pass through a intensity conversion function before being passed to this function.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ lor_set_unit()

void lor_set_unit ( lor_req_s *  req,
lor_unit  u 
)

Configures the request to be sent to, and accepted by, the specified unit. A unit is required for all requests. A magic value of 0xFF may be used to broadcast the request to all units.

Parameters
reqThe request to configure.
uThe unit to send the request to, or 0xFF to broadcast to all units.
Here is the caller graph for this function:

◆ lor_set_units()

void lor_set_units ( lor_req_s *  req,
lor_unit_set *  units 
)

Configures the request to be sent to, and accepted by, every unit in the provided set, using the LOR_UNIT_ID_LIST addressing form. This replaces any unit previously configured with lor_set_unit. The encoded frame grows by one count byte plus one byte per member.

Note
The set is referenced, not copied; it must remain valid and unchanged until the request has been encoded with lor_write. The set must contain at least one unit: an empty set encodes a count byte of 0x00, which terminates the frame before the command byte.
Parameters
reqThe request to configure.
unitsThe set of unit IDs to send the request to.
Here is the caller graph for this function:

◆ lor_unit_set_add()

void lor_unit_set_add ( lor_unit_set *  s,
lor_unit  unit 
)

Adds a single unit ID to the set. Adding an ID that is already a member has no effect.

Parameters
sThe set to modify.
unitThe unit ID to add, in [1, 0xF0].
Here is the caller graph for this function:

◆ lor_unit_set_all()

void lor_unit_set_all ( lor_unit_set *  s,
const lor_unit *  u,
size_t  us 
)

Adds each unit ID in an array to the set.

Note
Equivalent to calling lor_unit_set_add once per element of u.
Parameters
sThe set to modify.
uThe array of unit IDs to add, each in [1, 0xF0].
usThe number of unit IDs in u.
Here is the caller graph for this function:

◆ lor_unit_set_clear()

void lor_unit_set_clear ( lor_unit_set *  s)

Removes every unit ID from the set, leaving it empty. Also serves to initialize a set whose storage has not been zeroed.

Parameters
sThe set to clear.
Here is the caller graph for this function:

◆ lor_write()

size_t lor_write ( uint8_t *  b,
size_t  bs,
const lor_req_s *  r,
size_t  rs,
size_t *  wb 
)

Encodes and writes up to rs requests to the provided buffer b as binary data. Requests are first encoded into a scratch buffer to ensure the buffer has enough space to hold the encoded data. The function will attempt to write as many requests as possible to the buffer, up to the provided request count.

Parameters
bThe buffer to write the encoded requests to.
bsThe size of b in bytes.
rThe requests to encode, an array of at least rs elements.
rsThe number of requests in r to encode.
wbWritten byte count accumulator, may be NULL.
Returns
The number of requests successfully written to the buffer. The size of the written requests in bytes is added to wb if it is not NULL.
Here is the call graph for this function:
Here is the caller graph for this function: