From 1e27efc778f84ff027fb59a4df25e9501e333cfc Mon Sep 17 00:00:00 2001 From: eddyem Date: Wed, 20 Jan 2016 22:48:42 +0300 Subject: [PATCH] Add nokia5110 LCD support --- nokia5110/Makefile | 133 +++++++++++++++ nokia5110/cdcacm.c | 314 ++++++++++++++++++++++++++++++++++++ nokia5110/cdcacm.h | 54 +++++++ nokia5110/font.c | 260 +++++++++++++++++++++++++++++ nokia5110/font.h | 32 ++++ nokia5110/hw_init.c | 51 ++++++ nokia5110/hw_init.h | 74 +++++++++ nokia5110/ld/devices.data | 9 ++ nokia5110/ld/stm32f103x4.ld | 31 ++++ nokia5110/ld/stm32f103x6.ld | 31 ++++ nokia5110/ld/stm32f103x8.ld | 31 ++++ nokia5110/ld/stm32f103xB.ld | 31 ++++ nokia5110/ld/stm32f103xC.ld | 31 ++++ nokia5110/ld/stm32f103xD.ld | 31 ++++ nokia5110/ld/stm32f103xE.ld | 31 ++++ nokia5110/ld/stm32f103xF.ld | 31 ++++ nokia5110/ld/stm32f103xG.ld | 31 ++++ nokia5110/main.c | 107 ++++++++++++ nokia5110/main.h | 52 ++++++ nokia5110/nokia5110.bin | Bin 0 -> 9148 bytes nokia5110/pcd8544.c | 236 +++++++++++++++++++++++++++ nokia5110/pcd8544.h | 121 ++++++++++++++ nokia5110/spi.c | 175 ++++++++++++++++++++ nokia5110/spi.h | 33 ++++ nokia5110/sync.c | 93 +++++++++++ nokia5110/sync.h | 53 ++++++ nokia5110/user_proto.c | 103 ++++++++++++ nokia5110/user_proto.h | 45 ++++++ 28 files changed, 2224 insertions(+) create mode 100644 nokia5110/Makefile create mode 100644 nokia5110/cdcacm.c create mode 100644 nokia5110/cdcacm.h create mode 100644 nokia5110/font.c create mode 100644 nokia5110/font.h create mode 100644 nokia5110/hw_init.c create mode 100644 nokia5110/hw_init.h create mode 100644 nokia5110/ld/devices.data create mode 100644 nokia5110/ld/stm32f103x4.ld create mode 100644 nokia5110/ld/stm32f103x6.ld create mode 100644 nokia5110/ld/stm32f103x8.ld create mode 100644 nokia5110/ld/stm32f103xB.ld create mode 100644 nokia5110/ld/stm32f103xC.ld create mode 100644 nokia5110/ld/stm32f103xD.ld create mode 100644 nokia5110/ld/stm32f103xE.ld create mode 100644 nokia5110/ld/stm32f103xF.ld create mode 100644 nokia5110/ld/stm32f103xG.ld create mode 100644 nokia5110/main.c create mode 100644 nokia5110/main.h create mode 100755 nokia5110/nokia5110.bin create mode 100644 nokia5110/pcd8544.c create mode 100644 nokia5110/pcd8544.h create mode 100644 nokia5110/spi.c create mode 100644 nokia5110/spi.h create mode 100644 nokia5110/sync.c create mode 100644 nokia5110/sync.h create mode 100644 nokia5110/user_proto.c create mode 100644 nokia5110/user_proto.h diff --git a/nokia5110/Makefile b/nokia5110/Makefile new file mode 100644 index 0000000..2c582f9 --- /dev/null +++ b/nokia5110/Makefile @@ -0,0 +1,133 @@ +BINARY = nokia5110 +BOOTPORT ?= /dev/ttyUSB0 +BOOTSPEED ?= 115200 +# change this linking script depending on particular MCU model, +# for example, if you have STM32F103VBT6, you should write: +LDSCRIPT = ld/stm32f103x8.ld +LIBNAME = opencm3_stm32f1 +DEFS = -DSTM32F1 -DEBUG + +OBJDIR = mk +INDEPENDENT_HEADERS= + +FP_FLAGS ?= -msoft-float +ARCH_FLAGS = -mthumb -mcpu=cortex-m3 $(FP_FLAGS) -mfix-cortex-m3-ldrd + +############################################################################### +# Executables +PREFIX ?= arm-none-eabi + +RM := rm -f +RMDIR := rmdir +CC := $(PREFIX)-gcc +LD := $(PREFIX)-gcc +AR := $(PREFIX)-ar +AS := $(PREFIX)-as +OBJCOPY := $(PREFIX)-objcopy +OBJDUMP := $(PREFIX)-objdump +GDB := $(PREFIX)-gdb +STFLASH = $(shell which st-flash) +STBOOT = $(shell which stm32flash) + +############################################################################### +# Source files +LDSCRIPT ?= $(BINARY).ld +SRC = $(wildcard *.c) +OBJS = $(addprefix $(OBJDIR)/, $(SRC:%.c=%.o)) + +ifeq ($(strip $(OPENCM3_DIR)),) +OPENCM3_DIR := /usr/local/arm-none-eabi +$(info Using $(OPENCM3_DIR) path to library) +endif + +INCLUDE_DIR = $(OPENCM3_DIR)/include +LIB_DIR = $(OPENCM3_DIR)/lib +SCRIPT_DIR = $(OPENCM3_DIR)/scripts + +############################################################################### +# C flags +CFLAGS += -Os -g +CFLAGS += -Wall -Wextra -Wshadow -Wimplicit-function-declaration +CFLAGS += -Wredundant-decls +# -Wmissing-prototypes -Wstrict-prototypes +CFLAGS += -fno-common -ffunction-sections -fdata-sections + +############################################################################### +# C & C++ preprocessor common flags +CPPFLAGS += -MD +CPPFLAGS += -Wall -Werror +CPPFLAGS += -I$(INCLUDE_DIR) $(DEFS) + +############################################################################### +# Linker flags +LDFLAGS += --static -nostartfiles +LDFLAGS += -L$(LIB_DIR) +LDFLAGS += -T$(LDSCRIPT) +LDFLAGS += -Wl,-Map=$(*).map +LDFLAGS += -Wl,--gc-sections + +############################################################################### +# Used libraries +LDLIBS += -l$(LIBNAME) +LDLIBS += -Wl,--start-group -lc -lgcc -Wl,--end-group + +.SUFFIXES: .elf .bin .hex .srec .list .map .images +.SECONDEXPANSION: +.SECONDARY: + +ELF := $(OBJDIR)/$(BINARY).elf +LIST := $(OBJDIR)/$(BINARY).list +BIN := $(BINARY).bin +HEX := $(BINARY).hex + +all: bin + +elf: $(ELF) +bin: $(BIN) +hex: $(HEX) +list: $(LIST) + +$(OBJDIR): + mkdir $(OBJDIR) + +$(OBJDIR)/%.o: %.c + @printf " CC $<\n" + $(CC) $(CFLAGS) $(CPPFLAGS) $(ARCH_FLAGS) -o $@ -c $< + +$(SRC) : %.c : %.h $(INDEPENDENT_HEADERS) + @touch $@ + +%.h: ; + +$(BIN): $(ELF) + @printf " OBJCOPY $(BIN)\n" + $(OBJCOPY) -Obinary $(ELF) $(BIN) + +$(HEX): $(ELF) + @printf " OBJCOPY $(HEX)\n" + $(OBJCOPY) -Oihex $(ELF) $(HEX) + +$(LIST): $(ELF) + @printf " OBJDUMP $(LIST)\n" + $(OBJDUMP) -S $(ELF) > $(LIST) + +$(ELF): $(OBJDIR) $(OBJS) $(LDSCRIPT) $(LIB_DIR)/lib$(LIBNAME).a + @printf " LD $(ELF)\n" + $(LD) $(LDFLAGS) $(ARCH_FLAGS) $(OBJS) $(LDLIBS) -o $(ELF) + +clean: + @printf " CLEAN\n" + $(RM) $(OBJS) $(OBJDIR)/*.d $(ELF) $(HEX) $(LIST) $(OBJDIR)/*.map + $(RMDIR) $(OBJDIR) + +flash: $(BIN) + @printf " FLASH $(BIN)\n" + $(STFLASH) write $(BIN) 0x8000000 + +boot: $(BIN) + @printf " LOAD $(BIN) through bootloader\n" + $(STBOOT) -b$(BOOTSPEED) $(BOOTPORT) -w $(BIN) + +.PHONY: clean elf hex list flash boot + +#-include $(OBJS:.o=.d) diff --git a/nokia5110/cdcacm.c b/nokia5110/cdcacm.c new file mode 100644 index 0000000..6354836 --- /dev/null +++ b/nokia5110/cdcacm.c @@ -0,0 +1,314 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Gareth McMullin + * Copyright 2014 Edward V. Emelianov + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include "cdcacm.h" +#include "user_proto.h" +#include "main.h" + +// Buffer for USB Tx +static uint8_t USB_Tx_Buffer[USB_TX_DATA_SIZE]; +static uint8_t USB_Tx_ptr = 0; +// connection flag +uint8_t USB_connected = 0; +static const struct usb_device_descriptor dev = { + .bLength = USB_DT_DEVICE_SIZE, + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = 0x0200, + .bDeviceClass = USB_CLASS_CDC, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = 64, + .idVendor = 0x0483, + .idProduct = 0x5740, + .bcdDevice = 0x0200, + .iManufacturer = 1, + .iProduct = 2, + .iSerialNumber = 3, + .bNumConfigurations = 1, +}; + +char usbdatabuf[USB_RX_DATA_SIZE]; // buffer for received data +int usbdatalen = 0; // lenght of received data + +/* + * This notification endpoint isn't implemented. According to CDC spec its + * optional, but its absence causes a NULL pointer dereference in Linux + * cdc_acm driver. + */ +static const struct usb_endpoint_descriptor comm_endp[] = {{ + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x83, + .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, + .wMaxPacketSize = 16, + .bInterval = 255, +}}; + +static const struct usb_endpoint_descriptor data_endp[] = {{ + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x01, + .bmAttributes = USB_ENDPOINT_ATTR_BULK, + .wMaxPacketSize = 64, + .bInterval = 1, +}, { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x82, + .bmAttributes = USB_ENDPOINT_ATTR_BULK, + .wMaxPacketSize = 64, + .bInterval = 1, +}}; + +static const struct { + struct usb_cdc_header_descriptor header; + struct usb_cdc_call_management_descriptor call_mgmt; + struct usb_cdc_acm_descriptor acm; + struct usb_cdc_union_descriptor cdc_union; +} __attribute__((packed)) cdcacm_functional_descriptors = { + .header = { + .bFunctionLength = sizeof(struct usb_cdc_header_descriptor), + .bDescriptorType = CS_INTERFACE, + .bDescriptorSubtype = USB_CDC_TYPE_HEADER, + .bcdCDC = 0x0110, + }, + .call_mgmt = { + .bFunctionLength = + sizeof(struct usb_cdc_call_management_descriptor), + .bDescriptorType = CS_INTERFACE, + .bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT, + .bmCapabilities = 0, + .bDataInterface = 1, + }, + .acm = { + .bFunctionLength = sizeof(struct usb_cdc_acm_descriptor), + .bDescriptorType = CS_INTERFACE, + .bDescriptorSubtype = USB_CDC_TYPE_ACM, + .bmCapabilities = 0, + }, + .cdc_union = { + .bFunctionLength = sizeof(struct usb_cdc_union_descriptor), + .bDescriptorType = CS_INTERFACE, + .bDescriptorSubtype = USB_CDC_TYPE_UNION, + .bControlInterface = 0, + .bSubordinateInterface0 = 1, + }, +}; + +static const struct usb_interface_descriptor comm_iface[] = {{ + .bLength = USB_DT_INTERFACE_SIZE, + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 1, + .bInterfaceClass = USB_CLASS_CDC, + .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM, + .bInterfaceProtocol = USB_CDC_PROTOCOL_AT, + .iInterface = 0, + + .endpoint = comm_endp, + + .extra = &cdcacm_functional_descriptors, + .extralen = sizeof(cdcacm_functional_descriptors), +}}; + +static const struct usb_interface_descriptor data_iface[] = {{ + .bLength = USB_DT_INTERFACE_SIZE, + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 1, + .bAlternateSetting = 0, + .bNumEndpoints = 2, + .bInterfaceClass = USB_CLASS_DATA, + .bInterfaceSubClass = 0, + .bInterfaceProtocol = 0, + .iInterface = 0, + + .endpoint = data_endp, +}}; + +static const struct usb_interface ifaces[] = {{ + .num_altsetting = 1, + .altsetting = comm_iface, +}, { + .num_altsetting = 1, + .altsetting = data_iface, +}}; + +static const struct usb_config_descriptor config = { + .bLength = USB_DT_CONFIGURATION_SIZE, + .bDescriptorType = USB_DT_CONFIGURATION, + .wTotalLength = 0, + .bNumInterfaces = 2, + .bConfigurationValue = 1, + .iConfiguration = 0, + .bmAttributes = 0x80, + .bMaxPower = 0x32, + + .interface = ifaces, +}; + +static const char *usb_strings[] = { + "SAO RAS, Emelianov E.V.", + "Nokia 5110 control", + "0.1", +}; + +// default line coding: B115200, 1stop, 8bits, parity none +struct usb_cdc_line_coding linecoding = { + .dwDTERate = 115200, + .bCharFormat = USB_CDC_1_STOP_BITS, + .bParityType = USB_CDC_NO_PARITY, + .bDataBits = 8, +}; + +/* Buffer to be used for control requests. */ +uint8_t usbd_control_buffer[128]; + +/** + * This function runs every time it gets a request for control parameters get/set + * parameter SET_LINE_CODING used to change USART1 parameters: if you want to + * change them, just connect through USB with required parameters + */ +static int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, uint8_t **buf, + uint16_t *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)){ + (void)complete; + (void)buf; + (void)usbd_dev; + char local_buf[10]; + struct usb_cdc_line_coding lc; + + switch (req->bRequest) { + case SET_CONTROL_LINE_STATE:{ + if(req->wValue){ // terminal is opened + USB_connected = 1; + }else{ // terminal is closed + USB_connected = 0; + } + /* + * This Linux cdc_acm driver requires this to be implemented + * even though it's optional in the CDC spec, and we don't + * advertise it in the ACM functional descriptor. + */ + struct usb_cdc_notification *notif = (void *)local_buf; + /* We echo signals back to host as notification. */ + notif->bmRequestType = 0xA1; + notif->bNotification = USB_CDC_NOTIFY_SERIAL_STATE; + notif->wValue = 0; + notif->wIndex = 0; + notif->wLength = 2; + local_buf[8] = req->wValue & 3; + local_buf[9] = 0; + usbd_ep_write_packet(usbd_dev, 0x83, local_buf, 10); + }break; + case SET_LINE_CODING: + if (!len || (*len != sizeof(struct usb_cdc_line_coding))) + return 0; + memcpy((void *)&lc, (void *)*buf, *len); + // Mark & Space parity don't support by hardware, check it + if(lc.bParityType == USB_CDC_MARK_PARITY || lc.bParityType == USB_CDC_SPACE_PARITY){ + return 0; // error + }else{ +// memcpy((void *)&linecoding, (void *)&lc, sizeof(struct usb_cdc_line_coding)); +// UART_setspeed(USART1, &linecoding); + } + break; + case GET_LINE_CODING: // return linecoding buffer + if(len && *len == sizeof(struct usb_cdc_line_coding)) + memcpy((void *)*buf, (void *)&linecoding, sizeof(struct usb_cdc_line_coding)); + //usbd_ep_write_packet(usbd_dev, 0x83, (char*)&linecoding, sizeof(linecoding)); + break; + default: + return 0; + } + return 1; +} + +static void cdcacm_data_rx_cb(usbd_device *usbd_dev, uint8_t ep){ + (void)ep; + int len = usbd_ep_read_packet(usbd_dev, 0x01, usbdatabuf + usbdatalen, USB_RX_DATA_SIZE - usbdatalen); + usbdatalen += len; + if(usbdatalen >= USB_RX_DATA_SIZE){ // buffer overflow - drop all its contents + usbdatalen = 0; + } +} + +static void cdcacm_data_tx_cb(usbd_device *usbd_dev, uint8_t ep){ + (void)ep; + (void)usbd_dev; + + usb_send_buffer(); +} + +static void cdcacm_set_config(usbd_device *usbd_dev, uint16_t wValue) +{ + (void)wValue; + (void)usbd_dev; + + usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, USB_RX_DATA_SIZE, cdcacm_data_rx_cb); + usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, USB_TX_DATA_SIZE, cdcacm_data_tx_cb); + usbd_ep_setup(usbd_dev, 0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL); + + usbd_register_control_callback( + usbd_dev, + USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, + USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, + cdcacm_control_request); +} + +static usbd_device *current_usb = NULL; + +usbd_device *USB_init(){ + current_usb = usbd_init(&stm32f103_usb_driver, &dev, &config, + usb_strings, 3, usbd_control_buffer, sizeof(usbd_control_buffer)); + if(!current_usb) return NULL; + usbd_register_set_config_callback(current_usb, cdcacm_set_config); + return current_usb; +} + +mutex_t send_block_mutex = MUTEX_UNLOCKED; +/** + * Put byte into USB buffer to send + * @param byte - a byte to put into a buffer + */ +void usb_send(uint8_t byte){ + mutex_lock(&send_block_mutex); + USB_Tx_Buffer[USB_Tx_ptr++] = byte; + mutex_unlock(&send_block_mutex); + if(USB_Tx_ptr == USB_TX_DATA_SIZE){ // buffer can be overflowed - send it! + usb_send_buffer(); + } +} + +/** + * Send all data in buffer over USB + * this function runs when buffer is full or on SysTick + */ +void usb_send_buffer(){ + if(MUTEX_LOCKED == mutex_trylock(&send_block_mutex)) return; + if(USB_Tx_ptr){ + if(current_usb && USB_connected){ + // usbd_ep_write_packet return 0 if previous packet isn't transmit yet + while(USB_Tx_ptr != usbd_ep_write_packet(current_usb, 0x82, USB_Tx_Buffer, USB_Tx_ptr)); + usbd_poll(current_usb); + } + USB_Tx_ptr = 0; + } + mutex_unlock(&send_block_mutex); +} diff --git a/nokia5110/cdcacm.h b/nokia5110/cdcacm.h new file mode 100644 index 0000000..1051d83 --- /dev/null +++ b/nokia5110/cdcacm.h @@ -0,0 +1,54 @@ +/* + * ccdcacm.h + * + * 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 __CCDCACM_H__ +#define __CCDCACM_H__ + +#include + +// commands through EP0 +#define SEND_ENCAPSULATED_COMMAND 0x00 +#define GET_ENCAPSULATED_RESPONSE 0x01 +#define SET_COMM_FEATURE 0x02 +#define GET_COMM_FEATURE 0x03 +#define CLEAR_COMM_FEATURE 0x04 +#define SET_LINE_CODING 0x20 +#define GET_LINE_CODING 0x21 +#define SET_CONTROL_LINE_STATE 0x22 +#define SEND_BREAK 0x23 + +// Size of input/output buffers +#define USB_TX_DATA_SIZE 64 +#define USB_RX_DATA_SIZE 64 + +// USB connection flag +extern uint8_t USB_connected; +extern struct usb_cdc_line_coding linecoding; + +extern char usbdatabuf[]; +extern int usbdatalen; + +usbd_device *USB_init(); +void usb_send(uint8_t byte); +void usb_send_buffer(); + +#endif // __CCDCACM_H__ diff --git a/nokia5110/font.c b/nokia5110/font.c new file mode 100644 index 0000000..a43a4c7 --- /dev/null +++ b/nokia5110/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 + */ +const U8 *letter(U8 koi8){ + U16 idx; + if(koi8 < 32) koi8 = 32; + idx = (koi8 - 32) * LTR_WIDTH; + return &rusfont[idx]; +} + diff --git a/nokia5110/font.h b/nokia5110/font.h new file mode 100644 index 0000000..d92a747 --- /dev/null +++ b/nokia5110/font.h @@ -0,0 +1,32 @@ +/* + * 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 +typedef uint8_t U8; +typedef uint16_t U16; + +#define LTR_WIDTH (6) + +const U8 *letter(U8 koi8); + +#endif // __FONT_H__ diff --git a/nokia5110/hw_init.c b/nokia5110/hw_init.c new file mode 100644 index 0000000..4faaf21 --- /dev/null +++ b/nokia5110/hw_init.c @@ -0,0 +1,51 @@ +/* + * hw_init.c + * + * 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 "hw_init.h" + +/** + * GPIO initialisaion: clocking + pins setup + */ +void GPIO_init(){ + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN | + RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | + RCC_APB2ENR_IOPEEN); + // USB_DISC: push-pull + gpio_set_mode(USB_DISC_PORT, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, USB_DISC_PIN); + // USB_POWER: open drain, externall pull down with R7 (22k) + gpio_set_mode(USB_POWER_PORT, GPIO_MODE_INPUT, + GPIO_CNF_INPUT_FLOAT, USB_POWER_PIN); + // LCD pins: DC, SCE, RST + gpio_set_mode(DC_PORT, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, DC_PIN | SCE_PIN | RST_PIN); +} + +/* + * SysTick used for system timer with period of 1ms + */ +void SysTick_init(){ + systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8); // Systyck: 72/8=9MHz + systick_set_reload(8999); // 9000 pulses: 1kHz + systick_interrupt_enable(); + systick_counter_enable(); +} + + diff --git a/nokia5110/hw_init.h b/nokia5110/hw_init.h new file mode 100644 index 0000000..d09cedf --- /dev/null +++ b/nokia5110/hw_init.h @@ -0,0 +1,74 @@ +/* + * hw_init.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 __HW_INIT_H__ +#define __HW_INIT_H__ + +#include "main.h" + +/* + * USB interface + */ +// USB_DICS (disconnect) - PC11 +#define USB_DISC_PIN GPIO11 +#define USB_DISC_PORT GPIOC +// USB_POWER (high level when USB connected to PC) +#define USB_POWER_PIN GPIO10 +#define USB_POWER_PORT GPIOC +// change signal level on USB diconnect pin +#define usb_disc_high() gpio_set(USB_DISC_PORT, USB_DISC_PIN) +#define usb_disc_low() gpio_clear(USB_DISC_PORT, USB_DISC_PIN) +// in case of n-channel FET on 1.5k pull-up change on/off disconnect means low level +// in case of pnp bipolar transistor or p-channel FET on 1.5k pull-up disconnect means high level +#define usb_disconnect() usb_disc_high() +#define usb_connect() usb_disc_low() + +void GPIO_init(); +void SysTick_init(); + +/* 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 + * LCD_RST() - set 0 on RST pin + */ +/* pins: + * DC: PB6 + * SCE: PB7 + * RST: PB8 + */ +#define DC_PORT GPIOB +#define SCE_PORT GPIOB +#define RST_PORT GPIOB +#define DC_PIN GPIO6 +#define SCE_PIN GPIO7 +#define RST_PIN GPIO8 + +#define SET_DC() do{GPIO_BSRR(DC_PORT) = DC_PIN;}while(0) +#define CLEAR_DC() do{GPIO_BSRR(DC_PORT) = DC_PIN << 16;}while(0) +#define CHIP_EN() do{GPIO_BSRR(SCE_PORT) = SCE_PIN << 16;}while(0) +#define CHIP_DIS() do{GPIO_BSRR(SCE_PORT) = SCE_PIN;}while(0) +#define CLEAR_RST() do{GPIO_BSRR(RST_PORT) = RST_PIN;}while(0) +#define LCD_RST() do{GPIO_BSRR(RST_PORT) = RST_PIN << 16;}while(0) + +#endif // __HW_INIT_H__ diff --git a/nokia5110/ld/devices.data b/nokia5110/ld/devices.data new file mode 100644 index 0000000..7f29538 --- /dev/null +++ b/nokia5110/ld/devices.data @@ -0,0 +1,9 @@ +stm32f103?4* stm32f1 ROM=16K RAM=6K +stm32f103?6* stm32f1 ROM=32K RAM=10K +stm32f103?8* stm32f1 ROM=64K RAM=20K +stm32f103?b* stm32f1 ROM=128K RAM=20K +stm32f103?c* stm32f1 ROM=256K RAM=48K +stm32f103?d* stm32f1 ROM=384K RAM=64K +stm32f103?e* stm32f1 ROM=512K RAM=64K +stm32f103?f* stm32f1 ROM=768K RAM=96K +stm32f103?g* stm32f1 ROM=1024K RAM=96K diff --git a/nokia5110/ld/stm32f103x4.ld b/nokia5110/ld/stm32f103x4.ld new file mode 100644 index 0000000..efed65e --- /dev/null +++ b/nokia5110/ld/stm32f103x4.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F100x4, 16K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 16K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 6K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/nokia5110/ld/stm32f103x6.ld b/nokia5110/ld/stm32f103x6.ld new file mode 100644 index 0000000..13f05f9 --- /dev/null +++ b/nokia5110/ld/stm32f103x6.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F100x4, 16K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 32K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 10K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/nokia5110/ld/stm32f103x8.ld b/nokia5110/ld/stm32f103x8.ld new file mode 100644 index 0000000..2c4640f --- /dev/null +++ b/nokia5110/ld/stm32f103x8.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F100x4, 16K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 64K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/nokia5110/ld/stm32f103xB.ld b/nokia5110/ld/stm32f103xB.ld new file mode 100644 index 0000000..138444d --- /dev/null +++ b/nokia5110/ld/stm32f103xB.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F100x4, 16K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/nokia5110/ld/stm32f103xC.ld b/nokia5110/ld/stm32f103xC.ld new file mode 100644 index 0000000..fda76bf --- /dev/null +++ b/nokia5110/ld/stm32f103xC.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F100x4, 16K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/nokia5110/ld/stm32f103xD.ld b/nokia5110/ld/stm32f103xD.ld new file mode 100644 index 0000000..0f996c2 --- /dev/null +++ b/nokia5110/ld/stm32f103xD.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F100x4, 16K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 384K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/nokia5110/ld/stm32f103xE.ld b/nokia5110/ld/stm32f103xE.ld new file mode 100644 index 0000000..b0fcb69 --- /dev/null +++ b/nokia5110/ld/stm32f103xE.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F100x4, 16K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/nokia5110/ld/stm32f103xF.ld b/nokia5110/ld/stm32f103xF.ld new file mode 100644 index 0000000..62d47db --- /dev/null +++ b/nokia5110/ld/stm32f103xF.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F100x4, 16K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 768K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 96K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/nokia5110/ld/stm32f103xG.ld b/nokia5110/ld/stm32f103xG.ld new file mode 100644 index 0000000..0c0c968 --- /dev/null +++ b/nokia5110/ld/stm32f103xG.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F100x4, 16K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 1024K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 96K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/nokia5110/main.c b/nokia5110/main.c new file mode 100644 index 0000000..d117073 --- /dev/null +++ b/nokia5110/main.c @@ -0,0 +1,107 @@ +/* + * main.c + * + * 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. + */ + +#include "main.h" +#include "hw_init.h" +#include "spi.h" +#include "cdcacm.h" +#include "pcd8544.h" + +volatile uint32_t Timer = 0; // global timer (milliseconds) +usbd_device *usbd_dev; + +/** + * print current time in milliseconds: 4 bytes for ovrvlow + 4 bytes for time + * with ' ' as delimeter + */ +void print_time(){ + print_int(Timer); +} + + +int main(){ + uint32_t Old_timer = 0; + + // RCC clocking: 8MHz oscillator -> 72MHz system + rcc_clock_setup_in_hse_8mhz_out_72mhz(); + + GPIO_init(); + + usb_disconnect(); // turn off USB while initializing all + + // USB + usbd_dev = USB_init(); + + // SysTick is a system timer with 1ms period + SysTick_init(); + + switch_SPI(SPI1); + SPI_init(); + pcd8544_init(); + + usb_connect(); // turn on USB + + pcd8544_print((uint8_t*)" \n\nAll OK\n"); + + uint8_t wb; + int i; + while(1){ + usbd_poll(usbd_dev); + if(usbdatalen){ + for(i = 0; i < usbdatalen; ++i){ + uint8_t rb = (uint8_t)usbdatabuf[i]; + wb = pcd8544_putch(rb); + if(wb == rb){ + pcd8544_roll_screen(); + wb = pcd8544_putch(rb); + } + if(wb != rb){ + usb_send(rb); + if(wb == '\n') usb_send('\n'); + } + } + usbdatalen = 0; + } + //check_and_parce_UART(USART1); // also check data in UART buffers + if(Timer - Old_timer > 999){ // one-second cycle + Old_timer += 1000; + //print_int(Timer / 1000);newline(); + }else if(Timer < Old_timer){ // Timer overflow + Old_timer = 0; + } + } +} + + +/** + * SysTick interrupt: increment global time & send data buffer through USB + */ +void sys_tick_handler(){ + Timer++; + usbd_poll(usbd_dev); + usb_send_buffer(); +} + +// pause function, delay in ms +void Delay(uint16_t time){ + uint32_t waitto = Timer + time; + while(Timer < waitto); +} diff --git a/nokia5110/main.h b/nokia5110/main.h new file mode 100644 index 0000000..9218551 --- /dev/null +++ b/nokia5110/main.h @@ -0,0 +1,52 @@ +/* + * main.h + * + * 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 __MAIN_H__ +#define __MAIN_H__ + +#include +#include // memcpy +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sync.h" // mutexes +#include "user_proto.h" + +#define _U_ __attribute__((__unused__)) +#define U8(x) ((uint8_t) x) +#define U16(x) ((uint16_t) x) +#define U32(x) ((uint32_t) x) + +extern volatile uint32_t Timer; // global timer (milliseconds) +void Delay(uint16_t time); + +#endif // __MAIN_H__ + diff --git a/nokia5110/nokia5110.bin b/nokia5110/nokia5110.bin new file mode 100755 index 0000000000000000000000000000000000000000..76774673b705ee4848564bf2e956a29edd751c16 GIT binary patch literal 9148 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 LCxwznfu{chlnB2> literal 0 HcmV?d00001 diff --git a/nokia5110/pcd8544.c b/nokia5110/pcd8544.c new file mode 100644 index 0000000..896020a --- /dev/null +++ b/nokia5110/pcd8544.c @@ -0,0 +1,236 @@ +/* + * 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 + * LCD_RST() - set 0 on RST pin + */ +#include "hw_init.h" +#include + +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(); + Delay(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(4); + SETVOP(65); + SETTEMP(1); + // 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/nokia5110/pcd8544.h b/nokia5110/pcd8544.h new file mode 100644 index 0000000..36fbab2 --- /dev/null +++ b/nokia5110/pcd8544.h @@ -0,0 +1,121 @@ +/* + * 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" + +// 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/nokia5110/spi.c b/nokia5110/spi.c new file mode 100644 index 0000000..8d7abb2 --- /dev/null +++ b/nokia5110/spi.c @@ -0,0 +1,175 @@ +/* + * spi.c + * + * 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. + */ + +#include "main.h" +#include "spi.h" +#include "hw_init.h" + +uint32_t Current_SPI = SPI1; // this is SPI interface which would b +/** + * Set current SPI to given value + */ +void switch_SPI(uint32_t SPI){ + Current_SPI = SPI; +} + +/* + * Configure SPI ports + */ +/* + * SPI1 remapped: + * SCK - PB3 + * MISO - PB4 + * MOSI - PB5 + */ +void SPI1_init(){ + // enable AFIO & other clocking + rcc_peripheral_enable_clock(&RCC_APB2ENR, + RCC_APB2ENR_SPI1EN | RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPBEN); + // remap SPI1 (change pins from PA5..7 to PB3..5); also turn off JTAG + gpio_primary_remap(AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_OFF, AFIO_MAPR_SPI1_REMAP); + // SCK, MOSI - push-pull output + gpio_set_mode(GPIO_BANK_SPI1_RE_SCK, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_SPI1_RE_SCK); + gpio_set_mode(GPIO_BANK_SPI1_RE_MOSI, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_SPI1_RE_MOSI); + // MISO - opendrain in + gpio_set_mode(GPIO_BANK_SPI1_RE_MISO, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO_SPI1_RE_MISO); + spi_reset(SPI1); + /* Set up SPI in Master mode with: + * Clock baud rate: 1/128 of peripheral clock frequency (APB2, 72MHz) + * Clock polarity: CPOL=0, CPHA=0 + * Data frame format: 8-bit + * Frame format: MSB First + */ + spi_init_master(SPI1, SPI_CR1_BAUDRATE_FPCLK_DIV_256, SPI_CR1_CPOL_CLK_TO_0_WHEN_IDLE, + SPI_CR1_CPHA_CLK_TRANSITION_1, SPI_CR1_DFF_8BIT, SPI_CR1_MSBFIRST); + nvic_enable_irq(NVIC_SPI1_IRQ); // enable SPI interrupt + spi_enable(Current_SPI); +} + +/* + * SPI2: + * SCK - PB13 + * MISO - PB14 + * MOSI - PB15 + */ +void SPI2_init(){ + // turn on clocking + //rcc_periph_clock_enable(RCC_SPI2 | RCC_GPIOB); + rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_SPI2EN); + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPBEN); + // SCK, MOSI - push-pull output + gpio_set_mode(GPIO_BANK_SPI2_SCK, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_SPI2_SCK); + gpio_set_mode(GPIO_BANK_SPI2_MOSI, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_SPI2_MOSI); + // MISO - opendrain in + gpio_set_mode(GPIO_BANK_SPI2_MISO, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO_SPI2_MISO); + spi_reset(SPI2); + /* Set up SPI in Master mode with: + * Clock baud rate: 1/64 of peripheral clock frequency (APB1, 36MHz) + * Clock polarity: Idle High + * Clock phase: Data valid on 2nd clock pulse + * Data frame format: 8-bit + * Frame format: MSB First + */ + spi_init_master(SPI2, SPI_CR1_BAUDRATE_FPCLK_DIV_64, SPI_CR1_CPOL_CLK_TO_0_WHEN_IDLE, + SPI_CR1_CPHA_CLK_TRANSITION_1, SPI_CR1_DFF_8BIT, SPI_CR1_MSBFIRST); +// nvic_enable_irq(NVIC_SPI2_IRQ); // enable SPI interrupt + spi_enable(Current_SPI); +} + +void SPI_init(){ + switch(Current_SPI){ + case SPI1: + SPI1_init(); + break; + case SPI2: + SPI2_init(); + break; + default: + return; // error + } +} + +/** + * send 1 byte blocking + * return 1 on success + */ +uint8_t spi_write_byte(uint8_t data){ + while(!(SPI_SR(Current_SPI) & SPI_SR_TXE)); + SPI_DR(Current_SPI) = data; + while(!(SPI_SR(Current_SPI) & SPI_SR_TXE)); + while(!(SPI_SR(Current_SPI) & SPI_SR_RXNE)); + (void)SPI_DR(Current_SPI); + while(!(SPI_SR(Current_SPI) & SPI_SR_TXE)); + while(SPI_SR(Current_SPI) & SPI_SR_BSY); + return 1; +} + +/** + * Blocking rite data to current SPI + * @param data - buffer with data + * @param len - buffer length + * @return 0 in case of error (or 1 in case of success) + */ +uint8_t spiWrite(uint8_t *data, uint16_t len){ + uint16_t i; + while(!(SPI_SR(Current_SPI) & SPI_SR_TXE)); + for(i = 0; i < len; ++i){ + SPI_DR(Current_SPI) = data[i]; + while(!(SPI_SR(Current_SPI) & SPI_SR_TXE)); + } + while(!(SPI_SR(Current_SPI) & SPI_SR_RXNE)); + (void)SPI_DR(Current_SPI); + while(!(SPI_SR(Current_SPI) & SPI_SR_TXE)); + while(SPI_SR(Current_SPI) & SPI_SR_BSY); + return 1; +} + +/* +// SPI interrupt +void spi_isr(uint32_t spi){ + // TX empty + if(SPI_SR(spi) & SPI_SR_TXE){ + if(SPI_TxIndex < SPI_datalen){ // buffer still not sent fully + // Send Transaction data + SPI_DR(spi) = SPI_TxBuffer[SPI_TxIndex++]; + }else{ // disable TXE interrupt + set EOT flag + spi_disable_tx_buffer_empty_interrupt(spi); + //spi_disable(spi); + SPI_EOT_FLAG = 1; + while(SPI_SR(spi) & SPI_SR_BSY); + } + } + SPI_SR(spi) = 0; // clear all interrupt flags +} + +// interrupts for SPI1 & SPI2 +void spi1_isr(){ + spi_isr(SPI1); +} + +void spi2_isr(){ + spi_isr(SPI2); +} +*/ diff --git a/nokia5110/spi.h b/nokia5110/spi.h new file mode 100644 index 0000000..b0b2767 --- /dev/null +++ b/nokia5110/spi.h @@ -0,0 +1,33 @@ +/* + * spi.h + * + * 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 __SPI_H__ +#define __SPI_H__ + +void SPI_init(); +uint8_t spiWrite(uint8_t *data, uint16_t len); +extern uint32_t Current_SPI; +uint8_t spi_write_byte(uint8_t data); + +void switch_SPI(uint32_t SPI); + +#endif // __SPI_H__ diff --git a/nokia5110/sync.c b/nokia5110/sync.c new file mode 100644 index 0000000..ba688c3 --- /dev/null +++ b/nokia5110/sync.c @@ -0,0 +1,93 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Fergus Noble + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* + * TODO: + * implement mutexes for other type of MCU (which doesn't have strex & ldrex) + */ + +#include + +/* DMB is supported on CM0 */ +void __dmb() +{ + __asm__ volatile ("dmb"); +} + +/* Those are defined only on CM3 or CM4 */ +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) + +uint32_t __ldrex(volatile uint32_t *addr) +{ + uint32_t res; + __asm__ volatile ("ldrex %0, [%1]" : "=r" (res) : "r" (addr)); + return res; +} + +uint32_t __strex(uint32_t val, volatile uint32_t *addr) +{ + uint32_t res; + __asm__ volatile ("strex %0, %2, [%1]" + : "=&r" (res) : "r" (addr), "r" (val)); + return res; +} + +void mutex_lock(mutex_t *m) +{ + uint32_t status = 0; + + do { + /* Wait until the mutex is unlocked. */ + while (__ldrex(m) != MUTEX_UNLOCKED); + + /* Try to acquire it. */ + status = __strex(MUTEX_LOCKED, m); + + /* Did we get it? If not then try again. */ + } while (status != 0); + + /* Execute the mysterious Data Memory Barrier instruction! */ + __dmb(); +} + +void mutex_unlock(mutex_t *m) +{ + /* Ensure accesses to protected resource are finished */ + __dmb(); + + /* Free the lock. */ + *m = MUTEX_UNLOCKED; +} + +/* + * Try to lock mutex + * if it's already locked or there was error in STREX, return MUTEX_LOCKED + * else return MUTEX_UNLOCKED + */ +mutex_t mutex_trylock(mutex_t *m){ + uint32_t status = 0; + mutex_t old_lock = __ldrex(m); // get mutex value + // set mutex + status = __strex(MUTEX_LOCKED, m); + if(status == 0) __dmb(); + else old_lock = MUTEX_LOCKED; + return old_lock; +} + +#endif diff --git a/nokia5110/sync.h b/nokia5110/sync.h new file mode 100644 index 0000000..bfe837b --- /dev/null +++ b/nokia5110/sync.h @@ -0,0 +1,53 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Fergus Noble + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_CM3_SYNC_H +#define LIBOPENCM3_CM3_SYNC_H + +void __dmb(void); + +/* Implements synchronisation primitives as discussed in the ARM document + * DHT0008A (ID081709) "ARM Synchronization Primitives" and the ARM v7-M + * Architecture Reference Manual. +*/ + +/* --- Exclusive load and store instructions ------------------------------- */ + +/* Those are defined only on CM3 or CM4 */ +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) + +uint32_t __ldrex(volatile uint32_t *addr); +uint32_t __strex(uint32_t val, volatile uint32_t *addr); + +/* --- Convenience functions ----------------------------------------------- */ + +/* Here we implement some simple synchronisation primitives. */ + +typedef uint32_t mutex_t; + +#define MUTEX_UNLOCKED 0 +#define MUTEX_LOCKED 1 + +void mutex_lock(mutex_t *m); +void mutex_unlock(mutex_t *m); +mutex_t mutex_trylock(mutex_t *m); + +#endif + +#endif diff --git a/nokia5110/user_proto.c b/nokia5110/user_proto.c new file mode 100644 index 0000000..2a18b9b --- /dev/null +++ b/nokia5110/user_proto.c @@ -0,0 +1,103 @@ +/* + * user_proto.c + * + * 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. + */ + +#include "cdcacm.h" +#include "main.h" +#include "hw_init.h" +#include "pcd8544.h" + +/** + * show entered integer value + */ +uint8_t show_int(int32_t v){ + newline(); + print_int(v); + newline(); + return 0; +} + +/** + * parse command buffer when a full string comes + * return 0 if buffer processed or len if there's not enough data in buffer + */ +/* +void parse_incoming_buf(uint8_t *buf, int len){ + int curpos; + uint8_t *strbeg = buf; + for(curpos = 0; curpos < len; ++curpos){ + if(buf[curpos] == '\n'){ + buf[curpos] = 0; + pcd8544_print(strbeg); + P(strbeg); + P(" printed!\n"); + strbeg = &buf[curpos + 1]; + } + } +}*/ + +/** + * Send char array wrd thru USB or UART + */ +void prnt(uint8_t *wrd){ + if(!wrd) return; + while(*wrd) usb_send(*wrd++); +} + +/** + * Print buff as hex values + * @param buf - buffer to print + * @param l - buf length + * @param s - function to send a byte + */ +void print_hex(uint8_t *buff, uint8_t l){ + void putc(uint8_t c){ + if(c < 10) + usb_send(c + '0'); + else + usb_send(c + 'a' - 10); + } + usb_send('0'); usb_send('x'); // prefix 0x + while(l--){ + putc(buff[l] >> 4); + putc(buff[l] & 0x0f); + } +} + +/** + * Print decimal integer value + * @param N - value to print + * @param s - function to send a byte + */ +void print_int(int32_t N){ + uint8_t buf[10], L = 0; + if(N < 0){ + usb_send('-'); + N = -N; + } + if(N){ + while(N){ + buf[L++] = N % 10 + '0'; + N /= 10; + } + while(L--) usb_send(buf[L]); + }else usb_send('0'); +} + diff --git a/nokia5110/user_proto.h b/nokia5110/user_proto.h new file mode 100644 index 0000000..63059cd --- /dev/null +++ b/nokia5110/user_proto.h @@ -0,0 +1,45 @@ +/* + * user_proto.h + * + * 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 __USER_PROTO_H__ +#define __USER_PROTO_H__ + +#include "cdcacm.h" + +// shorthand for prnt +#define P(arg) do{prnt((uint8_t*)arg);}while(0) +// debug message - over USB +#ifdef EBUG + #define DBG(a) do{prnt((uint8_t*)a);}while(0) +#else + #define DBG(a) +#endif + +void prnt(uint8_t *wrd); +#define newline() usb_send('\n') + +void print_int(int32_t N); +void print_hex(uint8_t *buff, uint8_t l); + +//void parse_incoming_buf(uint8_t *buf, int len); + +#endif // __USER_PROTO_H__