192 lines
6.0 KiB
C
192 lines
6.0 KiB
C
#include "skiller.h"
|
|
#include "utils.h"
|
|
#include <memory.h>
|
|
|
|
skillerctl_name_value_pair_t modesLUT[] = {
|
|
SK_MODE_WAVE , "wave",
|
|
SK_MODE_DRIFT , "drift",
|
|
SK_MODE_SWIRL , "swirl",
|
|
SK_MODE_CHANGE , "change",
|
|
SK_MODE_PULSATING, "pulsating",
|
|
SK_MODE_PERMAMENT, "permament",
|
|
SK_MODE_TRIGGER , "trigger",
|
|
SK_MODE_EXPLOSION, "explosion",
|
|
SK_MODE_BURST , "burst",
|
|
SK_MODE_CHAOS , "chaos",
|
|
SK_MODE_COSMIC , "cosmic",
|
|
SK_MODE_GRADIENT , "gradient",
|
|
SK_MODE_TIDE , "tide",
|
|
SK_MODE_LIGHTING , "lighting",
|
|
SK_MODE_MATRIX , "matrix",
|
|
SK_MODE_RICOCHET , "ricochet",
|
|
SK_MODE_RIPPLE , "ripple",
|
|
SK_MODE_CUSTOM , "custom",
|
|
};
|
|
|
|
skillerctl_packet_t* skillerctl_unpack(skillerctl_packet_t *packet, uint8_t *data, size_t length) {
|
|
if (*(unsigned char*)data != 0x04 || length < 1) {
|
|
return NULL;
|
|
}
|
|
|
|
packet->magic = *(uint8_t*)(data);
|
|
packet->checksum = *(uint16_t*)(data + 1);
|
|
packet->command = *(uint8_t*)(data + 3);
|
|
packet->length = *(uint8_t*)(data + 4);
|
|
packet->address = *(uint8_t*)(data + 5);
|
|
// 1 null byte
|
|
memcpy(packet->payload, data + 8, packet->length);
|
|
|
|
return packet;
|
|
}
|
|
|
|
void* skillerctl_pack(skillerctl_packet_t *packet, uint8_t *data) {
|
|
memcpy(data, &packet->magic, 1);
|
|
memcpy(data + 1, &packet->checksum, 2);
|
|
memcpy(data + 3, &packet->command, 1);
|
|
memcpy(data + 4, &packet->length, 1);
|
|
memcpy(data + 5, &packet->address, 2);
|
|
// 1 null byte
|
|
memcpy(data + 8, packet->payload, SK_MAX_PAYLOAD);
|
|
|
|
return packet;
|
|
}
|
|
|
|
void skillerctl_make_packet(skillerctl_packet_t *packet, uint8_t command, uint16_t address, void* payload, uint8_t size)
|
|
{
|
|
packet->magic = SK_MAGIC;
|
|
packet->address = address;
|
|
packet->command = command;
|
|
packet->length = size;
|
|
|
|
memset(packet->payload, 0, SK_MAX_PAYLOAD);
|
|
|
|
if (payload && size)
|
|
memcpy(packet->payload, payload, size);
|
|
|
|
packet->checksum = skillectl_packet_checksum(packet);
|
|
}
|
|
|
|
uint16_t skillectl_packet_checksum(skillerctl_packet_t *packet)
|
|
{
|
|
uint16_t checksum = 0;
|
|
|
|
checksum += (packet->command) & 0xFF;
|
|
checksum += (packet->address) & 0xFF;
|
|
checksum += (packet->address >> 8) & 0xFF;
|
|
checksum += (packet->length) & 0xFF;
|
|
|
|
for (int i = 0; i < packet->length; i++) {
|
|
checksum += packet->payload[i];
|
|
}
|
|
|
|
return checksum;
|
|
}
|
|
|
|
void skillerctl_color_command(skillerctl_packet_t *packet, skillerctl_keyaddr_t address, uint32_t color)
|
|
{
|
|
skillerctl_payload_color_t payload;
|
|
|
|
payload.color[0].r = (color >> 16) & 0xFF;
|
|
payload.color[0].g = (color >> 8) & 0xFF;
|
|
payload.color[0].b = color & 0xFF;
|
|
|
|
skillerctl_make_packet(packet, SK_CMD_SET_COLOR, address, &payload, 3);
|
|
}
|
|
|
|
void skillerctl_color_batch_command(skillerctl_packet_t *packet, skillerctl_keyaddr_t address, uint32_t *color, size_t n)
|
|
{
|
|
skillerctl_payload_color_t payload;
|
|
|
|
for (int i = 0; i < n; i++) {
|
|
payload.color[i].r = (color[i] >> 16) & 0xFF;
|
|
payload.color[i].g = (color[i] >> 8) & 0xFF;
|
|
payload.color[i].b = color[i] & 0xFF;
|
|
}
|
|
|
|
skillerctl_make_packet(packet, SK_CMD_SET_COLOR, address, &payload, 3*n);
|
|
}
|
|
|
|
void skillerctl_enable_led_command(skillerctl_packet_t *packet)
|
|
{
|
|
skillerctl_payload_color_t payload;
|
|
skillerctl_make_packet(packet, SK_CMD_ENABLE_LED, 0x0000, NULL, 0);
|
|
}
|
|
|
|
void skillerctl_disable_led_command(skillerctl_packet_t *packet)
|
|
{
|
|
skillerctl_payload_color_t payload;
|
|
skillerctl_make_packet(packet, SK_CMD_DISABLE_LED, 0x0000, NULL, 0);
|
|
}
|
|
|
|
void skillerctl_set_mode_command(skillerctl_packet_t *packet, uint8_t mode)
|
|
{
|
|
skillerctl_make_packet(packet, SK_CMD_SET_PROP, SK_PROP_MODE, &mode, 1);
|
|
}
|
|
|
|
void skillerctl_set_brightness_command(skillerctl_packet_t *packet, uint8_t brightness)
|
|
{
|
|
skillerctl_make_packet(packet, SK_CMD_SET_PROP, SK_PROP_BRIGHTNESS, &brightness, 1);
|
|
}
|
|
|
|
void skillerctl_set_direction_command(skillerctl_packet_t *packet, uint8_t direction)
|
|
{
|
|
skillerctl_make_packet(packet, SK_CMD_SET_PROP, SK_PROP_DIRECTION, &direction, 1);
|
|
}
|
|
|
|
void skillerctl_set_rgb_command(skillerctl_packet_t *packet, uint8_t rgb)
|
|
{
|
|
skillerctl_make_packet(packet, SK_CMD_SET_PROP, SK_PROP_RGB, &rgb, 1);
|
|
}
|
|
|
|
void skillerctl_set_speed_command(skillerctl_packet_t *packet, uint8_t speed)
|
|
{
|
|
skillerctl_make_packet(packet, SK_CMD_SET_PROP, SK_PROP_SPEED, &speed, 1);
|
|
}
|
|
|
|
void skillerctl_set_polling_command(skillerctl_packet_t *packet, uint8_t rate)
|
|
{
|
|
skillerctl_make_packet(packet, SK_CMD_SET_PROP, SK_PROP_POLLING, &rate, 1);
|
|
}
|
|
|
|
void skillerctl_set_base_color_command(skillerctl_packet_t *packet, uint32_t color)
|
|
{
|
|
skillerctl_payload_color_t payload;
|
|
|
|
payload.color[0].r = (color >> 16) & 0xFF;
|
|
payload.color[0].g = (color >> 8) & 0xFF;
|
|
payload.color[0].b = color & 0xFF;
|
|
|
|
skillerctl_make_packet(packet, SK_CMD_SET_PROP, SK_PROP_COLOR, &payload, 3);
|
|
}
|
|
|
|
char* skillerctl_modestr(skillerctl_mode_t mode)
|
|
{
|
|
switch (mode) {
|
|
case SK_MODE_WAVE: return "SK_MODE_WAVE";
|
|
case SK_MODE_DRIFT: return "SK_MODE_DRIFT";
|
|
case SK_MODE_SWIRL: return "SK_MODE_SWIRL";
|
|
case SK_MODE_CHANGE: return "SK_MODE_CHANGE";
|
|
case SK_MODE_PULSATING: return "SK_MODE_PULSATING";
|
|
case SK_MODE_PERMAMENT: return "SK_MODE_PERMAMENT";
|
|
case SK_MODE_TRIGGER: return "SK_MODE_TRIGGER";
|
|
case SK_MODE_EXPLOSION: return "SK_MODE_EXPLOSION";
|
|
case SK_MODE_BURST: return "SK_MODE_BURST";
|
|
case SK_MODE_CHAOS: return "SK_MODE_CHAOS";
|
|
case SK_MODE_COSMIC: return "SK_MODE_COSMIC";
|
|
case SK_MODE_GRADIENT: return "SK_MODE_GRADIENT";
|
|
case SK_MODE_TIDE: return "SK_MODE_TIDE";
|
|
case SK_MODE_LIGHTING: return "SK_MODE_LIGHTING";
|
|
case SK_MODE_MATRIX: return "SK_MODE_MATRIX";
|
|
case SK_MODE_RICOCHET: return "SK_MODE_RICOCHET";
|
|
case SK_MODE_RIPPLE: return "SK_MODE_RIPPLE";
|
|
case SK_MODE_CUSTOM: return "SK_MODE_CUSTOM";
|
|
}
|
|
|
|
return "SK_MODE_UNKNOWN";
|
|
}
|
|
|
|
skillerctl_mode_t skillerctl_strmode(const char *mode)
|
|
{
|
|
return skillerctl_lut_search(modesLUT, sizeof(modesLUT) / sizeof(skillerctl_name_value_pair_t), mode);
|
|
}
|