Christian Kroll
10 years ago
5 changed files with 214 additions and 2 deletions
@ -0,0 +1,172 @@ |
|||
#include "../config.h" |
|||
#include "../makros.h" |
|||
|
|||
#include <avr/interrupt.h> |
|||
#include <avr/io.h> |
|||
#include <avr/wdt.h> |
|||
#include "borg_hw.h" |
|||
|
|||
|
|||
#if defined(__AVR_ATmega48__) || \ |
|||
defined(__AVR_ATmega48P__) || \ |
|||
defined(__AVR_ATmega88__) || \ |
|||
defined(__AVR_ATmega88P__) || \ |
|||
defined(__AVR_ATmega168__) || \ |
|||
defined(__AVR_ATmega168P__) || \ |
|||
defined(__AVR_ATmega328__) || \ |
|||
defined(__AVR_ATmega328P__) |
|||
# define TIMER0_OFF() TCCR0A = 0; TCCR0B = 0 |
|||
# define TIMER0_MODE_CS256() TCCR0A = _BV(WGM01); TCCR0B = _BV(CS02) |
|||
# define TIMER0_RESET() TCNT0 = 0 |
|||
# define TIMER0_COMPARE(t) OCR0A = t |
|||
# define TIMER0_INT_ENABLE() TIMSK0 = _BV(OCIE0A) |
|||
# define TIMER0_ISR TIMER0_COMPA_vect |
|||
#else // ATmega8
|
|||
# define TIMER0_OFF() TCCR0 = 0 |
|||
# define TIMER0_MODE_CS256() TCCR0 = _BV(CS02) |
|||
# define TIMER0_RESET() TCNT0 = 0 |
|||
# define TIMER0_COMPARE(t) TCNT0 = (0xff - t) |
|||
# define TIMER0_INT_ENABLE() TIMSK = _BV(TOIE0) |
|||
# define TIMER0_ISR TIMER0_OVF_vect |
|||
#endif |
|||
|
|||
|
|||
/* Output data of the current row to the column drivers:
|
|||
* Column: 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 |
|||
* Pin: PD2 PD3 PC5 PC4 PC3 PC2 PC1 PC0 PD7 PD6 PB5 PB4 PB3 PB2 PB1 PB0 |
|||
*/ |
|||
#define DISPLAY_PINS_B (_BV(PB5)|_BV(PB4)|_BV(PB3)|_BV(PB2)|_BV(PB1)|_BV(PB0)) |
|||
#define DISPLAY_PINS_C (_BV(PC5)|_BV(PC4)|_BV(PC3)|_BV(PC2)|_BV(PC1)|_BV(PC0)) |
|||
#define DISPLAY_PINS_D (_BV(PD7)|_BV(PD6)|_BV(PD3)|_BV(PD2)) |
|||
|
|||
#define ROW_DUMMY_PORT PORTB |
|||
#define ROW_DUMMY_DDR DDRB |
|||
#define ROW_DUMMY_PIN PB7 |
|||
#define ROW_LED_PORT PORTD |
|||
#define ROW_LED_DDR DDRD |
|||
#define ROW_LED_PIN PD5 |
|||
|
|||
// buffer which holds the currently shown frame
|
|||
unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES]; |
|||
|
|||
|
|||
// switch to next row
|
|||
static void nextrow(uint8_t row) { |
|||
// switch off all columns for now
|
|||
PORTB &= ~(DISPLAY_PINS_B); |
|||
PORTC &= ~(DISPLAY_PINS_C); |
|||
PORTD &= ~(DISPLAY_PINS_D); |
|||
|
|||
// short delay loop, to ensure proper deactivation of the drivers
|
|||
unsigned char i; |
|||
for (i = 0; i < 10; i++) { |
|||
asm volatile("nop"); |
|||
} |
|||
|
|||
if (row == LED_TESTER_DISPLAYED_ROW) { |
|||
// configured row: unblock LED MOSFET, block resistor MOSFET
|
|||
ROW_DUMMY_PORT &= ~_BV(ROW_DUMMY_PIN); // block resistor MOSFET
|
|||
ROW_LED_PORT |= _BV(ROW_LED_PIN); // unblock LED MOSFET
|
|||
} else { /* fake rows simulated by resistors */ |
|||
// remaining rows: unblock resistor MOSFET, block LED MOSFET
|
|||
ROW_LED_PORT &= ~_BV(ROW_LED_PIN); // block LED MOSFET
|
|||
ROW_DUMMY_PORT |= _BV(ROW_DUMMY_PIN); // block resistor MOSFET
|
|||
} |
|||
|
|||
// another delay loop, to ensure that the drivers are ready
|
|||
for (i = 0; i < 20; i++) { |
|||
asm volatile("nop"); |
|||
} |
|||
} |
|||
|
|||
|
|||
// show a row
|
|||
static void rowshow(unsigned char row, unsigned char plane) { |
|||
// depending on the currently drawn plane, display the row for a specific
|
|||
// amount of time
|
|||
#ifdef HIGH_CONTRAST |
|||
static unsigned char const ocr_table[] = {2, 5, 22}; |
|||
#else |
|||
static unsigned char const ocr_table[] = {3, 4, 22}; |
|||
#endif |
|||
|
|||
TIMER0_COMPARE(ocr_table[plane]); |
|||
|
|||
uint8_t port_b = (PORTB & ~DISPLAY_PINS_B) | (0x3f & pixmap[plane][row][0]); |
|||
uint8_t port_c = (PORTC & ~DISPLAY_PINS_C) | (0x3f & pixmap[plane][row][1]); |
|||
uint8_t port_d = (PORTD & ~DISPLAY_PINS_D) | (0xc0 & pixmap[plane][row][0]); |
|||
if (0x40u & pixmap[plane][row][1]) port_d |= _BV(PD3); |
|||
if (0x80u & pixmap[plane][row][1]) port_d |= _BV(PD2); |
|||
|
|||
PORTB = port_b; |
|||
PORTC = port_c; |
|||
PORTD = port_d; |
|||
} |
|||
|
|||
|
|||
// interrupt handler
|
|||
ISR(TIMER0_ISR) { |
|||
static unsigned char plane = 0; |
|||
static unsigned char row = 0; |
|||
|
|||
// increment both row and plane
|
|||
if (++plane == NUMPLANE) { |
|||
plane = 0; |
|||
if (++row == NUM_ROWS) { |
|||
// reset watchdog
|
|||
wdt_reset(); |
|||
|
|||
row = 0; |
|||
} |
|||
nextrow(row); |
|||
} |
|||
|
|||
// output current row according to current plane
|
|||
rowshow(row, plane); |
|||
} |
|||
|
|||
|
|||
// disables timer, causing the watchdog to reset the MCU
|
|||
void timer0_off() { |
|||
cli(); |
|||
// switch off all columns
|
|||
PORTB &= ~(DISPLAY_PINS_B); |
|||
PORTC &= ~(DISPLAY_PINS_C); |
|||
PORTD &= ~(DISPLAY_PINS_D); |
|||
TIMER0_OFF(); |
|||
sei(); |
|||
} |
|||
|
|||
|
|||
// initialize timer which triggers the interrupt
|
|||
static void timer0_on() { |
|||
TIMER0_MODE_CS256(); // CTC mode, prescaling conforms to clk/256
|
|||
TIMER0_RESET(); // set counter to 0
|
|||
TIMER0_COMPARE(20); // compare with this value first
|
|||
TIMER0_INT_ENABLE(); // enable Timer/Counter0 Output Compare Match (A) Int.
|
|||
} |
|||
|
|||
|
|||
void borg_hw_init() { |
|||
// switch column and row ports to output mode
|
|||
DDRB |= DISPLAY_PINS_B; |
|||
DDRC |= DISPLAY_PINS_C; |
|||
DDRD |= DISPLAY_PINS_D; |
|||
ROW_DUMMY_DDR |= _BV(ROW_DUMMY_PIN); |
|||
ROW_LED_DDR |= _BV(ROW_LED_PIN); |
|||
|
|||
// switch off all columns for now
|
|||
PORTB &= ~(DISPLAY_PINS_B); |
|||
PORTC &= ~(DISPLAY_PINS_C); |
|||
PORTD &= ~(DISPLAY_PINS_D); |
|||
|
|||
// switch off all rows
|
|||
ROW_DUMMY_PORT &= ~_BV(ROW_DUMMY_PIN); |
|||
ROW_LED_PORT &= ~_BV(ROW_LED_PIN); |
|||
|
|||
timer0_on(); |
|||
|
|||
// activate watchdog timer
|
|||
wdt_reset(); |
|||
wdt_enable(WDTO_15MS); // 15ms watchdog
|
|||
} |
@ -0,0 +1,22 @@ |
|||
mainmenu_option next_comment |
|||
comment "LED Tester Setup" |
|||
|
|||
bool "Higher Contrast" HIGH_CONTRAST n |
|||
|
|||
bool "UART Support" UART_SUPPORT n |
|||
choice 'Baud Rate' \ |
|||
"2400 2400 \ |
|||
4800 4800 \ |
|||
9600 9600 \ |
|||
14400 14400 \ |
|||
19200 19200 \ |
|||
28800 28800 \ |
|||
38400 38400 \ |
|||
57600 57600 \ |
|||
76800 76800 \ |
|||
115200 115200" \ |
|||
'19200' UART_BAUDRATE_SETTING |
|||
|
|||
int "Displayed row" LED_TESTER_DISPLAYED_ROW 0 |
|||
|
|||
endmenu |
Loading…
Reference in new issue