Browse Source

driver for LED tester

feature/2015
Christian Kroll 10 years ago
parent
commit
0fbadb7012
  1. 4
      src/borg_hw/Makefile
  2. 172
      src/borg_hw/borg_hw_led_tester.c
  3. 7
      src/borg_hw/config.in
  4. 22
      src/borg_hw/config_borg_led_tester.in
  5. 11
      src/uart/uart_commands.c

4
src/borg_hw/Makefile

@ -67,6 +67,10 @@ ifeq ($(BORG_HW),HW_ANCIENTBORG)
SRC = borg_hw_ancient.c
endif
ifeq ($(BORG_HW),HW_LED_TESTER)
SRC = borg_hw_led_tester.c
endif
ifeq ($(SRC),'')
$(error no valid hardware driver selected )
endif

172
src/borg_hw/borg_hw_led_tester.c

@ -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
}

7
src/borg_hw/config.in

@ -22,7 +22,8 @@ choice 'Hardware Driver' \
4xPD1165 HW_PD1165 \
Ping-Pong HW_PINGPONG \
Giga-Borg HW_GIGABORG \
Ancient-Borg HW_ANCIENTBORG" \
Ancient-Borg HW_ANCIENTBORG \
LED-Tester HW_LED_TESTER" \
'Borg-16' BORG_HW
@ -86,6 +87,10 @@ if [ "$BORG_HW" == "HW_ANCIENTBORG" ] ; then
source src/borg_hw/config_ancient.in
fi
if [ "$BORG_HW" == "HW_LED_TESTER" ] ; then
source src/borg_hw/config_borg_led_tester.in
fi
endmenu

22
src/borg_hw/config_borg_led_tester.in

@ -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

11
src/uart/uart_commands.c

@ -31,7 +31,12 @@
# define UART_PUTC uart1_putc
#endif
#define UART_BUFFER_SIZE (SCROLLTEXT_BUFFER_SIZE + 8)
#ifdef SCROLLTEXT_BUFFER_SIZE
# define UART_BUFFER_SIZE (SCROLLTEXT_BUFFER_SIZE + 8)
#else
# define UART_BUFFER_SIZE 136
#endif
char g_rx_buffer[UART_BUFFER_SIZE];
uint8_t g_rx_index;
@ -151,6 +156,7 @@ static void uartcmd_erase_eeprom(void) {
* Displays a simple message without the need to prefix a scrolltext command.
*/
static void uartcmd_simple_message(void) {
#ifdef SCROLLTEXT_SUPPORT
if (uartcmd_processing_allowed()) {
uartcmd_forbid();
#ifdef JOYSTICK_SUPPORT
@ -172,6 +178,7 @@ static void uartcmd_simple_message(void) {
#endif
uartcmd_permit();
}
#endif
}
@ -179,6 +186,7 @@ static void uartcmd_simple_message(void) {
* Displays a message which may use the complete range of scrolltext commands.
*/
static void uartcmd_scroll_message(void) {
#ifdef SCROLLTEXT_SUPPORT
if (uartcmd_processing_allowed()) {
uartcmd_forbid();
#ifdef JOYSTICK_SUPPORT
@ -196,6 +204,7 @@ static void uartcmd_scroll_message(void) {
#endif
uartcmd_permit();
}
#endif
}

Loading…
Cancel
Save