Skip to content

Instantly share code, notes, and snippets.

@mweyland
Created May 2, 2014 14:29
Show Gist options
  • Save mweyland/022817fe157d45bbaa0d to your computer and use it in GitHub Desktop.
Save mweyland/022817fe157d45bbaa0d to your computer and use it in GitHub Desktop.
#ifndef BUTTON_DRIVER_H_
#define BUTTON_DRIVER_H_
interface button_interface
{
void pressed(void);
};
void button_driver(in port button_port, client interface button_interface button_interface);
#endif
#include <xs1.h>
#include "button_driver.h"
#define DEBOUNCE_DELAY 10 // in ms
void button_driver(in port button_port, client interface button_interface button_interface)
{
int current_val = 0;
int is_stable = 1;
timer t;
unsigned debounce_timeout;
while(1)
{
select
{
case is_stable => button_port when pinsneq(current_val) :> int new_val:
if(!(new_val & 0x01))
button_interface.pressed();
current_val = new_val;
is_stable = 0;
int current_time;
t :> current_time;
debounce_timeout = current_time + (DEBOUNCE_DELAY * XS1_TIMER_MHZ * 1000);
break;
case !is_stable => t when timerafter(debounce_timeout) :> void:
is_stable = 1;
break;
}
}
}
#ifndef LARSSON_H_
#define LARSSON_H_
#include <stdint.h>
enum larsson_mode
{
KITT,
KARR
};
typedef struct larsson_s
{
int8_t dir;
uint16_t current_index;
} larsson_s;
void larsson_init(larsson_s &this, uint8_t buf[], uint16_t len);
void larsson_update(larsson_s &this, uint8_t buf[], uint16_t len, enum larsson_mode mode);
#endif
#include "larsson.h"
void larsson_init(larsson_s &this, uint8_t buf[], uint16_t len)
{
this.current_index = 0;
this.dir = 1;
for(uint16_t i=0; i < len; i++)
{
buf[i] = 0;
}
}
void larsson_update(larsson_s &this, uint8_t buf[], uint16_t len, enum larsson_mode mode)
{
for(uint16_t i=0; i < len; i++)
{
buf[i] >>= 1;
}
buf[this.current_index*3+1] = 0xff;
if(mode == KARR) buf[this.current_index*3] = 0xff;
if((this.dir == 1 && this.current_index*3 == len-3) || (this.dir == -1 && this.current_index*3 == 0))
{
this.dir *= -1;
}
this.current_index += this.dir;
}
#include <xs1.h>
#include <platform.h>
#include "ws2811_driver.h"
#include "button_driver.h"
out buffered port:4 led_strip_port = XS1_PORT_1A;
in port button_port = XS1_PORT_32A;
int main(void)
{
interface button_interface i_button;
par
{
on tile[0]: ws2811_driver(led_strip_port, i_button);
on tile[0]: button_driver(button_port, i_button);
}
return 0;
}
#ifndef WS2811_DRIVER_H_
#define WS2811_DRIVER_H_
#include "button_driver.h"
void ws2811_driver(out buffered port:4 p, server interface button_interface button_interface);
#endif
#include <xs1.h>
#include <platform.h>
#include <stdint.h>
#include "button_driver.h"
#include "larsson.h"
#define LED_COUNT 40*3 // 75 RGB LEDs (3 colours)
//#define UPDATE_PERIOD 3000 // Update every 3000 ms
#define UPDATE_PERIOD 50 // Update every 50 ms
timer t;
clock led_clock = XS1_CLKBLK_1;
void ws2811_driver(out buffered port:4 p, server interface button_interface button_interface)
{
configure_clock_rate(led_clock, 100, 32);
configure_out_port(p, led_clock, 0);
start_clock(led_clock);
uint8_t led_buffer[LED_COUNT];
larsson_s s;
larsson_init(s, led_buffer, LED_COUNT);
enum larsson_mode mode = KITT;
uint32_t time;
t :> time;
for(uint8_t i=0; i<200; i++) p<:0b0001;
while(1)
{
[[ordered]]
select
{
case t when timerafter(time) :> void:
for(uint16_t i=0; i<LED_COUNT; i++)
{
for(uint8_t j=0; j<8; j++)
{
if((led_buffer[i] >> (7-j)) & 0x01)
{
p <: 0b0011;
}
else
{
p <: 0b0001;
}
}
}
p <: 0b0000; // reset
larsson_update(s, led_buffer, LED_COUNT, mode);
time += UPDATE_PERIOD * XS1_TIMER_MHZ * 1000;
break;
case button_interface.pressed(void):
mode = (mode == KITT) ? KARR : KITT;
break;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment