178 lines
3.7 KiB
C
178 lines
3.7 KiB
C
/***************************************************************************
|
|
* Copyright (C) 03/2010 by Olaf Rempel *
|
|
* razzor@kopf-tisch.de *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; version 2 of the License, *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with this program; if not, write to the *
|
|
* Free Software Foundation, Inc., *
|
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
|
***************************************************************************/
|
|
#include <avr/io.h>
|
|
#include <avr/interrupt.h>
|
|
#include <avr/pgmspace.h>
|
|
|
|
#define F_CPU 8000000
|
|
#include <util/delay.h>
|
|
|
|
#include "6x8_vertikal_LSB_1.h"
|
|
|
|
#define nop() asm volatile ("nop")
|
|
|
|
#define nCLEAR PB0
|
|
#define RCLK PB1
|
|
#define nOE PB2
|
|
#define MOSI PB3
|
|
#define MISO PB3
|
|
#define SCK PB5
|
|
|
|
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
|
|
|
|
static const char text[] = " <<<atmega168:Scrolltext-Demo>>> ";
|
|
|
|
/* scrollbuffer */
|
|
static volatile uint8_t data[32];
|
|
static volatile uint8_t offset;
|
|
|
|
void setRow(uint8_t row)
|
|
{
|
|
uint8_t i;
|
|
volatile uint8_t *p = data + offset + 19;
|
|
|
|
row = (1 << row);
|
|
|
|
/* bit-banging spi, 20 cols */
|
|
for (i = 0; i < 20; i++) {
|
|
PORTB &= ~(1<<MISO);
|
|
if (*p-- & row)
|
|
PORTB |= (1<<MOSI);
|
|
|
|
PORTB |= (1<<SCK);
|
|
PORTB &= ~(1<<SCK);
|
|
|
|
/* insert extra cols (unused hc595 outputs) */
|
|
if (i == 5 || i == 12 || i == 19) {
|
|
PORTB |= (1<<SCK);
|
|
PORTB &= ~(1<<SCK);
|
|
}
|
|
}
|
|
|
|
/* disable outputs, update register */
|
|
PORTB |= ((1<<nOE) | (1<<RCLK));
|
|
|
|
/* select row */
|
|
PORTC |= 0x07;
|
|
PORTC &= ~(row & 0x07);
|
|
PORTD |= 0x78;
|
|
PORTD &= ~(row & 0x78);
|
|
|
|
/* enable outputs again */
|
|
PORTB &= ~((1<<nOE) | (1<<RCLK));
|
|
}
|
|
|
|
ISR(SIG_OVERFLOW0)
|
|
{
|
|
static uint8_t row;
|
|
|
|
/* 2ms */
|
|
TCNT0 = 0xFF - 64;
|
|
|
|
setRow(row++);
|
|
if (row == 7)
|
|
row = 0;
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
/* row 1-3 */
|
|
DDRC = 0x07;
|
|
PORTC = 0x07;
|
|
|
|
/* row 4-7 */
|
|
DDRD = 0x78;
|
|
PORTD = 0x78;
|
|
|
|
/* ctrl signals */
|
|
DDRB = (1<<nCLEAR) | (1<<RCLK) | (1<<nOE) | (1<<MOSI) | (1<<SCK);
|
|
PORTB = (1<<nCLEAR) | (1<<nOE);
|
|
|
|
/* F_CPU/256, Overflow Interrupt */
|
|
TCCR0B = (1<<CS02);
|
|
TIMSK0 = (1<<TOIE0);
|
|
|
|
sei();
|
|
|
|
uint8_t mode = 0;
|
|
uint8_t pos = 0;
|
|
uint8_t delay = 0;
|
|
|
|
while (1) {
|
|
switch (mode)
|
|
{
|
|
case 0:
|
|
if (offset == 6) {
|
|
offset = 0;
|
|
if (text[pos +3] == '\0') {
|
|
pos = 0;
|
|
mode++;
|
|
|
|
} else {
|
|
pos++;
|
|
}
|
|
}
|
|
|
|
if (offset == 0) {
|
|
int i;
|
|
for (i = 0; i < 5; i++) {
|
|
memcpy_P((void *)&data[i * 6], font[(uint8_t)text[pos + i]], 5);
|
|
}
|
|
}
|
|
|
|
offset++;
|
|
delay = 6;
|
|
break;
|
|
|
|
case 1:
|
|
if (offset == 6) {
|
|
offset = 0;
|
|
if (pos == (ARRAY_SIZE(font) -3)) {
|
|
pos = 0;
|
|
mode++;
|
|
|
|
} else {
|
|
pos++;
|
|
}
|
|
}
|
|
|
|
if (offset == 0) {
|
|
int i;
|
|
for (i = 0; i < 5; i++) {
|
|
memcpy_P((void *)&data[i * 6], font[(uint8_t)pos + i], 5);
|
|
}
|
|
}
|
|
|
|
offset++;
|
|
delay = 6;
|
|
break;
|
|
|
|
default:
|
|
mode = 0;
|
|
delay = 0;
|
|
break;
|
|
}
|
|
|
|
while (delay--)
|
|
_delay_ms(10);
|
|
}
|
|
|
|
return 0;
|
|
}
|