From d86206bb502ddaf5525571ee2db9a6640f6ff991 Mon Sep 17 00:00:00 2001 From: Ilya Elenskiy Date: Wed, 15 Apr 2020 19:30:08 +0200 Subject: [PATCH] Libs from the demo --- include/dataflash.h | 59 +++++++++ include/fifo.h | 21 +++ include/font.h | 265 ++++++++++++++++++++++++++++++++++++++ include/lcd.h | 69 ++++++++++ include/spi.h | 16 +++ include/twi.h | 11 ++ include/uart.h | 11 ++ src/dataflash.c | 176 +++++++++++++++++++++++++ src/fifo.c | 78 +++++++++++ src/lcd.c | 364 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/spi.c | 50 ++++++++ src/twi.c | 88 +++++++++++++ src/uart.c | 105 +++++++++++++++ 13 files changed, 1313 insertions(+) create mode 100644 include/dataflash.h create mode 100644 include/fifo.h create mode 100644 include/font.h create mode 100644 include/lcd.h create mode 100644 include/spi.h create mode 100644 include/twi.h create mode 100644 include/uart.h create mode 100644 src/dataflash.c create mode 100644 src/fifo.c create mode 100644 src/lcd.c create mode 100644 src/spi.c create mode 100644 src/twi.c create mode 100644 src/uart.c diff --git a/include/dataflash.h b/include/dataflash.h new file mode 100644 index 0000000..c9b9b7f --- /dev/null +++ b/include/dataflash.h @@ -0,0 +1,59 @@ +#ifndef _DATAFLASH_H_ +#define _DATAFLASH_H_ + +// Read Commands +#define DATAFLASH_MAIN_MEMORY_PAGE_READ 0xd2 +#define DATAFLASH_CONTINUOUS_ARRAY_READ_LC 0xe8 +#define DATAFLASH_CONTINUOUS_ARRAY_READ_LF 0x03 +#define DATAFLASH_CONTINUOUS_ARRAY_READ_HF 0x0b +#define DATAFLASH_BUFFER_1_READ_LF 0xd1 +#define DATAFLASH_BUFFER_2_READ_LF 0xd3 +#define DATAFLASH_BUFFER_1_READ 0xd4 +#define DATAFLASH_BUFFER_2_READ 0xd6 + +// Program and Erase Commands +#define DATAFLASH_BUFFER_1_WRITE 0x84 +#define DATAFLASH_BUFFER_2_WRITE 0x87 +#define DATAFLASH_BUFFER_1_TO_MAIN_MEMORY_PAGE_PROGRAM_WITH_BUILT_IN_ERASE 0x83 +#define DATAFLASH_BUFFER_2_TO_MAIN_MEMORY_PAGE_PROGRAM_WITH_BUILT_IN_ERASE 0x86 +#define DATAFLASH_BUFFER_1_TO_MAIN_MEMORY_PAGE_PROGRAM_WITHOUT_BUILT_IN_ERASE 0x88 +#define DATAFLASH_BUFFER_2_TO_MAIN_MEMORY_PAGE_PROGRAM_WITHOUT_BUILT_IN_ERASE 0x89 +#define DATAFLASH_PAGE_ERASE 0x81 +#define DATAFLASH_BLOCK_ERASE 0x50 +#define DATAFLASH_SECTOR_ERASE 0x7c +#define DATAFLASH_CHIP_ERASE_1 0xc7 +#define DATAFLASH_CHIP_ERASE_2 0x94 +#define DATAFLASH_CHIP_ERASE_3 0x80 +#define DATAFLASH_CHIP_ERASE_4 0x9a +#define DATAFLASH_MAIN_MEMORY_PAGE_PROGRAM_THROUGH_BUFFER_1 0x82 +#define DATAFLASH_MAIN_MEMORY_PAGE_PROGRAM_THROUGH_BUFFER_2 0x85 + +// Additional Commands +#define DATAFLASH_MAIN_MEMORY_PAGE_TO_BUFFER_1_TRANSFER 0x53 +#define DATAFLASH_MAIN_MEMORY_PAGE_TO_BUFFER_2_TRANSFER 0x55 +#define DATAFLASH_MAIN_MEMORY_PAGE_TO_BUFFER_1_COMPARE 0x60 +#define DATAFLASH_MAIN_MEMORY_PAGE_TO_BUFFER_2_COMPARE 0x61 +#define DATAFLASH_AUTO_PAGE_REWRITE_THROUGH_BUFFER_1 0x58 +#define DATAFLASH_AUTO_PAGE_REWRITE_THROUGH_BUFFER_2 0x59 +#define DATAFLASH_DEEP_POWER_DOWN 0xb9 +#define DATAFLASH_RESUME_FROM_DEEP_POWER_DOWN 0xab +#define DATAFLASH_STATUS_REGISTER_READ 0xd7 +#define DATAFLASH_MANUFACTURER_AND_DEVICE_ID_READ 0x9f + +#define DATAFLASH_Chip_Select (PORTB &= ~(1< +#include + +typedef struct +{ + uint8_t volatile count; // # Zeichen im Puffer + uint8_t size; // Puffer-Größe + uint8_t *pread; // Lesezeiger + uint8_t *pwrite; // Schreibzeiger + uint8_t read2end, write2end; // # Zeichen bis zum Überlauf Lese-/Schreibzeiger +} fifo_t; + +void fifo_init (fifo_t*, uint8_t* buf, const uint8_t size); +uint8_t fifo_put (fifo_t*, const uint8_t data); +uint8_t fifo_get_wait (fifo_t*); +int16_t fifo_get_nowait (fifo_t*); + +#endif // _FIFO_H diff --git a/include/font.h b/include/font.h new file mode 100644 index 0000000..c8ed7ee --- /dev/null +++ b/include/font.h @@ -0,0 +1,265 @@ +#ifndef _FONT_H_ +#define _FONT_H_ + +// Definition of LCD Font in Program Memory +const uint8_t PROGMEM font[256][6] = +{ + {0x00,0x00,0x00,0x00,0x00,0x00}, // 0x00 + {0x00,0x3e,0x45,0x51,0x45,0x3e}, // 0x01 + {0x00,0x3e,0x6b,0x6f,0x6b,0x3e}, // 0x02 + {0x00,0x1c,0x3e,0x7c,0x3e,0x1c}, // 0x03 + {0x00,0x18,0x3c,0x7e,0x3c,0x18}, // 0x04 + {0x00,0x30,0x36,0x7f,0x36,0x30}, // 0x05 + {0x00,0x18,0x5c,0x7e,0x5c,0x18}, // 0x06 + {0x00,0x00,0x00,0x00,0x00,0x00}, // 0x07 + {0x00,0x00,0x00,0x00,0x00,0x00}, // 0x08 + {0x00,0x00,0x00,0x00,0x00,0x00}, // 0x09 + {0x00,0x00,0x00,0x00,0x00,0x00}, // 0x0a + {0x00,0x30,0x48,0x4a,0x36,0x0e}, // 0x0b + {0x00,0x06,0x29,0x79,0x29,0x06}, // 0x0c + {0x00,0x00,0x00,0x00,0x00,0x00}, // 0x0d + {0x00,0x60,0x7e,0x0a,0x35,0x3f}, // 0x0e + {0x00,0x2a,0x1c,0x36,0x1c,0x2a}, // 0x0f + {0x00,0x00,0x7f,0x3e,0x1c,0x08}, // 0x10 + {0x00,0x08,0x1c,0x3e,0x7f,0x00}, // 0x11 + {0x00,0x14,0x36,0x7f,0x36,0x14}, // 0x12 + {0x00,0x00,0x5f,0x00,0x5f,0x00}, // 0x13 + {0x00,0x06,0x09,0x7f,0x01,0x7f}, // 0x14 + {0x00,0x22,0x4d,0x55,0x59,0x22}, // 0x15 + {0x00,0x60,0x60,0x60,0x60,0x00}, // 0x16 + {0x00,0x14,0xb6,0xff,0xb6,0x14}, // 0x17 + {0x00,0x04,0x06,0x7f,0x06,0x04}, // 0x18 + {0x00,0x10,0x30,0x7f,0x30,0x10}, // 0x19 + {0x00,0x08,0x08,0x3e,0x1c,0x08}, // 0x1a + {0x00,0x08,0x1c,0x3e,0x08,0x08}, // 0x1b + {0x00,0x78,0x40,0x40,0x40,0x40}, // 0x1c + {0x00,0x08,0x3e,0x08,0x3e,0x08}, // 0x1d + {0x00,0x30,0x3c,0x3f,0x3c,0x30}, // 0x1e + {0x00,0x03,0x0f,0x3f,0x0f,0x03}, // 0x1f + {0x00,0x00,0x00,0x00,0x00,0x00}, // 0x20 + {0x00,0x00,0x06,0x5f,0x06,0x00}, // 0x21 + {0x00,0x07,0x03,0x00,0x07,0x03}, // 0x22 + {0x00,0x24,0x7e,0x24,0x7e,0x24}, // 0x23 + {0x00,0x24,0x2b,0x6a,0x12,0x00}, // 0x24 + {0x00,0x63,0x13,0x08,0x64,0x63}, // 0x25 + {0x00,0x36,0x49,0x56,0x20,0x50}, // 0x26 + {0x00,0x00,0x07,0x03,0x00,0x00}, // 0x27 + {0x00,0x00,0x3e,0x41,0x00,0x00}, // 0x28 + {0x00,0x00,0x41,0x3e,0x00,0x00}, // 0x29 + {0x00,0x08,0x3e,0x1c,0x3e,0x08}, // 0x2a + {0x00,0x08,0x08,0x3e,0x08,0x08}, // 0x2b + {0x00,0x00,0xe0,0x60,0x00,0x00}, // 0x2c + {0x00,0x08,0x08,0x08,0x08,0x08}, // 0x2d + {0x00,0x00,0x60,0x60,0x00,0x00}, // 0x2e + {0x00,0x20,0x10,0x08,0x04,0x02}, // 0x2f + {0x00,0x3e,0x51,0x49,0x45,0x3e}, // 0x30 + {0x00,0x00,0x42,0x7f,0x40,0x00}, // 0x31 + {0x00,0x62,0x51,0x49,0x49,0x46}, // 0x32 + {0x00,0x22,0x49,0x49,0x49,0x36}, // 0x33 + {0x00,0x18,0x14,0x12,0x7f,0x10}, // 0x34 + {0x00,0x2f,0x49,0x49,0x49,0x31}, // 0x35 + {0x00,0x3c,0x4a,0x49,0x49,0x30}, // 0x36 + {0x00,0x01,0x71,0x09,0x05,0x03}, // 0x37 + {0x00,0x36,0x49,0x49,0x49,0x36}, // 0x38 + {0x00,0x06,0x49,0x49,0x29,0x1e}, // 0x39 + {0x00,0x00,0x6c,0x6c,0x00,0x00}, // 0x3a + {0x00,0x00,0xec,0x6c,0x00,0x00}, // 0x3b + {0x00,0x08,0x14,0x22,0x41,0x00}, // 0x3c + {0x00,0x24,0x24,0x24,0x24,0x24}, // 0x3d + {0x00,0x00,0x41,0x22,0x14,0x08}, // 0x3e + {0x00,0x02,0x01,0x59,0x09,0x06}, // 0x3f + {0x00,0x3e,0x41,0x5d,0x55,0x1e}, // 0x40 + {0x00,0x7e,0x11,0x11,0x11,0x7e}, // 0x41 + {0x00,0x7f,0x49,0x49,0x49,0x36}, // 0x42 + {0x00,0x3e,0x41,0x41,0x41,0x22}, // 0x43 + {0x00,0x7f,0x41,0x41,0x41,0x3e}, // 0x44 + {0x00,0x7f,0x49,0x49,0x49,0x41}, // 0x45 + {0x00,0x7f,0x09,0x09,0x09,0x01}, // 0x46 + {0x00,0x3e,0x41,0x49,0x49,0x7a}, // 0x47 + {0x00,0x7f,0x08,0x08,0x08,0x7f}, // 0x48 + {0x00,0x00,0x41,0x7f,0x41,0x00}, // 0x49 + {0x00,0x30,0x40,0x40,0x40,0x3f}, // 0x4a + {0x00,0x7f,0x08,0x14,0x22,0x41}, // 0x4b + {0x00,0x7f,0x40,0x40,0x40,0x40}, // 0x4c + {0x00,0x7f,0x02,0x04,0x02,0x7f}, // 0x4d + {0x00,0x7f,0x02,0x04,0x08,0x7f}, // 0x4e + {0x00,0x3e,0x41,0x41,0x41,0x3e}, // 0x4f + {0x00,0x7f,0x09,0x09,0x09,0x06}, // 0x50 + {0x00,0x3e,0x41,0x51,0x21,0x5e}, // 0x51 + {0x00,0x7f,0x09,0x09,0x19,0x66}, // 0x52 + {0x00,0x26,0x49,0x49,0x49,0x32}, // 0x53 + {0x00,0x01,0x01,0x7f,0x01,0x01}, // 0x54 + {0x00,0x3f,0x40,0x40,0x40,0x3f}, // 0x55 + {0x00,0x1f,0x20,0x40,0x20,0x1f}, // 0x56 + {0x00,0x3f,0x40,0x3c,0x40,0x3f}, // 0x57 + {0x00,0x63,0x14,0x08,0x14,0x63}, // 0x58 + {0x00,0x07,0x08,0x70,0x08,0x07}, // 0x59 + {0x00,0x71,0x49,0x45,0x43,0x00}, // 0x5a + {0x00,0x00,0x7f,0x41,0x41,0x00}, // 0x5b + {0x00,0x02,0x04,0x08,0x10,0x20}, // 0x5c + {0x00,0x00,0x41,0x41,0x7f,0x00}, // 0x5d + {0x00,0x04,0x02,0x01,0x02,0x04}, // 0x5e + {0x80,0x80,0x80,0x80,0x80,0x80}, // 0x5f + {0x00,0x00,0x03,0x07,0x00,0x00}, // 0x60 + {0x00,0x20,0x54,0x54,0x54,0x78}, // 0x61 + {0x00,0x7f,0x44,0x44,0x44,0x38}, // 0x62 + {0x00,0x38,0x44,0x44,0x44,0x28}, // 0x63 + {0x00,0x38,0x44,0x44,0x44,0x7f}, // 0x64 + {0x00,0x38,0x54,0x54,0x54,0x08}, // 0x65 + {0x00,0x08,0x7e,0x09,0x09,0x00}, // 0x66 + {0x00,0x18,0xa4,0xa4,0xa4,0x7c}, // 0x67 + {0x00,0x7f,0x04,0x04,0x78,0x00}, // 0x68 + {0x00,0x00,0x00,0x7d,0x40,0x00}, // 0x69 + {0x00,0x40,0x80,0x84,0x7d,0x00}, // 0x6a + {0x00,0x7f,0x10,0x28,0x44,0x00}, // 0x6b + {0x00,0x00,0x00,0x7f,0x40,0x00}, // 0x6c + {0x00,0x7c,0x04,0x18,0x04,0x78}, // 0x6d + {0x00,0x7c,0x04,0x04,0x78,0x00}, // 0x6e + {0x00,0x38,0x44,0x44,0x44,0x38}, // 0x6f + {0x00,0xfc,0x44,0x44,0x44,0x38}, // 0x70 + {0x00,0x38,0x44,0x44,0x44,0xfc}, // 0x71 + {0x00,0x44,0x78,0x44,0x04,0x08}, // 0x72 + {0x00,0x08,0x54,0x54,0x54,0x20}, // 0x73 + {0x00,0x04,0x3e,0x44,0x24,0x00}, // 0x74 + {0x00,0x3c,0x40,0x20,0x7c,0x00}, // 0x75 + {0x00,0x1c,0x20,0x40,0x20,0x1c}, // 0x76 + {0x00,0x3c,0x60,0x30,0x60,0x3c}, // 0x77 + {0x00,0x6c,0x10,0x10,0x6c,0x00}, // 0x78 + {0x00,0x9c,0xa0,0x60,0x3c,0x00}, // 0x79 + {0x00,0x64,0x54,0x54,0x4c,0x00}, // 0x7a + {0x00,0x08,0x3e,0x41,0x41,0x00}, // 0x7b + {0x00,0x00,0x00,0x77,0x00,0x00}, // 0x7c + {0x00,0x00,0x41,0x41,0x3e,0x08}, // 0x7d + {0x00,0x02,0x01,0x02,0x01,0x00}, // 0x7e + {0x00,0x3c,0x26,0x23,0x26,0x3c}, // 0x7f + {0x00,0x1e,0xa1,0xe1,0x21,0x12}, // 0x80 + {0x00,0x3d,0x40,0x20,0x7d,0x00}, // 0x81 + {0x00,0x38,0x54,0x54,0x55,0x09}, // 0x82 + {0x00,0x20,0x55,0x55,0x55,0x78}, // 0x83 + {0x00,0x20,0x55,0x54,0x55,0x78}, // 0x84 + {0x00,0x20,0x55,0x55,0x54,0x78}, // 0x85 + {0x00,0x20,0x57,0x55,0x57,0x78}, // 0x86 + {0x00,0x1c,0xa2,0xe2,0x22,0x14}, // 0x87 + {0x00,0x38,0x55,0x55,0x55,0x08}, // 0x88 + {0x00,0x38,0x55,0x54,0x55,0x08}, // 0x89 + {0x00,0x38,0x55,0x55,0x54,0x08}, // 0x8a + {0x00,0x00,0x01,0x7c,0x41,0x00}, // 0x8b + {0x00,0x00,0x01,0x7d,0x41,0x00}, // 0x8c + {0x00,0x00,0x01,0x7c,0x40,0x00}, // 0x8d + {0x00,0x70,0x29,0x24,0x29,0x70}, // 0x8e + {0x00,0x78,0x2f,0x25,0x2f,0x78}, // 0x8f + {0x00,0x7c,0x54,0x54,0x55,0x45}, // 0x90 + {0x00,0x34,0x54,0x7c,0x54,0x58}, // 0x91 + {0x00,0x7e,0x09,0x7f,0x49,0x49}, // 0x92 + {0x00,0x38,0x45,0x45,0x39,0x00}, // 0x93 + {0x00,0x38,0x45,0x44,0x39,0x00}, // 0x94 + {0x00,0x39,0x45,0x44,0x38,0x00}, // 0x95 + {0x00,0x3c,0x41,0x21,0x7d,0x00}, // 0x96 + {0x00,0x3d,0x41,0x20,0x7c,0x00}, // 0x97 + {0x00,0x9c,0xa1,0x60,0x3d,0x00}, // 0x98 + {0x00,0x3d,0x42,0x42,0x3d,0x00}, // 0x99 + {0x00,0x3c,0x41,0x40,0x3d,0x00}, // 0x9a + {0x80,0x70,0x68,0x58,0x38,0x04}, // 0x9b + {0x00,0x48,0x3e,0x49,0x49,0x62}, // 0x9c + {0x00,0x7e,0x61,0x5d,0x43,0x3f}, // 0x9d + {0x00,0x22,0x14,0x08,0x14,0x22}, // 0x9e + {0x00,0x40,0x88,0x7e,0x09,0x02}, // 0x9f + {0x00,0x20,0x54,0x55,0x55,0x78}, // 0xa0 + {0x00,0x00,0x00,0x7d,0x41,0x00}, // 0xa1 + {0x00,0x38,0x44,0x45,0x39,0x00}, // 0xa2 + {0x00,0x3c,0x40,0x21,0x7d,0x00}, // 0xa3 + {0x00,0x7a,0x09,0x0a,0x71,0x00}, // 0xa4 + {0x00,0x7a,0x11,0x22,0x79,0x00}, // 0xa5 + {0x00,0x08,0x55,0x55,0x55,0x5e}, // 0xa6 + {0x00,0x4e,0x51,0x51,0x4e,0x00}, // 0xa7 + {0x00,0x30,0x48,0x4d,0x40,0x20}, // 0xa8 + {0x3e,0x41,0x5d,0x4b,0x55,0x3e}, // 0xa9 + {0x04,0x04,0x04,0x04,0x04,0x1c}, // 0xaa + {0x00,0x17,0x08,0x4c,0x6a,0x50}, // 0xab + {0x00,0x17,0x08,0x34,0x2a,0x78}, // 0xac + {0x00,0x00,0x30,0x7d,0x30,0x00}, // 0xad + {0x00,0x08,0x14,0x00,0x08,0x14}, // 0xae + {0x00,0x14,0x08,0x00,0x14,0x08}, // 0xaf + {0x44,0x11,0x44,0x11,0x44,0x11}, // 0xb0 + {0xaa,0x55,0xaa,0x55,0xaa,0x55}, // 0xb1 + {0xbb,0xee,0xbb,0xee,0xbb,0xee}, // 0xb2 + {0x00,0x00,0x00,0xff,0x00,0x00}, // 0xb3 + {0x08,0x08,0x08,0xff,0x00,0x00}, // 0xb4 + {0x00,0x70,0x28,0x25,0x29,0x70}, // 0xb5 + {0x00,0x70,0x29,0x25,0x29,0x70}, // 0xb6 + {0x00,0x70,0x29,0x25,0x28,0x70}, // 0xb7 + {0x3e,0x41,0x5d,0x55,0x41,0x3e}, // 0xb8 + {0x0a,0xfb,0x00,0xff,0x00,0x00}, // 0xb9 + {0x00,0xff,0x00,0xff,0x00,0x00}, // 0xba + {0x0a,0xfa,0x02,0xfe,0x00,0x00}, // 0xbb + {0x0a,0x0b,0x08,0x0f,0x00,0x00}, // 0xbc + {0x00,0x18,0x24,0x66,0x24,0x00}, // 0xbd + {0x00,0x29,0x2a,0x7c,0x2a,0x29}, // 0xbe + {0x08,0x08,0x08,0xf8,0x00,0x00}, // 0xbf + {0x00,0x00,0x00,0x0f,0x08,0x08}, // 0xc0 + {0x08,0x08,0x08,0x0f,0x08,0x08}, // 0xc1 + {0x08,0x08,0x08,0xf8,0x08,0x08}, // 0xc2 + {0x00,0x00,0x00,0xff,0x08,0x08}, // 0xc3 + {0x08,0x08,0x08,0x08,0x08,0x08}, // 0xc4 + {0x08,0x08,0x08,0xff,0x08,0x08}, // 0xc5 + {0x00,0x20,0x56,0x55,0x56,0x79}, // 0xc6 + {0x00,0x70,0x2a,0x25,0x2a,0x71}, // 0xc7 + {0x00,0x0f,0x08,0x0b,0x0a,0x0a}, // 0xc8 + {0x00,0xfe,0x02,0xfa,0x0a,0x0a}, // 0xc9 + {0x0a,0x0b,0x08,0x0b,0x0a,0x0a}, // 0xca + {0x0a,0xfa,0x02,0xfa,0x0a,0x0a}, // 0xcb + {0x00,0xff,0x00,0xfb,0x0a,0x0a}, // 0xcc + {0x0a,0x0a,0x0a,0x0a,0x0a,0x0a}, // 0xcd + {0x0a,0xfb,0x00,0xfb,0x0a,0x0a}, // 0xce + {0x00,0x5d,0x22,0x22,0x22,0x5d}, // 0xcf + {0x00,0x22,0x55,0x59,0x30,0x00}, // 0xd0 + {0x00,0x08,0x7f,0x49,0x41,0x3e}, // 0xd1 + {0x00,0x7c,0x55,0x55,0x55,0x44}, // 0xd2 + {0x00,0x7c,0x55,0x54,0x55,0x44}, // 0xd3 + {0x00,0x7c,0x55,0x55,0x54,0x44}, // 0xd4 + {0x00,0x00,0x00,0x07,0x00,0x00}, // 0xd5 + {0x00,0x00,0x44,0x7d,0x45,0x00}, // 0xd6 + {0x00,0x00,0x45,0x7d,0x45,0x00}, // 0xd7 + {0x00,0x00,0x45,0x7c,0x45,0x00}, // 0xd8 + {0x08,0x08,0x08,0x0f,0x00,0x00}, // 0xd9 + {0x00,0x00,0x00,0xf8,0x08,0x08}, // 0xda + {0xff,0xff,0xff,0xff,0xff,0xff}, // 0xdb + {0xf0,0xf0,0xf0,0xf0,0xf0,0xf0}, // 0xdc + {0x00,0x00,0x00,0x77,0x00,0x00}, // 0xdd + {0x00,0x00,0x45,0x7d,0x44,0x00}, // 0xde + {0x0f,0x0f,0x0f,0x0f,0x0f,0x0f}, // 0xdf + {0x00,0x3c,0x42,0x43,0x3d,0x00}, // 0xe0 + {0x00,0xfe,0x4a,0x4a,0x34,0x00}, // 0xe1 + {0x00,0x3c,0x43,0x43,0x3d,0x00}, // 0xe2 + {0x00,0x3d,0x43,0x42,0x3c,0x00}, // 0xe3 + {0x00,0x32,0x49,0x4a,0x31,0x00}, // 0xe4 + {0x00,0x3a,0x45,0x46,0x39,0x00}, // 0xe5 + {0x00,0xfc,0x20,0x20,0x1c,0x00}, // 0xe6 + {0x00,0xfe,0xaa,0x28,0x10,0x00}, // 0xe7 + {0x00,0xff,0xa5,0x24,0x18,0x00}, // 0xe8 + {0x00,0x3c,0x40,0x41,0x3d,0x00}, // 0xe9 + {0x00,0x3c,0x41,0x41,0x3d,0x00}, // 0xea + {0x00,0x3d,0x41,0x40,0x3c,0x00}, // 0xeb + {0x00,0x9c,0xa0,0x61,0x3d,0x00}, // 0xec + {0x00,0x04,0x08,0x71,0x09,0x04}, // 0xed + {0x00,0x00,0x02,0x02,0x02,0x00}, // 0xee + {0x00,0x00,0x07,0x03,0x00,0x00}, // 0xef + {0x00,0x00,0x08,0x08,0x08,0x00}, // 0xf0 + {0x00,0x00,0x24,0x2e,0x24,0x00}, // 0xf1 + {0x00,0x24,0x24,0x24,0x24,0x24}, // 0xf2 + {0x05,0x17,0x0a,0x34,0x2a,0x78}, // 0xf3 + {0x00,0x06,0x09,0x7f,0x01,0x7f}, // 0xf4 + {0x00,0x22,0x4d,0x55,0x59,0x22}, // 0xf5 + {0x00,0x08,0x08,0x2a,0x08,0x08}, // 0xf6 + {0x00,0x00,0x08,0x18,0x18,0x00}, // 0xf7 + {0x00,0x06,0x09,0x09,0x06,0x00}, // 0xf8 + {0x00,0x00,0x08,0x00,0x08,0x00}, // 0xf9 + {0x00,0x00,0x08,0x00,0x00,0x00}, // 0xfa + {0x00,0x02,0x0f,0x00,0x00,0x00}, // 0xfb + {0x00,0x09,0x0f,0x05,0x00,0x00}, // 0xfc + {0x00,0x09,0x0d,0x0a,0x00,0x00}, // 0xfd + {0x00,0x3c,0x3c,0x3c,0x3c,0x00}, // 0xfe + {0x00,0x00,0x00,0x00,0x00,0x00} // 0xff +}; + +#endif diff --git a/include/lcd.h b/include/lcd.h new file mode 100644 index 0000000..d86f8f0 --- /dev/null +++ b/include/lcd.h @@ -0,0 +1,69 @@ +#ifndef _LCD_H_ +#define _LCD_H_ + +#define LCD_Chip_Select (PORTC &= ~(1< + +extern uint8_t lcd_framebuffer[8][128]; +extern uint8_t lcd_frameupdate; + +void LCD_Init (void); +void LCD_Clear (void); +void LCD_Update (void); +void LCD_DrawPixel (uint8_t x, uint8_t y, uint8_t mode); +void LCD_DrawLine (uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t mode); +void LCD_DrawCircle (uint8_t x0, uint8_t y0, uint8_t radius, uint8_t mode); +void LCD_PutChar (const char c); +void LCD_PutString (const char *s); +void LCD_PutString_P (PGM_P s); +void LCD_GotoXY (uint8_t x, uint8_t y); +void LCD_WipeLine (unsigned char line); +void LCD_SavePage (unsigned int page); +void LCD_LoadPage (unsigned int page); + +void Backlight_Off (void); +void Backlight_LED (uint8_t led_selector); +void Backlight_PWM (uint8_t pwm, uint8_t prescaler, uint8_t value); + +#endif diff --git a/include/spi.h b/include/spi.h new file mode 100644 index 0000000..907025e --- /dev/null +++ b/include/spi.h @@ -0,0 +1,16 @@ +#ifndef _SPI_H_ +#define _SPI_H_ + +void SPI_MasterInit (void); +void SPI_MasterTransfer (unsigned char c); +unsigned char SPI_MasterTransferRead (unsigned char c); + +/* Section only needed, when LCD is on USART1 in SPI Mode */ +#if BOARD_REVISION < 3 + +void SPI2_MasterInit (void); +unsigned char SPI2_MasterTransfer (unsigned char c); + +#endif + +#endif diff --git a/include/twi.h b/include/twi.h new file mode 100644 index 0000000..006952b --- /dev/null +++ b/include/twi.h @@ -0,0 +1,11 @@ +#ifndef _TWI_H_ +#define _TWI_H_ + +void TWI_Init (void); +int16_t TWI_Start (void); +int16_t TWI_Address_RW (uint8_t address); +int16_t TWI_Write (uint8_t data); +void TWI_Stop (void); +void LCD_BacklightLED (uint8_t led_selector); + +#endif diff --git a/include/uart.h b/include/uart.h new file mode 100644 index 0000000..9ee9298 --- /dev/null +++ b/include/uart.h @@ -0,0 +1,11 @@ +#ifndef _UART_H_ +#define _UART_H_ + +void UART_Init (void); +int8_t UART_PutChar (const uint8_t c); +int16_t UART_GetChar (void); +uint8_t UART_GetChar_Wait (void); +void UART_PutString (const char *s); +void UART_PutInteger (const int i); + +#endif diff --git a/src/dataflash.c b/src/dataflash.c new file mode 100644 index 0000000..a2510b3 --- /dev/null +++ b/src/dataflash.c @@ -0,0 +1,176 @@ +#include +#include + +#include "spi.h" +#include "dataflash.h" + +void +dataflash_opcode_and_address (unsigned char opcode, unsigned int page, unsigned int offset) +{ + SPI_MasterTransfer(opcode); + SPI_MasterTransfer((unsigned char)(page >> 7) & 0x1f); + SPI_MasterTransfer(((unsigned char)(offset >> 8) & 0x01) | ((unsigned char)(page) << 1)); + SPI_MasterTransfer((unsigned char)(offset)); +} + +void +dataflash_wait (void) +{ + DATAFLASH_Chip_Select; + SPI_MasterTransfer(DATAFLASH_STATUS_REGISTER_READ); + + while (!(SPI_MasterTransferRead(0x00) & 0x80)); + + DATAFLASH_Chip_Unselect; +} + +void +dataflash_init (void) +{ + // AT45DB081 doesn't actually need an intialization, + // only the ChipSelect should be configured as an output. + DDRB |= (1 << PB4); + DATAFLASH_Chip_Unselect; + SPI_MasterInit(); +} + +void +dataflash_buffer_to_page (unsigned int page, unsigned char buffer) +{ + dataflash_wait(); + DATAFLASH_Chip_Select; + + switch (buffer) + { + default: + dataflash_opcode_and_address + (DATAFLASH_BUFFER_1_TO_MAIN_MEMORY_PAGE_PROGRAM_WITH_BUILT_IN_ERASE, + page, 0x00); + break; + + case 2: + dataflash_opcode_and_address + (DATAFLASH_BUFFER_2_TO_MAIN_MEMORY_PAGE_PROGRAM_WITH_BUILT_IN_ERASE, + page, 0x00); + break; + } + DATAFLASH_Chip_Unselect; +} + +void +dataflash_page_to_buffer (unsigned int page, unsigned char buffer) +{ + dataflash_wait(); + DATAFLASH_Chip_Select; + + switch (buffer) + { + default: + dataflash_opcode_and_address + (DATAFLASH_MAIN_MEMORY_PAGE_TO_BUFFER_1_TRANSFER, + page, 0x00); + break; + + case 2: + dataflash_opcode_and_address + (DATAFLASH_MAIN_MEMORY_PAGE_TO_BUFFER_2_TRANSFER, + page, 0x00); + break; + } + DATAFLASH_Chip_Unselect; +} + +void +dataflash_buffer_read (unsigned char buffer, unsigned int offset, + unsigned int length, unsigned char *array) +{ + dataflash_wait(); + DATAFLASH_Chip_Select; + + switch (buffer) + { + default: + dataflash_opcode_and_address + (DATAFLASH_BUFFER_1_READ_LF, + 0x00, offset); + break; + + case 2: + dataflash_opcode_and_address + (DATAFLASH_BUFFER_2_READ_LF, + 0x00, offset); + break; + } + + offset = 0x00; + + while (length--) + { + array[offset++] = SPI_MasterTransferRead(0x00); + } + + DATAFLASH_Chip_Unselect; +} + +void +dataflash_buffer_write (unsigned char buffer, unsigned int offset, + unsigned int length, unsigned char *array) +{ + dataflash_wait(); + DATAFLASH_Chip_Select; + + switch (buffer) + { + default: + dataflash_opcode_and_address + (DATAFLASH_BUFFER_1_WRITE, + 0x00, offset); + break; + + case 2: + dataflash_opcode_and_address + (DATAFLASH_BUFFER_2_WRITE, + 0x00, offset); + break; + } + + offset = 0x00; + + while (length--) + { + SPI_MasterTransfer(array[offset++]); + } + + DATAFLASH_Chip_Unselect; +} + +void +dataflash_read (unsigned int page, unsigned int offset, + unsigned int length, unsigned char *array) +{ + dataflash_wait(); + DATAFLASH_Chip_Select; + + dataflash_opcode_and_address(DATAFLASH_CONTINUOUS_ARRAY_READ_LF, page, offset); + + offset = 0x00; + + while (length--) + { + array[offset++] = SPI_MasterTransferRead(0x00); + } + + DATAFLASH_Chip_Unselect; +} + +void +dataflash_chip_erase (void) +{ + dataflash_wait(); + DATAFLASH_Chip_Select; + SPI_MasterTransfer(DATAFLASH_CHIP_ERASE_1); + SPI_MasterTransfer(DATAFLASH_CHIP_ERASE_2); + SPI_MasterTransfer(DATAFLASH_CHIP_ERASE_3); + SPI_MasterTransfer(DATAFLASH_CHIP_ERASE_4); + DATAFLASH_Chip_Unselect; +} diff --git a/src/fifo.c b/src/fifo.c new file mode 100644 index 0000000..1095447 --- /dev/null +++ b/src/fifo.c @@ -0,0 +1,78 @@ +#include +#include "fifo.h" + +static uint8_t _fifo_get (fifo_t* f); + +void fifo_init (fifo_t* f, uint8_t* buffer, const uint8_t size) +{ + f->count = 0; + f->pread = f->pwrite = buffer; + f->read2end = f->write2end = f->size = size; +} + +uint8_t fifo_get_wait (fifo_t* f) +{ + while (!f->count); + + return _fifo_get(f); +} + +int16_t fifo_get_nowait (fifo_t* f) +{ + if (!f->count) + return -1; + + return (int)_fifo_get(f); +} + +uint8_t fifo_put (fifo_t* f, const uint8_t data) +{ + if (f->count >= f->size) + return 0; + + uint8_t* pwrite = f->pwrite; + + *(pwrite++) = data; + + uint8_t write2end = f->write2end; + + if (--write2end == 0) + { + write2end = f->size; + pwrite -= write2end; + } + + f->write2end = write2end; + f->pwrite = pwrite; + + uint8_t sreg = SREG; + cli(); + f->count++; + SREG = sreg; + + return 1; +} + +static uint8_t +_fifo_get (fifo_t* f) +{ + uint8_t* pread = f->pread; + uint8_t data = *(pread++); + uint8_t read2end = f->read2end; + + if (--read2end == 0) + { + read2end = f->size; + pread -= read2end; + } + + f->pread = pread; + f->read2end = read2end; + + uint8_t sreg = SREG; + cli(); + f->count--; + SREG = sreg; + + return data; +} diff --git a/src/lcd.c b/src/lcd.c new file mode 100644 index 0000000..ed14ac5 --- /dev/null +++ b/src/lcd.c @@ -0,0 +1,364 @@ +#include +#include +#include +#include +#include + +#include "spi.h" +#include "font.h" +#include "lcd.h" +#include "twi.h" +#include "dataflash.h" + +uint8_t lcd_framebuffer[8][128]; +uint8_t lcd_frameupdate = 0; +uint8_t lcd_textx = 0; +uint8_t lcd_texty = 0; + +void +LCD_Send (uint8_t data) +{ + SPI_MasterTransfer(data); +} + +void +LCD_Init (void) +{ + SPI_MasterInit(); + + /* Set Register Select and Chip Select as Output */ + DDRC |= (1< dy ? dx : -dy) / 2; + int8_t e2; + + for (;;) + { + LCD_DrawPixel(x0, y0, mode); + + if (x0 == x1 && y0 == y1) + break; + + e2 = err; + + if (e2 > -dx) + { + err -= dy; + x0 += sx; + } + + if (e2 < dy) + { + err += dx; + y0 += sy; + } + } +} + +void +LCD_DrawCircle (uint8_t x0, uint8_t y0, uint8_t radius, uint8_t mode) +{ + // look here: http://de.wikipedia.org/wiki/Bresenham-Algorithmus + int8_t f = 1 - radius; + int8_t ddF_x = 0; + int8_t ddF_y = -2 * radius; + int8_t x = 0; + int8_t y = radius; + + LCD_DrawPixel(x0, y0 + radius, mode); + LCD_DrawPixel(x0, y0 - radius, mode); + LCD_DrawPixel(x0 + radius, y0, mode); + LCD_DrawPixel(x0 - radius, y0, mode); + + while (x < y) + { + if (f >= 0) + { + 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); + } +} + +void +LCD_PutChar (const char c) +{ + // basic support for cr und new line + switch (c) + { + case '\r': + // Carriage Return + lcd_textx = 0; + break; + + case '\n': + // New Line + if (lcd_texty < 7) + lcd_texty++; + break; + + default: + 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_frameupdate |= (1 << lcd_texty); + + if (lcd_textx < 20) + lcd_textx++; + break; + } +} + +void +LCD_PutString (const char *s) +{ + // no empty strings allowed! + if (*s) + { + do + { + LCD_PutChar(*s); + } + while (*(++s)); + } +} + +void +LCD_PutString_P (PGM_P s) +{ + while(1) + { + unsigned char c = pgm_read_byte (s); + s++; + + if (c == '\0') + break; + + LCD_PutChar(c); + } +} + +void +LCD_GotoXY (uint8_t x, uint8_t y) +{ + lcd_textx = x; + lcd_texty = y; +} + +void +LCD_WipeLine (unsigned char line) +{ + unsigned char x; + + for (x = 0; x < 128; x++) + lcd_framebuffer[line][x] = 0x00; + + lcd_frameupdate |= (1 << line); +} + +void +Backlight_Off (void) +{ + TWI_Start(); + TWI_Address_RW(0xc4); + TWI_Write(0x11); + TWI_Write(0x00); + TWI_Write(0x00); + TWI_Write(0x00); + TWI_Write(0x00); + TWI_Write(0x00); + TWI_Stop(); +} + +void +Backlight_LED (uint8_t led_selector) +{ + TWI_Start(); + TWI_Address_RW(0xc4); + TWI_Write(0x15); + TWI_Write(led_selector); + TWI_Stop(); +} + +void +Backlight_PWM (uint8_t pwm, uint8_t prescaler, uint8_t value) +{ + TWI_Start(); + TWI_Address_RW(0xc4); + + if (pwm) + TWI_Write(0x13); + else + TWI_Write(0x11); + + TWI_Write(prescaler); + TWI_Write(value); + TWI_Stop(); +} + +void +LCD_SavePage (unsigned int page) +{ + // transfer framebuffer to dataflash using buffer 2 + unsigned char line = 0; + + for (line = 0; line < 8; line++) + { + dataflash_buffer_write(2, 0, 128, lcd_framebuffer[line]); + dataflash_buffer_to_page(page + line, 2); + } +} + +void +LCD_LoadPage (unsigned int page) +{ + // transfer dataflash page to framebuffer + unsigned char line = 0; + + for (line = 0; line < 8; line++) + { + dataflash_read(page + line, 0, 128, lcd_framebuffer[line]); + } + + // mark all lines to be updated + lcd_frameupdate = 0xff; + LCD_Update(); +} diff --git a/src/spi.c b/src/spi.c new file mode 100644 index 0000000..37f442a --- /dev/null +++ b/src/spi.c @@ -0,0 +1,50 @@ +#include +#include + +#include "spi.h" + +// Prevent Double Initialization +unsigned short SPI_flag = 0; + +void +SPI_MasterInit (void) +{ + /* Check if already initialized */ + if (!(SPI_flag & 1)) + { + /* Set MOSI and SCK output */ + DDRB |= (1< +#include +#include + +#include "twi.h" + +volatile uint8_t twi_timeout = 0x00; + +void +TWI_Init (void) +{ + // Port Setup + DDRC &= ~((1 << PC0)|(1 << PC1)); + PORTC |= (1 << PC0)|(1 << PC1); + + // Setup TWI Speed to 400kHZ (TWPS = 1) + TWBR = 3; + + // Using TIMER2 to detect timeout + TCCR2B = (7 << CS20); + TIMSK2 = (1 << OCIE2A); + + OCR2A = 125; + + // Interrupts REQUIRED! + sei(); +} + +int16_t +TWI_Start (void) +{ + twi_timeout = 10; + + TWCR = (1 << TWINT)|(1 << TWSTA)|(1 << TWEN); + while ((twi_timeout) && (!(TWCR & (1 << TWINT)))); + + if (twi_timeout) + return (int16_t) (TWSR & 0xf8); + else + return -1; +} + +int16_t +TWI_Address_RW (uint8_t address) +{ + twi_timeout = 10; + + TWDR = address; + TWCR = (1 << TWINT)|(1 << TWEN); + while ((twi_timeout) && (!(TWCR & (1 << TWINT)))); + + if (twi_timeout) + return (int16_t) (TWSR & 0xf8); + else + return -1; +} + +int16_t +TWI_Write (uint8_t data) +{ + twi_timeout = 10; + + TWDR = data; + TWCR = (1 << TWINT)|(1 << TWEN); + while ((twi_timeout) && (!(TWCR & (1 << TWINT)))); + + if (twi_timeout) + return (int16_t) (TWSR & 0xf8); + else + return -1; +} + +void +TWI_Stop (void) +{ + twi_timeout = 10; + + TWCR = (1 << TWINT)|(1 << TWEN)|(1 << TWSTO); +} + +// ISR will be called every 8ms to decrease twi_timeout if > 0 +ISR (TIMER2_COMPA_vect) +{ + OCR2A += 125; + + if (twi_timeout) + twi_timeout--; +} diff --git a/src/uart.c b/src/uart.c new file mode 100644 index 0000000..00b903f --- /dev/null +++ b/src/uart.c @@ -0,0 +1,105 @@ +#include +#include +#include +#include +#include + +#include "uart.h" +#include "fifo.h" + +#define UART_BUFSIZE_IN 16 +#define UART_BUFSIZE_OUT 64 + +uint8_t uart_inbuf[UART_BUFSIZE_IN]; +uint8_t uart_outbuf[UART_BUFSIZE_OUT]; + +fifo_t uart_infifo; +fifo_t uart_outfifo; + +void +UART_Init (void) +{ + // Save Status Register and disable Interrupts + uint8_t sreg = SREG; + cli(); + + // Set Baudrate according to datasheet (16MHz -> 9600 Baud -> 103) + UBRR0 = 103; + + // Enable RX, TX and RX Complete Interrupt + UCSR0B = (1 << RXEN0)|(1 << TXEN0)|(1 << RXCIE0); + + // Reset Complete-Flags + UCSR0A = (1 << RXC0)|(1 << TXC0); + + // Reset Status Register + SREG = sreg; + + // Initialize FIFO Buffers + fifo_init(&uart_infifo, uart_inbuf, UART_BUFSIZE_IN); + fifo_init(&uart_outfifo, uart_outbuf, UART_BUFSIZE_OUT); +} + +int8_t +UART_PutChar (const uint8_t c) +{ + + + + // Put char into TX Buffer + int8_t ret = fifo_put(&uart_outfifo, c); + + // Enable DRE Interrupt + UCSR0B |= (1 << UDRIE0); + + return ret; +} + +// Receive Interrupt Routine +ISR(USART0_RX_vect) +{ + fifo_put(&uart_infifo, UDR0); +} + +// Data Register Empty Interrupt +ISR(USART0_UDRE_vect) +{ + if (uart_outfifo.count > 0) + UDR0 = fifo_get_nowait(&uart_outfifo); + else + UCSR0B &= ~(1 << UDRIE0); +} + +int16_t +UART_GetChar (void) +{ + return fifo_get_nowait(&uart_infifo); +} + +uint8_t +UART_GetChar_Wait (void) +{ + return fifo_get_wait(&uart_infifo); +} + +void +UART_PutString (const char *s) +{ + do + { + UART_PutChar(*s); + } + while (*(s++)); +} + +void +UART_PutInteger (const int i) +{ + // Buffer for Output + char buffer[10]; + + // Convert Integer to ASCII, Base 10 + itoa(i, buffer, 10); + + UART_PutString(buffer); +}