mirror of
https://github.com/eddyem/stm32samples.git
synced 2025-12-06 10:45:11 +03:00
Add socket_fans schematic
This commit is contained in:
parent
d8a4c99ec7
commit
a0a7f18729
BIN
F0-nolib/CANbus_stepper/CANbus_stepper.tgz
Normal file
BIN
F0-nolib/CANbus_stepper/CANbus_stepper.tgz
Normal file
Binary file not shown.
BIN
F0-nolib/CANbus_stepper/src.tgz
Normal file
BIN
F0-nolib/CANbus_stepper/src.tgz
Normal file
Binary file not shown.
@ -244,7 +244,6 @@ void dma1_channel4_5_isr(){
|
||||
DMA1->IFCR |= DMA_IFCR_CTCIF4; // clear TC flag
|
||||
DMA1_Channel4->CCR &= ~DMA_CCR_EN;
|
||||
txrdy = 1;
|
||||
RS485_RX(); // switch to Rx
|
||||
}
|
||||
}
|
||||
// USART1
|
||||
|
||||
5
F0-nolib/Socket_fans/Readme.md
Normal file
5
F0-nolib/Socket_fans/Readme.md
Normal file
@ -0,0 +1,5 @@
|
||||
# PWM fan control
|
||||
|
||||
Control of 2 4-pin & 1 2-pin 12V fans according to 4 thermal sensors.
|
||||
Turn on/off two ~220V channels (normally opened).
|
||||
Buzzer signal.
|
||||
3
F0-nolib/Socket_fans/kicad/Readme.md
Normal file
3
F0-nolib/Socket_fans/kicad/Readme.md
Normal file
@ -0,0 +1,3 @@
|
||||
# FAN controller for electronics box
|
||||
|
||||
|
||||
22
F0-nolib/Socket_fans/kicad/acs712.lib
Normal file
22
F0-nolib/Socket_fans/kicad/acs712.lib
Normal file
@ -0,0 +1,22 @@
|
||||
EESchema-LIBRARY Version 2.3 Date: Sun 04 May 2014 09:27:50 PM MSK
|
||||
#encoding utf-8
|
||||
#
|
||||
# ACS712
|
||||
#
|
||||
DEF ACS712 U 0 40 Y Y 1 F N
|
||||
F0 "U" 0 300 60 H V C CNN
|
||||
F1 "ACS712" 0 -350 60 H V C CNN
|
||||
DRAW
|
||||
S -450 250 450 -300 0 1 0 N
|
||||
X IP+ 1 -550 150 300 R 50 50 1 1 I
|
||||
X IP+ 2 -550 50 300 R 50 50 1 1 I
|
||||
X IP- 3 -550 -100 300 R 50 50 1 1 I
|
||||
X IP- 4 -550 -200 300 R 50 50 1 1 I
|
||||
X GND 5 550 -200 300 L 50 50 1 1 I
|
||||
X FILTER 6 550 -100 300 L 50 50 1 1 I
|
||||
X VIOUT 7 550 50 300 L 50 50 1 1 I
|
||||
X Vcc 8 550 150 300 L 50 50 1 1 I
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
#End Library
|
||||
190
F0-nolib/Socket_fans/kicad/elements.lib
Normal file
190
F0-nolib/Socket_fans/kicad/elements.lib
Normal file
@ -0,0 +1,190 @@
|
||||
EESchema-LIBRARY Version 2.3
|
||||
#encoding utf-8
|
||||
#
|
||||
# 74HC4051
|
||||
#
|
||||
DEF 74HC4051 U 0 10 Y Y 1 F N
|
||||
F0 "U" 0 0 50 H V C CNN
|
||||
F1 "74HC4051" 0 -150 50 H V C CNN
|
||||
F2 "" 0 0 50 H V C CNN
|
||||
F3 "" 0 0 50 H V C CNN
|
||||
$FPLIST
|
||||
SO16
|
||||
TSSOP16
|
||||
SSOP16
|
||||
DHVQFN16
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
S -400 450 400 -450 0 1 0 N
|
||||
X Y4 1 700 -50 300 L 50 50 1 1 B
|
||||
X Y6 2 700 -250 300 L 50 50 1 1 B
|
||||
X Z 3 0 -750 300 U 50 50 1 1 B
|
||||
X Y7 4 700 -350 300 L 50 50 1 1 B
|
||||
X Y5 5 700 -150 300 L 50 50 1 1 B
|
||||
X ~E 6 -700 -350 300 R 50 50 1 1 I I
|
||||
X VEE 7 -700 0 300 R 50 50 1 1 W
|
||||
X GND 8 -700 -200 300 R 50 50 1 1 W
|
||||
X S2 9 -700 150 300 R 50 50 1 1 I
|
||||
X S1 10 -700 250 300 R 50 50 1 1 I
|
||||
X S0 11 -700 350 300 R 50 50 1 1 I
|
||||
X Y3 12 700 50 300 L 50 50 1 1 B
|
||||
X Y0 13 700 350 300 L 50 50 1 1 B
|
||||
X Y1 14 700 250 300 L 50 50 1 1 B
|
||||
X Y2 15 700 150 300 L 50 50 1 1 B
|
||||
X VCC 16 -700 -100 300 R 50 50 1 1 W
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# D_Schottky_x2_ACom_AKK
|
||||
#
|
||||
DEF D_Schottky_x2_ACom_AKK D 0 30 Y N 1 F N
|
||||
F0 "D" 50 -100 50 H V C CNN
|
||||
F1 "D_Schottky_x2_ACom_AKK" 0 100 50 H V C CNN
|
||||
F2 "" 0 0 50 H V C CNN
|
||||
F3 "" 0 0 50 H V C CNN
|
||||
DRAW
|
||||
P 2 0 1 0 -140 0 150 0 N
|
||||
P 2 0 1 0 0 0 0 -100 N
|
||||
P 3 0 1 8 -150 50 -150 -50 -150 -50 N
|
||||
P 3 0 1 8 150 50 150 -50 150 -50 N
|
||||
P 4 0 1 8 -150 50 -170 50 -170 40 -170 40 N
|
||||
P 4 0 1 8 150 -50 170 -50 170 -40 170 -40 N
|
||||
P 4 0 1 8 150 50 130 50 130 40 130 40 N
|
||||
P 5 0 1 8 -130 -40 -130 -50 -150 -50 -150 -50 -150 -50 N
|
||||
P 6 0 1 8 -50 -50 -150 0 -50 50 -50 -50 -50 -50 -50 -50 N
|
||||
P 6 0 1 8 50 50 150 0 50 -50 50 50 50 50 50 50 N
|
||||
X A 1 0 -200 100 U 50 50 0 1 P
|
||||
X K 2 -300 0 150 R 50 50 0 1 P
|
||||
X K 3 300 0 150 L 50 50 0 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# LM1117-ADJ
|
||||
#
|
||||
DEF LM1117-ADJ U 0 30 Y Y 1 F N
|
||||
F0 "U" 100 -250 50 H V C CNN
|
||||
F1 "LM1117-ADJ" 0 250 50 H V C CNN
|
||||
F2 "" 0 0 50 H V C CNN
|
||||
F3 "" 0 0 50 H V C CNN
|
||||
ALIAS LM1117-1.8 LM1117-2.5 LM1117-3.3 LM1117-5.0
|
||||
$FPLIST
|
||||
SOT-223*
|
||||
TO-263*
|
||||
TO-252*
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
S -200 -200 200 200 0 1 10 f
|
||||
X GND/ADJ 1 0 -300 100 U 50 50 1 1 W
|
||||
X VO 2 300 0 100 L 50 50 1 1 w
|
||||
X VI 3 -300 0 100 R 50 50 1 1 W
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# PESD1CAN
|
||||
#
|
||||
DEF PESD1CAN D 0 30 Y N 1 F N
|
||||
F0 "D" 0 -350 50 H V C CNN
|
||||
F1 "PESD1CAN" 50 150 50 H V C CNN
|
||||
F2 "" 0 0 50 H V C CNN
|
||||
F3 "" 0 0 50 H V C CNN
|
||||
$FPLIST
|
||||
SOT23
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
S -200 100 300 -300 0 1 0 N
|
||||
P 2 0 1 0 -140 -200 150 -200 N
|
||||
P 2 0 1 0 -140 0 150 0 N
|
||||
P 3 0 1 8 -150 -150 -150 -250 -150 -250 N
|
||||
P 3 0 1 8 -150 50 -150 -50 -150 -50 N
|
||||
P 3 0 1 8 150 -150 150 -250 150 -250 N
|
||||
P 3 0 1 8 150 50 150 -50 150 -50 N
|
||||
P 4 0 1 8 -150 -150 -170 -150 -170 -160 -170 -160 N
|
||||
P 4 0 1 8 -150 50 -170 50 -170 40 -170 40 N
|
||||
P 4 0 1 8 150 -250 170 -250 170 -240 170 -240 N
|
||||
P 4 0 1 8 150 -150 130 -150 130 -160 130 -160 N
|
||||
P 4 0 1 8 150 -50 170 -50 170 -40 170 -40 N
|
||||
P 4 0 1 0 150 0 250 0 250 -200 150 -200 N
|
||||
P 4 0 1 8 150 50 130 50 130 40 130 40 N
|
||||
P 5 0 1 8 -130 -240 -130 -250 -150 -250 -150 -250 -150 -250 N
|
||||
P 5 0 1 8 -130 -40 -130 -50 -150 -50 -150 -50 -150 -50 N
|
||||
P 6 0 1 8 -50 -250 -150 -200 -50 -150 -50 -250 -50 -250 -50 -250 N
|
||||
P 6 0 1 8 -50 -50 -150 0 -50 50 -50 -50 -50 -50 -50 -50 N
|
||||
P 6 0 1 8 50 -150 150 -200 50 -250 50 -150 50 -150 50 -150 N
|
||||
P 6 0 1 8 50 50 150 0 50 -50 50 50 50 50 50 50 N
|
||||
X K 1 -300 0 150 R 50 50 0 1 P
|
||||
X K 2 -300 -200 150 R 50 50 0 1 P
|
||||
X O 3 400 -100 150 L 50 50 0 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# TPS2051
|
||||
#
|
||||
DEF TPS2051 U 0 40 Y Y 1 F N
|
||||
F0 "U" 0 -300 60 H V C CNN
|
||||
F1 "TPS2051" 0 300 60 H V C CNN
|
||||
F2 "" 0 0 60 H I C CNN
|
||||
F3 "" 0 0 60 H I C CNN
|
||||
DRAW
|
||||
S -250 250 250 -250 0 1 0 N
|
||||
X GND 1 -450 150 200 R 50 50 1 1 W
|
||||
X IN 2 -450 50 200 R 50 50 1 1 W
|
||||
X IN 3 -450 -50 200 R 50 50 1 1 P
|
||||
X EN 4 -450 -150 200 R 50 50 1 1 I
|
||||
X ~OC 5 450 -150 200 L 50 50 1 1 O
|
||||
X OUT 6 450 -50 200 L 50 50 1 1 P
|
||||
X OUT 7 450 50 200 L 50 50 1 1 P
|
||||
X OUT 8 450 150 200 L 50 50 1 1 w
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# USB6B1
|
||||
#
|
||||
DEF USB6B1 D 0 30 Y N 1 F N
|
||||
F0 "D" 0 -450 50 H V C CNN
|
||||
F1 "USB6B1" 0 400 50 H V C CNN
|
||||
F2 "" 200 -100 50 V V C CNN
|
||||
F3 "" 200 -100 50 V V C CNN
|
||||
$FPLIST
|
||||
SO8
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
C -150 -300 7 0 1 0 N
|
||||
C -150 100 7 0 1 0 N
|
||||
C -150 300 7 0 1 0 N
|
||||
C 0 -300 7 0 1 0 N
|
||||
C 0 -100 7 0 1 0 N
|
||||
C 0 300 7 0 1 0 N
|
||||
C 200 -300 7 0 1 0 N
|
||||
C 200 300 7 0 1 0 N
|
||||
S -300 -100 300 -100 0 1 0 N
|
||||
S -300 300 300 300 0 1 0 N
|
||||
S -200 -150 -100 -150 0 1 0 N
|
||||
S -200 250 -100 250 0 1 0 N
|
||||
S -150 300 -150 -300 0 1 0 N
|
||||
S -50 -150 50 -150 0 1 0 N
|
||||
S -50 250 50 250 0 1 0 N
|
||||
S 0 300 0 -300 0 1 0 N
|
||||
S 200 300 200 -300 0 1 0 N
|
||||
S 300 -300 -300 -300 0 1 0 N
|
||||
S 300 100 -300 100 0 1 0 N
|
||||
P 3 0 1 8 150 50 250 50 250 50 N
|
||||
P 4 0 1 8 150 50 150 30 160 30 160 30 N
|
||||
P 4 0 1 8 250 50 250 70 240 70 240 70 N
|
||||
P 5 0 1 0 -250 350 300 350 300 -350 -250 -350 -250 350 N
|
||||
P 6 0 1 8 -200 -250 -150 -150 -100 -250 -200 -250 -200 -250 -200 -250 N
|
||||
P 6 0 1 8 -200 150 -150 250 -100 150 -200 150 -200 150 -200 150 N
|
||||
P 6 0 1 8 -50 -250 0 -150 50 -250 -50 -250 -50 -250 -50 -250 N
|
||||
P 6 0 1 8 -50 150 0 250 50 150 -50 150 -50 150 -50 150 N
|
||||
P 6 0 1 8 150 -50 200 50 250 -50 150 -50 150 -50 150 -50 N
|
||||
X VCC 1 -500 300 200 R 50 50 1 1 P
|
||||
X I/O1 2 -500 100 200 R 50 50 1 1 P
|
||||
X I/O2 3 -500 -100 200 R 50 50 1 1 P
|
||||
X GND 4 -500 -300 200 R 50 50 1 1 P
|
||||
X GND 5 500 -300 200 L 50 50 1 1 P
|
||||
X I/O2 6 500 -100 200 L 50 50 1 1 P
|
||||
X I/O1 7 500 100 200 L 50 50 1 1 P
|
||||
X VCC 8 500 300 200 L 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
#End Library
|
||||
2626
F0-nolib/Socket_fans/kicad/fp-info-cache
Normal file
2626
F0-nolib/Socket_fans/kicad/fp-info-cache
Normal file
File diff suppressed because it is too large
Load Diff
6
F0-nolib/Socket_fans/kicad/fp-lib-table
Normal file
6
F0-nolib/Socket_fans/kicad/fp-lib-table
Normal file
@ -0,0 +1,6 @@
|
||||
(fp_lib_table
|
||||
(lib (name TestPoint)(type KiCad)(uri ${KISYSMOD}/TestPoint.pretty)(options "")(descr ""))
|
||||
(lib (name Fuse)(type KiCad)(uri ${KISYSMOD}/Fuse.pretty)(options "")(descr ""))
|
||||
(lib (name MyFootprints)(type KiCad)(uri /home/eddy/Docs/SAO/ELECTRONICS/STM32/F0-srcs/CANbus_stepper/my_footprints.pretty)(options "")(descr ""))
|
||||
(lib (name Connector_Dsub)(type KiCad)(uri /usr/share/kicad/kicad-footprints/Connector_Dsub.pretty)(options "")(descr ""))
|
||||
)
|
||||
@ -0,0 +1,9 @@
|
||||
(module Hole_3mm (layer F.Cu) (tedit 5913F6E4)
|
||||
(fp_text reference REF** (at 0 3.81) (layer F.SilkS) hide
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
)
|
||||
(fp_text value Hole_3mm (at 0 -7.62) (layer F.Fab) hide
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
)
|
||||
(pad 1 thru_hole circle (at 0 0) (size 5 5) (drill 3) (layers *.Cu *.Mask))
|
||||
)
|
||||
@ -0,0 +1,10 @@
|
||||
(module TH_via (layer F.Cu) (tedit 5A5E619A)
|
||||
(fp_text reference REF** (at 0 0.5) (layer F.SilkS) hide
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
)
|
||||
(fp_text value TH_via (at 0 -0.5) (layer F.Fab) hide
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
)
|
||||
(pad 1 thru_hole circle (at 0 0) (size 1.5 1.5) (drill 0.8) (layers *.Cu *.Mask)
|
||||
(zone_connect 1))
|
||||
)
|
||||
307
F0-nolib/Socket_fans/kicad/stm32-rescue.lib
Normal file
307
F0-nolib/Socket_fans/kicad/stm32-rescue.lib
Normal file
@ -0,0 +1,307 @@
|
||||
EESchema-LIBRARY Version 2.4
|
||||
#encoding utf-8
|
||||
#
|
||||
# +12V-Chiller_control-rescue
|
||||
#
|
||||
DEF +12V-Chiller_control-rescue #PWR 0 0 Y Y 1 F P
|
||||
F0 "#PWR" 0 -150 50 H I C CNN
|
||||
F1 "+12V-Chiller_control-rescue" 0 140 50 H V C CNN
|
||||
F2 "" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
DRAW
|
||||
P 2 0 1 0 -30 50 0 100 N
|
||||
P 2 0 1 0 0 0 0 100 N
|
||||
P 2 0 1 0 0 100 30 50 N
|
||||
X +12V 1 0 0 0 U 50 50 1 1 W N
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# +3.3V-Chiller_control-rescue
|
||||
#
|
||||
DEF +3.3V-Chiller_control-rescue #PWR 0 0 Y Y 1 F P
|
||||
F0 "#PWR" 0 -150 50 H I C CNN
|
||||
F1 "+3.3V-Chiller_control-rescue" 0 140 50 H V C CNN
|
||||
F2 "" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
DRAW
|
||||
P 2 0 1 0 -30 50 0 100 N
|
||||
P 2 0 1 0 0 0 0 100 N
|
||||
P 2 0 1 0 0 100 30 50 N
|
||||
X +3V3 1 0 0 0 U 50 50 1 1 W N
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# C-Chiller_control-rescue
|
||||
#
|
||||
DEF C-Chiller_control-rescue C 0 10 N Y 1 F N
|
||||
F0 "C" 25 100 50 H V L CNN
|
||||
F1 "C-Chiller_control-rescue" 25 -100 50 H V L CNN
|
||||
F2 "" 38 -150 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
$FPLIST
|
||||
C_*
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
P 2 0 1 20 -80 -30 80 -30 N
|
||||
P 2 0 1 20 -80 30 80 30 N
|
||||
X ~ 1 0 150 110 D 50 50 1 1 P
|
||||
X ~ 2 0 -150 110 U 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# CP-Chiller_control-rescue
|
||||
#
|
||||
DEF CP-Chiller_control-rescue C 0 10 N Y 1 F N
|
||||
F0 "C" 25 100 50 H V L CNN
|
||||
F1 "CP-Chiller_control-rescue" 25 -100 50 H V L CNN
|
||||
F2 "" 38 -150 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
$FPLIST
|
||||
CP_*
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
S -90 20 -90 40 0 1 0 N
|
||||
S -90 20 90 20 0 1 0 N
|
||||
S 90 -20 -90 -40 0 1 0 F
|
||||
S 90 40 -90 40 0 1 0 N
|
||||
S 90 40 90 20 0 1 0 N
|
||||
P 2 0 1 0 -70 90 -30 90 N
|
||||
P 2 0 1 0 -50 110 -50 70 N
|
||||
X ~ 1 0 150 110 D 50 50 1 1 P
|
||||
X ~ 2 0 -150 110 U 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# Conn_01x02-Chiller_control-rescue
|
||||
#
|
||||
DEF Conn_01x02-Chiller_control-rescue J 0 40 Y N 1 F N
|
||||
F0 "J" 0 100 50 H V C CNN
|
||||
F1 "Conn_01x02-Chiller_control-rescue" 0 -200 50 H V C CNN
|
||||
F2 "" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
$FPLIST
|
||||
Connector*:*_??x*mm*
|
||||
Connector*:*1x??x*mm*
|
||||
Pin?Header?Straight?1X*
|
||||
Pin?Header?Angled?1X*
|
||||
Socket?Strip?Straight?1X*
|
||||
Socket?Strip?Angled?1X*
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
S -50 -95 0 -105 1 1 6 N
|
||||
S -50 5 0 -5 1 1 6 N
|
||||
S -50 50 50 -150 1 1 10 f
|
||||
X Pin_1 1 -200 0 150 R 50 50 1 1 P
|
||||
X Pin_2 2 -200 -100 150 R 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# D-Chiller_control-rescue
|
||||
#
|
||||
DEF D-Chiller_control-rescue D 0 40 N N 1 F N
|
||||
F0 "D" 0 100 50 H V C CNN
|
||||
F1 "D-Chiller_control-rescue" 0 -100 50 H V C CNN
|
||||
F2 "" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
$FPLIST
|
||||
TO-???*
|
||||
*SingleDiode
|
||||
*_Diode_*
|
||||
*SingleDiode*
|
||||
D_*
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
P 2 0 1 8 -50 50 -50 -50 N
|
||||
P 2 0 1 0 50 0 -50 0 N
|
||||
P 4 0 1 8 50 50 50 -50 -50 0 50 50 N
|
||||
X K 1 -150 0 100 R 50 50 1 1 P
|
||||
X A 2 150 0 100 L 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# G5LE-1-socket-rescue
|
||||
#
|
||||
DEF G5LE-1-socket-rescue K 0 40 Y Y 1 F N
|
||||
F0 "K" 450 150 50 H V L CNN
|
||||
F1 "G5LE-1-socket-rescue" 450 50 50 H V L CNN
|
||||
F2 "Relay_THT:Relay_SPDT_OMRON-G5LE-1" 450 -50 50 H I L CNN
|
||||
F3 "" 0 -400 50 H I C CNN
|
||||
$FPLIST
|
||||
Relay*SPDT*Omron*G5LE?1*
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
S -400 200 400 -200 0 1 10 f
|
||||
S -325 75 -75 -75 0 1 10 N
|
||||
P 2 0 0 0 100 150 100 200 N
|
||||
P 2 0 0 0 300 150 300 200 N
|
||||
P 4 0 0 0 300 150 300 100 275 125 300 150 N
|
||||
P 2 0 1 10 -300 -75 -100 75 N
|
||||
P 2 0 1 0 -200 -200 -200 -75 N
|
||||
P 2 0 1 0 -200 200 -200 75 N
|
||||
P 2 0 1 10 -75 0 -50 0 N
|
||||
P 2 0 1 10 -25 0 0 0 N
|
||||
P 2 0 1 10 25 0 50 0 N
|
||||
P 2 0 1 10 25 0 50 0 N
|
||||
P 2 0 1 10 75 0 100 0 N
|
||||
P 2 0 1 10 125 0 150 0 N
|
||||
P 2 0 1 20 200 -100 125 150 N
|
||||
P 2 0 1 0 200 -100 200 -200 N
|
||||
P 3 0 1 0 100 100 125 125 100 150 F
|
||||
X ~ 1 200 -300 100 U 50 50 1 1 P
|
||||
X ~ 2 -200 -300 100 U 50 50 1 1 P
|
||||
X ~ 3 300 300 100 D 50 50 1 1 P
|
||||
X ~ 4 100 300 100 D 50 50 1 1 P
|
||||
X ~ 5 -200 300 100 D 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# GND-Chiller_control-rescue
|
||||
#
|
||||
DEF GND-Chiller_control-rescue #PWR 0 0 Y Y 1 F P
|
||||
F0 "#PWR" 0 -250 50 H I C CNN
|
||||
F1 "GND-Chiller_control-rescue" 0 -150 50 H V C CNN
|
||||
F2 "" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
DRAW
|
||||
P 6 0 1 0 0 0 0 -50 50 -50 0 -100 -50 -50 0 -50 N
|
||||
X GND 1 0 0 0 D 50 50 1 1 W N
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# GND-socket-rescue
|
||||
#
|
||||
DEF GND-socket-rescue #PWR 0 0 Y Y 1 F P
|
||||
F0 "#PWR" 0 -250 50 H I C CNN
|
||||
F1 "GND-socket-rescue" 0 -150 50 H V C CNN
|
||||
F2 "" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
DRAW
|
||||
P 6 0 1 0 0 0 0 -50 50 -50 0 -100 -50 -50 0 -50 N
|
||||
X GND 1 0 0 0 D 50 50 1 1 W N
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# L-Chiller_control-rescue
|
||||
#
|
||||
DEF L-Chiller_control-rescue L 0 40 N N 1 F N
|
||||
F0 "L" -50 0 50 V V C CNN
|
||||
F1 "L-Chiller_control-rescue" 75 0 50 V V C CNN
|
||||
F2 "" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
$FPLIST
|
||||
Choke_*
|
||||
*Coil*
|
||||
Inductor_*
|
||||
L_*
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
A 0 -75 25 -899 899 0 1 0 N 0 -100 0 -50
|
||||
A 0 -25 25 -899 899 0 1 0 N 0 -50 0 0
|
||||
A 0 25 25 -899 899 0 1 0 N 0 0 0 50
|
||||
A 0 75 25 -899 899 0 1 0 N 0 50 0 100
|
||||
X 1 1 0 150 50 D 50 50 1 1 P
|
||||
X 2 2 0 -150 50 U 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# Q_NMOS_GSD-Chiller_control-rescue
|
||||
#
|
||||
DEF Q_NMOS_GSD-Chiller_control-rescue Q 0 0 Y N 1 F N
|
||||
F0 "Q" 200 50 50 H V L CNN
|
||||
F1 "Q_NMOS_GSD-Chiller_control-rescue" 200 -50 50 H V L CNN
|
||||
F2 "" 200 100 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
DRAW
|
||||
C 65 0 111 0 1 10 N
|
||||
C 100 -70 11 0 1 0 F
|
||||
C 100 70 11 0 1 0 F
|
||||
P 2 0 1 0 2 0 10 0 N
|
||||
P 2 0 1 0 30 -70 100 -70 N
|
||||
P 2 0 1 10 30 -50 30 -90 N
|
||||
P 2 0 1 0 30 0 100 0 N
|
||||
P 2 0 1 10 30 20 30 -20 N
|
||||
P 2 0 1 0 30 70 100 70 N
|
||||
P 2 0 1 10 30 90 30 50 N
|
||||
P 2 0 1 0 100 -70 100 -100 N
|
||||
P 2 0 1 0 100 -70 100 0 N
|
||||
P 2 0 1 0 100 100 100 70 N
|
||||
P 3 0 1 10 10 75 10 -75 10 -75 N
|
||||
P 4 0 1 0 40 0 80 15 80 -15 40 0 F
|
||||
P 4 0 1 0 100 -70 130 -70 130 70 100 70 N
|
||||
P 4 0 1 0 110 20 115 15 145 15 150 10 N
|
||||
P 4 0 1 0 130 15 115 -10 145 -10 130 15 N
|
||||
X G 1 -200 0 200 R 50 50 1 1 I
|
||||
X S 2 100 -200 100 U 50 50 1 1 P
|
||||
X D 3 100 200 100 D 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# Q_NMOS_GSD-socket-rescue
|
||||
#
|
||||
DEF Q_NMOS_GSD-socket-rescue Q 0 0 Y N 1 F N
|
||||
F0 "Q" 200 50 50 H V L CNN
|
||||
F1 "Q_NMOS_GSD-socket-rescue" 200 -50 50 H V L CNN
|
||||
F2 "" 200 100 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
DRAW
|
||||
C 65 0 111 0 1 10 N
|
||||
C 100 -70 11 0 1 0 F
|
||||
C 100 70 11 0 1 0 F
|
||||
P 2 0 1 0 2 0 10 0 N
|
||||
P 2 0 1 0 30 -70 100 -70 N
|
||||
P 2 0 1 10 30 -50 30 -90 N
|
||||
P 2 0 1 0 30 0 100 0 N
|
||||
P 2 0 1 10 30 20 30 -20 N
|
||||
P 2 0 1 0 30 70 100 70 N
|
||||
P 2 0 1 10 30 90 30 50 N
|
||||
P 2 0 1 0 100 -70 100 -100 N
|
||||
P 2 0 1 0 100 -70 100 0 N
|
||||
P 2 0 1 0 100 100 100 70 N
|
||||
P 3 0 1 10 10 75 10 -75 10 -75 N
|
||||
P 4 0 1 0 40 0 80 15 80 -15 40 0 F
|
||||
P 4 0 1 0 100 -70 130 -70 130 70 100 70 N
|
||||
P 4 0 1 0 110 20 115 15 145 15 150 10 N
|
||||
P 4 0 1 0 130 15 115 -10 145 -10 130 15 N
|
||||
X G 1 -200 0 200 R 50 50 1 1 I
|
||||
X S 2 100 -200 100 U 50 50 1 1 P
|
||||
X D 3 100 200 100 D 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# R-Chiller_control-rescue
|
||||
#
|
||||
DEF R-Chiller_control-rescue R 0 0 N Y 1 F N
|
||||
F0 "R" 80 0 50 V V C CNN
|
||||
F1 "R-Chiller_control-rescue" 0 0 50 V V C CNN
|
||||
F2 "" -70 0 50 V I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
$FPLIST
|
||||
R_*
|
||||
R_*
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
S -40 -100 40 100 0 1 10 N
|
||||
X ~ 1 0 150 50 D 50 50 1 1 P
|
||||
X ~ 2 0 -150 50 U 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# R-socket-rescue
|
||||
#
|
||||
DEF R-socket-rescue R 0 0 N Y 1 F N
|
||||
F0 "R" 80 0 50 V V C CNN
|
||||
F1 "R-socket-rescue" 0 0 50 V V C CNN
|
||||
F2 "" -70 0 50 V I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
$FPLIST
|
||||
R_*
|
||||
R_*
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
S -40 -100 40 100 0 1 10 N
|
||||
X ~ 1 0 150 50 D 50 50 1 1 P
|
||||
X ~ 2 0 -150 50 U 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
#End Library
|
||||
122
F0-nolib/Socket_fans/kicad/stm32.csv
Normal file
122
F0-nolib/Socket_fans/kicad/stm32.csv
Normal file
@ -0,0 +1,122 @@
|
||||
"Source:","/home/eddy/Yandex.Disk/Projects/stm32samples/F0-nolib/CANbus_stepper/kicad/stm32.sch"
|
||||
"Date:","÷Ô 10 ÍÁÒ 2020 09:31:14"
|
||||
"Tool:","Eeschema 5.1.4"
|
||||
"Generator:","/usr/local/share/kicad/plugins/bom_csv_grouped_by_value.py"
|
||||
"Component Count:","66"
|
||||
|
||||
"Individual Components:"
|
||||
|
||||
"Item","Qty","Reference(s)","Value","LibPart","Footprint","Datasheet"
|
||||
"","","C1","0.1","Device:C","Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
|
||||
"","","C2","100uF","Device:CP","Capacitor_THT:CP_Radial_D8.0mm_P3.50mm","~"
|
||||
"","","C3","0.1","Device:C","Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
|
||||
"","","C4","47uF, 10V","Device:CP","Capacitor_Tantalum_SMD:CP_EIA-6032-28_Kemet-C_Pad2.25x2.35mm_HandSolder","~"
|
||||
"","","C5","0.1","Device:C","Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
|
||||
"","","C6","47uF, 10V","Device:CP","Capacitor_Tantalum_SMD:CP_EIA-6032-28_Kemet-C_Pad2.25x2.35mm_HandSolder","~"
|
||||
"","","C7","0.1","Device:C","Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
|
||||
"","","C8","0.1","Device:C","Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
|
||||
"","","C9","0.1","Device:C","Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
|
||||
"","","C10","0.1","Device:C","Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
|
||||
"","","C11","0.1","Device:C","Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
|
||||
"","","C12","0.1","Device:C","Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
|
||||
"","","D1","MBRS130L","Device:D_Schottky","Diode_SMD:D_SMB_Handsoldering",""
|
||||
"","","D2","MBRS130L","Device:D_Schottky","Diode_SMD:D_SMB_Handsoldering",""
|
||||
"","","D3","PESD3V3L4UG","Power_Protection:PESD3V3L4UG","TO_SOT_Packages_SMD:SOT-363_SC-70-6_Handsoldering","https://assets.nexperia.com/documents/data-sheet/PESDXL4UF_G_W.pdf"
|
||||
"","","D4","PESD1CAN","elements:PESD1CAN","TO_SOT_Packages_SMD:SOT-23_Handsoldering",""
|
||||
"","","D5","MM3Z7V5","Device:D_Zener","Diode_SMD:D_0805_2012Metric_Pad1.15x1.40mm_HandSolder","~"
|
||||
"","","D6","USB6B1","Power_Protection:USB6B1","Package_SO:SOIC-8_3.9x4.9mm_P1.27mm",""
|
||||
"","","D7","MM3Z3V9","Device:D_Zener","Diode_SMD:D_0805_2012Metric_Pad1.15x1.40mm_HandSolder",""
|
||||
"","","D8","MM3Z3V9","Device:D_Zener","Diode_SMD:D_0805_2012Metric_Pad1.15x1.40mm_HandSolder",""
|
||||
"","","F1","1A","Device:Fuse","MyFootprints:FuseHolder","~"
|
||||
"","","J1","A","Connector:Screw_Terminal_01x02","TerminalBlock_Phoenix:TerminalBlock_Phoenix_MKDS-1,5-2_1x02_P5.00mm_Horizontal",""
|
||||
"","","J2","B","Connector:Screw_Terminal_01x02","TerminalBlock_Phoenix:TerminalBlock_Phoenix_MKDS-1,5-2_1x02_P5.00mm_Horizontal",""
|
||||
"","","J3","Conn_01x08_Female","Connector:Conn_01x08_Female","Connector_PinSocket_2.54mm:PinSocket_1x08_P2.54mm_Vertical","~"
|
||||
"","","J4","Conn_01x08_Female","Connector:Conn_01x08_Female","Connector_PinSocket_2.54mm:PinSocket_1x08_P2.54mm_Vertical","~"
|
||||
"","","J5","+/-","Connector:Screw_Terminal_01x02","TerminalBlock_Phoenix:TerminalBlock_Phoenix_MKDS-1,5-2_1x02_P5.00mm_Horizontal",""
|
||||
"","","J6","CONN_02X03","Switch:SW_DIP_x04","Button_Switch_THT:SW_DIP_SPSTx04_Slide_9.78x12.34mm_W7.62mm_P2.54mm",""
|
||||
"","","J7","0/1","Connector:Screw_Terminal_01x02","TerminalBlock_Phoenix:TerminalBlock_Phoenix_MKDS-1,5-2_1x02_P5.00mm_Horizontal",""
|
||||
"","","J8","2/3","Connector:Screw_Terminal_01x02","TerminalBlock_Phoenix:TerminalBlock_Phoenix_MKDS-1,5-2_1x02_P5.00mm_Horizontal",""
|
||||
"","","J9","DB9_Female","Connector:DB9_Female","Connector_Dsub:DSUB-9_Female_Horizontal_P2.77x2.84mm_EdgePinOffset4.94mm_Housed_MountingHolesOffset7.48mm",""
|
||||
"","","J10","12v","Connector:Screw_Terminal_01x02","TerminalBlock_Phoenix:TerminalBlock_Phoenix_MKDS-1,5-2_1x02_P5.00mm_Horizontal",""
|
||||
"","","J11","DB9_Male","Connector:DB9_Male","Connector_Dsub:DSUB-9_Male_Horizontal_P2.77x2.84mm_EdgePinOffset4.94mm_Housed_MountingHolesOffset7.48mm",""
|
||||
"","","J12","RS-485","Connector:Screw_Terminal_01x02","TerminalBlock_Phoenix:TerminalBlock_Phoenix_MKDS-1,5-2_1x02_P5.00mm_Horizontal",""
|
||||
"","","J13","Conn_01x06","Connector_Generic:Conn_01x06","Connector_PinSocket_2.54mm:PinSocket_1x06_P2.54mm_Vertical","~"
|
||||
"","","P1","USB_A","Connector:USB_B","Connectors_USB:USB_B_OST_USB-B1HSxx_Horizontal",""
|
||||
"","","P2","Hole","Connector_Generic:Conn_01x01","MountingHole:MountingHole_3.2mm_M3",""
|
||||
"","","P3","Hole","Connector_Generic:Conn_01x01","MountingHole:MountingHole_3.2mm_M3",""
|
||||
"","","P4","Hole","Connector_Generic:Conn_01x01","MountingHole:MountingHole_3.2mm_M3",""
|
||||
"","","P5","Hole","Connector_Generic:Conn_01x01","MountingHole:MountingHole_3.2mm_M3",""
|
||||
"","","Q1","SI2305","Device:Q_PMOS_GSD","TO_SOT_Packages_SMD:SOT-23_Handsoldering","~"
|
||||
"","","Q2","AO3407","Device:Q_PMOS_GSD","TO_SOT_Packages_SMD:SOT-23_Handsoldering",""
|
||||
"","","R1","330","Device:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder","~"
|
||||
"","","R2","10k","Device:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder","~"
|
||||
"","","R3","120","Device:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder","~"
|
||||
"","","R4","15k","Device:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
|
||||
"","","R5","330","Device:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder","~"
|
||||
"","","R6","330","Device:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder","~"
|
||||
"","","R7","330","Device:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder","~"
|
||||
"","","R8","330","Device:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder","~"
|
||||
"","","R9","120","Device:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
|
||||
"","","R10","10k","Device:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder","~"
|
||||
"","","R11","22","Device:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
|
||||
"","","R12","22","Device:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
|
||||
"","","R13","220k","Device:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
|
||||
"","","R14","56k","Device:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
|
||||
"","","R15","47k","Device:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
|
||||
"","","R16","47k","Device:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
|
||||
"","","R17","47k","Device:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
|
||||
"","","R18","22","Device:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder","~"
|
||||
"","","SW1","SW_DIP_x01","Switch:SW_DIP_x01","Button_Switch_THT:SW_DIP_SPSTx01_Slide_6.7x4.1mm_W7.62mm_P2.54mm_LowProfile","~"
|
||||
"","","U1","ISO1050DUB","Interface_CAN_LIN:ISO1050DUB","Package_SO:SOP-8_6.62x9.15mm_P2.54mm","http://www.ti.com/lit/ds/symlink/iso1050.pdf"
|
||||
"","","U2","LM1117-5.0","Regulator_Linear:LM1117-3.3","TO_SOT_Packages_SMD:SOT-223-3_TabPin2",""
|
||||
"","","U3","LM1117-3.3","Regulator_Linear:LM1117-3.3","TO_SOT_Packages_SMD:SOT-223-3_TabPin2",""
|
||||
"","","U4","MCP2551-I/SN","Interface_CAN_LIN:MCP2551-I-SN","Package_SO:SOIC-8_3.9x4.9mm_P1.27mm",""
|
||||
"","","U5","STM32F072CBTx","MCU_ST_STM32F0:STM32F072CBTx","Package_QFP:LQFP-48_7x7mm_P0.5mm","http://www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/DM00090510.pdf"
|
||||
"","","U6","MAX3485","Interface_UART:MAX3485","Package_SO:SO-8_3.9x4.9mm_P1.27mm","https://datasheets.maximintegrated.com/en/ds/MAX3483-MAX3491.pdf"
|
||||
|
||||
|
||||
|
||||
"Collated Components:"
|
||||
|
||||
"Item","Qty","Reference(s)","Value","LibPart","Footprint","Datasheet"
|
||||
"1","9","C1, C3, C5, C7, C8, C9, C10, C11, C12","0.1","Device:C","Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
|
||||
"2","1","C2","100uF","Device:CP","Capacitor_THT:CP_Radial_D8.0mm_P3.50mm","~"
|
||||
"3","2","C4, C6","47uF, 10V","Device:CP","Capacitor_Tantalum_SMD:CP_EIA-6032-28_Kemet-C_Pad2.25x2.35mm_HandSolder","~"
|
||||
"4","2","D1, D2","MBRS130L","Device:D_Schottky","Diode_SMD:D_SMB_Handsoldering",""
|
||||
"5","1","D3","PESD3V3L4UG","Power_Protection:PESD3V3L4UG","TO_SOT_Packages_SMD:SOT-363_SC-70-6_Handsoldering","https://assets.nexperia.com/documents/data-sheet/PESDXL4UF_G_W.pdf"
|
||||
"6","1","D4","PESD1CAN","elements:PESD1CAN","TO_SOT_Packages_SMD:SOT-23_Handsoldering",""
|
||||
"7","1","D5","MM3Z7V5","Device:D_Zener","Diode_SMD:D_0805_2012Metric_Pad1.15x1.40mm_HandSolder","~"
|
||||
"8","1","D6","USB6B1","Power_Protection:USB6B1","Package_SO:SOIC-8_3.9x4.9mm_P1.27mm",""
|
||||
"9","2","D7, D8","MM3Z3V9","Device:D_Zener","Diode_SMD:D_0805_2012Metric_Pad1.15x1.40mm_HandSolder",""
|
||||
"10","1","F1","1A","Device:Fuse","MyFootprints:FuseHolder","~"
|
||||
"11","1","J1","A","Connector:Screw_Terminal_01x02","TerminalBlock_Phoenix:TerminalBlock_Phoenix_MKDS-1,5-2_1x02_P5.00mm_Horizontal",""
|
||||
"12","1","J2","B","Connector:Screw_Terminal_01x02","TerminalBlock_Phoenix:TerminalBlock_Phoenix_MKDS-1,5-2_1x02_P5.00mm_Horizontal",""
|
||||
"13","2","J3, J4","Conn_01x08_Female","Connector:Conn_01x08_Female","Connector_PinSocket_2.54mm:PinSocket_1x08_P2.54mm_Vertical","~"
|
||||
"14","1","J5","+/-","Connector:Screw_Terminal_01x02","TerminalBlock_Phoenix:TerminalBlock_Phoenix_MKDS-1,5-2_1x02_P5.00mm_Horizontal",""
|
||||
"15","1","J6","CONN_02X03","Switch:SW_DIP_x04","Button_Switch_THT:SW_DIP_SPSTx04_Slide_9.78x12.34mm_W7.62mm_P2.54mm",""
|
||||
"16","1","J7","0/1","Connector:Screw_Terminal_01x02","TerminalBlock_Phoenix:TerminalBlock_Phoenix_MKDS-1,5-2_1x02_P5.00mm_Horizontal",""
|
||||
"17","1","J8","2/3","Connector:Screw_Terminal_01x02","TerminalBlock_Phoenix:TerminalBlock_Phoenix_MKDS-1,5-2_1x02_P5.00mm_Horizontal",""
|
||||
"18","1","J9","DB9_Female","Connector:DB9_Female","Connector_Dsub:DSUB-9_Female_Horizontal_P2.77x2.84mm_EdgePinOffset4.94mm_Housed_MountingHolesOffset7.48mm",""
|
||||
"19","1","J10","12v","Connector:Screw_Terminal_01x02","TerminalBlock_Phoenix:TerminalBlock_Phoenix_MKDS-1,5-2_1x02_P5.00mm_Horizontal",""
|
||||
"20","1","J11","DB9_Male","Connector:DB9_Male","Connector_Dsub:DSUB-9_Male_Horizontal_P2.77x2.84mm_EdgePinOffset4.94mm_Housed_MountingHolesOffset7.48mm",""
|
||||
"21","1","J12","RS-485","Connector:Screw_Terminal_01x02","TerminalBlock_Phoenix:TerminalBlock_Phoenix_MKDS-1,5-2_1x02_P5.00mm_Horizontal",""
|
||||
"22","1","J13","Conn_01x06","Connector_Generic:Conn_01x06","Connector_PinSocket_2.54mm:PinSocket_1x06_P2.54mm_Vertical","~"
|
||||
"23","1","P1","USB_A","Connector:USB_B","Connectors_USB:USB_B_OST_USB-B1HSxx_Horizontal",""
|
||||
"24","4","P2, P3, P4, P5","Hole","Connector_Generic:Conn_01x01","MountingHole:MountingHole_3.2mm_M3",""
|
||||
"25","1","Q1","SI2305","Device:Q_PMOS_GSD","TO_SOT_Packages_SMD:SOT-23_Handsoldering","~"
|
||||
"26","1","Q2","AO3407","Device:Q_PMOS_GSD","TO_SOT_Packages_SMD:SOT-23_Handsoldering",""
|
||||
"27","5","R1, R5, R6, R7, R8","330","Device:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder","~"
|
||||
"28","2","R2, R10","10k","Device:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder","~"
|
||||
"29","2","R3, R9","120","Device:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder","~"
|
||||
"30","1","R4","15k","Device:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
|
||||
"31","3","R11, R12, R18","22","Device:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder","~"
|
||||
"32","1","R13","220k","Device:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
|
||||
"33","1","R14","56k","Device:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
|
||||
"34","3","R15, R16, R17","47k","Device:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
|
||||
"35","1","SW1","SW_DIP_x01","Switch:SW_DIP_x01","Button_Switch_THT:SW_DIP_SPSTx01_Slide_6.7x4.1mm_W7.62mm_P2.54mm_LowProfile","~"
|
||||
"36","1","U1","ISO1050DUB","Interface_CAN_LIN:ISO1050DUB","Package_SO:SOP-8_6.62x9.15mm_P2.54mm","http://www.ti.com/lit/ds/symlink/iso1050.pdf"
|
||||
"37","1","U2","LM1117-5.0","Regulator_Linear:LM1117-3.3","TO_SOT_Packages_SMD:SOT-223-3_TabPin2",""
|
||||
"38","1","U3","LM1117-3.3","Regulator_Linear:LM1117-3.3","TO_SOT_Packages_SMD:SOT-223-3_TabPin2",""
|
||||
"39","1","U4","MCP2551-I/SN","Interface_CAN_LIN:MCP2551-I-SN","Package_SO:SOIC-8_3.9x4.9mm_P1.27mm",""
|
||||
"40","1","U5","STM32F072CBTx","MCU_ST_STM32F0:STM32F072CBTx","Package_QFP:LQFP-48_7x7mm_P0.5mm","http://www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/DM00090510.pdf"
|
||||
"41","1","U6","MAX3485","Interface_UART:MAX3485","Package_SO:SO-8_3.9x4.9mm_P1.27mm","https://datasheets.maximintegrated.com/en/ds/MAX3483-MAX3491.pdf"
|
||||
|
Can't render this file because it has a wrong number of fields in line 7.
|
6122
F0-nolib/Socket_fans/kicad/stm32.kicad_pcb
Normal file
6122
F0-nolib/Socket_fans/kicad/stm32.kicad_pcb
Normal file
File diff suppressed because it is too large
Load Diff
1387
F0-nolib/Socket_fans/kicad/stm32.net
Normal file
1387
F0-nolib/Socket_fans/kicad/stm32.net
Normal file
File diff suppressed because it is too large
Load Diff
276
F0-nolib/Socket_fans/kicad/stm32.pro
Normal file
276
F0-nolib/Socket_fans/kicad/stm32.pro
Normal file
@ -0,0 +1,276 @@
|
||||
update=Пн 03 фев 2020 17:18:45
|
||||
version=1
|
||||
last_client=kicad
|
||||
[cvpcb]
|
||||
version=1
|
||||
NetIExt=net
|
||||
[general]
|
||||
version=1
|
||||
[eeschema]
|
||||
version=1
|
||||
LibDir=
|
||||
[schematic_editor]
|
||||
version=1
|
||||
PageLayoutDescrFile=
|
||||
PlotDirectoryName=
|
||||
SubpartIdSeparator=46
|
||||
SubpartFirstId=49
|
||||
NetFmtName=Pcbnew
|
||||
SpiceAjustPassiveValues=0
|
||||
LabSize=50
|
||||
ERC_TestSimilarLabels=1
|
||||
[pcbnew]
|
||||
version=1
|
||||
PageLayoutDescrFile=
|
||||
LastNetListRead=stm32.net
|
||||
CopperLayerCount=2
|
||||
BoardThickness=2.5
|
||||
AllowMicroVias=0
|
||||
AllowBlindVias=0
|
||||
RequireCourtyardDefinitions=0
|
||||
ProhibitOverlappingCourtyards=1
|
||||
MinTrackWidth=0.2
|
||||
MinViaDiameter=0.7999999999999999
|
||||
MinViaDrill=0.5
|
||||
MinMicroViaDiameter=0.2
|
||||
MinMicroViaDrill=0.09999999999999999
|
||||
MinHoleToHole=0.25
|
||||
TrackWidth1=0.2
|
||||
TrackWidth2=0.2
|
||||
TrackWidth3=0.3
|
||||
TrackWidth4=0.5
|
||||
TrackWidth5=1
|
||||
TrackWidth6=2
|
||||
ViaDiameter1=1
|
||||
ViaDrill1=0.6
|
||||
ViaDiameter2=1
|
||||
ViaDrill2=0.6
|
||||
ViaDiameter3=1.5
|
||||
ViaDrill3=0.8
|
||||
dPairWidth1=0.2
|
||||
dPairGap1=0.25
|
||||
dPairViaGap1=0.25
|
||||
SilkLineWidth=0.15
|
||||
SilkTextSizeV=1
|
||||
SilkTextSizeH=1
|
||||
SilkTextSizeThickness=0.15
|
||||
SilkTextItalic=0
|
||||
SilkTextUpright=1
|
||||
CopperLineWidth=0.2
|
||||
CopperTextSizeV=1.5
|
||||
CopperTextSizeH=1.5
|
||||
CopperTextThickness=0.3
|
||||
CopperTextItalic=0
|
||||
CopperTextUpright=1
|
||||
EdgeCutLineWidth=0.15
|
||||
CourtyardLineWidth=0.05
|
||||
OthersLineWidth=0.15
|
||||
OthersTextSizeV=1
|
||||
OthersTextSizeH=1
|
||||
OthersTextSizeThickness=0.15
|
||||
OthersTextItalic=0
|
||||
OthersTextUpright=1
|
||||
SolderMaskClearance=0.2
|
||||
SolderMaskMinWidth=0
|
||||
SolderPasteClearance=0
|
||||
SolderPasteRatio=-0
|
||||
[pcbnew/Layer.F.Cu]
|
||||
Name=F.Cu
|
||||
Type=0
|
||||
Enabled=1
|
||||
[pcbnew/Layer.In1.Cu]
|
||||
Name=In1.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In2.Cu]
|
||||
Name=In2.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In3.Cu]
|
||||
Name=In3.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In4.Cu]
|
||||
Name=In4.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In5.Cu]
|
||||
Name=In5.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In6.Cu]
|
||||
Name=In6.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In7.Cu]
|
||||
Name=In7.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In8.Cu]
|
||||
Name=In8.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In9.Cu]
|
||||
Name=In9.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In10.Cu]
|
||||
Name=In10.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In11.Cu]
|
||||
Name=In11.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In12.Cu]
|
||||
Name=In12.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In13.Cu]
|
||||
Name=In13.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In14.Cu]
|
||||
Name=In14.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In15.Cu]
|
||||
Name=In15.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In16.Cu]
|
||||
Name=In16.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In17.Cu]
|
||||
Name=In17.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In18.Cu]
|
||||
Name=In18.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In19.Cu]
|
||||
Name=In19.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In20.Cu]
|
||||
Name=In20.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In21.Cu]
|
||||
Name=In21.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In22.Cu]
|
||||
Name=In22.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In23.Cu]
|
||||
Name=In23.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In24.Cu]
|
||||
Name=In24.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In25.Cu]
|
||||
Name=In25.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In26.Cu]
|
||||
Name=In26.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In27.Cu]
|
||||
Name=In27.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In28.Cu]
|
||||
Name=In28.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In29.Cu]
|
||||
Name=In29.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In30.Cu]
|
||||
Name=In30.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.B.Cu]
|
||||
Name=B.Cu
|
||||
Type=0
|
||||
Enabled=1
|
||||
[pcbnew/Layer.B.Adhes]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.F.Adhes]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.B.Paste]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.F.Paste]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.B.SilkS]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.F.SilkS]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.B.Mask]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.F.Mask]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.Dwgs.User]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.Cmts.User]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.Eco1.User]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.Eco2.User]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.Edge.Cuts]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.Margin]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.B.CrtYd]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.F.CrtYd]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.B.Fab]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.F.Fab]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.Rescue]
|
||||
Enabled=0
|
||||
[pcbnew/Netclasses]
|
||||
[pcbnew/Netclasses/Default]
|
||||
Name=Default
|
||||
Clearance=0.2
|
||||
TrackWidth=0.2
|
||||
ViaDiameter=1
|
||||
ViaDrill=0.6
|
||||
uViaDiameter=0.3
|
||||
uViaDrill=0.1
|
||||
dPairWidth=0.2
|
||||
dPairGap=0.25
|
||||
dPairViaGap=0.25
|
||||
[pcbnew/Netclasses/1]
|
||||
Name=0.5
|
||||
Clearance=0.3
|
||||
TrackWidth=0.5
|
||||
ViaDiameter=1
|
||||
ViaDrill=0.6
|
||||
uViaDiameter=0.3
|
||||
uViaDrill=0.1
|
||||
dPairWidth=0.2
|
||||
dPairGap=0.25
|
||||
dPairViaGap=0.25
|
||||
[pcbnew/Netclasses/2]
|
||||
Name=1
|
||||
Clearance=0.5
|
||||
TrackWidth=1
|
||||
ViaDiameter=1.5
|
||||
ViaDrill=0.8
|
||||
uViaDiameter=0.3
|
||||
uViaDrill=0.1
|
||||
dPairWidth=0.2
|
||||
dPairGap=0.25
|
||||
dPairViaGap=0.25
|
||||
2161
F0-nolib/Socket_fans/kicad/stm32.sch
Normal file
2161
F0-nolib/Socket_fans/kicad/stm32.sch
Normal file
File diff suppressed because it is too large
Load Diff
4
F0-nolib/Socket_fans/kicad/sym-lib-table
Normal file
4
F0-nolib/Socket_fans/kicad/sym-lib-table
Normal file
@ -0,0 +1,4 @@
|
||||
(sym_lib_table
|
||||
(lib (name elements)(type Legacy)(uri ${KIPRJMOD}/elements.lib)(options "")(descr ""))
|
||||
(lib (name stm32-rescue)(type Legacy)(uri ${KIPRJMOD}/stm32-rescue.lib)(options "")(descr ""))
|
||||
)
|
||||
49
F1-nolib/BUGS
Normal file
49
F1-nolib/BUGS
Normal file
@ -0,0 +1,49 @@
|
||||
1. Непонимание что такое "атомарный доступ" и для чего нужно "volatile" при совместной работе разных процессов/ISR с одними данными.
|
||||
|
||||
Смотрим например на usart2_getline() вызывающуюся в фоне и usart2_isr() (видимо - ISR), и думаем что будет если прерывание usart2_isr() произойдёт между строкой
|
||||
|
||||
int L = linerdy;
|
||||
|
||||
и строкой
|
||||
|
||||
linerdy = 0;
|
||||
|
||||
|
||||
|
||||
2. Алгоритм работы с приёмным потоком UART - в корне ущербный. Достаточно подумать, что будет если на большой скорости UART два символа '\n' подряд и в это время фоновая задача будет занята какой-то более-менее длительной работой (а ведь мы знаем что автор сего - ненавистник РТОС, и у него не будет повышен приоритет задаче, разгребающей UART-RX поток ;).
|
||||
|
||||
|
||||
|
||||
3. Инициализация UART (usart2_setup()) - кривая. Сначала автор программирует DMA на работу с UART, включает его, и только затем включает тактирование UART и инициализирует его.
|
||||
|
||||
Также - мультиплексор пинов переключает ноги с GPIO на UART ещё до инициализации самого UART (глитчи обеспечены).
|
||||
|
||||
Правильный порядок: 1) инит DMA; 2) инит UART; 3) разрешение DMA; 4) разрешение прерываний; 5) переключение мультиплексора ног GPIO->UART. И не забывать использовать __DMB() где надо.
|
||||
|
||||
|
||||
|
||||
4. Зачем в main() такое?:
|
||||
|
||||
const char dummy[] = "dummy text\n", err[] = "Error!\n";
|
||||
|
||||
Видимо чтобы получить как можно более тяжёлый код и занять побольше стека. Автор видимо не знает для чего нужно "static". :unknw:
|
||||
|
||||
|
||||
|
||||
5. Автор не читает мануал на используемый МК. Если бы читал, не писал бы такое:
|
||||
|
||||
USART2_ICR |= USART_ISR_CMF; // clear flag
|
||||
|
||||
Читаем описание регистра USART2_ICR и думаем: Что будет с остальными флагами кроме CMF после такой операции? Да и вообще - зачем читать из регистра если для сброса флага нужна запись в него "1"??? Тема эта уже 100500 раз обсасывалась здесь на форуме.
|
||||
|
||||
То же самое здесь:
|
||||
|
||||
DMA1_IFCR |= DMA_IFCR_CIF4; // clear TC flag
|
||||
|
||||
и в других подобных местах. Регистр DMA1_IFCR - write-only! Опять же - RTFM.
|
||||
|
||||
Наверняка ещё куча подобных багов есть - смотрел по диагонали.
|
||||
|
||||
|
||||
|
||||
6. Исходник просто наполнен "магическими" числами - стиль программирования начинающего. Плохой стиль.
|
||||
2
F1-nolib/chronometer_v3/Difference
Normal file
2
F1-nolib/chronometer_v3/Difference
Normal file
@ -0,0 +1,2 @@
|
||||
Difference from previous version:
|
||||
- LED screen with different modes
|
||||
179
F1-nolib/chronometer_v3/GPS.c
Normal file
179
F1-nolib/chronometer_v3/GPS.c
Normal file
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* GPS.c
|
||||
*
|
||||
* Copyright 2015 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 "GPS.h"
|
||||
#include "hardware.h"
|
||||
#include "time.h"
|
||||
#include "usart.h"
|
||||
#include "str.h"
|
||||
#include "usb.h"
|
||||
#include <string.h> // memcpy
|
||||
|
||||
#define GPS_send_string(str) do{usart_send(GPS_USART, str);}while(0)
|
||||
|
||||
gps_status GPS_status = GPS_NOTFOUND;
|
||||
int need2startseq = 1;
|
||||
|
||||
static uint8_t hex(uint8_t n){
|
||||
return ((n < 10) ? (n+'0') : (n+'A'-10));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check checksum
|
||||
*/
|
||||
static int checksum_true(const char *buf){
|
||||
char *eol;
|
||||
uint8_t checksum = 0, cs[3];
|
||||
if(*buf != '$' || !(eol = getchr(buf, '*'))){
|
||||
return 0;
|
||||
}
|
||||
while(++buf != eol)
|
||||
checksum ^= (uint8_t)*buf;
|
||||
++buf;
|
||||
cs[0] = hex(checksum >> 4);
|
||||
cs[1] = hex(checksum & 0x0f);
|
||||
if(buf[0] == cs[0] && buf[1] == cs[1])
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void send_chksum(uint8_t chs){
|
||||
usart_putchar(GPS_USART, hex(chs >> 4));
|
||||
usart_putchar(GPS_USART, hex(chs & 0x0f));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate checksum & write message to port
|
||||
* @param buf - command to write (without leading $ and trailing *)
|
||||
* return 0 if fails
|
||||
*/
|
||||
static void write_with_checksum(const char *buf){
|
||||
/*
|
||||
for(int i = 0; i < 10000; ++i){
|
||||
char *txt = NULL;
|
||||
if(usartrx(GPS_USART)){
|
||||
usart_getline(GPS_USART, &txt);
|
||||
DBG("Old data");
|
||||
GPS_parse_answer(txt);
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
uint8_t checksum = 0;
|
||||
usart_putchar(GPS_USART, '$');
|
||||
GPS_send_string(buf);
|
||||
do{
|
||||
checksum ^= *buf++;
|
||||
}while(*buf);
|
||||
usart_putchar(GPS_USART, '*');
|
||||
send_chksum(checksum);
|
||||
newline(GPS_USART);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MTK fields format:
|
||||
* $PMTKxxx,yyy,zzz*2E
|
||||
* P - proprietary, MTK - always this, xxx - packet type, yyy,zzz - packet data
|
||||
* Packet types:
|
||||
* 220 - PMTK_SET_POS_FIX, data - position fix interval (msec, > 200)
|
||||
* 255 - PMTK_SET_SYNC_PPS_NMEA - turn on/off (def - off) PPS, data = 0/1 -> "$PMTK255,1" turn ON
|
||||
* 285 - PMTK_SET_PPS_CONFIG - set PPS configuration, data fields:
|
||||
* 1st - 0-disable, 1-after 1st fix, 2-3D only, 3-2D/3D only, 4-always
|
||||
* 2nd - 2..998 - pulse width
|
||||
* 314 - PMTK_API_SET_NMEA_OUTPUT - set output messages, N== N fixes per output,
|
||||
* order of messages: GLL,RMC,VTG,GGA,GSA,GSV,GRS,GST, only RMC per every pos fix:
|
||||
* $PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
* 386 - PMTK_API_SET_STATIC_NAV_THD speed threshold (m/s) for static navigation
|
||||
* $PMTK386,1.5
|
||||
* ;
|
||||
*/
|
||||
|
||||
/**
|
||||
* Send starting sequences (get only RMC messages)
|
||||
*/
|
||||
void GPS_send_start_seq(){
|
||||
DBG("Send start seq");
|
||||
// turn ON PPS:
|
||||
write_with_checksum("PMTK255,1");
|
||||
// set pulse width to 10ms with working after 1st fix
|
||||
write_with_checksum("PMTK285,1,10");
|
||||
// set only RMC:
|
||||
write_with_checksum("PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0");
|
||||
// set static speed threshold
|
||||
write_with_checksum("PMTK386,1.5");
|
||||
need2startseq = 0;
|
||||
}
|
||||
|
||||
// send "full cold start" command to clear all almanach & location data
|
||||
void GPS_send_FullColdStart(){
|
||||
write_with_checksum("PMTK104");
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse answer from GPS module
|
||||
*
|
||||
* Recommended minimum specific GPS/Transit data
|
||||
* $GPRMC,hhmmss.sss,status,latitude,N,longitude,E,spd,cog,ddmmyy,mv,mvE,mode*cs
|
||||
* 1 = UTC of position fix
|
||||
* 2 = Data status (V=valid, A=invalid)
|
||||
* 3 = Latitude (ddmm.mmmm)
|
||||
* 4 = N or S
|
||||
* 5 = Longitude (dddmm.mmmm)
|
||||
* 6 = E or W
|
||||
* 7 = Speed over ground in knots
|
||||
* 8 = Cource over ground in degrees
|
||||
* 9 = UT date (ddmmyy)
|
||||
* 10 = Magnetic variation degrees (Easterly var. subtracts from true course)
|
||||
* 11 = E or W
|
||||
* 12 = Mode: N(bad), E(approx), A(auto), D(diff)
|
||||
* 213457.00,A,4340.59415,N,04127.47560,E,2.494,,290615,,,A*7B
|
||||
*/
|
||||
void GPS_parse_answer(const char *buf){
|
||||
char *ptr;
|
||||
if(buf[1] == 'P') return; // answers to proprietary messages
|
||||
if(cmpstr(buf+3, "RMC", 3)){ // not RMC message
|
||||
//need2startseq = 1;
|
||||
return;
|
||||
}
|
||||
if(!checksum_true(buf)){
|
||||
return; // wrong checksum
|
||||
}
|
||||
if(showGPSstr){
|
||||
showGPSstr = 0;
|
||||
sendstring(buf);
|
||||
}
|
||||
buf += 7; // skip header
|
||||
if(*buf == ','){ // time unknown
|
||||
GPS_status = GPS_WAIT;
|
||||
return;
|
||||
}
|
||||
ptr = getchr(buf, ',');
|
||||
if(!ptr ) return;
|
||||
*ptr++ = 0;
|
||||
if(*ptr == 'A'){
|
||||
GPS_status = GPS_VALID;
|
||||
set_time(buf);
|
||||
}else{
|
||||
uint8_t goth = (buf[0]-'0')*10 + buf[1]-'0';
|
||||
if(current_time.H != goth) set_time(buf); // set time once per hour even if it's not valid
|
||||
GPS_status = GPS_NOT_VALID;
|
||||
}
|
||||
}
|
||||
43
F1-nolib/chronometer_v3/GPS.h
Normal file
43
F1-nolib/chronometer_v3/GPS.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* GPS.h
|
||||
*
|
||||
* Copyright 2015 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 __GPS_H__
|
||||
#define __GPS_H__
|
||||
|
||||
#include "stm32f1.h"
|
||||
|
||||
extern int need2startseq;
|
||||
|
||||
typedef enum{
|
||||
GPS_NOTFOUND // default status before first RMC message
|
||||
,GPS_WAIT // wait for satellites
|
||||
,GPS_NOT_VALID // time known, but not valid
|
||||
,GPS_VALID
|
||||
} gps_status;
|
||||
|
||||
extern gps_status GPS_status;
|
||||
|
||||
void GPS_parse_answer(const char *string);
|
||||
void GPS_send_start_seq();
|
||||
void GPS_send_FullColdStart();
|
||||
|
||||
#endif // __GPS_H__
|
||||
159
F1-nolib/chronometer_v3/Makefile
Normal file
159
F1-nolib/chronometer_v3/Makefile
Normal file
@ -0,0 +1,159 @@
|
||||
# make debug adds -DEBUG -Werror
|
||||
# make ADDEFS="additional defs"
|
||||
BINARY = chrono
|
||||
BOOTPORT ?= /dev/ttyUSB0
|
||||
BOOTSPEED ?= 115200
|
||||
# MCU FAMILY
|
||||
FAMILY ?= F1
|
||||
# MCU code
|
||||
MCU ?= F103x8
|
||||
# density (stm32f10x.h, lines 70-84)
|
||||
DENSITY ?= MD
|
||||
# change this linking script depending on particular MCU model,
|
||||
LDSCRIPT ?= stm32F103xB.ld
|
||||
DEFS = ${ADDEFS} -DVERSION=\"0.2.0\"
|
||||
TARGET := RELEASE
|
||||
# proxy GPS output over USART1
|
||||
#DEFS += -DUSART1PROXY
|
||||
|
||||
FP_FLAGS ?= -msoft-float -mfloat-abi=soft
|
||||
ASM_FLAGS ?= -mthumb -mcpu=cortex-m3 -mfix-cortex-m3-ldrd
|
||||
ARCH_FLAGS = $(ASM_FLAGS) $(FP_FLAGS)
|
||||
|
||||
###############################################################################
|
||||
# Executables
|
||||
#PREFIX ?= arm-none-eabi
|
||||
# gcc from arm web site
|
||||
PREFIX ?= /opt/bin/arm-none-eabi
|
||||
TOOLCHLIB ?= /opt/arm-none-eabi/lib
|
||||
RM := rm -f
|
||||
RMDIR := rmdir
|
||||
CC := $(PREFIX)-gcc
|
||||
# don't replace ld with gcc: the binary size would be much greater!!
|
||||
LD := $(PREFIX)-ld
|
||||
AR := $(PREFIX)-ar
|
||||
AS := $(PREFIX)-as
|
||||
SIZE := $(PREFIX)-size
|
||||
OBJCOPY := $(PREFIX)-objcopy
|
||||
OBJDUMP := $(PREFIX)-objdump
|
||||
GDB := $(PREFIX)-gdb
|
||||
STFLASH := $(shell which st-flash)
|
||||
STBOOT := $(shell which stm32flash)
|
||||
DFUUTIL := $(shell which dfu-util)
|
||||
|
||||
###############################################################################
|
||||
# Source files
|
||||
OBJDIR = mk
|
||||
SRC := $(wildcard *.c)
|
||||
OBJS := $(addprefix $(OBJDIR)/, $(SRC:%.c=%.o))
|
||||
STARTUP = $(OBJDIR)/startup.o
|
||||
OBJS += $(STARTUP)
|
||||
# dependencies: we need them to recompile files if their headers-dependencies changed
|
||||
DEPS := $(OBJS:.o=.d)
|
||||
|
||||
INC_DIR ?= ../inc
|
||||
|
||||
INCLUDE := -I$(INC_DIR)/Fx -I$(INC_DIR)/cm
|
||||
LIB_DIR := $(INC_DIR)/ld
|
||||
|
||||
###############################################################################
|
||||
# C flags
|
||||
CFLAGS += -O2 -g -D__thumb2__=1 -MD
|
||||
CFLAGS += -Wall -Wextra -Wshadow
|
||||
CFLAGS += -fno-common -ffunction-sections -fdata-sections -fno-stack-protector
|
||||
CFLAGS += $(ARCH_FLAGS)
|
||||
|
||||
###############################################################################
|
||||
# Linker flags
|
||||
LDFLAGS += --static -nostartfiles -nostdlibs
|
||||
LDFLAGS += -L$(LIB_DIR) -L$(TOOLCHLIB)
|
||||
LDFLAGS += -T$(LDSCRIPT)
|
||||
|
||||
###############################################################################
|
||||
# Used libraries
|
||||
LDLIBS += -lc $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
|
||||
|
||||
DEFS += -DSTM32$(FAMILY) -DSTM32$(MCU) -DSTM32F10X_$(DENSITY)
|
||||
|
||||
ELF := $(OBJDIR)/$(BINARY).elf
|
||||
LIST := $(OBJDIR)/$(BINARY).list
|
||||
BIN := $(BINARY).bin
|
||||
HEX := $(BINARY).hex
|
||||
|
||||
all: $(OBJDIR)/RELEASE bin list size
|
||||
release: all
|
||||
|
||||
debug: CFLAGS += -DEBUG -Werror
|
||||
debug: $(OBJDIR)/DEBUG bin list size
|
||||
|
||||
$(OBJDIR)/DEBUG:
|
||||
@rm -rf $(OBJDIR)
|
||||
@mkdir $(OBJDIR)
|
||||
@> $(OBJDIR)/DEBUG
|
||||
@echo "TARGET: DEBUG"
|
||||
echo "CFLAGS += -DEBUG -Werror" > $(OBJDIR)/CFLAGS
|
||||
$(OBJDIR)/RELEASE:
|
||||
@rm -rf $(OBJDIR)
|
||||
@mkdir $(OBJDIR)
|
||||
@> $(OBJDIR)/RELEASE
|
||||
@echo "TARGET: RELEASE"
|
||||
echo "" > $(OBJDIR)/CFLAGS
|
||||
|
||||
elf: $(ELF)
|
||||
bin: $(BIN)
|
||||
hex: $(HEX)
|
||||
list: $(LIST)
|
||||
|
||||
ifneq ($(MAKECMDGOALS),clean)
|
||||
-include $(DEPS)
|
||||
-include $(OBJDIR)/CFLAGS
|
||||
endif
|
||||
|
||||
$(OBJDIR):
|
||||
mkdir $(OBJDIR)
|
||||
|
||||
$(STARTUP): $(INC_DIR)/startup/vector.c
|
||||
$(CC) $(CFLAGS) $(DEFS) $(INCLUDE) -o $@ -c $<
|
||||
|
||||
$(OBJDIR)/%.o: %.c
|
||||
@echo " CC $<"
|
||||
$(CC) $(CFLAGS) $(DEFS) $(INCLUDE) -o $@ -c $<
|
||||
|
||||
$(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) $(LDSCRIPT)
|
||||
@echo " LD $(ELF)"
|
||||
$(LD) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $(ELF)
|
||||
|
||||
size: $(ELF)
|
||||
$(SIZE) $(ELF)
|
||||
|
||||
clean:
|
||||
@echo " CLEAN"
|
||||
@$(RM) $(HEX)
|
||||
@$(RM) -rf $(OBJDIR) 2>/dev/null || true
|
||||
|
||||
|
||||
flash: $(BIN)
|
||||
@echo " FLASH $(BIN)"
|
||||
$(STFLASH) --reset write $(BIN) 0x8000000
|
||||
|
||||
boot: $(BIN)
|
||||
@echo " LOAD $(BIN) through bootloader"
|
||||
$(STBOOT) -b$(BOOTSPEED) $(BOOTPORT) -w $(BIN)
|
||||
|
||||
dfuboot: $(BIN)
|
||||
@echo " LOAD $(BIN) THROUGH DFU"
|
||||
$(DFUUTIL) -a0 -D $(BIN) -s 0x08000000
|
||||
|
||||
.PHONY: clean flash boot
|
||||
42
F1-nolib/chronometer_v3/Readme.md
Normal file
42
F1-nolib/chronometer_v3/Readme.md
Normal file
@ -0,0 +1,42 @@
|
||||
Chronometer for downhill competitions
|
||||
=====================================
|
||||
|
||||
The binary have two models: DEBUG (make debug) and RELEASE (make release or just make).
|
||||
DEBUGGing model use USART1 as debugging console, showing many messages.
|
||||
|
||||
When typing commands you can fix them using backspace key. ESC-sequences don't work.
|
||||
|
||||
## Pinout
|
||||
|
||||
### Interfaces
|
||||
|
||||
- PA11/12 -- USB
|
||||
- PA9(Tx), PA10 (Rx) -- USART1 (debug console / Bluetooth / GPS proxy)
|
||||
- PA2(Tx), PA3 -- USART2 (GPS)
|
||||
- PB10(Tx), PB11 -- USART3 (LIDAR / console)
|
||||
|
||||
- PA13/14 - SWDIO
|
||||
|
||||
### Other
|
||||
|
||||
- PA1 -- PPS signal from GPS (EXTI)
|
||||
- PA8 -- Bluetooth "State" pin (not implemented yet)
|
||||
- PA15 -- USB pullup
|
||||
|
||||
- PB0/1 -- TRIG0/1
|
||||
- PB3 -- TRIG2
|
||||
- PB8, PB9 -- onboard LEDs (PB8 - LED1, PB9 - LED0)
|
||||
|
||||
- PC13 -- buzzer
|
||||
|
||||
### LED screen:
|
||||
|
||||
- PA5,6,7 (SCK, MISO, MOSI) -- SPI for LED screen: PA5/7 - SCK/MOSI, PA6 - SCLK/nOE (connected together)
|
||||
- PB6/7 -- A/B for LED screen
|
||||
|
||||
## LEDS
|
||||
|
||||
- LED0 -- shining when there's no PPS signal, fades for 0.25s on PPS
|
||||
- LED1 -- don't shines if no GPS found, shines when time not valid, blinks when time valid
|
||||
|
||||
|
||||
244
F1-nolib/chronometer_v3/Readme_rus.txt
Normal file
244
F1-nolib/chronometer_v3/Readme_rus.txt
Normal file
@ -0,0 +1,244 @@
|
||||
Дополнено выводом времени на LED screen.
|
||||
|
||||
****** Распиновка ******
|
||||
|
||||
=== Интерфейсы I/O ===
|
||||
- PA11/12 - USB
|
||||
- PA9(Tx), PA10(Rx) - USART1 - консоль отладки / прокси RMC-сообщений GPS (опт. - bluetooth).
|
||||
- PA2(Tx), PA3(Rx) - USART2 - подключение GPS-приемника.
|
||||
- PB10(Tx), PB11(Rx) - USART3 - подключение лидара или другой консоли.
|
||||
|
||||
=== Остальные порты ===
|
||||
- PA1 - PPS сигнал от GPS; сюда можно подключать любой дополнительный высокоомный вход напрямую.
|
||||
- PB0 - TRIG0 - (замыкать на землю).
|
||||
- PB1 - TRIG1 - подключен к 12В.
|
||||
- PB3 - TRIG2 - (замыкать на землю).
|
||||
- PA15 - подтяжка USB.
|
||||
- PA8 - (не реализовано) - bluetooth "state"
|
||||
- PB8, PB9 - индикаторные светодиоды (LED1, LED0 соответственно).
|
||||
- PC13 - пищалка.
|
||||
|
||||
=== Светодиоды ===
|
||||
- LED0 - при отсутствии сигнала PPS просто горит, если PPS появляется - мигает (затухает на 0.25с на каждый сигнал).
|
||||
- LED1 - индикатор GPS: не горит, если приемник не обнаружен; горит постоянно, если неуверенный прием времени
|
||||
(буква "V" во второй позиции RMC-сообщения); мигает при уверенном приеме (буква "A" во второй позиции).
|
||||
Начинать работу можно сразу, как только замигает LED0.
|
||||
|
||||
|
||||
****** Триггеры ******
|
||||
К TRIG0/TRIG2 подключается кнопка, педаль, иной створ, замыкающий контакты. Никакого внешнего напряжения здесь быть не должно! При необходимости можно использовать ключ на полевом транзисторе или опторазвязке, замыкающий сигнальный контакт на землю.
|
||||
К TRIG1 нужно подключать 12-вольтный сигнал, ток не меньше 10мА. Если створ имеет открытый коллектор, то выход створа подключается к минусу TRIG2, а к плюсу подключается 12В с источника питания.
|
||||
В случае ложных срабатываний рекомендуется заземлить катод источника питания хронометра.
|
||||
|
||||
При подключении внешней кнопки желательно, чтобы она имела нормально замкнутые контакты - это предотвратит ложные срабатывания из-за электромагнитных помех.
|
||||
|
||||
|
||||
****** Подключение ******
|
||||
Хронометр эмулирует "китайский" преобразователь PL2303.
|
||||
|
||||
К выходам PA9/PA10 можно подключить преобразователь USART<>USB, накинуть их напрямую на ноги Rx/Tx "малинки" (PA9(Tx) соединить с Rx, PA10(Rx) - с Tx) или подключить к bluetooth-модулю. Этот USART может использоваться (в зависимости от настроек) как дополнительный управляющий терминал или прокси RMC-сообщений GPS-приемника (уже после обработки микроконтроллером, поэтому если МК выключен, а приемник включен, сигнала все равно не будет).
|
||||
|
||||
К разъему LIDAR можно подключить лидар, либо настроить его на еще один управляющий терминал. Скорость обоих настраивается в конфигурации.
|
||||
|
||||
Для подключения PPS сигнала к "малинке" выведен соответствующий разъем (там используется эмиттерный повторитель, поэтому уровень логической единицы на его выходе около 2.6В, при необходимости можно использовать буфер, согласующий уровни).
|
||||
|
||||
Разъемы I2C и SPI используются для подключения к светодиодной панели.
|
||||
"SPI":
|
||||
- MOSI - к пину DATA (12)
|
||||
- SCK - к пину CLK (10)
|
||||
- MISO - к пинам SCLK (10) и ENABLE (1)
|
||||
"I2C":
|
||||
- SCL - к пину A (2)
|
||||
- SDA - к пину B (4)
|
||||
- соединить земли панели и хронометра.
|
||||
|
||||
Нежелательно подключать пины напрямую, лучше использовать буфер для развязки, иначе есть шанс сжеть микроконтроллер, если прибор будет включен без подачи питания на панель.
|
||||
|
||||
|
||||
****** Конфигурация ******
|
||||
Хронометр конфигурируется через любой активный управляющий терминал (USB, USART1-Bluetooth, USART3-LIDAR). При наборе команд с клавиатуры в USB-терминале можно использовать клавишу Backspace для удаления неправильно введенных символов.
|
||||
Чтобы увидеть подсказку, достаточно отправить любую строку, начинающуюся с вопросительного знака. Появится справка:
|
||||
|
||||
btnstate - show triggers state
|
||||
buzzerS - turn buzzer ON/OFF
|
||||
cls - turn LED display off
|
||||
curdist - show current LIDAR distance
|
||||
deletelogs - delete logs from flash memory
|
||||
distmin - min distance threshold (cm)
|
||||
distmax - max distance threshold (cm)
|
||||
dumpN - dump 20 last stored events (no x), all (x<1) or x
|
||||
evtlenN - duration of the trigger event display (ms)
|
||||
flash - FLASH info
|
||||
gateS - check/not check triggers (1/0)
|
||||
gpsproxyS - GPS proxy over USART1 on/off
|
||||
gpsrestart - send Full Cold Restart to GPS
|
||||
gpsstat - get GPS status
|
||||
gpsstring - current GPS data string
|
||||
ledsS - turn leds on/off (1/0)
|
||||
lidarS - switch between LIDAR (1) or command TTY (0)
|
||||
lidspdN - set LIDAR speed to N
|
||||
mcutemp - MCU temperature
|
||||
mesg str - show 'str' at display (no more than 7 chars)
|
||||
ndumpN - dump Nth log & show on screen (-N - Nth from last)
|
||||
nfree - warn when free logs space less than this number (0 - not warn)
|
||||
reset - reset MCU
|
||||
seS - save/don't save (1/0) trigger events into flash
|
||||
showconf - show current configuration
|
||||
showshutterS - show/not show trigger events
|
||||
showtime - show current time
|
||||
stautoX - auto start every X minutes (0 or absent - cancel, +/- - increase/decrease by 1min)
|
||||
stonceX - delayed start after X minutes (like auto)
|
||||
store - store new configuration in flash
|
||||
stortest - add test trigger event record into flash
|
||||
strendC - string ends with \n (C=n) or \r\n (C=r)
|
||||
time - print current time
|
||||
triglevelNS - working trigger N level S
|
||||
trigpauseNP - pause (P, ms) after trigger N shots
|
||||
trigtimeN - show last trigger N time
|
||||
usartspdN - set USART1 speed to N
|
||||
usbreset - reset USB connectioin
|
||||
vdd - Vdd value
|
||||
|
||||
|
||||
Подробнее (S после команды означает 1 или 0, БЕЗ ПРОБЕЛА! N - число, пробел можно ставить):
|
||||
- btnstate - отображение состояния триггеров и уровня PPS, например:
|
||||
BTN0=0, BTN1=0, BTN2=0, PPS=0
|
||||
означает, что на всех входах сигнала нет. Можно применять эту команду для анализа срабатывания створов, если пищалка выключена.
|
||||
|
||||
- buzzer - buzzer1 разрешает пищать встроенной пищалке, buzzer0 - запрещает. После команды появляется ответ вроде
|
||||
BUZZER=ON
|
||||
|
||||
- cls - выключить экран.
|
||||
|
||||
- curdist - текущее расстояние, измеряемое лидаром.
|
||||
|
||||
- deletelogs - очистить из флеш-памяти все записи о времени срабатывания створов.
|
||||
|
||||
- distmin, distmax - пределы обнаружения для лидара.
|
||||
|
||||
- dump - вывести на терминале дамп последних 20 событий (без параметра N), последних N событий (N>0) или всех.
|
||||
|
||||
- evtlen - время (в миллисекундах, по умолчанию 5000), в течение которого на экране будет отображаться время пересечения створа или дампа.
|
||||
|
||||
- flash - информация о флеш-памяти, например:
|
||||
FLASHSIZE=128kB - общий объем памяти
|
||||
FLASH_BASE=0x08000000 - базовый адрес хранения прошивки
|
||||
Flash_Data=0x08007000 - адрес, с которого начинается хранилище настроек
|
||||
varslen=2048 - размер (в байтах) флеш-памяти, выделяемой под хранение конфигурации
|
||||
CONFsize=28 - размер (в байтах) одной "ячейки" с конфигурационными данными
|
||||
Nconf_records=72 - количество "ячеек" конфигурации, которые можно сохранить, не стирая флеш
|
||||
logsstart=0x08007800 - адрес, с которого начинается область хранения логов (дамп событий)
|
||||
LOGsize=16 - размер одной "ячейки" лога
|
||||
Nlogs_records=6271 - максимальный размер логов
|
||||
|
||||
- gate - реагировать на события створов (параметра нет, либо параметр != '0') или нет.
|
||||
|
||||
- gpsproxy - проксировать все сообщения GPS на USART1 (разъем Bluetooth), либо не проксировать (если параметр == '0').
|
||||
|
||||
- gpsrestart - перезапуск GPS, делает "холодный" рестарт.
|
||||
|
||||
- gpsstat - состояние GPS: "not found", если не обнаружено никаких приемников GPS; "waiting" во время поиска спутников; "no satellites" в случае потери спутников (GPRMC имеет статус "not valid"); "valid time", если все хорошо.
|
||||
|
||||
- gpsstring - вывод очередного сообщения от GPS. Если все нормально, то появится строка RMC вроде
|
||||
$GPRMC,124001.000,A,4340.9369,N,04127.5034,E,0.00,33.26,150819,,,A*5C
|
||||
для внешнего GPS появится первая попавшаяся строка.
|
||||
|
||||
- leds - включить/выключить диагностические светодиоды (валидны только параметры 1 или 0).
|
||||
|
||||
- lidar - настройка порта USART3 (LIDAR): если параметр отсутствует или не равен '0', то порт работает с лидаром, иначе USART3 используется как дополнительный диагностический порт. Если на этом порту ничего нет, выбор режима никак не сказывается на быстродействии.
|
||||
|
||||
- lidspd - установка скорости порта USART3 (LIDAR).
|
||||
|
||||
- mcutemp - условная температура микроконтроллера (degrC).
|
||||
|
||||
- mesg - отобразить на светодиодной панели короткое (максимум 7-8 символов) сообщение. Если до вызова этой команды экран отображал время, то он выходит из режима отображения времени и постоянно показывает сообщение. Для возвращения в режим отображения времени нужно ввести команду showtime. Для вывода сообщений кириллицей терминал должен иметь кодировку КОИ8-Р.
|
||||
|
||||
- ndump - отобразить N-ю запись в логе событий (если N<0, то отсчет идет от конца лога: N==-1 - последняя запись, N==-2 - предпоследняя и так далее), при N вне диапазона отображается сообщение об ошибке. Если светодиодная панель находится в режиме showtime, данное время отобразится и на ней в течение eventlen миллисекунд.
|
||||
|
||||
- nfree - позволяет установить количество записей до окончания флеша, когда хронометр станет выдавать в консоль предупреждения при каждом сохранении события створа. В случае, если свободной памяти во флеше не останется, попытки сохранения событий будут завершаться сообщениями об ошибке. Автоматической очистки флеша не происходит, необходимо вручну вызвать команду deletelogs.
|
||||
|
||||
- reset - перезагрузка микроконтроллера.
|
||||
|
||||
- se - с параметром '0' запрещает сохранение событий створов во флеш-память, без параметра или с любым параметром разрешает это.
|
||||
|
||||
- showconf - отображение текущей конфигурации, например:
|
||||
DISTMIN=50
|
||||
DISTMAX=1000
|
||||
TRIGLVL=0
|
||||
TRIGPAUSE={400, 400, 400, 300}
|
||||
USART1SPD=115200
|
||||
LIDARSPD=115200
|
||||
NFREE=100
|
||||
STREND=N
|
||||
SAVE_EVENTS=0
|
||||
GPSPROXY=0
|
||||
LIDAR=1
|
||||
EVTLEN=5000
|
||||
|
||||
Пункты конфигурации DISTMIN/DISTMAX относятся к лидару.
|
||||
TRIGLVL - конфигурация уровней срабатывания, каждый бит, начиная с младшего (всего три младших бита), равен нулю, если для соответствующего триггера срабатывание при переходе 1->0; равен единице, если при переходе 0->1.
|
||||
TRIGPAUSE - пауза между срабатываниями створа: если после срабатывания произойдет следующее событие за интервал, меньший заданного, это событие учитываться не будет.
|
||||
USART1SPD, LIDARSPD - скорости в бодах соответствующих портов (разъемы "Bluetooth" и "LIDAR").
|
||||
NFREE - количество свободных ячеек флеш-памяти, начиная с которого будут выдаваться предупреждения в терминал при сохранении событий створа.
|
||||
STREND - окончание строки: N - "\n", RN - "\r\n".
|
||||
SAVE_EVENTS - сохранять ли события створов во флеш-памяти микроконтроллера.
|
||||
GPSPROXY - проксировать ли сообщения GPS на USART1.
|
||||
LIDAR - что находится на разъеме "LIDAR": лидар (1) или управляющий терминал (0).
|
||||
EVTLEN - сколько миллисекунд отображается время срабатывания створа на экране.
|
||||
|
||||
При изменении определенных параметров конфигурации команда showconf позволяет убедиться, что все прошло нормально.
|
||||
Все изменения, кроме скорости портов, вступают в силу немедленно. Для изменения скорости портов необходимо сохранить конфигурацию во флеш-памяти при помощи команды store, а затем выполнить перезагрузку микроконтроллера. Перезагрузка не отражается на состоянии GPS: если он уже поймал спутники, то точная синхронизация МК будет длиться не более 11-12 секунд, а время с погрешностью в 1-2мс будет установлено через 2-3 секунды после включения.
|
||||
|
||||
- showshutter - при вызове команды с параметром '0' события створа не отображаются на светодиодной панели, если же параметр имеет другое значение или опущен, события отображаются.
|
||||
|
||||
- showtime - перевести светодиодную панель в режим отображения времени (т.е. отображается текущее время, события створов, обратный отсчет перед стартом). По умолчанию при включении экран показывает сообщение "Chrono", которое можно изменить при помощи команды mesg, отключить экран при помощи команды cls, либо перейти в режим отображения времени этой командой.
|
||||
|
||||
- stauto - перейти в режим отложенного автостарта с интервалом в N минут. В режиме активации автостарта параметр N должен иметь значение от 1 до 5. Если же хронометр уже находится в режиме автостарта, можно изменять общий интервал, задавая другое значение N, либо выполнять его инкремент/декремент, вызывая эту команду с N == '+' или '-'. Если текущее значение паузы составляет 1 минуту и вызвана команда stauto-, режим автостарта отключается. Аналогично отключить автостарт можно, вызвав stauto с любым другим параметром, кроме +/- или 1..5. В терминал после вызова команды выдаются соответствующие сообщения. Изменение периода автостарта не сказывается на времени до ближайшего отложенного старта, для его изменения необходимо вызывать команду stonce.
|
||||
|
||||
- stonce - перейти в режим одиночного отложенного старта через N минут. Декремент минут до отложенного старта выполняется на 28 секунде каждой минуты. Если при декременте время до старта становится равным нулю, на 29 секунде запускается обратный отсчет (начиная с 30 секунд), а на 59 секунде отображается сообщение "СТАРТ!". Оба режима - автоматический и одиночный отложенный старт - индицируются на табло отображения времени в крайнем правом столбце: в нижней половине указывается время (в минутах) до старта, в верхней - буква "A" для автостарта и "O" для одиночного старта.
|
||||
|
||||
- store - сохранить новую конфигурацию во флеш-памяти МК. Если ничего в конфигурации не менялось, команда пройдет без отклика. Если же были изменения, то в случае успешного сохранения появится сообщение "Success!", иначе будет сообщение об ошибке "Error: can't save data!".
|
||||
|
||||
- stortest - сохранить во флеш-памяти тестовую запись с текущим временем.
|
||||
|
||||
- strend - выбор окончания строки: "\r\n" (с параметром R или r) или "\n" (с параметром N или n).
|
||||
|
||||
- time - отображает текущее время так, как оно бы отобразилось при срабатывании створа, например, 55725.961 (15:28:45). ВРЕМЯ В UTC!!! Первое число - количество секунд и миллисекунд с начала суток по UTC, в скобках указывается человекочитаемое время.
|
||||
|
||||
- triglevel - рабочий уровень триггера. Здесь N - номер створа (0..2), S - уровень (0/1). Скажем, чтобы триггер 0 срабатывал при перепаде 1->0, нужно написать команду
|
||||
triglevel00
|
||||
а чтобы триггер 2 срабатывал при перепаде 0->1,
|
||||
triglevel21
|
||||
|
||||
- trigpause - задать паузу для триггера N, пауза в миллисекундах. Если написать 0, паузы не будет, и каждое срабатывание будет вызывать соответствующее сообщение. Эта пауза нужна для защиты от "звона" и нескольких срабатываний на "дырках" в объекте. Меньше 50мс лучше не делать.
|
||||
|
||||
- trigtimeN - отображение последнего времени срабатывания триггера N, например, на запрос trigtime0, может быть выведено:
|
||||
TRIG0=45212.930 (12:33:32)
|
||||
Если срабатываний с момента включения не было, выведутся нули:
|
||||
TRIG2=0.000 (00:00:00)
|
||||
|
||||
- usartspd - установить скорость порта USART1 ("Bluetooth").
|
||||
|
||||
- usbreset - реинициировать соединение по USB (подтяжка DP к +3.3В отключается и включается снова).
|
||||
|
||||
- vdd - напряжение питания микроконтроллера и GPS (3.3В).
|
||||
|
||||
|
||||
****** Режимы ******
|
||||
|
||||
Сразу после включения хронометр отображает на экране сообщение "Chrono", реагирует на события створа (в терминале отображается время и длительность, все время активности створа пищит buzzer). Сохранение событий во внутренней флеш-памяти зависит от конфигурации (SAVE_EVENTS). Скорости портов UART1 и UART3 определяются настройками (USART1SPD и LIDARSPD). Уровень срабатывания створов (1->0 или 0->1) тоже определяется настройками (TRIGLVL).
|
||||
|
||||
Обратите внимание на то, что переменная TRIGLVL (так же, как и USART1SPD и LIDARSPD) влияет на конфигурацию устройства лишь при загрузке, поэтому при изменении параметров необходимо сохранить настройки командой store и перезагрузить микроконтроллер командой reset или переподключением питания.
|
||||
|
||||
Прочие параметры конфигурации вступают в силу сразу после сохранения, т.е. их можно менять "на лету".
|
||||
|
||||
Для переключения в режим отображения времени необходимо задать команду "showtime". Только после этого будет возможно отображение текущего времени, времени срабатывания створа, обратного отсчета перед отложенным стартом.
|
||||
|
||||
Параметры отложенного старта задаются командами "stonce" и "stauto". В этих режимах отображение времени сопровождается указанием режима работы и временем в минутах до следующего старта. За 30 секунд до старта начинается обратный отсчет, завершающийся отображением в течение 1 секунды сообщения "СТАРТ!".
|
||||
Автостарт отличается от одиночного старта тем, что после сообщения "СТАРТ!" выполняется обновление счетчика "stonce", в одиночном же режиме после старта прибор входит в простой режим отображения времени.
|
||||
|
||||
Команда "showshutter" позволяет разрешать/запрещать отображение времени срабатывания створа на панели. Команда "gate" дает возможность включить или отключить реакцию на створы. Сохранять события створов во флеш-памяти или нет, решает команда "se".
|
||||
|
||||
На время бездействия можно отключить экран командой "cls", либо отобразить короткое (7-8 символов) сообщение командой "mesg".
|
||||
|
||||
При необходимости просмотреть лог событий створов можно при помощи команд "dump" (отображает N последних записей) или "ndump" (отображает N-ю запись, если N<0 - отображает |N|-ю запись с конца лога). Команда "ndump" также отображает время на светодиодной панели (если включен режим "showtime").
|
||||
72
F1-nolib/chronometer_v3/adc.c
Normal file
72
F1-nolib/chronometer_v3/adc.c
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* This file is part of the chronometer project.
|
||||
* Copyright 2018 Edward V. Emelianov <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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "adc.h"
|
||||
#include "flash.h"
|
||||
#include "hardware.h"
|
||||
|
||||
/**
|
||||
* @brief ADC_array - array for ADC channels with median filtering:
|
||||
* 0 - Rvar
|
||||
* 1 - internal Tsens
|
||||
* 2 - Vref
|
||||
*/
|
||||
uint16_t ADC_array[NUMBER_OF_ADC_CHANNELS*9];
|
||||
|
||||
/**
|
||||
* @brief getADCval - calculate median value for `nch` channel
|
||||
* @param nch - number of channel
|
||||
* @return
|
||||
*/
|
||||
uint16_t getADCval(int nch){
|
||||
int i, addr = nch;
|
||||
register uint16_t temp;
|
||||
#define PIX_SORT(a,b) do{ if ((a)>(b)) PIX_SWAP((a),(b)); }while(0)
|
||||
#define PIX_SWAP(a,b) do{ temp=(a);(a)=(b);(b)=temp; }while(0)
|
||||
uint16_t p[9];
|
||||
for(i = 0; i < 9; ++i, addr += NUMBER_OF_ADC_CHANNELS) // first we should prepare array for optmed
|
||||
p[i] = ADC_array[addr];
|
||||
PIX_SORT(p[1], p[2]) ; PIX_SORT(p[4], p[5]) ; PIX_SORT(p[7], p[8]) ;
|
||||
PIX_SORT(p[0], p[1]) ; PIX_SORT(p[3], p[4]) ; PIX_SORT(p[6], p[7]) ;
|
||||
PIX_SORT(p[1], p[2]) ; PIX_SORT(p[4], p[5]) ; PIX_SORT(p[7], p[8]) ;
|
||||
PIX_SORT(p[0], p[3]) ; PIX_SORT(p[5], p[8]) ; PIX_SORT(p[4], p[7]) ;
|
||||
PIX_SORT(p[3], p[6]) ; PIX_SORT(p[1], p[4]) ; PIX_SORT(p[2], p[5]) ;
|
||||
PIX_SORT(p[4], p[7]) ; PIX_SORT(p[4], p[2]) ; PIX_SORT(p[6], p[4]) ;
|
||||
PIX_SORT(p[4], p[2]) ;
|
||||
return p[4];
|
||||
#undef PIX_SORT
|
||||
#undef PIX_SWAP
|
||||
}
|
||||
|
||||
// return MCU temperature (degrees of celsius * 10)
|
||||
int32_t getMCUtemp(){
|
||||
// Temp = (V25 - Vsense)/Avg_Slope + 25
|
||||
// V_25 = 1.45V, Slope = 4.3e-3
|
||||
uint32_t Vsense = getVdd() * getADCval(ADC_TMCU_CHANNEL);
|
||||
int32_t temperature = 593920 - (int32_t)Vsense; // 593920 == 145*4096
|
||||
temperature /= 172; // == /(4096*10*4.3e-3), 10 - to convert from *100 to *10
|
||||
temperature += 250;
|
||||
return(temperature);
|
||||
}
|
||||
|
||||
// return Vdd * 100 (V)
|
||||
uint32_t getVdd(){
|
||||
uint32_t vdd = 120 * 4096; // 1.2V
|
||||
vdd /= getADCval(ADC_VDD_CHANNEL);
|
||||
return vdd;
|
||||
}
|
||||
32
F1-nolib/chronometer_v3/adc.h
Normal file
32
F1-nolib/chronometer_v3/adc.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* This file is part of the chronometer project.
|
||||
* Copyright 2018 Edward V. Emelianov <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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef ADC_H
|
||||
#define ADC_H
|
||||
#include "stm32f1.h"
|
||||
|
||||
// interval of trigger's shot (>min && <max), maybe negative
|
||||
#define ADC_MIN_VAL (1024)
|
||||
#define ADC_MAX_VAL (3072)
|
||||
// 2*ADC_THRESHOLD = hysteresis width
|
||||
#define ADC_THRESHOLD (50)
|
||||
|
||||
extern uint16_t ADC_array[];
|
||||
int32_t getMCUtemp();
|
||||
uint32_t getVdd();
|
||||
uint16_t getADCval(int nch);
|
||||
#endif // ADC_H
|
||||
BIN
F1-nolib/chronometer_v3/chrono.bin
Executable file
BIN
F1-nolib/chronometer_v3/chrono.bin
Executable file
Binary file not shown.
366
F1-nolib/chronometer_v3/flash.c
Normal file
366
F1-nolib/chronometer_v3/flash.c
Normal file
@ -0,0 +1,366 @@
|
||||
/*
|
||||
* geany_encoding=koi8-r
|
||||
* flash.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.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
ATTENTION!!
|
||||
This things works only if you will add next section:
|
||||
|
||||
.myvars :
|
||||
{
|
||||
. = ALIGN(1024);
|
||||
KEEP(*(.myvars))
|
||||
} > rom
|
||||
|
||||
after section .data
|
||||
*/
|
||||
|
||||
#include "stm32f1.h"
|
||||
|
||||
#include "adc.h"
|
||||
#include "flash.h"
|
||||
#include "lidar.h"
|
||||
#include "str.h"
|
||||
#include "usart.h" // DBG
|
||||
#include "usb.h" // printout
|
||||
#include <string.h> // memcpy
|
||||
|
||||
// max amount of records stored: Config & Logs
|
||||
uint32_t maxCnum = FLASH_BLOCK_SIZE / sizeof(user_conf);
|
||||
uint32_t maxLnum = FLASH_BLOCK_SIZE / sizeof(user_conf);
|
||||
|
||||
// common structure for all datatypes stored
|
||||
/*typedef struct {
|
||||
uint16_t userconf_sz;
|
||||
} flash_storage;*/
|
||||
|
||||
#define USERCONF_INITIALIZER { \
|
||||
.userconf_sz = sizeof(user_conf) \
|
||||
,.dist_min = LIDAR_MIN_DIST \
|
||||
,.dist_max = LIDAR_MAX_DIST \
|
||||
,.trigstate = 0 \
|
||||
,.trigpause = {400, 400, 400, 300} \
|
||||
,.USART_speed = USART1_DEFAULT_SPEED \
|
||||
,.LIDAR_speed = LIDAR_DEFAULT_SPEED \
|
||||
,.defflags = 0 \
|
||||
,.NLfreeWarn = 100 \
|
||||
,.ledshow_time = 5000 \
|
||||
}
|
||||
|
||||
// change to placement
|
||||
/*
|
||||
__attribute__ ((section(".logs"))) const uint32_t *logsstart;
|
||||
__attribute__ ((section(".myvars"))) const user_conf *Flash_Data;
|
||||
*/
|
||||
|
||||
static int erase_flash(const void*, const void*);
|
||||
static int write2flash(const void*, const void*, uint32_t);
|
||||
|
||||
const user_conf *Flash_Data = (const user_conf *)&__varsstart;
|
||||
const event_log *logsstart = (event_log*) &__logsstart;
|
||||
TODO("Add to event_log a comment - up to 8 chars")
|
||||
|
||||
user_conf the_conf = USERCONF_INITIALIZER;
|
||||
|
||||
static int currentconfidx = -1; // index of current configuration
|
||||
static int currentlogidx = -1; // index of current logs record
|
||||
|
||||
/**
|
||||
* @brief binarySearch - binary search in flash for last non-empty cell
|
||||
* any struct searched should have its sizeof() @ the first field!!!
|
||||
* @param l - left index
|
||||
* @param r - right index (should be @1 less than last index!)
|
||||
* @param start - starting address
|
||||
* @param stor_size - size of structure to search
|
||||
* @return index of non-empty cell or -1
|
||||
*/
|
||||
static int binarySearch(int r, const uint8_t *start, int stor_size){
|
||||
int l = 0;
|
||||
#ifdef EBUG
|
||||
SEND("stor_size=");
|
||||
SEND(u2str(stor_size));
|
||||
newline(1);
|
||||
#endif
|
||||
while(r >= l){
|
||||
int mid = l + (r - l) / 2;
|
||||
#ifdef EBUG
|
||||
SEND("r=");
|
||||
SEND(u2str(r));
|
||||
SEND(", l=");
|
||||
SEND(u2str(l));
|
||||
SEND(", mid=");
|
||||
SEND(u2str(mid));
|
||||
newline(1);
|
||||
#endif
|
||||
const uint8_t *s = start + mid * stor_size;
|
||||
#ifdef EBUG
|
||||
SEND("data=");
|
||||
SEND(u2hex(*((const uint16_t*)s)));
|
||||
newline(1);
|
||||
#endif
|
||||
if(*((const uint16_t*)s) == stor_size){
|
||||
if(*((const uint16_t*)(s + stor_size)) == 0xffff){
|
||||
#ifdef EBUG
|
||||
SEND("\nindex=");
|
||||
SEND(u2str(mid));
|
||||
newline(1);
|
||||
#endif
|
||||
return mid;
|
||||
}else{ // element is to the right
|
||||
l = mid + 1;
|
||||
}
|
||||
}else{ // element is to the left
|
||||
r = mid - 1;
|
||||
}
|
||||
}
|
||||
return -1; // not found
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief flashstorage_init - initialization of user conf & logs storage
|
||||
* run in once @ start
|
||||
*/
|
||||
void flashstorage_init(){
|
||||
maxCnum = ((uint32_t)&_varslen) / sizeof(user_conf);
|
||||
//SEND("maxCnum="); printu(1, maxCnum);
|
||||
if(FLASH_SIZE > 0 && FLASH_SIZE < 20000){
|
||||
uint32_t flsz = FLASH_SIZE * 1024; // size in bytes
|
||||
flsz -= (uint32_t)logsstart - FLASH_BASE;
|
||||
maxLnum = flsz / sizeof(event_log);
|
||||
//SEND("\nmaxLnum="); printu(1, maxLnum);
|
||||
}
|
||||
// -1 if there's no data at all & flash is clear; maxnum-1 if flash is full
|
||||
currentconfidx = binarySearch((int)maxCnum-2, (const uint8_t*)Flash_Data, sizeof(user_conf));
|
||||
if(currentconfidx > -1){
|
||||
memcpy(&the_conf, &Flash_Data[currentconfidx], sizeof(user_conf));
|
||||
}
|
||||
currentlogidx = binarySearch((int)maxLnum-2, (const uint8_t*)logsstart, sizeof(event_log));
|
||||
}
|
||||
|
||||
// store new configuration
|
||||
// @return 0 if all OK
|
||||
int store_userconf(){
|
||||
// maxnum - 3 means that there always should be at least one empty record after last data
|
||||
// for binarySearch() checking that there's nothing more after it!
|
||||
if(currentconfidx > (int)maxCnum - 3){ // there's no more place
|
||||
currentconfidx = 0;
|
||||
DBG("Need to erase flash!");
|
||||
if(erase_flash(Flash_Data, logsstart)) return 1;
|
||||
}else ++currentconfidx; // take next data position (0 - within first run after firmware flashing)
|
||||
return write2flash((const void*)&Flash_Data[currentconfidx], &the_conf, sizeof(the_conf));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief store_log - save log record L into flash memory
|
||||
* @param L - event log (or NULL to delete flash)
|
||||
* @return 0 if all OK
|
||||
*/
|
||||
int store_log(event_log *L){
|
||||
if(!L){
|
||||
currentlogidx = -1;
|
||||
return erase_flash(logsstart, NULL);
|
||||
}
|
||||
#ifdef EBUG
|
||||
SEND("currentlogidx=");
|
||||
SEND(u2str(currentlogidx));
|
||||
newline(1);
|
||||
#endif
|
||||
if(currentlogidx > (int)maxLnum - 3){ // there's no more place
|
||||
/*currentlogidx = 0;
|
||||
DBG("Need to erase flash!");
|
||||
if(erase_flash(logsstart, NULL)) return 1;*/
|
||||
// prevent automatic logs erasing!
|
||||
sendstring("\n\nERROR!\nCan't save logs: delete old manually!!!\n");
|
||||
return 1;
|
||||
}else ++currentlogidx; // take next data position (0 - within first run after firmware flashing)
|
||||
// put warning if there's little space
|
||||
if(currentlogidx + the_conf.NLfreeWarn > (int)maxLnum - 3){
|
||||
uint32_t nfree = maxLnum - 2 - (uint32_t)currentlogidx;
|
||||
sendstring("\n\nWARNING!\nCan store only ");
|
||||
sendstring(u2str(nfree));
|
||||
sendstring(" logs!\n\n");
|
||||
}
|
||||
L->evtlog_sz = sizeof(event_log);
|
||||
return write2flash(&logsstart[currentlogidx], L, sizeof(event_log));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief dump_log - dump N log records
|
||||
* @param start - first record to show (if start<0, then first=last+1-start)
|
||||
* @param Nlogs - amount of logs to show (if Nlogs<=0, then show all logs)
|
||||
* @return 0 if all OK, 1 if there's no logs in flash
|
||||
*/
|
||||
int dump_log(int start, int Nlogs){
|
||||
if(currentlogidx < 0) return 1;
|
||||
#ifdef EBUG
|
||||
SEND("currentlogidx=");
|
||||
SEND(u2str(currentlogidx));
|
||||
SEND("\nstart=");
|
||||
SEND(u2str(start));
|
||||
SEND("\nNlogs=");
|
||||
SEND(u2str(Nlogs));
|
||||
newline(1);
|
||||
#endif
|
||||
if(start < 0){
|
||||
start += currentlogidx + 1;
|
||||
if(start < 0){
|
||||
if(Nlogs == 1) return 1; // out of range
|
||||
else start = 0; // show all
|
||||
}
|
||||
}
|
||||
if(start > currentlogidx) return 1;
|
||||
int nlast;
|
||||
if(Nlogs > 0){
|
||||
nlast = start + Nlogs - 1;
|
||||
if(nlast > currentlogidx) nlast = currentlogidx;
|
||||
}else nlast = currentlogidx;
|
||||
++nlast;
|
||||
const event_log *l = logsstart + start;
|
||||
for(int i = start; i < nlast; ++i, ++l){
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
sendstring(get_trigger_shot(i, l));
|
||||
if(Nlogs == 1){ // show on LED
|
||||
lastTtrig = Tms;
|
||||
lastLog.shottime = l->shottime;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int write2flash(const void *start, const void *wrdata, uint32_t stor_size){
|
||||
int ret = 0;
|
||||
if (FLASH->CR & FLASH_CR_LOCK){ // unloch flash
|
||||
FLASH->KEYR = FLASH_KEY1;
|
||||
FLASH->KEYR = FLASH_KEY2;
|
||||
}
|
||||
while (FLASH->SR & FLASH_SR_BSY);
|
||||
if(FLASH->SR & FLASH_SR_WRPRTERR){
|
||||
DBG("Can't remove write protection");
|
||||
return 1; // write protection
|
||||
}
|
||||
FLASH->SR = FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPRTERR; // clear all flags
|
||||
FLASH->CR |= FLASH_CR_PG;
|
||||
const uint16_t *data = (const uint16_t*) wrdata;
|
||||
volatile uint16_t *address = (volatile uint16_t*) start;
|
||||
uint32_t i, count = (stor_size + 1) / 2;
|
||||
for (i = 0; i < count; ++i){
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
*(volatile uint16_t*)(address + i) = data[i];
|
||||
while (FLASH->SR & FLASH_SR_BSY);
|
||||
if(FLASH->SR & FLASH_SR_PGERR){
|
||||
ret = 1; // program error - meet not 0xffff
|
||||
DBG("FLASH_SR_PGERR");
|
||||
break;
|
||||
}else while (!(FLASH->SR & FLASH_SR_EOP));
|
||||
FLASH->SR = FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPRTERR;
|
||||
}
|
||||
FLASH->CR &= ~(FLASH_CR_PG);
|
||||
DBG("Flash stored");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief erase_flash - erase N pages of flash memory
|
||||
* @param start - first address
|
||||
* @param end - last address (or NULL if need to erase all flash remaining)
|
||||
* @return 0 if succeed
|
||||
*/
|
||||
static int erase_flash(const void *start, const void *end){
|
||||
int ret = 0;
|
||||
uint32_t nblocks = 1, flsz = 0;
|
||||
if(!end){ // erase all remaining
|
||||
if(FLASH_SIZE > 0 && FLASH_SIZE < 20000){
|
||||
flsz = FLASH_SIZE * 1024; // size in bytes
|
||||
flsz -= (uint32_t)start - FLASH_BASE;
|
||||
}
|
||||
}else{ // erase a part
|
||||
flsz = (uint32_t)end - (uint32_t)start;
|
||||
}
|
||||
nblocks = flsz / FLASH_BLOCK_SIZE;
|
||||
if(nblocks == 0 || nblocks >= FLASH_SIZE) return 1;
|
||||
for(uint32_t i = 0; i < nblocks; ++i){
|
||||
#ifdef EBUG
|
||||
SEND("Try to erase page #"); printu(1,i); newline(1);
|
||||
#endif
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
/* (1) Wait till no operation is on going */
|
||||
/* (2) Clear error & EOP bits */
|
||||
/* (3) Check that the Flash is unlocked */
|
||||
/* (4) Perform unlock sequence */
|
||||
while ((FLASH->SR & FLASH_SR_BSY) != 0){} /* (1) */
|
||||
FLASH->SR = FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPRTERR; /* (2) */
|
||||
/* if (FLASH->SR & FLASH_SR_EOP){
|
||||
FLASH->SR |= FLASH_SR_EOP;
|
||||
}*/
|
||||
if ((FLASH->CR & FLASH_CR_LOCK) != 0){ /* (3) */
|
||||
FLASH->KEYR = FLASH_KEY1; /* (4) */
|
||||
FLASH->KEYR = FLASH_KEY2;
|
||||
}
|
||||
/* (1) Set the PER bit in the FLASH_CR register to enable page erasing */
|
||||
/* (2) Program the FLASH_AR register to select a page to erase */
|
||||
/* (3) Set the STRT bit in the FLASH_CR register to start the erasing */
|
||||
/* (4) Wait until the EOP flag in the FLASH_SR register set */
|
||||
/* (5) Clear EOP flag by software by writing EOP at 1 */
|
||||
/* (6) Reset the PER Bit to disable the page erase */
|
||||
FLASH->CR |= FLASH_CR_PER; /* (1) */
|
||||
FLASH->AR = (uint32_t)Flash_Data + i*FLASH_BLOCK_SIZE; /* (2) */
|
||||
FLASH->CR |= FLASH_CR_STRT; /* (3) */
|
||||
while(!(FLASH->SR & FLASH_SR_EOP));
|
||||
FLASH->SR |= FLASH_SR_EOP; /* (5)*/
|
||||
if(FLASH->SR & FLASH_SR_WRPRTERR){ /* Check Write protection error */
|
||||
ret = 1;
|
||||
DBG("Write protection error!");
|
||||
FLASH->SR |= FLASH_SR_WRPRTERR; /* Clear the flag by software by writing it at 1*/
|
||||
break;
|
||||
}
|
||||
FLASH->CR &= ~FLASH_CR_PER; /* (6) */
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef EBUG
|
||||
void dump_userconf(){
|
||||
SEND("userconf_sz="); printu(1, the_conf.userconf_sz);
|
||||
SEND("\ndist_min="); printu(1, the_conf.dist_min);
|
||||
SEND("\ndist_max="); printu(1, the_conf.dist_max);
|
||||
SEND("\ntrigstate="); printuhex(1, the_conf.trigstate);
|
||||
SEND("\ntrigpause={");
|
||||
for(int i = 0; i < TRIGGERS_AMOUNT; ++i){
|
||||
if(i) SEND(", ");
|
||||
printu(1, the_conf.trigpause[i]);
|
||||
}
|
||||
SEND("}\n");
|
||||
transmit_tbuf(1);
|
||||
}
|
||||
|
||||
void addNrecs(int N){
|
||||
SEND("Try to store userconf for "); printu(1, N); SEND(" times\n");
|
||||
for(int i = 0; i < N; ++i){
|
||||
if(store_userconf()){
|
||||
SEND("Error @ "); printu(1, i); newline(1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
SEND("Curr idx: "); printu(1, currentconfidx); newline(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
89
F1-nolib/chronometer_v3/flash.h
Normal file
89
F1-nolib/chronometer_v3/flash.h
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* flash.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 __FLASH_H__
|
||||
#define __FLASH_H__
|
||||
|
||||
#include <stm32f1.h>
|
||||
#include "hardware.h"
|
||||
|
||||
#define FLASH_BLOCK_SIZE (1024)
|
||||
#define FLASH_SIZE_REG ((uint32_t)0x1FFFF7E0)
|
||||
#define FLASH_SIZE *((uint16_t*)FLASH_SIZE_REG)
|
||||
|
||||
/*
|
||||
* struct to save user configurations
|
||||
*/
|
||||
typedef struct __attribute__((packed, aligned(4))){
|
||||
uint16_t userconf_sz; // "magick number"
|
||||
uint16_t NLfreeWarn; // warn user when there's less free log records than NLfreeWarn
|
||||
uint8_t trigstate; // level in `triggered` state
|
||||
uint8_t defflags; // default flags
|
||||
uint16_t dist_min; // minimal distance for LIDAR
|
||||
uint16_t dist_max; // maximal -//-
|
||||
uint32_t USART_speed; // USART1 speed (115200 by default)
|
||||
uint32_t LIDAR_speed; // USART3 speed (115200 by default)
|
||||
uint16_t trigpause[TRIGGERS_AMOUNT]; // pause (ms) for false shots
|
||||
uint16_t ledshow_time; // shutter events display time (ms)
|
||||
} user_conf;
|
||||
|
||||
// values for user_conf.defflags:
|
||||
// save events in flash
|
||||
#define FLAG_SAVE_EVENTS (1 << 0)
|
||||
// strings ends with "\r\n" instead of normal "\n"
|
||||
#define FLAG_STRENDRN (1 << 1)
|
||||
// proxy GPS messages over USART1
|
||||
#define FLAG_GPSPROXY (1 << 2)
|
||||
// USART3 works as regular TTY instead of LIDAR
|
||||
#define FLAG_NOLIDAR (1 << 3)
|
||||
|
||||
/*
|
||||
* struct to save events logs
|
||||
*/
|
||||
typedef struct __attribute__((packed, aligned(4))){
|
||||
uint16_t evtlog_sz;
|
||||
uint8_t trigno;
|
||||
trigtime shottime;
|
||||
int16_t triglen;
|
||||
uint16_t lidar_dist;
|
||||
} event_log;
|
||||
|
||||
extern user_conf the_conf;
|
||||
extern const user_conf *Flash_Data;
|
||||
extern const event_log *logsstart;
|
||||
extern uint32_t maxCnum, maxLnum;
|
||||
// data from ld-file
|
||||
extern uint32_t _varslen, __varsstart, __logsstart;
|
||||
|
||||
|
||||
void flashstorage_init();
|
||||
int store_userconf();
|
||||
int store_log(event_log *L);
|
||||
int dump_log(int start, int Nlogs);
|
||||
|
||||
#ifdef EBUG
|
||||
void dump_userconf();
|
||||
void addNrecs(int N);
|
||||
#endif
|
||||
|
||||
#endif // __FLASH_H__
|
||||
3168
F1-nolib/chronometer_v3/font14.h
Normal file
3168
F1-nolib/chronometer_v3/font14.h
Normal file
File diff suppressed because it is too large
Load Diff
249
F1-nolib/chronometer_v3/fontNumb10.h
Normal file
249
F1-nolib/chronometer_v3/fontNumb10.h
Normal file
@ -0,0 +1,249 @@
|
||||
/*
|
||||
* This file is part of the LED_screen project.
|
||||
* Copyright 2019 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// this file should be included JUST ONCE!
|
||||
// only in fonts.c
|
||||
|
||||
#define FONTNUMB10BYTES 10
|
||||
#define FONTNUMB10HEIGHT 10
|
||||
#define FONTNUMB10BASELINE 0
|
||||
|
||||
// this array shows position of every koi8-r symbol in font10_table
|
||||
const uint8_t fontNumb10_encoding[256] = {
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0..31
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, // 47
|
||||
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 0, 0, 0, // 63
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 79
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 95
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 111
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 127
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 143
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 159
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 175
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 191
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 207
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 223
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 239
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 255
|
||||
};
|
||||
|
||||
const uint8_t fontNumb10_table[] = {
|
||||
// 0x00 - empty
|
||||
0,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
// 0x20 - ' '
|
||||
4,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
// 0x30 - '0'
|
||||
7,
|
||||
__XX____,
|
||||
_X__X___,
|
||||
X____X__,
|
||||
X____X__,
|
||||
X____X__,
|
||||
X____X__,
|
||||
X____X__,
|
||||
X____X__,
|
||||
_X__X___,
|
||||
__XX____,
|
||||
// 0x31 - '1'
|
||||
4,
|
||||
__X_____,
|
||||
_XX_____,
|
||||
X_X_____,
|
||||
__X_____,
|
||||
__X_____,
|
||||
__X_____,
|
||||
__X_____,
|
||||
__X_____,
|
||||
__X_____,
|
||||
__X_____,
|
||||
// 0x32 - '2'
|
||||
6,
|
||||
_XXX____,
|
||||
X__XX___,
|
||||
____X___,
|
||||
____X___,
|
||||
____X___,
|
||||
___X____,
|
||||
__X_____,
|
||||
_X______,
|
||||
XX______,
|
||||
XXXXX___,
|
||||
// 0x33 - '3'
|
||||
6,
|
||||
_XX_____,
|
||||
X__X____,
|
||||
___X____,
|
||||
___X____,
|
||||
_XX_____,
|
||||
___XX___,
|
||||
____X___,
|
||||
____X___,
|
||||
X__X____,
|
||||
_XX_____,
|
||||
// 0x34 - '4'
|
||||
6,
|
||||
____X___,
|
||||
___XX___,
|
||||
___XX___,
|
||||
__X_X___,
|
||||
_X__X___,
|
||||
_X__X___,
|
||||
X___X___,
|
||||
XXXXX___,
|
||||
____X___,
|
||||
____X___,
|
||||
// 0x35 - '5'
|
||||
6,
|
||||
XXXXX___,
|
||||
X_______,
|
||||
X_______,
|
||||
X_______,
|
||||
XXXX____,
|
||||
___XX___,
|
||||
____X___,
|
||||
____X___,
|
||||
X__XX___,
|
||||
_XXX____,
|
||||
// 0x36 - '6'
|
||||
6,
|
||||
__XX____,
|
||||
_X__X___,
|
||||
X_______,
|
||||
X_______,
|
||||
X_XX____,
|
||||
XX_XX___,
|
||||
X___X___,
|
||||
X___X___,
|
||||
XX_XX___,
|
||||
_XXX____,
|
||||
// 0x37 - '7'
|
||||
6,
|
||||
XXXXX___,
|
||||
____X___,
|
||||
___X____,
|
||||
___X____,
|
||||
__X_____,
|
||||
__X_____,
|
||||
__X_____,
|
||||
_X______,
|
||||
_X______,
|
||||
_X______,
|
||||
// 0x38 - '8'
|
||||
7,
|
||||
__XXX___,
|
||||
_X___X__,
|
||||
_X___X__,
|
||||
_XX_X___,
|
||||
__XX____,
|
||||
_X__X___,
|
||||
X____X__,
|
||||
X____X__,
|
||||
XX__XX__,
|
||||
_XXXX___,
|
||||
// 0x39 - '9'
|
||||
6,
|
||||
_XXX____,
|
||||
XX_XX___,
|
||||
X___X___,
|
||||
X___X___,
|
||||
XX_XX___,
|
||||
_XX_X___,
|
||||
____X___,
|
||||
____X___,
|
||||
X__X____,
|
||||
_XX_____,
|
||||
// 0x3A - ':'
|
||||
3,
|
||||
________,
|
||||
________,
|
||||
XX______,
|
||||
XX______,
|
||||
________,
|
||||
________,
|
||||
XX______,
|
||||
XX______,
|
||||
________,
|
||||
________,
|
||||
// 0x2e - '.'
|
||||
3,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
XX______,
|
||||
XX______,
|
||||
};
|
||||
|
||||
/*
|
||||
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) - ÿ
|
||||
*/
|
||||
315
F1-nolib/chronometer_v3/fontNumb16.h
Normal file
315
F1-nolib/chronometer_v3/fontNumb16.h
Normal file
@ -0,0 +1,315 @@
|
||||
/*
|
||||
* This file is part of the LED_screen project.
|
||||
* Copyright 2019 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// this file should be included JUST ONCE!
|
||||
// only in fonts.c
|
||||
|
||||
#define FONTNUMB16BYTES 16
|
||||
#define FONTNUMB16HEIGHT 16
|
||||
#define FONTNUMB16BASELINE 0
|
||||
|
||||
// this array shows position of every koi8-r symbol in font16_table
|
||||
const uint8_t fontNumb16_encoding[256] = {
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0..31
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 47
|
||||
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 0, 0, 0, // 63
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 79
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 95
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 111
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 127
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 143
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 159
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 175
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 191
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 207
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 223
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 239
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 255
|
||||
};
|
||||
|
||||
const uint8_t fontNumb16_table[] = {
|
||||
// 0x00 - empty
|
||||
0,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
// 0x20 - ' '
|
||||
4,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
// 0x30 - '0'
|
||||
8,
|
||||
__XXX___,
|
||||
_XX_XX__,
|
||||
_X__XX__,
|
||||
XX___XX_,
|
||||
XX___XX_,
|
||||
XX___XX_,
|
||||
XX___XX_,
|
||||
XX___XX_,
|
||||
XX___XX_,
|
||||
XX___XX_,
|
||||
XX___XX_,
|
||||
XX___XX_,
|
||||
XX___XX_,
|
||||
XXX__X__,
|
||||
_XX_XX__,
|
||||
__XXX___,
|
||||
// 0x31 - '1'
|
||||
6,
|
||||
___X____,
|
||||
__XX____,
|
||||
_XXX____,
|
||||
XXXX____,
|
||||
__XX____,
|
||||
__XX____,
|
||||
__XX____,
|
||||
__XX____,
|
||||
__XX____,
|
||||
__XX____,
|
||||
__XX____,
|
||||
__XX____,
|
||||
__XX____,
|
||||
__XX____,
|
||||
__XX____,
|
||||
_XXXX___,
|
||||
// 0x32 - '2'
|
||||
7,
|
||||
__XX____,
|
||||
_XXXX___,
|
||||
XX_XXX__,
|
||||
X___XX__,
|
||||
____XX__,
|
||||
____XX__,
|
||||
____XX__,
|
||||
____XX__,
|
||||
___XX___,
|
||||
___X____,
|
||||
__XX____,
|
||||
__X_____,
|
||||
_XX_____,
|
||||
XX______,
|
||||
XX___X__,
|
||||
XXXXXX__,
|
||||
// 0x33 - '3'
|
||||
7,
|
||||
_XXX____,
|
||||
XX_X____,
|
||||
X__XX___,
|
||||
___XX___,
|
||||
___XX___,
|
||||
___XX___,
|
||||
__XX____,
|
||||
_XXX____,
|
||||
___XX___,
|
||||
____XX__,
|
||||
____XX__,
|
||||
____XX__,
|
||||
____XX__,
|
||||
X__XXX__,
|
||||
XX_XX___,
|
||||
_XXX____,
|
||||
// 0x34 - '4'
|
||||
8,
|
||||
_____X__,
|
||||
____XX__,
|
||||
____XX__,
|
||||
___XXX__,
|
||||
__XX_X__,
|
||||
__X__X__,
|
||||
_XX_XX__,
|
||||
_XX_XX__,
|
||||
_X__XX__,
|
||||
XX__XX__,
|
||||
XX__XX__,
|
||||
XXXXXXX_,
|
||||
____XX__,
|
||||
____XX__,
|
||||
____XX__,
|
||||
____XX__,
|
||||
// 0x35 - '5'
|
||||
6,
|
||||
XXXXX___,
|
||||
XX______,
|
||||
XX______,
|
||||
XX______,
|
||||
XX______,
|
||||
XXXX____,
|
||||
XXXXX___,
|
||||
___XX___,
|
||||
___XX___,
|
||||
___XX___,
|
||||
___XX___,
|
||||
___XX___,
|
||||
___XX___,
|
||||
X__XX___,
|
||||
XXXX____,
|
||||
_XX_____,
|
||||
// 0x36 - '6'
|
||||
7,
|
||||
___XX___,
|
||||
__X__X__,
|
||||
_XX_____,
|
||||
_X______,
|
||||
XX______,
|
||||
XX______,
|
||||
XX_X____,
|
||||
XXXXX___,
|
||||
XX__XX__,
|
||||
XX__XX__,
|
||||
XX___X__,
|
||||
XX___X__,
|
||||
XX__XX__,
|
||||
_X__XX__,
|
||||
_XX_XX__,
|
||||
__XXX___,
|
||||
// 0x37 - '7'
|
||||
7,
|
||||
XXXXXX__,
|
||||
_____X__,
|
||||
____XX__,
|
||||
____XX__,
|
||||
____X___,
|
||||
___XX___,
|
||||
___XX___,
|
||||
___X____,
|
||||
__XX____,
|
||||
__XX____,
|
||||
_XX_____,
|
||||
_XX_____,
|
||||
_XX_____,
|
||||
XX______,
|
||||
XX______,
|
||||
XX______,
|
||||
// 0x38 - '8'
|
||||
7,
|
||||
__XX____,
|
||||
_XX_X___,
|
||||
XX__XX__,
|
||||
XX___X__,
|
||||
XX___X__,
|
||||
XX__XX__,
|
||||
_XX_X___,
|
||||
__XX____,
|
||||
_XXXX___,
|
||||
XX__XX__,
|
||||
X___XX__,
|
||||
X____X__,
|
||||
XX___X__,
|
||||
XX__XX__,
|
||||
_XXXXX__,
|
||||
__XX____,
|
||||
// 0x39 - '9'
|
||||
7,
|
||||
_XXX____,
|
||||
XX_XX___,
|
||||
X___X___,
|
||||
X___XX__,
|
||||
X___XX__,
|
||||
X___XX__,
|
||||
X___XX__,
|
||||
X___XX__,
|
||||
XX_XXX__,
|
||||
_XX_XX__,
|
||||
____XX__,
|
||||
____XX__,
|
||||
____X___,
|
||||
X__XX___,
|
||||
XXXX____,
|
||||
_XX_____,
|
||||
// 0x3A - ':'
|
||||
3,
|
||||
________,
|
||||
________,
|
||||
XX______,
|
||||
XX______,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
XX______,
|
||||
XX______,
|
||||
________,
|
||||
________
|
||||
};
|
||||
|
||||
/*
|
||||
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) - ÿ
|
||||
*/
|
||||
221
F1-nolib/chronometer_v3/fontNumb8.h
Normal file
221
F1-nolib/chronometer_v3/fontNumb8.h
Normal file
@ -0,0 +1,221 @@
|
||||
/*
|
||||
* This file is part of the LED_screen project.
|
||||
* Copyright 2019 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// this file should be included JUST ONCE!
|
||||
// only in fonts.c
|
||||
|
||||
#define FONTNUMB8BYTES 8
|
||||
#define FONTNUMB8HEIGHT 8
|
||||
#define FONTNUMB8BASELINE 0
|
||||
|
||||
// this array shows position of every koi8-r symbol in font10_table
|
||||
const uint8_t fontNumb8_encoding[256] = {
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0..31
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 47
|
||||
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, 0, 0, 0, 0, // 63
|
||||
0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, // 79
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 95
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 111
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 127
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 143
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 159
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 175
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 191
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 207
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 223
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 239
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 255
|
||||
};
|
||||
|
||||
const uint8_t fontNumb8_table[] = {
|
||||
// 0 0x00 - empty
|
||||
0,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
// 1 0x20 - ' '
|
||||
4,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
________,
|
||||
// 2 0x30 - '0'
|
||||
6,
|
||||
_XXX____,
|
||||
XX_XX___,
|
||||
X___X___,
|
||||
X___X___,
|
||||
X___X___,
|
||||
X___X___,
|
||||
XX_XX___,
|
||||
_XXX____,
|
||||
// 3 0x31 - '1'
|
||||
6,
|
||||
_XX_____,
|
||||
X_X_____,
|
||||
__X_____,
|
||||
__X_____,
|
||||
__X_____,
|
||||
__X_____,
|
||||
__X_____,
|
||||
XXXXX___,
|
||||
// 4 0x32 - '2'
|
||||
6,
|
||||
_XXX____,
|
||||
X___X___,
|
||||
____X___,
|
||||
____X___,
|
||||
___X____,
|
||||
__X_____,
|
||||
_X______,
|
||||
XXXXX___,
|
||||
// 5 0x33 - '3'
|
||||
6,
|
||||
XXXX____,
|
||||
____X___,
|
||||
____X___,
|
||||
_XXX____,
|
||||
____X___,
|
||||
____X___,
|
||||
____X___,
|
||||
XXXX____,
|
||||
// 6 0x34 - '4'
|
||||
7,
|
||||
___XX___,
|
||||
___XX___,
|
||||
__X_X___,
|
||||
_X__X___,
|
||||
_X__X___,
|
||||
XXXXXX__,
|
||||
____X___,
|
||||
____X___,
|
||||
// 7 0x35 - '5'
|
||||
5,
|
||||
XXXX____,
|
||||
X_______,
|
||||
X_______,
|
||||
XXX_____,
|
||||
___X____,
|
||||
___X____,
|
||||
___X____,
|
||||
XXX_____,
|
||||
// 8 0x36 - '6'
|
||||
6,
|
||||
_XXX____,
|
||||
X___X___,
|
||||
X_______,
|
||||
XXXX____,
|
||||
X___X___,
|
||||
X___X___,
|
||||
X___X___,
|
||||
_XXX____,
|
||||
// 9 0x37 - '7'
|
||||
5,
|
||||
XXXX____,
|
||||
___X____,
|
||||
__X_____,
|
||||
__X_____,
|
||||
__X_____,
|
||||
_X______,
|
||||
_X______,
|
||||
_X______,
|
||||
// 10 0x38 - '8'
|
||||
6,
|
||||
_XXX____,
|
||||
X___X___,
|
||||
X___X___,
|
||||
_XXX____,
|
||||
X___X___,
|
||||
X___X___,
|
||||
X___X___,
|
||||
_XXX____,
|
||||
// 11 0x39 - '9'
|
||||
6,
|
||||
_XXX____,
|
||||
X___X___,
|
||||
X___X___,
|
||||
X___X___,
|
||||
_XXXX___,
|
||||
____X___,
|
||||
X___X___,
|
||||
_XXX____,
|
||||
// 12 0x41 - 'A'
|
||||
6,
|
||||
__X_____,
|
||||
_X_X____,
|
||||
_X_X____,
|
||||
_X_X____,
|
||||
X___X___,
|
||||
XXXXX___,
|
||||
X___X___,
|
||||
X___X___,
|
||||
// 13 0x4f - 'O'
|
||||
7,
|
||||
__XX____,
|
||||
_X__X___,
|
||||
X____X__,
|
||||
X____X__,
|
||||
X____X__,
|
||||
X____X__,
|
||||
_X__X___,
|
||||
__XX____,
|
||||
};
|
||||
|
||||
/*
|
||||
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) - ÿ
|
||||
*/
|
||||
118
F1-nolib/chronometer_v3/font_EMPTY.h
Normal file
118
F1-nolib/chronometer_v3/font_EMPTY.h
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* This file is part of the LED_screen project.
|
||||
* Copyright 2019 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// this file should be included JUST ONCE!
|
||||
// only in fonts.c
|
||||
|
||||
#define FONTNUMB16BYTES 32
|
||||
#define FONTNUMB16HEIGHT 16
|
||||
#define FONTNUMB16BASELINE 0
|
||||
|
||||
// this array shows position of every koi8-r symbol in font14_table
|
||||
const uint8_t font14_encoding[256] = {
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0..31
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 47
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 63
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 79
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 95
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 111
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 127
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 143
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 159
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 175
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 191
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 207
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 223
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 239
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 255
|
||||
};
|
||||
|
||||
const uint8_t fontNumb16_table[] = {
|
||||
// 0x00 - empty
|
||||
0,
|
||||
________,________,
|
||||
________,________,
|
||||
________,________,
|
||||
________,________,
|
||||
________,________,
|
||||
________,________,
|
||||
________,________,
|
||||
________,________,
|
||||
________,________,
|
||||
________,________,
|
||||
________,________,
|
||||
________,________,
|
||||
________,________,
|
||||
________,________,
|
||||
________,________,
|
||||
________,________
|
||||
// 0x20 - ' '
|
||||
,
|
||||
4,
|
||||
________,________,
|
||||
________,________,
|
||||
________,________,
|
||||
________,________,
|
||||
________,________,
|
||||
________,________,
|
||||
________,________,
|
||||
________,________,
|
||||
________,________,
|
||||
________,________,
|
||||
________,________,
|
||||
________,________,
|
||||
________,________,
|
||||
________,________,
|
||||
________,________,
|
||||
________,________
|
||||
};
|
||||
|
||||
/*
|
||||
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) - ÿ
|
||||
*/
|
||||
330
F1-nolib/chronometer_v3/fonts.c
Normal file
330
F1-nolib/chronometer_v3/fonts.c
Normal file
@ -0,0 +1,330 @@
|
||||
/*
|
||||
* This file is part of the LED_screen project.
|
||||
* Copyright 2019 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include "fonts.h"
|
||||
#include "usart.h"
|
||||
|
||||
/* Bash-script to generate the symbols
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
function bits(){
|
||||
Ans=""
|
||||
for x in $(seq 7 -1 0); do
|
||||
B=$((1<<$x))
|
||||
if [ $(($1&$B)) -ne 0 ]; then Ans="${Ans}X"
|
||||
else Ans="${Ans}_"
|
||||
fi
|
||||
done
|
||||
echo $Ans
|
||||
}
|
||||
|
||||
for x in $(seq 0 255); do
|
||||
printf "#define $(bits $x)\t0x%02x\n" $x
|
||||
done
|
||||
|
||||
*/
|
||||
|
||||
#define ________ 0x00
|
||||
#define _______X 0x01
|
||||
#define ______X_ 0x02
|
||||
#define ______XX 0x03
|
||||
#define _____X__ 0x04
|
||||
#define _____X_X 0x05
|
||||
#define _____XX_ 0x06
|
||||
#define _____XXX 0x07
|
||||
#define ____X___ 0x08
|
||||
#define ____X__X 0x09
|
||||
#define ____X_X_ 0x0a
|
||||
#define ____X_XX 0x0b
|
||||
#define ____XX__ 0x0c
|
||||
#define ____XX_X 0x0d
|
||||
#define ____XXX_ 0x0e
|
||||
#define ____XXXX 0x0f
|
||||
#define ___X____ 0x10
|
||||
#define ___X___X 0x11
|
||||
#define ___X__X_ 0x12
|
||||
#define ___X__XX 0x13
|
||||
#define ___X_X__ 0x14
|
||||
#define ___X_X_X 0x15
|
||||
#define ___X_XX_ 0x16
|
||||
#define ___X_XXX 0x17
|
||||
#define ___XX___ 0x18
|
||||
#define ___XX__X 0x19
|
||||
#define ___XX_X_ 0x1a
|
||||
#define ___XX_XX 0x1b
|
||||
#define ___XXX__ 0x1c
|
||||
#define ___XXX_X 0x1d
|
||||
#define ___XXXX_ 0x1e
|
||||
#define ___XXXXX 0x1f
|
||||
#define __X_____ 0x20
|
||||
#define __X____X 0x21
|
||||
#define __X___X_ 0x22
|
||||
#define __X___XX 0x23
|
||||
#define __X__X__ 0x24
|
||||
#define __X__X_X 0x25
|
||||
#define __X__XX_ 0x26
|
||||
#define __X__XXX 0x27
|
||||
#define __X_X___ 0x28
|
||||
#define __X_X__X 0x29
|
||||
#define __X_X_X_ 0x2a
|
||||
#define __X_X_XX 0x2b
|
||||
#define __X_XX__ 0x2c
|
||||
#define __X_XX_X 0x2d
|
||||
#define __X_XXX_ 0x2e
|
||||
#define __X_XXXX 0x2f
|
||||
#define __XX____ 0x30
|
||||
#define __XX___X 0x31
|
||||
#define __XX__X_ 0x32
|
||||
#define __XX__XX 0x33
|
||||
#define __XX_X__ 0x34
|
||||
#define __XX_X_X 0x35
|
||||
#define __XX_XX_ 0x36
|
||||
#define __XX_XXX 0x37
|
||||
#define __XXX___ 0x38
|
||||
#define __XXX__X 0x39
|
||||
#define __XXX_X_ 0x3a
|
||||
#define __XXX_XX 0x3b
|
||||
#define __XXXX__ 0x3c
|
||||
#define __XXXX_X 0x3d
|
||||
#define __XXXXX_ 0x3e
|
||||
#define __XXXXXX 0x3f
|
||||
#define _X______ 0x40
|
||||
#define _X_____X 0x41
|
||||
#define _X____X_ 0x42
|
||||
#define _X____XX 0x43
|
||||
#define _X___X__ 0x44
|
||||
#define _X___X_X 0x45
|
||||
#define _X___XX_ 0x46
|
||||
#define _X___XXX 0x47
|
||||
#define _X__X___ 0x48
|
||||
#define _X__X__X 0x49
|
||||
#define _X__X_X_ 0x4a
|
||||
#define _X__X_XX 0x4b
|
||||
#define _X__XX__ 0x4c
|
||||
#define _X__XX_X 0x4d
|
||||
#define _X__XXX_ 0x4e
|
||||
#define _X__XXXX 0x4f
|
||||
#define _X_X____ 0x50
|
||||
#define _X_X___X 0x51
|
||||
#define _X_X__X_ 0x52
|
||||
#define _X_X__XX 0x53
|
||||
#define _X_X_X__ 0x54
|
||||
#define _X_X_X_X 0x55
|
||||
#define _X_X_XX_ 0x56
|
||||
#define _X_X_XXX 0x57
|
||||
#define _X_XX___ 0x58
|
||||
#define _X_XX__X 0x59
|
||||
#define _X_XX_X_ 0x5a
|
||||
#define _X_XX_XX 0x5b
|
||||
#define _X_XXX__ 0x5c
|
||||
#define _X_XXX_X 0x5d
|
||||
#define _X_XXXX_ 0x5e
|
||||
#define _X_XXXXX 0x5f
|
||||
#define _XX_____ 0x60
|
||||
#define _XX____X 0x61
|
||||
#define _XX___X_ 0x62
|
||||
#define _XX___XX 0x63
|
||||
#define _XX__X__ 0x64
|
||||
#define _XX__X_X 0x65
|
||||
#define _XX__XX_ 0x66
|
||||
#define _XX__XXX 0x67
|
||||
#define _XX_X___ 0x68
|
||||
#define _XX_X__X 0x69
|
||||
#define _XX_X_X_ 0x6a
|
||||
#define _XX_X_XX 0x6b
|
||||
#define _XX_XX__ 0x6c
|
||||
#define _XX_XX_X 0x6d
|
||||
#define _XX_XXX_ 0x6e
|
||||
#define _XX_XXXX 0x6f
|
||||
#define _XXX____ 0x70
|
||||
#define _XXX___X 0x71
|
||||
#define _XXX__X_ 0x72
|
||||
#define _XXX__XX 0x73
|
||||
#define _XXX_X__ 0x74
|
||||
#define _XXX_X_X 0x75
|
||||
#define _XXX_XX_ 0x76
|
||||
#define _XXX_XXX 0x77
|
||||
#define _XXXX___ 0x78
|
||||
#define _XXXX__X 0x79
|
||||
#define _XXXX_X_ 0x7a
|
||||
#define _XXXX_XX 0x7b
|
||||
#define _XXXXX__ 0x7c
|
||||
#define _XXXXX_X 0x7d
|
||||
#define _XXXXXX_ 0x7e
|
||||
#define _XXXXXXX 0x7f
|
||||
#define X_______ 0x80
|
||||
#define X______X 0x81
|
||||
#define X_____X_ 0x82
|
||||
#define X_____XX 0x83
|
||||
#define X____X__ 0x84
|
||||
#define X____X_X 0x85
|
||||
#define X____XX_ 0x86
|
||||
#define X____XXX 0x87
|
||||
#define X___X___ 0x88
|
||||
#define X___X__X 0x89
|
||||
#define X___X_X_ 0x8a
|
||||
#define X___X_XX 0x8b
|
||||
#define X___XX__ 0x8c
|
||||
#define X___XX_X 0x8d
|
||||
#define X___XXX_ 0x8e
|
||||
#define X___XXXX 0x8f
|
||||
#define X__X____ 0x90
|
||||
#define X__X___X 0x91
|
||||
#define X__X__X_ 0x92
|
||||
#define X__X__XX 0x93
|
||||
#define X__X_X__ 0x94
|
||||
#define X__X_X_X 0x95
|
||||
#define X__X_XX_ 0x96
|
||||
#define X__X_XXX 0x97
|
||||
#define X__XX___ 0x98
|
||||
#define X__XX__X 0x99
|
||||
#define X__XX_X_ 0x9a
|
||||
#define X__XX_XX 0x9b
|
||||
#define X__XXX__ 0x9c
|
||||
#define X__XXX_X 0x9d
|
||||
#define X__XXXX_ 0x9e
|
||||
#define X__XXXXX 0x9f
|
||||
#define X_X_____ 0xa0
|
||||
#define X_X____X 0xa1
|
||||
#define X_X___X_ 0xa2
|
||||
#define X_X___XX 0xa3
|
||||
#define X_X__X__ 0xa4
|
||||
#define X_X__X_X 0xa5
|
||||
#define X_X__XX_ 0xa6
|
||||
#define X_X__XXX 0xa7
|
||||
#define X_X_X___ 0xa8
|
||||
#define X_X_X__X 0xa9
|
||||
#define X_X_X_X_ 0xaa
|
||||
#define X_X_X_XX 0xab
|
||||
#define X_X_XX__ 0xac
|
||||
#define X_X_XX_X 0xad
|
||||
#define X_X_XXX_ 0xae
|
||||
#define X_X_XXXX 0xaf
|
||||
#define X_XX____ 0xb0
|
||||
#define X_XX___X 0xb1
|
||||
#define X_XX__X_ 0xb2
|
||||
#define X_XX__XX 0xb3
|
||||
#define X_XX_X__ 0xb4
|
||||
#define X_XX_X_X 0xb5
|
||||
#define X_XX_XX_ 0xb6
|
||||
#define X_XX_XXX 0xb7
|
||||
#define X_XXX___ 0xb8
|
||||
#define X_XXX__X 0xb9
|
||||
#define X_XXX_X_ 0xba
|
||||
#define X_XXX_XX 0xbb
|
||||
#define X_XXXX__ 0xbc
|
||||
#define X_XXXX_X 0xbd
|
||||
#define X_XXXXX_ 0xbe
|
||||
#define X_XXXXXX 0xbf
|
||||
#define XX______ 0xc0
|
||||
#define XX_____X 0xc1
|
||||
#define XX____X_ 0xc2
|
||||
#define XX____XX 0xc3
|
||||
#define XX___X__ 0xc4
|
||||
#define XX___X_X 0xc5
|
||||
#define XX___XX_ 0xc6
|
||||
#define XX___XXX 0xc7
|
||||
#define XX__X___ 0xc8
|
||||
#define XX__X__X 0xc9
|
||||
#define XX__X_X_ 0xca
|
||||
#define XX__X_XX 0xcb
|
||||
#define XX__XX__ 0xcc
|
||||
#define XX__XX_X 0xcd
|
||||
#define XX__XXX_ 0xce
|
||||
#define XX__XXXX 0xcf
|
||||
#define XX_X____ 0xd0
|
||||
#define XX_X___X 0xd1
|
||||
#define XX_X__X_ 0xd2
|
||||
#define XX_X__XX 0xd3
|
||||
#define XX_X_X__ 0xd4
|
||||
#define XX_X_X_X 0xd5
|
||||
#define XX_X_XX_ 0xd6
|
||||
#define XX_X_XXX 0xd7
|
||||
#define XX_XX___ 0xd8
|
||||
#define XX_XX__X 0xd9
|
||||
#define XX_XX_X_ 0xda
|
||||
#define XX_XX_XX 0xdb
|
||||
#define XX_XXX__ 0xdc
|
||||
#define XX_XXX_X 0xdd
|
||||
#define XX_XXXX_ 0xde
|
||||
#define XX_XXXXX 0xdf
|
||||
#define XXX_____ 0xe0
|
||||
#define XXX____X 0xe1
|
||||
#define XXX___X_ 0xe2
|
||||
#define XXX___XX 0xe3
|
||||
#define XXX__X__ 0xe4
|
||||
#define XXX__X_X 0xe5
|
||||
#define XXX__XX_ 0xe6
|
||||
#define XXX__XXX 0xe7
|
||||
#define XXX_X___ 0xe8
|
||||
#define XXX_X__X 0xe9
|
||||
#define XXX_X_X_ 0xea
|
||||
#define XXX_X_XX 0xeb
|
||||
#define XXX_XX__ 0xec
|
||||
#define XXX_XX_X 0xed
|
||||
#define XXX_XXX_ 0xee
|
||||
#define XXX_XXXX 0xef
|
||||
#define XXXX____ 0xf0
|
||||
#define XXXX___X 0xf1
|
||||
#define XXXX__X_ 0xf2
|
||||
#define XXXX__XX 0xf3
|
||||
#define XXXX_X__ 0xf4
|
||||
#define XXXX_X_X 0xf5
|
||||
#define XXXX_XX_ 0xf6
|
||||
#define XXXX_XXX 0xf7
|
||||
#define XXXXX___ 0xf8
|
||||
#define XXXXX__X 0xf9
|
||||
#define XXXXX_X_ 0xfa
|
||||
#define XXXXX_XX 0xfb
|
||||
#define XXXXXX__ 0xfc
|
||||
#define XXXXXX_X 0xfd
|
||||
#define XXXXXXX_ 0xfe
|
||||
#define XXXXXXXX 0xff
|
||||
|
||||
// here are fonts themself
|
||||
#include "font14.h"
|
||||
#include "fontNumb16.h"
|
||||
#include "fontNumb10.h"
|
||||
#include "fontNumb8.h"
|
||||
|
||||
static const afont FONTS[] = {
|
||||
[FONT14] = {font14_table, font14_encoding, FONT14HEIGHT, FONT14BYTES, FONT14BASELINE},
|
||||
[FONTN16] = {fontNumb16_table, fontNumb16_encoding, FONTNUMB16HEIGHT, FONTNUMB16BYTES, FONTNUMB16BASELINE},
|
||||
[FONTN10] = {fontNumb10_table, fontNumb10_encoding, FONTNUMB10HEIGHT, FONTNUMB10BYTES, FONTNUMB10BASELINE},
|
||||
[FONTN8] = {fontNumb8_table, fontNumb8_encoding, FONTNUMB8HEIGHT, FONTNUMB8BYTES, FONTNUMB8BASELINE},
|
||||
};
|
||||
|
||||
const afont *curfont = &FONTS[FONT14];
|
||||
|
||||
/**
|
||||
* @brief choose_font - font selector
|
||||
* @param newfont - font to choose
|
||||
* @return 0 if all OK
|
||||
*/
|
||||
int choose_font(font_t newfont){
|
||||
if(newfont >= FONT_T_MAX || newfont <= FONT_T_MIN) return 1;
|
||||
curfont = &FONTS[newfont];
|
||||
return 0;
|
||||
}
|
||||
|
||||
const uint8_t *font_char(uint8_t Char){
|
||||
uint8_t idx = curfont->enctable[Char];
|
||||
if(!idx) return NULL; // no this character in font
|
||||
return &(curfont->font[idx*(curfont->bytes+1)]);
|
||||
}
|
||||
48
F1-nolib/chronometer_v3/fonts.h
Normal file
48
F1-nolib/chronometer_v3/fonts.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* This file is part of the LED_screen project.
|
||||
* Copyright 2019 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef FONTS_H__
|
||||
#define FONTS_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// type for font choosing
|
||||
typedef enum{
|
||||
FONT_T_MIN = -1, // no fonts <= this
|
||||
FONT14, // 16x16, font height near 14px
|
||||
FONTN16, // numbers 16x8, font height 16px
|
||||
FONTN10, // numbers 10x8, font height 10px
|
||||
FONTN8, // numbers and 'A'/'O', height 8px
|
||||
FONT_T_MAX // no fonts >= this
|
||||
} font_t;
|
||||
|
||||
int choose_font(font_t newfont);
|
||||
const uint8_t *font_char(uint8_t Char);
|
||||
|
||||
typedef struct{
|
||||
const uint8_t *font; // font inself
|
||||
const uint8_t *enctable; // font encoding table
|
||||
uint8_t height; // full font matrix height
|
||||
uint8_t bytes; // amount of bytes in font matrix
|
||||
uint8_t baseline; // baseline position (coordinate from bottom line)
|
||||
} afont;
|
||||
|
||||
extern const afont *curfont;
|
||||
|
||||
#endif // FONTS_H__
|
||||
281
F1-nolib/chronometer_v3/hardware.c
Normal file
281
F1-nolib/chronometer_v3/hardware.c
Normal file
@ -0,0 +1,281 @@
|
||||
/*
|
||||
* geany_encoding=koi8-r
|
||||
* hardware.c - hardware-dependent macros & functions
|
||||
*
|
||||
* Copyright 2018 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 "adc.h"
|
||||
#include "hardware.h"
|
||||
#include "flash.h"
|
||||
#include "lidar.h"
|
||||
#include "str.h"
|
||||
#include "time.h"
|
||||
#include "usart.h"
|
||||
|
||||
#include <string.h> // memcpy
|
||||
|
||||
uint8_t buzzer_on = 1; // buzzer ON by default
|
||||
uint8_t LEDSon = 1; // LEDS are working
|
||||
// ports of triggers: PB0, PB1, PB3
|
||||
static GPIO_TypeDef *trigport[DIGTRIG_AMOUNT] = {GPIOB, GPIOB, GPIOB};
|
||||
// pins of triggers: 0, 1, 3
|
||||
static uint16_t trigpin[DIGTRIG_AMOUNT] = {1<<0, 1<<1, 1<<3};
|
||||
// value of pin in `triggered` state
|
||||
static uint8_t trigstate[DIGTRIG_AMOUNT];
|
||||
// time of triggers shot
|
||||
trigtime shottime[TRIGGERS_AMOUNT];
|
||||
// Tms value when they shot
|
||||
uint32_t shotms[TRIGGERS_AMOUNT];
|
||||
// trigger length (-1 if > MAX_TRIG_LEN)
|
||||
int16_t triglen[TRIGGERS_AMOUNT];
|
||||
// if trigger[N] shots, the bit N will be 1
|
||||
uint8_t trigger_shot = 0;
|
||||
|
||||
static inline void gpio_setup(){
|
||||
BUZZER_OFF(); // turn off buzzer @start
|
||||
LED_on(); // turn ON LED0 @start
|
||||
LED1_off(); // turn off LED1 @start
|
||||
USBPU_OFF(); // turn off USB pullup @start
|
||||
// Enable clocks to the GPIO subsystems (PB for ADC), turn on AFIO clocking enable EXTI & so on
|
||||
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_AFIOEN;
|
||||
// turn off JTAG (PA15, PB3)
|
||||
AFIO->MAPR = AFIO_MAPR_SWJ_CFG_JTAGDISABLE;
|
||||
// AFIO->MAPR = AFIO_MAPR_SWJ_CFG_DISABLE;
|
||||
// PORTA
|
||||
// pullups: PA1 - PPS, PA15 - USB pullup
|
||||
GPIOA->ODR = (1<<1)|(1<<15);
|
||||
// PPS pin (PA1) - input with weak pullup, PA6 - SCLK of LED screen
|
||||
GPIOA->CRL = CRL(1, CNF_PUDINPUT|MODE_INPUT) | CRL(6, CNF_PPOUTPUT|MODE_SLOW);
|
||||
EXTI->IMR = EXTI_IMR_MR1; // mask PA1
|
||||
// interrupt on pulse front: buttons - 1->0, PPS - 0->1
|
||||
EXTI->RTSR = EXTI_RTSR_TR1; // rising trigger for PPS
|
||||
NVIC_EnableIRQ(EXTI1_IRQn); // enable PPS interrupt
|
||||
// Set USB pullup (PA15) - opendrain output
|
||||
GPIOA->CRH = CRH(15, CNF_ODOUTPUT|MODE_SLOW);
|
||||
// PORTB
|
||||
// Set leds (PB8/9) as opendrain output
|
||||
GPIOB->CRH = CRH(8, CNF_ODOUTPUT|MODE_SLOW) | CRH(9, CNF_ODOUTPUT|MODE_SLOW);
|
||||
// TRIGGERS: PB0,1,3; SCREEN pins: A,B - PB6,PB7;
|
||||
GPIOB->CRL = CRL(0, CNF_PUDINPUT|MODE_INPUT) | CRL(1, CNF_PUDINPUT|MODE_INPUT) | CRL(3, CNF_PUDINPUT|MODE_INPUT) |
|
||||
CRL(6, CNF_PPOUTPUT|MODE_SLOW) | CRL(7, CNF_PPOUTPUT|MODE_SLOW);
|
||||
// PORTC
|
||||
// buzzer (PC13): pushpull output
|
||||
GPIOC->CRH = CRH(13, CNF_PPOUTPUT|MODE_SLOW);
|
||||
// exti: PB0, 3; PA1
|
||||
AFIO->EXTICR[0] = AFIO_EXTICR1_EXTI0_PB | AFIO_EXTICR1_EXTI1_PA | AFIO_EXTICR1_EXTI3_PB;
|
||||
// PB0/1/3 - triggers
|
||||
for(int i = 0; i < DIGTRIG_AMOUNT; ++i){
|
||||
uint16_t pin = trigpin[i];
|
||||
if(pin == 1<<1) continue; // omit PB1
|
||||
// fill trigstate array
|
||||
uint8_t trgs = (the_conf.trigstate & (1<<i)) ? 1 : 0;
|
||||
trigstate[i] = trgs;
|
||||
trigport[i]->ODR |= pin; // turn on pullups
|
||||
if(i != 1){ // turn interrupts on
|
||||
EXTI->IMR |= pin;
|
||||
if(trgs){ // triggered @1 -> rising interrupt
|
||||
EXTI->RTSR |= pin;
|
||||
}else{ // falling interrupt
|
||||
EXTI->FTSR |= pin;
|
||||
}
|
||||
}
|
||||
}
|
||||
// ---------------------> config-depengent block, interrupts & pullup inputs:
|
||||
// !!! change AFIO_EXTICRx if some triggers not @GPIOA
|
||||
NVIC_EnableIRQ(EXTI0_IRQn); // PB0
|
||||
NVIC_EnableIRQ(EXTI3_IRQn); // PB3
|
||||
// <---------------------
|
||||
}
|
||||
|
||||
static inline void adc_setup(){
|
||||
GPIOB->CRL |= CRL(0, CNF_ANALOG|MODE_INPUT);
|
||||
uint32_t ctr = 0;
|
||||
// Enable clocking
|
||||
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
|
||||
RCC->CFGR &= ~(RCC_CFGR_ADCPRE);
|
||||
RCC->CFGR |= RCC_CFGR_ADCPRE_DIV8; // ADC clock = RCC / 8
|
||||
// sampling time - 239.5 cycles for channels 16 and 17
|
||||
ADC1->SMPR1 = ADC_SMPR1_SMP16 | ADC_SMPR1_SMP17;
|
||||
// we have three conversions in group -> ADC1->SQR1[L] = 2, order: 16->17
|
||||
// Tsens == 16, Vdd == 17
|
||||
ADC1->SQR3 = (16<<0) | (17<<5);
|
||||
ADC1->SQR1 = ADC_SQR1_L_0; // 2 conversions
|
||||
ADC1->CR1 |= ADC_CR1_SCAN; // scan mode
|
||||
// DMA configuration
|
||||
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
|
||||
DMA1_Channel1->CPAR = (uint32_t) (&(ADC1->DR));
|
||||
DMA1_Channel1->CMAR = (uint32_t)(ADC_array);
|
||||
DMA1_Channel1->CNDTR = NUMBER_OF_ADC_CHANNELS * 9;
|
||||
DMA1_Channel1->CCR |= DMA_CCR_MINC | DMA_CCR_MSIZE_0 | DMA_CCR_PSIZE_0
|
||||
| DMA_CCR_CIRC | DMA_CCR_PL | DMA_CCR_EN;
|
||||
// continuous mode & DMA; enable vref & Tsens; wake up ADC
|
||||
ADC1->CR2 |= ADC_CR2_DMA | ADC_CR2_TSVREFE | ADC_CR2_CONT | ADC_CR2_ADON;
|
||||
// wait for Tstab - at least 1us
|
||||
while(++ctr < 0xff) nop();
|
||||
// calibration
|
||||
ADC1->CR2 |= ADC_CR2_RSTCAL;
|
||||
ctr = 0; while((ADC1->CR2 & ADC_CR2_RSTCAL) && ++ctr < 0xfffff);
|
||||
ADC1->CR2 |= ADC_CR2_CAL;
|
||||
ctr = 0; while((ADC1->CR2 & ADC_CR2_CAL) && ++ctr < 0xfffff);
|
||||
// turn ON ADC
|
||||
ADC1->CR2 |= ADC_CR2_ADON;
|
||||
}
|
||||
|
||||
void hw_setup(){
|
||||
gpio_setup();
|
||||
adc_setup();
|
||||
}
|
||||
|
||||
static trigtime trgtm;
|
||||
void savetrigtime(){
|
||||
trgtm.millis = Timer;
|
||||
memcpy(&trgtm.Time, ¤t_time, sizeof(curtime));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief fillshotms - save trigger shot time
|
||||
* @param i - trigger number
|
||||
*/
|
||||
void fillshotms(int i){
|
||||
if(i < 0 || i >= TRIGGERS_AMOUNT) return;
|
||||
if(Tms - shotms[i] > (uint32_t)the_conf.trigpause[i] || i == LIDAR_TRIGGER){
|
||||
memcpy(&shottime[i], &trgtm, sizeof(trigtime));
|
||||
shotms[i] = Tms;
|
||||
trigger_shot |= 1<<i;
|
||||
BUZZER_ON();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief fillunshotms - calculate trigger length time
|
||||
*/
|
||||
void fillunshotms(){
|
||||
if(!trigger_shot) return;
|
||||
uint8_t X = 1;
|
||||
for(int i = 0; i < TRIGGERS_AMOUNT; ++i, X<<=1){
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
// check whether trigger is OFF but shot recently
|
||||
if(trigger_shot & X){
|
||||
uint32_t len = Tms - shotms[i];
|
||||
uint8_t rdy = 0;
|
||||
if(len > MAX_TRIG_LEN){
|
||||
triglen[i] = -1;
|
||||
rdy = 1;
|
||||
}else triglen[i] = (int16_t) len;
|
||||
if(i == LIDAR_TRIGGER){
|
||||
if(!parse_lidar_data(NULL)) rdy = 1;
|
||||
}else{
|
||||
uint8_t pinval = (trigport[i]->IDR & trigpin[i]) ? 1 : 0;
|
||||
if(pinval != trigstate[i]) rdy = 1; // trigger is OFF
|
||||
}
|
||||
if(rdy){
|
||||
if(i != LIDAR_TRIGGER) shotms[i] = Tms;
|
||||
show_trigger_shot(X);
|
||||
trigger_shot &= ~X;
|
||||
// now trigger data is in lastLog -> store it in flash
|
||||
if(the_conf.defflags & FLAG_SAVE_EVENTS){
|
||||
if(store_log(&lastLog)) sendstring("\n\nError saving event!\n\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void exti0_isr(){ // PB0 - trig0
|
||||
EXTI->PR = EXTI_PR_PR0;
|
||||
if(!chkshtr) return;
|
||||
savetrigtime();
|
||||
fillshotms(0);
|
||||
}
|
||||
|
||||
void exti1_isr(){ // PPS - PA1
|
||||
systick_correction();
|
||||
LED_off(); // turn off LED0 @ each PPS
|
||||
EXTI->PR = EXTI_PR_PR1;
|
||||
}
|
||||
|
||||
void chkTrig1(){
|
||||
// ================> HARD HARDWARE DEPENDENT: PB1 trigger
|
||||
if(!chkshtr) return;
|
||||
static uint8_t oldstate = 0;
|
||||
uint8_t curstate = GPIOB->IDR & 2;
|
||||
if(Tms < 100){ // don't mind for first 100ms
|
||||
oldstate = curstate;
|
||||
return;
|
||||
}
|
||||
if(curstate == oldstate){ // state didn't changed
|
||||
return;
|
||||
}
|
||||
oldstate = curstate;
|
||||
if(curstate != (the_conf.trigstate & 2)) return; // relax from trigger
|
||||
savetrigtime();
|
||||
fillshotms(1);
|
||||
// <================
|
||||
}
|
||||
|
||||
void exti3_isr(){ // PB3 - trig2
|
||||
EXTI->PR = EXTI_PR_PR3;
|
||||
if(!chkshtr) return;
|
||||
savetrigtime();
|
||||
fillshotms(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief gettrig - get trigger state
|
||||
* @return 1 if trigger active or 0
|
||||
*/
|
||||
uint8_t gettrig(uint8_t N){
|
||||
if(N >= TRIGGERS_AMOUNT) return 0;
|
||||
uint8_t curval = (trigport[N]->IDR & trigpin[N]) ? 1 : 0;
|
||||
if(curval == trigstate[N]) return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
static uint32_t Ton = 0; // Time of first buzzer check
|
||||
void chk_buzzer(){
|
||||
if(!BUZZER_GET()) return; // buzzer if OFF
|
||||
if(!trigger_shot){ // should we turn off buzzer?
|
||||
uint8_t notrg = 1;
|
||||
for(int i = 0; i < DIGTRIG_AMOUNT; ++i){
|
||||
uint8_t curval = (trigport[i]->IDR & trigpin[i]) ? 1 : 0;
|
||||
if(curval == trigstate[i]){
|
||||
notrg = 0; // cheep while digital trigger is ON
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(notrg){ // turn off buzzer when there's no trigger events & timeout came
|
||||
if(Tms - Ton < BUZZER_CHEEP_TIME) return;
|
||||
Ton = 0;
|
||||
BUZZER_OFF();
|
||||
}
|
||||
}else{ // buzzer is ON - check timer
|
||||
if(Ton == 0){
|
||||
Ton = Tms;
|
||||
if(!Ton) Ton = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// make a short squeak
|
||||
void buzzer_squeak(){
|
||||
Ton = Tms;
|
||||
if(!Ton) Ton = 1;
|
||||
BUZZER_ON();
|
||||
}
|
||||
131
F1-nolib/chronometer_v3/hardware.h
Normal file
131
F1-nolib/chronometer_v3/hardware.h
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* geany_encoding=koi8-r
|
||||
* hardware.h
|
||||
*
|
||||
* Copyright 2018 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 __HARDWARE_H__
|
||||
#define __HARDWARE_H__
|
||||
|
||||
#include "stm32f1.h"
|
||||
#include "time.h"
|
||||
|
||||
#ifdef EBUG
|
||||
#define DO_PRAGMA(x) _Pragma (#x)
|
||||
#define TODO(x) DO_PRAGMA(message #x)
|
||||
#else
|
||||
#define TODO(x)
|
||||
#endif
|
||||
|
||||
// only 2 ADC channels used: Tmcu and Vdd
|
||||
#define NUMBER_OF_ADC_CHANNELS (2)
|
||||
#define ADC_TMCU_CHANNEL (0)
|
||||
#define ADC_VDD_CHANNEL (1)
|
||||
|
||||
// onboard LEDs - PB8/PB9
|
||||
#define LED0_port GPIOB
|
||||
#define LED0_pin (1<<9)
|
||||
#define LED1_port GPIOB
|
||||
#define LED1_pin (1<<8)
|
||||
|
||||
// buzzer (1 - active) - PC13
|
||||
extern uint8_t buzzer_on;
|
||||
#define BUZZER_port GPIOC
|
||||
#define BUZZER_pin (1<<13)
|
||||
#define BUZZER_ON() do{if(buzzer_on)pin_set(BUZZER_port, BUZZER_pin);}while(0)
|
||||
#define BUZZER_OFF() pin_clear(BUZZER_port, BUZZER_pin)
|
||||
#define BUZZER_GET() (pin_read(BUZZER_port, BUZZER_pin))
|
||||
// minimal cheeping time of buzzer (ms)
|
||||
#define BUZZER_CHEEP_TIME 500
|
||||
|
||||
// PPS pin - PA1
|
||||
#define PPS_port GPIOA
|
||||
#define PPS_pin (1<<1)
|
||||
|
||||
// PPS and triggers state
|
||||
// amount of triggers, should be less than 9; 4 - 0..2 - switches, 3 - LIDAR
|
||||
#define TRIGGERS_AMOUNT 4
|
||||
// number of LIDAR trigger
|
||||
#define LIDAR_TRIGGER 3
|
||||
// amount of digital triggers (on interrupts)
|
||||
#define DIGTRIG_AMOUNT 3
|
||||
// max length of trigger event (ms)
|
||||
#define MAX_TRIG_LEN 1000
|
||||
|
||||
uint8_t gettrig(uint8_t N);
|
||||
void fillshotms(int i);
|
||||
void fillunshotms();
|
||||
void savetrigtime();
|
||||
#define GET_PPS() ((GPIOA->IDR & (1<<1)) ? 1 : 0)
|
||||
|
||||
// USB pullup - PA15
|
||||
#define USBPU_port GPIOA
|
||||
#define USBPU_pin (1<<15)
|
||||
#define USBPU_ON() pin_clear(USBPU_port, USBPU_pin)
|
||||
#define USBPU_OFF() pin_set(USBPU_port, USBPU_pin)
|
||||
|
||||
#define LED_blink() do{if(LEDSon)pin_toggle(LED0_port, LED0_pin);}while(0)
|
||||
#define LED_on() do{if(LEDSon)pin_clear(LED0_port, LED0_pin);}while(0)
|
||||
#define LED_off() do{pin_set(LED0_port, LED0_pin);}while(0)
|
||||
#define LED1_blink() do{if(LEDSon)pin_toggle(LED1_port, LED1_pin);}while(0)
|
||||
#define LED1_on() do{if(LEDSon)pin_clear(LED1_port, LED1_pin);}while(0)
|
||||
#define LED1_off() do{pin_set(LED1_port, LED1_pin);}while(0)
|
||||
|
||||
// GPS USART == USART2, LIDAR USART == USART3
|
||||
#define GPS_USART (2)
|
||||
#define LIDAR_USART (3)
|
||||
|
||||
// SPI DMA channel
|
||||
#define DMA_SPI_Channel DMA1_Channel3
|
||||
// SCREEN PINs: A,B - PB6,PB7; SCLK - PA6
|
||||
#define A_port GPIOB
|
||||
#define A_pin (1<<6)
|
||||
#define B_port GPIOB
|
||||
#define B_pin (1<<7)
|
||||
// SCLK/nOE connected together
|
||||
#define SCLK_port GPIOA
|
||||
#define SCLK_pin (1<<6)
|
||||
#define SET(x) pin_set(x ## _port, x ## _pin)
|
||||
#define CLEAR(x) pin_clear(x ## _port, x ## _pin)
|
||||
#define TOGGLE(x) pin_toggle(x ## _port, x ## _pin)
|
||||
|
||||
typedef struct{
|
||||
uint32_t millis;
|
||||
curtime Time;
|
||||
} trigtime;
|
||||
|
||||
// turn on/off LEDs:
|
||||
extern uint8_t LEDSon;
|
||||
// time of triggers shot
|
||||
extern trigtime shottime[TRIGGERS_AMOUNT];
|
||||
// length (in ms) of trigger event (-1 if > MAX_TRIG_LEN
|
||||
extern int16_t triglen[TRIGGERS_AMOUNT];
|
||||
// if trigger[N] shots, the bit N will be 1
|
||||
extern uint8_t trigger_shot;
|
||||
// Tms value when they shot
|
||||
extern uint32_t shotms[TRIGGERS_AMOUNT];
|
||||
|
||||
void chk_buzzer();
|
||||
void buzzer_squeak();
|
||||
void hw_setup();
|
||||
|
||||
void chkTrig1();
|
||||
|
||||
#endif // __HARDWARE_H__
|
||||
81
F1-nolib/chronometer_v3/lidar.c
Normal file
81
F1-nolib/chronometer_v3/lidar.c
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* This file is part of the chronometer project.
|
||||
* Copyright 2019 Edward V. Emelianov <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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "flash.h"
|
||||
#include "lidar.h"
|
||||
#include "usart.h"
|
||||
|
||||
uint16_t last_lidar_dist = 0;
|
||||
uint16_t last_lidar_stren = 0;
|
||||
uint16_t lidar_triggered_dist = 0;
|
||||
|
||||
extern uint32_t shotms[];
|
||||
|
||||
/**
|
||||
* @brief parse_lidar_data - parsing of string from lidar
|
||||
* @param txt - the string or NULL (if you want just check trigger state)
|
||||
* @return trigger state
|
||||
*/
|
||||
uint8_t parse_lidar_data(char *txt){
|
||||
static uint8_t triggered = 0;
|
||||
if(!txt){
|
||||
// clear trigger state after timeout -> need to monitor lidar
|
||||
uint32_t len = Tms - shotms[LIDAR_TRIGGER];
|
||||
//if(len > MAX_TRIG_LEN || len > (uint32_t)the_conf.trigpause[LIDAR_TRIGGER]){
|
||||
if(len > MAX_TRIG_LEN){
|
||||
triggered = 0;
|
||||
DBG("MAX time gone, untrigger!");
|
||||
}
|
||||
return triggered;
|
||||
}
|
||||
last_lidar_dist = txt[2] | (txt[3] << 8);
|
||||
last_lidar_stren = txt[4] | (txt[5] << 8);
|
||||
if(last_lidar_stren < LIDAR_LOWER_STREN) return 0; // weak signal
|
||||
if(!lidar_triggered_dist){ // first run
|
||||
lidar_triggered_dist = last_lidar_dist;
|
||||
return 0;
|
||||
}
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
if(triggered){ // check if body gone
|
||||
if(last_lidar_dist < the_conf.dist_min || last_lidar_dist > the_conf.dist_max || last_lidar_dist > lidar_triggered_dist + LIDAR_DIST_THRES){
|
||||
triggered = 0;
|
||||
#ifdef EBUG
|
||||
SEND("Untriggered! distance=");
|
||||
printu(1, last_lidar_dist);
|
||||
SEND(" signal=");
|
||||
printu(1, last_lidar_stren);
|
||||
newline(1);
|
||||
#endif
|
||||
}
|
||||
}else{
|
||||
if(last_lidar_dist > the_conf.dist_min && last_lidar_dist < the_conf.dist_max){
|
||||
savetrigtime();
|
||||
triggered = 1;
|
||||
lidar_triggered_dist = last_lidar_dist;
|
||||
fillshotms(LIDAR_TRIGGER);
|
||||
#ifdef EBUG
|
||||
SEND("Triggered! distance=");
|
||||
printu(1, last_lidar_dist);
|
||||
SEND(" signal=");
|
||||
printu(1, last_lidar_stren);
|
||||
newline(1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return triggered;
|
||||
}
|
||||
39
F1-nolib/chronometer_v3/lidar.h
Normal file
39
F1-nolib/chronometer_v3/lidar.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* This file is part of the chronometer project.
|
||||
* Copyright 2019 Edward V. Emelianov <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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef LIDAR_H__
|
||||
#define LIDAR_H__
|
||||
#include <stm32f1.h>
|
||||
|
||||
#define LIDAR_FRAME_LEN (9)
|
||||
// frame header
|
||||
#define LIDAR_FRAME_HEADER (0x59)
|
||||
// lower strength limit
|
||||
#define LIDAR_LOWER_STREN (10)
|
||||
// triggered distance threshold - 1 meter
|
||||
#define LIDAR_DIST_THRES (100)
|
||||
#define LIDAR_MIN_DIST (50)
|
||||
#define LIDAR_MAX_DIST (1000)
|
||||
|
||||
extern uint16_t last_lidar_dist;
|
||||
extern uint16_t lidar_triggered_dist;
|
||||
extern uint16_t last_lidar_stren;
|
||||
|
||||
uint8_t parse_lidar_data(char *txt);
|
||||
|
||||
#endif // LIDAR_H__
|
||||
337
F1-nolib/chronometer_v3/main.c
Normal file
337
F1-nolib/chronometer_v3/main.c
Normal file
@ -0,0 +1,337 @@
|
||||
/*
|
||||
* 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 "adc.h"
|
||||
#include "GPS.h"
|
||||
#include "flash.h"
|
||||
#include "fonts.h"
|
||||
#include "hardware.h"
|
||||
#include "lidar.h"
|
||||
#include "screen.h"
|
||||
#include "spi.h"
|
||||
#include "str.h"
|
||||
#include "time.h"
|
||||
#include "usart.h"
|
||||
#include "usb.h"
|
||||
#include "usb_lib.h"
|
||||
|
||||
#ifndef VERSION
|
||||
#define VERSION "0.0.0"
|
||||
#endif
|
||||
|
||||
// global pseudo-milliseconds counter
|
||||
volatile uint32_t Tms = 0;
|
||||
|
||||
/* Called when systick fires */
|
||||
void sys_tick_handler(void){
|
||||
++Tms; // increment pseudo-milliseconds counter
|
||||
if(++Timer == 1000){ // increment milliseconds counter
|
||||
time_increment();
|
||||
}
|
||||
}
|
||||
|
||||
void iwdg_setup(){
|
||||
uint32_t tmout = 16000000;
|
||||
/* Enable the peripheral clock RTC */
|
||||
/* (1) Enable the LSI (40kHz) */
|
||||
/* (2) Wait while it is not ready */
|
||||
RCC->CSR |= RCC_CSR_LSION; /* (1) */
|
||||
while((RCC->CSR & RCC_CSR_LSIRDY) != RCC_CSR_LSIRDY){if(--tmout == 0) break;} /* (2) */
|
||||
/* Configure IWDG */
|
||||
/* (1) Activate IWDG (not needed if done in option bytes) */
|
||||
/* (2) Enable write access to IWDG registers */
|
||||
/* (3) Set prescaler by 64 (1.6ms for each tick) */
|
||||
/* (4) Set reload value to have a rollover each 2s */
|
||||
/* (5) Check if flags are reset */
|
||||
/* (6) Refresh counter */
|
||||
IWDG->KR = IWDG_START; /* (1) */
|
||||
IWDG->KR = IWDG_WRITE_ACCESS; /* (2) */
|
||||
IWDG->PR = IWDG_PR_PR_1; /* (3) */
|
||||
IWDG->RLR = 1250; /* (4) */
|
||||
tmout = 16000000;
|
||||
while(IWDG->SR){if(--tmout == 0) break;} /* (5) */
|
||||
IWDG->KR = IWDG_REFRESH; /* (6) */
|
||||
}
|
||||
|
||||
#define USBBUF 63
|
||||
// usb getline
|
||||
static char *get_USB(){
|
||||
static char tmpbuf[USBBUF+1], *curptr = tmpbuf;
|
||||
static int rest = USBBUF;
|
||||
int x = USB_receive(curptr, rest);
|
||||
if(!x) return NULL;
|
||||
curptr[x] = 0;
|
||||
if(x == 1 && *curptr == 0x7f){ // backspace
|
||||
if(curptr > tmpbuf){
|
||||
--curptr;
|
||||
USB_send("\b \b");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
USB_send(curptr); // echo
|
||||
if(curptr[x-1] == '\n'){ // || curptr[x-1] == '\r'){
|
||||
curptr = tmpbuf;
|
||||
rest = USBBUF;
|
||||
// omit empty lines
|
||||
if(tmpbuf[0] == '\n') return NULL;
|
||||
// and wrong empty lines
|
||||
if(tmpbuf[0] == '\r' && tmpbuf[1] == '\n') return NULL;
|
||||
return tmpbuf;
|
||||
}
|
||||
curptr += x; rest -= x;
|
||||
if(rest <= 0){ // buffer overflow
|
||||
sendstring("\nUSB buffer overflow!\n");
|
||||
curptr = tmpbuf;
|
||||
rest = USBBUF;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void linecoding_handler(usb_LineCoding __attribute__((unused)) *lc){ // get/set line coding
|
||||
#ifdef EBUG
|
||||
SEND("Change speed to ");
|
||||
printu(1, lc->dwDTERate);
|
||||
newline(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static volatile uint8_t USBconn = 0;
|
||||
uint8_t USB_connected = 0; // need for usb.c
|
||||
void clstate_handler(uint16_t __attribute__((unused)) val){ // lesser bits of val: RTS|DTR
|
||||
USBconn = 1; // if == 1 -> send welcome message
|
||||
USB_connected = 1;
|
||||
#if 0
|
||||
if(val & 2){
|
||||
DBG("RTS set");
|
||||
sendstring("RTS set\n");
|
||||
}
|
||||
if(val & 1){
|
||||
DBG("DTR set");
|
||||
sendstring("DTR set\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void break_handler(){ // client disconnected
|
||||
DBG("Disconnected");
|
||||
USB_connected = 0;
|
||||
}
|
||||
|
||||
int main(void){
|
||||
uint32_t lastT = 0, lastTshow = 0; // last time of status check, last time of time displayed
|
||||
uint8_t evtDisp = 0; // last event was displayed
|
||||
sysreset();
|
||||
StartHSE();
|
||||
SysTick_Config(SYSTICK_DEFCONF); // function SysTick_Config decrements argument!
|
||||
// read data stored in flash - before all pins/ports setup!!!
|
||||
flashstorage_init();
|
||||
// !!! hw_setup() should be the first in setup stage
|
||||
hw_setup();
|
||||
USB_setup();
|
||||
USBPU_ON();
|
||||
#ifdef EBUG
|
||||
SEND("This is chronometer version " VERSION ".\n");
|
||||
if(RCC->CSR & RCC_CSR_IWDGRSTF){ // watchdog reset occured
|
||||
SEND("WDGRESET=1\n");
|
||||
}
|
||||
if(RCC->CSR & RCC_CSR_SFTRSTF){ // software reset occured
|
||||
SEND("SOFTRESET=1\n");
|
||||
}
|
||||
#endif
|
||||
RCC->CSR |= RCC_CSR_RMVF; // remove reset flags
|
||||
#ifdef EBUG
|
||||
usarts_setup(); // setup usarts for debug console
|
||||
#endif
|
||||
usarts_setup(); // setup usarts after reading configuration
|
||||
spi_setup();
|
||||
ScreenOFF(); // clear screen
|
||||
PutStringAt(0, SCREEN_HEIGHT-1-curfont->baseline, "Chrono");
|
||||
ConvertScreenBuf();
|
||||
ShowScreen();
|
||||
iwdg_setup();
|
||||
|
||||
while (1){
|
||||
IWDG->KR = IWDG_REFRESH; // refresh watchdog
|
||||
if(Timer > 499) LED_on(); // turn ON LED0 over 0.25s after PPS pulse
|
||||
if(USBconn && Tms > 100){ // USB connection
|
||||
USBconn = 0;
|
||||
sendstring("Chronometer version " VERSION ".\n");
|
||||
}
|
||||
// check if triggers that was recently shot are off now
|
||||
fillunshotms();
|
||||
if(Tms - lastT > 499){
|
||||
if(need2startseq) GPS_send_start_seq();
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
switch(GPS_status){
|
||||
case GPS_VALID:
|
||||
LED1_blink(); // blink LED1 @ VALID time
|
||||
break;
|
||||
case GPS_NOT_VALID:
|
||||
LED1_on(); // shine LED1 @ NON-VALID time
|
||||
break;
|
||||
default:
|
||||
LED1_off(); // turn off LED1 if GPS not found or time unknown
|
||||
}
|
||||
lastT = Tms;
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
transmit_tbuf(1); // non-blocking transmission of data from UART buffer every 0.5s
|
||||
transmit_tbuf(GPS_USART);
|
||||
transmit_tbuf(LIDAR_USART);
|
||||
#if 0
|
||||
#ifdef EBUG
|
||||
static int32_t oldctr = 0;
|
||||
if(timecntr && timecntr != oldctr){
|
||||
oldctr = timecntr;
|
||||
SEND("ticksdiff=");
|
||||
if(ticksdiff < 0){
|
||||
SEND("-");
|
||||
printu(1, -ticksdiff);
|
||||
}else printu(1, ticksdiff);
|
||||
SEND(", timecntr=");
|
||||
printu(1, timecntr);
|
||||
SEND("\nlast_corr_time=");
|
||||
printu(1, last_corr_time);
|
||||
SEND(", Tms=");
|
||||
printu(1, Tms1);
|
||||
SEND("\nTimer=");
|
||||
printu(1, timerval);
|
||||
SEND(", LOAD=");
|
||||
printu(1, SysTick->LOAD);
|
||||
usart_putchar(1, '\n');
|
||||
newline(1);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
if(showtime){ // show current time (HH:MM:SS.S) every 100ms
|
||||
if(Tms - lastTtrig < the_conf.ledshow_time && showshtr){ // show last event on screen
|
||||
if(!evtDisp){
|
||||
evtDisp = 1;
|
||||
FillScreen(0);
|
||||
choose_font(FONTN10);
|
||||
char *tm = get_scrntime(&lastLog.shottime.Time, lastLog.shottime.millis);
|
||||
tm[11] = 0; // throw out thousands
|
||||
uint16_t w = GetStrWidth(tm);
|
||||
PutStringAt((SCREEN_WIDTH-w-1)/2, SCREEN_HEIGHT-4-curfont->baseline, tm);
|
||||
ConvertScreenBuf();
|
||||
ShowScreen();
|
||||
}
|
||||
}else if(Tms - lastTshow > 99 && Timer < 5){ // change time value
|
||||
lastTshow = Tms;
|
||||
evtDisp = 0;
|
||||
FillScreen(0);
|
||||
choose_font(FONTN16);
|
||||
if(startflags && timetostartO == 0){ // countdown
|
||||
char s[3] = {0,0,0}, *buf=s;
|
||||
uint8_t N = 59 - current_time.S; // show "0" @ 59 seconds!
|
||||
if(N == 0){ // countdown ends
|
||||
sendstring("START!!!\n");
|
||||
if(startflags & ST_FLAG_AUTO){ // rewind for autostart
|
||||
timetostartO = timetostartA;
|
||||
}else{ // clear autostart
|
||||
timetostartA = 0;
|
||||
startflags = 0;
|
||||
}
|
||||
choose_font(FONT14);
|
||||
const char *strt = "óôáòô!";
|
||||
uint16_t w = GetStrWidth(strt);
|
||||
PutStringAt((SCREEN_WIDTH-w-1)/2, SCREEN_HEIGHT-1-curfont->baseline, strt);
|
||||
}else{
|
||||
if(N >= 10){
|
||||
*buf++ = N/10 + '0';
|
||||
N %= 10;
|
||||
}
|
||||
*buf++ = (char)(N + '0');
|
||||
uint16_t w = GetStrWidth(s);
|
||||
PutStringAt((SCREEN_WIDTH-w-1)/2, SCREEN_HEIGHT-1-curfont->baseline, s);
|
||||
}
|
||||
}else{
|
||||
char *tm = get_scrntime(¤t_time, get_millis());
|
||||
tm[8] = 0; // throw out fractional parts
|
||||
PutStringAt(5, SCREEN_HEIGHT-1-curfont->baseline, tm);
|
||||
if(startflags){
|
||||
if(current_time.S == 28){ // decrease timetostartO, prepare to countdown
|
||||
--timetostartO;
|
||||
}
|
||||
char ltr = 'O';
|
||||
if(startflags & ST_FLAG_AUTO) ltr = 'A';
|
||||
choose_font(FONTN8);
|
||||
DrawCharAt(SCREEN_WIDTH-8, SCREEN_HEIGHT-9, ltr);
|
||||
DrawCharAt(SCREEN_WIDTH-8, SCREEN_HEIGHT-1, timetostartO + '0');
|
||||
}
|
||||
}
|
||||
ConvertScreenBuf();
|
||||
ShowScreen();
|
||||
}
|
||||
}
|
||||
process_screen();
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
usb_proc();
|
||||
int r = 0;
|
||||
char *txt = NULL;
|
||||
if((txt = get_USB())){
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
parse_CMD(txt);
|
||||
}
|
||||
if(usartrx(1)){ // usart1 received data, store it in buffer
|
||||
r = usart_getline(1, &txt);
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
if(r){
|
||||
txt[r] = 0;
|
||||
if(the_conf.defflags & FLAG_GPSPROXY){
|
||||
usart_send(GPS_USART, txt);
|
||||
}else{ // UART1 is additive serial/bluetooth console
|
||||
usart_send(1, txt);
|
||||
if(*txt != '\n'){
|
||||
parse_CMD(txt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(usartrx(GPS_USART)){
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
r = usart_getline(GPS_USART, &txt);
|
||||
if(r){
|
||||
txt[r] = 0;
|
||||
if(the_conf.defflags & FLAG_GPSPROXY) usart_send(1, txt);
|
||||
GPS_parse_answer(txt);
|
||||
}
|
||||
}
|
||||
if(usartrx(LIDAR_USART)){
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
r = usart_getline(LIDAR_USART, &txt);
|
||||
if(r){
|
||||
if(the_conf.defflags & FLAG_NOLIDAR){
|
||||
usart_send(LIDAR_USART, txt);
|
||||
if(*txt != '\n'){
|
||||
parse_CMD(txt);
|
||||
}
|
||||
}else
|
||||
parse_lidar_data(txt);
|
||||
}
|
||||
}
|
||||
chk_buzzer(); // should we turn off buzzer?
|
||||
chkTrig1(); // check trigger without interrupt
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
238
F1-nolib/chronometer_v3/screen.c
Normal file
238
F1-nolib/chronometer_v3/screen.c
Normal file
@ -0,0 +1,238 @@
|
||||
/*
|
||||
* This file is part of the LED_screen project.
|
||||
* Copyright 2019 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h> // memset, memcpy
|
||||
#include <stdio.h>
|
||||
#include "fonts.h"
|
||||
#include "hardware.h"
|
||||
#include "screen.h"
|
||||
#include "spi.h"
|
||||
#include "usart.h"
|
||||
|
||||
#undef DBG
|
||||
#define DBG(x)
|
||||
|
||||
// !!!FOR LITTLE-ENDIAN!!!
|
||||
|
||||
// X coordinate - from left to right!
|
||||
// Y coordinate - from top to bottom!
|
||||
// (0,0) is top left corner
|
||||
|
||||
// all-screen buffer
|
||||
static uint8_t screenbuf[SCREENBUF_SZ];
|
||||
// buffers for DMA - for each of four parts
|
||||
static uint8_t dmabuf[4][DMABUF_SZ];
|
||||
|
||||
/**
|
||||
* @brief FillScreen - fill screen buffer with 0 or 1
|
||||
* @param setclear - !=1 to set & ==0 to reset
|
||||
*/
|
||||
void FillScreen(uint8_t setclear){
|
||||
uint8_t pattern = 0;
|
||||
if(setclear) pattern = 0xff;
|
||||
if(SCREEN_IS_NEGATIVE) pattern = ~pattern;
|
||||
for(int i = 0; i < SCREENBUF_SZ; ++i) screenbuf[i] = pattern;
|
||||
// memset -> halt
|
||||
//memset(screenbuf, pattern, SCREENBUF_SZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DrawPix - set or clear pixel
|
||||
* @param X, Y - pixel coordinates (could be outside of screen)
|
||||
* @param pix - == 1 to set and 0 to clear
|
||||
*/
|
||||
void DrawPix(int16_t X, int16_t Y, uint8_t pix){
|
||||
if(X < 0 || X > SCREEN_WIDTH-1 || Y < 0 || Y > SCREEN_HEIGHT-1) return; // outside of screen
|
||||
// now calculate coordinate of pixel
|
||||
uint8_t *ptr = &screenbuf[Y*SCREEN_WIDTH/8 + X/8];
|
||||
if(SCREEN_IS_NEGATIVE)pix = !pix;
|
||||
if(pix) *ptr |= 1 << (7 - (X%8)); // only for little-endian
|
||||
else *ptr &= ~(1 << (7 - (X%8))); // only for little-endian
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DrawCharAt - draws character @ position X,Y (this point is left baseline corner of char!)
|
||||
* @param X, Y - started point
|
||||
* @param Char - char to draw
|
||||
* @return char width
|
||||
*/
|
||||
uint8_t DrawCharAt(int16_t X, int16_t Y, uint8_t Char){
|
||||
const uint8_t *curchar = font_char(Char);
|
||||
if(!curchar) return 0;
|
||||
// now change Y coordinate to left upper corner of font
|
||||
Y += 1 - curfont->height + curfont->baseline;
|
||||
// height and width of letter in pixels
|
||||
uint8_t h = curfont->height, w = *curchar++; // now curchar is pointer to bits array
|
||||
uint8_t lw = curfont->bytes / h; // width of letter in bytes
|
||||
for(uint8_t row = 0; row < h; ++row){
|
||||
for(uint8_t col = 0; col < w; ++col){
|
||||
DrawPix(X + col, Y + row, curchar[row*lw + (col/8)] & (1 << (7 - (col%8)))); // only for little-endian
|
||||
}
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief GetStrWidth - get width of string (in pixels)
|
||||
* @param str - text string
|
||||
* @return amount of pixels
|
||||
*/
|
||||
uint16_t GetStrWidth(const char *str){
|
||||
uint16_t w = 0;
|
||||
while(*str){
|
||||
const uint8_t *curchar = font_char(*str);
|
||||
if(curchar){
|
||||
w += *curchar;
|
||||
}
|
||||
++str;
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ConvertScreenBuf - convert scscreenbuf into dmabuf
|
||||
*
|
||||
*/
|
||||
void ConvertScreenBuf(){
|
||||
for(uint8_t partNo = 0; partNo < 4; ++ partNo){ // cycle by strings
|
||||
uint8_t *dmaptr = dmabuf[partNo];
|
||||
for(int X = 0; X < SCREEN_WIDTH/8; ++X){
|
||||
for(int Y = SCREEN_HEIGHT-4+partNo; Y >= 0; Y -= 4){ // and cycle by Y
|
||||
*dmaptr++ = screenbuf[X + Y*(SCREEN_WIDTH/8)];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief PutStringAt - draw text string @ screen
|
||||
* @param X, Y - base coordinates
|
||||
* @param str - string to draw
|
||||
* @return - text width in pixels
|
||||
*/
|
||||
uint8_t PutStringAt(int16_t X, int16_t Y, const char *str){
|
||||
if(!str) return 0;
|
||||
int16_t Xold = X;
|
||||
while(*str){
|
||||
X += DrawCharAt(X, Y, *str++);
|
||||
}
|
||||
return X - Xold;
|
||||
}
|
||||
|
||||
uint8_t *getScreenBuf(){return screenbuf;}
|
||||
uint8_t *getDmaBuf(uint8_t N){
|
||||
if(N > 3) return NULL;
|
||||
return dmabuf[N];
|
||||
}
|
||||
|
||||
extern volatile uint32_t Tms;
|
||||
typedef enum{ // screen states
|
||||
SCREEN_RELAX, // nothing to do (screen is off)
|
||||
SCREEN_SPIACTIVE, // SPI transmission active
|
||||
SCREEN_WAIT, // pause - current quarter is ON
|
||||
SCREEN_UPDATENXT // update next quarter
|
||||
} screen_state;
|
||||
|
||||
static screen_state ScrnState = SCREEN_RELAX;
|
||||
|
||||
/**
|
||||
* @brief process_screen - screen state machine processing
|
||||
*/
|
||||
void process_screen(){
|
||||
static uint32_t Tscr_last = 0;
|
||||
static uint8_t currentQ = 0; // current quarter
|
||||
switch(ScrnState){
|
||||
case SCREEN_SPIACTIVE: // SPI transmission active
|
||||
if(SPI_status == SPI_READY){
|
||||
DBG("SPI ready\n");
|
||||
Tscr_last = Tms;
|
||||
ScrnState = SCREEN_WAIT;
|
||||
SET(SCLK); // lock data
|
||||
}
|
||||
break;
|
||||
case SCREEN_WAIT: // wait
|
||||
if(Tms - Tscr_last > SCREEN_PAUSE){
|
||||
DBG("Pause ends\n");
|
||||
ScrnState = SCREEN_UPDATENXT;
|
||||
}
|
||||
break;
|
||||
case SCREEN_UPDATENXT:
|
||||
if(SPI_status == SPI_NOTREADY){
|
||||
DBG("SPI not ready - setup");
|
||||
spi_setup();
|
||||
return;
|
||||
}
|
||||
if(SPI_status != SPI_READY){
|
||||
DBG("SPI busy");
|
||||
return; // SPI not ready - try next time
|
||||
}
|
||||
if(SPI_transmit(dmabuf[currentQ], DMABUF_SZ)){
|
||||
DBG("SPI error");
|
||||
return; // transmission error - try next time
|
||||
}
|
||||
DBG("Send next");
|
||||
ScrnState = SCREEN_SPIACTIVE;
|
||||
// now prepare selectors
|
||||
CLEAR(SCLK);
|
||||
switch(currentQ){ // set address bits
|
||||
case 0:
|
||||
CLEAR(A);
|
||||
CLEAR(B);
|
||||
break;
|
||||
case 1:
|
||||
SET(A);
|
||||
CLEAR(B);
|
||||
break;
|
||||
case 2:
|
||||
CLEAR(A);
|
||||
SET(B);
|
||||
break;
|
||||
case 3:
|
||||
SET(A);
|
||||
SET(B);
|
||||
break;
|
||||
}
|
||||
if(++currentQ > 3) currentQ = 0; // roll next
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ShowScreen - turn on data transmission
|
||||
*/
|
||||
void ShowScreen(){
|
||||
if(ScrnState == SCREEN_RELAX) ScrnState = SCREEN_UPDATENXT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ScreenOFF - turn off screen & clear screen buffer
|
||||
*/
|
||||
void ScreenOFF(){
|
||||
DBG("Screen off");
|
||||
CLEAR(SCLK);
|
||||
CLEAR(A);
|
||||
CLEAR(B);
|
||||
FillScreen(0);
|
||||
ScrnState = SCREEN_RELAX;
|
||||
}
|
||||
|
||||
void setdmabuf0(uint8_t pattern, uint8_t N){
|
||||
for(int i = 0; i < N; ++i) dmabuf[0][i] = pattern;
|
||||
}
|
||||
54
F1-nolib/chronometer_v3/screen.h
Normal file
54
F1-nolib/chronometer_v3/screen.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* This file is part of the LED_screen project.
|
||||
* Copyright 2019 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef SCREEN_H__
|
||||
#define SCREEN_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// display size in px
|
||||
// PANEL_WIDTH is width of one panel
|
||||
#define PANEL_WIDTH 32
|
||||
// SCREEN_WIDTH is total screen width
|
||||
#define SCREEN_WIDTH 64
|
||||
#define SCREEN_HEIGHT 16
|
||||
#define SCREENBUF_SZ (SCREEN_WIDTH*SCREEN_HEIGHT/8)
|
||||
#define DMABUF_SZ (SCREENBUF_SZ/4)
|
||||
|
||||
// pause to show a quater of screen - 10ms (25Hz framerate)
|
||||
#define SCREEN_PAUSE 2
|
||||
|
||||
// screen is positive (1->on, 0->off)
|
||||
#define SCREEN_IS_NEGATIVE 1
|
||||
|
||||
void FillScreen(uint8_t setclear);
|
||||
void DrawPix(int16_t X, int16_t Y, uint8_t pix);
|
||||
uint8_t DrawCharAt(int16_t X, int16_t Y, uint8_t Char);
|
||||
void ConvertScreenBuf();
|
||||
uint8_t PutStringAt(int16_t X, int16_t Y, const char *str);
|
||||
uint8_t *getScreenBuf();
|
||||
uint8_t *getDmaBuf(uint8_t N);
|
||||
void process_screen();
|
||||
void ShowScreen();
|
||||
void ScreenOFF();
|
||||
uint16_t GetStrWidth(const char *str);
|
||||
|
||||
void setdmabuf0(uint8_t pattern, uint8_t N);
|
||||
|
||||
#endif // SCREEN_H__
|
||||
77
F1-nolib/chronometer_v3/spi.c
Normal file
77
F1-nolib/chronometer_v3/spi.c
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* This file is part of the LED_screen project.
|
||||
* Copyright 2019 Edward V. Emelianov <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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "spi.h"
|
||||
#include "hardware.h"
|
||||
|
||||
spiStatus SPI_status = SPI_NOTREADY;
|
||||
|
||||
void spi_setup(){
|
||||
// setup SPI GPIO - alternate function PP (PA5 - SCK, PA7 - MOSI)
|
||||
GPIOA->CRL |= CRL(5, CNF_AFPP|MODE_FAST) | CRL(7, CNF_AFPP|MODE_FAST);
|
||||
// configure SPI (transmit only)
|
||||
/* Enable the peripheral clock SPI1 */
|
||||
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
|
||||
/* Configure SPI1 in master */
|
||||
/* (1) Master selection, BR: Fpclk/16
|
||||
CPOL and CPHA at zero (rising first edge) */
|
||||
/* (2) TX with DMA, slave select output disabled (software managed) */
|
||||
/* (3) Enable SPI1 */
|
||||
SPI1->CR1 = SPI_CR1_MSTR | SPI_CR1_BR_0 | SPI_CR1_BR_1 | SPI_CR1_SSM | SPI_CR1_SSI; /* (1) */
|
||||
SPI1->CR2 = SPI_CR2_TXDMAEN; /* (2) */
|
||||
// setup SPI1 DMA
|
||||
/* Enable the peripheral clock DMA11 */
|
||||
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
|
||||
/* DMA1 Channel3 SPI1_TX config */
|
||||
/* (5) Peripheral address */
|
||||
/* (7) Memory increment */
|
||||
/* Memory to peripheral */
|
||||
/* 8-bit transfer */
|
||||
/* Transfer complete IRQ enable */
|
||||
DMA_SPI_Channel->CPAR = (uint32_t)&(SPI1->DR); /* (5) */
|
||||
DMA_SPI_Channel->CCR |= DMA_CCR_MINC | DMA_CCR_DIR | DMA_CCR_TCIE; /* (7) */
|
||||
NVIC_SetPriority(DMA1_Channel3_IRQn, 0);
|
||||
NVIC_EnableIRQ(DMA1_Channel3_IRQn);
|
||||
SPI_status = SPI_READY;
|
||||
SPI1->CR1 |= SPI_CR1_SPE; /* (3) */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SPI_transmit - transmit data over SPI DMA
|
||||
* @param buf - data to transmit
|
||||
* @param len - its length
|
||||
* @return 0 if all OK
|
||||
*/
|
||||
uint8_t SPI_transmit(const uint8_t *buf, uint8_t len){
|
||||
if(!buf || !len) return 1; // bad data format
|
||||
if(SPI_status != SPI_READY) return 2; // spi not ready to transmit data
|
||||
DMA_SPI_Channel->CMAR = (uint32_t)buf;
|
||||
DMA_SPI_Channel->CNDTR = len;
|
||||
SPI_status = SPI_BUSY;
|
||||
DMA_SPI_Channel->CCR |= DMA_CCR_EN;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// SPI1 DMA Tx interrupt
|
||||
void dma1_channel3_isr(){
|
||||
if(DMA1->ISR & DMA_ISR_TCIF3){
|
||||
DMA1->IFCR |= DMA_IFCR_CTCIF3; /* Clear TC flag */
|
||||
SPI_status = SPI_READY;
|
||||
DMA_SPI_Channel->CCR &=~ DMA_CCR_EN; // turn off DMA for further reconfiguration
|
||||
}
|
||||
}
|
||||
36
F1-nolib/chronometer_v3/spi.h
Normal file
36
F1-nolib/chronometer_v3/spi.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* This file is part of the LED_screen project.
|
||||
* Copyright 2019 Edward V. Emelianov <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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef SPI_H__
|
||||
#define SPI_H__
|
||||
|
||||
#include "stm32f1.h"
|
||||
|
||||
typedef enum{
|
||||
SPI_NOTREADY,
|
||||
SPI_READY,
|
||||
SPI_BUSY
|
||||
} spiStatus;
|
||||
|
||||
extern spiStatus SPI_status;
|
||||
|
||||
void spi_setup();
|
||||
uint8_t SPI_transmit(const uint8_t *buf, uint8_t len);
|
||||
|
||||
#endif // SPI_H__
|
||||
109
F1-nolib/chronometer_v3/stm32F103xB.ld
Normal file
109
F1-nolib/chronometer_v3/stm32F103xB.ld
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
********************************************************************************
|
||||
* *
|
||||
* Copyright (c) 2017 Andrea Loi *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a *
|
||||
* copy of this software and associated documentation files (the "Software"), *
|
||||
* to deal in the Software without restriction, including without limitation *
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
|
||||
* and/or sell copies of the Software, and to permit persons to whom the *
|
||||
* Software is furnished to do so, subject to the following conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included *
|
||||
* in all copies or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
|
||||
* DEALINGS IN THE SOFTWARE. *
|
||||
* *
|
||||
********************************************************************************
|
||||
*/
|
||||
|
||||
MEMORY
|
||||
{
|
||||
rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K
|
||||
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* DON'T EDIT THIS FILE UNLESS YOU KNOW WHAT YOU'RE DOING! */
|
||||
/******************************************************************************/
|
||||
|
||||
/* _isrvectors_tend = 0x00000150; - different for different series */
|
||||
|
||||
ENTRY(reset_handler)
|
||||
|
||||
SECTIONS {
|
||||
.vector_table 0x08000000 :
|
||||
{
|
||||
_sisrvectors = .;
|
||||
KEEP(*(.vector_table))
|
||||
/* ASSERT(. == _isrvectors_tend, "The vector table needs to be 84 elements long!"); */
|
||||
_eisrvectors = .;
|
||||
} >rom
|
||||
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_stext = .;
|
||||
*(.text*)
|
||||
*(.rodata*)
|
||||
. = ALIGN(4);
|
||||
_etext = .;
|
||||
} >rom
|
||||
|
||||
.ARM.extab :
|
||||
{
|
||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||
} >rom
|
||||
|
||||
.ARM : {
|
||||
*(.ARM.exidx*)
|
||||
} >rom
|
||||
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sdata = .;
|
||||
*(.data*)
|
||||
. = ALIGN(4);
|
||||
_edata = .;
|
||||
} >ram AT >rom
|
||||
|
||||
.myvars :
|
||||
{
|
||||
. = ALIGN(1024);
|
||||
__varsstart = ABSOLUTE(.);
|
||||
KEEP(*(.myvars));
|
||||
. = . + 2000;
|
||||
. = ALIGN(1024);
|
||||
__varsend = ABSOLUTE(.);
|
||||
} > rom
|
||||
|
||||
.logs :
|
||||
{
|
||||
. = ALIGN(1024);
|
||||
__logsstart = ABSOLUTE(.);
|
||||
KEEP(*(.logs))
|
||||
} > rom
|
||||
|
||||
_ldata = LOADADDR(.data);
|
||||
|
||||
.bss :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sbss = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
_ebss = .;
|
||||
} >ram
|
||||
}
|
||||
|
||||
PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram));
|
||||
PROVIDE(_varslen = __varsend - __varsstart);
|
||||
734
F1-nolib/chronometer_v3/str.c
Normal file
734
F1-nolib/chronometer_v3/str.c
Normal file
@ -0,0 +1,734 @@
|
||||
/*
|
||||
* This file is part of the chronometer project.
|
||||
* Copyright 2019 Edward V. Emelianov <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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Commands parser
|
||||
|
||||
#include "adc.h"
|
||||
#include "GPS.h"
|
||||
#include "fonts.h"
|
||||
#include "hardware.h"
|
||||
#include "lidar.h"
|
||||
#include "screen.h"
|
||||
#include "str.h"
|
||||
#include "time.h"
|
||||
#include "usart.h"
|
||||
#include "usb.h"
|
||||
|
||||
// flag to show new GPS message over USB
|
||||
uint8_t showGPSstr = 0;
|
||||
// check/not check shutter
|
||||
uint8_t chkshtr = 1;
|
||||
// show/not show shutter events
|
||||
uint8_t showshtr = 1;
|
||||
// show time or message; starting types; time to next start (once/auto)
|
||||
uint8_t showtime = 0, startflags = 0, timetostartO = 0, timetostartA = 0;
|
||||
|
||||
extern uint32_t shotms[];
|
||||
|
||||
/**
|
||||
* @brief cmpstr - the same as strncmp
|
||||
* @param s1,s2 - strings to compare
|
||||
* @param n - max symbols amount + 1 (!!!!)
|
||||
* @return 0 if strings equal or 1/-1
|
||||
*/
|
||||
int cmpstr(const char *s1, const char *s2, int n){
|
||||
int ret = 0;
|
||||
while(--n){
|
||||
ret = *s1 - *s2;
|
||||
if(ret == 0 && *s1 && *s2){
|
||||
++s1; ++s2;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief getchr - analog of strchr
|
||||
* @param str - string to search
|
||||
* @param symbol - searching symbol
|
||||
* @return pointer to symbol found or NULL
|
||||
*/
|
||||
char *getchr(const char *str, char symbol){
|
||||
do{
|
||||
if(*str == symbol) return (char*)str;
|
||||
}while(*(++str));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define sendu(x) do{sendstring(u2str(x));}while(0)
|
||||
|
||||
/*
|
||||
static void sendi(int32_t I){
|
||||
if(I < 0){
|
||||
sendchar('-');
|
||||
I = -I;
|
||||
}
|
||||
sendstring(u2str((uint32_t)I));
|
||||
}*/
|
||||
|
||||
// echo '1' if true or '0' if false
|
||||
static void checkflag(uint8_t f){
|
||||
if(f) sendchar('1');
|
||||
else sendchar('0');
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief showuserconf - show configuration over USB
|
||||
*/
|
||||
static void showuserconf(){
|
||||
sendstring("DISTMIN="); sendu(the_conf.dist_min);
|
||||
sendstring("\nDISTMAX="); sendu(the_conf.dist_max);
|
||||
sendstring("\nTRIGLVL="); sendu(the_conf.trigstate);
|
||||
sendstring("\nTRIGPAUSE={");
|
||||
for(int i = 0; i < TRIGGERS_AMOUNT; ++i){
|
||||
if(i) sendstring(", ");
|
||||
sendu(the_conf.trigpause[i]);
|
||||
}
|
||||
sendstring("}\nUSART1SPD="); sendu(the_conf.USART_speed);
|
||||
sendstring("\nLIDARSPD="); sendu(the_conf.LIDAR_speed);
|
||||
sendstring("\nNFREE=");
|
||||
sendu(the_conf.NLfreeWarn);
|
||||
sendstring("\nSTREND=");
|
||||
if(the_conf.defflags & FLAG_STRENDRN) sendstring("RN");
|
||||
else sendchar('N');
|
||||
uint8_t f = the_conf.defflags;
|
||||
sendstring("\nSAVE_EVENTS=");
|
||||
checkflag(f & FLAG_SAVE_EVENTS);
|
||||
sendstring("\nGPSPROXY=");
|
||||
checkflag(f & FLAG_GPSPROXY);
|
||||
sendstring("\nLIDAR=");
|
||||
checkflag(!(f & FLAG_NOLIDAR));
|
||||
sendstring("\nEVTLEN="); sendu(the_conf.ledshow_time);
|
||||
sendstring("\n"); // <-- sendstring @ the end to initialize data transmission
|
||||
}
|
||||
|
||||
extern uint8_t USB_connected; // need to reset USB
|
||||
/**
|
||||
* @brief parse_USBCMD - parsing of string buffer got by USB
|
||||
* @param cmd - buffer with commands
|
||||
* @return 0 if got command, 1 if command not recognized
|
||||
*/
|
||||
void parse_CMD(char *cmd){
|
||||
char *oldcmd = cmd;
|
||||
#define CMP(a,b) cmpstr(a, b, sizeof(b))
|
||||
#define GETNUM(x) do{if(getnum(cmd+sizeof(x)-1, &N)) goto bad_number;}while(0)
|
||||
static uint8_t conf_modified = 0;
|
||||
uint8_t succeed = 0;
|
||||
int32_t N;
|
||||
if(!cmd || !*cmd) return;
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
if(*cmd == '?' || CMP(cmd, "help") == 0){ // help
|
||||
sendstring("Commands:\n"
|
||||
CMD_BTNSTATE " - show triggers state\n"
|
||||
CMD_BUZZER "S - turn buzzer ON/OFF\n"
|
||||
CMD_CLEARSCRN " - turn LED display off\n"
|
||||
CMD_CURDIST " - show current LIDAR distance\n"
|
||||
CMD_DELLOGS " - delete logs from flash memory\n"
|
||||
CMD_DISTMIN " - min distance threshold (cm)\n"
|
||||
CMD_DISTMAX " - max distance threshold (cm)\n"
|
||||
CMD_DUMP "N - dump 20 last stored events (no x), all (x<1) or x\n"
|
||||
CMD_EVTLEN "N - duration of the trigger event display (ms)\n"
|
||||
CMD_FLASH " - FLASH info\n"
|
||||
CMD_GATE "S - check/not check triggers (1/0)\n"
|
||||
CMD_GPSPROXY "S - GPS proxy over USART1 on/off\n"
|
||||
CMD_GPSRESTART " - send Full Cold Restart to GPS\n"
|
||||
CMD_GPSSTAT " - get GPS status\n"
|
||||
CMD_GPSSTR " - current GPS data string\n"
|
||||
CMD_LEDS "S - turn leds on/off (1/0)\n"
|
||||
CMD_LIDAR "S - switch between LIDAR (1) or command TTY (0)\n"
|
||||
CMD_LIDARSPEED "N - set LIDAR speed to N\n"
|
||||
CMD_GETMCUTEMP " - MCU temperature\n"
|
||||
CMD_MESG " str - show 'str' at display (no more than 7 chars)\n"
|
||||
CMD_DUMPN "N - dump Nth log & show on screen (-N - Nth from last)\n"
|
||||
CMD_NFREE " - warn when free logs space less than this number (0 - not warn)\n"
|
||||
CMD_RESET " - reset MCU\n"
|
||||
CMD_SAVEEVTS "S - save/don't save (1/0) trigger events into flash\n"
|
||||
CMD_SHOWCONF " - show current configuration\n"
|
||||
CMD_SHOWSHTR "S - show/not show trigger events\n"
|
||||
CMD_SHOWTIME " - show current time\n"
|
||||
CMD_SQUEAK " - make a short buzzer chirp\n"
|
||||
CMD_STARTAUTO "X - auto start every X minutes (0 or absent - cancel, +/- - increase/decrease by 1min)\n"
|
||||
CMD_STARTONCE "X - delayed start after X minutes (like auto)\n"
|
||||
CMD_STORECONF " - store new configuration in flash\n"
|
||||
CMD_STORTEST " - add test trigger event record into flash\n"
|
||||
CMD_STREND "C - string ends with \\n (C=n) or \\r\\n (C=r)\n"
|
||||
CMD_PRINTTIME " - print current time\n"
|
||||
CMD_TRIGLVL "NS - working trigger N level S\n"
|
||||
CMD_TRGPAUSE "NP - pause (P, ms) after trigger N shots\n"
|
||||
CMD_TRGTIME "N - show last trigger N time\n"
|
||||
CMD_USARTSPD "N - set USART1 speed to N\n"
|
||||
CMD_USBRST " - reset USB connectioin\n"
|
||||
CMD_GETVDD " - Vdd value\n"
|
||||
);
|
||||
}else if(CMP(cmd, CMD_PRINTTIME) == 0){ // print current time
|
||||
sendstring(get_time(¤t_time, get_millis()));
|
||||
sendstring("\n");
|
||||
}else if(CMP(cmd, CMD_DISTMIN) == 0){ // set low LIDAR limit
|
||||
GETNUM(CMD_DISTMIN);
|
||||
if(N < 0 || N > 0xffff) goto bad_number;
|
||||
if(the_conf.dist_min != (uint16_t)N){
|
||||
conf_modified = 1;
|
||||
the_conf.dist_min = (uint16_t) N;
|
||||
}
|
||||
succeed = 1;
|
||||
}else if(CMP(cmd, CMD_DISTMAX) == 0){ // set high LIDAR limit
|
||||
GETNUM(CMD_DISTMAX);
|
||||
if(N < 0 || N > 0xffff) goto bad_number;
|
||||
if(the_conf.dist_max != (uint16_t)N){
|
||||
conf_modified = 1;
|
||||
the_conf.dist_max = (uint16_t) N;
|
||||
}
|
||||
succeed = 1;
|
||||
}else if(CMP(cmd, CMD_STORECONF) == 0){ // store everything in flash
|
||||
if(conf_modified){
|
||||
if(store_userconf()){
|
||||
sendstring("Error: can't save data!\n");
|
||||
}else{
|
||||
conf_modified = 0;
|
||||
succeed = 1;
|
||||
}
|
||||
}
|
||||
}else if(CMP(cmd, CMD_GPSSTR) == 0){ // show GPS status string
|
||||
showGPSstr = 1;
|
||||
}else if(CMP(cmd, CMD_TRIGLVL) == 0){ // trigger levels: 0->1 or 1->0
|
||||
cmd += sizeof(CMD_TRIGLVL) - 1;
|
||||
uint8_t Nt = (uint8_t)(*cmd++ - '0');
|
||||
if(Nt > TRIGGERS_AMOUNT - 1) goto bad_number;
|
||||
uint8_t state = (uint8_t)(*cmd -'0');
|
||||
if(state > 1) goto bad_number;
|
||||
uint8_t oldval = the_conf.trigstate;
|
||||
if(!state) the_conf.trigstate = oldval & ~(1<<Nt);
|
||||
else the_conf.trigstate = (uint8_t)(oldval | (1<<Nt));
|
||||
if(oldval != the_conf.trigstate) conf_modified = 1;
|
||||
succeed = 1;
|
||||
}else if(CMP(cmd, CMD_SHOWCONF) == 0){ // print current configuration
|
||||
showuserconf();
|
||||
}else if(CMP(cmd, CMD_TRGPAUSE) == 0){ // pause after Nth trigger
|
||||
cmd += sizeof(CMD_TRGPAUSE) - 1;
|
||||
uint8_t Nt = (uint8_t)(*cmd++ - '0');
|
||||
if(Nt > TRIGGERS_AMOUNT - 1) goto bad_number;
|
||||
if(getnum(cmd, &N)) goto bad_number;
|
||||
if(N < 0 || N > 10000) goto bad_number;
|
||||
if(the_conf.trigpause[Nt] != (uint16_t)N){
|
||||
conf_modified = 1;
|
||||
the_conf.trigpause[Nt] = (uint16_t)N;
|
||||
}
|
||||
succeed = 1;
|
||||
}else if(CMP(cmd, CMD_TRGTIME) == 0){ // last trigger time
|
||||
cmd += sizeof(CMD_TRGTIME) - 1;
|
||||
uint8_t Nt = (uint8_t)(*cmd++ - '0');
|
||||
if(Nt > TRIGGERS_AMOUNT - 1) goto bad_number;
|
||||
show_trigger_shot((uint8_t)(1<<Nt));
|
||||
}else if(CMP(cmd, CMD_GETVDD) == 0){ // Vdd
|
||||
sendstring("VDD=");
|
||||
uint32_t vdd = getVdd();
|
||||
sendu(vdd/100);
|
||||
vdd %= 100;
|
||||
if(vdd < 10) sendstring(".0");
|
||||
else sendstring(".");
|
||||
sendu(vdd);
|
||||
sendstring("\n");
|
||||
}else if(CMP(cmd, CMD_GETMCUTEMP) == 0){ // ~Tmcu
|
||||
int32_t t = getMCUtemp();
|
||||
sendstring("MCUTEMP=");
|
||||
if(t < 0){
|
||||
t = -t;
|
||||
sendstring("-");
|
||||
}
|
||||
sendu(t/10);
|
||||
sendstring(".");
|
||||
sendu(t%10);
|
||||
sendstring("\n");
|
||||
}else if(CMP(cmd, CMD_LEDS) == 0){ // turn LEDs on/off
|
||||
uint8_t Nt = (uint8_t)(cmd[sizeof(CMD_LEDS) - 1] - '0');
|
||||
if(Nt > 1) goto bad_number;
|
||||
sendstring("LEDS=");
|
||||
if(Nt){
|
||||
LEDSon = 1;
|
||||
sendstring("ON\n");
|
||||
}else{
|
||||
LED_off(); // turn off LEDS
|
||||
LED1_off(); // by user request
|
||||
LEDSon = 0;
|
||||
sendstring("OFF\n");
|
||||
}
|
||||
}else if(CMP(cmd, CMD_GPSRESTART) == 0){ // restart GPS
|
||||
sendstring("Send full cold restart to GPS\n");
|
||||
GPS_send_FullColdStart();
|
||||
}else if(CMP(cmd, CMD_BUZZER) == 0){
|
||||
uint8_t Nt = (uint8_t)(cmd[sizeof(CMD_BUZZER) - 1] - '0');
|
||||
if(Nt > 1) goto bad_number;
|
||||
sendstring("BUZZER=");
|
||||
if(Nt){
|
||||
buzzer_on = 1;
|
||||
sendstring("ON\n");
|
||||
}else{
|
||||
buzzer_on = 0;
|
||||
sendstring("OFF\n");
|
||||
}
|
||||
}else if(CMP(cmd, CMD_GPSSTAT) == 0){ // GPS status
|
||||
sendstring("GPS status: ");
|
||||
const char *str = "unknown";
|
||||
switch(GPS_status){
|
||||
case GPS_NOTFOUND:
|
||||
str = "not found";
|
||||
break;
|
||||
case GPS_WAIT:
|
||||
str = "waiting";
|
||||
break;
|
||||
case GPS_NOT_VALID:
|
||||
str = "no satellites";
|
||||
break;
|
||||
case GPS_VALID:
|
||||
str = "valid time";
|
||||
break;
|
||||
}
|
||||
sendstring(str);
|
||||
if(Tms - last_corr_time < 1500)
|
||||
sendstring(", PPS working\n");
|
||||
else
|
||||
sendstring(", no PPS\n");
|
||||
}else if(CMP(cmd, CMD_USARTSPD) == 0){ // USART speed
|
||||
GETNUM(CMD_USARTSPD);
|
||||
if(N < 400 || N > 3000000) goto bad_number;
|
||||
if(the_conf.USART_speed != (uint32_t)N){
|
||||
the_conf.USART_speed = (uint32_t)N;
|
||||
conf_modified = 1;
|
||||
}
|
||||
succeed = 1;
|
||||
}else if(CMP(cmd, CMD_LIDARSPEED) == 0){ // LIDAR speed
|
||||
GETNUM(CMD_LIDARSPEED);
|
||||
if(N < 400 || N > 3000000) goto bad_number;
|
||||
if(the_conf.LIDAR_speed != (uint32_t)N){
|
||||
the_conf.LIDAR_speed = (uint32_t)N;
|
||||
conf_modified = 1;
|
||||
}
|
||||
succeed = 1;
|
||||
}else if(CMP(cmd, CMD_RESET) == 0){ // Reset MCU
|
||||
sendstring("Soft reset\n");
|
||||
NVIC_SystemReset();
|
||||
}else if(CMP(cmd, CMD_STREND) == 0){ // string ends in '\n' or "\r\n"
|
||||
char c = cmd[sizeof(CMD_STREND) - 1];
|
||||
succeed = 1;
|
||||
if(c == 'n' || c == 'N'){
|
||||
if(the_conf.defflags & FLAG_STRENDRN){
|
||||
conf_modified = 1;
|
||||
the_conf.defflags &= ~FLAG_STRENDRN;
|
||||
}
|
||||
}else if(c == 'r' || c == 'R'){
|
||||
if(!(the_conf.defflags & FLAG_STRENDRN)){
|
||||
conf_modified = 1;
|
||||
the_conf.defflags |= FLAG_STRENDRN;
|
||||
}
|
||||
}else{
|
||||
succeed = 0;
|
||||
sendstring("Bad letter, should be 'n' or 'r'\n");
|
||||
}
|
||||
}else if(CMP(cmd, CMD_FLASH) == 0){ // show flash size
|
||||
sendstring("FLASHSIZE=");
|
||||
sendu(FLASH_SIZE);
|
||||
sendstring("kB\nFLASH_BASE=");
|
||||
sendstring(u2hex(FLASH_BASE));
|
||||
sendstring("\nFlash_Data=");
|
||||
sendstring(u2hex((uint32_t)Flash_Data));
|
||||
sendstring("\nvarslen=");
|
||||
sendu((uint32_t)&_varslen);
|
||||
sendstring("\nCONFsize=");
|
||||
sendu(sizeof(user_conf));
|
||||
sendstring("\nNconf_records=");
|
||||
sendu(maxCnum - 1);
|
||||
sendstring("\nlogsstart=");
|
||||
sendstring(u2hex((uint32_t)logsstart));
|
||||
sendstring("\nLOGsize=");
|
||||
sendu(sizeof(event_log));
|
||||
sendstring("\nNlogs_records=");
|
||||
sendu(maxLnum - 1);
|
||||
sendstring("\n");
|
||||
}else if(CMP(cmd, CMD_SAVEEVTS) == 0){ // save all events
|
||||
if('0' == cmd[sizeof(CMD_SAVEEVTS) - 1]){
|
||||
if(the_conf.defflags & FLAG_SAVE_EVENTS){
|
||||
conf_modified = 1;
|
||||
the_conf.defflags &= ~FLAG_SAVE_EVENTS;
|
||||
}
|
||||
}else{
|
||||
if(!(the_conf.defflags & FLAG_SAVE_EVENTS)){
|
||||
conf_modified = 1;
|
||||
the_conf.defflags |= FLAG_SAVE_EVENTS;
|
||||
}
|
||||
}
|
||||
succeed = 1;
|
||||
}else if(CMP(cmd, CMD_DUMP) == 0){ // dump N last events
|
||||
if(getnum(cmd+sizeof(CMD_DUMP)-1, &N)) N = -20; // default - without N
|
||||
else N = -N;
|
||||
if(N > 0) N = 0;
|
||||
if(dump_log(N, -1)) sendstring("Event log empty!\n");
|
||||
}else if(CMP(cmd, CMD_NFREE) == 0){ // warn if there's less than N free cells for logs in flash
|
||||
GETNUM(CMD_NFREE);
|
||||
if(N < 0 || N > 0xffff) goto bad_number;
|
||||
if(the_conf.NLfreeWarn != (uint16_t)N){
|
||||
conf_modified = 1;
|
||||
the_conf.NLfreeWarn = (uint16_t)N;
|
||||
}
|
||||
succeed = 1;
|
||||
}else if(CMP(cmd, CMD_DELLOGS) == 0){ // delete all logs
|
||||
if(store_log(NULL)) sendstring("Error during erasing flash\n");
|
||||
else sendstring("All logs erased\n");
|
||||
}else if(CMP(cmd, CMD_GPSPROXY) == 0){ // proxy GPS data over USART1
|
||||
if(cmd[sizeof(CMD_GPSPROXY) - 1] == '0'){
|
||||
if(the_conf.defflags & FLAG_GPSPROXY){
|
||||
conf_modified = 1;
|
||||
the_conf.defflags &= ~FLAG_GPSPROXY;
|
||||
}
|
||||
}else{
|
||||
if(!(the_conf.defflags & FLAG_GPSPROXY)){
|
||||
conf_modified = 1;
|
||||
the_conf.defflags |= FLAG_GPSPROXY;
|
||||
}
|
||||
}
|
||||
succeed = 1;
|
||||
}else if(CMP(cmd, CMD_CURDIST) == 0){ // current LIDAR distance
|
||||
sendstring("DIST=");
|
||||
sendu(last_lidar_dist);
|
||||
sendstring("\nSTREN=");
|
||||
sendu(last_lidar_stren);
|
||||
sendstring("\nTRIGDIST=");
|
||||
sendu(lidar_triggered_dist);
|
||||
sendstring("\nTms=");
|
||||
sendu(Tms);
|
||||
sendstring("\nshotms=");
|
||||
sendu(shotms[LIDAR_TRIGGER]);
|
||||
sendstring("\n");
|
||||
}else if(CMP(cmd, CMD_LIDAR) == 0){ // turn LIDAR on/off
|
||||
if(cmd[sizeof(CMD_LIDAR) - 1] == '0'){
|
||||
if(!(the_conf.defflags & FLAG_NOLIDAR)){
|
||||
conf_modified = 1;
|
||||
the_conf.defflags |= FLAG_NOLIDAR;
|
||||
}
|
||||
}else{
|
||||
if(the_conf.defflags & FLAG_NOLIDAR){
|
||||
conf_modified = 1;
|
||||
the_conf.defflags &= ~FLAG_NOLIDAR;
|
||||
}
|
||||
}
|
||||
succeed = 1;
|
||||
}else if(CMP(cmd, CMD_CLEARSCRN) == 0){ // turn display off
|
||||
sendstring("Clear screen\n");
|
||||
showtime = 0;
|
||||
ScreenOFF();
|
||||
}else if(CMP(cmd, CMD_MESG) == 0){ // show short message instead of time
|
||||
char *m = &cmd[sizeof(CMD_MESG) - 1];
|
||||
while(*m == ' ' || *m == '\t') ++m;
|
||||
showtime = 0;
|
||||
ScreenOFF();
|
||||
choose_font(FONT14);
|
||||
uint16_t w = GetStrWidth(m);
|
||||
PutStringAt((SCREEN_WIDTH-w-1)/2, SCREEN_HEIGHT-1-curfont->baseline, m);
|
||||
ConvertScreenBuf();
|
||||
ShowScreen();
|
||||
}else if(CMP(cmd, CMD_SHOWTIME) == 0){ // show current time @ LED display
|
||||
ScreenOFF();
|
||||
showtime = 1;
|
||||
}else if(CMP(cmd, CMD_STORTEST) == 0){ // test storing event log
|
||||
event_log l;
|
||||
l.trigno = 1;
|
||||
l.shottime.Time = current_time;
|
||||
l.shottime.millis = Timer;
|
||||
l.triglen = 10;
|
||||
DBG("Try to store test");
|
||||
if(store_log(&l)) sendstring("Error storing\n");
|
||||
else succeed = 1;
|
||||
}else if(CMP(cmd, CMD_BTNSTATE) == 0){ // show gates/buttons state
|
||||
char btns[] = "BTN0=0, BTN1=0, BTN2=0, PPS=0\n";
|
||||
btns[5] = gettrig(0) + '0';
|
||||
btns[13] = gettrig(1) + '0';
|
||||
btns[21] = gettrig(2) + '0';
|
||||
btns[28] = GET_PPS() + '0';
|
||||
sendstring(btns);
|
||||
}else if(CMP(cmd, CMD_USBRST) == 0){ // reset USB pullup
|
||||
USBPU_OFF();
|
||||
USB_connected = 0;
|
||||
sendstring("Reset USB\n");
|
||||
USBPU_ON();
|
||||
}else if(CMP(cmd, CMD_STARTAUTO) == 0){ // set/clear 'start auto' mode
|
||||
char c = cmd[sizeof(CMD_STARTAUTO) - 1];
|
||||
if(c == '+'){
|
||||
if(timetostartA && timetostartA < MAX_TIMETOSTART) ++timetostartA; // increase
|
||||
}else if(c == '-'){ // decrease or cancel
|
||||
if(timetostartA > 1) --timetostartA;
|
||||
else{ // cancel
|
||||
timetostartO = timetostartA = 0;
|
||||
startflags = 0;
|
||||
}
|
||||
}else if(c >= '1' && c <= MAX_TIMETOSTART + '0'){ // set time to start
|
||||
timetostartO = timetostartA = c - '0';
|
||||
startflags = ST_FLAG_AUTO | ST_FLAG_ONCE;
|
||||
}else{ // cancel
|
||||
timetostartO = timetostartA = 0;
|
||||
startflags = 0;
|
||||
}
|
||||
sendstring("Autostart ");
|
||||
if(startflags){
|
||||
sendstring("every ");
|
||||
sendchar('0' + timetostartA);
|
||||
sendstring(" minutes\n");
|
||||
}else{
|
||||
sendstring("canceled\n");
|
||||
}
|
||||
}else if(CMP(cmd, CMD_STARTONCE) == 0){ // set/clear 'start once' mode & modify time to next start (including nearest autostart)
|
||||
char c = cmd[sizeof(CMD_STARTAUTO) - 1];
|
||||
if(c == '+'){
|
||||
if(timetostartO && timetostartO < MAX_TIMETOSTART) ++timetostartO;
|
||||
}else if(c == '-'){
|
||||
if(timetostartO > 1) --timetostartO;
|
||||
else{
|
||||
timetostartO = timetostartA = 0;
|
||||
startflags = 0;
|
||||
}
|
||||
}else if(c >= '1' && c <= MAX_TIMETOSTART + '0'){ // set time to start
|
||||
timetostartO = c - '0';
|
||||
startflags |= ST_FLAG_ONCE;
|
||||
}else{ // cancel
|
||||
timetostartO = timetostartA = 0;
|
||||
startflags = 0;
|
||||
}
|
||||
sendstring("Single start ");
|
||||
if(startflags){
|
||||
sendstring("after ");
|
||||
sendchar('0' + timetostartO);
|
||||
sendstring(" minutes\n");
|
||||
}else{
|
||||
sendstring("canceled\n");
|
||||
}
|
||||
}else if(CMP(cmd, CMD_GATE) == 0){ // gate0 - don't check shutters; otherwise - check
|
||||
if(cmd[sizeof(CMD_GATE-1)] == '0'){
|
||||
sendstring("Don't ");
|
||||
chkshtr = 0;
|
||||
}else chkshtr = 1;
|
||||
sendstring("check gate\n");
|
||||
}else if(CMP(cmd, CMD_SHOWSHTR) == 0){ // showshutter0 - not show shutter events
|
||||
if(cmd[sizeof(CMD_SHOWSHTR)-1] == '0'){
|
||||
sendstring("Don't ");
|
||||
showshtr = 0;
|
||||
}else showshtr = 1;
|
||||
sendstring("show shutter events on LED\n");
|
||||
}else if(CMP(cmd, CMD_EVTLEN) == 0){ // USART speed
|
||||
GETNUM(CMD_EVTLEN);
|
||||
if(N < 1000 || N > 60000) goto bad_number;
|
||||
if(the_conf.ledshow_time != (uint16_t)N){
|
||||
the_conf.ledshow_time = (uint16_t)N;
|
||||
conf_modified = 1;
|
||||
}
|
||||
succeed = 1;
|
||||
}else if(CMP(cmd, CMD_DUMPN) == 0){ // dump Nth event
|
||||
if(getnum(cmd+sizeof(CMD_DUMPN)-1, &N)) N = -1; // default - last
|
||||
if(dump_log(N, 1)) sendstring("Wrong index!\n");
|
||||
}else if(CMP(cmd, CMD_SQUEAK) == 0){ // make a short squeak
|
||||
buzzer_squeak();
|
||||
}else{
|
||||
sendstring("Bad command: ");
|
||||
sendstring(oldcmd);
|
||||
sendstring("\n");
|
||||
return;
|
||||
}
|
||||
/*else if(CMP(cmd, CMD_) == 0){
|
||||
;
|
||||
}*/
|
||||
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
if(succeed) sendstring("Success!\n");
|
||||
return;
|
||||
bad_number:
|
||||
sendstring("Error: bad number!\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get_trigger_shot - print on USB message about last trigger shot time
|
||||
* @param number - number of event (if > -1)
|
||||
* @param logdata - record from event log
|
||||
* @return string with data
|
||||
*/
|
||||
char *get_trigger_shot(int number, const event_log *logdata){
|
||||
static char buf[64];
|
||||
char *bptr = buf;
|
||||
if(number > -1){
|
||||
bptr = strcp(bptr, u2str(number));
|
||||
bptr = strcp(bptr, ": ");
|
||||
}
|
||||
if(logdata->trigno == LIDAR_TRIGGER){
|
||||
bptr = strcp(bptr, "LIDAR, dist=");
|
||||
bptr = strcp(bptr, u2str(logdata->lidar_dist));
|
||||
bptr = strcp(bptr, ", TRIG" STR(LIDAR_TRIGGER));
|
||||
}else{
|
||||
bptr = strcp(bptr, "TRIG");
|
||||
*bptr++ = '0' + logdata->trigno;
|
||||
}
|
||||
*bptr++ = '=';
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
bptr = strcp(bptr, get_time(&logdata->shottime.Time, logdata->shottime.millis));
|
||||
bptr = strcp(bptr, ", len=");
|
||||
if(logdata->triglen < 0) bptr = strcp(bptr, ">1s");
|
||||
else bptr = strcp(bptr, u2str((uint32_t) logdata->triglen));
|
||||
*bptr++ = '\n'; *bptr++ = 0;
|
||||
return buf;
|
||||
}
|
||||
|
||||
// time (Tms) of last trigger event
|
||||
uint32_t lastTtrig;
|
||||
// data of last trigger event
|
||||
event_log lastLog;
|
||||
/**
|
||||
* @brief show_trigger_shot printout @ USB data with all triggers shot recently (+ save it in flash)
|
||||
* @param tshot - each bit consists information about trigger
|
||||
*/
|
||||
void show_trigger_shot(uint8_t tshot){
|
||||
uint8_t X = 1;
|
||||
for(uint8_t i = 0; i < TRIGGERS_AMOUNT && tshot; ++i, X <<= 1){
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
if(tshot & X) tshot &= ~X;
|
||||
else continue;
|
||||
lastTtrig = Tms;
|
||||
lastLog.trigno = i;
|
||||
if(i == LIDAR_TRIGGER) lastLog.lidar_dist = lidar_triggered_dist;
|
||||
lastLog.shottime = shottime[i];
|
||||
lastLog.triglen = triglen[i];
|
||||
sendstring(get_trigger_shot(-1, &lastLog));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief strln == strlen
|
||||
* @param s - string
|
||||
* @return length
|
||||
*/
|
||||
int strln(const char *s){
|
||||
int i = 0;
|
||||
while(*s++) ++i;
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief strcp - strcpy (be carefull: it doesn't checks destination length!)
|
||||
* @param dst - destination
|
||||
* @param src - source
|
||||
* @return pointer to '\0' @ dst`s end
|
||||
*/
|
||||
char *strcp(char* dst, const char *src){
|
||||
int l = strln(src);
|
||||
if(l < 1) return dst;
|
||||
while((*dst++ = *src++));
|
||||
return dst - 1;
|
||||
}
|
||||
|
||||
|
||||
// read `buf` and get first integer `N` in it
|
||||
// @return 0 if all OK or 1 if there's not a number; omit spaces and '='
|
||||
int getnum(const char *buf, int32_t *N){
|
||||
char c;
|
||||
int positive = -1;
|
||||
int32_t val = 0;
|
||||
while((c = *buf++)){
|
||||
if(c == '\t' || c == ' ' || c == '='){
|
||||
if(positive < 0) continue; // beginning spaces
|
||||
else break; // spaces after number
|
||||
}
|
||||
if(c == '-'){
|
||||
if(positive < 0){
|
||||
positive = 0;
|
||||
continue;
|
||||
}else break; // there already was `-` or number
|
||||
}
|
||||
if(c < '0' || c > '9') break;
|
||||
if(positive < 0) positive = 1;
|
||||
val = val * 10 + (int32_t)(c - '0');
|
||||
}
|
||||
if(positive != -1){
|
||||
if(positive == 0){
|
||||
if(val == 0) return 1; // single '-'
|
||||
val = -val;
|
||||
}
|
||||
*N = val;
|
||||
}else return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char strbuf[11];
|
||||
// return string buffer (strbuf) with val
|
||||
char *u2str(uint32_t val){
|
||||
char *bufptr = &strbuf[10];
|
||||
*bufptr = 0;
|
||||
if(!val){
|
||||
*(--bufptr) = '0';
|
||||
}else{
|
||||
while(val){
|
||||
*(--bufptr) = val % 10 + '0';
|
||||
val /= 10;
|
||||
}
|
||||
}
|
||||
return bufptr;
|
||||
}
|
||||
|
||||
// return strbuf filled with hex
|
||||
char *u2hex(uint32_t val){
|
||||
char *bufptr = strbuf;
|
||||
*bufptr++ = '0';
|
||||
*bufptr++ = 'x';
|
||||
uint8_t *ptr = (uint8_t*)&val + 3;
|
||||
int i, j;
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
for(i = 0; i < 4; ++i, --ptr){
|
||||
for(j = 1; j > -1; --j){
|
||||
register uint8_t half = (*ptr >> (4*j)) & 0x0f;
|
||||
if(half < 10) *bufptr++ = half + '0';
|
||||
else *bufptr++ = half - 10 + 'a';
|
||||
}
|
||||
}
|
||||
*bufptr = 0;
|
||||
return strbuf;
|
||||
}
|
||||
|
||||
static char localbuffer[LOCBUFSZ];
|
||||
static uint8_t bufidx = 0;
|
||||
static void transmitlocbuf(){
|
||||
localbuffer[bufidx] = 0;
|
||||
USB_send(localbuffer);
|
||||
if(!(the_conf.defflags & FLAG_GPSPROXY)){ // USART1 isn't a GPS proxy
|
||||
usart_send(1, localbuffer);
|
||||
transmit_tbuf(1);
|
||||
}
|
||||
if(the_conf.defflags & FLAG_NOLIDAR){ // USART3 isn't a LIDAR
|
||||
usart_send(LIDAR_USART, localbuffer);
|
||||
transmit_tbuf(LIDAR_USART);
|
||||
}
|
||||
bufidx = 0;
|
||||
}
|
||||
// add char to buf
|
||||
void sendchar(char ch){
|
||||
localbuffer[bufidx++] = ch;
|
||||
if(bufidx >= LOCBUFSZ-1) transmitlocbuf();
|
||||
}
|
||||
/**
|
||||
* @brief addtobuf - add to local buffer any zero-terminated substring
|
||||
* @param str - string to add
|
||||
* it sends data to USB and (due to setup) USART1 when buffer will be full or when meet '\n' at the end of str
|
||||
*/
|
||||
void sendstring(const char *str){
|
||||
while(*str) sendchar(*str++);
|
||||
if(str[-1] == '\n') transmitlocbuf();
|
||||
}
|
||||
93
F1-nolib/chronometer_v3/str.h
Normal file
93
F1-nolib/chronometer_v3/str.h
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* This file is part of the chronometer project.
|
||||
* Copyright 2019 Edward V. Emelianov <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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef STR_H__
|
||||
#define STR_H__
|
||||
|
||||
#include "stm32f1.h"
|
||||
#include "flash.h"
|
||||
#include "hardware.h"
|
||||
|
||||
// local buffer size (chars)
|
||||
#define LOCBUFSZ 128
|
||||
|
||||
// TTY commands
|
||||
#define CMD_BTNSTATE "btnstate"
|
||||
#define CMD_BUZZER "buzzer"
|
||||
#define CMD_CLEARSCRN "cls"
|
||||
#define CMD_CURDIST "curdist"
|
||||
#define CMD_DELLOGS "deletelogs"
|
||||
#define CMD_DISTMAX "distmax"
|
||||
#define CMD_DISTMIN "distmin"
|
||||
#define CMD_DUMP "dump"
|
||||
#define CMD_DUMPN "ndump"
|
||||
#define CMD_EVTLEN "evtlen"
|
||||
#define CMD_FLASH "flash"
|
||||
#define CMD_GETMCUTEMP "mcutemp"
|
||||
#define CMD_GETVDD "vdd"
|
||||
#define CMD_GATE "gate"
|
||||
#define CMD_GPSPROXY "gpsproxy"
|
||||
#define CMD_GPSRESTART "gpsrestart"
|
||||
#define CMD_GPSSTAT "gpsstat"
|
||||
#define CMD_GPSSTR "gpsstring"
|
||||
#define CMD_LEDS "leds"
|
||||
#define CMD_LIDAR "lidar"
|
||||
#define CMD_LIDARSPEED "lidspd"
|
||||
#define CMD_MESG "mesg"
|
||||
#define CMD_NFREE "nfree"
|
||||
#define CMD_PRINTTIME "time"
|
||||
#define CMD_RESET "reset"
|
||||
#define CMD_SAVEEVTS "se"
|
||||
#define CMD_SHOWCONF "showconf"
|
||||
#define CMD_SHOWSHTR "showshutter"
|
||||
#define CMD_SHOWTIME "showtime"
|
||||
#define CMD_STARTAUTO "stauto"
|
||||
#define CMD_STARTONCE "stonce"
|
||||
#define CMD_STORECONF "store"
|
||||
#define CMD_STORTEST "stortest"
|
||||
#define CMD_STREND "strend"
|
||||
#define CMD_SQUEAK "squeak"
|
||||
#define CMD_TRGPAUSE "trigpause"
|
||||
#define CMD_TRGTIME "trigtime"
|
||||
#define CMD_TRIGLVL "triglevel"
|
||||
#define CMD_USARTSPD "usartspd"
|
||||
#define CMD_USBRST "usbreset"
|
||||
|
||||
// starting flags: once, every N seconds
|
||||
#define ST_FLAG_ONCE (1<<0)
|
||||
#define ST_FLAG_AUTO (1<<1)
|
||||
// max delayed time = 5 min (2..9)
|
||||
#define MAX_TIMETOSTART 5
|
||||
extern uint8_t showGPSstr, showtime, startflags, timetostartO, timetostartA, chkshtr, showshtr;
|
||||
extern uint32_t lastTtrig;
|
||||
extern event_log lastLog;
|
||||
|
||||
int getnum(const char *buf, int32_t *N);
|
||||
char *u2str(uint32_t val);
|
||||
char *u2hex(uint32_t val);
|
||||
|
||||
int strln(const char *s);
|
||||
char *strcp(char* dst, const char *src);
|
||||
int cmpstr(const char *s1, const char *s2, int n);
|
||||
char *getchr(const char *str, char symbol);
|
||||
void parse_CMD(char *cmd);
|
||||
char *get_trigger_shot(int number, const event_log *logdata);
|
||||
void show_trigger_shot(uint8_t trigger_shot);
|
||||
void sendstring(const char *str);
|
||||
void sendchar(char ch);
|
||||
#endif // STR_H__
|
||||
212
F1-nolib/chronometer_v3/time.c
Normal file
212
F1-nolib/chronometer_v3/time.c
Normal file
@ -0,0 +1,212 @@
|
||||
/*
|
||||
* This file is part of the chronometer project.
|
||||
* Copyright 2019 Edward V. Emelianov <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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "GPS.h"
|
||||
#include "time.h"
|
||||
#ifdef EBUG
|
||||
#include "usart.h"
|
||||
#endif
|
||||
#include "usb.h"
|
||||
#include <string.h>
|
||||
|
||||
volatile uint32_t Timer; // milliseconds counter
|
||||
curtime current_time = TMNOTINI;
|
||||
|
||||
// convert two-digit decimal string into number
|
||||
static inline uint8_t atou(const char *b){
|
||||
return (uint8_t)((b[0]-'0')*10 + b[1]-'0');
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set_time - set current time from GPS data
|
||||
* @param buf - buffer with time data (HHMMSS)
|
||||
*/
|
||||
void set_time(const char *buf){
|
||||
uint8_t H = atou(buf);// + TIMEZONE_GMT_PLUS;
|
||||
if(H > 23) H -= 24;
|
||||
current_time.H = H;
|
||||
current_time.M = atou(&buf[2]);
|
||||
current_time.S = atou(&buf[4]);
|
||||
/*
|
||||
#ifdef EBUG
|
||||
SEND("set_time, Tms: "); printu(1, Tms);
|
||||
SEND("; Timer: "); printu(1, Timer);
|
||||
newline(1);
|
||||
#endif
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief time_increment - increment system timer by systick
|
||||
*/
|
||||
void time_increment(){
|
||||
Timer = 0;
|
||||
if(current_time.H == 25) return; // Time not initialized
|
||||
if(++current_time.S == 60){
|
||||
current_time.S = 0;
|
||||
if(++current_time.M == 60){
|
||||
current_time.M = 0;
|
||||
if(++current_time.H == 24)
|
||||
current_time.H = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static char *puttwo(uint8_t N, char *buf){
|
||||
if(N < 10){
|
||||
*buf++ = '0';
|
||||
}else{
|
||||
*buf++ = N/10 + '0';
|
||||
N %= 10;
|
||||
}
|
||||
*buf++ = (char)(N + '0');
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ms2str - fill buffer str with milliseconds ms
|
||||
* @param str (io) - pointer to buffer
|
||||
* @param T - milliseconds
|
||||
*/
|
||||
static void ms2str(char **str, uint32_t T){
|
||||
char *bptr = *str;
|
||||
*bptr++ = '.';
|
||||
if(T > 99){
|
||||
*bptr++ = (char)(T/100 + '0');
|
||||
T %= 100;
|
||||
}else *bptr++ = '0';
|
||||
if(T > 9){
|
||||
*bptr++ = (char)(T/10 + '0');
|
||||
T %= 10;
|
||||
}else *bptr++ = '0';
|
||||
*bptr++ = (char)(T + '0');
|
||||
*str = bptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* print time: Tm - time structure, T - milliseconds
|
||||
*/
|
||||
char *get_time(const curtime *Tm, uint32_t T){
|
||||
static char buf[64];
|
||||
char *bstart = &buf[5], *bptr = bstart;
|
||||
int S = 0;
|
||||
if(T > 999) return "Wrong time";
|
||||
if(Tm->S < 60 && Tm->M < 60 && Tm->H < 24)
|
||||
S = Tm->S + Tm->H*3600 + Tm->M*60; // seconds from day beginning
|
||||
if(!S) *(--bstart) = '0';
|
||||
while(S){
|
||||
*(--bstart) = S%10 + '0';
|
||||
S /= 10;
|
||||
}
|
||||
// now bstart is buffer starting index; bptr points to decimal point
|
||||
ms2str(&bptr, T);
|
||||
// put current time in HH:MM:SS format into buf
|
||||
*bptr++ = ' '; *bptr++ = '(';
|
||||
bptr = puttwo(Tm->H, bptr); *bptr++ = ':';
|
||||
bptr = puttwo(Tm->M, bptr); *bptr++ = ':';
|
||||
bptr = puttwo(Tm->S, bptr);
|
||||
ms2str(&bptr, T);
|
||||
*bptr++ = ')';
|
||||
if(GPS_status == GPS_NOTFOUND){
|
||||
strcpy(bptr, " GPS not found");
|
||||
bptr += 14;
|
||||
}
|
||||
*bptr = 0;
|
||||
return bstart;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get_scrntime - the same as get_time, but for screen (HH:MM:SS.S)
|
||||
* @param T - time structure
|
||||
* @param m - milliseconds
|
||||
* @return string allocated here
|
||||
*/
|
||||
char *get_scrntime(const curtime *T, uint32_t m){
|
||||
static char buf[15];
|
||||
char *bptr = buf;
|
||||
if(m > 999) return "Wrong time";
|
||||
// put current time in HH:MM:SS format into buf
|
||||
bptr = puttwo(T->H, bptr); *bptr++ = ':';
|
||||
bptr = puttwo(T->M, bptr); *bptr++ = ':';
|
||||
bptr = puttwo(T->S, bptr);
|
||||
ms2str(&bptr, m);
|
||||
*bptr = 0;
|
||||
return buf;
|
||||
}
|
||||
|
||||
#ifdef EBUG
|
||||
uint32_t timerval, Tms1;
|
||||
int32_t timecntr=0, ticksdiff=0;
|
||||
#else
|
||||
static int32_t timecntr=0, ticksdiff=0;
|
||||
#endif
|
||||
uint32_t last_corr_time = 0;
|
||||
|
||||
/**
|
||||
* @brief systick_correction
|
||||
* Makes correction of system timer
|
||||
* The default frequency of timer is 1kHz - 72000 clocks per interrupt
|
||||
* So we check how much ticks there was for last one second - between PPS interrupts
|
||||
* Their amount equal to M = `Timer` value x (SysTick->LOAD+1) + (SysTick->LOAD+1 - SysTick->VAL)
|
||||
* if `Timer` is very small, add 1000 to its value.
|
||||
* We need 1000xN ticks instead of M
|
||||
* if L = LOAD+1, then
|
||||
* M = Timer*L + L - VAL; newL = L + D = M/1000
|
||||
* 1000*D = M - 1000*L = L(Timer+1-1000) - VAL ->
|
||||
* D = [L*(Timer-999) - VAL]/1000
|
||||
* So correction equal to
|
||||
* [ (SysTick->LOAD + 1) * (Timer - 999) - SysTick->VAL ] / 1000
|
||||
*/
|
||||
void systick_correction(){
|
||||
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; // stop systick for a while
|
||||
int32_t systick_val = (int32_t)SysTick->VAL, L = (int32_t)SysTick->LOAD + 1;
|
||||
uint32_t timer_val = Timer;
|
||||
#ifdef EBUG
|
||||
timerval = Timer;
|
||||
Tms1 = Tms;
|
||||
#endif
|
||||
Timer = 0;
|
||||
SysTick->VAL = SysTick->LOAD;
|
||||
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; // start it again
|
||||
// if(systick_val != SysTick->LOAD) ++Tms;
|
||||
if(timer_val > 500) time_increment(); // counter greater than 500 -> need to increment time
|
||||
if(last_corr_time){
|
||||
uint32_t Tdiff = Tms - last_corr_time;
|
||||
if(Tdiff < 1500 && Tdiff > 700){ // there was perevious PPS signal ~1s ago
|
||||
int32_t D = L * ((int32_t)(Tms - 1000 - last_corr_time)) + ((int32_t)SysTick->LOAD - systick_val); // amount of spare ticks
|
||||
++timecntr;
|
||||
ticksdiff += D;
|
||||
uint32_t ticksabs = (ticksdiff < 0) ? (uint32_t)-ticksdiff : (uint32_t)ticksdiff;
|
||||
// 30000 == 30 seconds * 1000 interrupts per second
|
||||
if(ticksabs > 30000 && timecntr > 10){ // need correction (not more often than each 10s)
|
||||
ticksdiff /= timecntr * 1000; // correction per one interrupt
|
||||
SysTick->LOAD = (uint32_t)(ticksdiff + (int32_t)SysTick->LOAD);
|
||||
timecntr = 0;
|
||||
ticksdiff = 0;
|
||||
#ifdef EBUG
|
||||
SEND("Correction\n");
|
||||
#endif
|
||||
}
|
||||
}else{
|
||||
timecntr = 0;
|
||||
ticksdiff = 0;
|
||||
}
|
||||
}
|
||||
last_corr_time = Tms;
|
||||
}
|
||||
|
||||
66
F1-nolib/chronometer_v3/time.h
Normal file
66
F1-nolib/chronometer_v3/time.h
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* This file is part of the chronometer project.
|
||||
* Copyright 2019 Edward V. Emelianov <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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef TIME_H__
|
||||
#define TIME_H__
|
||||
|
||||
#include <stm32f1.h>
|
||||
|
||||
// default value for systick_config
|
||||
#define SYSTICK_DEFCONF (72000)
|
||||
// defaul for systick->load
|
||||
#define SYSTICK_DEFLOAD (SYSTICK_DEFCONF - 1)
|
||||
#define TIMEZONE_GMT_PLUS (3)
|
||||
|
||||
#define DIDNT_TRIGGERED (2000)
|
||||
|
||||
// debounce delay: .4s
|
||||
#define TRIGGER_DELAY (400)
|
||||
|
||||
#define TMNOTINI {25,61,61}
|
||||
|
||||
// current milliseconds
|
||||
#define get_millis() (Timer)
|
||||
|
||||
typedef struct{
|
||||
uint8_t H;
|
||||
uint8_t M;
|
||||
uint8_t S;
|
||||
} curtime;
|
||||
|
||||
#ifdef EBUG
|
||||
extern int32_t ticksdiff, timecntr;
|
||||
extern uint32_t timerval, Tms1;
|
||||
#endif
|
||||
extern volatile uint32_t Tms;
|
||||
extern volatile uint32_t Timer;
|
||||
extern curtime current_time;
|
||||
extern uint32_t last_corr_time;
|
||||
|
||||
extern curtime trigger_time[];
|
||||
extern uint32_t trigger_ms[];
|
||||
|
||||
extern volatile int need_sync;
|
||||
|
||||
char *get_time(const curtime *T, uint32_t m);
|
||||
char *get_scrntime(const curtime *T, uint32_t m);
|
||||
void set_time(const char *buf);
|
||||
void time_increment();
|
||||
void systick_correction();
|
||||
|
||||
#endif // TIME_H__
|
||||
309
F1-nolib/chronometer_v3/usart.c
Normal file
309
F1-nolib/chronometer_v3/usart.c
Normal file
@ -0,0 +1,309 @@
|
||||
/*
|
||||
* This file is part of the chronometer project.
|
||||
* Copyright 2019 Edward V. Emelianov <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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "stm32f1.h"
|
||||
#include "flash.h"
|
||||
#include "lidar.h"
|
||||
#include "str.h"
|
||||
#include "usart.h"
|
||||
|
||||
extern volatile uint32_t Tms;
|
||||
static volatile uint8_t idatalen[4][2] = {{0}}; // received data line length (including '\n')
|
||||
static volatile uint8_t odatalen[4][2] = {{0}};
|
||||
|
||||
static volatile uint8_t dlen[4] = {0}; // length of data (including '\n') in current buffer
|
||||
|
||||
volatile uint8_t linerdy[4] = {0}, // received data ready
|
||||
bufovr[4] = {0}, // input buffer overfull
|
||||
txrdy[4] = {0,1,1,1} // transmission done
|
||||
;
|
||||
|
||||
|
||||
static uint8_t rbufno[4] = {0}, tbufno[4] = {0}; // current rbuf/tbuf numbers
|
||||
static char rbuf[4][2][UARTBUFSZ], tbuf[4][2][UARTBUFSZ]; // receive & transmit buffers
|
||||
static char *recvdata[4] = {0};
|
||||
|
||||
/**
|
||||
* return length of received data (without trailing zero)
|
||||
*/
|
||||
int usart_getline(int n, char **line){
|
||||
if(bufovr[n]){
|
||||
bufovr[n] = 0;
|
||||
linerdy[n] = 0;
|
||||
return 0;
|
||||
}
|
||||
*line = recvdata[n];
|
||||
linerdy[n] = 0;
|
||||
return dlen[n];
|
||||
}
|
||||
|
||||
// transmit current tbuf and swap buffers
|
||||
void transmit_tbuf(uint8_t n){
|
||||
DMA_Channel_TypeDef *DMA;
|
||||
switch(n){ // also check if n wrong
|
||||
case 1:
|
||||
DMA = DMA1_Channel4;
|
||||
break;
|
||||
case 2:
|
||||
DMA = DMA1_Channel7;
|
||||
break;
|
||||
case 3:
|
||||
DMA = DMA1_Channel2;
|
||||
break;
|
||||
default: return;
|
||||
}
|
||||
uint32_t tmout = 72000;
|
||||
while(!txrdy[n]){if(--tmout == 0) return;} // wait for previos buffer transmission
|
||||
register uint32_t l = odatalen[n][tbufno[n]];
|
||||
if(!l) return;
|
||||
txrdy[n] = 0;
|
||||
odatalen[n][tbufno[n]] = 0;
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
DMA->CCR &= ~DMA_CCR_EN;
|
||||
DMA->CMAR = (uint32_t) tbuf[n][tbufno[n]]; // mem
|
||||
DMA->CNDTR = l;
|
||||
DMA->CCR |= DMA_CCR_EN;
|
||||
tbufno[n] = !tbufno[n];
|
||||
}
|
||||
|
||||
void usart_putchar(uint8_t n, char ch){
|
||||
if(!n || n > USART_LAST+1) return;
|
||||
for(int i = 0; odatalen[n][tbufno[n]] == UARTBUFSZ && i < 1024; ++i) transmit_tbuf(n);
|
||||
tbuf[n][tbufno[n]][odatalen[n][tbufno[n]]++] = ch;
|
||||
}
|
||||
|
||||
void usart_send(uint8_t n, const char *str){
|
||||
if(!n || n > USART_LAST+1) return;
|
||||
uint32_t x = 512;
|
||||
while(*str && --x){
|
||||
if(odatalen[n][tbufno[n]] == UARTBUFSZ){
|
||||
transmit_tbuf(n);
|
||||
continue;
|
||||
}
|
||||
tbuf[n][tbufno[n]][odatalen[n][tbufno[n]]++] = *str++;
|
||||
}
|
||||
}
|
||||
|
||||
// send newline ("\r" or "\r\n") and transmit whole buffer
|
||||
// for GPS_USART endline always is "\r\n"
|
||||
// @param n - USART number
|
||||
void newline(uint8_t n){
|
||||
if((the_conf.defflags & FLAG_STRENDRN) || n == GPS_USART) usart_putchar(n, '\r');
|
||||
usart_putchar(n, '\n');
|
||||
transmit_tbuf(n);
|
||||
}
|
||||
|
||||
/*
|
||||
* USART speed: baudrate = Fck/(USARTDIV)
|
||||
* USARTDIV stored in USART->BRR
|
||||
*
|
||||
* for 72MHz USARTDIV=72000/f(kboud); so for 115200 USARTDIV=72000/115.2=625 -> BRR=0x271
|
||||
* 9600: BRR = 7500 (0x1D4C)
|
||||
*/
|
||||
static void usart_setup(uint8_t n, uint16_t BRR){
|
||||
DMA_Channel_TypeDef *DMA;
|
||||
IRQn_Type DMAirqN, USARTirqN;
|
||||
USART_TypeDef *USART;
|
||||
switch(n){
|
||||
case 1:
|
||||
// USART1 Tx DMA - Channel4 (Rx - channel 5)
|
||||
DMA = DMA1_Channel4;
|
||||
DMAirqN = DMA1_Channel4_IRQn;
|
||||
USARTirqN = USART1_IRQn;
|
||||
// PA9 - Tx, PA10 - Rx
|
||||
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_USART1EN;
|
||||
GPIOA->CRH |= CRH(9, CNF_AFPP|MODE_NORMAL) | CRH(10, CNF_FLINPUT|MODE_INPUT);
|
||||
USART = USART1;
|
||||
break;
|
||||
case 2:
|
||||
// USART2 Tx DMA - Channel7
|
||||
DMA = DMA1_Channel7;
|
||||
DMAirqN = DMA1_Channel7_IRQn;
|
||||
USARTirqN = USART2_IRQn;
|
||||
// PA2 - Tx, PA3 - Rx
|
||||
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
|
||||
RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
|
||||
GPIOA->CRL |= CRL(2, CNF_AFPP|MODE_NORMAL) | CRL(3, CNF_FLINPUT|MODE_INPUT);
|
||||
USART = USART2;
|
||||
break;
|
||||
case 3:
|
||||
// USART3 Tx DMA - Channel2
|
||||
DMA = DMA1_Channel2;
|
||||
DMAirqN = DMA1_Channel2_IRQn;
|
||||
USARTirqN = USART3_IRQn;
|
||||
// PB10 - Tx, PB11 - Rx
|
||||
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
|
||||
RCC->APB1ENR |= RCC_APB1ENR_USART3EN;
|
||||
GPIOB->CRH |= CRH(10, CNF_AFPP|MODE_NORMAL) | CRH(11, CNF_FLINPUT|MODE_INPUT);
|
||||
USART = USART3;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
DMA->CPAR = (uint32_t) &USART->DR; // periph
|
||||
DMA->CCR |= DMA_CCR_MINC | DMA_CCR_DIR | DMA_CCR_TCIE; // 8bit, mem++, mem->per, transcompl irq
|
||||
// setup usart(n)
|
||||
USART->BRR = BRR;
|
||||
USART->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE; // 1start,8data,nstop; enable Rx,Tx,USART
|
||||
uint32_t tmout = 16000000;
|
||||
while(!(USART->SR & USART_SR_TC)){if(--tmout == 0) break;} // polling idle frame Transmission
|
||||
USART->SR = 0; // clear flags
|
||||
USART->CR1 |= USART_CR1_RXNEIE; // allow Rx IRQ
|
||||
USART->CR3 = USART_CR3_DMAT; // enable DMA Tx
|
||||
// Tx CNDTR set @ each transmission due to data size
|
||||
NVIC_SetPriority(DMAirqN, n);
|
||||
NVIC_EnableIRQ(DMAirqN);
|
||||
NVIC_SetPriority(USARTirqN, n);
|
||||
NVIC_EnableIRQ(USARTirqN);
|
||||
}
|
||||
|
||||
void usarts_setup(){
|
||||
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
|
||||
usart_setup(1, 72000000 / the_conf.USART_speed); // debug console or GPS proxy
|
||||
usart_setup(GPS_USART, 36000000 / GPS_DEFAULT_SPEED); // GPS
|
||||
usart_setup(LIDAR_USART, 36000000 / the_conf.LIDAR_speed); // LIDAR
|
||||
}
|
||||
|
||||
|
||||
static void usart_isr(uint8_t n, USART_TypeDef *USART){
|
||||
#ifdef CHECK_TMOUT
|
||||
static uint32_t tmout[n] = 0;
|
||||
#endif
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
if(USART->SR & USART_SR_RXNE){ // RX not emty - receive next char
|
||||
#ifdef CHECK_TMOUT
|
||||
if(tmout[n] && Tms >= tmout[n]){ // set overflow flag
|
||||
bufovr[n] = 1;
|
||||
idatalen[n][rbufno[n]] = 0;
|
||||
}
|
||||
tmout[n] = Tms + TIMEOUT_MS;
|
||||
if(!tmout[n]) tmout[n] = 1; // prevent 0
|
||||
#endif
|
||||
char rb = (char)USART->DR;
|
||||
if(idatalen[n][rbufno[n]] < UARTBUFSZ){ // put next char into buf
|
||||
if(rb != '\r') rbuf[n][rbufno[n]][idatalen[n][rbufno[n]]++] = rb; // omit '\r'
|
||||
if(rb == '\n'){ // got newline - line ready
|
||||
linerdy[n] = 1;
|
||||
dlen[n] = idatalen[n][rbufno[n]];
|
||||
rbuf[n][rbufno[n]][dlen[n]] = 0;
|
||||
recvdata[n] = rbuf[n][rbufno[n]];
|
||||
// prepare other buffer
|
||||
rbufno[n] = !rbufno[n];
|
||||
idatalen[n][rbufno[n]] = 0;
|
||||
#ifdef CHECK_TMOUT
|
||||
// clear timeout at line end
|
||||
tmout[n] = 0;
|
||||
#endif
|
||||
}
|
||||
}else{ // buffer overrun
|
||||
bufovr[n] = 1;
|
||||
idatalen[n][rbufno[n]] = 0;
|
||||
#ifdef CHECK_TMOUT
|
||||
tmout[n] = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void usart1_isr(){
|
||||
usart_isr(1, USART1);
|
||||
}
|
||||
|
||||
// GPS_USART
|
||||
void usart2_isr(){
|
||||
usart_isr(2, USART2);
|
||||
}
|
||||
|
||||
// LIDAR_USART
|
||||
void usart3_isr(){
|
||||
if(the_conf.defflags & FLAG_NOLIDAR){ // regular TTY
|
||||
usart_isr(3, USART3);
|
||||
return;
|
||||
}
|
||||
// LIDAR - check for different things
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
if(USART3->SR & USART_SR_RXNE){ // RX not emty - receive next char
|
||||
char rb = (char)USART3->DR;
|
||||
uint8_t L = idatalen[3][rbufno[3]];
|
||||
if(rb != LIDAR_FRAME_HEADER && (L == 0 || L == 1)){ // bad starting sequence
|
||||
idatalen[3][rbufno[3]] = 0;
|
||||
return;
|
||||
}
|
||||
if(L < LIDAR_FRAME_LEN){ // put next char into buf
|
||||
rbuf[3][rbufno[3]][idatalen[3][rbufno[3]]++] = rb;
|
||||
if(L == LIDAR_FRAME_LEN-1){ // got LIDAR_FRAME_LEN bytes - line ready
|
||||
linerdy[3] = 1;
|
||||
dlen[3] = idatalen[3][rbufno[3]];
|
||||
recvdata[3] = rbuf[3][rbufno[3]];
|
||||
// prepare other buffer
|
||||
rbufno[3] = !rbufno[3];
|
||||
idatalen[3][rbufno[3]] = 0;
|
||||
}
|
||||
}else{ // buffer overrun
|
||||
idatalen[3][rbufno[3]] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// print 32bit unsigned int
|
||||
void printu(uint8_t n, uint32_t val){
|
||||
usart_send(n, u2str(val));
|
||||
}
|
||||
|
||||
// print 32bit unsigned int as hex
|
||||
void printuhex(uint8_t n, uint32_t val){
|
||||
usart_send(n, u2hex(val));
|
||||
}
|
||||
|
||||
#ifdef EBUG
|
||||
// dump memory buffer
|
||||
void hexdump(uint8_t *arr, uint16_t len){
|
||||
for(uint16_t l = 0; l < len; ++l, ++arr){
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
for(int16_t j = 1; j > -1; --j){
|
||||
register uint8_t half = (*arr >> (4*j)) & 0x0f;
|
||||
if(half < 10) usart_putchar(1, half + '0');
|
||||
else usart_putchar(1, half - 10 + 'a');
|
||||
}
|
||||
if(l % 16 == 15) usart_putchar(1, '\n');
|
||||
else if((l & 3) == 3) usart_putchar(1, ' ');
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void dma1_channel4_isr(){ // USART1
|
||||
if(DMA1->ISR & DMA_ISR_TCIF4){ // Tx
|
||||
DMA1->IFCR = DMA_IFCR_CTCIF4; // clear TC flag
|
||||
txrdy[1] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void dma1_channel7_isr(){ // USART2
|
||||
if(DMA1->ISR & DMA_ISR_TCIF7){ // Tx
|
||||
DMA1->IFCR = DMA_IFCR_CTCIF7; // clear TC flag
|
||||
txrdy[2] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void dma1_channel2_isr(){ // USART3
|
||||
if(DMA1->ISR & DMA_ISR_TCIF2){ // Tx
|
||||
DMA1->IFCR = DMA_IFCR_CTCIF2; // clear TC flag
|
||||
txrdy[3] = 1;
|
||||
}
|
||||
}
|
||||
73
F1-nolib/chronometer_v3/usart.h
Normal file
73
F1-nolib/chronometer_v3/usart.h
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* This file is part of the chronometer project.
|
||||
* Copyright 2019 Edward V. Emelianov <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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef __USART_H__
|
||||
#define __USART_H__
|
||||
|
||||
#include <stm32f1.h>
|
||||
|
||||
// input and output buffers size (should be less than 256!!!)
|
||||
#define UARTBUFSZ (128)
|
||||
// timeout between data bytes
|
||||
#ifndef TIMEOUT_MS
|
||||
#define TIMEOUT_MS (1500)
|
||||
#endif
|
||||
|
||||
// number of last USART used
|
||||
#define USART_LAST 3
|
||||
|
||||
// USART1 default speed
|
||||
#define USART1_DEFAULT_SPEED (115200)
|
||||
// LIDAR default speed
|
||||
#define LIDAR_DEFAULT_SPEED (115200)
|
||||
// GPS default speed
|
||||
#define GPS_DEFAULT_SPEED (9600)
|
||||
|
||||
#define STR_HELPER(s) #s
|
||||
#define STR(s) STR_HELPER(s)
|
||||
|
||||
#ifdef EBUG
|
||||
#define SEND(str) usart_send(1, str)
|
||||
#define MSG(str) do{SEND(__FILE__ " (L" STR(__LINE__) "): " str);}while(0)
|
||||
#define DBG(str) do{SEND(str); newline(1); }while(0)
|
||||
#else
|
||||
#define SEND(str)
|
||||
#define MSG(str)
|
||||
#define DBG(str)
|
||||
#endif
|
||||
|
||||
#define usartrx(n) (linerdy[n])
|
||||
#define usartovr(n) (bufovr[n])
|
||||
|
||||
extern volatile uint8_t linerdy[], bufovr[], txrdy[];
|
||||
|
||||
void transmit_tbuf(uint8_t n);
|
||||
void usarts_setup();
|
||||
int usart_getline(int n, char **line);
|
||||
void usart_send(uint8_t n, const char *str);
|
||||
void usart_putchar(uint8_t n, char ch);
|
||||
void printu(uint8_t n, uint32_t val);
|
||||
void printuhex(uint8_t n, uint32_t val);
|
||||
void newline(uint8_t n);
|
||||
|
||||
#ifdef EBUG
|
||||
void hexdump(uint8_t *arr, uint16_t len);
|
||||
#endif
|
||||
|
||||
#endif // __USART_H__
|
||||
212
F1-nolib/chronometer_v3/usb.c
Normal file
212
F1-nolib/chronometer_v3/usb.c
Normal file
@ -0,0 +1,212 @@
|
||||
/*
|
||||
* geany_encoding=koi8-r
|
||||
* usb.c - base functions for different USB types
|
||||
*
|
||||
* Copyright 2018 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 "flash.h"
|
||||
#include "usb.h"
|
||||
#include "usb_lib.h"
|
||||
#include "usart.h"
|
||||
|
||||
// incoming buffer size
|
||||
#define IDATASZ (256)
|
||||
static uint8_t incoming_data[IDATASZ];
|
||||
static uint8_t ovfl = 0;
|
||||
static uint16_t idatalen = 0;
|
||||
static volatile uint8_t tx_succesfull = 0;
|
||||
static int8_t usbON = 0; // ==1 when USB fully configured
|
||||
|
||||
// interrupt IN handler (never used?)
|
||||
static uint16_t EP1_Handler(ep_t ep){
|
||||
if (ep.rx_flag){
|
||||
ep.status = SET_VALID_TX(ep.status);
|
||||
ep.status = KEEP_STAT_RX(ep.status);
|
||||
}else if (ep.tx_flag){
|
||||
ep.status = SET_VALID_RX(ep.status);
|
||||
ep.status = SET_STALL_TX(ep.status);
|
||||
}
|
||||
return ep.status;
|
||||
}
|
||||
|
||||
// data IN/OUT handler
|
||||
static uint16_t EP23_Handler(ep_t ep){
|
||||
if(ep.rx_flag){
|
||||
int rd = ep.rx_cnt, rest = IDATASZ - idatalen;
|
||||
if(rd){
|
||||
if(rd <= rest){
|
||||
idatalen += EP_Read(2, (uint16_t*)&incoming_data[idatalen]);
|
||||
ovfl = 0;
|
||||
}else{
|
||||
ep.status = SET_NAK_RX(ep.status);
|
||||
ovfl = 1;
|
||||
return ep.status;
|
||||
}
|
||||
}
|
||||
// end of transaction: clear DTOGs
|
||||
ep.status = CLEAR_DTOG_RX(ep.status);
|
||||
ep.status = CLEAR_DTOG_TX(ep.status);
|
||||
ep.status = SET_STALL_TX(ep.status);
|
||||
}else if (ep.tx_flag){
|
||||
ep.status = KEEP_STAT_TX(ep.status);
|
||||
tx_succesfull = 1;
|
||||
}
|
||||
ep.status = SET_VALID_RX(ep.status);
|
||||
return ep.status;
|
||||
}
|
||||
|
||||
void USB_setup(){
|
||||
NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn);
|
||||
NVIC_DisableIRQ(USB_HP_CAN1_TX_IRQn);
|
||||
RCC->APB1ENR |= RCC_APB1ENR_USBEN;
|
||||
USB->CNTR = USB_CNTR_FRES; // Force USB Reset
|
||||
for(uint32_t ctr = 0; ctr < 72000; ++ctr) nop(); // wait >1ms
|
||||
//uint32_t ctr = 0;
|
||||
USB->CNTR = 0;
|
||||
USB->BTABLE = 0;
|
||||
USB->DADDR = 0;
|
||||
USB->ISTR = 0;
|
||||
USB->CNTR = USB_CNTR_RESETM | USB_CNTR_WKUPM; // allow only wakeup & reset interrupts
|
||||
NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
|
||||
NVIC_EnableIRQ(USB_HP_CAN1_TX_IRQn );
|
||||
}
|
||||
|
||||
void usb_proc(){
|
||||
if(USB_GetState() == USB_CONFIGURE_STATE){ // USB configured - activate other endpoints
|
||||
if(!usbON){ // endpoints not activated
|
||||
// make new BULK endpoint
|
||||
// Buffer have 1024 bytes, but last 256 we use for CAN bus (30.2 of RM: USB main features)
|
||||
EP_Init(1, EP_TYPE_INTERRUPT, 10, 0, EP1_Handler); // IN1 - transmit
|
||||
EP_Init(2, EP_TYPE_BULK, 0, USB_RXBUFSZ, EP23_Handler); // OUT2 - receive data
|
||||
EP_Init(3, EP_TYPE_BULK, USB_TXBUFSZ, 0, EP23_Handler); // IN3 - transmit data
|
||||
usbON = 1;
|
||||
}
|
||||
}else{
|
||||
usbON = 0;
|
||||
}
|
||||
}
|
||||
|
||||
extern uint8_t USB_connected;
|
||||
void USB_send(const char *buf){
|
||||
if(!USB_configured()){
|
||||
DBG("USB not configured");
|
||||
return;
|
||||
}
|
||||
if(!USB_connected) return; // no connection -> no need to send data into nothing
|
||||
char tmpbuf[USB_TXBUFSZ];
|
||||
uint16_t l = 0, ctr = 0;
|
||||
const char *p = buf;
|
||||
while(*p++) ++l;
|
||||
while(l){
|
||||
uint16_t proc = 0, s = (l > USB_TXBUFSZ - 1) ? USB_TXBUFSZ - 1: l;
|
||||
for(int i = 0; i < s; ++i, ++proc){
|
||||
char c = buf[ctr+proc];
|
||||
if(c == '\n' && the_conf.defflags & FLAG_STRENDRN){ // add '\r' before '\n'
|
||||
tmpbuf[i++] = '\r';
|
||||
if(i == s) ++s;
|
||||
}
|
||||
if(c == 0x1B) tmpbuf[i] = 'E'; // ESC
|
||||
else if(c == 0x7F) tmpbuf[i] = 'B'; // Backspace
|
||||
else tmpbuf[i] = c;
|
||||
}
|
||||
tx_succesfull = 0;
|
||||
EP_Write(3, (uint8_t*)tmpbuf, s);
|
||||
uint32_t ctra = 1000000;
|
||||
while(--ctra && tx_succesfull == 0);
|
||||
l -= proc;
|
||||
ctr += proc;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USB_receive
|
||||
* @param buf (i) - buffer for received data
|
||||
* @param bufsize - its size
|
||||
* @return amount of received bytes
|
||||
*/
|
||||
int USB_receive(char *buf, int bufsize){
|
||||
if(!bufsize || !idatalen) return 0;
|
||||
USB->CNTR = 0;
|
||||
int sz = (idatalen > bufsize) ? bufsize : idatalen, rest = idatalen - sz;
|
||||
for(int i = 0; i < sz; ++i) buf[i] = incoming_data[i];
|
||||
if(rest > 0){
|
||||
uint8_t *ptr = &incoming_data[sz];
|
||||
for(int i = 0; i < rest; ++i) incoming_data[i] = *ptr++;
|
||||
idatalen = rest;
|
||||
}else idatalen = 0;
|
||||
if(ovfl){
|
||||
EP23_Handler(endpoints[2]);
|
||||
uint16_t epstatus = USB->EPnR[2];
|
||||
epstatus = CLEAR_DTOG_RX(epstatus);
|
||||
epstatus = SET_VALID_RX(epstatus);
|
||||
USB->EPnR[2] = epstatus;
|
||||
}
|
||||
USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM;
|
||||
return sz;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USB_configured
|
||||
* @return 1 if USB is in configured state
|
||||
*/
|
||||
int USB_configured(){
|
||||
return usbON;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* default handlers
|
||||
*
|
||||
// SET_LINE_CODING
|
||||
void WEAK linecoding_handler(usb_LineCoding __attribute__((unused)) *lc){
|
||||
DBG("WEAK LH");
|
||||
}
|
||||
|
||||
// SET_CONTROL_LINE_STATE
|
||||
void WEAK clstate_handler(uint16_t __attribute__((unused)) val){
|
||||
DBG("WEAK CLSH");
|
||||
}
|
||||
|
||||
// SEND_BREAK
|
||||
void WEAK break_handler(){
|
||||
DBG("WEAK BH");
|
||||
}*/
|
||||
|
||||
// handler of vendor requests
|
||||
void WEAK vendor_handler(config_pack_t *packet){
|
||||
if(packet->bmRequestType & 0x80){ // read
|
||||
uint8_t c;
|
||||
switch(packet->wValue){
|
||||
case 0x8484:
|
||||
c = 2;
|
||||
break;
|
||||
case 0x0080:
|
||||
c = 1;
|
||||
break;
|
||||
case 0x8686:
|
||||
c = 0xaa;
|
||||
break;
|
||||
default:
|
||||
c = 0;
|
||||
}
|
||||
EP_WriteIRQ(0, &c, 1);
|
||||
}else{ // write ZLP
|
||||
EP_WriteIRQ(0, (uint8_t *)0, 0);
|
||||
}
|
||||
}
|
||||
37
F1-nolib/chronometer_v3/usb.h
Normal file
37
F1-nolib/chronometer_v3/usb.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* geany_encoding=koi8-r
|
||||
* usb.h
|
||||
*
|
||||
* Copyright 2018 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 __USB_H__
|
||||
#define __USB_H__
|
||||
|
||||
#include "hardware.h"
|
||||
|
||||
#define BUFFSIZE (64)
|
||||
|
||||
void USB_setup();
|
||||
void usb_proc();
|
||||
void USB_send(const char *buf);
|
||||
int USB_receive(char *buf, int bufsize);
|
||||
int USB_configured();
|
||||
|
||||
#endif // __USB_H__
|
||||
117
F1-nolib/chronometer_v3/usb_defs.h
Normal file
117
F1-nolib/chronometer_v3/usb_defs.h
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* geany_encoding=koi8-r
|
||||
* usb_defs.h
|
||||
*
|
||||
* Copyright 2018 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 __USB_DEFS_H__
|
||||
#define __USB_DEFS_H__
|
||||
|
||||
#include <stm32f1.h>
|
||||
|
||||
// max endpoints number
|
||||
#define STM32ENDPOINTS 8
|
||||
/**
|
||||
* Buffers size definition
|
||||
**/
|
||||
#define USB_BTABLE_SIZE 512
|
||||
// first 64 bytes of USB_BTABLE are registers!
|
||||
//#define USB_EP0_BASEADDR 64
|
||||
// for USB FS EP0 buffers are from 8 to 64 bytes long (64 for PL2303)
|
||||
#define USB_EP0_BUFSZ 64
|
||||
// USB transmit buffer size (64 for PL2303)
|
||||
#define USB_TXBUFSZ 64
|
||||
// USB receive buffer size (64 for PL2303)
|
||||
#define USB_RXBUFSZ 64
|
||||
|
||||
#define USB_BTABLE_BASE 0x40006000
|
||||
#define USB_BASE ((uint32_t)0x40005C00)
|
||||
#define USB ((USB_TypeDef *) USB_BASE)
|
||||
|
||||
#ifdef USB_BTABLE
|
||||
#undef USB_BTABLE
|
||||
#endif
|
||||
#define USB_BTABLE ((USB_BtableDef *)(USB_BTABLE_BASE))
|
||||
#define USB_ISTR_EPID 0x0000000F
|
||||
#define USB_FNR_LSOF_0 0x00000800
|
||||
#define USB_FNR_lSOF_1 0x00001000
|
||||
#define USB_LPMCSR_BESL_0 0x00000010
|
||||
#define USB_LPMCSR_BESL_1 0x00000020
|
||||
#define USB_LPMCSR_BESL_2 0x00000040
|
||||
#define USB_LPMCSR_BESL_3 0x00000080
|
||||
#define USB_EPnR_CTR_RX 0x00008000
|
||||
#define USB_EPnR_DTOG_RX 0x00004000
|
||||
#define USB_EPnR_STAT_RX 0x00003000
|
||||
#define USB_EPnR_STAT_RX_0 0x00001000
|
||||
#define USB_EPnR_STAT_RX_1 0x00002000
|
||||
#define USB_EPnR_SETUP 0x00000800
|
||||
#define USB_EPnR_EP_TYPE 0x00000600
|
||||
#define USB_EPnR_EP_TYPE_0 0x00000200
|
||||
#define USB_EPnR_EP_TYPE_1 0x00000400
|
||||
#define USB_EPnR_EP_KIND 0x00000100
|
||||
#define USB_EPnR_CTR_TX 0x00000080
|
||||
#define USB_EPnR_DTOG_TX 0x00000040
|
||||
#define USB_EPnR_STAT_TX 0x00000030
|
||||
#define USB_EPnR_STAT_TX_0 0x00000010
|
||||
#define USB_EPnR_STAT_TX_1 0x00000020
|
||||
#define USB_EPnR_EA 0x0000000F
|
||||
#define USB_COUNTn_RX_BLSIZE 0x00008000
|
||||
#define USB_COUNTn_NUM_BLOCK 0x00007C00
|
||||
#define USB_COUNTn_RX 0x0000003F
|
||||
|
||||
#ifdef USB_TypeDef
|
||||
#define USB_TypeDef USB_TypeDef_custom
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
__IO uint32_t EPnR[STM32ENDPOINTS];
|
||||
__IO uint32_t RESERVED[STM32ENDPOINTS];
|
||||
__IO uint32_t CNTR;
|
||||
__IO uint32_t ISTR;
|
||||
__IO uint32_t FNR;
|
||||
__IO uint32_t DADDR;
|
||||
__IO uint32_t BTABLE;
|
||||
} USB_TypeDef;
|
||||
|
||||
/*
|
||||
typedef struct{
|
||||
__IO uint16_t USB_ADDR_TX;
|
||||
__IO uint16_t res1;
|
||||
__IO uint16_t USB_COUNT_TX;
|
||||
__IO uint16_t res2;
|
||||
__IO uint16_t USB_ADDR_RX;
|
||||
__IO uint16_t res3;
|
||||
__IO uint16_t USB_COUNT_RX;
|
||||
__IO uint16_t res4;
|
||||
} USB_EPDATA_TypeDef;*/
|
||||
|
||||
typedef struct{
|
||||
__IO uint32_t USB_ADDR_TX;
|
||||
__IO uint32_t USB_COUNT_TX;
|
||||
__IO uint32_t USB_ADDR_RX;
|
||||
__IO uint32_t USB_COUNT_RX;
|
||||
} USB_EPDATA_TypeDef;
|
||||
|
||||
typedef struct{
|
||||
__IO USB_EPDATA_TypeDef EP[STM32ENDPOINTS];
|
||||
} USB_BtableDef;
|
||||
|
||||
#endif // __USB_DEFS_H__
|
||||
488
F1-nolib/chronometer_v3/usb_lib.c
Normal file
488
F1-nolib/chronometer_v3/usb_lib.c
Normal file
@ -0,0 +1,488 @@
|
||||
/*
|
||||
* geany_encoding=koi8-r
|
||||
* usb_lib.c
|
||||
*
|
||||
* Copyright 2018 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 <stdint.h>
|
||||
#include "usb_lib.h"
|
||||
#include "usart.h"
|
||||
|
||||
ep_t endpoints[STM32ENDPOINTS];
|
||||
|
||||
static usb_dev_t USB_Dev;
|
||||
static usb_LineCoding lineCoding = {115200, 0, 0, 8};
|
||||
static config_pack_t setup_packet;
|
||||
static uint8_t ep0databuf[EP0DATABUF_SIZE];
|
||||
static uint8_t ep0dbuflen = 0;
|
||||
|
||||
usb_LineCoding getLineCoding(){return lineCoding;}
|
||||
|
||||
// definition of parts common for USB_DeviceDescriptor & USB_DeviceQualifierDescriptor
|
||||
#define bcdUSB_L 0x10
|
||||
#define bcdUSB_H 0x01
|
||||
#define bDeviceClass 0
|
||||
#define bDeviceSubClass 0
|
||||
#define bDeviceProtocol 0
|
||||
#define bNumConfigurations 1
|
||||
|
||||
static const uint8_t USB_DeviceDescriptor[] = {
|
||||
18, // bLength
|
||||
0x01, // bDescriptorType - Device descriptor
|
||||
bcdUSB_L, // bcdUSB_L - 1.10
|
||||
bcdUSB_H, // bcdUSB_H
|
||||
bDeviceClass, // bDeviceClass - USB_COMM
|
||||
bDeviceSubClass, // bDeviceSubClass
|
||||
bDeviceProtocol, // bDeviceProtocol
|
||||
USB_EP0_BUFSZ, // bMaxPacketSize
|
||||
0x7b, // idVendor_L PL2303: VID=0x067b, PID=0x2303
|
||||
0x06, // idVendor_H
|
||||
0x03, // idProduct_L
|
||||
0x23, // idProduct_H
|
||||
0x00, // bcdDevice_Ver_L
|
||||
0x03, // bcdDevice_Ver_H
|
||||
0x01, // iManufacturer
|
||||
0x02, // iProduct
|
||||
0x00, // iSerialNumber
|
||||
bNumConfigurations // bNumConfigurations
|
||||
};
|
||||
|
||||
static const uint8_t USB_DeviceQualifierDescriptor[] = {
|
||||
10, //bLength
|
||||
0x06, // bDescriptorType - Device qualifier
|
||||
bcdUSB_L, // bcdUSB_L
|
||||
bcdUSB_H, // bcdUSB_H
|
||||
bDeviceClass, // bDeviceClass
|
||||
bDeviceSubClass, // bDeviceSubClass
|
||||
bDeviceProtocol, // bDeviceProtocol
|
||||
USB_EP0_BUFSZ, // bMaxPacketSize0
|
||||
bNumConfigurations, // bNumConfigurations
|
||||
0x00 // Reserved
|
||||
};
|
||||
|
||||
static const uint8_t USB_ConfigDescriptor[] = {
|
||||
/*Configuration Descriptor*/
|
||||
0x09, /* bLength: Configuration Descriptor size */
|
||||
0x02, /* bDescriptorType: Configuration */
|
||||
39, /* wTotalLength:no of returned bytes */
|
||||
0x00,
|
||||
0x01, /* bNumInterfaces: 1 interface */
|
||||
0x01, /* bConfigurationValue: Configuration value */
|
||||
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
|
||||
0xa0, /* bmAttributes - Bus powered, Remote wakeup */
|
||||
0x32, /* MaxPower 100 mA */
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/*Interface Descriptor */
|
||||
0x09, /* bLength: Interface Descriptor size */
|
||||
0x04, /* bDescriptorType: Interface */
|
||||
0x00, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x03, /* bNumEndpoints: 3 endpoints used */
|
||||
0xff, /* bInterfaceClass */
|
||||
0x00, /* bInterfaceSubClass */
|
||||
0x00, /* bInterfaceProtocol */
|
||||
0x00, /* iInterface: */
|
||||
///////////////////////////////////////////////////
|
||||
/*Endpoint 1 Descriptor*/
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
0x05, /* bDescriptorType: Endpoint */
|
||||
0x81, /* bEndpointAddress IN1 */
|
||||
0x03, /* bmAttributes: Interrupt */
|
||||
0x0a, /* wMaxPacketSize LO: */
|
||||
0x00, /* wMaxPacketSize HI: */
|
||||
0x01, /* bInterval: */
|
||||
|
||||
/*Endpoint OUT2 Descriptor*/
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
0x05, /* bDescriptorType: Endpoint */
|
||||
0x02, /* bEndpointAddress: OUT2 */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
(USB_RXBUFSZ & 0xff), /* wMaxPacketSize: 64 */
|
||||
(USB_RXBUFSZ >> 8),
|
||||
0x00, /* bInterval: ignore for Bulk transfer */
|
||||
|
||||
/*Endpoint IN3 Descriptor*/
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
0x05, /* bDescriptorType: Endpoint */
|
||||
0x83, /* bEndpointAddress IN3 */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
(USB_TXBUFSZ & 0xff), /* wMaxPacketSize: 64 */
|
||||
(USB_TXBUFSZ >> 8),
|
||||
0x00, /* bInterval: ignore for Bulk transfer */
|
||||
};
|
||||
|
||||
_USB_LANG_ID_(USB_StringLangDescriptor, LANG_US);
|
||||
// these descriptors are not used in PL2303 emulator!
|
||||
_USB_STRING_(USB_StringSerialDescriptor, u"0");
|
||||
_USB_STRING_(USB_StringManufacturingDescriptor, u"Prolific Technology Inc.");
|
||||
_USB_STRING_(USB_StringProdDescriptor, u"USB-Serial Controller");
|
||||
|
||||
static void wr0(const uint8_t *buf, uint16_t size){
|
||||
if(setup_packet.wLength < size) size = setup_packet.wLength;
|
||||
EP_WriteIRQ(0, buf, size);
|
||||
}
|
||||
|
||||
static inline void get_descriptor(){
|
||||
switch(setup_packet.wValue){
|
||||
case DEVICE_DESCRIPTOR:
|
||||
wr0(USB_DeviceDescriptor, sizeof(USB_DeviceDescriptor));
|
||||
break;
|
||||
case CONFIGURATION_DESCRIPTOR:
|
||||
wr0(USB_ConfigDescriptor, sizeof(USB_ConfigDescriptor));
|
||||
break;
|
||||
case STRING_LANG_DESCRIPTOR:
|
||||
wr0((const uint8_t *)&USB_StringLangDescriptor, STRING_LANG_DESCRIPTOR_SIZE_BYTE);
|
||||
break;
|
||||
case STRING_MAN_DESCRIPTOR:
|
||||
wr0((const uint8_t *)&USB_StringManufacturingDescriptor, USB_StringManufacturingDescriptor.bLength);
|
||||
break;
|
||||
case STRING_PROD_DESCRIPTOR:
|
||||
wr0((const uint8_t *)&USB_StringProdDescriptor, USB_StringProdDescriptor.bLength);
|
||||
break;
|
||||
case STRING_SN_DESCRIPTOR:
|
||||
wr0((const uint8_t *)&USB_StringSerialDescriptor, USB_StringSerialDescriptor.bLength);
|
||||
break;
|
||||
case DEVICE_QUALIFIER_DESCRIPTOR:
|
||||
wr0(USB_DeviceQualifierDescriptor, USB_DeviceQualifierDescriptor[0]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t configuration = 0; // reply for GET_CONFIGURATION (==1 if configured)
|
||||
static inline void std_d2h_req(){
|
||||
uint16_t status = 0; // bus powered
|
||||
switch(setup_packet.bRequest){
|
||||
case GET_DESCRIPTOR:
|
||||
get_descriptor();
|
||||
break;
|
||||
case GET_STATUS:
|
||||
EP_WriteIRQ(0, (uint8_t *)&status, 2); // send status: Bus Powered
|
||||
break;
|
||||
case GET_CONFIGURATION:
|
||||
EP_WriteIRQ(0, &configuration, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void std_h2d_req(){
|
||||
switch(setup_packet.bRequest){
|
||||
case SET_ADDRESS:
|
||||
// new address will be assigned later - after acknowlegement or request to host
|
||||
USB_Dev.USB_Addr = setup_packet.wValue;
|
||||
break;
|
||||
case SET_CONFIGURATION:
|
||||
// Now device configured
|
||||
USB_Dev.USB_Status = USB_CONFIGURE_STATE;
|
||||
configuration = setup_packet.wValue;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
bmRequestType: 76543210
|
||||
7 direction: 0 - host->device, 1 - device->host
|
||||
65 type: 0 - standard, 1 - class, 2 - vendor
|
||||
4..0 getter: 0 - device, 1 - interface, 2 - endpoint, 3 - other
|
||||
*/
|
||||
/**
|
||||
* Endpoint0 (control) handler
|
||||
* @param ep - endpoint state
|
||||
* @return data written to EP0R
|
||||
*/
|
||||
static uint16_t EP0_Handler(ep_t ep){
|
||||
uint16_t epstatus = ep.status; // EP0R on input -> return this value after modifications
|
||||
uint8_t reqtype = setup_packet.bmRequestType & 0x7f;
|
||||
uint8_t dev2host = (setup_packet.bmRequestType & 0x80) ? 1 : 0;
|
||||
if ((ep.rx_flag) && (ep.setup_flag)){
|
||||
switch(reqtype){
|
||||
case STANDARD_DEVICE_REQUEST_TYPE: // standard device request
|
||||
if(dev2host){
|
||||
std_d2h_req();
|
||||
}else{
|
||||
std_h2d_req();
|
||||
EP_WriteIRQ(0, (uint8_t *)0, 0);
|
||||
}
|
||||
//epstatus = SET_NAK_RX(epstatus);
|
||||
//epstatus = SET_VALID_TX(epstatus);
|
||||
break;
|
||||
case STANDARD_ENDPOINT_REQUEST_TYPE: // standard endpoint request
|
||||
if(setup_packet.bRequest == CLEAR_FEATURE){
|
||||
EP_WriteIRQ(0, (uint8_t *)0, 0);
|
||||
//epstatus = SET_NAK_RX(epstatus);
|
||||
//epstatus = SET_VALID_TX(epstatus);
|
||||
}
|
||||
break;
|
||||
case VENDOR_REQUEST_TYPE:
|
||||
vendor_handler(&setup_packet);
|
||||
//epstatus = SET_NAK_RX(epstatus);
|
||||
//epstatus = SET_VALID_TX(epstatus);
|
||||
break;
|
||||
case CONTROL_REQUEST_TYPE:
|
||||
switch(setup_packet.bRequest){
|
||||
case GET_LINE_CODING:
|
||||
EP_WriteIRQ(0, (uint8_t*)&lineCoding, sizeof(lineCoding));
|
||||
break;
|
||||
case SET_LINE_CODING: // omit this for next stage, when data will come
|
||||
break;
|
||||
case SET_CONTROL_LINE_STATE:
|
||||
clstate_handler(setup_packet.wValue);
|
||||
break;
|
||||
case SEND_BREAK:
|
||||
break_handler();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// SET_CONTROL_LINE_STATE don't work! Need something to fix the BUG!
|
||||
//if(!dev2host)
|
||||
if(setup_packet.bRequest != GET_LINE_CODING)
|
||||
EP_WriteIRQ(0, (uint8_t *)0, 0); // write acknowledgement
|
||||
//epstatus = SET_VALID_RX(epstatus);
|
||||
//epstatus = SET_VALID_TX(epstatus);
|
||||
break;
|
||||
default:
|
||||
EP_WriteIRQ(0, (uint8_t *)0, 0);
|
||||
//epstatus = SET_NAK_RX(epstatus);
|
||||
//epstatus = SET_VALID_TX(epstatus);
|
||||
}
|
||||
}else if (ep.rx_flag){ // got data over EP0 or host acknowlegement
|
||||
if(ep.rx_cnt){
|
||||
//EP_WriteIRQ(0, (uint8_t *)0, 0);
|
||||
if(setup_packet.bRequest == SET_LINE_CODING){
|
||||
linecoding_handler((usb_LineCoding*)ep0databuf);
|
||||
}
|
||||
}
|
||||
// wait for new data from host
|
||||
//epstatus = SET_VALID_RX(epstatus);
|
||||
//epstatus = SET_VALID_TX(epstatus);
|
||||
} else if (ep.tx_flag){ // package transmitted
|
||||
// now we can change address after enumeration
|
||||
if ((USB->DADDR & USB_DADDR_ADD) != USB_Dev.USB_Addr){
|
||||
USB->DADDR = USB_DADDR_EF | USB_Dev.USB_Addr;
|
||||
// change state to ADRESSED
|
||||
USB_Dev.USB_Status = USB_ADRESSED_STATE;
|
||||
}
|
||||
// end of transaction
|
||||
epstatus = CLEAR_DTOG_RX(epstatus);
|
||||
epstatus = CLEAR_DTOG_TX(epstatus);
|
||||
//epstatus = SET_VALID_RX(epstatus);
|
||||
//epstatus = SET_VALID_TX(epstatus);
|
||||
}
|
||||
epstatus = SET_VALID_RX(epstatus);
|
||||
epstatus = SET_VALID_TX(epstatus);
|
||||
return epstatus;
|
||||
}
|
||||
|
||||
static uint16_t lastaddr = LASTADDR_DEFAULT;
|
||||
/**
|
||||
* Endpoint initialisation
|
||||
* @param number - EP num (0...7)
|
||||
* @param type - EP type (EP_TYPE_BULK, EP_TYPE_CONTROL, EP_TYPE_ISO, EP_TYPE_INTERRUPT)
|
||||
* @param txsz - transmission buffer size @ USB/CAN buffer
|
||||
* @param rxsz - reception buffer size @ USB/CAN buffer
|
||||
* @param uint16_t (*func)(ep_t *ep) - EP handler function
|
||||
* @return 0 if all OK
|
||||
*/
|
||||
int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, uint16_t (*func)(ep_t ep)){
|
||||
if(number >= STM32ENDPOINTS) return 4; // out of configured amount
|
||||
if(txsz > USB_BTABLE_SIZE || rxsz > USB_BTABLE_SIZE) return 1; // buffer too large
|
||||
if(lastaddr + txsz + rxsz >= USB_BTABLE_SIZE) return 2; // out of btable
|
||||
USB->EPnR[number] = (type << 9) | (number & USB_EPnR_EA);
|
||||
USB->EPnR[number] ^= USB_EPnR_STAT_RX | USB_EPnR_STAT_TX_1;
|
||||
if(rxsz & 1 || rxsz > 512) return 3; // wrong rx buffer size
|
||||
uint16_t countrx = 0;
|
||||
if(rxsz < 64) countrx = rxsz / 2;
|
||||
else{
|
||||
if(rxsz & 0x1f) return 3; // should be multiple of 32
|
||||
countrx = 31 + rxsz / 32;
|
||||
}
|
||||
USB_BTABLE->EP[number].USB_ADDR_TX = lastaddr;
|
||||
endpoints[number].tx_buf = (uint16_t *)(USB_BTABLE_BASE + lastaddr*2);
|
||||
lastaddr += txsz;
|
||||
USB_BTABLE->EP[number].USB_COUNT_TX = 0;
|
||||
USB_BTABLE->EP[number].USB_ADDR_RX = lastaddr;
|
||||
endpoints[number].rx_buf = (uint16_t *)(USB_BTABLE_BASE + lastaddr*2);
|
||||
lastaddr += rxsz;
|
||||
USB_BTABLE->EP[number].USB_COUNT_RX = countrx << 10;
|
||||
endpoints[number].func = func;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//extern int8_t dump;
|
||||
// standard IRQ handler
|
||||
void usb_isr(){
|
||||
if (USB->ISTR & USB_ISTR_RESET){
|
||||
// Reinit registers
|
||||
USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM;
|
||||
USB->ISTR = 0;
|
||||
// Endpoint 0 - CONTROL
|
||||
// ON USB LS size of EP0 may be 8 bytes, but on FS it should be 64 bytes!
|
||||
lastaddr = LASTADDR_DEFAULT;
|
||||
if(EP_Init(0, EP_TYPE_CONTROL, USB_EP0_BUFSZ, USB_EP0_BUFSZ, EP0_Handler)){
|
||||
DBG("Err init EP0");
|
||||
}
|
||||
// clear address, leave only enable bit
|
||||
USB->DADDR = USB_DADDR_EF;
|
||||
// state is default - wait for enumeration
|
||||
USB_Dev.USB_Status = USB_DEFAULT_STATE;
|
||||
}
|
||||
if(USB->ISTR & USB_ISTR_CTR){
|
||||
// EP number
|
||||
uint8_t n = USB->ISTR & USB_ISTR_EPID;
|
||||
// copy status register
|
||||
uint16_t epstatus = USB->EPnR[n];
|
||||
// dump = 1;
|
||||
// Calculate flags
|
||||
endpoints[n].rx_flag = (epstatus & USB_EPnR_CTR_RX) ? 1 : 0;
|
||||
endpoints[n].setup_flag = (epstatus & USB_EPnR_SETUP) ? 1 : 0;
|
||||
endpoints[n].tx_flag = (epstatus & USB_EPnR_CTR_TX) ? 1 : 0;
|
||||
// copy received bytes amount
|
||||
endpoints[n].rx_cnt = USB_BTABLE->EP[n].USB_COUNT_RX & 0x3FF; // low 10 bits is counter
|
||||
// check direction
|
||||
if(USB->ISTR & USB_ISTR_DIR){ // OUT interrupt - receive data, CTR_RX==1 (if CTR_TX == 1 - two pending transactions: receive following by transmit)
|
||||
if(n == 0){ // control endpoint
|
||||
if(epstatus & USB_EPnR_SETUP){ // setup packet -> copy data to conf_pack
|
||||
EP_Read(0, (uint16_t*)&setup_packet);
|
||||
ep0dbuflen = 0;
|
||||
// interrupt handler will be called later
|
||||
}else if(epstatus & USB_EPnR_CTR_RX){ // data packet -> push received data to ep0databuf
|
||||
ep0dbuflen = endpoints[0].rx_cnt;
|
||||
EP_Read(0, (uint16_t*)&ep0databuf);
|
||||
}
|
||||
}
|
||||
}else{ // IN interrupt - transmit data, only CTR_TX == 1
|
||||
// enumeration end could be here (if EP0)
|
||||
}
|
||||
// prepare status field for EP handler
|
||||
endpoints[n].status = epstatus;
|
||||
// call EP handler (even if it will change EPnR, it should return new status)
|
||||
epstatus = endpoints[n].func(endpoints[n]);
|
||||
// keep DTOG state
|
||||
epstatus = KEEP_DTOG_TX(epstatus);
|
||||
epstatus = KEEP_DTOG_RX(epstatus);
|
||||
// clear all RX/TX flags
|
||||
epstatus = CLEAR_CTR_RX(epstatus);
|
||||
epstatus = CLEAR_CTR_TX(epstatus);
|
||||
// refresh EPnR
|
||||
USB->EPnR[n] = epstatus;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if (USB->ISTR & USB_ISTR_PMAOVR) {
|
||||
MSG("PMAOVR\n");
|
||||
// Handle PMAOVR status
|
||||
}
|
||||
if (USB->ISTR & USB_ISTR_SUSP) {
|
||||
MSG("SUSP\n");
|
||||
if (USB->DADDR & 0x7f) {
|
||||
USB->DADDR = 0;
|
||||
USB->CNTR &= ~ 0x800;
|
||||
}
|
||||
}
|
||||
if (USB->ISTR & USB_ISTR_ERR) {
|
||||
MSG("ERR\n");
|
||||
// Handle Error
|
||||
}
|
||||
if (USB->ISTR & USB_ISTR_WKUP) {
|
||||
MSG("WKUP\n");
|
||||
// Handle Wakeup
|
||||
}
|
||||
if (USB->ISTR & USB_ISTR_SOF) {
|
||||
MSG("SOF\n");
|
||||
// Handle SOF
|
||||
}
|
||||
if (USB->ISTR & USB_ISTR_ESOF) {
|
||||
MSG("ESOF\n");
|
||||
// Handle ESOF
|
||||
}
|
||||
USB->ISTR = 0;
|
||||
*/
|
||||
|
||||
void usb_lp_can_rx0_isr(){
|
||||
usb_isr();
|
||||
}
|
||||
|
||||
void usb_hp_can_tx_isr(){
|
||||
usb_isr();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write data to EP buffer (called from IRQ handler)
|
||||
* @param number - EP number
|
||||
* @param *buf - array with data
|
||||
* @param size - its size
|
||||
*/
|
||||
void EP_WriteIRQ(uint8_t number, const uint8_t *buf, uint16_t size){
|
||||
uint8_t i;
|
||||
if(size > USB_TXBUFSZ) size = USB_TXBUFSZ;
|
||||
uint16_t N2 = (size + 1) >> 1;
|
||||
// the buffer is 16-bit, so we should copy data as it would be uint16_t
|
||||
uint16_t *buf16 = (uint16_t *)buf;
|
||||
uint32_t *out = (uint32_t *)endpoints[number].tx_buf;
|
||||
for(i = 0; i < N2; ++i, ++out){
|
||||
*out = buf16[i];
|
||||
}
|
||||
USB_BTABLE->EP[number].USB_COUNT_TX = size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write data to EP buffer (called outside IRQ handler)
|
||||
* @param number - EP number
|
||||
* @param *buf - array with data
|
||||
* @param size - its size
|
||||
*/
|
||||
void EP_Write(uint8_t number, const uint8_t *buf, uint16_t size){
|
||||
uint16_t status = USB->EPnR[number];
|
||||
EP_WriteIRQ(number, buf, size);
|
||||
status = SET_NAK_RX(status);
|
||||
status = SET_VALID_TX(status);
|
||||
status = KEEP_DTOG_TX(status);
|
||||
status = KEEP_DTOG_RX(status);
|
||||
USB->EPnR[number] = status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy data from EP buffer into user buffer area
|
||||
* @param *buf - user array for data
|
||||
* @return amount of data read
|
||||
*/
|
||||
int EP_Read(uint8_t number, uint16_t *buf){
|
||||
int n = (endpoints[number].rx_cnt + 1) >> 1;
|
||||
uint32_t *in = (uint32_t *)endpoints[number].rx_buf;
|
||||
if(n){
|
||||
for(int i = 0; i < n; ++i, ++in)
|
||||
buf[i] = *(uint16_t*)in;
|
||||
}
|
||||
return endpoints[number].rx_cnt;
|
||||
}
|
||||
|
||||
// USB status
|
||||
uint8_t USB_GetState(){
|
||||
return USB_Dev.USB_Status;
|
||||
}
|
||||
202
F1-nolib/chronometer_v3/usb_lib.h
Normal file
202
F1-nolib/chronometer_v3/usb_lib.h
Normal file
@ -0,0 +1,202 @@
|
||||
/*
|
||||
* geany_encoding=koi8-r
|
||||
* usb_lib.h
|
||||
*
|
||||
* Copyright 2018 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 __USB_LIB_H__
|
||||
#define __USB_LIB_H__
|
||||
|
||||
#include <wchar.h>
|
||||
#include "usb_defs.h"
|
||||
|
||||
#define EP0DATABUF_SIZE (64)
|
||||
#define LASTADDR_DEFAULT (STM32ENDPOINTS * 8)
|
||||
|
||||
// Max EP amount (EP0 + other used)
|
||||
//#define ENDPOINTS_NUM 4
|
||||
// bmRequestType & 0x7f
|
||||
#define STANDARD_DEVICE_REQUEST_TYPE 0
|
||||
#define STANDARD_ENDPOINT_REQUEST_TYPE 2
|
||||
#define VENDOR_REQUEST_TYPE 0x40
|
||||
#define CONTROL_REQUEST_TYPE 0x21
|
||||
// bRequest, standard; for bmRequestType == 0x80
|
||||
#define GET_STATUS 0x00
|
||||
#define GET_DESCRIPTOR 0x06
|
||||
#define GET_CONFIGURATION 0x08
|
||||
// for bmRequestType == 0
|
||||
#define CLEAR_FEATURE 0x01
|
||||
#define SET_FEATURE 0x03 // unused
|
||||
#define SET_ADDRESS 0x05
|
||||
#define SET_DESCRIPTOR 0x07 // unused
|
||||
#define SET_CONFIGURATION 0x09
|
||||
// for bmRequestType == 0x81, 1 or 0xB2
|
||||
#define GET_INTERFACE 0x0A // unused
|
||||
#define SET_INTERFACE 0x0B // unused
|
||||
#define SYNC_FRAME 0x0C // unused
|
||||
#define VENDOR_REQUEST 0x01 // unused
|
||||
|
||||
// Class-Specific Control Requests
|
||||
#define SEND_ENCAPSULATED_COMMAND 0x00 // unused
|
||||
#define GET_ENCAPSULATED_RESPONSE 0x01 // unused
|
||||
#define SET_COMM_FEATURE 0x02 // unused
|
||||
#define GET_COMM_FEATURE 0x03 // unused
|
||||
#define CLEAR_COMM_FEATURE 0x04 // unused
|
||||
#define SET_LINE_CODING 0x20
|
||||
#define GET_LINE_CODING 0x21
|
||||
#define SET_CONTROL_LINE_STATE 0x22
|
||||
#define SEND_BREAK 0x23
|
||||
|
||||
// control line states
|
||||
#define CONTROL_DTR 0x01
|
||||
#define CONTROL_RTS 0x02
|
||||
|
||||
// wValue
|
||||
#define DEVICE_DESCRIPTOR 0x100
|
||||
#define CONFIGURATION_DESCRIPTOR 0x200
|
||||
#define STRING_LANG_DESCRIPTOR 0x300
|
||||
#define STRING_MAN_DESCRIPTOR 0x301
|
||||
#define STRING_PROD_DESCRIPTOR 0x302
|
||||
#define STRING_SN_DESCRIPTOR 0x303
|
||||
#define DEVICE_QUALIFIER_DESCRIPTOR 0x600
|
||||
|
||||
// EPnR bits manipulation
|
||||
#define CLEAR_DTOG_RX(R) (R & USB_EPnR_DTOG_RX) ? R : (R & (~USB_EPnR_DTOG_RX))
|
||||
#define SET_DTOG_RX(R) (R & USB_EPnR_DTOG_RX) ? (R & (~USB_EPnR_DTOG_RX)) : R
|
||||
#define TOGGLE_DTOG_RX(R) (R | USB_EPnR_DTOG_RX)
|
||||
#define KEEP_DTOG_RX(R) (R & (~USB_EPnR_DTOG_RX))
|
||||
#define CLEAR_DTOG_TX(R) (R & USB_EPnR_DTOG_TX) ? R : (R & (~USB_EPnR_DTOG_TX))
|
||||
#define SET_DTOG_TX(R) (R & USB_EPnR_DTOG_TX) ? (R & (~USB_EPnR_DTOG_TX)) : R
|
||||
#define TOGGLE_DTOG_TX(R) (R | USB_EPnR_DTOG_TX)
|
||||
#define KEEP_DTOG_TX(R) (R & (~USB_EPnR_DTOG_TX))
|
||||
#define SET_VALID_RX(R) ((R & USB_EPnR_STAT_RX) ^ USB_EPnR_STAT_RX) | (R & (~USB_EPnR_STAT_RX))
|
||||
#define SET_NAK_RX(R) ((R & USB_EPnR_STAT_RX) ^ USB_EPnR_STAT_RX_1) | (R & (~USB_EPnR_STAT_RX))
|
||||
#define SET_STALL_RX(R) ((R & USB_EPnR_STAT_RX) ^ USB_EPnR_STAT_RX_0) | (R & (~USB_EPnR_STAT_RX))
|
||||
#define KEEP_STAT_RX(R) (R & (~USB_EPnR_STAT_RX))
|
||||
#define SET_VALID_TX(R) ((R & USB_EPnR_STAT_TX) ^ USB_EPnR_STAT_TX) | (R & (~USB_EPnR_STAT_TX))
|
||||
#define SET_NAK_TX(R) ((R & USB_EPnR_STAT_TX) ^ USB_EPnR_STAT_TX_1) | (R & (~USB_EPnR_STAT_TX))
|
||||
#define SET_STALL_TX(R) ((R & USB_EPnR_STAT_TX) ^ USB_EPnR_STAT_TX_0) | (R & (~USB_EPnR_STAT_TX))
|
||||
#define KEEP_STAT_TX(R) (R & (~USB_EPnR_STAT_TX))
|
||||
#define CLEAR_CTR_RX(R) (R & (~USB_EPnR_CTR_RX))
|
||||
#define CLEAR_CTR_TX(R) (R & (~USB_EPnR_CTR_TX))
|
||||
#define CLEAR_CTR_RX_TX(R) (R & (~(USB_EPnR_CTR_TX | USB_EPnR_CTR_RX)))
|
||||
|
||||
// USB state: uninitialized, addressed, ready for use
|
||||
#define USB_DEFAULT_STATE 0
|
||||
#define USB_ADRESSED_STATE 1
|
||||
#define USB_CONFIGURE_STATE 2
|
||||
|
||||
// EP types
|
||||
#define EP_TYPE_BULK 0x00
|
||||
#define EP_TYPE_CONTROL 0x01
|
||||
#define EP_TYPE_ISO 0x02
|
||||
#define EP_TYPE_INTERRUPT 0x03
|
||||
|
||||
#define LANG_US (uint16_t)0x0409
|
||||
|
||||
#define _USB_STRING_(name, str) \
|
||||
static const struct name \
|
||||
{ \
|
||||
uint8_t bLength; \
|
||||
uint8_t bDescriptorType; \
|
||||
uint16_t bString[(sizeof(str) - 2) / 2]; \
|
||||
\
|
||||
} \
|
||||
name = {sizeof(name), 0x03, str}
|
||||
|
||||
#define _USB_LANG_ID_(name, lng_id) \
|
||||
\
|
||||
static const struct name \
|
||||
{ \
|
||||
uint8_t bLength; \
|
||||
uint8_t bDescriptorType; \
|
||||
uint16_t bString; \
|
||||
\
|
||||
} \
|
||||
name = {0x04, 0x03, lng_id}
|
||||
#define STRING_LANG_DESCRIPTOR_SIZE_BYTE (4)
|
||||
|
||||
// EP0 configuration packet
|
||||
typedef struct {
|
||||
uint8_t bmRequestType;
|
||||
uint8_t bRequest;
|
||||
uint16_t wValue;
|
||||
uint16_t wIndex;
|
||||
uint16_t wLength;
|
||||
} config_pack_t;
|
||||
|
||||
// endpoints state
|
||||
typedef struct __ep_t{
|
||||
uint16_t *tx_buf; // transmission buffer address
|
||||
uint16_t *rx_buf; // reception buffer address
|
||||
uint16_t (*func)(); // endpoint action function
|
||||
uint16_t status; // status flags
|
||||
unsigned rx_cnt : 10; // received data counter
|
||||
unsigned tx_flag : 1; // transmission flag
|
||||
unsigned rx_flag : 1; // reception flag
|
||||
unsigned setup_flag : 1; // this is setup packet (only for EP0)
|
||||
} ep_t;
|
||||
|
||||
// USB status & its address
|
||||
typedef struct {
|
||||
uint8_t USB_Status;
|
||||
uint16_t USB_Addr;
|
||||
}usb_dev_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t dwDTERate;
|
||||
uint8_t bCharFormat;
|
||||
#define USB_CDC_1_STOP_BITS 0
|
||||
#define USB_CDC_1_5_STOP_BITS 1
|
||||
#define USB_CDC_2_STOP_BITS 2
|
||||
uint8_t bParityType;
|
||||
#define USB_CDC_NO_PARITY 0
|
||||
#define USB_CDC_ODD_PARITY 1
|
||||
#define USB_CDC_EVEN_PARITY 2
|
||||
#define USB_CDC_MARK_PARITY 3
|
||||
#define USB_CDC_SPACE_PARITY 4
|
||||
uint8_t bDataBits;
|
||||
} __attribute__ ((packed)) usb_LineCoding;
|
||||
|
||||
typedef struct {
|
||||
uint8_t bmRequestType;
|
||||
uint8_t bNotificationType;
|
||||
uint16_t wValue;
|
||||
uint16_t wIndex;
|
||||
uint16_t wLength;
|
||||
} __attribute__ ((packed)) usb_cdc_notification;
|
||||
|
||||
extern ep_t endpoints[];
|
||||
|
||||
void USB_Init();
|
||||
uint8_t USB_GetState();
|
||||
int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, uint16_t (*func)(ep_t ep));
|
||||
void EP_WriteIRQ(uint8_t number, const uint8_t *buf, uint16_t size);
|
||||
void EP_Write(uint8_t number, const uint8_t *buf, uint16_t size);
|
||||
int EP_Read(uint8_t number, uint16_t *buf);
|
||||
usb_LineCoding getLineCoding();
|
||||
|
||||
void WEAK linecoding_handler(usb_LineCoding *lc);
|
||||
void WEAK clstate_handler(uint16_t val);
|
||||
void WEAK break_handler();
|
||||
void WEAK vendor_handler(config_pack_t *packet);
|
||||
|
||||
#endif // __USB_LIB_H__
|
||||
Loading…
x
Reference in New Issue
Block a user