mirror of
https://github.com/mon/PocketVoltex.git
synced 2026-09-22 22:57:58 +03:00
V2 stuff done, initial LED support
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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 =
|
||||
|
||||
@@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user