From 6afd060f985733ea7a238771a292cd39a2c5b953 Mon Sep 17 00:00:00 2001 From: eddyem Date: Wed, 20 Jan 2016 16:58:43 +0300 Subject: [PATCH] add LCD 5110 --- uart_lcd5110/Makefile | 37 +++ uart_lcd5110/font.c | 260 +++++++++++++++ uart_lcd5110/font.h | 31 ++ uart_lcd5110/interrupts.c | 171 ++++++++++ uart_lcd5110/interrupts.h | 144 ++++++++ uart_lcd5110/main.c | 159 +++++++++ uart_lcd5110/pcd8544.c | 237 ++++++++++++++ uart_lcd5110/pcd8544.h | 122 +++++++ uart_lcd5110/ports_definition.h | 65 ++++ uart_lcd5110/spi.c | 116 +++++++ uart_lcd5110/spi.h | 34 ++ uart_lcd5110/stm8l.h | 561 ++++++++++++++++++++++++++++++++ uart_lcd5110/uart.c | 168 ++++++++++ uart_lcd5110/uart.h | 45 +++ uart_lcd5110/uartlcd.ihx | 188 +++++++++++ 15 files changed, 2338 insertions(+) create mode 100644 uart_lcd5110/Makefile create mode 100644 uart_lcd5110/font.c create mode 100644 uart_lcd5110/font.h create mode 100644 uart_lcd5110/interrupts.c create mode 100644 uart_lcd5110/interrupts.h create mode 100644 uart_lcd5110/main.c create mode 100644 uart_lcd5110/pcd8544.c create mode 100644 uart_lcd5110/pcd8544.h create mode 100644 uart_lcd5110/ports_definition.h create mode 100644 uart_lcd5110/spi.c create mode 100644 uart_lcd5110/spi.h create mode 100644 uart_lcd5110/stm8l.h create mode 100644 uart_lcd5110/uart.c create mode 100644 uart_lcd5110/uart.h create mode 100644 uart_lcd5110/uartlcd.ihx diff --git a/uart_lcd5110/Makefile b/uart_lcd5110/Makefile new file mode 100644 index 0000000..6778445 --- /dev/null +++ b/uart_lcd5110/Makefile @@ -0,0 +1,37 @@ +NAME=uartlcd +SDCC=sdcc + +CCFLAGS=-DSTM8S105 -I../ -I/usr/share/sdcc/include -mstm8 --out-fmt-ihx +LDFLAGS= -mstm8 --out-fmt-ihx -lstm8 +FLASHFLAGS=-cstlinkv2 -pstm8s105?4 + +SRC=$(wildcard *.c) + +OBJ=$(SRC:%.c=%.rel) +TRASH=$(OBJ) $(SRC:%.c=%.rst) $(SRC:%.c=%.asm) $(SRC:%.c=%.lst) +TRASH+=$(SRC:%.c=%.sym) $(NAME).lk $(NAME).map +INDEPENDENT_HEADERS=../stm8l.h ports_definition.h Makefile + +all: $(NAME).ihx + +#$(SRC) : %.c : %.h $(INDEPENDENT_HEADERS) +# @touch $@ +# +#%.h: ; + +clean: + rm -f $(TRASH) + +load: $(NAME).ihx + stm8flash $(FLASHFLAGS) -w $(NAME).ihx + +%.rel: %.c + $(SDCC) $(CCFLAGS) -c $< + +$(NAME).ihx: $(OBJ) + $(SDCC) $(LDFLAGS) $(OBJ) -o $(NAME).ihx + +bin: $(NAME).ihx + hex2bin $(NAME).ihx + +.PHONY: all diff --git a/uart_lcd5110/font.c b/uart_lcd5110/font.c new file mode 100644 index 0000000..0a7346e --- /dev/null +++ b/uart_lcd5110/font.c @@ -0,0 +1,260 @@ +/* + * font.c - russian font + * + * Copyright 2015 Edward V. Emelianoff + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include "font.h" + +const U8 rusfont [] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// 32 [0x20] - + 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00,// 33 [0x21] - ! + 0x00, 0x07, 0x00, 0x07, 0x00, 0x00,// 34 [0x22] - " + 0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00,// 35 [0x23] - # + 0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00,// 36 [0x24] - $ + 0x23, 0x13, 0x08, 0x64, 0x62, 0x00,// 37 [0x25] - % + 0x36, 0x49, 0x55, 0x22, 0x50, 0x00,// 38 [0x26] - & + 0x00, 0x05, 0x03, 0x00, 0x00, 0x00,// 39 [0x27] - ' + 0x00, 0x1C, 0x22, 0x41, 0x00, 0x00,// 40 [0x28] - ( + 0x00, 0x41, 0x22, 0x1C, 0x00, 0x00,// 41 [0x29] - ) + 0x08, 0x2A, 0x1C, 0x2A, 0x08, 0x00,// 42 [0x2a] - * + 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00,// 43 [0x2b] - + + 0x00, 0x50, 0x30, 0x00, 0x00, 0x00,// 44 [0x2c] - , + 0x08, 0x08, 0x08, 0x08, 0x08, 0x00,// 45 [0x2d] - - + 0x00, 0x60, 0x60, 0x00, 0x00, 0x00,// 46 [0x2e] - . + 0x20, 0x10, 0x08, 0x04, 0x02, 0x00,// 47 [0x2f] - / + 0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00,// 48 [0x30] - 0 + 0x00, 0x42, 0x7F, 0x40, 0x00, 0x00,// 49 [0x31] - 1 + 0x42, 0x61, 0x51, 0x49, 0x46, 0x00,// 50 [0x32] - 2 + 0x21, 0x41, 0x45, 0x4B, 0x31, 0x00,// 51 [0x33] - 3 + 0x18, 0x14, 0x12, 0x7F, 0x10, 0x00,// 52 [0x34] - 4 + 0x27, 0x45, 0x45, 0x45, 0x39, 0x00,// 53 [0x35] - 5 + 0x3C, 0x4A, 0x49, 0x49, 0x30, 0x00,// 54 [0x36] - 6 + 0x01, 0x71, 0x09, 0x05, 0x03, 0x00,// 55 [0x37] - 7 + 0x36, 0x49, 0x49, 0x49, 0x36, 0x00,// 56 [0x38] - 8 + 0x06, 0x49, 0x49, 0x29, 0x1E, 0x00,// 57 [0x39] - 9 + 0x00, 0x36, 0x36, 0x00, 0x00, 0x00,// 58 [0x3a] - : + 0x00, 0x56, 0x36, 0x00, 0x00, 0x00,// 59 [0x3b] - ; + 0x00, 0x08, 0x14, 0x22, 0x41, 0x00,// 60 [0x3c] - < + 0x14, 0x14, 0x14, 0x14, 0x14, 0x00,// 61 [0x3d] - = + 0x41, 0x22, 0x14, 0x08, 0x00, 0x00,// 62 [0x3e] - > + 0x02, 0x01, 0x51, 0x09, 0x06, 0x00,// 63 [0x3f] - ? + 0x32, 0x49, 0x79, 0x41, 0x3E, 0x00,// 64 [0x40] - @ + 0x7E, 0x11, 0x11, 0x11, 0x7E, 0x00,// 65 [0x41] - A + 0x7F, 0x49, 0x49, 0x49, 0x36, 0x00,// 66 [0x42] - B + 0x3E, 0x41, 0x41, 0x41, 0x22, 0x00,// 67 [0x43] - C + 0x7F, 0x41, 0x41, 0x22, 0x1C, 0x00,// 68 [0x44] - D + 0x7F, 0x49, 0x49, 0x49, 0x41, 0x00,// 69 [0x45] - E + 0x7F, 0x09, 0x09, 0x01, 0x01, 0x00,// 70 [0x46] - F + 0x3E, 0x41, 0x41, 0x51, 0x32, 0x00,// 71 [0x47] - G + 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00,// 72 [0x48] - H + 0x00, 0x41, 0x7F, 0x41, 0x00, 0x00,// 73 [0x49] - I + 0x20, 0x40, 0x41, 0x3F, 0x01, 0x00,// 74 [0x4a] - J + 0x7F, 0x08, 0x14, 0x22, 0x41, 0x00,// 75 [0x4b] - K + 0x7F, 0x40, 0x40, 0x40, 0x40, 0x00,// 76 [0x4c] - L + 0x7F, 0x02, 0x04, 0x02, 0x7F, 0x00,// 77 [0x4d] - M + 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00,// 78 [0x4e] - N + 0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00,// 79 [0x4f] - O + 0x7F, 0x09, 0x09, 0x09, 0x06, 0x00,// 80 [0x50] - P + 0x3e, 0x41, 0x51, 0x21, 0xde, 0x00,// 81 [0x51] - Q + 0x7F, 0x09, 0x19, 0x29, 0x46, 0x00,// 82 [0x52] - R + 0x46, 0x49, 0x49, 0x49, 0x31, 0x00,// 83 [0x53] - S + 0x01, 0x01, 0x7F, 0x01, 0x01, 0x00,// 84 [0x54] - T + 0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00,// 85 [0x55] - U + 0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00,// 86 [0x56] - V + 0x7F, 0x20, 0x18, 0x20, 0x7F, 0x00,// 87 [0x57] - W + 0x63, 0x14, 0x08, 0x14, 0x63, 0x00,// 88 [0x58] - X + 0x03, 0x04, 0x78, 0x04, 0x03, 0x00,// 89 [0x59] - Y + 0x61, 0x51, 0x49, 0x45, 0x43, 0x00,// 90 [0x5a] - Z + 0x00, 0x00, 0x7F, 0x41, 0x41, 0x00,// 91 [0x5b] - [ + 0x02, 0x04, 0x08, 0x10, 0x20, 0x00,// 92 [0x5c] - "\" + 0x41, 0x41, 0x7F, 0x00, 0x00, 0x00,// 93 [0x5d] - ] + 0x04, 0x02, 0x01, 0x02, 0x04, 0x00,// 94 [0x5e] - ^ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00,// 95 [0x5f] - _ + 0x00, 0x01, 0x02, 0x04, 0x00, 0x00,// 96 [0x60] - ` + 0x20, 0x54, 0x54, 0x54, 0x78, 0x00,// 97 [0x61] - a + 0x7F, 0x48, 0x44, 0x44, 0x38, 0x00,// 98 [0x62] - b + 0x38, 0x44, 0x44, 0x44, 0x20, 0x00,// 99 [0x63] - c + 0x38, 0x44, 0x44, 0x48, 0x7F, 0x00,//100 [0x64] - d + 0x38, 0x54, 0x54, 0x54, 0x18, 0x00,//101 [0x65] - e + 0x00, 0x08, 0xfe, 0x09, 0x02, 0x00,//102 [0x66] - f + 0x18, 0xa4, 0xa4, 0x94, 0x78, 0x00,//103 [0x67] - g + 0x7F, 0x08, 0x04, 0x04, 0x78, 0x00,//104 [0x68] - h + 0x00, 0x44, 0x7D, 0x40, 0x00, 0x00,//105 [0x69] - i + 0x40, 0x80, 0x84, 0x7d, 0x00, 0x00,//106 [0x6a] - j + 0x00, 0x7F, 0x10, 0x28, 0x44, 0x00,//107 [0x6b] - k + 0x00, 0x41, 0x7F, 0x40, 0x00, 0x00,//108 [0x6c] - l + 0x7C, 0x04, 0x18, 0x04, 0x78, 0x00,//109 [0x6d] - m + 0x7C, 0x08, 0x04, 0x04, 0x78, 0x00,//110 [0x6e] - n + 0x38, 0x44, 0x44, 0x44, 0x38, 0x00,//111 [0x6f] - o + 0xfc, 0x28, 0x24, 0x24, 0x18, 0x00,//112 [0x70] - p + 0x18, 0x24, 0x24, 0x28, 0xfc, 0x00,//113 [0x71] - q + 0x7C, 0x08, 0x04, 0x04, 0x08, 0x00,//114 [0x72] - r + 0x48, 0x54, 0x54, 0x54, 0x20, 0x00,//115 [0x73] - s + 0x04, 0x3F, 0x44, 0x40, 0x20, 0x00,//116 [0x74] - t + 0x3C, 0x40, 0x40, 0x20, 0x7C, 0x00,//117 [0x75] - u + 0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00,//118 [0x76] - v + 0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00,//119 [0x77] - w + 0x44, 0x28, 0x10, 0x28, 0x44, 0x00,//120 [0x78] - x + 0x0C, 0x50, 0x50, 0x50, 0x3C, 0x00,//121 [0x79] - y + 0x44, 0x64, 0x54, 0x4C, 0x44, 0x00,//122 [0x7a] - z + 0x00, 0x08, 0x36, 0x41, 0x00, 0x00,//123 [0x7b] - { + 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00,//124 [0x7c] - | + 0x00, 0x41, 0x36, 0x08, 0x00, 0x00,//125 [0x7d] - } + 0x08, 0x04, 0x08, 0x10, 0x08, 0x00,//126 [0x7e] - ~ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,//127 [0x7f] - + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,//128 [0x80] - + 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,//129 [0x81] - + 0x00, 0x00, 0xf8, 0x08, 0x08, 0x08,//130 [0x82] - + 0x08, 0x08, 0xf8, 0x00, 0x00, 0x00,//131 [0x83] - + 0x00, 0x00, 0x0f, 0x08, 0x08, 0x08,//132 [0x84] - + 0x08, 0x08, 0x0f, 0x00, 0x00, 0x00,//133 [0x85] - + 0x00, 0x00, 0xff, 0x08, 0x08, 0x08,//134 [0x86] - + 0x08, 0x08, 0xff, 0x00, 0x00, 0x00,//135 [0x87] - + 0x08, 0x08, 0xf8, 0x08, 0x08, 0x08,//136 [0x88] - + 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08,//137 [0x89] - + 0x08, 0x08, 0xff, 0x08, 0x08, 0x08,//138 [0x8a] - + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,//139 [0x8b] - + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,//140 [0x8c] - + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,//141 [0x8d] - + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,//142 [0x8e] - + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,//143 [0x8f] - + 0x00, 0xaa, 0x00, 0x55, 0x00, 0xaa,//144 [0x90] - + 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,//145 [0x91] - + 0x55, 0xff, 0x55, 0xff, 0x55, 0xff,//146 [0x92] - + 0x00, 0x00, 0xfc, 0x02, 0x04, 0x00,//147 [0x93] - + 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,//148 [0x94] - + 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,//149 [0x95] - + 0x08, 0x38, 0x40, 0x30, 0x0e, 0x01,//150 [0x96] - + 0x24, 0x12, 0x24, 0x48, 0x24, 0x00,//151 [0x97] - + 0x00, 0x44, 0x4a, 0x51, 0x00, 0x00,//152 [0x98] - + 0x00, 0x51, 0x4a, 0x44, 0x00, 0x00,//153 [0x99] - + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,//154 [0x9a] - + 0x20, 0x40, 0x3f, 0x00, 0x00, 0x00,//155 [0x9b] - + 0x00, 0x06, 0x09, 0x06, 0x00, 0x00,//156 [0x9c] - + 0x00, 0x0d, 0x0b, 0x00, 0x00, 0x00,//157 [0x9d] - + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,//158 [0x9e] - + 0x08, 0x08, 0x2a, 0x08, 0x08, 0x00,//159 [0x9f] - + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,//160 [0xa0] - + 0x00, 0xff, 0x00, 0xff, 0x00, 0x00,//161 [0xa1] - + 0x00, 0x00, 0xfc, 0x14, 0x14, 0x14,//162 [0xa2] - + 0x38, 0x55, 0x54, 0x55, 0x18, 0x00,//163 [0xa3] - + 0x00, 0xf8, 0x08, 0xf8, 0x08, 0x08,//164 [0xa4] - + 0x00, 0xfc, 0x04, 0xf4, 0x14, 0x14,//165 [0xa5] - + 0x14, 0x14, 0xfc, 0x00, 0x00, 0x00,//166 [0xa6] - + 0x08, 0xf8, 0x08, 0xf8, 0x00, 0x00,//167 [0xa7] - + 0x14, 0xf4, 0x04, 0xfc, 0x00, 0x00,//168 [0xa8] - + 0x00, 0x00, 0x1f, 0x14, 0x14, 0x14,//169 [0xa9] - + 0x00, 0x0f, 0x08, 0x0f, 0x08, 0x08,//170 [0xaa] - + 0x00, 0x1f, 0x10, 0x17, 0x14, 0x14,//171 [0xab] - + 0x14, 0x14, 0x1f, 0x00, 0x00, 0x00,//172 [0xac] - + 0x08, 0x0f, 0x08, 0x0f, 0x00, 0x00,//173 [0xad] - + 0x14, 0x17, 0x10, 0x1f, 0x00, 0x00,//174 [0xae] - + 0x00, 0x00, 0xff, 0x14, 0x14, 0x14,//175 [0xaf] - + 0x00, 0xff, 0x00, 0xff, 0x08, 0x08,//176 [0xb0] - + 0x00, 0xff, 0x00, 0xf7, 0x14, 0x14,//177 [0xb1] - + 0x14, 0x14, 0xff, 0x00, 0x00, 0x00,//178 [0xb2] - + 0x7e, 0x4b, 0x4a, 0x43, 0x42, 0x00,//179 [0xb3] - + 0x08, 0xff, 0x00, 0xff, 0x00, 0x00,//180 [0xb4] - + 0x14, 0xf7, 0x00, 0xff, 0x00, 0x00,//181 [0xb5] - + 0x14, 0x14, 0xf4, 0x14, 0x14, 0x14,//182 [0xb6] - + 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x08,//183 [0xb7] - + 0x14, 0xf4, 0x04, 0xf4, 0x14, 0x14,//184 [0xb8] - + 0x14, 0x14, 0x17, 0x14, 0x14, 0x14,//185 [0xb9] - + 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x08,//186 [0xba] - + 0x14, 0x17, 0x14, 0x17, 0x14, 0x14,//187 [0xbb] - + 0x14, 0x14, 0xff, 0x14, 0x14, 0x14,//188 [0xbc] - + 0x08, 0xff, 0x08, 0xff, 0x08, 0x08,//189 [0xbd] - + 0x14, 0xf7, 0x00, 0xf7, 0x14, 0x14,//190 [0xbe] - + 0x3e, 0x5d, 0x55, 0x41, 0x3e, 0x00,//191 [0xbf] - + 0x7c, 0x10, 0x38, 0x44, 0x38, 0x00,//192 [0xc0] - + 0x20, 0x54, 0x54, 0x54, 0x78, 0x00,//193 [0xc1] - + 0x3c, 0x4a, 0x4a, 0x49, 0x31, 0x00,//194 [0xc2] - + 0x7c, 0x40, 0x40, 0x40, 0xfc, 0x00,//195 [0xc3] - + 0xe0, 0x54, 0x4c, 0x44, 0xfc, 0x00,//196 [0xc4] - + 0x38, 0x54, 0x54, 0x54, 0x18, 0x00,//197 [0xc5] - + 0x30, 0x48, 0xfc, 0x48, 0x30, 0x00,//198 [0xc6] - + 0x7c, 0x04, 0x04, 0x04, 0x0c, 0x00,//199 [0xc7] - + 0x44, 0x28, 0x10, 0x28, 0x44, 0x00,//200 [0xc8] - + 0x7c, 0x20, 0x10, 0x08, 0x7c, 0x00,//201 [0xc9] - + 0x7c, 0x41, 0x22, 0x11, 0x7c, 0x00,//202 [0xca] - + 0x7c, 0x10, 0x28, 0x44, 0x00, 0x00,//203 [0xcb] - + 0x20, 0x44, 0x3c, 0x04, 0x7c, 0x00,//204 [0xcc] - + 0x7c, 0x08, 0x10, 0x08, 0x7c, 0x00,//205 [0xcd] - + 0x7c, 0x10, 0x10, 0x10, 0x7c, 0x00,//206 [0xce] - + 0x38, 0x44, 0x44, 0x44, 0x38, 0x00,//207 [0xcf] - + 0x7c, 0x04, 0x04, 0x04, 0x7c, 0x00,//208 [0xd0] - + 0x08, 0x54, 0x34, 0x14, 0x7c, 0x00,//209 [0xd1] - + 0x7C, 0x14, 0x14, 0x14, 0x08, 0x00,//210 [0xd2] - + 0x38, 0x44, 0x44, 0x44, 0x20, 0x00,//211 [0xd3] - + 0x04, 0x04, 0x7c, 0x04, 0x04, 0x00,//212 [0xd4] - + 0x0C, 0x50, 0x50, 0x50, 0x3C, 0x00,//213 [0xd5] - + 0x6c, 0x10, 0x7c, 0x10, 0x6c, 0x00,//214 [0xd6] - + 0x7c, 0x54, 0x54, 0x28, 0x00, 0x00,//215 [0xd7] - + 0x7c, 0x50, 0x50, 0x20, 0x00, 0x00,//216 [0xd8] - + 0x7c, 0x50, 0x50, 0x20, 0x7c, 0x00,//217 [0xd9] - + 0x44, 0x44, 0x54, 0x54, 0x28, 0x00,//218 [0xda] - + 0x7c, 0x40, 0x7c, 0x40, 0x7c, 0x00,//219 [0xdb] - + 0x28, 0x44, 0x54, 0x54, 0x38, 0x00,//220 [0xdc] - + 0x7c, 0x40, 0x7c, 0x40, 0xfc, 0x00,//221 [0xdd] - + 0x0c, 0x10, 0x10, 0x10, 0x7c, 0x00,//222 [0xde] - + 0x04, 0x7c, 0x50, 0x50, 0x20, 0x00,//223 [0xdf] - + 0x7f, 0x08, 0x3e, 0x41, 0x3e, 0x00,//224 [0xe0] - + 0x7e, 0x11, 0x11, 0x11, 0x7e, 0x00,//225 [0xe1] - + 0x7f, 0x49, 0x49, 0x49, 0x33, 0x00,//226 [0xe2] - + 0x7f, 0x40, 0x40, 0x40, 0xff, 0x00,//227 [0xe3] - + 0xe0, 0x51, 0x4f, 0x41, 0xff, 0x00,//228 [0xe4] - + 0x7f, 0x49, 0x49, 0x49, 0x41, 0x00,//229 [0xe5] - + 0x1c, 0x22, 0x7f, 0x22, 0x1c, 0x00,//230 [0xe6] - + 0x7f, 0x01, 0x01, 0x01, 0x03, 0x00,//231 [0xe7] - + 0x63, 0x14, 0x08, 0x14, 0x63, 0x00,//232 [0xe8] - + 0x7f, 0x10, 0x08, 0x04, 0x7f, 0x00,//233 [0xe9] - + 0x7c, 0x21, 0x12, 0x09, 0x7c, 0x00,//234 [0xea] - + 0x7f, 0x08, 0x14, 0x22, 0x41, 0x00,//235 [0xeb] - + 0x20, 0x41, 0x3f, 0x01, 0x7f, 0x00,//236 [0xec] - + 0x7f, 0x02, 0x0c, 0x02, 0x7f, 0x00,//237 [0xed] - + 0x7f, 0x08, 0x08, 0x08, 0x7f, 0x00,//238 [0xee] - + 0x3e, 0x41, 0x41, 0x41, 0x3e, 0x00,//239 [0xef] - + 0x7f, 0x01, 0x01, 0x01, 0x7f, 0x00,//240 [0xf0] - + 0x46, 0x29, 0x19, 0x09, 0x7f, 0x00,//241 [0xf1] - + 0x7f, 0x09, 0x09, 0x09, 0x06, 0x00,//242 [0xf2] - + 0x3e, 0x41, 0x41, 0x41, 0x22, 0x00,//243 [0xf3] - + 0x01, 0x01, 0x7f, 0x01, 0x01, 0x00,//244 [0xf4] - + 0x47, 0x28, 0x10, 0x08, 0x07, 0x00,//245 [0xf5] - + 0x77, 0x08, 0x7f, 0x08, 0x77, 0x00,//246 [0xf6] - + 0x7f, 0x49, 0x49, 0x49, 0x36, 0x00,//247 [0xf7] - + 0x22, 0x41, 0x49, 0x49, 0x3e, 0x00,//248 [0xf8] - + 0x7f, 0x48, 0x30, 0x00, 0x7f, 0x00,//249 [0xf9] - + 0x41, 0x49, 0x49, 0x49, 0x36, 0x00,//250 [0xfa] - + 0x7f, 0x40, 0x7f, 0x40, 0x7f, 0x00,//251 [0xfb] - + 0x00, 0x7f, 0x48, 0x48, 0x30, 0x00,//252 [0xfc] - + 0x7f, 0x40, 0x7f, 0x40, 0xff, 0x00,//253 [0xfd] - + 0x07, 0x08, 0x08, 0x08, 0x7f, 0x00,//254 [0xfe] - + 0x01, 0x7f, 0x48, 0x48, 0x30, 0x00,//255 [0xff] - +}; + +/** + * Return letter array + */ +U8 *letter(U8 koi8){ + U16 idx; + if(koi8 < 32) koi8 = 32; + idx = (koi8 - 32) * LTR_WIDTH; + return &rusfont[idx]; +} + diff --git a/uart_lcd5110/font.h b/uart_lcd5110/font.h new file mode 100644 index 0000000..f2c7605 --- /dev/null +++ b/uart_lcd5110/font.h @@ -0,0 +1,31 @@ +/* + * font.h + * + * Copyright 2015 Edward V. Emelianoff + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#pragma once +#ifndef __FONT_H__ +#define __FONT_H__ +#include + +#include "stm8l.h" +#define LTR_WIDTH (6) + +U8 *letter(U8 koi8); + +#endif // __FONT_H__ diff --git a/uart_lcd5110/interrupts.c b/uart_lcd5110/interrupts.c new file mode 100644 index 0000000..4fb11be --- /dev/null +++ b/uart_lcd5110/interrupts.c @@ -0,0 +1,171 @@ +/* + * interrupts.c + * + * Copyright 2014 Edward V. Emelianoff + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include "ports_definition.h" +#include "uart.h" +#include "spi.h" + +// Top Level Interrupt +INTERRUPT_HANDLER(TLI_IRQHandler, 0){} + +// Auto Wake Up Interrupt +INTERRUPT_HANDLER(AWU_IRQHandler, 1){} + +// Clock Controller Interrupt +INTERRUPT_HANDLER(CLK_IRQHandler, 2){} + +// External Interrupt PORTA +INTERRUPT_HANDLER(EXTI_PORTA_IRQHandler, 3){} + +// External Interrupt PORTB +INTERRUPT_HANDLER(EXTI_PORTB_IRQHandler, 4){} + +// External Interrupt PORTC +INTERRUPT_HANDLER(EXTI_PORTC_IRQHandler, 5){ +} + +// External Interrupt PORTD +INTERRUPT_HANDLER(EXTI_PORTD_IRQHandler, 6){ +} + +// External Interrupt PORTE +INTERRUPT_HANDLER(EXTI_PORTE_IRQHandler, 7){} + +#ifdef STM8S903 +// External Interrupt PORTF +INTERRUPT_HANDLER(EXTI_PORTF_IRQHandler, 8){} +#endif // STM8S903 + +#if defined (STM8S208) || defined (STM8AF52Ax) +// CAN RX Interrupt routine. +INTERRUPT_HANDLER(CAN_RX_IRQHandler, 8){} + +// CAN TX Interrupt routine. +INTERRUPT_HANDLER(CAN_TX_IRQHandler, 9){} +#endif // STM8S208 || STM8AF52Ax + +// SPI Interrupt routine. +INTERRUPT_HANDLER(SPI_IRQHandler, 10){ + if(SPI_SR & SPI_SR_RXNE){ // RX not empty - send next byte + spi_send_next(); + } +} + +// Timer1 Update/Overflow/Trigger/Break Interrupt +INTERRUPT_HANDLER(TIM1_UPD_OVF_TRG_BRK_IRQHandler, 11){ +} + +// Timer1 Capture/Compare Interrupt routine. +INTERRUPT_HANDLER(TIM1_CAP_COM_IRQHandler, 12){} + +#ifdef STM8S903 +// Timer5 Update/Overflow/Break/Trigger Interrupt +INTERRUPT_HANDLER(TIM5_UPD_OVF_BRK_TRG_IRQHandler, 13){} + +// Timer5 Capture/Compare Interrupt +INTERRUPT_HANDLER(TIM5_CAP_COM_IRQHandler, 14){} + +#else // STM8S208, STM8S207, STM8S105 or STM8S103 or STM8AF62Ax or STM8AF52Ax or STM8AF626x + +// Timer2 Update/Overflow/Break Interrupt +INTERRUPT_HANDLER(TIM2_UPD_OVF_BRK_IRQHandler, 13){ +} + +// Timer2 Capture/Compare Interrupt +// manage with sending/receiving +INTERRUPT_HANDLER(TIM2_CAP_COM_IRQHandler, 14){ +} +#endif // STM8S903 + +#if defined (STM8S208) || defined(STM8S207) || defined(STM8S007) || defined(STM8S105) || \ + defined(STM8S005) || defined (STM8AF62Ax) || defined (STM8AF52Ax) || defined (STM8AF626x) +// Timer3 Update/Overflow/Break Interrupt +INTERRUPT_HANDLER(TIM3_UPD_OVF_BRK_IRQHandler, 15){} + +// Timer3 Capture/Compare Interrupt +INTERRUPT_HANDLER(TIM3_CAP_COM_IRQHandler, 16){} +#endif // STM8S208, STM8S207 or STM8S105 or STM8AF62Ax or STM8AF52Ax or STM8AF626x + +#if defined (STM8S208) || defined(STM8S207) || defined(STM8S007) || defined(STM8S103) || \ + defined(STM8S003) || defined (STM8AF62Ax) || defined (STM8AF52Ax) || defined (STM8S903) +// UART1 TX Interrupt +INTERRUPT_HANDLER(UART1_TX_IRQHandler, 17){} + +// UART1 RX Interrupt +INTERRUPT_HANDLER(UART1_RX_IRQHandler, 18){} +#endif // STM8S208 or STM8S207 or STM8S103 or STM8S903 or STM8AF62Ax or STM8AF52Ax + +// I2C Interrupt +INTERRUPT_HANDLER(I2C_IRQHandler, 19){} + +#if defined(STM8S105) || defined(STM8S005) || defined (STM8AF626x) +// UART2 TX interrupt +INTERRUPT_HANDLER(UART2_TX_IRQHandler, 20){} + +// UART2 RX interrupt +INTERRUPT_HANDLER(UART2_RX_IRQHandler, 21){ + U8 rb; + if(UART2_SR & UART_SR_RXNE){ // data received + rb = UART2_DR; // read received byte & clear RXNE flag + while(!(UART2_SR & UART_SR_TXE)); + // UART2_DR = rb; // echo received symbol + UART_rx[UART_rx_cur_i++] = rb; // put received byte into cycled buffer + if(UART_rx_cur_i == UART_rx_start_i){ // Oops: buffer overflow! Just forget old data + UART_rx_start_i++; + check_UART_pointer(UART_rx_start_i); + } + check_UART_pointer(UART_rx_cur_i); + } +} +#endif // STM8S105 or STM8AF626x + +#if defined(STM8S207) || defined(STM8S007) || defined(STM8S208) || defined (STM8AF52Ax) || defined (STM8AF62Ax) +// UART3 TX interrupt +INTERRUPT_HANDLER(UART3_TX_IRQHandler, 20){} + +// UART3 RX interrupt +INTERRUPT_HANDLER(UART3_RX_IRQHandler, 21){} +#endif // STM8S208 or STM8S207 or STM8AF52Ax or STM8AF62Ax + +#if defined(STM8S207) || defined(STM8S007) || defined(STM8S208) || defined (STM8AF52Ax) || defined (STM8AF62Ax) +// ADC2 interrupt +INTERRUPT_HANDLER(ADC2_IRQHandler, 22){} +#else +// ADC1 interrupt +INTERRUPT_HANDLER(ADC1_IRQHandler, 22){ +} +#endif // STM8S208 or STM8S207 or STM8AF52Ax or STM8AF62Ax + +#ifdef STM8S903 +// Timer6 Update/Overflow/Trigger Interrupt +INTERRUPT_HANDLER(TIM6_UPD_OVF_TRG_IRQHandler, 23){} +#else // STM8S208, STM8S207, STM8S105 or STM8S103 or STM8AF52Ax or STM8AF62Ax or STM8AF626x +// Timer4 Update/Overflow Interrupt +INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler, 23){ + if(TIM4_SR & TIM_SR1_UIF){ // update interrupt + Global_time++; // increase timer + } + TIM4_SR = 0; // clear all interrupt flags +} +#endif // STM8S903 + +// Eeprom EEC Interrupt +INTERRUPT_HANDLER(EEPROM_EEC_IRQHandler, 24){} diff --git a/uart_lcd5110/interrupts.h b/uart_lcd5110/interrupts.h new file mode 100644 index 0000000..6edf384 --- /dev/null +++ b/uart_lcd5110/interrupts.h @@ -0,0 +1,144 @@ +/* + * interrupts.h + * + * Copyright 2014 Edward V. Emelianoff + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#pragma once +#ifndef __INTERRUPTS_H__ +#define __INTERRUPTS_H__ + +#include "stm8l.h" + +// Top Level Interrupt +INTERRUPT_DEFINITION(TLI_IRQHandler, 0); + +// Auto Wake Up Interrupt +INTERRUPT_DEFINITION(AWU_IRQHandler, 1); + +// Clock Controller Interrupt +INTERRUPT_DEFINITION(CLK_IRQHandler, 2); + +// External Interrupt PORTA +INTERRUPT_DEFINITION(EXTI_PORTA_IRQHandler, 3); + +// External Interrupt PORTB +INTERRUPT_DEFINITION(EXTI_PORTB_IRQHandler, 4); + +// External Interrupt PORTC +INTERRUPT_DEFINITION(EXTI_PORTC_IRQHandler, 5); + +// External Interrupt PORTD +INTERRUPT_DEFINITION(EXTI_PORTD_IRQHandler, 6); + +// External Interrupt PORTE +INTERRUPT_DEFINITION(EXTI_PORTE_IRQHandler, 7); + +#ifdef STM8S903 +// External Interrupt PORTF +INTERRUPT_DEFINITION(EXTI_PORTF_IRQHandler, 8); +#endif // STM8S903 + +#if defined (STM8S208) || defined (STM8AF52Ax) +// CAN RX Interrupt routine. +INTERRUPT_DEFINITION(CAN_RX_IRQHandler, 8); + +// CAN TX Interrupt routine. +INTERRUPT_DEFINITION(CAN_TX_IRQHandler, 9); +#endif // STM8S208 || STM8AF52Ax + +// SPI Interrupt routine. +INTERRUPT_DEFINITION(SPI_IRQHandler, 10); + +// Timer1 Update/Overflow/Trigger/Break Interrupt +INTERRUPT_DEFINITION(TIM1_UPD_OVF_TRG_BRK_IRQHandler, 11); + +// Timer1 Capture/Compare Interrupt routine. +INTERRUPT_DEFINITION(TIM1_CAP_COM_IRQHandler, 12); + +#ifdef STM8S903 +// Timer5 Update/Overflow/Break/Trigger Interrupt +INTERRUPT_DEFINITION(TIM5_UPD_OVF_BRK_TRG_IRQHandler, 13); + +// Timer5 Capture/Compare Interrupt +INTERRUPT_DEFINITION(TIM5_CAP_COM_IRQHandler, 14); + +#else // STM8S208, STM8S207, STM8S105 or STM8S103 or STM8AF62Ax or STM8AF52Ax or STM8AF626x +// Timer2 Update/Overflow/Break Interrupt +INTERRUPT_DEFINITION(TIM2_UPD_OVF_BRK_IRQHandler, 13); + +// Timer2 Capture/Compare Interrupt +INTERRUPT_DEFINITION(TIM2_CAP_COM_IRQHandler, 14); +#endif // STM8S903 + +#if defined (STM8S208) || defined(STM8S207) || defined(STM8S007) || defined(STM8S105) || \ + defined(STM8S005) || defined (STM8AF62Ax) || defined (STM8AF52Ax) || defined (STM8AF626x) +// Timer3 Update/Overflow/Break Interrupt +INTERRUPT_DEFINITION(TIM3_UPD_OVF_BRK_IRQHandler, 15); + +// Timer3 Capture/Compare Interrupt +INTERRUPT_DEFINITION(TIM3_CAP_COM_IRQHandler, 16); +#endif // STM8S208, STM8S207 or STM8S105 or STM8AF62Ax or STM8AF52Ax or STM8AF626x + +#if defined (STM8S208) || defined(STM8S207) || defined(STM8S007) || defined(STM8S103) || \ + defined(STM8S003) || defined (STM8AF62Ax) || defined (STM8AF52Ax) || defined (STM8S903) +// UART1 TX Interrupt +INTERRUPT_DEFINITION(UART1_TX_IRQHandler, 17); + +// UART1 RX Interrupt +INTERRUPT_DEFINITION(UART1_RX_IRQHandler, 18); +#endif // STM8S208 or STM8S207 or STM8S103 or STM8S903 or STM8AF62Ax or STM8AF52Ax + +// I2C Interrupt +INTERRUPT_DEFINITION(I2C_IRQHandler, 19); + +#if defined(STM8S105) || defined(STM8S005) || defined (STM8AF626x) +// UART2 TX interrupt +INTERRUPT_DEFINITION(UART2_TX_IRQHandler, 20); + +// UART2 RX interrupt +INTERRUPT_DEFINITION(UART2_RX_IRQHandler, 21); +#endif // STM8S105 or STM8AF626x + +#if defined(STM8S207) || defined(STM8S007) || defined(STM8S208) || defined (STM8AF52Ax) || defined (STM8AF62Ax) +// UART3 TX interrupt +INTERRUPT_DEFINITION(UART3_TX_IRQHandler, 20); + +// UART3 RX interrupt +INTERRUPT_DEFINITION(UART3_RX_IRQHandler, 21); +#endif // STM8S208 or STM8S207 or STM8AF52Ax or STM8AF62Ax + +#if defined(STM8S207) || defined(STM8S007) || defined(STM8S208) || defined (STM8AF52Ax) || defined (STM8AF62Ax) +// ADC2 interrupt +INTERRUPT_DEFINITION(ADC2_IRQHandler, 22); +#else // STM8S105, STM8S103 or STM8S903 or STM8AF626x +// ADC1 interrupt +INTERRUPT_DEFINITION(ADC1_IRQHandler, 22); +#endif // STM8S208 or STM8S207 or STM8AF52Ax or STM8AF62Ax + +#ifdef STM8S903 +// Timer6 Update/Overflow/Trigger Interrupt +INTERRUPT_DEFINITION(TIM6_UPD_OVF_TRG_IRQHandler, 23); +#else // STM8S208, STM8S207, STM8S105 or STM8S103 or STM8AF52Ax or STM8AF62Ax or STM8AF626x +// Timer4 Update/Overflow Interrupt +INTERRUPT_DEFINITION(TIM4_UPD_OVF_IRQHandler, 23); +#endif // STM8S903 + +// Eeprom EEC Interrupt +INTERRUPT_DEFINITION(EEPROM_EEC_IRQHandler, 24); + +#endif // __INTERRUPTS_H__ diff --git a/uart_lcd5110/main.c b/uart_lcd5110/main.c new file mode 100644 index 0000000..c9b9330 --- /dev/null +++ b/uart_lcd5110/main.c @@ -0,0 +1,159 @@ +/* + * blinky.c + * + * Copyright 2014 Edward V. Emelianoff + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#include "ports_definition.h" +#include "interrupts.h" +#include "uart.h" +#include "pcd8544.h" +#include "spi.h" + +volatile unsigned long Global_time = 0L; // global time in ms +U16 paused_val = 500; // interval between LED flashing +U8 bias = 4, vop = 60, temp = 1; + +void setbias(){ + pcd8544_setbias(bias); + uart_write("\nbias value: "); + UART_send_byte('0' + bias); + UART_send_byte('\n'); +} +void setvop(){ + pcd8544_setvop(vop); + uart_write("\nvop value: "); + printUint(&vop, 1); + UART_send_byte('\n'); +} +void settemp(){ + pcd8544_settemp(temp); + uart_write("\ntemp. value: "); + UART_send_byte('0' + temp); + UART_send_byte('\n'); +} + +int main() { + unsigned long T = 0L; + U8 rb, wb; + CFG_GCR |= 1; // disable SWIM + // Configure clocking + CLK_CKDIVR = 0; // F_HSI = 16MHz, f_CPU = 16MHz +// Timer 4 (8 bit) used as system tick timer + // prescaler == 128 (2^7), Tfreq = 125kHz + // period = 1ms, so ARR = 125 + TIM4_PSCR = 7; + TIM4_ARR = 125; + // interrupts: update + TIM4_IER = TIM_IER_UIE; + // auto-reload + interrupt on overflow + enable + TIM4_CR1 = TIM_CR1_APRE | TIM_CR1_URS | TIM_CR1_CEN; + + // PC2 - PP output (on-board LED) + PORT(LED_PORT, DDR) |= LED_PIN; + PORT(LED_PORT, CR1) |= LED_PIN; + // LCD ~RST, ~CE and D/~C configuration: all PP outputs, clear all at start + PORT(LCD_PORT, ODR) &= ~(LCD_DC_PIN | LCD_CE_PIN | LCD_RST_PIN); + PORT(LCD_PORT, DDR) |= LCD_DC_PIN | LCD_CE_PIN | LCD_RST_PIN; + PORT(LCD_PORT, CR1) |= LCD_DC_PIN | LCD_CE_PIN | LCD_RST_PIN; + + uart_init(); + spi_init(); + // enable all interrupts + enableInterrupts(); + + pcd8544_init(); + pcd8544_print(" !\n"); + + // Loop + do{ + if((Global_time - T > paused_val) || (T > Global_time)){ + T = Global_time; + PORT(LED_PORT, ODR) ^= LED_PIN; // blink on-board LED + } + if(UART_read_byte(&rb)){ // buffer isn't empty + switch(rb){ + case 'h': // help + case 'H': + UART_send_byte(rb); + uart_write("\nPROTO:\n" + "i - init LCD\n" + "+/- Contrast\n" + "V/v +/- vop\n" + "T/t +/- temp\n" + ); + break; + case 'i': + PORT(LCD_PORT, ODR) &= ~(LCD_DC_PIN | LCD_CE_PIN | LCD_RST_PIN); + spi_init(); + pcd8544_init(); + break; + case '+': + if(bias < PCD8544_BIAS_MASK){ + ++bias; + setbias(); + } + break; + case '-': + if(bias > 0){ + --bias; + setbias(); + } + break; + case 'V': + if(vop < PCD8544_VOP_MASK){ + ++vop; + setvop(); + } + break; + case 'v': + if(vop > 0){ + --vop; + setvop(); + } + break; + case 'T': + if(temp < PCD8544_TEMP_MASK){ + ++temp; + settemp(); + } + break; + case 't': + if(temp > 0){ + --temp; + settemp(); + } + break; + default: + wb = pcd8544_putch(rb); + if(wb == rb){ + pcd8544_roll_screen(); + wb = pcd8544_putch(rb); + } + if(wb != rb){ + UART_send_byte(rb); + if(wb == '\n') UART_send_byte('\n'); + } + } + } + }while(1); +} + +void msleep(U16 pause){ + unsigned long T = Global_time + pause; + while(T > Global_time); +} diff --git a/uart_lcd5110/pcd8544.c b/uart_lcd5110/pcd8544.c new file mode 100644 index 0000000..2d03712 --- /dev/null +++ b/uart_lcd5110/pcd8544.c @@ -0,0 +1,237 @@ +/* + * pcd8544.c - functions for work with display controller + * + * Copyright 2015 Edward V. Emelianoff + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +/* + * we have two modes: direct write into LCD (with local buffer update) - for text + * and refresh whole buffer - for graphics + * all writings are in horizontal addressing mode + */ + +#include "pcd8544.h" +// here should be functions spiWrite(U8 *data, bufsz_t size) & spi_write_byte(U8 onebyte) +// max SPI speed is 4MHz +#include "spi.h" +/* here are functions & macros for changing command pins state: + * SET_DC() - set D/~C pin high (data) + * CLEAR_DC() - clear D/~C (command) + * CHIP_EN() - clear ~SCE + * CHIP_DIS() - set ~SCE (disable chip) + * CLEAR_RST() - set 1 on RST pin (SHOULD BE 0 AT START - USE PULLING RESISTOR!!!) + */ +#include "ports_definition.h" +#include + +extern void msleep(U16 pause); + +const scrnsz_t LTRS_IN_ROW = XSIZE / LTR_WIDTH; +const scrnsz_t ROW_MAX = YSIZE / 8; +// array for fast pixel set/reset +const U8 const pixels_set[] = {1,2,4,8,0x10,0x20,0x40,0x80}; +const U8 const pixels_reset[] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; +/** + * I use horizontal addressing of PCD8544, so data in buffer + * stored line by line, each byte is 8 vertical pixels (LSB upper) + * + * As refresh speed is fast enough, I don't use partial update for graphics + * (but use for letters) + */ +#define DISPLAYBUFSIZE (XSIZE*YCHARSZ) +static U8 displaybuf[DISPLAYBUFSIZE]; + +// current letter coordinates - for "printf" +static scrnsz_t cur_x = 0, cur_y = 0; +extern U8 bias, vop, temp; + +void pcd8544_setbias(U8 val){ + CMD(PCD8544_EXTENDEDINSTRUCTION); + SETBIAS(val); + CMD(PCD8544_DEFAULTMODE); +} + +void pcd8544_setvop(U8 val){ + CMD(PCD8544_EXTENDEDINSTRUCTION); + SETVOP(val); + CMD(PCD8544_DEFAULTMODE); +} + +void pcd8544_settemp(U8 val){ + CMD(PCD8544_EXTENDEDINSTRUCTION); + SETTEMP(val); + CMD(PCD8544_DEFAULTMODE); +} + +/** + * Init SPI & display + */ +void pcd8544_init(){ + CHIP_DIS(); + SET_DC(); + LCD_RST(); + msleep(10); + CLEAR_RST(); // set ~RST to 1, performing out of RESET stage +// CMD(0x21); CMD(0xc8); CMD(0x06); CMD(0x13); CMD(0x20); CMD(0x0c); + + // set LCD to optimal mode by datasheet: bias 1/48 (n=4), Vlcd 6.06 (Vop=50), normal Tcorr (1) + CMD(PCD8544_EXTENDEDINSTRUCTION); + SETBIAS(bias); + SETVOP(vop); + SETTEMP(temp); + // return to regular instructions set, horizontal addressing & prepare normal display mode + CMD(PCD8544_DEFAULTMODE); + CMD(PCD8544_DISPLAYNORMAL); + + pcd8544_cls(); +} + +/** + * Send command (cmd != 0) or data (cmd == 0) byte + */ +void pcd8544_send_byte(U8 byte, U8 cmd){ + CHIP_EN(); + if(cmd) + CLEAR_DC(); + else + SET_DC(); + spi_write_byte(byte); +} + +/** + * Send data sequence + */ +void pcd8544_send_data(U8 *data, bufsz_t size, U8 cmd){ + CHIP_EN(); + if(cmd) + CLEAR_DC(); + else + SET_DC(); + spiWrite(data, size); + CHIP_DIS(); +} + +void draw_pixel(scrnsz_t x, scrnsz_t y, U8 set){ + bufsz_t idx; + if(bad_coords(x,y)) return; + idx = x + (y/8) * XSIZE; + y %= 8; + if(set) + displaybuf[idx] |= pixels_set[y]; + else + displaybuf[idx] &= pixels_reset[y]; +} + +void pcd8544_cls(){ + memset(displaybuf, 0, DISPLAYBUFSIZE); + cur_x = cur_y = 0; + pcd8544_refresh(); +} + +/** + * send full data buffer onto display + */ +void pcd8544_refresh(){ + SETXADDR(0); + SETYADDR(0); + DBUF(displaybuf, DISPLAYBUFSIZE); +} + +/** + * draw letter at x,y position in char coordinates (XCHARSZ x YCHARSZ) + * @return 0 if fail + */ +int pcd8544_put(U8 koi8, scrnsz_t x, scrnsz_t y){ + U8 *symbol; + bufsz_t idx; + if(x >= XCHARSZ || y >= YCHARSZ) return 0; + if(koi8 < 32) return 0; + symbol = (U8*)letter(koi8); + x *= LTR_WIDTH; + idx = x + y*XSIZE; + // put letter into display buffer + memcpy(&displaybuf[idx], symbol, LTR_WIDTH); + // and show it on display + SETXADDR(x); + SETYADDR(y); + DBUF(symbol, LTR_WIDTH); + return 1; +} + +/** + * put char into current position or next line; return char if couldn't be printed + * (if OK return 0 or '\n' if newline was made) + */ +U8 pcd8544_putch(U8 chr){ + scrnsz_t tabpos; + U8 ret = 0; + if(cur_x >= XCHARSZ || cur_y >= YCHARSZ) return chr; + if(chr < 32){ // special symbols + switch(chr){ + case '\n': // carriage return - return to beginning of current line + ++cur_y; + // here shouldn't be a "break" because '\n' == "\r\n" + case '\r': // newline + cur_x = 0; + break; + case '\b': // return to previous position (backspace) + if(cur_x) --cur_x; + break; + case '\t': // tabulation by 4 symbols + tabpos = ((cur_x>>2)<<2) + 4; + if(tabpos < XCHARSZ) cur_x = tabpos; + else return chr; + break; + } + }else{ + // increment x position here (there could be not writeable letters) + pcd8544_put(chr, cur_x++, cur_y); + } + if(cur_x == XCHARSZ){ + cur_x = 0; + ++cur_y; + return '\n'; + } + return ret; +} + +/** + * print zero-terminated string from current (cur_x, cur_y) + * truncate long strings that don't fit into display + * @return NULL if all OK or pointer to non-printed string + */ +U8 *pcd8544_print(U8 *koi8){ + while(*koi8){ + U8 chr = *koi8; + if(pcd8544_putch(chr) == chr) return koi8; + ++koi8; + } + return NULL; +} + +/** + * roll screen by 1 line up + */ +void pcd8544_roll_screen(){ + bufsz_t idx = DISPLAYBUFSIZE-XSIZE; + memmove(displaybuf, displaybuf + XSIZE, idx); + memset(displaybuf+idx, 0, XSIZE); + pcd8544_refresh(); + if(cur_y) --cur_y; +} + diff --git a/uart_lcd5110/pcd8544.h b/uart_lcd5110/pcd8544.h new file mode 100644 index 0000000..d4d85f7 --- /dev/null +++ b/uart_lcd5110/pcd8544.h @@ -0,0 +1,122 @@ +/* + * pcd8544.h + * + * Copyright 2015 Edward V. Emelianoff + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#pragma once +#ifndef __PCD8544_H__ +#define __PCD8544_H__ + +#include "font.h" +#include "stm8l.h" + +// sizes in graphics (84x48) & char(letter 6x8 -> 14x6) mode +#define XSIZE (84) +#define XCHARSZ (XSIZE/LTR_WIDTH) +#define YSIZE (48) +#define YCHARSZ (YSIZE/8) + +// type of screen size +typedef U8 scrnsz_t; +// type of screen buffer index (scrnsz_t^2) +typedef U16 bufsz_t; + +extern const scrnsz_t LTRS_IN_ROW; +extern const scrnsz_t ROW_MAX; + +#define bad_coords(x, y) (!(x < XSIZE && y < YSIZE)) +#define bad_text_coords(col, row) (!(col < LTRS_IN_ROW && row < ROW_MAX)) + +/* +// bounding box +typedef struct{ + scrnsz_t xmin, + scrnsz_t ymin, + scrnsz_t xmax, + scrnsz_t ymax +} bbox_t; +*/ + +void pcd8544_init(); +void pcd8544_send_byte(U8 byte, U8 cmd); +void pcd8544_send_data(U8 *data, bufsz_t size, U8 cmd); +void draw_pixel(scrnsz_t x, scrnsz_t y, U8 set); +void pcd8544_cls(); +void pcd8544_refresh(); +int pcd8544_put(U8 koi8, scrnsz_t x, scrnsz_t y); +U8 *pcd8544_print(U8 *koi8); +U8 pcd8544_putch(U8 koi8); +void pcd8544_roll_screen(); + +void pcd8544_setbias(U8 val); +void pcd8544_setvop(U8 val); +void pcd8544_settemp(U8 val); + +#define set_pixel(x,y) do{draw_pixel(x,y,1);}while(0) +#define clear_pixel(x,y) do{draw_pixel(x,y,0);}while(0) + +/********************** PCD8544 protocol **********************/ +// Function set: | 0 | 0 | 1 | 0 | 0 | PD | V | H | +#define PCD8544_POWERDOWN (0x24) +#define PCD8544_VERTADDRESSING (0x22) +#define PCD8544_EXTENDEDINSTRUCTION (0x21) +#define PCD8544_DEFAULTMODE (0x20) +/* + * functions with H=0 (basic) + */ +// Display control: | 0 | 0 | 0 | 0 | 1 | D | 0 | E | +#define PCD8544_DISPLAYBLANK (8) +#define PCD8544_DISPLAYFILLED (9) +#define PCD8544_DISPLAYNORMAL (0xc) +#define PCD8544_DISPLAYINVERTED (0xd) +// Set Xaddr: | 1 | X6 | X5 | X4 | X3 | X2 | X1 | X0 | +#define PCD8544_SETXADDR (0x80) +#define PCD8544_XADDR_MASK (0x7f) +// Set Yaddr: | 0 | 1 | 0 | 0 | 0 | Y2 | Y1 | Y0 | +#define PCD8544_SETYADDR (0x40) +#define PCD8544_YADDR_MASK (7) +/* + * functions with H=1 (extended) + */ +// Temperature control: | 0 | 0 | 0 | 0 | 0 | 1 | TC1 | TC0 | +#define PCD8544_SETTEMP (4) +#define PCD8544_TEMP_MASK (3) +// BIAS: | 0 | 0 | 0 | 1 | 0 | BS2 | BS1 | BS0 | +#define PCD8544_SETBIAS (0x10) +#define PCD8544_BIAS_MASK (7) +// VOP: | 1 | VOP6 | VOP5 | VOP4 | VOP3 | VOP2 | VOP1 | VOP0 | +#define PCD8544_SETVOP (0x80) +#define PCD8544_VOP_MASK (0x7f) +// | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | + +/********************** Shortened macros **********************/ +#define CMD(x) do{pcd8544_send_byte(x, 1);}while(0) +#define DAT(x) do{pcd8544_send_byte(x, 0);}while(0) +#define CBUF(x,l) do{pcd8544_send_data(x, l, 1);}while(0) +#define DBUF(x,l) do{pcd8544_send_data(x, l, 0);}while(0) +// set bias level (look into datasheet, 4 - recommend) +#define SETBIAS(x) CMD(PCD8544_SETBIAS|(x&PCD8544_BIAS_MASK)) +// set operation voltage (=3.06+0.06*x) +#define SETVOP(x) CMD(PCD8544_SETVOP |(x&PCD8544_VOP_MASK)) +// temperature compensation: 0 - high, 1 - recommended, 2 - IC, 3 - minimal +#define SETTEMP(x) CMD(PCD8544_SETTEMP|(x&PCD8544_TEMP_MASK)) +// x,y addressing +#define SETXADDR(x) CMD(PCD8544_SETXADDR|(x&PCD8544_XADDR_MASK)) +#define SETYADDR(x) CMD(PCD8544_SETYADDR|(x&PCD8544_YADDR_MASK)) +#endif // __PCD8544_H__ diff --git a/uart_lcd5110/ports_definition.h b/uart_lcd5110/ports_definition.h new file mode 100644 index 0000000..d53a49a --- /dev/null +++ b/uart_lcd5110/ports_definition.h @@ -0,0 +1,65 @@ +/* + * ports_definition.h - definition of ports pins & so on + * + * Copyright 2014 Edward V. Emelianov + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#pragma once +#ifndef __PORTS_DEFINITION_H__ +#define __PORTS_DEFINITION_H__ + +#include "stm8l.h" + +// macro for using in port constructions like PORT(LED_PORT, ODR) = xx +#define CONCAT(a, b) a ## _ ## b +#define PORT(a, b) CONCAT(a , b) + +// on-board LED +#define LED_PORT PC +#define LED_PIN GPIO_PIN2 + +// UART2_TX +#define UART_PORT PD +#define UART_TX_PIN GPIO_PIN5 + +// SPI pins: SCK - PC5, MOSI - PC6, MISO - PC7 +#define SPI_PORT PC +#define SPI_SCK_PIN GPIO_PIN5 +#define SPI_MOSI_PIN GPIO_PIN6 +#define SPI_MISO_PIN GPIO_PIN7 + +// LCD5110 pins: ~RST is PD2, ~CE is PD1, D/~C is PD0 +#define LCD_PORT PD +#define LCD_RST_PIN GPIO_PIN2 +#define LCD_CE_PIN GPIO_PIN1 +#define LCD_DC_PIN GPIO_PIN0 +/* here are functions & macros for changing command pins state: + * SET_DC() - set D/~C pin high (data) + * CLEAR_DC() - clear D/~C (command) + * CHIP_EN() - clear ~SCE + * CHIP_DIS() - set ~SCE (disable chip) + * CLEAR_RST() - set 1 on RST pin (SHOULD BE 0 AT START) + */ +#define SET_DC() (PORT(LCD_PORT, ODR) |= LCD_DC_PIN) +#define CLEAR_DC() (PORT(LCD_PORT, ODR) &= ~LCD_DC_PIN) +#define CHIP_EN() (PORT(LCD_PORT, ODR) &= ~LCD_CE_PIN) +#define CHIP_DIS() (PORT(LCD_PORT, ODR) |= LCD_CE_PIN) +#define CLEAR_RST() (PORT(LCD_PORT, ODR) |= LCD_RST_PIN) +#define LCD_RST() (PORT(LCD_PORT, ODR) &= ~LCD_RST_PIN) + +#endif // __PORTS_DEFINITION_H__ diff --git a/uart_lcd5110/spi.c b/uart_lcd5110/spi.c new file mode 100644 index 0000000..28702ed --- /dev/null +++ b/uart_lcd5110/spi.c @@ -0,0 +1,116 @@ +/* + * spi.c + * + * Copyright 2016 Edward V. Emelianov + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include "ports_definition.h" +#include "spi.h" + +// global variables for sending big buffer +static U16 sendbuflen = 0; +static U8 *sendbuf = NULL, *inbuff = NULL; + +/* + * SPI registers + * SPI_CR1 (page 271): | LSBFIRST | SPE | BR[2:0] | MSTR | CPOL | CPHA | + * BR: xxx - f/2^{xxx+1} + * 01111100 + * SPI_CR2 (page 272): | BDM | BDOE | CRCEN | CRCNEXT | - | RXONLY | SSM | SSI | + * 00000000 + * SPI_ICR (page 273): | TXIE | RXIE | ERRIE | WKIE | - | - | - | - | + * SPI_SR (page 274): | BSY | OVR | MODF | CRCERR | WKUP | - | TXE | RXNE | + * set it to zero before send new byte + */ + +void spi_init(){ + // pins config: MISO is pullup in, MOSI & SCK are pp out + PORT(SPI_PORT, DDR) |= SPI_MOSI_PIN | SPI_SCK_PIN; + PORT(SPI_PORT, CR1) |= SPI_MOSI_PIN | SPI_SCK_PIN | SPI_MISO_PIN; + // setup line: f/256, enable, master + SPI_CR1 = SPI_CR1_SPE | SPI_CR1_BRMASK | SPI_CR1_MSTR; + //SPI_CR1 = SPI_CR1_SPE | (SPI_CR1_BRMASK&0x10) | SPI_CR1_MSTR; + SPI_CR2 = 0; +} + +/** + * static routine waiting SPI free + */ +static void spi_wait(){ + while(!(SPI_SR & SPI_SR_TXE)) + while(SPI_SR & SPI_SR_BSY); +} + +/** + * send given data buffer + * WARNING! Buffer should have livetime at least while !spi_buf_sent() + * set _get == 1 to put received data into the same buffer + */ +void spi_send_buffer(U8 *buff, U16 len, U8 *inb){ + inbuff = inb; + sendbuflen = len; + sendbuf = buff; + spi_wait(); + SPI_DR = *sendbuf; + // interrupts: RXNE + SPI_ICR = SPI_ICR_RXIE; +} + +/** + * send next byte from sendbuf (called by interrupt routine) + */ +void spi_send_next(){ + if(!sendbuf) return; + if(inbuff){ + *inbuff++ = SPI_DR; + } + if(--sendbuflen == 0){ + sendbuf = NULL; + SPI_ICR = 0; + return; + } + SPI_DR = *(++sendbuf); +} + +/** + * blocking send 1 byte & return ansver + */ +U8 spi_send_byte(U8 data){ + spi_wait(); + SPI_ICR = 0; + SPI_DR = data; + while(!(SPI_SR & SPI_SR_RXNE)); + return SPI_DR; +} + +void spi_send_buffer_blocking(U8 *buff, U16 len, U8 *inb){ + U16 i; + U8 r; + for(i = 0; i < len; ++i){ + r = spi_send_byte(buff[i]); + if(inb) inb[i] = r; + } +} + +/** + * return 1 if there's no data in queue to send + */ +U8 spi_buf_sent(){ + if(!sendbuf) return 1; + else return 0; +} diff --git a/uart_lcd5110/spi.h b/uart_lcd5110/spi.h new file mode 100644 index 0000000..1847ebc --- /dev/null +++ b/uart_lcd5110/spi.h @@ -0,0 +1,34 @@ +/* + * spi.h + * + * Copyright 2016 Edward V. Emelianov + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#pragma once +#ifndef __SPI_H__ +#define __SPI_H__ + +void spi_init(); +void spi_send_next(); +void spi_send_buffer_blocking(U8 *buff, U16 len, U8 *inb); +void spi_send_buffer(U8 *buff, U16 len, U8 *inbuf); +U8 spi_send_byte(U8 data); +U8 spi_buf_sent(); +#define spiWrite(d, s) do{spi_send_buffer_blocking(d, s, NULL);}while(0) +#define spi_write_byte(b) do{spi_send_byte(b);}while(0) + +#endif // __SPI_H__ diff --git a/uart_lcd5110/stm8l.h b/uart_lcd5110/stm8l.h new file mode 100644 index 0000000..cee5f59 --- /dev/null +++ b/uart_lcd5110/stm8l.h @@ -0,0 +1,561 @@ +/* + * stm8l.h + * + * Copyright 2014 Edward V. Emelianoff + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + + +#pragma once +#ifndef __STM8L_H__ +#define __STM8L_H__ + +typedef unsigned char U8; +typedef unsigned int U16; +typedef unsigned long U32; +#define NULL (void*)0 + +/* functions */ +#define enableInterrupts() {__asm__("rim\n");} // enable interrupts +#define disableInterrupts() {__asm__("sim\n");} // disable interrupts +#define iret() {__asm__("iret\n");} // Interrupt routine return +#define pop_ccr() {__asm__("pop cc\n");} // Pop CCR from the stack +#define push_ccr() {__asm__("push cc\n");}// Push CCR on the stack +#define rim() {__asm__("rim\n");} // enable interrupts +#define sim() {__asm__("sim\n");} // disable interrupts +#define nop() {__asm__("nop\n");} // No Operation +#define trap() {__asm__("trap\n");} // Trap (soft IT) +#define wfi() {__asm__("wfi\n");} // Wait For Interrupt +#define halt() {__asm__("halt\n");} // Halt + +/* + * Registers map is shown in short datasheet, page 26 + */ +/* GPIO */ +#define PA_ODR *(unsigned char*)0x5000 +#define PA_IDR *(unsigned char*)0x5001 +#define PA_DDR *(unsigned char*)0x5002 +#define PA_CR1 *(unsigned char*)0x5003 +#define PA_CR2 *(unsigned char*)0x5004 + +#define PB_ODR *(unsigned char*)0x5005 +#define PB_IDR *(unsigned char*)0x5006 +#define PB_DDR *(unsigned char*)0x5007 +#define PB_CR1 *(unsigned char*)0x5008 +#define PB_CR2 *(unsigned char*)0x5009 + +#define PC_ODR *(unsigned char*)0x500A +#define PC_IDR *(unsigned char*)0x500B +#define PC_DDR *(unsigned char*)0x500C +#define PC_CR1 *(unsigned char*)0x500D +#define PC_CR2 *(unsigned char*)0x500E + +#define PD_ODR *(unsigned char*)0x500F +#define PD_IDR *(unsigned char*)0x5010 +#define PD_DDR *(unsigned char*)0x5011 +#define PD_CR1 *(unsigned char*)0x5012 +#define PD_CR2 *(unsigned char*)0x5013 + +#define PE_ODR *(unsigned char*)0x5014 +#define PE_IDR *(unsigned char*)0x5015 +#define PE_DDR *(unsigned char*)0x5016 +#define PE_CR1 *(unsigned char*)0x5017 +#define PE_CR2 *(unsigned char*)0x5018 + +#define PF_ODR *(unsigned char*)0x5019 +#define PF_IDR *(unsigned char*)0x501A +#define PF_DDR *(unsigned char*)0x501B +#define PF_CR1 *(unsigned char*)0x501C +#define PF_CR2 *(unsigned char*)0x501D + +#ifdef STM8S105 +#define PG_ODR *(unsigned char*)0x501E +#define PG_IDR *(unsigned char*)0x501F +#define PG_DDR *(unsigned char*)0x5020 +#define PG_CR1 *(unsigned char*)0x5021 +#define PG_CR2 *(unsigned char*)0x5022 + +#define PH_ODR *(unsigned char*)0x5023 +#define PH_IDR *(unsigned char*)0x5024 +#define PH_DDR *(unsigned char*)0x5025 +#define PH_CR1 *(unsigned char*)0x5026 +#define PH_CR2 *(unsigned char*)0x5027 + +#define PI_ODR *(unsigned char*)0x5028 +#define PI_IDR *(unsigned char*)0x5029 +#define PI_DDR *(unsigned char*)0x502A +#define PI_CR1 *(unsigned char*)0x502B +#define PI_CR2 *(unsigned char*)0x502C +#endif // STM8S105 + +/* GPIO bits */ +#define GPIO_PIN0 (1 << 0) +#define GPIO_PIN1 (1 << 1) +#define GPIO_PIN2 (1 << 2) +#define GPIO_PIN3 (1 << 3) +#define GPIO_PIN4 (1 << 4) +#define GPIO_PIN5 (1 << 5) +#define GPIO_PIN6 (1 << 6) +#define GPIO_PIN7 (1 << 7) + +/* -------------------- FLASH/EEPROM -------------------- */ +#define FLASH_CR1 *(unsigned char*)0x505A +#define FLASH_CR2 *(unsigned char*)0x505B +#define FLASH_NCR2 *(unsigned char*)0x505C +#define FLASH_FPR *(unsigned char*)0x505D +#define FLASH_NFPR *(unsigned char*)0x505E +#define FLASH_IAPSR *(unsigned char*)0x505F +#define FLASH_PUKR *(unsigned char*)0x5062 // progmem unprotection +#define FLASH_DUKR *(unsigned char*)0x5064 // EEPROM unprotection + +#define EEPROM_KEY1 0xAE // keys to manage EEPROM's write access +#define EEPROM_KEY2 0x56 +#define EEPROM_START_ADDR (unsigned char*)0x4000 + +/* ------------------- interrupts ------------------- */ +#define EXTI_CR1 *(unsigned char*)0x50A0 +#define EXTI_CR2 *(unsigned char*)0x50A1 +#define INTERRUPT_HANDLER(fn, num) void fn() __interrupt(num) +#define INTERRUPT_DEFINITION(fn, num) extern void fn() __interrupt(num) + +// Reset status register +#define RST_SR *(unsigned char*)0x50B3 + +/* ------------------- CLOCK ------------------- */ +#define CLK_ICKR *(unsigned char*)0x50C0 +#define CLK_ECKR *(unsigned char*)0x50C1 +#define CLK_CMSR *(unsigned char*)0x50C3 +#define CLK_SWR *(unsigned char*)0x50C4 +#define CLK_SWCR *(unsigned char*)0x50C5 +#define CLK_CKDIVR *(unsigned char*)0x50C6 +#define CLK_SPCKENR1 *(unsigned char*)0x50C7 +#define CLK_CSSR *(unsigned char*)0x50C8 +#define CLK_CCOR *(unsigned char*)0x50C9 +#define CLK_PCKENR2 *(unsigned char*)0x50CA +#define CLK_HSITRIMR *(unsigned char*)0x50CC +#define CLK_SWIMCCR *(unsigned char*)0x50CD + +/* ------------------- Watchdog ------------------ */ +#define WWDG_CR *(unsigned char*)0x50D1 +#define WWDG_WR *(unsigned char*)0x50D2 +#define IWDG_KR *(unsigned char*)0x50E0 +#define IWDG_PR *(unsigned char*)0x50E1 +#define IWDG_RLR *(unsigned char*)0x50E2 + +/* ------------------- AWU, BEEP ------------------- */ +#define AWU_CSR1 *(unsigned char*)0x50F0 +#define AWU_APR *(unsigned char*)0x50F1 +#define AWU_TBR *(unsigned char*)0x50F2 +#define BEEP_CSR *(unsigned char*)0x50F3 + +/* ------------------- SPI ------------------- */ +#define SPI_CR1 *(unsigned char*)0x5200 +#define SPI_CR2 *(unsigned char*)0x5201 +#define SPI_ICR *(unsigned char*)0x5202 +#define SPI_SR *(unsigned char*)0x5203 +#define SPI_DR *(unsigned char*)0x5204 +#define SPI_CRCPR *(unsigned char*)0x5205 +#define SPI_RXCRCR *(unsigned char*)0x5206 +#define SPI_TXCRCR *(unsigned char*)0x5207 +// SPI_CR1 (page 271): | LSBFIRST | SPE | BR[2:0] | MSTR | CPOL | CPHA | +#define SPI_CR1_LSBFIRST (1<<7) +#define SPI_CR1_SPE (1<<6) +#define SPI_CR1_BRMASK (0x38) +#define SPI_CR1_MSTR (1<<2) +#define SPI_CR1_CPOL (1<<1) +#define SPI_CR1_CPHA (1) +// SPI_CR2 (page 272): | BDM | BDOE | CRCEN | CRCNEXT | - | RXONLY | SSM | SSI | +#define SPI_CR2_BDM (1<<7) +#define SPI_CR2_BDOE (1<<6) +#define SPI_CR2_CRCEN (1<<5) +#define SPI_CR2_CRCNEXT (1<<4) +#define SPI_CR2_RXONLY (1<<2) +#define SPI_CR2_SSM (1<<1) +#define SPI_CR2_SSI (1) +// SPI_ICR (page 273): | TXIE | RXIE | ERRIE | WKIE | - | - | - | - | +#define SPI_ICR_TXIE (1<<7) +#define SPI_ICR_RXIE (1<<6) +#define SPI_ICR_ERRIE (1<<5) +#define SPI_ICR_WKIE (1<<4) +// SPI_SR (page 274): | BSY | OVR | MODF | CRCERR | WKUP | - | TXE | RXNE | +#define SPI_SR_BSY (1<<7) +#define SPI_SR_OVR (1<<6) +#define SPI_SR_MODF (1<<5) +#define SPI_SR_CRCERR (1<<4) +#define SPI_SR_WKUP (1<<3) +#define SPI_SR_TXE (1<<1) +#define SPI_SR_RXNE (1) + +/* ------------------- I2C ------------------- */ +#define I2C_CR1 *(unsigned char*)0x5210 +#define I2C_CR2 *(unsigned char*)0x5211 +#define I2C_FREQR *(unsigned char*)0x5212 +#define I2C_OARL *(unsigned char*)0x5213 +#define I2C_OARH *(unsigned char*)0x5214 +#define I2C_DR *(unsigned char*)0x5216 +#define I2C_SR1 *(unsigned char*)0x5217 +#define I2C_SR2 *(unsigned char*)0x5218 +#define I2C_SR3 *(unsigned char*)0x5219 +#define I2C_ITR *(unsigned char*)0x521A +#define I2C_CCRL *(unsigned char*)0x521B +#define I2C_CCRH *(unsigned char*)0x521C +#define I2C_TRISER *(unsigned char*)0x521D +#define I2C_PECR *(unsigned char*)0x521E + +/* ------------------- UART ------------------- */ +#ifdef STM8S003 +#define UART1_SR *(unsigned char*)0x5230 +#define UART1_DR *(unsigned char*)0x5231 +#define UART1_BRR1 *(unsigned char*)0x5232 +#define UART1_BRR2 *(unsigned char*)0x5233 +#define UART1_CR1 *(unsigned char*)0x5234 +#define UART1_CR2 *(unsigned char*)0x5235 +#define UART1_CR3 *(unsigned char*)0x5236 +#define UART1_CR4 *(unsigned char*)0x5237 +#define UART1_CR5 *(unsigned char*)0x5238 +#define UART1_GTR *(unsigned char*)0x5239 +#define UART1_PSCR *(unsigned char*)0x523A +#endif // STM8S003 +#ifdef STM8S105 +#define UART2_SR *(unsigned char*)0x5240 +#define UART2_DR *(unsigned char*)0x5241 +#define UART2_BRR1 *(unsigned char*)0x5242 +#define UART2_BRR2 *(unsigned char*)0x5243 +#define UART2_CR1 *(unsigned char*)0x5244 +#define UART2_CR2 *(unsigned char*)0x5245 +#define UART2_CR3 *(unsigned char*)0x5246 +#define UART2_CR4 *(unsigned char*)0x5247 +#define UART2_CR5 *(unsigned char*)0x5248 +#define UART2_CR6 *(unsigned char*)0x5249 +#define UART2_GTR *(unsigned char*)0x524A +#define UART2_PSCR *(unsigned char*)0x524B +#endif // STM8S105 + +/* UART_CR1 bits */ +#define UART_CR1_R8 (1 << 7) +#define UART_CR1_T8 (1 << 6) +#define UART_CR1_UARTD (1 << 5) +#define UART_CR1_M (1 << 4) +#define UART_CR1_WAKE (1 << 3) +#define UART_CR1_PCEN (1 << 2) +#define UART_CR1_PS (1 << 1) +#define UART_CR1_PIEN (1 << 0) + +/* UART_CR2 bits */ +#define UART_CR2_TIEN (1 << 7) +#define UART_CR2_TCIEN (1 << 6) +#define UART_CR2_RIEN (1 << 5) +#define UART_CR2_ILIEN (1 << 4) +#define UART_CR2_TEN (1 << 3) +#define UART_CR2_REN (1 << 2) +#define UART_CR2_RWU (1 << 1) +#define UART_CR2_SBK (1 << 0) + +/* USART_CR3 bits */ +#define UART_CR3_LINEN (1 << 6) +#define UART_CR3_STOP2 (1 << 5) +#define UART_CR3_STOP1 (1 << 4) +#define UART_CR3_CLKEN (1 << 3) +#define UART_CR3_CPOL (1 << 2) +#define UART_CR3_CPHA (1 << 1) +#define UART_CR3_LBCL (1 << 0) + +/* UART_SR bits */ +#define UART_SR_TXE (1 << 7) +#define UART_SR_TC (1 << 6) +#define UART_SR_RXNE (1 << 5) +#define UART_SR_IDLE (1 << 4) +#define UART_SR_OR (1 << 3) +#define UART_SR_NF (1 << 2) +#define UART_SR_FE (1 << 1) +#define UART_SR_PE (1 << 0) + + +/* ------------------- TIMERS ------------------- */ +/* TIM1 */ +#define TIM1_CR1 *(unsigned char*)0x5250 +#define TIM1_CR2 *(unsigned char*)0x5251 +#define TIM1_SMCR *(unsigned char*)0x5252 +#define TIM1_ETR *(unsigned char*)0x5253 +#define TIM1_IER *(unsigned char*)0x5254 +#define TIM1_SR1 *(unsigned char*)0x5255 +#define TIM1_SR2 *(unsigned char*)0x5256 +#define TIM1_EGR *(unsigned char*)0x5257 +#define TIM1_CCMR1 *(unsigned char*)0x5258 +#define TIM1_CCMR2 *(unsigned char*)0x5259 +#define TIM1_CCMR3 *(unsigned char*)0x525A +#define TIM1_CCMR4 *(unsigned char*)0x525B +#define TIM1_CCER1 *(unsigned char*)0x525C +#define TIM1_CCER2 *(unsigned char*)0x525D +#define TIM1_CNTRH *(unsigned char*)0x525E +#define TIM1_CNTRL *(unsigned char*)0x525F +#define TIM1_PSCRH *(unsigned char*)0x5260 +#define TIM1_PSCRL *(unsigned char*)0x5261 +#define TIM1_ARRH *(unsigned char*)0x5262 +#define TIM1_ARRL *(unsigned char*)0x5263 +#define TIM1_RCR *(unsigned char*)0x5264 +#define TIM1_CCR1H *(unsigned char*)0x5265 +#define TIM1_CCR1L *(unsigned char*)0x5266 +#define TIM1_CCR2H *(unsigned char*)0x5267 +#define TIM1_CCR2L *(unsigned char*)0x5268 +#define TIM1_CCR3H *(unsigned char*)0x5269 +#define TIM1_CCR3L *(unsigned char*)0x526A +#define TIM1_CCR4H *(unsigned char*)0x526B +#define TIM1_CCR4L *(unsigned char*)0x526C +#define TIM1_BKR *(unsigned char*)0x526D +#define TIM1_DTR *(unsigned char*)0x526E +#define TIM1_OISR *(unsigned char*)0x526F + + +/* TIM_IER bits */ +#define TIM_IER_BIE (1 << 7) +#define TIM_IER_TIE (1 << 6) +#define TIM_IER_COMIE (1 << 5) +#define TIM_IER_CC4IE (1 << 4) +#define TIM_IER_CC3IE (1 << 3) +#define TIM_IER_CC2IE (1 << 2) +#define TIM_IER_CC1IE (1 << 1) +#define TIM_IER_UIE (1 << 0) + +/* TIM_CR1 bits */ +#define TIM_CR1_APRE (1 << 7) +#define TIM_CR1_CMSH (1 << 6) +#define TIM_CR1_CMSL (1 << 5) +#define TIM_CR1_DIR (1 << 4) +#define TIM_CR1_OPM (1 << 3) +#define TIM_CR1_URS (1 << 2) +#define TIM_CR1_UDIS (1 << 1) +#define TIM_CR1_CEN (1 << 0) + +/* TIM_SR1 bits */ +#define TIM_SR1_BIF (1 << 7) +#define TIM_SR1_TIF (1 << 6) +#define TIM_SR1_COMIF (1 << 5) +#define TIM_SR1_CC4IF (1 << 4) +#define TIM_SR1_CC3IF (1 << 3) +#define TIM_SR1_CC2IF (1 << 2) +#define TIM_SR1_CC1IF (1 << 1) +#define TIM_SR1_UIF (1 << 0) + +/* TIM_EGR bits */ +#define TIM_EGR_BG (1 << 7) +#define TIM_EGR_TG (1 << 6) +#define TIM_EGR_COMG (1 << 5) +#define TIM_EGR_CC4G (1 << 4) +#define TIM_EGR_CC3G (1 << 3) +#define TIM_EGR_CC2G (1 << 2) +#define TIM_EGR_CC1G (1 << 1) +#define TIM_EGR_UG (1 << 0) + + +/* TIM2 */ +#define TIM2_CR1 *(unsigned char*)0x5300 +#if defined STM8S105 || defined STM8S103 +#define TIM2_IER *(unsigned char*)0x5301 +#define TIM2_SR1 *(unsigned char*)0x5302 +#define TIM2_SR2 *(unsigned char*)0x5303 +#define TIM2_EGR *(unsigned char*)0x5304 +#define TIM2_CCMR1 *(unsigned char*)0x5305 +#define TIM2_CCMR2 *(unsigned char*)0x5306 +#define TIM2_CCMR3 *(unsigned char*)0x5307 +#define TIM2_CCER1 *(unsigned char*)0x5308 +#define TIM2_CCER2 *(unsigned char*)0x5309 +#define TIM2_CNTRH *(unsigned char*)0x530A +#define TIM2_CNTRL *(unsigned char*)0x530B +#define TIM2_PSCR *(unsigned char*)0x530C +#define TIM2_ARRH *(unsigned char*)0x530D +#define TIM2_ARRL *(unsigned char*)0x530E +#define TIM2_CCR1H *(unsigned char*)0x530F +#define TIM2_CCR1L *(unsigned char*)0x5310 +#define TIM2_CCR2H *(unsigned char*)0x5311 +#define TIM2_CCR2L *(unsigned char*)0x5312 +#define TIM2_CCR3H *(unsigned char*)0x5313 +#define TIM2_CCR3L *(unsigned char*)0x5314 +#elif defined STM8S003 +#define TIM2_IER *(unsigned char*)0x5303 +#define TIM2_SR1 *(unsigned char*)0x5304 +#define TIM2_SR2 *(unsigned char*)0x5305 +#define TIM2_EGR *(unsigned char*)0x5306 +#define TIM2_CCMR1 *(unsigned char*)0x5307 +#define TIM2_CCMR2 *(unsigned char*)0x5308 +#define TIM2_CCMR3 *(unsigned char*)0x5309 +#define TIM2_CCER1 *(unsigned char*)0x530A +#define TIM2_CCER2 *(unsigned char*)0x530B +#define TIM2_CNTRH *(unsigned char*)0x530C +#define TIM2_CNTRL *(unsigned char*)0x530D +#define TIM2_PSCR *(unsigned char*)0x530E +#define TIM2_ARRH *(unsigned char*)0x530F +#define TIM2_ARRL *(unsigned char*)0x5310 +#define TIM2_CCR1H *(unsigned char*)0x5311 +#define TIM2_CCR1L *(unsigned char*)0x5312 +#define TIM2_CCR2H *(unsigned char*)0x5313 +#define TIM2_CCR2L *(unsigned char*)0x5314 +#define TIM2_CCR3H *(unsigned char*)0x5315 +#define TIM2_CCR3L *(unsigned char*)0x5316 +#endif + + +/* TIM3 */ +#if defined STM8S105 || defined STM8S103 +#define TIM3_CR1 *(unsigned char*)0x5320 +#define TIM3_IER *(unsigned char*)0x5321 +#define TIM3_SR1 *(unsigned char*)0x5322 +#define TIM3_SR2 *(unsigned char*)0x5323 +#define TIM3_EGR *(unsigned char*)0x5324 +#define TIM3_CCMR1 *(unsigned char*)0x5325 +#define TIM3_CCMR2 *(unsigned char*)0x5326 +#define TIM3_CCER1 *(unsigned char*)0x5327 +#define TIM3_CNTRH *(unsigned char*)0x5328 +#define TIM3_CNTRL *(unsigned char*)0x5329 +#define TIM3_PSCR *(unsigned char*)0x532A +#define TIM3_ARRH *(unsigned char*)0x532B +#define TIM3_ARRL *(unsigned char*)0x532C +#define TIM3_CCR1H *(unsigned char*)0x532D +#define TIM3_CCR1L *(unsigned char*)0x532E +#define TIM3_CCR2H *(unsigned char*)0x532F +#define TIM3_CCR2L *(unsigned char*)0x5330 +#endif + +/* TIM4 */ +#define TIM4_CR1 *(unsigned char*)0x5340 +#if defined STM8S105 || defined STM8S103 +#define TIM4_IER *(unsigned char*)0x5341 +#define TIM4_SR *(unsigned char*)0x5342 +#define TIM4_EGR *(unsigned char*)0x5343 +#define TIM4_CNTR *(unsigned char*)0x5344 +#define TIM4_PSCR *(unsigned char*)0x5345 +#define TIM4_ARR *(unsigned char*)0x5346 +#elif defined STM8S003 +#define TIM4_IER *(unsigned char*)0x5343 +#define TIM4_SR *(unsigned char*)0x5344 +#define TIM4_EGR *(unsigned char*)0x5345 +#define TIM4_CNTR *(unsigned char*)0x5346 +#define TIM4_PSCR *(unsigned char*)0x5347 +#define TIM4_ARR *(unsigned char*)0x5348 +#endif + +/* ------------------- ADC ------------------- */ +#define ADC_DB0RH *(unsigned char*)0x53E0 +#define ADC_DB0RL *(unsigned char*)0x53E1 +#define ADC_DB1RH *(unsigned char*)0x53E2 +#define ADC_DB1RL *(unsigned char*)0x53E3 +#define ADC_DB2RH *(unsigned char*)0x53E4 +#define ADC_DB2RL *(unsigned char*)0x53E5 +#define ADC_DB3RH *(unsigned char*)0x53E6 +#define ADC_DB3RL *(unsigned char*)0x53E7 +#define ADC_DB4RH *(unsigned char*)0x53E8 +#define ADC_DB4RL *(unsigned char*)0x53E9 +#define ADC_DB5RH *(unsigned char*)0x53EA +#define ADC_DB5RL *(unsigned char*)0x53EB +#define ADC_DB6RH *(unsigned char*)0x53EC +#define ADC_DB6RL *(unsigned char*)0x53ED +#define ADC_DB7RH *(unsigned char*)0x53EE +#define ADC_DB7RL *(unsigned char*)0x53EF +#define ADC_DB8RH *(unsigned char*)0x53F0 +#define ADC_DB8RL *(unsigned char*)0x53F1 +#define ADC_DB9RH *(unsigned char*)0x53F2 +#define ADC_DB9RL *(unsigned char*)0x53F3 +#define ADC_CSR *(unsigned char*)0x5400 +#define ADC_CR1 *(unsigned char*)0x5401 +#define ADC_CR2 *(unsigned char*)0x5402 +#define ADC_CR3 *(unsigned char*)0x5403 +#define ADC_DRH *(unsigned char*)0x5404 +#define ADC_DRL *(unsigned char*)0x5405 +#define ADC_TDRH *(unsigned char*)0x5406 +#define ADC_TDRL *(unsigned char*)0x5407 +#define ADC_HTRH *(unsigned char*)0x5408 +#define ADC_HTRL *(unsigned char*)0x5409 +#define ADC_LTRH *(unsigned char*)0x540A +#define ADC_LTRL *(unsigned char*)0x540B +#define ADC_AWSRH *(unsigned char*)0x540C +#define ADC_AWSRL *(unsigned char*)0x540D +#define ADC_AWCRH *(unsigned char*)0x540E +#define ADC_AWCRL *(unsigned char*)0x540F + +/* ------------------- swim control ------------------- */ +#define CFG_GCR *(unsigned char*)0x7F60 +#define SWIM_CSR *(unsigned char*)0x7F80 + +/* ------------------- ITC ------------------- */ +#define ITC_SPR1 *(unsigned char*)0x7F70 +#define ITC_SPR2 *(unsigned char*)0x7F71 +#define ITC_SPR3 *(unsigned char*)0x7F72 +#define ITC_SPR4 *(unsigned char*)0x7F73 +#define ITC_SPR5 *(unsigned char*)0x7F74 +#define ITC_SPR6 *(unsigned char*)0x7F75 +#define ITC_SPR7 *(unsigned char*)0x7F76 +#define ITC_SPR8 *(unsigned char*)0x7F77 + + +/* -------------------- UNIQUE ID -------------------- */ +#if defined STM8S105 || defined STM8S103 // maybe some other MCU have this too??? +#define U_ID00 (unsigned char*)0x48CD +#define U_ID01 (unsigned char*)0x48CE +#define U_ID02 (unsigned char*)0x48CF +#define U_ID03 (unsigned char*)0x48D0 +#define U_ID04 (unsigned char*)0x48D1 +#define U_ID05 (unsigned char*)0x48D2 +#define U_ID06 (unsigned char*)0x48D3 +#define U_ID07 (unsigned char*)0x48D4 +#define U_ID08 (unsigned char*)0x48D5 +#define U_ID09 (unsigned char*)0x48D6 +#define U_ID10 (unsigned char*)0x48D7 +#define U_ID11 (unsigned char*)0x48D8 +#endif // defined STM8S105 || defined STM8S103 + +// CCR REGISTER: bits 3&5 should be 1 if you wanna change EXTI_CRx +#define CCR *(unsigned char*)0x7F0A + +/* -------------------- OPTION BYTES -------------------- */ +#if defined STM8S105 +// readout protection +#define OPT0 *(unsigned char*)0x4800 +// user boot code +#define OPT1 *(unsigned char*)0x4801 +#define NOPT1 *(unsigned char*)0x4802 +// alternate functions remapping +// | AFR7 | ... | AFR0 | +// AFR7 - PD4 = BEEP; AFR6 - PB4/PB5 = I2C; AFR5 - PB0..3 - TIM1 +// AFR4 - PD7 = TIM1_CH4; AFR3 - PD0 = TIM1_BKIN +// AFR2 - PD0 = CLK_CCO; AFR1 - PA3 = TIM3_CH1, PD2 = TIM2_CH3 +// AFR0 - PD3 = ADC_ETR +#define OPT2 *(unsigned char*)0x4803 +#define NOPT2 *(unsigned char*)0x4804 +// trim, watchdog +#define OPT3 *(unsigned char*)0x4805 +#define NOPT3 *(unsigned char*)0x4806 +// extclc, awu +#define OPT4 *(unsigned char*)0x4807 +#define NOPT4 *(unsigned char*)0x4808 +// HSE stab time +#define OPT5 *(unsigned char*)0x4809 +#define NOPT5 *(unsigned char*)0x480a +// none +#define OPT6 *(unsigned char*)0x480b +#define NOPT6 *(unsigned char*)0x480c +// none +#define OPT7 *(unsigned char*)0x480d +#define NOPT7 *(unsigned char*)0x480e +// bootloader opt byte +#define OPTBL *(unsigned char*)0x487e +#define NOPTBL *(unsigned char*)0x487f + +#endif + +#endif // __STM8L_H__ + +// #define *(unsigned char*)0x diff --git a/uart_lcd5110/uart.c b/uart_lcd5110/uart.c new file mode 100644 index 0000000..265040c --- /dev/null +++ b/uart_lcd5110/uart.c @@ -0,0 +1,168 @@ +/* + * blinky.c + * + * Copyright 2014 Edward V. Emelianoff + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + + +#include "ports_definition.h" +#include "uart.h" +#include "interrupts.h" + +U8 UART_rx[UART_BUF_LEN]; // cycle buffer for received data +U8 UART_rx_start_i = 0; // started index of received data (from which reading starts) +U8 UART_rx_cur_i = 0; // index of current first byte in rx array (to which data will be written) + +/** + * Send one byte through UART + * @param byte - data to send + */ +void UART_send_byte(U8 byte){ + while(!(UART2_SR & UART_SR_TXE)); // wait until previous byte transmitted + UART2_DR = byte; +} + +void uart_write(char *str){ + while(*str){ + while(!(UART2_SR & UART_SR_TXE)); + UART2_CR2 |= UART_CR2_TEN; + UART2_DR = *str++; + } +} + +/** + * Read one byte from Rx buffer + * @param byte - where to store readed data + * @return 1 in case of non-empty buffer + */ +U8 UART_read_byte(U8 *byte){ + if(UART_rx_start_i == UART_rx_cur_i) // buffer is empty + return 0; + *byte = UART_rx[UART_rx_start_i++]; + check_UART_pointer(UART_rx_start_i); + return 1; +} + +void printUint(U8 *val, U8 len){ + unsigned long Number = 0; + U8 i = len; + char ch; + U8 decimal_buff[12]; // max len of U32 == 10 + \n + \0 + if(len > 4 || len == 3 || len == 0) return; + for(i = 0; i < 12; i++) + decimal_buff[i] = 0; + decimal_buff[10] = '\n'; + ch = 9; + switch(len){ + case 1: + Number = *((U8*)val); + break; + case 2: + Number = *((U16*)val); + break; + case 4: + Number = *((unsigned long*)val); + break; + } + do{ + i = Number % 10L; + decimal_buff[ch--] = i + '0'; + Number /= 10L; + }while(Number && ch > -1); + uart_write((char*)&decimal_buff[ch+1]); +} + +/** + * print signed long onto terminal + * max len = 10 symbols + 1 for "-" + 1 for '\n' + 1 for 0 = 13 + */ +void print_long(long Number){ + U8 i, L = 0; + char ch; + char decimal_buff[12]; + decimal_buff[11] = 0; + ch = 11; + if(Number < 0){ + Number = -Number; + L = 1; + } + do{ + i = Number % 10L; + decimal_buff[--ch] = i + '0'; + Number /= 10L; + }while(Number && ch > 0); + if(ch > 0 && L) decimal_buff[--ch] = '-'; + uart_write(&decimal_buff[ch]); +} + +U8 readInt(int *val){ + unsigned long T = Global_time; + unsigned long R = 0; + int readed; + U8 sign = 0, rb, ret = 0, bad = 0; + do{ + if(!UART_read_byte(&rb)) continue; + if(rb == '-' && R == 0){ // negative number + sign = 1; + continue; + } + if(rb < '0' || rb > '9') break; // number ends with any non-digit symbol that will be omitted + ret = 1; // there's at least one digit + R = R * 10L + rb - '0'; + if(R > 0x7fff){ // bad value + R = 0; + bad = 0; + } + }while(Global_time - T < 10000); // wait no longer than 10s + if(bad || !ret) return 0; + readed = (int) R; + if(sign) readed *= -1; + *val = readed; + return 1; +} + +void error_msg(char *msg){ + uart_write("\nERROR: "); + uart_write(msg); + UART_send_byte('\n'); +} + +U8 U8toHEX(U8 val){ + val &= 0x0f; + if(val < 10) val += '0'; + else val += 'a' - 10; + return val; +} + +void printUHEX(U8 val){ + uart_write("0x"); + UART_send_byte(U8toHEX(val>>4)); // MSB + UART_send_byte(U8toHEX(val)); // LSB +} + +void uart_init(){ + // PD5 - UART2_TX + PORT(UART_PORT, DDR) |= UART_TX_PIN; + PORT(UART_PORT, CR1) |= UART_TX_PIN; +// Configure UART + // 8 bit, no parity, 1 stop (UART_CR1/3 = 0 - reset value) + // 57600 on 16MHz: BRR1=0x11, BRR2=0x06 + UART2_BRR1 = 0x11; UART2_BRR2 = 0x06; + UART2_CR2 = UART_CR2_TEN | UART_CR2_REN | UART_CR2_RIEN; // Allow RX/TX, generate ints on rx +} + diff --git a/uart_lcd5110/uart.h b/uart_lcd5110/uart.h new file mode 100644 index 0000000..cfd9d6e --- /dev/null +++ b/uart_lcd5110/uart.h @@ -0,0 +1,45 @@ +/* + * blinky.h + * + * Copyright 2014 Edward V. Emelianoff + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#pragma once +#ifndef __MAIN_H__ +#define __MAIN_H__ + +extern volatile unsigned long Global_time; // global time in ms + +#define UART_BUF_LEN 8 // max 7 bytes transmited in on operation + +extern U8 UART_rx[]; +extern U8 UART_rx_start_i; +extern U8 UART_rx_cur_i; + + +void UART_send_byte(U8 byte); +void uart_write(char *str); +void printUint(U8 *val, U8 len); +void print_long(long Number); +void error_msg(char *msg); +void uart_init(); +U8 UART_read_byte(U8 *byte); +void printUHEX(U8 val); + +#define check_UART_pointer(x) do{if(x == UART_BUF_LEN) x = 0;}while(0) + +#endif // __MAIN_H__ diff --git a/uart_lcd5110/uartlcd.ihx b/uart_lcd5110/uartlcd.ihx new file mode 100644 index 0000000..0ec7696 --- /dev/null +++ b/uart_lcd5110/uartlcd.ihx @@ -0,0 +1,188 @@ +:2080A000AE5240F64824F9AE52417B03F781160390F64D271BAE5240F64824F9AE5245F6EA +:2080C000AA08AE5245F790F6905CAE5241F720E0815202C60202C1020126034F20271605CB +:2080E000AE00011F01C6020197C602014CC702014F9572FB01F690F7C60201A10826047295 +:208100005F0201A6015B0281521C5F1F101F0E7B21A1042303CC81DE7B21A1032603CC8107 +:20812000DE0D212603CC81DE965C1F124F5F9772FB127F4CA10C25F51E121C000AA60AF769 +:208140007B21A101270E7B21A102271C7B21A104272120301E1FF66B1C5F0F191F0F7B1C4B +:208160006B117B196B0E201C161F90FE5F17101F0E20111E1FE6036B18E602FE6B101F0E5C +:208180007B186B11A6096B0D4B0A5F894B001E14891E1489CD92EA5B089F887B0E6B15844B +:2081A0000A0D5F417B144172FB12AB30F74B0A5F894B001E14891E1489CD941B5B081F10DB +:2081C000170E1E1026041E0E27067B0DA1FF2CB87B0D4C5F9772FB1289CD80AE5B025B1C1C +:2081E0008152110F0E965C1F101E101C000B7F1E16A300007B15A2007B14A2002E141616E1 +:2082000090504F1215974F12149517161F14A6016B0EA60B6B0D4B0A5F894B001E1A891E57 +:208220001A89CD92455B089F0A0D5F417B0D4172FB10AB30F74B0A5F894B001E1A891E1AA5 +:2082400089CD93675B081F1617147B0DA1002C034F2002A6011E1626041E1427034D26B6B8 +:20826000887B0E6B10844D27140D0E27100A0D7B0D6B0F5F7B0F9772FB10A62DF75F7B0F4B +:208280009772FB1089CD80AE5B025B1181521ACE020B1F0DCE02091F0B5F1F091F070F04C6 +:2082A0000F020F01961C000389CD80D15B024D2603CC83317B03A12D260E1E09260A1E07F2 +:2082C0002606A6016B0420697B03A1302403CC83537B03A1392303CC8353A6016B021E0960 +:2082E000891E09894B0A5F894B00CD95085B081F1517137B030F115F90977B11909572F952 +:20830000159F1914979E19139572A200309FA2006B189EA20017096B077B186B08AE7FFF7A +:2083200013094F12084F120724075F1F091F070F0190CE020B72F20DC6020A120C95C6023F +:2083400009120B9790A327109EA2009FA2002403CC82A40D0126040D0226034F201A7B09DF +:20836000887B0B6B07846B050D0427051E05501F051E1D1605FFA6015B1A81AE83FE89CD3E +:2083800080AE5B021E0389CD80AE5B024B0ACD80A084817B03A40F6B037B03887B04A10A3A +:2083A000842406AB306B032004AB576B037B0381AE840789CD80AE5B027B034EA40F88CD45 +:2083C00083935B0188CD80A0847B0388CD83935B0188CD80A08481AE5011F6AA20AE501195 +:2083E000F7AE5012F6AA20AE5012F7AE5242A611F7AE5243A606F7AE5245A62CF7810A45FB +:0A84000052524F523A20003078002B +:02966D000000FB +:20840A008080808080808080AE5203F6442403CD84F98080808080808080805204AE52408E +:20842A00F66B027B02A520274AAE5241F66B017B02A4804D27FDAE00011F03C6020297C66F +:20844A0002024CC702024F9572FB037B01F7C60201C102022612C602014CC70201C60201C2 +:20846A00A1082604725F0201C60202A1082604725F02025B048080AE5342F644241B90CE60 +:1F848A00020B72A90001C6020AA90097C60209A9009590CF020BCF0209AE53427F808081 +:2084A900AE500CF6AA60AE500CF7AE500DF6AAE0AE500DF7AE5200A67CF7AE52017F81AE53 +:2084C9005203F6A5022607A4804D27F320FB811E07CF02071E05CF02031E03CF0205CD8411 +:2084E900C8CE0205F6AE5204F7AE5202A640F781CE0205273FCE0207271190CE0207AE52D4 +:2085090004F690F7CE02075CCF0207CE02035ACF0203CE0203260E725F0206725F0205AE5F +:2085290052027F200FCE02055CCF0205CE0205F6AE5204F781CD84C8AE52027FAE52047BC9 +:2085490003F7AE5203F64424F9AE5204F6815F1305241D909372F90390F68988CD853E5B78 +:1C856900018516072707909372F90790F75C20DF81CE02052604A60120014F8196 +:06966F00000000000000F5 +:2085850052027B05A1202404A6206B055F7B05971D0020894B064B00CD91EF5B041F01AE91 +:2085A50085AD72FB015B028100000000000000005F000000000700070000147F147F140091 +:2085C500242A7F2A1200231308646200364955225000000503000000001C2241000000417B +:2085E500221C0000082A1C2A080008083E08080000503000000008080808080000606000F2 +:2086050000002010080402003E5149453E0000427F4000004261514946002141454B310015 +:208625001814127F10002745454539003C4A494930000171090503003649494936000649D8 +:2086450049291E00003636000000005636000000000814224100141414141400412214082B +:208665000000020151090600324979413E007E1111117E007F49494936003E41414122003D +:208685007F4141221C007F49494941007F09090101003E41415132007F0808087F000041CE +:2086A5007F4100002040413F01007F08142241007F40404040007F0204027F007F040810F6 +:2086C5007F003E4141413E007F09090906003E415121DE007F091929460046494949310006 +:2086E50001017F0101003F4040403F001F2040201F007F2018207F006314081463000304A3 +:208705007804030061514945430000007F41410002040810200041417F0000000402010209 +:2087250004004040404040000001020400002054545478007F4844443800384444442000AA +:20874500384444487F003854545418000008FE09020018A4A49478007F0804047800004479 +:208765007D4000004080847D0000007F1028440000417F4000007C04180478007C080404DB +:208785007800384444443800FC282424180018242428FC007C080404080048545454200020 +:2087A500043F444020003C4040207C001C2040201C003C4030403C004428102844000C5051 +:2087C50050503C004464544C440000083641000000007F000000004136080000080408108B +:2087E50008000000000000000808080808080000FF0000000000F80808080808F800000025 +:2088050000000F08080808080F0000000000FF0808080808FF0000000808F80808080808B7 +:208825000F0808080808FF0808080F0F0F0F0F0FF0F0F0F0F0F0FFFFFFFFFFFFFFFFFF00F4 +:208845000000000000FFFFFF00AA005500AA55AA55AA55AA55FF55FF55FF0000FC02040072 +:208865003C3C3C3C3C3C000018180000083840300E0124122448240000444A5100000051A6 +:208885004A44000000000000000020403F000000000609060000000D0B0000000000080071 +:2088A500000008082A08080014141414141400FF00FF00000000FC1414143855545518006D +:2088C50000F808F8080800FC04F414141414FC00000008F808F8000014F404FC0000000043 +:2088E5001F141414000F080F0808001F1017141414141F000000080F080F00001417101FA5 +:2089050000000000FF14141400FF00FF080800FF00F714141414FF0000007E4B4A4342002C +:2089250008FF00FF000014F700FF00001414F414141408F808F8080814F404F4141414146A +:2089450017141414080F080F08081417141714141414FF14141408FF08FF080814F700F780 +:2089650014143E5D55413E007C10384438002054545478003C4A4A4931007C404040FC0005 +:20898500E0544C44FC003854545418003048FC4830007C0404040C004428102844007C20C2 +:2089A50010087C007C4122117C007C102844000020443C047C007C0810087C007C101010D6 +:2089C5007C003844444438007C0404047C00085434147C007C1414140800384444442000D2 +:2089E50004047C0404000C5050503C006C107C106C007C54542800007C50502000007C50E6 +:208A050050207C004444545428007C407C407C002844545438007C407C40FC000C1010101D +:208A25007C00047C505020007F083E413E007E1111117E007F49494933007F404040FF0037 +:208A4500E0514F41FF007F49494941001C227F221C007F01010103006314081463007F10B1 +:208A650008047F007C2112097C007F081422410020413F017F007F020C027F007F0808086F +:208A85007F003E4141413E007F0101017F00462919097F007F09090906003E41414122003F +:208AA50001017F01010047281008070077087F0877007F4949493600224149493E007F4899 +:208AC50030007F004149494936007F407F407F00007F484830007F407F40FF0007080808B8 +:088AE5007F00017F48483000CA +:2080000082008083820000008200840A8200840B8200840C8200840D8200840E8200840FEA +:2080200082008410820084118200000082000000820084128200841D8200841E8200841F8B +:20804000820084208200842182008422820000008200000082008423820084248200842529 +:208060008200848082008481820084A88200000082000000820000008200000082000000BB +:1D808300AE02002707724F00005A26F9AE00132709D6966CD702005A26F7CC8080E3 +:03808000CC8B5155 +:208AED003B020FCD8DF784AE8D8389CD80AE5B02C6020FAB3088CD80A0844B0ACD80A08438 +:208B0D00813B0210CD8E1884AE8D9189CD80AE5B02AE02104B0189CD81085B034B0ACD80EB +:208B2D00A084813B0211CD8E3984AE8D9E89CD80AE5B02C60211AB3088CD80A0844B0ACD94 +:208B4D0080A0848152095F1F041F02AE7F60F6AA01AE7F60F7AE50C67FAE5345A607F7AE58 +:208B6D005346A67DF7AE5341A601F7AE5340A685F7AE500CF6AA04AE500CF7AE500DF6AA98 +:208B8D0004AE500DF7AE500FF6A4F8AE500FF7AE5011F6AA07AE5011F7AE5012F6AA07AEFE +:208BAD005012F7CD83D7CD84A99ACD8E5AAE8DAD89CD90E95B02CE020B72F0041F08C6029B +:208BCD000A12036B07C602091202CE020D905F881309909F1208909E12015B012511CE02B6 +:208BED000B1304C6020A1203C6020912022414CE020B1F04CE02091F02AE500AF6A804AEF2 +:208C0D00500AF7965C89CD80D15B024D27A87B01A12B2758A12D2603CC8C90A1482727A166 +:208C2D00542603CC8CD3A1562603CC8CA6A1682715A1692724A1742603CC8CEAA176260307 +:208C4D00CC8CBDCC8D007B0188CD80A084AE8DBB89CD80AE5B02CC8BC3AE500FF6A4F8AEE6 +:208C6D00500FF7CD84A9CD8E5ACC8BC3C6020FA1072503CC8BC3C6020F4CC7020FCD8AEDC8 +:208C8D00CC8BC3725D020F2603CC8BC3C6020F4AC7020FCD8AEDCC8BC3C60210A17F250313 +:208CAD00CC8BC3C602104CC70210CD8B0ECC8BC3725D02102603CC8BC3C602104AC70210F1 +:208CCD00CD8B0ECC8BC3C60211A1032503CC8BC3C602114CC70211CD8B30CC8BC3725D02D6 +:208CED00112603CC8BC3C602114AC70211CD8B30CC8BC37B01A12024077B0188CD83B08484 +:208D0D007B0188CD905D5B011101260BCD91087B0188CD905D5B0111012603CC8BC388414B +:208D2D007B0241895B01CD80A08484A10A2703CC8BC34B0ACD80A084CC8BC35B0981520880 +:208D4D00160B17070F060F05CE020B72FB071F03C6020A19066B02C60209190516021702AF +:208D6D0088CE020B1304C6020A1203C6020912018425ED5B08810A626961732076616C75A6 +:208D8D00653A20000A766F702076616C75653A20000A74656D702E2076616C75653A20008C +:208DAD00F7D3C5CD20D0D2C9D7C5D4210A000A50524F544F3A0A69202D20696E6974204C4C +:208DCD0043440A2B2F2D20436F6E74726173740A562F76202B2F2D20766F700A542F7420BE +:0A8DED002B2F2D2074656D700A0015 +:099675000000000001F4043C01B6 +:208DF7004B014B21CD8ED65B027B03A407AA104B0188CD8ED65B024B014B20CD8ED65B028C +:208E1700814B014B21CD8ED65B027B03A47FAA804B0188CD8ED65B024B014B20CD8ED65B04 +:208E370002814B014B21CD8ED65B027B03A403AA044B0188CD8ED65B024B014B20CD8ED635 +:208E57005B0281AE500FF6AA02AE500FF7AE500FF6AA01AE500FF7AE500FF6A4FBAE500F09 +:208E7700F74B0A4B00CD8D4B5B02AE500FF6AA04AE500FF74B014B21CD8ED65B02C6020F70 +:208E9700A407AA104B0188CD8ED65B02C60210A47FAA804B0188CD8ED65B02C60211A403ED +:208EB700AA044B0188CD8ED65B024B014B20CD8ED65B024B014B0CCD8ED65B02CC8F9EAE6E +:208ED700500FF6A4FDAE500FF7AE500FF60D042708A4FEAE500FF72006AA01AE500FF77B48 +:208EF7000388CD853E8481AE500FF6A4FDAE500FF7AE500FF60D072708A4FEAE500FF72087 +:208F170006AA01AE500FF75F891E07891E0789CD85575B06AE500FF6AA02AE500FF78152B1 +:208F3700067B09A154245D7B0AA13024577B096B050F047B0A44444441A654414272FB04C2 +:208F57001F017B0AA4076B0A0D0B271D90AE000972F90190F66B06AE91479F1B0A979EA907 +:208F77000095F61A0690F7201B90AE000972F90190F66B03AE914F9F1B0A979EA90095F60B +:208F9700140390F75B068190AE00094BF84B015F899089CD94BA5B06725F0213725F02121C +:208FB700CC8FBA4B014B80CD8ED65B024B014B40CD8ED65B02AE00094B004BF84B0189CD94 +:208FD7008EFE5B058152067B0AA10E24067B0BA10625035F206D7B09A12024035F20647B4C +:208FF7000988CD8585841F037B0A97A606429F6B0A7B0A6B060F057B0B97A6544272FB0559 +:209017001F011603AE000972FB014B064B00908989CD94D95B067B0AA47FAA804B0188CD8F +:209037008ED65B027B0BA407AA404B0188CD8ED65B024B004B064B001E0689CD8EFE5B058E +:20905700AE00015B0681C60212A10E2407C60213A10625057B03CC90E87B03A12024467B22 +:2090770003A108271BA1092726A10A2706A10D2709204AC602134CC70213725F0212203D8F +:20909700725D02122737C602124AC70212202EC6021244444848AB04A10E2405C7021220B7 +:2090B7001C7B03202CC6021295C602124CC702123B02139E887B0588CD8FDC5B03C6021255 +:2090D700A10E260C725F0212725C0213A60A20014F81881E04F64D27156B01897B0388CD3E +:2090F700905D5B01851101270620005C20E75F84815202AE00091F011E011C005416014B49 +:20911700A44B01899089CD91575B06160172A901A44B544B005F899089CD94BA5B06CD8FF6 +:20913700BA725D02132704725A02135B02810E060102040810204080FEFDFBF7EFDFBF7F84 +:02967E000000EA +:20915700521D162017051E2216201716162017141622171C16241316243E1E1472FB245AE6 +:209177001F037B03887B056B1C841E1C72FB245A1F011E011F181E181F126B107B1B6B1196 +:2091970093905A5D274D1E12F61E125A1F121E10F71E105A1F1020E87B14887B166B058409 +:2091B7001E1C1F011E011F0E6B0C7B046B0D170A160A17081E0A5A1F0A1E0827161E0EF6F4 +:2091D7006B071E0E5C1F0E1E0C7B07F71E0C5C1F0C20DD1E055B1D815210961C00131F0599 +:2091F700961C00151F03965C1F091E055C1F071E07F690971E035C1F0D1E0DF690421E09AB +:20921700FF965C1F0B1E0BF66B101E07F697160390F642416B0F411E05F697160D90F64258 +:209237009F1B0F1B101E0BF7965CFE5B1081521D1E22A300007B21A2007B20A2002F040F18 +:209257000D2004A6016B0D0D0D27151E22504F12216B1B4F12201F186B167B1B6B17200840 +:20927700162217181620171616181714161617121E26A300007B25A2007B24A2002E1E7B2E +:2092970027406B114F12266B104F12256B0F4F12246B0E1610170B160E17092008162617CD +:2092B7000B16241709160B170716091E078990891E18891E1889CD92EA5B0817010D0D278A +:2092D7000D504F120290974F12019095200216015B1D8152040F020F017B0B484F494D2687 +:2092F7002E160D1E0B905859170D1F0B1E09130D7B08120C7B07120B240D160D1E0B549066 +:2093170056170D1F0B20080C017B016B0220CA7B026B041E09130D7B08120C7B07120B25F2 +:2093370013160972F20D7B08120C977B07120B9517091F07160D1E0B549056170D1F0B7B72 +:20935700046B030A040D0326CA1E0916075B0481521E1E23A300007B22A2007B21A2002F52 +:20937700040F112004A6016B110D1127151E23504F12226B0E4F12211F076B057B0E6B0672 +:209397002008162317071621170516071714160517121E27A300007B26A2007B25A2002FBC +:2093B700040F162004A6016B160D16271E7B28406B1E4F12276B1D4F12266B1C4F12256B3E +:2093D7001B161D1719161B1717200816271719162517171619170B16171E0B8990891E181C +:2093F700891E1889CD941B5B0817017B1118164D270D504F120290974F1201909520021643 +:20941700015B1E8152125F1F051F03A6206B027B15484F496B0116171E1590585917171F34 +:20943700157B036B0F1E04887B076B1384081259090F1F047B126B067B0F6B030D01271AE7 +:209457007B06AA016B0A7B056B097B046B087B036B0716091705160717031E05131B7B043C +:20947700121A7B031219252B160572F21B7B04121A6B0C7B03121917056B037B0C6B047B50 +:2094970018AA0190977B1790957B16977B159517171F150A020D022703CC94261E1716153A +:2094B7005B1281520216051701160993905A5D270C7B081E01F71E015C1F0120EE1E055B34 +:2094D70002815208160B1701160B1E0D1F071705160F1703905A1E0327121E07F61E075CB2 +:2094F7001F071E05F71E055C1F0520E61E015B088152409096905C961C00431F0B1E0BE697 +:2095170003961C00471F151E151F171E171F3F1E3F88E60197844290FF72A900021E0BE624 +:20953700031E151F111E111F131E131F191E1988E60397844290FF965C1F1B1E1BF66B1D6D +:209557001E0BF697161590E603429F1B1D1E1BF71E1BF66B1E1E0BE60197161590E602420D +:209577009F1B1E1E1BF79096905C93FE1F1F1E0BE6011E151F211E211F231E231F251E251F +:2095970088E60397844272FB1F90FF93FE1F271E0BE6021E151F291E291F2B1E2B1F2F1E22 +:2095B7002F88E60297844272FB2790FF160B1E0BE6021E151F311E311F331E331F351E3527 +:2095D70088E6019784429F90F71E0B5C1F371E0BE60290971E15E60390421E37FF16151EE4 +:2095F7000BE6031E151F3D1E3D1F051E0588F69784429F90F71E155C1F2D1E0BE60390971A +:209617001E15E60290421E2DFF1E151C00037F1E0B1C00037F965CE6036B0AE6026B09E6D2 +:20963700016B08F61643170D164572F909173B887B09190F6B3B84190D6B39163BEF02168B +:1696570039FFFE16491E4772F93B9F193A979E193995515B4081E2 +:00000001FF