243 lines
6.9 KiB
C
243 lines
6.9 KiB
C
#include "keyboard.h"
|
|
#include <avr/io.h>
|
|
#include <avr/wdt.h>
|
|
#include <util/delay.h>
|
|
#include <avr/pgmspace.h>
|
|
#include <avr/interrupt.h>
|
|
#include <avr/eeprom.h>
|
|
#include "usbdrv.h"
|
|
#include "lib/prgKeyboard.h"
|
|
#include "lib/ws2812.h"
|
|
|
|
// COMMANDS:
|
|
#define CMD_PING 0
|
|
#define CMD_SWVERSION 1
|
|
#define CMD_EEWRITE 2
|
|
#define CMD_EEREAD 3
|
|
#define CMD_EEOPEN 4 // Can be used if errors occour while writing to the device.
|
|
#define CMD_RESET 5 // WDT RESET
|
|
#define CMD_SERIAL 6 // DEV-Serial
|
|
#define CMD_IEEWRITE 7 //internal eeprom
|
|
#define CMD_IEEREAD 8 // int. eep.
|
|
#define CMD_SETBLOCK 9
|
|
#define CMD_SETLED 10
|
|
|
|
volatile int change_block = 255;
|
|
|
|
const uint8_t PROGMEM gamma8[] = {
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
|
|
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
|
|
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
|
|
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
|
|
25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
|
|
37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
|
|
51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
|
|
69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
|
|
90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114,
|
|
115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,
|
|
144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,
|
|
177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,
|
|
215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 };
|
|
|
|
struct cRGB led[LEDS_PER_SLOT];
|
|
|
|
USB_PUBLIC uchar usbFunctionSetup(uchar data[8])
|
|
{
|
|
usbRequest_t *rq = (void *)data;
|
|
static uchar reportBuffer[2];
|
|
|
|
usbMsgPtr = reportBuffer;
|
|
if(rq->bRequest == CMD_PING) {
|
|
reportBuffer[0] = rq->wValue.bytes[0];
|
|
return 1;
|
|
}
|
|
else if(rq->bRequest == CMD_SWVERSION) {
|
|
reportBuffer[0] = '0';
|
|
reportBuffer[1] = '1';
|
|
reportBuffer[2] = 'B';
|
|
return 3;
|
|
}
|
|
else if(rq->bRequest == CMD_EEWRITE) {
|
|
EEWriteByte(rq->wValue.bytes[0] + (rq->wValue.bytes[1] << 8), rq->wIndex.bytes[0]);
|
|
//reportBuffer[0] = EEReadByte(rq->wValue.bytes[0] + (rq->wValue.bytes[1] << 8)); // WE MIGHT HAVE 2 REMOVE THIS BECAUSE OF PERFORMANCE ISSUES -- Reading back too quickly causes an error (-1)
|
|
reportBuffer[0] = rq->wIndex.bytes[0];
|
|
return 1;
|
|
}
|
|
else if(rq->bRequest == CMD_EEREAD) {
|
|
reportBuffer[0] = EEReadByte(rq->wValue.bytes[0] + (rq->wValue.bytes[1] << 8));
|
|
reportBuffer[1] = EEReadByte(rq->wValue.bytes[0] + (rq->wValue.bytes[1] << 8)); // We read twice to ensure the right value was loaded and transmitted.
|
|
return 2;
|
|
}
|
|
else if(rq->bRequest == CMD_EEOPEN) {
|
|
EEOpen();
|
|
reportBuffer[0] = 1;
|
|
return 1;
|
|
}
|
|
else if(rq->bRequest == CMD_RESET) {
|
|
wdt_enable(WDTO_15MS); // faster reboot
|
|
while (1); // Wait 'til the watchdog resets our system
|
|
}
|
|
else if(rq->bRequest == CMD_IEEWRITE) {
|
|
eeprom_write_byte(rq->wValue.bytes[0] + (rq->wValue.bytes[1] << 8), rq->wIndex.bytes[0]);
|
|
reportBuffer[0] = eeprom_read_byte(rq->wValue.bytes[0] + (rq->wValue.bytes[1] << 8)); // (WE MIGHT HAVE 2 REMOVE THIS BECAUSE OF PERFORMANCE ISSUES)
|
|
return 1;
|
|
}
|
|
else if(rq->bRequest == CMD_IEEREAD) {
|
|
reportBuffer[0] = eeprom_read_byte(rq->wValue.bytes[0] + (rq->wValue.bytes[1] << 8));
|
|
reportBuffer[1] = eeprom_read_byte(rq->wValue.bytes[0] + (rq->wValue.bytes[1] << 8)); // Check
|
|
return 2;
|
|
}
|
|
else if (rq->bRequest == CMD_SETBLOCK) {
|
|
change_block = rq->wValue.bytes[0];
|
|
return 0;
|
|
}
|
|
else if (rq->bRequest == CMD_SETLED) {
|
|
led[rq->wValue.bytes[0]].r = rq->wValue.bytes[1];
|
|
led[rq->wValue.bytes[0]].g = rq->wIndex.bytes[0];
|
|
led[rq->wValue.bytes[0]].b = rq->wIndex.bytes[1];
|
|
return 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
enum enum_state {
|
|
IDLE = 0,
|
|
LOAD,
|
|
PREP_LOAD,
|
|
RENDER,
|
|
SLEEP,
|
|
WAIT_NO_KEY
|
|
};
|
|
|
|
void keyboard(void) {
|
|
enum enum_state state = PREP_LOAD;
|
|
enum enum_state next_state = IDLE;
|
|
uint8_t i;
|
|
uint8_t factor = 1;
|
|
uint8_t key = 0;
|
|
uint16_t loadAddress;
|
|
uint16_t loadCount;
|
|
uint8_t sleepcnt = 0;
|
|
uint16_t loadAddress_ld = 0;
|
|
|
|
LED_PORT |= (1 << LED_RED);
|
|
LED_PORT |= (1 << LED_GREEN);
|
|
_delay_ms(500);
|
|
while (getKey());
|
|
|
|
wdt_enable(WDTO_2S);
|
|
EEOpen();
|
|
|
|
cli();
|
|
usbInit();
|
|
usbDeviceDisconnect();
|
|
i = 0;
|
|
while(--i){
|
|
wdt_reset();
|
|
_delay_ms(2);
|
|
}
|
|
usbDeviceConnect();
|
|
sei();
|
|
|
|
LED_PORT &= ~(1 << LED_RED);
|
|
LED_PORT |= (1 << LED_GREEN);
|
|
|
|
led[1].g = 66;
|
|
|
|
for (;;) { /* main event loop */
|
|
wdt_reset();
|
|
usbPoll();
|
|
key = getKey();
|
|
|
|
if (key == KEY_MODE) { /* Exit to bootloader */
|
|
LED_PORT |= (1 << LED_RED);
|
|
LED_PORT |= (1 << LED_GREEN);
|
|
//_delay_ms(100);
|
|
LED_PORT &= ~(1 << LED_RED);
|
|
LED_PORT &= ~(1 << LED_GREEN);
|
|
wdt_enable(WDTO_15MS);
|
|
while(1);
|
|
}
|
|
|
|
switch (state) {
|
|
case IDLE:
|
|
if (change_block != 255) {
|
|
if (change_block == 254) {
|
|
state = RENDER;
|
|
next_state = IDLE;
|
|
} else {
|
|
loadAddress_ld = (change_block) * LEDS_PER_SLOT * 3;
|
|
state = PREP_LOAD;
|
|
next_state = IDLE;
|
|
}
|
|
change_block = 255;
|
|
} else if (key) {
|
|
if (key > 12) { /* Special key */
|
|
switch (key) {
|
|
case KEY_BRIGHTNESS_UP:
|
|
factor = (factor <= 1 ? 1 : factor - 1);
|
|
break;
|
|
case KEY_BRIGHTNESS_DOWN:
|
|
factor = (factor > 30 ? 30 : factor + 1);
|
|
break;
|
|
case KEY_SF_1:
|
|
break;
|
|
case KEY_SF_2:
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
state = PREP_LOAD;
|
|
loadCount = LEDS_PER_SLOT;
|
|
} else { /* Program key */
|
|
loadAddress_ld = (key - 1) * LEDS_PER_SLOT * 3;
|
|
state = PREP_LOAD;
|
|
}
|
|
sleepcnt = 50;
|
|
next_state = SLEEP;
|
|
}
|
|
break;
|
|
case PREP_LOAD:
|
|
loadAddress = loadAddress_ld;
|
|
loadCount = LEDS_PER_SLOT;
|
|
state = LOAD;
|
|
case LOAD:
|
|
led[LEDS_PER_SLOT - loadCount].r = EEReadByte(loadAddress++);
|
|
//led[LEDS_PER_SLOT - loadCount].r = (int)pgm_read_byte(&gamma8[led[LEDS_PER_SLOT - loadCount].r]);
|
|
led[LEDS_PER_SLOT - loadCount].r = led[LEDS_PER_SLOT - loadCount].r / factor;
|
|
led[LEDS_PER_SLOT - loadCount].g = EEReadByte(loadAddress++);
|
|
////led[LEDS_PER_SLOT - loadCount].g = (int)pgm_read_byte(&gamma8[led[LEDS_PER_SLOT - loadCount].g]);
|
|
led[LEDS_PER_SLOT - loadCount].g = led[LEDS_PER_SLOT - loadCount].g / factor;
|
|
led[LEDS_PER_SLOT - loadCount].b = EEReadByte(loadAddress++);
|
|
//led[LEDS_PER_SLOT - loadCount].b = (int)pgm_read_byte(&gamma8[led[LEDS_PER_SLOT - loadCount].b]);
|
|
led[LEDS_PER_SLOT - loadCount].b = led[LEDS_PER_SLOT - loadCount].b / factor;
|
|
if (!--loadCount) {
|
|
state = RENDER;
|
|
loadCount = LEDS_PER_SLOT;
|
|
}
|
|
break;
|
|
case RENDER:
|
|
ws2812_setleds(led, LEDS_PER_SLOT);
|
|
state = next_state;
|
|
break;
|
|
|
|
case WAIT_NO_KEY:
|
|
if (!key)
|
|
state = IDLE;
|
|
next_state = IDLE;
|
|
break;
|
|
|
|
case SLEEP:
|
|
_delay_ms(2);
|
|
if (!--sleepcnt)
|
|
state = IDLE;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|