Compare commits

...

3 Commits

@ -28,3 +28,9 @@ libdeps_dir = depends
In diesem Fall sollte man davon absehen, die automatisch vom PIO In diesem Fall sollte man davon absehen, die automatisch vom PIO
heruntergeladenen Bibliotheken ins Git des eigenen Projektes einzuchecken. heruntergeladenen Bibliotheken ins Git des eigenen Projektes einzuchecken.
Es empfiehlt sich in dem Fall `depends` ins `.gitignore` einzufügen. Es empfiehlt sich in dem Fall `depends` ins `.gitignore` einzufügen.
## Interrrupts
Die UART-Schnittstelle und TWI bzw. I²C arbeiten mit Interrupts. Bei der
Initialisierung der jeweiligen (oder auch beiden) Schnittstelle mit
[UART_Init()](src/uart.c) bzw. [TWI_Init()](src/twi.c) werden die Interrupts global aktiviert.
Die Schnittstellen sind nach der Initialisierung sofort funktionsfähig und können direkt verwendet werden.

@ -1,11 +1,14 @@
#include <avr/io.h> #include <avr/io.h>
#include <stdint.h> #include <stdint.h>
#include <avr/interrupt.h>
#include "spi.h" #include "spi.h"
#include "dataflash.h" #include "dataflash.h"
void // Prevent Double Initialization
dataflash_opcode_and_address (unsigned char opcode, unsigned int page, unsigned int offset) unsigned short dataflash_flag = 0;
void dataflash_opcode_and_address(unsigned char opcode, unsigned int page, unsigned int offset)
{ {
SPI_MasterTransfer(opcode); SPI_MasterTransfer(opcode);
SPI_MasterTransfer((unsigned char)(page >> 7) & 0x1f); SPI_MasterTransfer((unsigned char)(page >> 7) & 0x1f);
@ -13,158 +16,156 @@ dataflash_opcode_and_address (unsigned char opcode, unsigned int page, unsigned
SPI_MasterTransfer((unsigned char)(offset)); SPI_MasterTransfer((unsigned char)(offset));
} }
void void dataflash_wait(void)
dataflash_wait (void)
{ {
DATAFLASH_Chip_Select; DATAFLASH_Chip_Select;
SPI_MasterTransfer(DATAFLASH_STATUS_REGISTER_READ); SPI_MasterTransfer(DATAFLASH_STATUS_REGISTER_READ);
while (!(SPI_MasterTransferRead(0x00) & 0x80)); while (!(SPI_MasterTransferRead(0x00) & 0x80))
;
DATAFLASH_Chip_Unselect; DATAFLASH_Chip_Unselect;
} }
void void dataflash_init(void)
dataflash_init (void)
{ {
// AT45DB081 doesn't actually need an intialization, // Check if already initialized
// only the ChipSelect should be configured as an output. if (!(dataflash_flag & 1))
DDRB |= (1 << PB4); {
DATAFLASH_Chip_Unselect; // Backup Status Register and disable Interrupts
SPI_MasterInit(); uint8_t sreg = SREG;
cli();
// AT45DB081 doesn't actually need an intialization,
// only the ChipSelect should be configured as an output.
DDRB |= (1 << PB4);
DATAFLASH_Chip_Unselect;
SPI_MasterInit();
// Restore Status Register
SREG = sreg;
// Set dataflash Init Flag
dataflash_flag = 1;
}
} }
void void dataflash_buffer_to_page(unsigned int page, unsigned char buffer)
dataflash_buffer_to_page (unsigned int page, unsigned char buffer)
{ {
dataflash_wait(); dataflash_wait();
DATAFLASH_Chip_Select; DATAFLASH_Chip_Select;
switch (buffer) switch (buffer)
{ {
default: default:
dataflash_opcode_and_address dataflash_opcode_and_address(DATAFLASH_BUFFER_1_TO_MAIN_MEMORY_PAGE_PROGRAM_WITH_BUILT_IN_ERASE,
(DATAFLASH_BUFFER_1_TO_MAIN_MEMORY_PAGE_PROGRAM_WITH_BUILT_IN_ERASE, page, 0x00);
page, 0x00); break;
break;
case 2:
case 2: dataflash_opcode_and_address(DATAFLASH_BUFFER_2_TO_MAIN_MEMORY_PAGE_PROGRAM_WITH_BUILT_IN_ERASE,
dataflash_opcode_and_address page, 0x00);
(DATAFLASH_BUFFER_2_TO_MAIN_MEMORY_PAGE_PROGRAM_WITH_BUILT_IN_ERASE, break;
page, 0x00); }
break;
}
DATAFLASH_Chip_Unselect; DATAFLASH_Chip_Unselect;
} }
void void dataflash_page_to_buffer(unsigned int page, unsigned char buffer)
dataflash_page_to_buffer (unsigned int page, unsigned char buffer)
{ {
dataflash_wait(); dataflash_wait();
DATAFLASH_Chip_Select; DATAFLASH_Chip_Select;
switch (buffer) switch (buffer)
{ {
default: default:
dataflash_opcode_and_address dataflash_opcode_and_address(DATAFLASH_MAIN_MEMORY_PAGE_TO_BUFFER_1_TRANSFER,
(DATAFLASH_MAIN_MEMORY_PAGE_TO_BUFFER_1_TRANSFER, page, 0x00);
page, 0x00); break;
break;
case 2:
case 2: dataflash_opcode_and_address(DATAFLASH_MAIN_MEMORY_PAGE_TO_BUFFER_2_TRANSFER,
dataflash_opcode_and_address page, 0x00);
(DATAFLASH_MAIN_MEMORY_PAGE_TO_BUFFER_2_TRANSFER, break;
page, 0x00); }
break;
}
DATAFLASH_Chip_Unselect; DATAFLASH_Chip_Unselect;
} }
void void dataflash_buffer_read(unsigned char buffer, unsigned int offset,
dataflash_buffer_read (unsigned char buffer, unsigned int offset, unsigned int length, unsigned char *array)
unsigned int length, unsigned char *array)
{ {
dataflash_wait(); dataflash_wait();
DATAFLASH_Chip_Select; DATAFLASH_Chip_Select;
switch (buffer) switch (buffer)
{ {
default: default:
dataflash_opcode_and_address dataflash_opcode_and_address(DATAFLASH_BUFFER_1_READ_LF,
(DATAFLASH_BUFFER_1_READ_LF, 0x00, offset);
0x00, offset); break;
break;
case 2:
case 2: dataflash_opcode_and_address(DATAFLASH_BUFFER_2_READ_LF,
dataflash_opcode_and_address 0x00, offset);
(DATAFLASH_BUFFER_2_READ_LF, break;
0x00, offset); }
break;
}
offset = 0x00; offset = 0x00;
while (length--) while (length--)
{ {
array[offset++] = SPI_MasterTransferRead(0x00); array[offset++] = SPI_MasterTransferRead(0x00);
} }
DATAFLASH_Chip_Unselect; DATAFLASH_Chip_Unselect;
} }
void void dataflash_buffer_write(unsigned char buffer, unsigned int offset,
dataflash_buffer_write (unsigned char buffer, unsigned int offset, unsigned int length, unsigned char *array)
unsigned int length, unsigned char *array)
{ {
dataflash_wait(); dataflash_wait();
DATAFLASH_Chip_Select; DATAFLASH_Chip_Select;
switch (buffer) switch (buffer)
{ {
default: default:
dataflash_opcode_and_address dataflash_opcode_and_address(DATAFLASH_BUFFER_1_WRITE,
(DATAFLASH_BUFFER_1_WRITE, 0x00, offset);
0x00, offset); break;
break;
case 2:
case 2: dataflash_opcode_and_address(DATAFLASH_BUFFER_2_WRITE,
dataflash_opcode_and_address 0x00, offset);
(DATAFLASH_BUFFER_2_WRITE, break;
0x00, offset); }
break;
}
offset = 0x00; offset = 0x00;
while (length--) while (length--)
{ {
SPI_MasterTransfer(array[offset++]); SPI_MasterTransfer(array[offset++]);
} }
DATAFLASH_Chip_Unselect; DATAFLASH_Chip_Unselect;
} }
void void dataflash_read(unsigned int page, unsigned int offset,
dataflash_read (unsigned int page, unsigned int offset, unsigned int length, unsigned char *array)
unsigned int length, unsigned char *array)
{ {
dataflash_wait(); dataflash_wait();
DATAFLASH_Chip_Select; DATAFLASH_Chip_Select;
dataflash_opcode_and_address(DATAFLASH_CONTINUOUS_ARRAY_READ_LF, page, offset); dataflash_opcode_and_address(DATAFLASH_CONTINUOUS_ARRAY_READ_LF, page, offset);
offset = 0x00; offset = 0x00;
while (length--) while (length--)
{ {
array[offset++] = SPI_MasterTransferRead(0x00); array[offset++] = SPI_MasterTransferRead(0x00);
} }
DATAFLASH_Chip_Unselect; DATAFLASH_Chip_Unselect;
} }
void void dataflash_chip_erase(void)
dataflash_chip_erase (void)
{ {
dataflash_wait(); dataflash_wait();
DATAFLASH_Chip_Select; DATAFLASH_Chip_Select;

@ -1,47 +1,53 @@
#include <stdint.h> #include <stdint.h>
#include "fifo.h" #include "fifo.h"
static uint8_t _fifo_get (fifo_t* f); static uint8_t _fifo_get(fifo_t *f);
void fifo_init (fifo_t* f, uint8_t* buffer, const uint8_t size) void fifo_init(fifo_t *f, uint8_t *buffer, const uint8_t size)
{ {
// Backup Status Register and disable Interrupts
uint8_t sreg = SREG;
cli();
f->count = 0; f->count = 0;
f->pread = f->pwrite = buffer; f->pread = f->pwrite = buffer;
f->read2end = f->write2end = f->size = size; f->read2end = f->write2end = f->size = size;
// Restore Status Register
SREG = sreg;
} }
uint8_t fifo_get_wait (fifo_t* f) uint8_t fifo_get_wait(fifo_t *f)
{ {
while (!f->count); while (!f->count)
;
return _fifo_get(f);
return _fifo_get(f);
} }
int16_t fifo_get_nowait (fifo_t* f) int16_t fifo_get_nowait(fifo_t *f)
{ {
if (!f->count) if (!f->count)
return -1; return -1;
return (int)_fifo_get(f); return (int)_fifo_get(f);
} }
uint8_t fifo_put (fifo_t* f, const uint8_t data) uint8_t fifo_put(fifo_t *f, const uint8_t data)
{ {
if (f->count >= f->size) if (f->count >= f->size)
return 0; return 0;
uint8_t* pwrite = f->pwrite; uint8_t *pwrite = f->pwrite;
*(pwrite++) = data; *(pwrite++) = data;
uint8_t write2end = f->write2end; uint8_t write2end = f->write2end;
if (--write2end == 0) if (--write2end == 0)
{ {
write2end = f->size; write2end = f->size;
pwrite -= write2end; pwrite -= write2end;
} }
f->write2end = write2end; f->write2end = write2end;
f->pwrite = pwrite; f->pwrite = pwrite;
@ -49,30 +55,30 @@ uint8_t fifo_put (fifo_t* f, const uint8_t data)
cli(); cli();
f->count++; f->count++;
SREG = sreg; SREG = sreg;
return 1; return 1;
} }
static uint8_t static uint8_t
_fifo_get (fifo_t* f) _fifo_get(fifo_t *f)
{ {
uint8_t* pread = f->pread; uint8_t *pread = f->pread;
uint8_t data = *(pread++); uint8_t data = *(pread++);
uint8_t read2end = f->read2end; uint8_t read2end = f->read2end;
if (--read2end == 0) if (--read2end == 0)
{ {
read2end = f->size; read2end = f->size;
pread -= read2end; pread -= read2end;
} }
f->pread = pread; f->pread = pread;
f->read2end = read2end; f->read2end = read2end;
uint8_t sreg = SREG; uint8_t sreg = SREG;
cli(); cli();
f->count--; f->count--;
SREG = sreg; SREG = sreg;
return data; return data;
} }

@ -15,138 +15,140 @@ uint8_t lcd_frameupdate = 0;
uint8_t lcd_textx = 0; uint8_t lcd_textx = 0;
uint8_t lcd_texty = 0; uint8_t lcd_texty = 0;
void // Prevent Double Initialization
LCD_Send (uint8_t data) unsigned short LCD_flag = 0;
void LCD_Send(uint8_t data)
{ {
SPI_MasterTransfer(data); SPI_MasterTransfer(data);
} }
void void LCD_Init(void)
LCD_Init (void)
{ {
SPI_MasterInit(); // Check if already initialized
if (!(LCD_flag & 1))
{
SPI_MasterInit();
/* Set Register Select and Chip Select as Output */ // Set Register Select and Chip Select as Output
DDRC |= (1<<PC7)|(1<<PC6); DDRC |= (1 << PC7) | (1 << PC6);
/* Backup Status Register and disable Interrupts */ // Backup Status Register and disable Interrupts
uint8_t sreg = SREG; uint8_t sreg = SREG;
cli(); cli();
/* Starting Init Command Sequence */ // Starting Init Command Sequence
LCD_Command_Mode; LCD_Command_Mode;
LCD_Chip_Select; LCD_Chip_Select;
LCD_Send(LCD_RESET); LCD_Send(LCD_RESET);
LCD_Send(LCD_BIAS_1_7); LCD_Send(LCD_BIAS_1_7);
LCD_Send(LCD_ELECTRONIC_VOLUME_MODE_SET); LCD_Send(LCD_ELECTRONIC_VOLUME_MODE_SET);
LCD_Send(0x08); LCD_Send(0x08);
LCD_Send(LCD_ADC_SELECT_NORMAL); LCD_Send(LCD_ADC_SELECT_NORMAL);
LCD_Send(LCD_COMMON_OUTPUT_MODE_REVERSE); LCD_Send(LCD_COMMON_OUTPUT_MODE_REVERSE);
LCD_Send(LCD_V5_VOLTAGE_REGULATOR | 0x05); LCD_Send(LCD_V5_VOLTAGE_REGULATOR | 0x05);
LCD_Send(LCD_POWER_CONTROLLER_SET | 0x07); LCD_Send(LCD_POWER_CONTROLLER_SET | 0x07);
LCD_Send(LCD_DISPLAY_ON); LCD_Send(LCD_DISPLAY_ON);
LCD_Chip_Unselect; LCD_Chip_Unselect;
LCD_Data_Mode; LCD_Data_Mode;
LCD_Clear(); LCD_Clear();
/* Restore Status Register */ // Restore Status Register
SREG = sreg; SREG = sreg;
// Initialize TWI for Backlight Control // Initialize TWI for Backlight Control
TWI_Init(); TWI_Init();
Backlight_Off(); Backlight_Off();
// Initialize Dataflash // Initialize Dataflash
dataflash_init(); dataflash_init();
// Set UART Init Flag
LCD_flag = 1;
}
} }
void void LCD_Clear(void)
LCD_Clear (void)
{ {
uint8_t x = 0, y = 0; uint8_t x = 0, y = 0;
for (y = 0; y < 8; y++) for (y = 0; y < 8; y++)
for (x = 0; x < 128; x++) for (x = 0; x < 128; x++)
lcd_framebuffer[y][x] = 0; lcd_framebuffer[y][x] = 0;
// update every line (8bits height) // update every line (8bits height)
lcd_frameupdate = 0xff; lcd_frameupdate = 0xff;
LCD_Update(); LCD_Update();
} }
void void LCD_Update(void)
LCD_Update (void)
{ {
int8_t page = 7; int8_t page = 7;
/* Backup Status Register and disable Interrupts */ // Backup Status Register and disable Interrupts
uint8_t sreg = SREG; uint8_t sreg = SREG;
cli(); cli();
do do
{
if (lcd_frameupdate & (1 << page))
{ {
if (lcd_frameupdate & (1<<page)) LCD_Chip_Select;
{ LCD_Command_Mode;
LCD_Chip_Select;
LCD_Command_Mode; LCD_Send(LCD_PAGE_ADDRESS_SET | page);
LCD_Send(LCD_COLUMN_ADDRESS_SET_H);
LCD_Send(LCD_PAGE_ADDRESS_SET | page); LCD_Send(LCD_COLUMN_ADDRESS_SET_L);
LCD_Send(LCD_COLUMN_ADDRESS_SET_H);
LCD_Send(LCD_COLUMN_ADDRESS_SET_L); LCD_Data_Mode;
LCD_Data_Mode; for (uint8_t x = 0; x < 128; x++)
LCD_Send(lcd_framebuffer[page][x]);
for (uint8_t x = 0; x < 128; x++)
LCD_Send(lcd_framebuffer[page][x]); LCD_Chip_Unselect;
LCD_Chip_Unselect;
}
} }
while (page--); } while (page--);
lcd_frameupdate = 0; lcd_frameupdate = 0;
/* Restore Status Register */ // Restore Status Register
SREG = sreg; SREG = sreg;
} }
void void LCD_DrawPixel(uint8_t x, uint8_t y, uint8_t mode)
LCD_DrawPixel (uint8_t x, uint8_t y, uint8_t mode)
{ {
// Check if x and y are within display coordinates // Check if x and y are within display coordinates
if ((x < 128) && (y < 64)) if ((x < 128) && (y < 64))
{
// Precalculate Page and Pixel values
uint8_t page = (y / 8);
uint8_t pixel = (1 << (y % 8));
switch (mode)
{ {
// Precalculate Page and Pixel values case 0:
uint8_t page = (y / 8); // Clear Pixel
uint8_t pixel = (1 << (y % 8)); lcd_framebuffer[page][x] &= ~pixel;
break;
switch (mode)
{ case 2:
case 0: // Toggle Pixel
// Clear Pixel lcd_framebuffer[page][x] ^= pixel;
lcd_framebuffer[page][x] &= ~pixel; break;
break;
default:
case 2: // Set Pixel
// Toggle Pixel lcd_framebuffer[page][x] |= pixel;
lcd_framebuffer[page][x] ^= pixel; break;
break;
default:
// Set Pixel
lcd_framebuffer[page][x] |= pixel;
break;
}
lcd_frameupdate |= (1 << page);
} }
lcd_frameupdate |= (1 << page);
}
} }
void void LCD_DrawLine(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t mode)
LCD_DrawLine (uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t mode)
{ {
// look here: http://de.wikipedia.org/wiki/Bresenham-Algorithmus // look here: http://de.wikipedia.org/wiki/Bresenham-Algorithmus
int8_t dx = abs(x1 - x0); int8_t dx = abs(x1 - x0);
@ -155,32 +157,31 @@ LCD_DrawLine (uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t mode)
int8_t sy = y0 < y1 ? 1 : -1; int8_t sy = y0 < y1 ? 1 : -1;
int8_t err = (dx > dy ? dx : -dy) / 2; int8_t err = (dx > dy ? dx : -dy) / 2;
int8_t e2; int8_t e2;
for (;;) for (;;)
{
LCD_DrawPixel(x0, y0, mode);
if (x0 == x1 && y0 == y1)
break;
e2 = err;
if (e2 > -dx)
{
err -= dy;
x0 += sx;
}
if (e2 < dy)
{ {
LCD_DrawPixel(x0, y0, mode); err += dx;
y0 += sy;
if (x0 == x1 && y0 == y1)
break;
e2 = err;
if (e2 > -dx)
{
err -= dy;
x0 += sx;
}
if (e2 < dy)
{
err += dx;
y0 += sy;
}
} }
}
} }
void void LCD_DrawCircle(uint8_t x0, uint8_t y0, uint8_t radius, uint8_t mode)
LCD_DrawCircle (uint8_t x0, uint8_t y0, uint8_t radius, uint8_t mode)
{ {
// look here: http://de.wikipedia.org/wiki/Bresenham-Algorithmus // look here: http://de.wikipedia.org/wiki/Bresenham-Algorithmus
int8_t f = 1 - radius; int8_t f = 1 - radius;
@ -188,114 +189,107 @@ LCD_DrawCircle (uint8_t x0, uint8_t y0, uint8_t radius, uint8_t mode)
int8_t ddF_y = -2 * radius; int8_t ddF_y = -2 * radius;
int8_t x = 0; int8_t x = 0;
int8_t y = radius; int8_t y = radius;
LCD_DrawPixel(x0, y0 + radius, mode); LCD_DrawPixel(x0, y0 + radius, mode);
LCD_DrawPixel(x0, y0 - radius, mode); LCD_DrawPixel(x0, y0 - radius, mode);
LCD_DrawPixel(x0 + radius, y0, mode); LCD_DrawPixel(x0 + radius, y0, mode);
LCD_DrawPixel(x0 - radius, y0, mode); LCD_DrawPixel(x0 - radius, y0, mode);
while (x < y) while (x < y)
{
if (f >= 0)
{ {
if (f >= 0) y--;
{ ddF_y += 2;
y--; f += ddF_y;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x + 1;
LCD_DrawPixel(x0 + x, y0 + y, mode);
LCD_DrawPixel(x0 - x, y0 + y, mode);
LCD_DrawPixel(x0 + x, y0 - y, mode);
LCD_DrawPixel(x0 - x, y0 - y, mode);
LCD_DrawPixel(x0 + y, y0 + x, mode);
LCD_DrawPixel(x0 - y, y0 + x, mode);
LCD_DrawPixel(x0 + y, y0 - x, mode);
LCD_DrawPixel(x0 - y, y0 - x, mode);
} }
x++;
ddF_x += 2;
f += ddF_x + 1;
LCD_DrawPixel(x0 + x, y0 + y, mode);
LCD_DrawPixel(x0 - x, y0 + y, mode);
LCD_DrawPixel(x0 + x, y0 - y, mode);
LCD_DrawPixel(x0 - x, y0 - y, mode);
LCD_DrawPixel(x0 + y, y0 + x, mode);
LCD_DrawPixel(x0 - y, y0 + x, mode);
LCD_DrawPixel(x0 + y, y0 - x, mode);
LCD_DrawPixel(x0 - y, y0 - x, mode);
}
} }
void void LCD_PutChar(const char c)
LCD_PutChar (const char c)
{ {
// basic support for cr und new line // basic support for cr und new line
switch (c) switch (c)
{ {
case '\r': case '\r':
// Carriage Return // Carriage Return
lcd_textx = 0; lcd_textx = 0;
break; break;
case '\n': case '\n':
// New Line // New Line
if (lcd_texty < 7) if (lcd_texty < 7)
lcd_texty++; lcd_texty++;
break; break;
default: default:
for (uint8_t x = 0; x < 6; x++) for (uint8_t x = 0; x < 6; x++)
lcd_framebuffer[lcd_texty][(lcd_textx * 6) + x] = pgm_read_byte(&font[(uint8_t)(c)][x]); lcd_framebuffer[lcd_texty][(lcd_textx * 6) + x] = pgm_read_byte(&font[(uint8_t)(c)][x]);
lcd_frameupdate |= (1 << lcd_texty); lcd_frameupdate |= (1 << lcd_texty);
if (lcd_textx < 20) if (lcd_textx < 20)
lcd_textx++; lcd_textx++;
break; break;
} }
} }
void void LCD_PutString(const char *s)
LCD_PutString (const char *s)
{ {
// no empty strings allowed! // no empty strings allowed!
if (*s) if (*s)
{
do
{ {
do LCD_PutChar(*s);
{ } while (*(++s));
LCD_PutChar(*s); }
}
while (*(++s));
}
} }
void void LCD_PutString_P(PGM_P s)
LCD_PutString_P (PGM_P s)
{ {
while(1) while (1)
{ {
unsigned char c = pgm_read_byte (s); unsigned char c = pgm_read_byte(s);
s++; s++;
if (c == '\0') if (c == '\0')
break; break;
LCD_PutChar(c); LCD_PutChar(c);
} }
} }
void void LCD_GotoXY(uint8_t x, uint8_t y)
LCD_GotoXY (uint8_t x, uint8_t y)
{ {
lcd_textx = x; lcd_textx = x;
lcd_texty = y; lcd_texty = y;
} }
void void LCD_WipeLine(unsigned char line)
LCD_WipeLine (unsigned char line)
{ {
unsigned char x; unsigned char x;
for (x = 0; x < 128; x++) for (x = 0; x < 128; x++)
lcd_framebuffer[line][x] = 0x00; lcd_framebuffer[line][x] = 0x00;
lcd_frameupdate |= (1 << line); lcd_frameupdate |= (1 << line);
} }
void void Backlight_Off(void)
Backlight_Off (void)
{ {
TWI_Start(); TWI_Start();
TWI_Address_RW(0xc4); TWI_Address_RW(0xc4);
@ -308,8 +302,7 @@ Backlight_Off (void)
TWI_Stop(); TWI_Stop();
} }
void void Backlight_LED(uint8_t led_selector)
Backlight_LED (uint8_t led_selector)
{ {
TWI_Start(); TWI_Start();
TWI_Address_RW(0xc4); TWI_Address_RW(0xc4);
@ -318,12 +311,11 @@ Backlight_LED (uint8_t led_selector)
TWI_Stop(); TWI_Stop();
} }
void void Backlight_PWM(uint8_t pwm, uint8_t prescaler, uint8_t value)
Backlight_PWM (uint8_t pwm, uint8_t prescaler, uint8_t value)
{ {
TWI_Start(); TWI_Start();
TWI_Address_RW(0xc4); TWI_Address_RW(0xc4);
if (pwm) if (pwm)
TWI_Write(0x13); TWI_Write(0x13);
else else
@ -334,29 +326,27 @@ Backlight_PWM (uint8_t pwm, uint8_t prescaler, uint8_t value)
TWI_Stop(); TWI_Stop();
} }
void void LCD_SavePage(unsigned int page)
LCD_SavePage (unsigned int page)
{ {
// transfer framebuffer to dataflash using buffer 2 // transfer framebuffer to dataflash using buffer 2
unsigned char line = 0; unsigned char line = 0;
for (line = 0; line < 8; line++) for (line = 0; line < 8; line++)
{ {
dataflash_buffer_write(2, 0, 128, lcd_framebuffer[line]); dataflash_buffer_write(2, 0, 128, lcd_framebuffer[line]);
dataflash_buffer_to_page(page + line, 2); dataflash_buffer_to_page(page + line, 2);
} }
} }
void void LCD_LoadPage(unsigned int page)
LCD_LoadPage (unsigned int page)
{ {
// transfer dataflash page to framebuffer // transfer dataflash page to framebuffer
unsigned char line = 0; unsigned char line = 0;
for (line = 0; line < 8; line++) for (line = 0; line < 8; line++)
{ {
dataflash_read(page + line, 0, 128, lcd_framebuffer[line]); dataflash_read(page + line, 0, 128, lcd_framebuffer[line]);
} }
// mark all lines to be updated // mark all lines to be updated
lcd_frameupdate = 0xff; lcd_frameupdate = 0xff;

@ -1,50 +1,58 @@
#include <avr/io.h> #include <avr/io.h>
#include <stdint.h> #include <stdint.h>
#include <avr/interrupt.h>
#include "spi.h" #include "spi.h"
// Prevent Double Initialization // Prevent Double Initialization
unsigned short SPI_flag = 0; unsigned short SPI_flag = 0;
void void SPI_MasterInit(void)
SPI_MasterInit (void)
{ {
/* Check if already initialized */ // Check if already initialized
if (!(SPI_flag & 1)) if (!(SPI_flag & 1))
{ {
/* Set MOSI and SCK output */ // Backup Status Register and disable Interrupts
DDRB |= (1<<PB5)|(1<<PB7); uint8_t sreg = SREG;
cli();
/* Enable SPI, Master */
SPCR = (1<<SPE)|(1<<MSTR); // Set MOSI, SCK and SS output
DDRB |= (1 << PB5) | (1 << PB7) | (1 << PB4);
/* Set Double SPI Speed Bit, SPI clock will be fck/2 */
SPSR = (1<<SPI2X); // Enable SPI, Master
SPCR = (1 << SPE) | (1 << MSTR);
/* Set SPI Init Flag */
SPI_flag = 1; // Set Double SPI Speed Bit, SPI clock will be fck/2
} SPSR = (1 << SPI2X);
// Restore Status Register
SREG = sreg;
// Set SPI Init Flag
SPI_flag = 1;
}
} }
void void SPI_MasterTransfer(unsigned char c)
SPI_MasterTransfer (unsigned char c)
{ {
/* Start transmission */ // Start transmission
SPDR = c; SPDR = c;
/* Wait for transmission complete */ // Wait for transmission complete
while (!(SPSR & (1<<SPIF))); while (!(SPSR & (1 << SPIF)))
;
} }
unsigned char unsigned char
SPI_MasterTransferRead (unsigned char c) SPI_MasterTransferRead(unsigned char c)
{ {
/* Start transmission */ // Start transmission
SPDR = c; SPDR = c;
/* Wait for transmission complete */ // Wait for transmission complete
while (!(SPSR & (1<<SPIF))); while (!(SPSR & (1 << SPIF)))
;
/* Return incoming character */
// Return incoming character
return SPDR; return SPDR;
} }

@ -6,80 +6,94 @@
volatile uint8_t twi_timeout = 0x00; volatile uint8_t twi_timeout = 0x00;
void // Prevent Double Initialization
TWI_Init (void) unsigned short TWI_flag = 0;
void TWI_Init(void)
{ {
// Port Setup // Check if already initialized
DDRC &= ~((1 << PC0)|(1 << PC1)); if (!(TWI_flag & 1))
PORTC |= (1 << PC0)|(1 << PC1); {
//disable global interrupts
// Setup TWI Speed to 400kHZ (TWPS = 1) cli();
TWBR = 3;
// Port Setup
// Using TIMER2 to detect timeout DDRC &= ~((1 << PC0) | (1 << PC1));
TCCR2B = (7 << CS20); PORTC |= (1 << PC0) | (1 << PC1);
TIMSK2 = (1 << OCIE2A);
// Setup TWI Speed to 400kHZ (TWPS = 1)
OCR2A = 125; TWBR = 3;
// Interrupts REQUIRED! // Using TIMER2 to detect timeout
sei(); TCCR2B = (7 << CS20);
TIMSK2 = (1 << OCIE2A);
OCR2A = 125;
// Set TWI Init Flag
TWI_flag = 1;
// Interrupts REQUIRED!
sei();
}
} }
int16_t int16_t
TWI_Start (void) TWI_Start(void)
{ {
twi_timeout = 10; twi_timeout = 10;
TWCR = (1 << TWINT)|(1 << TWSTA)|(1 << TWEN); TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
while ((twi_timeout) && (!(TWCR & (1 << TWINT)))); while ((twi_timeout) && (!(TWCR & (1 << TWINT))))
;
if (twi_timeout) if (twi_timeout)
return (int16_t) (TWSR & 0xf8); return (int16_t)(TWSR & 0xf8);
else else
return -1; return -1;
} }
int16_t int16_t
TWI_Address_RW (uint8_t address) TWI_Address_RW(uint8_t address)
{ {
twi_timeout = 10; twi_timeout = 10;
TWDR = address; TWDR = address;
TWCR = (1 << TWINT)|(1 << TWEN); TWCR = (1 << TWINT) | (1 << TWEN);
while ((twi_timeout) && (!(TWCR & (1 << TWINT)))); while ((twi_timeout) && (!(TWCR & (1 << TWINT))))
;
if (twi_timeout) if (twi_timeout)
return (int16_t) (TWSR & 0xf8); return (int16_t)(TWSR & 0xf8);
else else
return -1; return -1;
} }
int16_t int16_t
TWI_Write (uint8_t data) TWI_Write(uint8_t data)
{ {
twi_timeout = 10; twi_timeout = 10;
TWDR = data; TWDR = data;
TWCR = (1 << TWINT)|(1 << TWEN); TWCR = (1 << TWINT) | (1 << TWEN);
while ((twi_timeout) && (!(TWCR & (1 << TWINT)))); while ((twi_timeout) && (!(TWCR & (1 << TWINT))))
;
if (twi_timeout) if (twi_timeout)
return (int16_t) (TWSR & 0xf8); return (int16_t)(TWSR & 0xf8);
else else
return -1; return -1;
} }
void void TWI_Stop(void)
TWI_Stop (void)
{ {
twi_timeout = 10; twi_timeout = 10;
TWCR = (1 << TWINT)|(1 << TWEN)|(1 << TWSTO); TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
} }
// ISR will be called every 8ms to decrease twi_timeout if > 0 // ISR will be called every 8ms to decrease twi_timeout if > 0
ISR (TIMER2_COMPA_vect) ISR(TIMER2_COMPA_vect)
{ {
OCR2A += 125; OCR2A += 125;

@ -16,11 +16,16 @@ uint8_t uart_outbuf[UART_BUFSIZE_OUT];
fifo_t uart_infifo; fifo_t uart_infifo;
fifo_t uart_outfifo; fifo_t uart_outfifo;
// Prevent Double Initialization
unsigned short UART_flag = 0;
void void
UART_Init (void) UART_Init (void)
{ {
// Save Status Register and disable Interrupts // Check if already initialized
uint8_t sreg = SREG; if (!(UART_flag & 1))
{
//disable Interrupts
cli(); cli();
// Set Baudrate according to datasheet (16MHz -> 9600 Baud -> 103) // Set Baudrate according to datasheet (16MHz -> 9600 Baud -> 103)
@ -32,12 +37,16 @@ UART_Init (void)
// Reset Complete-Flags // Reset Complete-Flags
UCSR0A = (1 << RXC0)|(1 << TXC0); UCSR0A = (1 << RXC0)|(1 << TXC0);
// Reset Status Register // Interrupts REQUIRED!
SREG = sreg; sei();
// Initialize FIFO Buffers // Initialize FIFO Buffers
fifo_init(&uart_infifo, uart_inbuf, UART_BUFSIZE_IN); fifo_init(&uart_infifo, uart_inbuf, UART_BUFSIZE_IN);
fifo_init(&uart_outfifo, uart_outbuf, UART_BUFSIZE_OUT); fifo_init(&uart_outfifo, uart_outbuf, UART_BUFSIZE_OUT);
// Set UART Init Flag
UART_flag = 1;
}
} }
int8_t int8_t

Loading…
Cancel
Save