V2 stuff done, initial LED support

This commit is contained in:
William Toohey
2016-10-26 19:52:03 +10:00
parent e6d32a2b4c
commit 37ee52ee4b
6 changed files with 176 additions and 109 deletions
-30
View File
@@ -1,33 +1,3 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2014.
dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org
*/
/*
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaims all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special
+25 -76
View File
@@ -1,46 +1,9 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2014.
dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org
*/
/*
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaims all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Main source file for the Keyboard demo. This file contains the main tasks of
* the demo and is responsible for the initial application hardware configuration.
*/
#include "Keyboard.h"
#include "Config.h"
#include "Encoder.h"
#include "LED.h"
#define READ_SWITCH(x) (!(*pins[switches[x].switchPort] & _BV(switches[x].switchPin)))
#define SET_LED(x) (*ports[switches[x].lightPort] |= _BV(switches[x].lightPin))
#define CLEAR_LED(x) (*ports[switches[x].lightPort] &= ~_BV(switches[x].lightPin))
typedef struct
{
@@ -125,21 +88,19 @@ static volatile uint8_t *ddrs[] = {&DDRB, &DDRC, &DDRD};
typedef struct {
port_t switchPort;
uint8_t switchPin;
port_t lightPort;
uint8_t lightPin;
uint8_t state;
uint8_t lastReport;
uint8_t debounce;
} switch_t;
static switch_t switches[SWITCH_COUNT] = {
{C, 7, C, 6}, // A
{B, 4, B, 5}, // B
{B, 2, B, 3}, // C
{D, 6, D, 7}, // D
{B, 6, B, 7}, // FX L
{B, 0, B, 1}, // FX R
{D, 5, D, 4} // START
{B, 1}, // A
{D, 7}, // B
{D, 5}, // C
{D, 4}, // D
{B, 0}, // FX L
{D, 6}, // FX R
{C, 2} // START
};
static uint8_t switchesChanged = 1;
@@ -174,13 +135,7 @@ void update_switches(void) {
uint8_t i, newState;
for(i = 0; i < SWITCH_COUNT; i++) {
// The I2C data starts at the 6th bit and goes down
newState = READ_SWITCH(i);
if(newState) {
SET_LED(i);
} else {
CLEAR_LED(i);
}
if(!switches[i].debounce && newState != switches[i].lastReport) {
switches[i].state = newState;
switches[i].debounce = sdvxConfig.debounce;
@@ -189,32 +144,25 @@ void update_switches(void) {
}
}
/** Main program entry point. This routine contains the overall program flow, including initial
* setup of all components and the main program loop.
*/
int main(void)
{
GlobalInterruptDisable();
uint8_t i;
InitConfig();
SetupHardware();
// FX_L held while plugging in
if(READ_SWITCH(4)) {
RebootToBootloader();
}
// Blink to show we're not in bootloader
for(i = 0; i < SWITCH_COUNT; i++) {
*ports[switches[i].lightPort] |= _BV(switches[i].lightPin);
_delay_ms(50);
*ports[switches[i].lightPort] &= ~_BV(switches[i].lightPin);
}
GlobalInterruptEnable();
// Blink to show we're not in bootloader
for(uint8_t i = 0; i < LED_COUNT; i++) {
led_set(i, 32, 0, 0);
_delay_ms(1000);
led_set(i, 0, 0, 0);
}
// Not in SetupHardware so we don't time out
USB_Init();
for (;;)
{
@@ -225,7 +173,7 @@ int main(void)
}
}
/** Configures the board hardware and chip peripherals for the demo's functionality. */
/** Configures the board hardware and chip peripherals */
void SetupHardware()
{
uint8_t i;
@@ -242,15 +190,16 @@ void SetupHardware()
*ddrs[switches[i].switchPort] &= ~_BV(switches[i].switchPin);
// with internal pullups
*ports[switches[i].switchPort] |= _BV(switches[i].switchPin);
// setup LEDs to be outputs
*ddrs[switches[i].lightPort] |= _BV(switches[i].lightPin);
// off by default
*ports[switches[i].lightPort] &= ~_BV(switches[i].lightPin);
}
// FX_L held while plugging in
if(READ_SWITCH(4)) {
RebootToBootloader();
}
/* Hardware Initialization */
encoder_init();
USB_Init();
led_init();
}
/** HID class driver callback function for the creation of HID reports to the host.
+135
View File
@@ -0,0 +1,135 @@
#include "LED.h"
//#include <util/delay.h>
#define BRIGHTNESS_LEVELS 64
#define GND_COUNT 4
// RGB * 2
#define LED_PINS 6
// LED gnd 0-3 are on PC7-4
#define GND_PORT PORTC
#define GND_DDR DDRC
#define GND_MASK 0xF0
#define GND_OFFSET 4 // in bits
// LED power BGR BGR PB2-7
#define LED_PORT PORTB
#define LED_DDR DDRB
#define LED_MASK (0b111111 << 2)
#define R 2
#define G 1
#define B 0
//typedef struct {
// uint8_t gnd;
// uint8_t brightness;
//} matrix_t;
// Arranged left to right, bottom to top
static volatile uint8_t leds[LED_COUNT][3];
//volatile matrix_t current;
volatile uint8_t currentGnd;
// This saves us doing a costly dynamic _BV()
volatile uint8_t currentGndMask;
volatile uint8_t currentBright;
void led_init() {
// all GNDs low level for high impedence or gnd
GND_PORT &= ~GND_MASK;
// all GNDs input
GND_DDR &= ~GND_MASK;
// Because we roll over on each loop and want to start at 0
currentBright = BRIGHTNESS_LEVELS - 1;
currentGnd = GND_COUNT - 1;
currentGndMask = _BV(GND_OFFSET);
// all LEDs off
LED_PORT &= ~LED_MASK;
// all LEDs output
LED_DDR |= LED_MASK;
for(uint8_t i = 0; i < LED_COUNT; i++) {
leds[i][R] = 0;
leds[i][G] = 0;
leds[i][B] = 0;
}
// 64 light levels * 60Hz update * 4 different GND pins = 15360Hz
// 520 clock cycles for our interrupt handler
// CTC mode
TCCR0A = _BV(WGM01);
// clk/8 prescaler
TCCR0B = _BV(CS01);
// 0.16% error on above calculation
OCR0A = 128;//64; DEBUG SLOWER
// Enable interrupt on OCR0A
TIMSK0 = _BV(OCIE0A);
// Clear interrupt
TIFR0 = _BV(OCF0A);
/*debug shit
sei();
while(1) {
led_set(0, 32, 0, 0);
_delay_ms(500);
led_set(0, 0, 0, 0);
_delay_ms(500);
currentGnd++;
currentGnd %= GND_COUNT;
GND_ENABLE(currentGnd);
LED_PORT &= ~LED_MASK;
LED_PORT |= 0b100010 << 2;
_delay_ms(500);
LED_PORT &= ~LED_MASK;
LED_PORT |= 0b010001 << 2;
_delay_ms(500);
LED_PORT &= ~LED_MASK;
LED_PORT |= 0b001100 << 2;
_delay_ms(500);
GND_DISABLE(currentGnd);
}*/
}
void led_set(uint8_t num, uint8_t r, uint8_t g, uint8_t b) {
leds[num][R] = r;
leds[num][G] = g;
leds[num][B] = b;
}
//if(leds[(currentGnd << 1) + side][colour] <= currentBright)
#define LED_SET(side, colour, outPin) \
if(leds[offset + side][colour] > currentBright) \
out |= _BV(outPin)
// This function takes about 279 clock cycles. Could be improved :(
// Optimised GND accesses got it to 157
ISR(TIMER0_COMPA_vect) {
uint8_t out = 0;
currentGnd++;
currentGndMask >>= 1;
if(currentGnd >= GND_COUNT) {
currentGnd = 0;
currentGndMask = _BV(7);
++currentBright;
currentBright %= BRIGHTNESS_LEVELS;
}
uint8_t offset = currentGnd * 2;
// Faster than loops
LED_SET(0, 0, 2);
LED_SET(0, 1, 3);
LED_SET(0, 2, 4);
LED_SET(1, 0, 5);
LED_SET(1, 1, 6);
LED_SET(1, 2, 7);
// Turn off before switch
LED_PORT &= ~LED_MASK;
GND_DDR &= ~GND_MASK;
// Enable new ground
GND_DDR |= currentGndMask;
LED_PORT |= out;
}
+13
View File
@@ -0,0 +1,13 @@
#ifndef LED_h_
#define LED_h_
#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#define LED_COUNT 8
void led_init(void);
void led_set(uint8_t num, uint8_t r, uint8_t g, uint8_t b);
#endif
+1 -1
View File
@@ -18,7 +18,7 @@ F_CPU = 8000000
F_USB = $(F_CPU)
OPTIMIZATION = s
TARGET = Keyboard
SRC = $(TARGET).c Descriptors.c Config.c Encoder.c $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS)
SRC = $(TARGET).c Descriptors.c Config.c Encoder.c LED.c $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS)
LUFA_PATH = ../LUFA
CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -IConfig/
LD_FLAGS =
+2 -2
View File
@@ -5,8 +5,8 @@ C2,YAGEO,CC0402MRX5R5BB106,1,0402 10uf
R1,YAGEO,RC0603JR-0722RL,1,0603 22r
R2,YAGEO,RC0402FR-0722RL,1,0402 22r
R3,YAGEO,RC0402JR-0710KL,1,0402 10k
"R6,R9",YAGEO,RC0603JR-07100RL,2,0603 100r
"R4,R5,R7,R8",YAGEO,RC0603JR-07150RL,4,0603 150r
"R6,R9",YAGEO,RC0603JR-07100RL,2,0603 150r
"R4,R5,R7,R8",YAGEO,RC0603JR-07150RL,4,0603 100r
U1,Atmel,ATMEGA16U2-MU,1,atmega
J1,suntech,ZX62D-B-5P8,1,usb conn
XT1,Murata,CSTCE8M00G15L99-R0,1,resonator
1 Part/Designator Mfr Mfr. Part# Quantity comment
5 R1 YAGEO RC0603JR-0722RL 1 0603 22r
6 R2 YAGEO RC0402FR-0722RL 1 0402 22r
7 R3 YAGEO RC0402JR-0710KL 1 0402 10k
8 R6,R9 YAGEO RC0603JR-07100RL 2 0603 100r 0603 150r
9 R4,R5,R7,R8 YAGEO RC0603JR-07150RL 4 0603 150r 0603 100r
10 U1 Atmel ATMEGA16U2-MU 1 atmega
11 J1 suntech ZX62D-B-5P8 1 usb conn
12 XT1 Murata CSTCE8M00G15L99-R0 1 resonator