mirror of
https://github.com/eddyem/stm32samples.git
synced 2025-12-06 10:45:11 +03:00
Add Morze
This commit is contained in:
parent
d827cd385d
commit
5c5bd9468e
9
F0-nolib/Readme.md
Normal file
9
F0-nolib/Readme.md
Normal file
@ -0,0 +1,9 @@
|
||||
Samples for STM32F042-nucleo and chinese STM32F030-based devboard
|
||||
=================================
|
||||
|
||||
This directory contains examples for F0 without any library
|
||||
|
||||
- blink - simple LED blink
|
||||
- uart - USART over DMA with hardware end-of-string detection
|
||||
- uart_blink - code for STM32F030F4, echo data on USART1 and blink LEDS on PA4 and PA5
|
||||
- morze - for STM32F030, echo data from USART1 on TIM3CH1 (PA6) as Morze code
|
||||
137
F0-nolib/morze/Makefile
Normal file
137
F0-nolib/morze/Makefile
Normal file
@ -0,0 +1,137 @@
|
||||
BINARY = morze
|
||||
BOOTPORT ?= /dev/ttyUSB0
|
||||
BOOTSPEED ?= 115200
|
||||
# MCU FAMILY
|
||||
FAMILY = F0
|
||||
# MCU code
|
||||
MCU = F030x4
|
||||
DEFS = -DEBUG
|
||||
# change this linking script depending on particular MCU model,
|
||||
# for example, if you have STM32F103VBT6, you should write:
|
||||
LDSCRIPT = ld/stm32f030f.ld
|
||||
|
||||
INDEPENDENT_HEADERS=
|
||||
|
||||
FP_FLAGS ?= -msoft-float
|
||||
ASM_FLAGS = -mthumb -mcpu=cortex-m0 -march=armv6-m -mtune=cortex-m0
|
||||
ARCH_FLAGS = $(ASM_FLAGS) $(FP_FLAGS)
|
||||
|
||||
###############################################################################
|
||||
# Executables
|
||||
PREFIX ?= /opt/bin/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
|
||||
OBJDIR = mk
|
||||
LDSCRIPT ?= $(BINARY).ld
|
||||
SRC := $(wildcard *.c)
|
||||
OBJS := $(addprefix $(OBJDIR)/, $(SRC:%.c=%.o))
|
||||
STARTUP = $(OBJDIR)/startup.o
|
||||
OBJS += $(STARTUP)
|
||||
DEPS := $(OBJS:.o=.d)
|
||||
|
||||
INC_DIR ?= ../inc
|
||||
|
||||
INCLUDE := -I$(INC_DIR)/F0 -I$(INC_DIR)/cm
|
||||
LIB_DIR := $(INC_DIR)/ld
|
||||
|
||||
###############################################################################
|
||||
# C flags
|
||||
CFLAGS += -O2 -g -MD -D__thumb2__=1
|
||||
CFLAGS += -Wall -Werror -Wextra -Wshadow -Wimplicit-function-declaration
|
||||
CFLAGS += -Wredundant-decls $(INCLUDE)
|
||||
# -Wmissing-prototypes -Wstrict-prototypes
|
||||
CFLAGS += -fno-common -ffunction-sections -fdata-sections
|
||||
|
||||
###############################################################################
|
||||
# Linker flags
|
||||
LDFLAGS += --static -nostartfiles
|
||||
#--specs=nano.specs
|
||||
LDFLAGS += -L$(LIB_DIR)
|
||||
LDFLAGS += -T$(LDSCRIPT)
|
||||
LDFLAGS += -Wl,-Map=$(OBJDIR)/$(BINARY).map
|
||||
LDFLAGS += -Wl,--gc-sections
|
||||
|
||||
###############################################################################
|
||||
# Used libraries
|
||||
LDLIBS += -Wl,--start-group -lc -lgcc -Wl,--end-group
|
||||
LDLIBS += $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
|
||||
|
||||
DEFS += -DSTM32$(FAMILY) -DSTM32$(MCU)
|
||||
|
||||
#.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 list
|
||||
|
||||
elf: $(ELF)
|
||||
bin: $(BIN)
|
||||
hex: $(HEX)
|
||||
list: $(LIST)
|
||||
|
||||
ifneq ($(MAKECMDGOALS),clean)
|
||||
-include $(DEPS)
|
||||
endif
|
||||
|
||||
$(OBJDIR):
|
||||
mkdir $(OBJDIR)
|
||||
|
||||
$(STARTUP): $(INC_DIR)/startup/vector.c
|
||||
$(CC) $(CFLAGS) $(DEFS) $(INCLUDE) $(ARCH_FLAGS) -o $@ -c $<
|
||||
|
||||
$(OBJDIR)/%.o: %.c
|
||||
@echo " CC $<"
|
||||
$(CC) $(CFLAGS) $(DEFS) $(INCLUDE) $(ARCH_FLAGS) -o $@ -c $<
|
||||
|
||||
#$(OBJDIR)/%.d: %.c $(OBJDIR)
|
||||
# $(CC) -MM -MG $< | sed -e 's,^\([^:]*\)\.o[ ]*:,$(@D)/\1.o $(@D)/\1.d:,' >$@
|
||||
|
||||
$(BIN): $(ELF)
|
||||
@echo " OBJCOPY $(BIN)"
|
||||
$(OBJCOPY) -Obinary $(ELF) $(BIN)
|
||||
|
||||
$(HEX): $(ELF)
|
||||
@echo " OBJCOPY $(HEX)"
|
||||
$(OBJCOPY) -Oihex $(ELF) $(HEX)
|
||||
|
||||
$(LIST): $(ELF)
|
||||
@echo " OBJDUMP $(LIST)"
|
||||
$(OBJDUMP) -S $(ELF) > $(LIST)
|
||||
|
||||
$(ELF): $(OBJDIR) $(OBJS)
|
||||
@echo " LD $(ELF)"
|
||||
$(LD) $(LDFLAGS) $(ARCH_FLAGS) $(OBJS) $(LDLIBS) -o $(ELF)
|
||||
|
||||
clean:
|
||||
@echo " CLEAN"
|
||||
$(RM) $(OBJS) $(DEPS) $(ELF) $(HEX) $(LIST) $(OBJDIR)/*.map
|
||||
@rmdir $(OBJDIR) 2>/dev/null || true
|
||||
|
||||
|
||||
flash: $(BIN)
|
||||
@echo " FLASH $(BIN)"
|
||||
$(STFLASH) write $(BIN) 0x8000000
|
||||
|
||||
boot: $(BIN)
|
||||
@echo " LOAD $(BIN) through bootloader"
|
||||
$(STBOOT) -b$(BOOTSPEED) $(BOOTPORT) -w $(BIN)
|
||||
|
||||
.PHONY: clean flash boot
|
||||
8
F0-nolib/morze/Readme.md
Normal file
8
F0-nolib/morze/Readme.md
Normal file
@ -0,0 +1,8 @@
|
||||
Code for STM32F030F4 chinese board
|
||||
|
||||
Echo received by USART data as morze code (@ PA6, TIM3CH1)
|
||||
|
||||
USART Rx by interrupts, Tx by DMA, Morze by timer3 with DMA @ each letter
|
||||
- Toggle onboard green LED once per second.
|
||||
- Echo received by USART1 data (not more than 64 bytes including '\n') on B115200
|
||||
- Morze text by dimmer
|
||||
12
F0-nolib/morze/ld/stm32f030f.ld
Normal file
12
F0-nolib/morze/ld/stm32f030f.ld
Normal file
@ -0,0 +1,12 @@
|
||||
/* Linker script for STM32F030f4, 16K flash, 4K RAM. */
|
||||
|
||||
/* Define memory regions. */
|
||||
MEMORY
|
||||
{
|
||||
rom (rx) : ORIGIN = 0x08000000, LENGTH = 16K
|
||||
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 4K
|
||||
}
|
||||
|
||||
/* Include the common ld script. */
|
||||
INCLUDE stm32f0.ld
|
||||
|
||||
122
F0-nolib/morze/main.c
Normal file
122
F0-nolib/morze/main.c
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* main.c
|
||||
*
|
||||
* Copyright 2017 Edward V. Emelianoff <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||
*
|
||||
* 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 <string.h>
|
||||
#include "stm32f0.h"
|
||||
#include "usart.h"
|
||||
#include "morse.h"
|
||||
|
||||
volatile uint32_t Tms = 0;
|
||||
|
||||
/* Called when systick fires */
|
||||
void sys_tick_handler(void){
|
||||
++Tms;
|
||||
}
|
||||
|
||||
static void gpio_setup(void){
|
||||
/* Enable clocks to the GPIO subsystems (A&B) */
|
||||
RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
|
||||
/* Set green leds (PA4 & PA6) as output; AF1 to enable timer on PA6 */
|
||||
GPIOA->MODER = GPIO_MODER_MODER4_O | GPIO_MODER_MODER6_AF;
|
||||
GPIOA->AFR[0] |= 1<<24; // AF1
|
||||
GPIOA->OTYPER = 1 << 6; // PA6 - opendrain, PA4 - pushpull
|
||||
}
|
||||
|
||||
// Tim3_ch1 - PA6, 48MHz -> 1kHz
|
||||
static void tim3_setup(){
|
||||
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; // enable clocking
|
||||
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
|
||||
TIM3->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1; // PWM mode 1: acive->inactive, preload enable
|
||||
TIM3->PSC = 47999; // 1kHz
|
||||
TIM3->ARR = WRD_GAP;
|
||||
TIM3->CCR1 = 0;
|
||||
TIM3->CCER = TIM_CCER_CC1P | TIM_CCER_CC1E; // turn it on, active low
|
||||
TIM3->EGR |= TIM_EGR_UG;
|
||||
// DMA ch3 - TIM3_UP
|
||||
DMA1_Channel3->CPAR = (uint32_t)(&(TIM3->DMAR)); // TIM3_ch1
|
||||
DMA1_Channel3->CMAR = (uint32_t)(mbuff);
|
||||
DMA1_Channel3->CNDTR = 0;
|
||||
// memsiz 16bit, psiz 32bit, memincrement, from memory
|
||||
DMA1_Channel3->CCR |= DMA_CCR_MSIZE_0 | DMA_CCR_PSIZE_1
|
||||
| DMA_CCR_MINC | DMA_CCR_DIR;
|
||||
TIM3->DCR = (2 << 8) // three bytes
|
||||
+ (((uint32_t)&TIM3->ARR - (uint32_t)&TIM3->CR1) >> 2);
|
||||
TIM3->DIER = TIM_DIER_UDE; // enable DMA requests
|
||||
DMA1_Channel3->CCR |= DMA_CCR_TCIE; // enable TC interrupt
|
||||
}
|
||||
|
||||
char buftoping[256] = {0}, *nxtltr = buftoping;
|
||||
|
||||
int main(void){
|
||||
uint32_t lastT = 0; // last time counter value
|
||||
int L = 0; // length
|
||||
char *txt;
|
||||
sysreset();
|
||||
SysTick_Config(6000, 1);
|
||||
gpio_setup();
|
||||
tim3_setup();
|
||||
USART1_config();
|
||||
int first = 1; // first letter in phrase
|
||||
while (1){
|
||||
if(dmaflag){
|
||||
dmaflag = 0;
|
||||
if(*nxtltr){
|
||||
DMA1_Channel3->CCR &= ~DMA_CCR_EN;
|
||||
while(ALL_OK != usart1_send(nxtltr, 1));
|
||||
uint8_t x;
|
||||
nxtltr = fillbuffer(nxtltr, &x);
|
||||
if(x){
|
||||
DMA1_Channel3->CNDTR = 3 * x;
|
||||
DMA1_Channel3->CCR |= DMA_CCR_EN;
|
||||
//x += '0';
|
||||
//while(ALL_OK != usart1_send((char*)&x, 1));
|
||||
if(first){ // first letter in message
|
||||
first = 0;
|
||||
TIM3->CR1 |= TIM_CR1_CEN;
|
||||
TIM3->EGR |= TIM_EGR_UG; // force update generation
|
||||
}
|
||||
}
|
||||
}else{
|
||||
TIM3->CR1 &= ~TIM_CR1_CEN; // turn timer off
|
||||
first = 1;
|
||||
}
|
||||
}
|
||||
if(lastT > Tms || Tms - lastT > 499){
|
||||
pin_toggle(GPIOA, 1<<4); // blink by onboard LED once per second
|
||||
lastT = Tms;
|
||||
}
|
||||
if(usart1rx()){ // usart1 received data, store in in buffer
|
||||
L = usart1_getline(&txt);
|
||||
if(L < 256 && !*nxtltr){
|
||||
memcpy(buftoping, txt, L);
|
||||
buftoping[L] = 0;
|
||||
nxtltr = buftoping;
|
||||
dmaflag = 1; //
|
||||
usart1_send("Send ", 5);
|
||||
while(ALL_OK != usart1_send(txt, L));
|
||||
}else usart1_send("Please, wait\n", 13);
|
||||
}
|
||||
/* if(L){ // text waits for sending
|
||||
if(ALL_OK == usart1_send(txt, L)){
|
||||
L = 0;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
188
F0-nolib/morze/morse.c
Normal file
188
F0-nolib/morze/morse.c
Normal file
@ -0,0 +1,188 @@
|
||||
/*
|
||||
* geany_encoding=koi8-r
|
||||
* morse.c
|
||||
*
|
||||
* Copyright 2017 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||
*
|
||||
* 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 "stm32f0.h"
|
||||
#include "morse.h"
|
||||
|
||||
#define MAXPINGS (8)
|
||||
|
||||
uint16_t mbuff[3*MAXPINGS];
|
||||
/*
|
||||
32 (0x20) - 64 (0x40) - @ 96 (0x60) - ` 128 (0x80) - € 160 (0xa0) - 192 (0xc0) - À 224 (0xe0) - à
|
||||
33 (0x21) - ! 65 (0x41) - A 97 (0x61) - a 129 (0x81) - <EFBFBD> 161 (0xa1) - ¡ 193 (0xc1) - Á 225 (0xe1) - á
|
||||
34 (0x22) - " 66 (0x42) - B 98 (0x62) - b 130 (0x82) - ‚ 162 (0xa2) - ¢ 194 (0xc2) - Â 226 (0xe2) - â
|
||||
35 (0x23) - # 67 (0x43) - C 99 (0x63) - c 131 (0x83) - ƒ 163 (0xa3) - £ 195 (0xc3) - Ã 227 (0xe3) - ã
|
||||
36 (0x24) - $ 68 (0x44) - D 100 (0x64) - d 132 (0x84) - „ 164 (0xa4) - ¤ 196 (0xc4) - Ä 228 (0xe4) - ä
|
||||
37 (0x25) - % 69 (0x45) - E 101 (0x65) - e 133 (0x85) - … 165 (0xa5) - ¥ 197 (0xc5) - Å 229 (0xe5) - å
|
||||
38 (0x26) - & 70 (0x46) - F 102 (0x66) - f 134 (0x86) - † 166 (0xa6) - ¦ 198 (0xc6) - Æ 230 (0xe6) - æ
|
||||
39 (0x27) - ' 71 (0x47) - G 103 (0x67) - g 135 (0x87) - ‡ 167 (0xa7) - § 199 (0xc7) - Ç 231 (0xe7) - ç
|
||||
40 (0x28) - ( 72 (0x48) - H 104 (0x68) - h 136 (0x88) - ˆ 168 (0xa8) - ¨ 200 (0xc8) - È 232 (0xe8) - è
|
||||
41 (0x29) - ) 73 (0x49) - I 105 (0x69) - i 137 (0x89) - ‰ 169 (0xa9) - © 201 (0xc9) - É 233 (0xe9) - é
|
||||
42 (0x2a) - * 74 (0x4a) - J 106 (0x6a) - j 138 (0x8a) - Š 170 (0xaa) - ª 202 (0xca) - Ê 234 (0xea) - ê
|
||||
43 (0x2b) - + 75 (0x4b) - K 107 (0x6b) - k 139 (0x8b) - ‹ 171 (0xab) - « 203 (0xcb) - Ë 235 (0xeb) - ë
|
||||
44 (0x2c) - , 76 (0x4c) - L 108 (0x6c) - l 140 (0x8c) - Œ 172 (0xac) - ¬ 204 (0xcc) - Ì 236 (0xec) - ì
|
||||
45 (0x2d) - - 77 (0x4d) - M 109 (0x6d) - m 141 (0x8d) - <EFBFBD> 173 (0xad) - 205 (0xcd) - Í 237 (0xed) - í
|
||||
46 (0x2e) - . 78 (0x4e) - N 110 (0x6e) - n 142 (0x8e) - Ž 174 (0xae) - ® 206 (0xce) - Î 238 (0xee) - î
|
||||
47 (0x2f) - / 79 (0x4f) - O 111 (0x6f) - o 143 (0x8f) - <EFBFBD> 175 (0xaf) - ¯ 207 (0xcf) - Ï 239 (0xef) - ï
|
||||
48 (0x30) - 0 80 (0x50) - P 112 (0x70) - p 144 (0x90) - <EFBFBD> 176 (0xb0) - ° 208 (0xd0) - Ð 240 (0xf0) - ð
|
||||
49 (0x31) - 1 81 (0x51) - Q 113 (0x71) - q 145 (0x91) - ‘ 177 (0xb1) - ± 209 (0xd1) - Ñ 241 (0xf1) - ñ
|
||||
50 (0x32) - 2 82 (0x52) - R 114 (0x72) - r 146 (0x92) - ’ 178 (0xb2) - ² 210 (0xd2) - Ò 242 (0xf2) - ò
|
||||
51 (0x33) - 3 83 (0x53) - S 115 (0x73) - s 147 (0x93) - “ 179 (0xb3) - ³ 211 (0xd3) - Ó 243 (0xf3) - ó
|
||||
52 (0x34) - 4 84 (0x54) - T 116 (0x74) - t 148 (0x94) - ” 180 (0xb4) - ´ 212 (0xd4) - Ô 244 (0xf4) - ô
|
||||
53 (0x35) - 5 85 (0x55) - U 117 (0x75) - u 149 (0x95) - • 181 (0xb5) - µ 213 (0xd5) - Õ 245 (0xf5) - õ
|
||||
54 (0x36) - 6 86 (0x56) - V 118 (0x76) - v 150 (0x96) - – 182 (0xb6) - ¶ 214 (0xd6) - Ö 246 (0xf6) - ö
|
||||
55 (0x37) - 7 87 (0x57) - W 119 (0x77) - w 151 (0x97) - — 183 (0xb7) - · 215 (0xd7) - × 247 (0xf7) - ÷
|
||||
56 (0x38) - 8 88 (0x58) - X 120 (0x78) - x 152 (0x98) - ˜ 184 (0xb8) - ¸ 216 (0xd8) - Ø 248 (0xf8) - ø
|
||||
57 (0x39) - 9 89 (0x59) - Y 121 (0x79) - y 153 (0x99) - ™ 185 (0xb9) - ¹ 217 (0xd9) - Ù 249 (0xf9) - ù
|
||||
58 (0x3a) - : 90 (0x5a) - Z 122 (0x7a) - z 154 (0x9a) - š 186 (0xba) - º 218 (0xda) - Ú 250 (0xfa) - ú
|
||||
59 (0x3b) - ; 91 (0x5b) - [ 123 (0x7b) - { 155 (0x9b) - › 187 (0xbb) - » 219 (0xdb) - Û 251 (0xfb) - û
|
||||
60 (0x3c) - < 92 (0x5c) - \ 124 (0x7c) - | 156 (0x9c) - œ 188 (0xbc) - ¼ 220 (0xdc) - Ü 252 (0xfc) - ü
|
||||
61 (0x3d) - = 93 (0x5d) - ] 125 (0x7d) - } 157 (0x9d) - <EFBFBD> 189 (0xbd) - ½ 221 (0xdd) - Ý 253 (0xfd) - ý
|
||||
62 (0x3e) - > 94 (0x5e) - ^ 126 (0x7e) - ~ 158 (0x9e) - ž 190 (0xbe) - ¾ 222 (0xde) - Þ 254 (0xfe) - þ
|
||||
63 (0x3f) - ? 95 (0x5f) - _ 127 (0x7f) - 159 (0x9f) - Ÿ 191 (0xbf) - ¿ 223 (0xdf) - ß 255 (0xff) - ÿ
|
||||
*/
|
||||
// 1 - len in pings, 2 - pings (0 - dot, 1 - dash), reverse order
|
||||
static const uint8_t ascii[] = { // sarting from space+1
|
||||
6, 53, // ! -*-*--
|
||||
6, 18, // " *-**-*
|
||||
5, 29, // # [no] -*---
|
||||
7, 72, // $ ***-**-
|
||||
8, 86, // % [pc] *--*-*-*
|
||||
5, 2, // & *-***
|
||||
6, 30, // ' *----*
|
||||
5, 13, // ( -*--*
|
||||
6, 45, // ) -*--*-
|
||||
7, 40, // * [str] ***-*-*
|
||||
5, 10, // + *-*-*
|
||||
6, 51, // , --**--
|
||||
6, 33, // - -****-
|
||||
6, 42, // . *-*-*-
|
||||
5, 9, // / -**-*
|
||||
5, 31, // 0 -----
|
||||
5, 30, // 1 *----
|
||||
5, 28, // 2 **---
|
||||
5, 24, // 3 ***--
|
||||
5, 16, // 4 ****-
|
||||
5, 0, // 5 *****
|
||||
5, 1, // 6 -****
|
||||
5, 3, // 7 --***
|
||||
5, 7, // 8 ---**
|
||||
5, 15, // 9 ----*
|
||||
6, 7, // : ---***
|
||||
6, 21, // ; -*-*-*
|
||||
7, 2, // < [ls] *-*****
|
||||
5, 17, // = -***-
|
||||
6, 3, // > [gs] --****
|
||||
6, 12, // ? **--**
|
||||
6, 22, // @ *--*-*
|
||||
2, 2, // a *-
|
||||
4, 1, // b -***
|
||||
4, 5, // c -*-*
|
||||
3, 1, // d -**
|
||||
1, 0, // e *
|
||||
4, 4, // f **-*
|
||||
3, 3, // g --*
|
||||
4, 0, // h ****
|
||||
2, 0, // i **
|
||||
4, 14, // j *---
|
||||
3, 5, // k -*-
|
||||
4, 2, // l *-**
|
||||
2, 3, // m --
|
||||
2, 1, // n -*
|
||||
3, 7, // o ---
|
||||
4, 6, // p *--*
|
||||
4, 11, // q --*-
|
||||
3, 2, // r *-*
|
||||
3, 0, // s ***
|
||||
1, 1, // t -
|
||||
3, 4, // u **-
|
||||
4, 8, // v ***-
|
||||
3, 6, // w *--
|
||||
4, 9, // x -**-
|
||||
4, 13, // y -*--
|
||||
4, 3, // z --**
|
||||
5, 13, // [ [(]
|
||||
6, 40, // \ [End of work] ***-*- //
|
||||
6, 45, // ] [)]
|
||||
7, 96, // ^ [hat] *****--
|
||||
6, 44, // _ **--*-
|
||||
6, 30, // ` [']
|
||||
2, 2, // a *-
|
||||
4, 1, // b -***
|
||||
4, 5, // c -*-*
|
||||
3, 1, // d -**
|
||||
1, 0, // e *
|
||||
4, 4, // f **-*
|
||||
3, 3, // g --*
|
||||
4, 0, // h ****
|
||||
2, 0, // i **
|
||||
4, 14, // j *---
|
||||
3, 5, // k -*-
|
||||
4, 2, // l *-**
|
||||
2, 3, // m --
|
||||
2, 1, // n -*
|
||||
3, 7, // o ---
|
||||
4, 6, // p *--*
|
||||
4, 11, // q --*-
|
||||
3, 2, // r *-*
|
||||
3, 0, // s ***
|
||||
1, 1, // t -
|
||||
3, 4, // u **-
|
||||
4, 8, // v ***-
|
||||
3, 6, // w *--
|
||||
4, 9, // x -**-
|
||||
4, 13, // y -*--
|
||||
4, 3, // z --**
|
||||
5, 13, // { [(]
|
||||
6, 30, // | [']
|
||||
6, 45, // } [)]
|
||||
8, 37, // ~ [tld] -*-**-**
|
||||
};
|
||||
/*
|
||||
* I was too lazy
|
||||
static const uint8_t koi8[] = {
|
||||
|
||||
};*/
|
||||
|
||||
/**
|
||||
* return next character in word
|
||||
* @param str (i) - string to send
|
||||
* @param len (o) - length of buffer/3
|
||||
*/
|
||||
char *fillbuffer(char *str, uint8_t *len){
|
||||
const uint8_t *arr = NULL;
|
||||
char ltr = *str++;
|
||||
if(ltr > ' ' && ltr < 127){ arr = ascii; ltr -= '!'; };
|
||||
if(!arr){*len = 1; mbuff[0] = WRD_GAP+DASH_LEN; mbuff[2] = 0; return str;};
|
||||
ltr *= 2;
|
||||
uint8_t i, N = arr[(uint8_t)ltr], code = arr[(uint8_t)ltr+1];
|
||||
uint16_t *ptr = mbuff;
|
||||
for(i = 0; i < N; ++i){
|
||||
uint16_t L = DOT_LEN;
|
||||
if(code & 1) L = DASH_LEN;
|
||||
*ptr++ = L + SHRT_GAP; *ptr++ = 0; *ptr++ = L;
|
||||
code >>= 1;
|
||||
}
|
||||
ptr[-3] += LTR_GAP;
|
||||
*len = N;
|
||||
return str;
|
||||
}
|
||||
51
F0-nolib/morze/morse.h
Normal file
51
F0-nolib/morze/morse.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* geany_encoding=koi8-r
|
||||
* morse.h
|
||||
*
|
||||
* Copyright 2017 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||
*
|
||||
* 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 __MORSE_H__
|
||||
#define __MORSE_H__
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
International Morse code is composed of five elements:
|
||||
|
||||
short mark, dot or "dit" (Œ): "dot duration" is one time unit long == 50ms
|
||||
longer mark, dash or "dah" (ŒŒŒ): three time units long == 150ms
|
||||
inter-element gap between the dots and dashes within a character: one dot duration or one unit long == 50ms
|
||||
short gap (between letters): three time units long == 150ms
|
||||
medium gap (between words): seven time units long == 350ms
|
||||
*/
|
||||
// base timing (in ms)
|
||||
#define DOT_LEN (75)
|
||||
#define DASH_LEN (3*DOT_LEN)
|
||||
#define SHRT_GAP (DOT_LEN)
|
||||
// minus shr gap
|
||||
#define LTR_GAP (2*DOT_LEN)
|
||||
// minus ltr gap
|
||||
#define WRD_GAP (4*DOT_LEN)
|
||||
|
||||
extern uint16_t mbuff[];
|
||||
char *fillbuffer(char *ltr, uint8_t *len);
|
||||
|
||||
|
||||
#endif // __MORSE_H__
|
||||
BIN
F0-nolib/morze/morze.bin
Executable file
BIN
F0-nolib/morze/morze.bin
Executable file
Binary file not shown.
161
F0-nolib/morze/usart.c
Normal file
161
F0-nolib/morze/usart.c
Normal file
@ -0,0 +1,161 @@
|
||||
/*
|
||||
* usart.c
|
||||
*
|
||||
* Copyright 2017 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||
*
|
||||
* 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 "usart.h"
|
||||
#include <string.h> // memcpy
|
||||
|
||||
extern volatile uint32_t Tms;
|
||||
|
||||
static int datalen[2] = {0,0}; // received data line length (including '\n')
|
||||
|
||||
int linerdy = 0, // received data ready
|
||||
dlen = 0, // length of data (including '\n') in current buffer
|
||||
bufovr = 0, // input buffer overfull
|
||||
txrdy = 1, // transmission done
|
||||
dmaflag = 0
|
||||
;
|
||||
|
||||
static int rbufno = 0; // current rbuf number
|
||||
static char rbuf[2][UARTBUFSZ], tbuf[UARTBUFSZ]; // receive & transmit buffers
|
||||
static char *recvdata = NULL;
|
||||
|
||||
void USART1_config(){
|
||||
/* Enable the peripheral clock of GPIOA */
|
||||
RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
|
||||
/* GPIO configuration for USART1 signals */
|
||||
/* (1) Select AF mode (10) on PA9 and PA10 */
|
||||
/* (2) AF1 for USART1 signals */
|
||||
GPIOA->MODER = (GPIOA->MODER & ~(GPIO_MODER_MODER9|GPIO_MODER_MODER10))\
|
||||
| (GPIO_MODER_MODER9_1 | GPIO_MODER_MODER10_1); /* (1) */
|
||||
GPIOA->AFR[1] = (GPIOA->AFR[1] &~ (GPIO_AFRH_AFRH1 | GPIO_AFRH_AFRH2))\
|
||||
| (1 << (1 * 4)) | (1 << (2 * 4)); /* (2) */
|
||||
/* Enable the peripheral clock USART1 */
|
||||
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
|
||||
/* Configure USART1 */
|
||||
/* (1) oversampling by 16, 115200 baud */
|
||||
/* (2) 8 data bit, 1 start bit, 1 stop bit, no parity */
|
||||
USART1->BRR = 480000 / 1152; /* (1) */
|
||||
USART1->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE; /* (2) */
|
||||
/* polling idle frame Transmission */
|
||||
while(!(USART1->ISR & USART_ISR_TC)){}
|
||||
USART1->ICR |= USART_ICR_TCCF; /* clear TC flag */
|
||||
USART1->CR1 |= USART_CR1_RXNEIE; /* enable TC, TXE & RXNE interrupt */
|
||||
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
|
||||
DMA1_Channel2->CPAR = (uint32_t) &(USART1->TDR); // periph
|
||||
DMA1_Channel2->CMAR = (uint32_t) tbuf; // mem
|
||||
DMA1_Channel2->CCR |= DMA_CCR_MINC | DMA_CCR_DIR | DMA_CCR_TCIE; // 8bit, mem++, mem->per, transcompl irq
|
||||
USART1->CR3 = USART_CR3_DMAT;
|
||||
NVIC_SetPriority(DMA1_Channel2_3_IRQn, 3);
|
||||
NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);
|
||||
/* Configure IT */
|
||||
/* (3) Set priority for USART1_IRQn */
|
||||
/* (4) Enable USART1_IRQn */
|
||||
NVIC_SetPriority(USART1_IRQn, 0); /* (3) */
|
||||
NVIC_EnableIRQ(USART1_IRQn); /* (4) */
|
||||
}
|
||||
|
||||
void usart1_isr(){
|
||||
#ifdef CHECK_TMOUT
|
||||
static uint32_t tmout = 0;
|
||||
#endif
|
||||
if(USART1->ISR & USART_ISR_RXNE){ // RX not emty - receive next char
|
||||
#ifdef CHECK_TMOUT
|
||||
if(tmout && Tms >= tmout){ // set overflow flag
|
||||
bufovr = 1;
|
||||
datalen[rbufno] = 0;
|
||||
}
|
||||
tmout = Tms + TIMEOUT_MS;
|
||||
if(!tmout) tmout = 1; // prevent 0
|
||||
#endif
|
||||
// read RDR clears flag
|
||||
uint8_t rb = USART1->RDR;
|
||||
if(datalen[rbufno] < UARTBUFSZ){ // put next char into buf
|
||||
rbuf[rbufno][datalen[rbufno]++] = rb;
|
||||
if(rb == '\n'){ // got newline - line ready
|
||||
linerdy = 1;
|
||||
dlen = datalen[rbufno];
|
||||
recvdata = rbuf[rbufno];
|
||||
// prepare other buffer
|
||||
rbufno = !rbufno;
|
||||
datalen[rbufno] = 0;
|
||||
#ifdef CHECK_TMOUT
|
||||
// clear timeout at line end
|
||||
tmout = 0;
|
||||
#endif
|
||||
}
|
||||
}else{ // buffer overrun
|
||||
bufovr = 1;
|
||||
datalen[rbufno] = 0;
|
||||
#ifdef CHECK_TMOUT
|
||||
tmout = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// both timer and usart DMA
|
||||
void dma1_channel2_3_isr(){
|
||||
if(DMA1->ISR & DMA_ISR_TCIF2){ // Tx
|
||||
DMA1->IFCR |= DMA_IFCR_CTCIF2; // clear TC flag
|
||||
txrdy = 1;
|
||||
}
|
||||
if(DMA1->ISR & DMA_ISR_TCIF3){ // TIM3_UPd
|
||||
DMA1_Channel3->CCR &= ~DMA_CCR_EN;
|
||||
DMA1->IFCR |= DMA_IFCR_CTCIF3; // clear TC flag
|
||||
dmaflag = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* return length of received data (without trailing zero
|
||||
*/
|
||||
int usart1_getline(char **line){
|
||||
if(bufovr){
|
||||
bufovr = 0;
|
||||
linerdy = 0;
|
||||
return 0;
|
||||
}
|
||||
*line = recvdata;
|
||||
linerdy = 0;
|
||||
return dlen;
|
||||
}
|
||||
|
||||
TXstatus usart1_send(const char *str, int len){
|
||||
if(!txrdy) return LINE_BUSY;
|
||||
if(len > UARTBUFSZ) return STR_TOO_LONG;
|
||||
txrdy = 0;
|
||||
DMA1_Channel2->CCR &= ~DMA_CCR_EN;
|
||||
memcpy(tbuf, str, len);
|
||||
DMA1_Channel2->CNDTR = len;
|
||||
DMA1_Channel2->CCR |= DMA_CCR_EN; // start transmission
|
||||
return ALL_OK;
|
||||
}
|
||||
|
||||
TXstatus usart1_send_blocking(const char *str, int len){
|
||||
if(!txrdy) return LINE_BUSY;
|
||||
int i;
|
||||
for(i = 0; i < len; ++i){
|
||||
USART1->TDR = *str++;
|
||||
while(!(USART1->ISR & USART_ISR_TXE));
|
||||
}
|
||||
txrdy = 1;
|
||||
return ALL_OK;
|
||||
}
|
||||
51
F0-nolib/morze/usart.h
Normal file
51
F0-nolib/morze/usart.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* usart.h
|
||||
*
|
||||
* Copyright 2017 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||
*
|
||||
* 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 __USART_H__
|
||||
#define __USART_H__
|
||||
|
||||
#include "stm32f0.h"
|
||||
|
||||
// input and output buffers size
|
||||
#define UARTBUFSZ (64)
|
||||
// timeout between data bytes
|
||||
#define TIMEOUT_MS (1500)
|
||||
// check timeout
|
||||
#define CHECK_TMOUT
|
||||
|
||||
typedef enum{
|
||||
ALL_OK,
|
||||
LINE_BUSY,
|
||||
STR_TOO_LONG
|
||||
} TXstatus;
|
||||
|
||||
#define usart1rx() (linerdy)
|
||||
#define usart1ovr() (bufovr)
|
||||
|
||||
extern int linerdy, bufovr, txrdy, dmaflag;
|
||||
|
||||
void USART1_config();
|
||||
int usart1_getline(char **line);
|
||||
TXstatus usart1_send(const char *str, int len);
|
||||
TXstatus usart1_send_blocking(const char *str, int len);
|
||||
|
||||
|
||||
#endif // __USART_H__
|
||||
Loading…
x
Reference in New Issue
Block a user