Initial commit

This commit is contained in:
Sebastian 2015-09-02 21:48:07 +02:00
commit c0def49827
8 changed files with 197 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.swp

5
README.md Normal file
View File

@ -0,0 +1,5 @@
twinkl
------
A simple multiclient network protocol for your blinkenlights.

23
include/config.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef _CONFIG_H_
#define _CONFIG_H_
/*
* Here be Configuration
*/
// Number of channels
#define TWINKL_CHANNEL_COUNT 512
// Number of priority levels
#define TWINKL_LEVEL_COUNT 8
/*
* Only automagic below this point
*/
// ceil(TWINKL_CHANNEL_COUNT / 8)
#define TWINKL_MASK_BYTES ((TWINKL_CHANNEL_COUNT + 7) / 8)
#endif

62
include/message.h Normal file
View File

@ -0,0 +1,62 @@
#ifndef _MESSAGE_H_
#define _MESSAGE_H_
#include <stdint.h>
#include "config.h"
#include "util.h"
struct twinkl_message {
// Channel values from 0 to 255
uint8_t values[TWINKL_CHANNEL_COUNT];
/*
* Mask bits
*
* If the value of channel X should be set,
* set bit X % 8 in byte X / 8.
*/
uint8_t mask[TWINKL_MASK_BYTES];
// Priority of this message.
uint8_t priority;
};
/*
* Static helper functions for messages
*/
static inline void twinkl_init_message(struct twinkl_message *msg) {
twinkl_memset(msg->values, 0, TWINKL_CHANNEL_COUNT);
twinkl_memset(msg->mask, 0, TWINKL_MASK_BYTES);
msg->priority = 0;
}
static inline void twinkl_set_value(struct twinkl_message *msg, uint16_t chan, uint8_t value) {
if(chan < TWINKL_CHANNEL_COUNT) {
msg->values[chan] = value;
uint16_t byte = chan / 8;
uint8_t bit = chan % 8;
msg->mask[byte] |= (1 << bit);
}
}
static inline void twinkl_unset_value(struct twinkl_message *msg, uint16_t chan) {
if(chan < TWINKL_CHANNEL_COUNT) {
msg->values[chan] = 0;
uint16_t byte = chan / 8;
uint8_t bit = chan % 8;
msg->mask[byte] &= ~(1 << bit);
}
}
static inline void twinkl_set_priority(struct twinkl_message *msg, uint8_t priority) {
if(priority < TWINKL_LEVEL_COUNT) {
msg->priority = priority;
}
}
#endif

17
include/twinkl.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef _TWINKL_H_
#define _TWINKL_H_
#include <stdint.h>
#include "message.h"
void twinkl_init(void);
void twinkl_process_message(struct twinkl_message* msg);
uint8_t twinkl_has_changes(void);
void twinkl_render(uint8_t *channels);
#endif

9
include/util.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef _UTIL_H_
#define _UTIL_H_
#include <stdlib.h>
void* __attribute__((weak)) twinkl_memset(void *ptr, int value, size_t num);
void* __attribute__((weak)) twinkl_memcpy(void * destination, const void * source, size_t num);
#endif

69
twinkl.c Normal file
View File

@ -0,0 +1,69 @@
#include <stdint.h>
#include "config.h"
#include "util.h"
#include "twinkl.h"
uint8_t twinkl_channels[TWINKL_LEVEL_COUNT][TWINKL_CHANNEL_COUNT];
uint8_t twinkl_masks[TWINKL_LEVEL_COUNT][TWINKL_MASK_BYTES];
uint8_t twinkl_has_changed;
void twinkl_init() {
twinkl_memset(twinkl_channels, 0, TWINKL_LEVEL_COUNT * TWINKL_CHANNEL_COUNT);
twinkl_memset(twinkl_masks, 0, TWINKL_LEVEL_COUNT * TWINKL_MASK_BYTES);
twinkl_has_changed = 0;
}
void twinkl_process_message(struct twinkl_message *msg) {
if(msg->priority < TWINKL_LEVEL_COUNT) {
twinkl_memcpy(twinkl_channels[msg->priority], msg->values, TWINKL_CHANNEL_COUNT);
twinkl_memcpy(twinkl_masks[msg->priority], msg->mask, TWINKL_MASK_BYTES);
twinkl_has_changed = 1;
}
}
uint8_t twinkl_has_changes() {
return twinkl_has_changed;
}
uint8_t get_mask_bit(uint8_t level, uint16_t channel) {
if(level >= TWINKL_LEVEL_COUNT && channel >= TWINKL_CHANNEL_COUNT) {
return 0;
}
uint16_t byte = channel / 8;
uint8_t bit = channel % 8;
if((twinkl_masks[level][byte] & (1 << bit)) != 0) {
return 1;
}
else {
return 0;
}
}
void twinkl_render(uint8_t *channels) {
uint16_t chan;
uint8_t level;
for(chan = 0; chan < TWINKL_CHANNEL_COUNT; chan++) {
for(level = 0; level < TWINKL_LEVEL_COUNT; level++) {
if(get_mask_bit(level,chan)) {
channels[chan] = twinkl_channels[level][chan];
break;
}
}
}
twinkl_has_changed = 0;
}

11
util.c Normal file
View File

@ -0,0 +1,11 @@
#include <string.h>
#include "util.h"
void* twinkl_memset(void *ptr, int value, size_t num) {
return memset(ptr, value, num);
}
void* twinkl_memcpy(void *destination, const void *source, size_t num) {
return memcpy(destination, source, num);
}