mirror of
https://github.com/eddyem/mmpp.git
synced 2025-12-06 18:45:17 +03:00
modify firmware (fix some bugs)
This commit is contained in:
parent
3963252d68
commit
a4144090c2
Binary file not shown.
@ -12,7 +12,7 @@
|
|||||||
\nocolon
|
\nocolon
|
||||||
\def\Z{Цейсс--1000\xspace}
|
\def\Z{Цейсс--1000\xspace}
|
||||||
\title{Многорежимный фотометр--поляриметр (MMPP) телескопа \Z. Техническая документация.}
|
\title{Многорежимный фотометр--поляриметр (MMPP) телескопа \Z. Техническая документация.}
|
||||||
\author{Емельянов~Э.В. \and Фатхуллин~Т.А.}
|
\author{Емельянов~Э.В. \and Москвитин~А.С.\and Фатхуллин~Т.А.}
|
||||||
\graphicspath{{./imgs/}}
|
\graphicspath{{./imgs/}}
|
||||||
\begin{document}
|
\begin{document}
|
||||||
\maketitle
|
\maketitle
|
||||||
@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
|
|
||||||
\section{Описание прибора}
|
\section{Описание прибора}
|
||||||
|
|
||||||
MMPP (Multi-Mode Photometer-Polarimeter) "--- многорежимный фотометр-поляриметр телескопа \Z
|
MMPP (Multi-Mode Photometer-Polarimeter) "--- многорежимный фотометр-поляриметр телескопа \Z
|
||||||
предназначен для проведения фотометрических и поляриметрических исследований. Прибор оснащен двумя турелями
|
предназначен для проведения фотометрических и поляриметрических исследований. Прибор оснащен двумя турелями
|
||||||
USB-HSFW (Edmund Optics) с пятью позициями для 50-мм фильтров, анализатором линейной поляризации и
|
USB-HSFW (Edmund Optics) с пятью позициями для 50-мм фильтров, анализатором линейной поляризации и
|
||||||
@ -673,11 +672,11 @@ PF1 & PUPD &
|
|||||||
посылок экстренного останова, сброса и т.п.).
|
посылок экстренного останова, сброса и т.п.).
|
||||||
|
|
||||||
После идентификатора контроллера следует текст команды и (опционально) ее аргументы. В случае, если команда
|
После идентификатора контроллера следует текст команды и (опционально) ее аргументы. В случае, если команда
|
||||||
валидна, контроллер возвращает строку <<ALL OK>>. Если команда не распознана, возвращается маркер ошибки
|
валидна, контроллер возвращает строку <<ALLOK>>. Если команда не распознана, возвращается маркер ошибки
|
||||||
<<BADCMD>>. В случае же ошибок в аргументах команды возвращается маркер ошибки <<ERR>>. Если команда
|
<<BADCMD>>. В случае же ошибок в аргументах команды возвращается маркер ошибки <<ERR>>. Если команда
|
||||||
возвращает какую-либо информацию, она следует сразу за маркером <<ALL OK>>. Данные, занимающие более одной
|
возвращает какую-либо информацию, она следует сразу за маркером <<ALLOK>>. Данные, занимающие более одной
|
||||||
строки текста, завершаются маркером <<DATAEND>>. Если команда лишь требует выполнения определенного действия,
|
строки текста, завершаются маркером <<DATAEND>>. Если команда лишь требует выполнения определенного действия,
|
||||||
маркер <<ALL OK>> возвращается после установления возможности выполнения данного действия. В силу синхронного
|
маркер <<ALLOK>> возвращается после установления возможности выполнения данного действия. В силу синхронного
|
||||||
характера интерфейса связи, команды, требующие длительного времени на исполнение (например, перемещение
|
характера интерфейса связи, команды, требующие длительного времени на исполнение (например, перемещение
|
||||||
объекта) не выводят в случае ошибки или достижения заданного положения никаких данных, процесс их исполнения
|
объекта) не выводят в случае ошибки или достижения заданного положения никаких данных, процесс их исполнения
|
||||||
необходимо контролировать периодическим запросом состояния модуля.
|
необходимо контролировать периодическим запросом состояния модуля.
|
||||||
@ -716,21 +715,24 @@ PF1 & PUPD &
|
|||||||
\item[\itm{C}] получение текущих значений параметров конфигурации, например,
|
\item[\itm{C}] получение текущих значений параметров конфигурации, например,
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
CONFSZ=36
|
CONFSZ=36
|
||||||
DEVID=0
|
DEVID=2
|
||||||
V12NUM=1
|
V12NUM=605
|
||||||
V12DEN=10
|
V12DEN=94
|
||||||
I12NUM=1
|
I12NUM=3
|
||||||
I12DEN=1
|
I12DEN=4
|
||||||
V33NUM=1
|
V33NUM=1
|
||||||
V33DEN=1
|
V33DEN=1
|
||||||
ESWTHR=150
|
ESWTHR=500
|
||||||
MOT0SPD=60
|
MOT0SPD=3
|
||||||
MOT1SPD=60
|
MOT1SPD=2
|
||||||
USARTSPD=115200
|
MAXSTEPS0=50000
|
||||||
|
MAXSTEPS1=50000
|
||||||
|
USARTSPD=9600
|
||||||
|
INTPULLUP=1
|
||||||
REVERSE0=0
|
REVERSE0=0
|
||||||
REVERSE1=0
|
REVERSE1=1
|
||||||
MAXSTEPS0=0
|
USTEPS=16
|
||||||
MAXSTEPS1=0
|
ACCDECSTEPS=50
|
||||||
DATAEND
|
DATAEND
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
|
|
||||||
@ -745,12 +747,12 @@ DATAEND
|
|||||||
\end{description}
|
\end{description}
|
||||||
например,
|
например,
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
ADC[0]=4095
|
ADC[0]=189
|
||||||
ADC[1]=2340
|
ADC[1]=2317
|
||||||
ADC[2]=4095
|
ADC[2]=4088
|
||||||
ADC[3]=4087
|
ADC[3]=4090
|
||||||
ADC[4]=1665
|
ADC[4]=1703
|
||||||
ADC[5]=1532
|
ADC[5]=1525
|
||||||
DATAEND
|
DATAEND
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
|
|
||||||
@ -837,25 +839,32 @@ ESW11=HALL
|
|||||||
проведенных изменений и их проверки.
|
проведенных изменений и их проверки.
|
||||||
|
|
||||||
\begin{description}\def\itm#1{\rlap{#1}\phantom{M\#num}}
|
\begin{description}\def\itm#1{\rlap{#1}\phantom{M\#num}}
|
||||||
|
\item[\itm{A num}] установка количества шагов (\verb'ACCDECSTEPS'), в течение которого движение будет
|
||||||
|
производиться с ускорением (на старте) или замедлением (на финише); в случае, если требуется
|
||||||
|
переместить двигатель на меньшее количество шагов, движение будет производиться с минимальной
|
||||||
|
скоростью (равной произведению \verb'MOTxSPD' на значение макроса \verb'LOWEST_SPEED_DIV');
|
||||||
\item[\itm{C\#num}] изменение значения текущей скорости двигателя с номером \textbf{\#} на \textbf{num}
|
\item[\itm{C\#num}] изменение значения текущей скорости двигателя с номером \textbf{\#} на \textbf{num}
|
||||||
(данное изменение действует лишь до окончания движения двигателя);
|
(данное изменение действует лишь до окончания движения двигателя);
|
||||||
\item[\itm{Dxnum}] установка знаменателя (\textbf{d}enominator) величины \textbf{x} (D, I или M~-- в
|
\item[\itm{Dvnum}] установка знаменателя (\textbf{d}enominator, \verb'xxxDEN') величины \textbf{v} (D, I или
|
||||||
соответствии с геттером значения измерений АЦП) в \textbf{num};
|
M~-- в соответствии с геттером значения измерений АЦП) в \textbf{num};
|
||||||
\item[\itm{Exnum}] установка числителя (num\textbf{e}rator) (аналогично \textbf{Dxnum});
|
\item[\itm{Evnum}] установка числителя (num\textbf{e}rator, \verb'xxxNUM') (аналогично \textbf{Dvnum});
|
||||||
\item[\itm{I num}] изменение значения идентификатора (целое число) контроллера;
|
\item[\itm{I num}] изменение значения идентификатора (\verb'DEVID', целое число) контроллера;
|
||||||
\item[\itm{M\#num}] установка максимального диапазона (\textbf{num} от~1 до~65535) шагового двигателя
|
\item[\itm{M\#num}] установка максимального диапазона (\verb'MAXSTEPS#', \textbf{num} от~1 до~65535) шагового
|
||||||
\textbf{\#};
|
двигателя \textbf{\#};
|
||||||
\item[\itm{P num}] включение (\textbf{num} равно нулю) или отключение (\textbf{num} отсутствует или любое,
|
\item[\itm{P num}] (\verb'INTPULLUP') включение (\textbf{num} равно нулю) или отключение (\textbf{num}
|
||||||
кроме нуля) внутренней подтяжки на UART Tx;
|
отсутствует или любое, кроме нуля) внутренней подтяжки на UART Tx;
|
||||||
\item[\itm{R\#num}] реверсивное движение двигателя \textbf{\#} (\textbf{num} равное нулю отключает реверс),
|
\item[\itm{R\#num}] (\verb'REVERSE#') реверсивное движение двигателя \textbf{\#} (\textbf{num} равное нулю
|
||||||
в режиме реверса меняется только направление вращения двигателя, но не обрабатываемые концевики;
|
отключает реверс), в режиме реверса меняется только направление вращения двигателя, но не
|
||||||
\item[\itm{S\#num}] изменение значения максимальной скорости двигателя с номером \textbf{\#} на \textbf{num}
|
обрабатываемые концевики;
|
||||||
(максимальная скорость устанавливается после окончания движения с ускорением и не зависит от
|
\item[\itm{S\#num}] изменение значения максимальной скорости (\verb'MOT#SPD') двигателя с номером
|
||||||
текущей скорости, \textbf{C\#num});
|
\textbf{\#} на \textbf{num} (максимальная скорость устанавливается после окончания движения с
|
||||||
\item[\itm{T num}] изменение пороговых величин (\textbf{num} в ADU) для градации состояний концевика
|
ускорением и не зависит от текущей скорости, \textbf{C\#num});
|
||||||
двигателя~0 (0..num~-- датчик Холла, 2048-num..2048+num~-- пользовательская кнопка,
|
\item[\itm{T num}] изменение пороговых величин (\verb'ESWTHR', \textbf{num} в ADU) для градации состояний
|
||||||
|
концевика двигателя~0 (0..num~-- датчик Холла, 2048-num..2048+num~-- пользовательская кнопка,
|
||||||
4096-num..4095~-- свободное состояние);
|
4096-num..4095~-- свободное состояние);
|
||||||
\item[\itm{U num}] изменение скорости UART.
|
\item[\itm{U num}] изменение скорости UART (\verb'USARTSPD');
|
||||||
|
\item[\itm{u num}] установка количества микрошагов (\verb'USTEPS') в одном шаге; это число должно быть
|
||||||
|
степенью двойки (до~32 включительно).
|
||||||
\end{description}
|
\end{description}
|
||||||
|
|
||||||
\paragraph{Сеттеры скорости двигателей.}
|
\paragraph{Сеттеры скорости двигателей.}
|
||||||
@ -925,10 +934,12 @@ MOT0SPD=3
|
|||||||
MOT1SPD=5
|
MOT1SPD=5
|
||||||
MAXSTEPS0=50000
|
MAXSTEPS0=50000
|
||||||
MAXSTEPS1=50000
|
MAXSTEPS1=50000
|
||||||
|
USARTSPD=9600
|
||||||
INTPULLUP=1
|
INTPULLUP=1
|
||||||
USARTSPD=115200
|
|
||||||
REVERSE0=1
|
REVERSE0=1
|
||||||
REVERSE1=0
|
REVERSE1=0
|
||||||
|
USTEPS=16
|
||||||
|
ACCDECSTEPS=50
|
||||||
DATAEND
|
DATAEND
|
||||||
|
|
||||||
MMPP_control -a 2GC
|
MMPP_control -a 2GC
|
||||||
@ -947,10 +958,12 @@ MOT0SPD=3
|
|||||||
MOT1SPD=2
|
MOT1SPD=2
|
||||||
MAXSTEPS0=50000
|
MAXSTEPS0=50000
|
||||||
MAXSTEPS1=50000
|
MAXSTEPS1=50000
|
||||||
|
USARTSPD=9600
|
||||||
INTPULLUP=1
|
INTPULLUP=1
|
||||||
USARTSPD=115200
|
|
||||||
REVERSE0=0
|
REVERSE0=0
|
||||||
REVERSE1=1
|
REVERSE1=1
|
||||||
|
USTEPS=16
|
||||||
|
ACCDECSTEPS=50
|
||||||
DATAEND
|
DATAEND
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
|
|
||||||
@ -959,11 +972,13 @@ DATAEND
|
|||||||
изменение уровня на концевиках двигателя~0, \verb'MOTxSPD' (предельные скорости соответствующих двигателей),
|
изменение уровня на концевиках двигателя~0, \verb'MOTxSPD' (предельные скорости соответствующих двигателей),
|
||||||
\verb'MAXSTEPSx' (максимальное количество шагов данного двигателя), \verb'INTPULLUP' (при отсутствии внешней
|
\verb'MAXSTEPSx' (максимальное количество шагов данного двигателя), \verb'INTPULLUP' (при отсутствии внешней
|
||||||
подтяжки шины~Tx контроллеров отключенная подтяжка приведет к неработоспособности), \verb'USARTSPD' (скорость
|
подтяжки шины~Tx контроллеров отключенная подтяжка приведет к неработоспособности), \verb'USARTSPD' (скорость
|
||||||
шины UART) и \verb'REVERSEx' (направление вращения двигателя).
|
шины UART), \verb'REVERSEx' (направление вращения двигателя) и \verb'ACCDECSTEPS' (количество шагов для
|
||||||
|
ускорения\slash замедления движения).
|
||||||
|
|
||||||
\paragraph{Значения предельных токов DRV8825.} \label{MotCurrents}
|
\paragraph{Значения предельных токов DRV8825.} \label{MotCurrents}
|
||||||
Предельные токи определяются по уровню напряжения на подстроечных резисторах DRV8825.
|
Предельные токи определяются по уровню напряжения на подстроечных резисторах DRV8825.
|
||||||
\TODO[ТОКИ!]
|
Анализатор поляризации: M0 (подвижка) 0.5\,В, M1 (ротатор) 3.1\,В.
|
||||||
|
Фазовая пластина: M0 (подвижка) 0.9\,В, M1 (ротатор) 0.25\,В.
|
||||||
|
|
||||||
\comment[ФОТО!]{добавить табличку со значениями напряжений + фотографию, как настраивать}
|
\comment[ФОТО!]{добавить табличку со значениями напряжений + фотографию, как настраивать}
|
||||||
\end{document}
|
\end{document}
|
||||||
|
|||||||
@ -52,7 +52,7 @@ LIB_DIR := $(INC_DIR)/ld
|
|||||||
CFLAGS += -O2 -g -MD -D__thumb2__=1
|
CFLAGS += -O2 -g -MD -D__thumb2__=1
|
||||||
CFLAGS += -Wall -Werror -Wextra -Wshadow -Wimplicit-function-declaration
|
CFLAGS += -Wall -Werror -Wextra -Wshadow -Wimplicit-function-declaration
|
||||||
CFLAGS += -Wredundant-decls $(INCLUDE)
|
CFLAGS += -Wredundant-decls $(INCLUDE)
|
||||||
# -Wmissing-prototypes -Wstrict-prototypes
|
#-Wmissing-prototypes -Wstrict-prototypes
|
||||||
CFLAGS += -fno-common -ffunction-sections -fdata-sections
|
CFLAGS += -fno-common -ffunction-sections -fdata-sections
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@ -71,10 +71,6 @@ LDLIBS += $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
|
|||||||
|
|
||||||
DEFS += -DSTM32$(FAMILY) -DSTM32$(MCU)
|
DEFS += -DSTM32$(FAMILY) -DSTM32$(MCU)
|
||||||
|
|
||||||
#.SUFFIXES: .elf .bin .hex .srec .list .map .images
|
|
||||||
#.SECONDEXPANSION:
|
|
||||||
#.SECONDARY:
|
|
||||||
|
|
||||||
ELF := $(OBJDIR)/$(BINARY).elf
|
ELF := $(OBJDIR)/$(BINARY).elf
|
||||||
LIST := $(OBJDIR)/$(BINARY).list
|
LIST := $(OBJDIR)/$(BINARY).list
|
||||||
BIN := $(BINARY).bin
|
BIN := $(BINARY).bin
|
||||||
@ -101,9 +97,6 @@ $(OBJDIR)/%.o: %.c
|
|||||||
@echo " CC $<"
|
@echo " CC $<"
|
||||||
$(CC) $(CFLAGS) $(DEFS) $(INCLUDE) $(ARCH_FLAGS) -o $@ -c $<
|
$(CC) $(CFLAGS) $(DEFS) $(INCLUDE) $(ARCH_FLAGS) -o $@ -c $<
|
||||||
|
|
||||||
#$(OBJDIR)/%.d: %.c $(OBJDIR)
|
|
||||||
# $(CC) -MM -MG $< | sed -e 's,^\([^:]*\)\.o[ ]*:,$(@D)/\1.o $(@D)/\1.d:,' >$@
|
|
||||||
|
|
||||||
$(BIN): $(ELF)
|
$(BIN): $(ELF)
|
||||||
@echo " OBJCOPY $(BIN)"
|
@echo " OBJCOPY $(BIN)"
|
||||||
$(OBJCOPY) -Obinary $(ELF) $(BIN)
|
$(OBJCOPY) -Obinary $(ELF) $(BIN)
|
||||||
|
|||||||
@ -148,7 +148,7 @@ Getters returning more than one field ends with `DATAEND` meaning that's all dat
|
|||||||
|
|
||||||
|
|
||||||
### Motors' manipulation
|
### Motors' manipulation
|
||||||
Next char should be '0' or '1' --- motor's number. If wrong, `Num>1` answer would be returned.
|
Next char should be '0' or '1' --- motor's number. If wrong, `BADCMD` answer would be returned.
|
||||||
There's only two commands in this section:
|
There's only two commands in this section:
|
||||||
|
|
||||||
* **Mnum** - move motor to *num* steps. Errors:
|
* **Mnum** - move motor to *num* steps. Errors:
|
||||||
@ -164,9 +164,10 @@ There's only two commands in this section:
|
|||||||
Change of any setter takes place in MCU RAM immediately. To store them permanently run
|
Change of any setter takes place in MCU RAM immediately. To store them permanently run
|
||||||
*write flash* command.
|
*write flash* command.
|
||||||
|
|
||||||
|
* **A num** - set value of ACCDECSTEPS (approximate amount of steps to do acceleration/deceleration) to *num*
|
||||||
* **C#num** - set current *speed* to *num* for motor #
|
* **C#num** - set current *speed* to *num* for motor #
|
||||||
* **D num** - set *denominator* to number *num*
|
* **D$num** - set *denominator $* (*D* - Vdd, *I* - current, *M* - 12V) to number *num*
|
||||||
* **E num** - set *numerator*
|
* **E$num** - set *numerator $*
|
||||||
* **I num** - set *device ID*
|
* **I num** - set *device ID*
|
||||||
* **M#num** - set maxsteps (*num* is 1..65535) for motor `#`
|
* **M#num** - set maxsteps (*num* is 1..65535) for motor `#`
|
||||||
* **P num** - properties of internal pullup (0 - disabled, other or without `num` - enabled)
|
* **P num** - properties of internal pullup (0 - disabled, other or without `num` - enabled)
|
||||||
@ -175,10 +176,11 @@ Change of any setter takes place in MCU RAM immediately. To store them permanent
|
|||||||
* **T num** - set *end-switches threshold* (in ADU, near 0 for Hall switch, 2048 for user button
|
* **T num** - set *end-switches threshold* (in ADU, near 0 for Hall switch, 2048 for user button
|
||||||
and 4096 for released state)
|
and 4096 for released state)
|
||||||
* **U num** - set *USART speed* to *num* bits per second
|
* **U num** - set *USART speed* to *num* bits per second
|
||||||
|
* **u num** - set value of USTEPS (amount of microsteps per one step)
|
||||||
|
|
||||||
### Motor speed setters
|
### Motor speed setters
|
||||||
To set motor speed to **N** steps per second, give command `C` or `S` with argument equal to
|
To set motor speed to **N** steps per second, give command `C` or `S` with argument equal to
|
||||||
3000/N. E.g. to set current speed for DevID=0, motor0 to 50 steps per second give command `0SC050`.
|
3000/N. E.g. to set current speed for DevID=0, motor0 to 50 steps per second give command `0SC060`.
|
||||||
|
|
||||||
### Denominator and numerator setters
|
### Denominator and numerator setters
|
||||||
Have naxt letter similar to ADC getter (**D** - Vdd, **I** - motors' I, or **M** - motors' U).
|
Have naxt letter similar to ADC getter (**D** - Vdd, **I** - motors' I, or **M** - motors' U).
|
||||||
|
|||||||
@ -20,18 +20,18 @@
|
|||||||
* MA 02110-1301, USA.
|
* MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#include "stm32f0.h"
|
|
||||||
#include "flash.h"
|
|
||||||
#include "adc.h"
|
#include "adc.h"
|
||||||
|
#include "flash.h"
|
||||||
|
#include "stm32f0.h"
|
||||||
#include "usart.h"
|
#include "usart.h"
|
||||||
|
|
||||||
extern volatile uint32_t Tms; // time counter for 1-second Vdd measurement
|
|
||||||
static uint32_t lastVddtime = 0; // Tms value of last Vdd measurement
|
static uint32_t lastVddtime = 0; // Tms value of last Vdd measurement
|
||||||
static uint32_t VddValue = 0; // value of Vdd * 100 (for more precision measurements)
|
static uint32_t VddValue = 0; // value of Vdd * 100 (for more precision measurements)
|
||||||
// check time of last Vdd measurement & refresh it value
|
// check time of last Vdd measurement & refresh it value
|
||||||
#define CHKVDDTIME() do{if(!VddValue || Tms < lastVddtime || Tms - lastVddtime > 999) getVdd();}while(0)
|
#define CHKVDDTIME() do{if(!VddValue || Tms - lastVddtime > 999) getVdd();}while(0)
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
* Array for ADC raw values (before median filter by 9 elements):
|
||||||
* 0 - Steppers current
|
* 0 - Steppers current
|
||||||
* 1 - Input voltage 12V
|
* 1 - Input voltage 12V
|
||||||
* 2 - EndSwitch2 of motor1
|
* 2 - EndSwitch2 of motor1
|
||||||
@ -39,7 +39,32 @@ static uint32_t VddValue = 0; // value of Vdd * 100 (for more precision measurem
|
|||||||
* 4 - inner temperature
|
* 4 - inner temperature
|
||||||
* 5 - vref
|
* 5 - vref
|
||||||
*/
|
*/
|
||||||
uint16_t ADC_array[NUMBER_OF_ADC_CHANNELS];
|
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) { if ((a)>(b)) PIX_SWAP((a),(b)); }
|
||||||
|
#define PIX_SWAP(a,b) { temp=(a);(a)=(b);(b)=temp; }
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
void adc_setup(){
|
void adc_setup(){
|
||||||
// AIN: PA0..3, PA13, PA14. ADC_IN16 - inner temperature. ADC_IN17 - VREFINT
|
// AIN: PA0..3, PA13, PA14. ADC_IN16 - inner temperature. ADC_IN17 - VREFINT
|
||||||
@ -86,7 +111,7 @@ void adc_setup(){
|
|||||||
ADC1->CFGR1 |= ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG; /* (2) */
|
ADC1->CFGR1 |= ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG; /* (2) */
|
||||||
DMA1_Channel1->CPAR = (uint32_t) (&(ADC1->DR)); /* (3) */
|
DMA1_Channel1->CPAR = (uint32_t) (&(ADC1->DR)); /* (3) */
|
||||||
DMA1_Channel1->CMAR = (uint32_t)(ADC_array); /* (4) */
|
DMA1_Channel1->CMAR = (uint32_t)(ADC_array); /* (4) */
|
||||||
DMA1_Channel1->CNDTR = NUMBER_OF_ADC_CHANNELS; /* (5) */
|
DMA1_Channel1->CNDTR = NUMBER_OF_ADC_CHANNELS * 9; /* (5) */
|
||||||
DMA1_Channel1->CCR |= DMA_CCR_MINC | DMA_CCR_MSIZE_0 | DMA_CCR_PSIZE_0 | DMA_CCR_CIRC; /* (6) */
|
DMA1_Channel1->CCR |= DMA_CCR_MINC | DMA_CCR_MSIZE_0 | DMA_CCR_PSIZE_0 | DMA_CCR_CIRC; /* (6) */
|
||||||
DMA1_Channel1->CCR |= DMA_CCR_EN; /* (7) */
|
DMA1_Channel1->CCR |= DMA_CCR_EN; /* (7) */
|
||||||
ADC1->CR |= ADC_CR_ADSTART; /* start the ADC conversions */
|
ADC1->CR |= ADC_CR_ADSTART; /* start the ADC conversions */
|
||||||
@ -96,90 +121,18 @@ void adc_setup(){
|
|||||||
int32_t getTemp(){
|
int32_t getTemp(){
|
||||||
CHKVDDTIME();
|
CHKVDDTIME();
|
||||||
// make correction on Vdd value
|
// make correction on Vdd value
|
||||||
int32_t temperature = (int32_t)ADC_array[4] * VddValue / 330;
|
int32_t temperature = (int32_t)getADCval(4) * (int32_t)VddValue / 330;
|
||||||
/*
|
|
||||||
write2trbuf("getTemp()\ncal30=");
|
|
||||||
put_uint(*TEMP30_CAL_ADDR);
|
|
||||||
write2trbuf(", cal110=");
|
|
||||||
put_uint(*TEMP110_CAL_ADDR);
|
|
||||||
write2trbuf(", t=");
|
|
||||||
put_int(temperature);
|
|
||||||
SENDBUF();
|
|
||||||
*/
|
|
||||||
temperature = (int32_t) *TEMP30_CAL_ADDR - temperature;
|
temperature = (int32_t) *TEMP30_CAL_ADDR - temperature;
|
||||||
/*
|
|
||||||
put_int(temperature);
|
|
||||||
SENDBUF();
|
|
||||||
*/
|
|
||||||
temperature *= (int32_t)(1100 - 300);
|
temperature *= (int32_t)(1100 - 300);
|
||||||
/*
|
|
||||||
put_int(temperature);
|
|
||||||
SENDBUF();
|
|
||||||
*/
|
|
||||||
temperature = temperature / (int32_t)(*TEMP30_CAL_ADDR - *TEMP110_CAL_ADDR);
|
temperature = temperature / (int32_t)(*TEMP30_CAL_ADDR - *TEMP110_CAL_ADDR);
|
||||||
/*
|
|
||||||
put_int(temperature);
|
|
||||||
SENDBUF();
|
|
||||||
*/
|
|
||||||
temperature += 300;
|
temperature += 300;
|
||||||
return(temperature);
|
return(temperature);
|
||||||
}
|
}
|
||||||
|
|
||||||
// return Vdd * 100 (V)
|
// return Vdd * 100 (V)
|
||||||
uint32_t getVdd(){
|
uint32_t getVdd(){
|
||||||
#define ARRSZ (10)
|
|
||||||
static uint16_t arr[ARRSZ] = {0};
|
|
||||||
static int arridx = 0;
|
|
||||||
uint32_t v = ADC_array[5];
|
|
||||||
int i;
|
|
||||||
/*
|
|
||||||
write2trbuf("getVdd(), val=");
|
|
||||||
put_uint(v);
|
|
||||||
write2trbuf(", cal=");
|
|
||||||
put_uint(*VREFINT_CAL_ADDR);
|
|
||||||
SENDBUF();
|
|
||||||
*/
|
|
||||||
if(arr[0] == 0){ // first run - fill all with current data
|
|
||||||
/*
|
|
||||||
write2trbuf("1st run");
|
|
||||||
SENDBUF();
|
|
||||||
*/
|
|
||||||
for(i = 0; i < ARRSZ; ++i) arr[i] = (uint16_t) v;
|
|
||||||
}else{
|
|
||||||
/*
|
|
||||||
write2trbuf("arridx=");
|
|
||||||
put_int(arridx);
|
|
||||||
SENDBUF();
|
|
||||||
*/
|
|
||||||
arr[arridx++] = v;
|
|
||||||
v = 0; // now v is mean
|
|
||||||
if(arridx > ARRSZ-1) arridx = 0;
|
|
||||||
// calculate mean
|
|
||||||
for(i = 0; i < ARRSZ; ++i){
|
|
||||||
/*
|
|
||||||
write2trbuf("arr["); put2trbuf('0'+i); write2trbuf("]=");
|
|
||||||
put_uint(arr[i]);
|
|
||||||
SENDBUF();
|
|
||||||
*/
|
|
||||||
v += arr[i];
|
|
||||||
}
|
|
||||||
v /= ARRSZ;
|
|
||||||
/*
|
|
||||||
write2trbuf("mean value: ");
|
|
||||||
put_uint(v);
|
|
||||||
SENDBUF();
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
uint32_t vdd = ((uint32_t) *VREFINT_CAL_ADDR) * (uint32_t)330 * the_conf.v33numerator; // 3.3V
|
uint32_t vdd = ((uint32_t) *VREFINT_CAL_ADDR) * (uint32_t)330 * the_conf.v33numerator; // 3.3V
|
||||||
/*
|
vdd /= getADCval(5) * the_conf.v33denominator;
|
||||||
put_uint(vdd);
|
|
||||||
SENDBUF();
|
|
||||||
*/
|
|
||||||
vdd /= v * the_conf.v33denominator;
|
|
||||||
/*
|
|
||||||
put_uint(vdd);
|
|
||||||
SENDBUF();
|
|
||||||
*/
|
|
||||||
lastVddtime = Tms;
|
lastVddtime = Tms;
|
||||||
VddValue = vdd;
|
VddValue = vdd;
|
||||||
return vdd;
|
return vdd;
|
||||||
@ -188,7 +141,7 @@ SENDBUF();
|
|||||||
// return value of 12V * 100 (V)
|
// return value of 12V * 100 (V)
|
||||||
uint32_t getVmot(){
|
uint32_t getVmot(){
|
||||||
CHKVDDTIME();
|
CHKVDDTIME();
|
||||||
uint32_t vmot = ADC_array[1] * VddValue * the_conf.v12numerator;
|
uint32_t vmot = getADCval(1) * VddValue * the_conf.v12numerator;
|
||||||
vmot >>= 12;
|
vmot >>= 12;
|
||||||
vmot /= the_conf.v12denominator;
|
vmot /= the_conf.v12denominator;
|
||||||
return vmot;
|
return vmot;
|
||||||
@ -197,7 +150,7 @@ uint32_t getVmot(){
|
|||||||
// return value of motors' current * 100 (A)
|
// return value of motors' current * 100 (A)
|
||||||
uint32_t getImot(){
|
uint32_t getImot(){
|
||||||
CHKVDDTIME();
|
CHKVDDTIME();
|
||||||
uint32_t vmot = ADC_array[0] * VddValue * the_conf.i12numerator;
|
uint32_t vmot = getADCval(0) * VddValue * the_conf.i12numerator;
|
||||||
vmot >>= 12;
|
vmot >>= 12;
|
||||||
vmot /= the_conf.i12denominator;
|
vmot /= the_conf.i12denominator;
|
||||||
return vmot;
|
return vmot;
|
||||||
@ -220,7 +173,7 @@ ESW_status eswStatus(int motnum, int eswnum){
|
|||||||
if(eswnum) idx = 2;
|
if(eswnum) idx = 2;
|
||||||
else idx = 3;
|
else idx = 3;
|
||||||
}
|
}
|
||||||
uint16_t thres = the_conf.ESW_thres, val = ADC_array[idx];
|
uint16_t thres = the_conf.ESW_thres, val = getADCval(idx);
|
||||||
// low sighal: 0..threshold - Hall activated
|
// low sighal: 0..threshold - Hall activated
|
||||||
if(val < thres) return ESW_HALL;
|
if(val < thres) return ESW_HALL;
|
||||||
// high signal: (4096-thres)..4096 - pullup
|
// high signal: (4096-thres)..4096 - pullup
|
||||||
|
|||||||
@ -22,14 +22,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#ifndef __ADC_H__
|
#ifndef ADC_H__
|
||||||
#define __ADC_H__
|
#define ADC_H__
|
||||||
|
|
||||||
// 8 channels (including inttemp & vrefint)
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// 6 channels (including inttemp & vrefint)
|
||||||
#define NUMBER_OF_ADC_CHANNELS (6)
|
#define NUMBER_OF_ADC_CHANNELS (6)
|
||||||
|
|
||||||
extern uint16_t ADC_array[];
|
extern volatile uint32_t Tms; // time counter for 1-second Vdd measurement
|
||||||
void adc_setup();
|
|
||||||
|
|
||||||
typedef enum{
|
typedef enum{
|
||||||
ESW_RELEASED,
|
ESW_RELEASED,
|
||||||
@ -38,10 +39,12 @@ typedef enum{
|
|||||||
ESW_ERROR
|
ESW_ERROR
|
||||||
} ESW_status;
|
} ESW_status;
|
||||||
|
|
||||||
int32_t getTemp();
|
void adc_setup(void);
|
||||||
uint32_t getVdd();
|
uint16_t getADCval(int nch);
|
||||||
uint32_t getVmot();
|
int32_t getTemp(void);
|
||||||
uint32_t getImot();
|
uint32_t getVdd(void);
|
||||||
ESW_status eswStatus(int motnum, int eswnum);
|
uint32_t getVmot(void);
|
||||||
|
uint32_t getImot(void);
|
||||||
|
ESW_status eswStatus(int motnum, int eswnum);
|
||||||
|
|
||||||
#endif // __ADC_H__
|
#endif // ADC_H__
|
||||||
|
|||||||
@ -41,31 +41,23 @@ user_conf the_conf = {
|
|||||||
,.v33denominator = 1
|
,.v33denominator = 1
|
||||||
,.v33numerator = 1
|
,.v33numerator = 1
|
||||||
,.ESW_thres = 500
|
,.ESW_thres = 500
|
||||||
,.usartspd = (uint32_t)115200
|
,.usartspd = (uint32_t)9600
|
||||||
,.motspd = {10, 10} // max speed: 300 steps per second
|
,.motspd = {10, 10} // max speed: 300 steps per second, should be LESS than 1310!
|
||||||
,.maxsteps = {50000, 50000} // max steps from point to point
|
,.maxsteps = {50000, 50000} // max steps from point to point
|
||||||
,.reverse = {0,0} // set DIR to this value when moving to '+'
|
,.reverse = {0,0} // set DIR to this value when moving to '+'
|
||||||
,.intpullup = 1 // by default internal pullup @ Tx pin enabled
|
,.intpullup = 1 // by default internal pullup @ Tx pin enabled
|
||||||
|
,.usteps = 16
|
||||||
|
,.accdecsteps = 100
|
||||||
};
|
};
|
||||||
|
|
||||||
static int erase_flash();
|
static int erase_flash(void);
|
||||||
|
|
||||||
static int get_gooddata(){
|
static int get_gooddata(){
|
||||||
user_conf *c = (user_conf*) FLASH_CONF_START_ADDR;
|
user_conf *c = (user_conf*) FLASH_CONF_START_ADDR;
|
||||||
// have data - move it to `the_conf`
|
// have data - move it to `the_conf`
|
||||||
int idx;
|
int idx;
|
||||||
//write2trbuf("get_gooddata()\n");
|
|
||||||
for(idx = 0; idx < maxnum; ++idx){ // find current settings index - first good
|
for(idx = 0; idx < maxnum; ++idx){ // find current settings index - first good
|
||||||
uint16_t sz = c[idx].userconf_sz;
|
uint16_t sz = c[idx].userconf_sz;
|
||||||
/*write2trbuf("idx=");
|
|
||||||
put_int((int32_t) idx);
|
|
||||||
write2trbuf(", sz=");
|
|
||||||
put_uint((uint32_t) sz);
|
|
||||||
write2trbuf(", devID=");
|
|
||||||
put_uint((uint32_t) c[idx].devID);
|
|
||||||
write2trbuf(", ESW_thres=");
|
|
||||||
put_uint((uint32_t) c[idx].ESW_thres);
|
|
||||||
SENDBUF();*/
|
|
||||||
if(sz != sizeof(user_conf)){
|
if(sz != sizeof(user_conf)){
|
||||||
if(sz == 0xffff) break; // first clear
|
if(sz == 0xffff) break; // first clear
|
||||||
else{
|
else{
|
||||||
@ -93,9 +85,6 @@ int store_userconf(){
|
|||||||
idx = 0;
|
idx = 0;
|
||||||
if(erase_flash()) return 1;
|
if(erase_flash()) return 1;
|
||||||
}else ++idx; // take next data position
|
}else ++idx; // take next data position
|
||||||
/*write2trbuf("store_userconf()\nidx=");
|
|
||||||
put_int((int32_t) idx);
|
|
||||||
SENDBUF();*/
|
|
||||||
if (FLASH->CR & FLASH_CR_LOCK){ // unloch flash
|
if (FLASH->CR & FLASH_CR_LOCK){ // unloch flash
|
||||||
FLASH->KEYR = FLASH_FKEY1;
|
FLASH->KEYR = FLASH_FKEY1;
|
||||||
FLASH->KEYR = FLASH_FKEY2;
|
FLASH->KEYR = FLASH_FKEY2;
|
||||||
@ -106,23 +95,12 @@ SENDBUF();*/
|
|||||||
FLASH->CR |= FLASH_CR_PG;
|
FLASH->CR |= FLASH_CR_PG;
|
||||||
uint16_t *data = (uint16_t*) &the_conf;
|
uint16_t *data = (uint16_t*) &the_conf;
|
||||||
uint16_t *address = (uint16_t*) &c[idx];
|
uint16_t *address = (uint16_t*) &c[idx];
|
||||||
uint32_t i, count = sizeof(user_conf) / 2;
|
uint32_t i, count = (1 + sizeof(user_conf)) / 2;
|
||||||
for (i = 0; i < count; ++i){
|
for (i = 0; i < count; ++i){
|
||||||
*(volatile uint16_t*)(address + i) = data[i];
|
*(volatile uint16_t*)(address + i) = data[i];
|
||||||
while (FLASH->SR & FLASH_SR_BSY);
|
while (FLASH->SR & FLASH_SR_BSY);
|
||||||
if(FLASH->SR & FLASH_SR_PGERR) ret = 1; // program error - meet not 0xffff
|
if(FLASH->SR & FLASH_SR_PGERR) ret = 1; // program error - meet not 0xffff
|
||||||
else while (!(FLASH->SR & FLASH_SR_EOP));
|
else while (!(FLASH->SR & FLASH_SR_EOP));
|
||||||
/*write2trbuf("write byte ");
|
|
||||||
put_int((int32_t) i);
|
|
||||||
write2trbuf(", write value=");
|
|
||||||
put_uint(data[i]);
|
|
||||||
write2trbuf(", read value=");
|
|
||||||
put_uint(address[i]);
|
|
||||||
SENDBUF();
|
|
||||||
if(ret){
|
|
||||||
write2trbuf("PGERR");
|
|
||||||
SENDBUF();
|
|
||||||
}*/
|
|
||||||
FLASH->SR = FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR;
|
FLASH->SR = FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR;
|
||||||
}
|
}
|
||||||
FLASH->CR &= ~(FLASH_CR_PG);
|
FLASH->CR &= ~(FLASH_CR_PG);
|
||||||
@ -132,17 +110,12 @@ SENDBUF();
|
|||||||
|
|
||||||
static int erase_flash(){
|
static int erase_flash(){
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
/*write2trbuf("erase_flash()");
|
|
||||||
SENDBUF();*/
|
|
||||||
/* (1) Wait till no operation is on going */
|
/* (1) Wait till no operation is on going */
|
||||||
/* (2) Clear error & EOP bits */
|
/* (2) Clear error & EOP bits */
|
||||||
/* (3) Check that the Flash is unlocked */
|
/* (3) Check that the Flash is unlocked */
|
||||||
/* (4) Perform unlock sequence */
|
/* (4) Perform unlock sequence */
|
||||||
while ((FLASH->SR & FLASH_SR_BSY) != 0){} /* (1) */
|
while ((FLASH->SR & FLASH_SR_BSY) != 0){} /* (1) */
|
||||||
FLASH->SR = FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR; /* (2) */
|
FLASH->SR = FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR; /* (2) */
|
||||||
/* if (FLASH->SR & FLASH_SR_EOP){
|
|
||||||
FLASH->SR |= FLASH_SR_EOP;
|
|
||||||
}*/
|
|
||||||
if ((FLASH->CR & FLASH_CR_LOCK) != 0){ /* (3) */
|
if ((FLASH->CR & FLASH_CR_LOCK) != 0){ /* (3) */
|
||||||
FLASH->KEYR = FLASH_FKEY1; /* (4) */
|
FLASH->KEYR = FLASH_FKEY1; /* (4) */
|
||||||
FLASH->KEYR = FLASH_FKEY2;
|
FLASH->KEYR = FLASH_FKEY2;
|
||||||
|
|||||||
@ -22,30 +22,41 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#ifndef __FLASH_H__
|
#ifndef FLASH_H__
|
||||||
#define __FLASH_H__
|
#define FLASH_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef struct{
|
typedef struct{
|
||||||
uint16_t userconf_sz; // size of data
|
uint16_t userconf_sz; // size of data
|
||||||
uint16_t devID; // device address (id)
|
uint16_t devID; // device address (id)
|
||||||
uint16_t ESW_thres; // ADC threshold for end-switches/Hall sensors
|
|
||||||
// calibration values for current/voltage sensors
|
uint16_t ESW_thres; // ADC threshold for end-switches/Hall sensors
|
||||||
uint16_t v12numerator; // 12V to motors
|
uint16_t v12numerator; // 12V to motors
|
||||||
|
|
||||||
uint16_t v12denominator;
|
uint16_t v12denominator;
|
||||||
uint16_t i12numerator; // motors' current
|
uint16_t i12numerator; // motors' current
|
||||||
|
|
||||||
uint16_t i12denominator;
|
uint16_t i12denominator;
|
||||||
uint16_t v33numerator; // 3.3V (vref)
|
uint16_t v33numerator; // 3.3V (vref)
|
||||||
|
|
||||||
|
uint16_t motspd[2]; // max motor speed ([3000 / motspd] steps per second)
|
||||||
|
|
||||||
|
uint16_t maxsteps[2]; // maximum amount of steps for each motor (0 - infinity)
|
||||||
|
|
||||||
|
uint32_t usartspd; // usartspeed
|
||||||
|
|
||||||
uint16_t v33denominator;
|
uint16_t v33denominator;
|
||||||
uint32_t usartspd; // usartspeed
|
uint8_t reverse[2]; // == 1 if positive direction when DIR is low
|
||||||
uint16_t motspd[2]; // max motor speed ([3000 / motspd] steps per second)
|
|
||||||
uint16_t maxsteps[2]; // maximum amount of steps for each motor (0 - infinity)
|
uint8_t intpullup; // internal pullup @ Tx
|
||||||
uint8_t reverse[2]; // == 1 if positive direction when DIR is low
|
uint8_t usteps; // amount of microsteps in each step
|
||||||
uint8_t intpullup; // internal pullup @ Tx
|
uint8_t accdecsteps; // amount of steps need for full acceleration/deceleration cycle
|
||||||
} user_conf;
|
} user_conf;
|
||||||
|
|
||||||
extern user_conf the_conf;
|
extern user_conf the_conf;
|
||||||
|
|
||||||
void get_userconf();
|
void get_userconf(void);
|
||||||
int store_userconf();
|
int store_userconf(void);
|
||||||
|
|
||||||
#endif // __FLASH_H__
|
#endif // FLASH_H__
|
||||||
|
|||||||
@ -19,12 +19,12 @@
|
|||||||
* MA 02110-1301, USA.
|
* MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "stm32f0.h"
|
|
||||||
#include "usart.h"
|
|
||||||
#include "adc.h"
|
#include "adc.h"
|
||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
#include "proto.h"
|
#include "proto.h"
|
||||||
#include "steppers.h"
|
#include "steppers.h"
|
||||||
|
#include "stm32f0.h"
|
||||||
|
#include "usart.h"
|
||||||
|
|
||||||
volatile uint32_t Tms = 0;
|
volatile uint32_t Tms = 0;
|
||||||
|
|
||||||
@ -85,13 +85,14 @@ void iwdg_setup(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(void){
|
int main(void){
|
||||||
uint32_t lastT = 0;
|
//uint32_t lastT = 0;
|
||||||
uint32_t ostctr = 0;
|
uint32_t ostctr = 0;
|
||||||
#if 0
|
#if 0
|
||||||
//def EBUG
|
//def EBUG
|
||||||
uint32_t msgctr = 0;
|
uint32_t msgctr = 0;
|
||||||
#endif
|
#endif
|
||||||
char *txt = NULL;
|
char *txt = NULL;
|
||||||
|
const char *ret = NULL;
|
||||||
sysreset();
|
sysreset();
|
||||||
SysTick_Config(6000, 1);
|
SysTick_Config(6000, 1);
|
||||||
get_userconf();
|
get_userconf();
|
||||||
@ -103,17 +104,13 @@ int main(void){
|
|||||||
//pin_set(GPIOA, 1<<5); // clear extern LED
|
//pin_set(GPIOA, 1<<5); // clear extern LED
|
||||||
while (1){
|
while (1){
|
||||||
IWDG->KR = IWDG_REFRESH; // refresh watchdog
|
IWDG->KR = IWDG_REFRESH; // refresh watchdog
|
||||||
if(lastT > Tms || Tms - lastT > 499){
|
/*if(lastT > Tms || Tms - lastT > 499){
|
||||||
/* #ifdef EBUG
|
|
||||||
pin_toggle(GPIOA, 1<<4); // blink by onboard LED once per second
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
lastT = Tms;
|
lastT = Tms;
|
||||||
}
|
}*/
|
||||||
if(usart1rx()){ // usart1 received data, store in in buffer
|
if(usart1rx()){ // usart1 received data, store in in buffer
|
||||||
if(usart1_getline(&txt)){
|
if(usart1_getline(&txt)){
|
||||||
txt = process_command(txt);
|
ret = process_command(txt);
|
||||||
}else txt = NULL; // buffer overflow
|
}else ret = NULL; // buffer overflow
|
||||||
}
|
}
|
||||||
#if 0
|
#if 0
|
||||||
//def EBUG
|
//def EBUG
|
||||||
@ -122,15 +119,9 @@ int main(void){
|
|||||||
txt = "hello, I'm alive!\n";
|
txt = "hello, I'm alive!\n";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/*
|
if(ret){ // text waits for sending
|
||||||
if(trbufisfull()){
|
if(ALL_OK == usart1_send(ret)){
|
||||||
write2trbuf("ERR");
|
ret = NULL;
|
||||||
usart1_send_blocking(gettrbuf());
|
|
||||||
}
|
|
||||||
cleartrbuf();*/
|
|
||||||
if(txt){ // text waits for sending
|
|
||||||
if(ALL_OK == usart1_send(txt)){
|
|
||||||
txt = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(ostctr != Tms){ // check steppers not frequently than once in 1ms
|
if(ostctr != Tms){ // check steppers not frequently than once in 1ms
|
||||||
|
|||||||
@ -20,41 +20,43 @@
|
|||||||
* MA 02110-1301, USA.
|
* MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#include "stm32f0.h"
|
|
||||||
#include "proto.h"
|
|
||||||
#include "adc.h"
|
#include "adc.h"
|
||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
|
#include "proto.h"
|
||||||
|
#include "steppers.h"
|
||||||
|
#include "stm32f0.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "usart.h"
|
#include "usart.h"
|
||||||
#include "steppers.h"
|
|
||||||
|
|
||||||
static const char *eodata = "DATAEND";
|
static const char *eodata = "DATAEND";
|
||||||
static const char *badcmd = "BADCMD";
|
static const char *badcmd = "BADCMD";
|
||||||
static const char *allok = "ALL OK";
|
static const char *allok = "ALLOK";
|
||||||
static const char *err = "ERR";
|
static const char *err = "ERR";
|
||||||
|
|
||||||
#define EODATA ((char*)eodata)
|
#define EODATA (eodata)
|
||||||
#define BADCMD ((char*)badcmd)
|
#define BADCMD (badcmd)
|
||||||
#define ALLOK ((char*)allok)
|
#define ALLOK (allok)
|
||||||
#define ERR ((char*)err)
|
#define ERR (err)
|
||||||
|
|
||||||
static char *getnum(char *buf, int32_t *N);
|
static const char *getnum(const char *buf, int32_t *N);
|
||||||
static char *get_something(char *str);
|
static const char *get_something(const char *str);
|
||||||
static char *set_something(char *str);
|
static const char *set_something(const char *str);
|
||||||
static char *motor_cmd(char *str);
|
static const char *motor_cmd(const char *str);
|
||||||
|
|
||||||
static char *get_status();
|
static const char *get_status(void);
|
||||||
static char *get_conf();
|
static const char *get_conf(void);
|
||||||
static char *get_raw_adc();
|
static const char *get_raw_adc(void);
|
||||||
static char *get_ADCval(char *str);
|
static const char *get_ADCval(const char *str);
|
||||||
static char *get_temper();
|
static const char *get_temper(void);
|
||||||
|
|
||||||
static char *setDenEn(uint8_t De, char *str);
|
static const char *setDenEn(uint8_t De, const char *str);
|
||||||
static char *setDevId(char *str);
|
static const char *setDevId(const char *str);
|
||||||
static char *setESWthres(char *str);
|
static const char *setESWthres(const char *str);
|
||||||
static char *setUSARTspd(char *str);
|
static const char *setUSARTspd(const char *str);
|
||||||
static char *setmotvals(char v, char *str);
|
static const char *setUSTEPS(const char *str);
|
||||||
static char *setMotSpeed(int cur, char *str);
|
static const char *setACCDEC(const char *str);
|
||||||
|
static const char *setmotvals(char v, const char *str);
|
||||||
|
static const char *setMotSpeed(int cur, const char *str);
|
||||||
|
|
||||||
#define omitwsp(str) do{register char nxt; while((nxt = *str)){if(nxt != ' ' && nxt != '\t') break; else ++str;}}while(0)
|
#define omitwsp(str) do{register char nxt; while((nxt = *str)){if(nxt != ' ' && nxt != '\t') break; else ++str;}}while(0)
|
||||||
|
|
||||||
@ -62,9 +64,10 @@ static char *setMotSpeed(int cur, char *str);
|
|||||||
* get input buffer `cmdbuf`, parse it and change system state
|
* get input buffer `cmdbuf`, parse it and change system state
|
||||||
* @return message to send
|
* @return message to send
|
||||||
*/
|
*/
|
||||||
char* process_command(char *cmdbuf){
|
const char* process_command(const char *cmdbuf){
|
||||||
int32_t num;
|
int32_t num;
|
||||||
char *str, c;
|
const char *str;
|
||||||
|
char c;
|
||||||
#ifdef EBUG
|
#ifdef EBUG
|
||||||
usart1_send_blocking(cmdbuf);
|
usart1_send_blocking(cmdbuf);
|
||||||
#endif
|
#endif
|
||||||
@ -99,7 +102,7 @@ char* process_command(char *cmdbuf){
|
|||||||
|
|
||||||
// read `buf` and get first integer `N` in it
|
// read `buf` and get first integer `N` in it
|
||||||
// @return pointer to first non-number if all OK or NULL if first symbol isn't a space or number
|
// @return pointer to first non-number if all OK or NULL if first symbol isn't a space or number
|
||||||
static char *getnum(char *buf, int32_t *N){
|
static const char *getnum(const char *buf, int32_t *N){
|
||||||
char c;
|
char c;
|
||||||
int positive = -1;
|
int positive = -1;
|
||||||
int32_t val = 0;
|
int32_t val = 0;
|
||||||
@ -130,7 +133,7 @@ static char *getnum(char *buf, int32_t *N){
|
|||||||
|
|
||||||
// get conf (uint16_t) number
|
// get conf (uint16_t) number
|
||||||
// @return 0 if all OK
|
// @return 0 if all OK
|
||||||
static int getu16(char *buf, uint16_t *N){
|
static int getu16(const char *buf, uint16_t *N){
|
||||||
int32_t N32;
|
int32_t N32;
|
||||||
if(!getnum(buf, &N32)) return 1;
|
if(!getnum(buf, &N32)) return 1;
|
||||||
if(N32 > 0xffff || N32 < 0) return 1;
|
if(N32 > 0xffff || N32 < 0) return 1;
|
||||||
@ -138,7 +141,7 @@ static int getu16(char *buf, uint16_t *N){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *get_something(char *str){
|
static const char *get_something(const char *str){
|
||||||
switch(*str++){
|
switch(*str++){
|
||||||
case 'A': // get ADC value: voltage or current
|
case 'A': // get ADC value: voltage or current
|
||||||
return get_ADCval(str);
|
return get_ADCval(str);
|
||||||
@ -159,8 +162,7 @@ static char *get_something(char *str){
|
|||||||
return BADCMD;
|
return BADCMD;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *get_status(){
|
static const char *get_status(){
|
||||||
int i, j;
|
|
||||||
char str[3] = {0, '=', 0};
|
char str[3] = {0, '=', 0};
|
||||||
if(RCC->CSR & RCC_CSR_IWDGRSTF){ // watchdog reset occured
|
if(RCC->CSR & RCC_CSR_IWDGRSTF){ // watchdog reset occured
|
||||||
write2trbuf("WDGRESET=1\n");
|
write2trbuf("WDGRESET=1\n");
|
||||||
@ -169,7 +171,7 @@ static char *get_status(){
|
|||||||
write2trbuf("SOFTRESET=1\n");
|
write2trbuf("SOFTRESET=1\n");
|
||||||
}
|
}
|
||||||
RCC->CSR = RCC_CSR_RMVF; // clear reset flags
|
RCC->CSR = RCC_CSR_RMVF; // clear reset flags
|
||||||
for(i = 0; i < 2; ++i){
|
for(int8_t i = 0; i < 2; ++i){
|
||||||
write2trbuf("MOTOR"); str[0] = '0' + i;
|
write2trbuf("MOTOR"); str[0] = '0' + i;
|
||||||
write2trbuf(str);
|
write2trbuf(str);
|
||||||
stp_state stt = stp_getstate(i);
|
stp_state stt = stp_getstate(i);
|
||||||
@ -212,7 +214,7 @@ static char *get_status(){
|
|||||||
write2trbuf(str);
|
write2trbuf(str);
|
||||||
put_int(stp_position(i));
|
put_int(stp_position(i));
|
||||||
SENDBUF();
|
SENDBUF();
|
||||||
for(j = 0; j < 2; ++j){
|
for(int8_t j = 0; j < 2; ++j){
|
||||||
write2trbuf("ESW"); put2trbuf('0' + i);
|
write2trbuf("ESW"); put2trbuf('0' + i);
|
||||||
put2trbuf('0' + j); put2trbuf('=');
|
put2trbuf('0' + j); put2trbuf('=');
|
||||||
ESW_status stat = eswStatus(i, j);
|
ESW_status stat = eswStatus(i, j);
|
||||||
@ -242,24 +244,38 @@ typedef struct{
|
|||||||
const uint16_t *ptr;
|
const uint16_t *ptr;
|
||||||
} user_conf_descr;
|
} user_conf_descr;
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
const char *fieldname;
|
||||||
|
const uint8_t *ptr;
|
||||||
|
} user_conf_descr8;
|
||||||
|
|
||||||
static const user_conf_descr descrarr[] = {
|
static const user_conf_descr descrarr[] = {
|
||||||
{"CONFSZ", &the_conf.userconf_sz},
|
{"CONFSZ", &the_conf.userconf_sz},
|
||||||
{"DEVID", &the_conf.devID},
|
{"DEVID", &the_conf.devID},
|
||||||
{"V12NUM", &the_conf.v12numerator},
|
{"V12NUM", &the_conf.v12numerator},
|
||||||
{"V12DEN", &the_conf.v12denominator},
|
{"V12DEN", &the_conf.v12denominator},
|
||||||
{"I12NUM", &the_conf.i12numerator},
|
{"I12NUM", &the_conf.i12numerator},
|
||||||
{"I12DEN", &the_conf.i12denominator},
|
{"I12DEN", &the_conf.i12denominator},
|
||||||
{"V33NUM", &the_conf.v33numerator},
|
{"V33NUM", &the_conf.v33numerator},
|
||||||
{"V33DEN", &the_conf.v33denominator},
|
{"V33DEN", &the_conf.v33denominator},
|
||||||
{"ESWTHR", &the_conf.ESW_thres},
|
{"ESWTHR", &the_conf.ESW_thres},
|
||||||
{"MOT0SPD",&the_conf.motspd[0]},
|
{"MOT0SPD", &the_conf.motspd[0]},
|
||||||
{"MOT1SPD",&the_conf.motspd[1]},
|
{"MOT1SPD", &the_conf.motspd[1]},
|
||||||
{"MAXSTEPS0",&the_conf.maxsteps[0]},
|
{"MAXSTEPS0", &the_conf.maxsteps[0]},
|
||||||
{"MAXSTEPS1",&the_conf.maxsteps[1]},
|
{"MAXSTEPS1", &the_conf.maxsteps[1]},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
static char *get_conf(){
|
static const user_conf_descr8 descrarr8[] = {
|
||||||
|
{"INTPULLUP", &the_conf.intpullup},
|
||||||
|
{"REVERSE0", &the_conf.reverse[0]},
|
||||||
|
{"REVERSE1", &the_conf.reverse[1]},
|
||||||
|
{"USTEPS", &the_conf.usteps},
|
||||||
|
{"ACCDECSTEPS", &the_conf.accdecsteps},
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *get_conf(){
|
||||||
const user_conf_descr *curdesc = descrarr;
|
const user_conf_descr *curdesc = descrarr;
|
||||||
do{
|
do{
|
||||||
write2trbuf(curdesc->fieldname);
|
write2trbuf(curdesc->fieldname);
|
||||||
@ -267,32 +283,31 @@ static char *get_conf(){
|
|||||||
put_uint((uint32_t) *curdesc->ptr);
|
put_uint((uint32_t) *curdesc->ptr);
|
||||||
SENDBUF();
|
SENDBUF();
|
||||||
}while((++curdesc)->fieldname);
|
}while((++curdesc)->fieldname);
|
||||||
write2trbuf("INTPULLUP=");
|
const user_conf_descr8 *curdesc8 = descrarr8;
|
||||||
put2trbuf(the_conf.intpullup ? '1' : '0');
|
write2trbuf("USARTSPD=");
|
||||||
write2trbuf("\nUSARTSPD=");
|
|
||||||
put_uint(the_conf.usartspd);
|
put_uint(the_conf.usartspd);
|
||||||
SENDBUF();
|
SENDBUF();
|
||||||
write2trbuf("REVERSE0=");
|
do{
|
||||||
put_uint(the_conf.reverse[0]);
|
write2trbuf(curdesc8->fieldname);
|
||||||
write2trbuf("\nREVERSE1=");
|
put2trbuf('=');
|
||||||
put_uint(the_conf.reverse[1]);
|
put_uint((uint32_t) *curdesc8->ptr);
|
||||||
SENDBUF();
|
SENDBUF();
|
||||||
|
}while((++curdesc8)->fieldname);
|
||||||
return EODATA;
|
return EODATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *get_raw_adc(){
|
static const char *get_raw_adc(){
|
||||||
int i;
|
for(int8_t i = 0; i < NUMBER_OF_ADC_CHANNELS; ++i){
|
||||||
for(i = 0; i < NUMBER_OF_ADC_CHANNELS; ++i){
|
|
||||||
write2trbuf("ADC[");
|
write2trbuf("ADC[");
|
||||||
put2trbuf('0' + i);
|
put2trbuf('0' + i);
|
||||||
write2trbuf("]=");
|
write2trbuf("]=");
|
||||||
put_uint((uint32_t) ADC_array[i]);
|
put_uint((uint32_t) getADCval(i));
|
||||||
SENDBUF();
|
SENDBUF();
|
||||||
}
|
}
|
||||||
return EODATA;
|
return EODATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *get_ADCval(char *str){
|
static const char *get_ADCval(const char *str){
|
||||||
uint32_t v;
|
uint32_t v;
|
||||||
switch(*str){
|
switch(*str){
|
||||||
case 'D': // vdd
|
case 'D': // vdd
|
||||||
@ -315,7 +330,7 @@ static char *get_ADCval(char *str){
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *get_temper(){
|
static const char *get_temper(){
|
||||||
int32_t t = getTemp();
|
int32_t t = getTemp();
|
||||||
write2trbuf("TEMP=");
|
write2trbuf("TEMP=");
|
||||||
put_int(t);
|
put_int(t);
|
||||||
@ -323,8 +338,11 @@ static char *get_temper(){
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *set_something(char *str){
|
static const char *set_something(const char *str){
|
||||||
switch(*str++){
|
switch(*str++){
|
||||||
|
case 'A': // set accdecsteps
|
||||||
|
return setACCDEC(str);
|
||||||
|
break;
|
||||||
case 'C': // set current speed
|
case 'C': // set current speed
|
||||||
return setMotSpeed(1, str);
|
return setMotSpeed(1, str);
|
||||||
break;
|
break;
|
||||||
@ -358,6 +376,9 @@ static char *set_something(char *str){
|
|||||||
case 'U': // set USART speed
|
case 'U': // set USART speed
|
||||||
return setUSARTspd(str);
|
return setUSARTspd(str);
|
||||||
break;
|
break;
|
||||||
|
case 'u': // set usteps
|
||||||
|
return setUSTEPS(str);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return BADCMD;
|
return BADCMD;
|
||||||
}
|
}
|
||||||
@ -367,7 +388,7 @@ static char *set_something(char *str){
|
|||||||
* @param De == 1 for denominator, == 0 for numerator
|
* @param De == 1 for denominator, == 0 for numerator
|
||||||
* @param str - rest of string
|
* @param str - rest of string
|
||||||
*/
|
*/
|
||||||
static char *setDenEn(uint8_t De, char *str){
|
static const char *setDenEn(uint8_t De, const char *str){
|
||||||
uint16_t *targ = NULL;
|
uint16_t *targ = NULL;
|
||||||
switch(*str++){
|
switch(*str++){
|
||||||
case 'D':
|
case 'D':
|
||||||
@ -387,19 +408,19 @@ static char *setDenEn(uint8_t De, char *str){
|
|||||||
return ALLOK;
|
return ALLOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *setDevId(char *str){
|
static const char *setDevId(const char *str){
|
||||||
omitwsp(str);
|
omitwsp(str);
|
||||||
if(getu16(str, &the_conf.devID)) return BADCMD;
|
if(getu16(str, &the_conf.devID)) return BADCMD;
|
||||||
return ALLOK;
|
return ALLOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *setESWthres(char *str){
|
static const char *setESWthres(const char *str){
|
||||||
omitwsp(str);
|
omitwsp(str);
|
||||||
if(getu16(str, &the_conf.ESW_thres)) return BADCMD;
|
if(getu16(str, &the_conf.ESW_thres)) return BADCMD;
|
||||||
return ALLOK;
|
return ALLOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *setUSARTspd(char *str){
|
static const char *setUSARTspd(const char *str){
|
||||||
omitwsp(str);
|
omitwsp(str);
|
||||||
int32_t N32;
|
int32_t N32;
|
||||||
if(!getnum(str, &N32)) return BADCMD;
|
if(!getnum(str, &N32)) return BADCMD;
|
||||||
@ -408,40 +429,40 @@ static char *setUSARTspd(char *str){
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if cur == 1 set current speed else set global motspd
|
// if cur == 1 set current speed else set global motspd
|
||||||
static char *setMotSpeed(int cur, char *str){
|
static const char *setMotSpeed(int cur, const char *str){
|
||||||
omitwsp(str);
|
omitwsp(str);
|
||||||
uint8_t Num = *str++ - '0';
|
uint8_t Num = (uint8_t)(*str++ - '0');
|
||||||
if(Num > 1) return ERR;
|
if(Num > 1) return ERR;
|
||||||
int32_t spd;
|
int32_t spd;
|
||||||
omitwsp(str);
|
omitwsp(str);
|
||||||
if(!getnum(str, &spd)) return ERR;
|
if(!getnum(str, &spd)) return BADCMD;
|
||||||
if(spd < 2 || spd > 6553) return "BadSpd";
|
if(spd < 2 || spd > (0xffff/LOWEST_SPEED_DIV)) return ERR;
|
||||||
if(cur){ // change current speed
|
if(cur){ // change current speed
|
||||||
stp_chARR(Num, spd);
|
stp_chARR(Num, spd);
|
||||||
}else{
|
}else{
|
||||||
the_conf.motspd[Num] = spd;
|
the_conf.motspd[Num] = (uint16_t)spd;
|
||||||
stp_chspd();
|
stp_chspd();
|
||||||
}
|
}
|
||||||
return ALLOK;
|
return ALLOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set other motor values
|
// set other motor values
|
||||||
static char *setmotvals(char v, char *str){
|
static const char *setmotvals(char v, const char *str){
|
||||||
omitwsp(str);
|
omitwsp(str);
|
||||||
uint8_t Num = *str++ - '0';
|
uint8_t Num = (uint8_t)(*str++ - '0');
|
||||||
if(Num > 1) return ERR;
|
if(Num > 1) return ERR;
|
||||||
omitwsp(str);
|
omitwsp(str);
|
||||||
int32_t val;
|
int32_t val;
|
||||||
if(!getnum(str, &val)) return ERR;
|
if(!getnum(str, &val)) return BADCMD;
|
||||||
if(val < 0 || val > 0xffff) return "BadUINT16";
|
if(val < 0 || val > 0xffff) return ERR;
|
||||||
switch(v){
|
switch(v){
|
||||||
case 'M': // maxsteps
|
case 'M': // maxsteps
|
||||||
if(val == 0) return ERR;
|
if(val == 0) return ERR;
|
||||||
the_conf.maxsteps[Num] = val;
|
the_conf.maxsteps[Num] = (uint16_t)val;
|
||||||
break;
|
break;
|
||||||
case 'R': // reverse
|
case 'R': // reverse
|
||||||
if(val && val != 1) return ERR;
|
if(val && val != 1) return ERR;
|
||||||
the_conf.reverse[Num] = val;
|
the_conf.reverse[Num] = (uint8_t)val;
|
||||||
break;
|
break;
|
||||||
default: return ERR;
|
default: return ERR;
|
||||||
}
|
}
|
||||||
@ -449,12 +470,12 @@ static char *setmotvals(char v, char *str){
|
|||||||
}
|
}
|
||||||
|
|
||||||
// process motor command: start/stop
|
// process motor command: start/stop
|
||||||
static char *motor_cmd(char *str){
|
static const char *motor_cmd(const char *str){
|
||||||
omitwsp(str);
|
omitwsp(str);
|
||||||
uint8_t Num = *str++ - '0';
|
uint8_t Num = (uint8_t)(*str++ - '0');
|
||||||
int32_t steps;
|
int32_t steps;
|
||||||
stp_status st;
|
stp_status st;
|
||||||
if(Num > 1) return "Num>1";
|
if(Num > 1) return ERR;
|
||||||
omitwsp(str);
|
omitwsp(str);
|
||||||
switch(*str++){
|
switch(*str++){
|
||||||
case 'M':
|
case 'M':
|
||||||
@ -485,3 +506,34 @@ static char *motor_cmd(char *str){
|
|||||||
}
|
}
|
||||||
return ERR;
|
return ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set value of usteps
|
||||||
|
static const char *setUSTEPS(const char *str){
|
||||||
|
omitwsp(str);
|
||||||
|
uint16_t x;
|
||||||
|
if(getu16(str, &x)) return BADCMD;
|
||||||
|
switch(x){
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 4:
|
||||||
|
case 8:
|
||||||
|
case 16:
|
||||||
|
case 32:
|
||||||
|
the_conf.usteps = (uint8_t)x;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return ERR;
|
||||||
|
}
|
||||||
|
return ALLOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set value of accdecsteps
|
||||||
|
static const char *setACCDEC(const char *str){
|
||||||
|
omitwsp(str);
|
||||||
|
uint16_t x;
|
||||||
|
if(getu16(str, &x)) return BADCMD;
|
||||||
|
if(x < ACCDECSTEPS_MIN || x > 255) return ERR;
|
||||||
|
the_conf.accdecsteps = (uint8_t)x;
|
||||||
|
stp_chspd();
|
||||||
|
return ALLOK;
|
||||||
|
}
|
||||||
|
|||||||
@ -21,9 +21,9 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#ifndef __PROTO_H__
|
#ifndef PROTO_H__
|
||||||
#define __PROTO_H__
|
#define PROTO_H__
|
||||||
|
|
||||||
char* process_command(char *cmdbuf);
|
const char* process_command(const char *cmdbuf);
|
||||||
|
|
||||||
#endif // __PROTO_H__
|
#endif // PROTO_H__
|
||||||
|
|||||||
@ -237,7 +237,7 @@ just <code>ALL OK</code> if succeed.</p>
|
|||||||
|
|
||||||
<h3>Motors' manipulation</h3>
|
<h3>Motors' manipulation</h3>
|
||||||
|
|
||||||
<p>Next char should be ‘0’ or ‘1’ — motor’s number. If wrong, <code>Num>1</code> answer would be returned.
|
<p>Next char should be ‘0’ or ‘1’ — motor’s number. If wrong, <code>BADCMD</code> answer would be returned.
|
||||||
There’s only two commands in this section:</p>
|
There’s only two commands in this section:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
@ -261,9 +261,10 @@ There’s only two commands in this section:</p>
|
|||||||
<em>write flash</em> command.</p>
|
<em>write flash</em> command.</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
|
<li><strong>A num</strong> - set value of ACCDECSTEPS (approximate amount of steps to do acceleration/deceleration) to <em>num</em></li>
|
||||||
<li><strong>C#num</strong> - set current <em>speed</em> to <em>num</em> for motor #</li>
|
<li><strong>C#num</strong> - set current <em>speed</em> to <em>num</em> for motor #</li>
|
||||||
<li><strong>D num</strong> - set <em>denominator</em> to number <em>num</em></li>
|
<li><strong>D$num</strong> - set <em>denominator $</em> (<em>D</em> - Vdd, <em>I</em> - current, <em>M</em> - 12V) to number <em>num</em></li>
|
||||||
<li><strong>E num</strong> - set <em>numerator</em></li>
|
<li><strong>E$num</strong> - set <em>numerator $</em></li>
|
||||||
<li><strong>I num</strong> - set <em>device ID</em></li>
|
<li><strong>I num</strong> - set <em>device ID</em></li>
|
||||||
<li><strong>M#num</strong> - set maxsteps (<em>num</em> is 1..65535) for motor <code>#</code></li>
|
<li><strong>M#num</strong> - set maxsteps (<em>num</em> is 1..65535) for motor <code>#</code></li>
|
||||||
<li><strong>P num</strong> - properties of internal pullup (0 - disabled, other or without <code>num</code> - enabled)</li>
|
<li><strong>P num</strong> - properties of internal pullup (0 - disabled, other or without <code>num</code> - enabled)</li>
|
||||||
@ -272,13 +273,14 @@ There’s only two commands in this section:</p>
|
|||||||
<li><strong>T num</strong> - set <em>end-switches threshold</em> (in ADU, near 0 for Hall switch, 2048 for user button
|
<li><strong>T num</strong> - set <em>end-switches threshold</em> (in ADU, near 0 for Hall switch, 2048 for user button
|
||||||
and 4096 for released state)</li>
|
and 4096 for released state)</li>
|
||||||
<li><strong>U num</strong> - set <em>USART speed</em> to <em>num</em> bits per second</li>
|
<li><strong>U num</strong> - set <em>USART speed</em> to <em>num</em> bits per second</li>
|
||||||
|
<li><strong>u num</strong> - set value of USTEPS (amount of microsteps per one step)</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
<h3>Motor speed setters</h3>
|
<h3>Motor speed setters</h3>
|
||||||
|
|
||||||
<p>To set motor speed to <strong>N</strong> steps per second, give command <code>C</code> or <code>S</code> with argument equal to
|
<p>To set motor speed to <strong>N</strong> steps per second, give command <code>C</code> or <code>S</code> with argument equal to
|
||||||
3000/N. E.g. to set current speed for DevID=0, motor0 to 50 steps per second give command <code>0SC050</code>.</p>
|
3000/N. E.g. to set current speed for DevID=0, motor0 to 50 steps per second give command <code>0SC060</code>.</p>
|
||||||
|
|
||||||
<h3>Denominator and numerator setters</h3>
|
<h3>Denominator and numerator setters</h3>
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@ -27,9 +27,9 @@
|
|||||||
#include "usart.h"
|
#include "usart.h"
|
||||||
|
|
||||||
// amount of steps need for full acceleration/deceleration cycle
|
// amount of steps need for full acceleration/deceleration cycle
|
||||||
#define ACCDECSTEPS (50)
|
#define ACCDECSTEPS (the_conf.accdecsteps)
|
||||||
// amount of microsteps in each step
|
// amount of microsteps in each step
|
||||||
#define USTEPS (16)
|
#define USTEPS (the_conf.usteps)
|
||||||
|
|
||||||
static GPIO_TypeDef* const MPORT[2] = {GPIOF, GPIOA};
|
static GPIO_TypeDef* const MPORT[2] = {GPIOF, GPIOA};
|
||||||
static const uint16_t MENPIN[2] = { 1<<0, 1 << 5}; // enable pins: PF0 and PA5
|
static const uint16_t MENPIN[2] = { 1<<0, 1 << 5}; // enable pins: PF0 and PA5
|
||||||
@ -58,8 +58,8 @@ void stp_chspd(){
|
|||||||
for(i = 0; i < 2; ++i){
|
for(i = 0; i < 2; ++i){
|
||||||
uint16_t spd = the_conf.motspd[i];
|
uint16_t spd = the_conf.motspd[i];
|
||||||
stplowarr[i] = spd;
|
stplowarr[i] = spd;
|
||||||
stphigharr[i] = spd * 10;
|
stphigharr[i] = spd * LOWEST_SPEED_DIV;
|
||||||
stpsteparr[i] = (spd * 9) / ACCDECSTEPS + 1;
|
stpsteparr[i] = (spd * (LOWEST_SPEED_DIV - 1)) / ((uint16_t)ACCDECSTEPS) + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,34 +106,25 @@ void stp_process(){
|
|||||||
esw[0] = eswStatus(0, 0);
|
esw[0] = eswStatus(0, 0);
|
||||||
esw[1] = eswStatus(0, 1);
|
esw[1] = eswStatus(0, 1);
|
||||||
if(esw[0] == ESW_BUTTON || esw[1] == ESW_BUTTON){
|
if(esw[0] == ESW_BUTTON || esw[1] == ESW_BUTTON){
|
||||||
if(lastbtnpressed++ == 3){ // stop all motors @ button
|
if(lastbtnpressed++ == 5){ // stop all motors @ button
|
||||||
//~ write2trbuf("1stpress");
|
|
||||||
//~ SENDBUF();
|
|
||||||
uint8_t stopped = 0;
|
uint8_t stopped = 0;
|
||||||
if(state[0] != STP_SLEEP){
|
if(state[0] != STP_SLEEP){
|
||||||
//~ write2trbuf("stopmot0");
|
|
||||||
//~ SENDBUF();
|
|
||||||
state[0] = STP_STOP;
|
state[0] = STP_STOP;
|
||||||
stopped = 1;
|
stopped = 1;
|
||||||
}
|
}
|
||||||
if(state[1] != STP_SLEEP){
|
if(state[1] != STP_SLEEP){
|
||||||
//~ write2trbuf("stopmot1");
|
|
||||||
//~ SENDBUF();
|
|
||||||
state[1] = STP_STOP;
|
state[1] = STP_STOP;
|
||||||
stopped = 1;
|
stopped = 1;
|
||||||
}
|
}
|
||||||
if(stopped) lastbtnpressed = 111; // override value
|
if(stopped){
|
||||||
}else if(lastbtnpressed == 100){ // one or both buttons pressed, run only after ~100ms
|
DBG("S(btn)\n");
|
||||||
//~ write2trbuf("lastbtnpressed");
|
lastbtnpressed = 51; // override value
|
||||||
//~ SENDBUF();
|
}
|
||||||
|
}else if(lastbtnpressed == 50){ // one or both buttons pressed, run only after ~100ms
|
||||||
if(esw[0] == ESW_BUTTON && esw[1] == ESW_BUTTON){
|
if(esw[0] == ESW_BUTTON && esw[1] == ESW_BUTTON){
|
||||||
//~ write2trbuf("both");
|
|
||||||
//~ SENDBUF();
|
|
||||||
// both buttons pressed - move MOTOR1 to zero
|
// both buttons pressed - move MOTOR1 to zero
|
||||||
state[1] = STP_MOVE0;
|
state[1] = STP_MOVE0;
|
||||||
}else{ // move motor 0 to 0 or 1
|
}else{ // move motor 0 to 0 or 1
|
||||||
//~ write2trbuf("single");
|
|
||||||
//~ SENDBUF();
|
|
||||||
if(esw[0] == ESW_BUTTON) state[0] = STP_MOVE0;
|
if(esw[0] == ESW_BUTTON) state[0] = STP_MOVE0;
|
||||||
else state[0] = STP_MOVE1;
|
else state[0] = STP_MOVE1;
|
||||||
}
|
}
|
||||||
@ -148,35 +139,21 @@ void stp_process(){
|
|||||||
case STP_MOVE0: // move towards zero endswitch
|
case STP_MOVE0: // move towards zero endswitch
|
||||||
state[i] = STP_SLEEP;
|
state[i] = STP_SLEEP;
|
||||||
stp_move(i, -the_conf.maxsteps[i]); // won't move if the_conf.maxsteps == 0
|
stp_move(i, -the_conf.maxsteps[i]); // won't move if the_conf.maxsteps == 0
|
||||||
//~ write2trbuf("MOTOR");
|
|
||||||
//~ put2trbuf('0'+i);
|
|
||||||
//~ write2trbuf(" move0");
|
|
||||||
//~ SENDBUF();
|
|
||||||
break;
|
break;
|
||||||
case STP_MOVE1:
|
case STP_MOVE1:
|
||||||
state[i] = STP_SLEEP;
|
state[i] = STP_SLEEP;
|
||||||
stp_move(i, the_conf.maxsteps[i]);
|
stp_move(i, the_conf.maxsteps[i]);
|
||||||
//~ write2trbuf("MOTOR");
|
|
||||||
//~ put2trbuf('0'+i);
|
|
||||||
//~ write2trbuf(" move1");
|
|
||||||
//~ SENDBUF();
|
|
||||||
break;
|
break;
|
||||||
case STP_ACCEL: // @ any move check esw
|
case STP_ACCEL: // @ any move check esw
|
||||||
case STP_DECEL:
|
case STP_DECEL:
|
||||||
case STP_MOVE:
|
case STP_MOVE:
|
||||||
case STP_MVSLOW: // check end-switches status
|
case STP_MVSLOW: // check end-switches status
|
||||||
if(esw[0] == ESW_HALL && dir[i] == -1){
|
if(esw[0] == ESW_HALL && dir[i] == -1){
|
||||||
|
DBG("S@0\n");
|
||||||
state[i] = STP_STOPZERO; // stop @ end-switch
|
state[i] = STP_STOPZERO; // stop @ end-switch
|
||||||
//~ write2trbuf("MOTOR");
|
|
||||||
//~ put2trbuf('0'+i);
|
|
||||||
//~ write2trbuf(" stop on zero end-switch");
|
|
||||||
//~ SENDBUF();
|
|
||||||
}else{ if(esw[1] == ESW_HALL && dir[i] == 1){
|
}else{ if(esw[1] == ESW_HALL && dir[i] == 1){
|
||||||
state[i] = STP_STOP; // stop @ end-switch 1
|
state[i] = STP_STOP; // stop @ end-switch 1
|
||||||
//~ write2trbuf("MOTOR");
|
DBG("S@1\n");
|
||||||
//~ put2trbuf('0'+i);
|
|
||||||
//~ write2trbuf(" stop on sw1");
|
|
||||||
//~ SENDBUF();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -192,12 +169,12 @@ stp_status stp_move(int nmotor, int32_t steps){
|
|||||||
if(st != STP_SLEEP && st != STP_MOVE0 && st != STP_MOVE1) return STPS_ACTIVE;
|
if(st != STP_SLEEP && st != STP_MOVE0 && st != STP_MOVE1) return STPS_ACTIVE;
|
||||||
if(steps == 0)
|
if(steps == 0)
|
||||||
return STPS_ZEROMOVE;
|
return STPS_ZEROMOVE;
|
||||||
|
if(the_conf.maxsteps[nmotor] && steps > the_conf.maxsteps[nmotor]) return STPS_TOOBIG;
|
||||||
int8_t d;
|
int8_t d;
|
||||||
if(steps < 0){
|
if(steps < 0){
|
||||||
d = -1;
|
d = -1;
|
||||||
steps = -steps;
|
steps = -steps;
|
||||||
}else d = 1; // positive direction
|
}else d = 1; // positive direction
|
||||||
if(the_conf.maxsteps[nmotor] && steps > the_conf.maxsteps[nmotor]) return STPS_TOOBIG;
|
|
||||||
// check end-switches
|
// check end-switches
|
||||||
if(eswStatus(nmotor, 0) == ESW_HALL && d == -1) return STPS_ONESW;
|
if(eswStatus(nmotor, 0) == ESW_HALL && d == -1) return STPS_ONESW;
|
||||||
if(eswStatus(nmotor, 1) == ESW_HALL && d == 1) return STPS_ONESW;
|
if(eswStatus(nmotor, 1) == ESW_HALL && d == 1) return STPS_ONESW;
|
||||||
@ -216,7 +193,7 @@ stp_status stp_move(int nmotor, int32_t steps){
|
|||||||
}
|
}
|
||||||
// turn on EN pin (0)
|
// turn on EN pin (0)
|
||||||
pin_clear(MPORT[nmotor], MENPIN[nmotor]);
|
pin_clear(MPORT[nmotor], MENPIN[nmotor]);
|
||||||
steps_left[nmotor] = steps;
|
steps_left[nmotor] = (uint32_t)steps;
|
||||||
// setup timer & start it
|
// setup timer & start it
|
||||||
TIM_TypeDef *TIMx = nmotor ? TIM3 : TIM14;
|
TIM_TypeDef *TIMx = nmotor ? TIM3 : TIM14;
|
||||||
TIMx->ARR = stphigharr[nmotor];
|
TIMx->ARR = stphigharr[nmotor];
|
||||||
@ -231,7 +208,7 @@ stp_status stp_move(int nmotor, int32_t steps){
|
|||||||
void stp_chARR(int n, int32_t val){
|
void stp_chARR(int n, int32_t val){
|
||||||
TIM_TypeDef *TIMx = n ? TIM3 : TIM14;
|
TIM_TypeDef *TIMx = n ? TIM3 : TIM14;
|
||||||
if(val < 2) val = 2;
|
if(val < 2) val = 2;
|
||||||
TIMx->ARR = val;
|
TIMx->ARR = (uint32_t)val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void stp_stop(int n){ // stop motor by demand or @ end-switch
|
void stp_stop(int n){ // stop motor by demand or @ end-switch
|
||||||
@ -265,25 +242,30 @@ static void stpr_int(int n){
|
|||||||
}else return;
|
}else return;
|
||||||
switch(state[n]){
|
switch(state[n]){
|
||||||
case STP_ACCEL: // acceleration phase
|
case STP_ACCEL: // acceleration phase
|
||||||
arrval = TIMx->ARR - stpsteparr[n];
|
arrval = (uint16_t)TIMx->ARR - stpsteparr[n];
|
||||||
tmp = stplowarr[n];
|
tmp = stplowarr[n];
|
||||||
if(arrval <= tmp || arrval > stphigharr[n]){
|
if(arrval <= tmp || arrval > stphigharr[n]){
|
||||||
arrval = tmp;
|
arrval = tmp;
|
||||||
state[n] = STP_MOVE; // end of acceleration phase
|
state[n] = STP_MOVE; // end of acceleration phase
|
||||||
|
DBG("AccEnd\n");
|
||||||
}
|
}
|
||||||
TIMx->ARR = arrval;
|
TIMx->ARR = arrval;
|
||||||
break;
|
break;
|
||||||
case STP_DECEL: // deceleration phase
|
case STP_DECEL: // deceleration phase
|
||||||
arrval = TIMx->ARR + stpsteparr[n];
|
arrval = (uint16_t)TIMx->ARR + stpsteparr[n];
|
||||||
tmp = stphigharr[n];
|
tmp = stphigharr[n];
|
||||||
if(arrval >= tmp || arrval < stplowarr[n]){
|
if(arrval >= tmp || arrval < stplowarr[n]){
|
||||||
arrval = tmp;
|
arrval = tmp;
|
||||||
state[n] = STP_MVSLOW; // end of deceleration phase, move @ lowest speed
|
state[n] = STP_MVSLOW; // end of deceleration phase, move @ lowest speed
|
||||||
|
DBG("DecEnd\n");
|
||||||
}
|
}
|
||||||
TIMx->ARR = arrval;
|
TIMx->ARR = arrval;
|
||||||
break;
|
break;
|
||||||
case STP_MOVE: // moving with constant speed phases
|
case STP_MOVE: // moving with constant speed phases
|
||||||
if(steps_left[n] <= ACCDECSTEPS) state[n] = STP_DECEL; // change moving status to decelerate
|
if(steps_left[n] <= ACCDECSTEPS){
|
||||||
|
state[n] = STP_DECEL; // change moving status to decelerate
|
||||||
|
DBG("->Dec\n");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case STP_MVSLOW:
|
case STP_MVSLOW:
|
||||||
// nothing to do here: all done before switch()
|
// nothing to do here: all done before switch()
|
||||||
@ -296,6 +278,7 @@ static void stpr_int(int n){
|
|||||||
dir[n] = 0;
|
dir[n] = 0;
|
||||||
steps_left[n] = 0;
|
steps_left[n] = 0;
|
||||||
state[n] = STP_SLEEP;
|
state[n] = STP_SLEEP;
|
||||||
|
DBG("Stop\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,37 +0,0 @@
|
|||||||
[editor]
|
|
||||||
line_wrapping=false
|
|
||||||
line_break_column=100
|
|
||||||
auto_continue_multiline=true
|
|
||||||
|
|
||||||
[file_prefs]
|
|
||||||
final_new_line=true
|
|
||||||
ensure_convert_new_lines=true
|
|
||||||
strip_trailing_spaces=true
|
|
||||||
replace_tabs=true
|
|
||||||
|
|
||||||
[indentation]
|
|
||||||
indent_width=4
|
|
||||||
indent_type=0
|
|
||||||
indent_hard_tab_width=4
|
|
||||||
detect_indent=false
|
|
||||||
detect_indent_width=false
|
|
||||||
indent_mode=3
|
|
||||||
|
|
||||||
[project]
|
|
||||||
name=Steppers
|
|
||||||
base_path=/home/eddy/Docs/SAO/Zeiss-1000/Simple_photometer/STM32/
|
|
||||||
|
|
||||||
[long line marker]
|
|
||||||
long_line_behaviour=1
|
|
||||||
long_line_column=100
|
|
||||||
|
|
||||||
[files]
|
|
||||||
current_page=4
|
|
||||||
FILE_NAME_0=0;C;0;EUTF-8;0;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FZeiss-1000%2FSimple_photometer%2FSTM32%2Fmain.c;0;4
|
|
||||||
FILE_NAME_1=130;Make;0;EUTF-8;1;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FZeiss-1000%2FSimple_photometer%2FSTM32%2FMakefile;0;4
|
|
||||||
FILE_NAME_2=0;Markdown;0;EUTF-8;0;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FZeiss-1000%2FSimple_photometer%2FSTM32%2FReadme.md;0;4
|
|
||||||
FILE_NAME_3=0;C;0;EUTF-8;0;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FZeiss-1000%2FSimple_photometer%2FSTM32%2Fusart.c;0;4
|
|
||||||
FILE_NAME_4=0;C;0;EUTF-8;0;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FZeiss-1000%2FSimple_photometer%2FSTM32%2Fusart.h;0;4
|
|
||||||
|
|
||||||
[VTE]
|
|
||||||
last_dir=/home/eddy
|
|
||||||
@ -21,10 +21,16 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#ifndef __STEPPERS_H__
|
#ifndef STEPPERS_H__
|
||||||
#define __STEPPERS_H__
|
#define STEPPERS_H__
|
||||||
|
|
||||||
#include "stm32f0.h"
|
#include "stm32f0.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// the lowest speed equal to [max speed] / LOWEST_SPEED_DIV
|
||||||
|
#define LOWEST_SPEED_DIV (30)
|
||||||
|
// minimal value of ACCDECSTEPS
|
||||||
|
#define ACCDECSTEPS_MIN (30)
|
||||||
|
|
||||||
extern int32_t mot_position[];
|
extern int32_t mot_position[];
|
||||||
extern uint32_t steps_left[];
|
extern uint32_t steps_left[];
|
||||||
@ -54,12 +60,12 @@ typedef enum{
|
|||||||
#define stp_stepsleft(n) (steps_left[n])
|
#define stp_stepsleft(n) (steps_left[n])
|
||||||
|
|
||||||
stp_state stp_getstate(int motnum);
|
stp_state stp_getstate(int motnum);
|
||||||
void stp_setup();
|
void stp_setup(void);
|
||||||
void stp_chspd();
|
void stp_chspd(void);
|
||||||
stp_status stp_move(int nmotor, int32_t steps);
|
stp_status stp_move(int nmotor, int32_t steps);
|
||||||
void stp_stop(int n);
|
void stp_stop(int n);
|
||||||
void stp_process();
|
void stp_process(void);
|
||||||
void stp_disable();
|
void stp_disable(void);
|
||||||
void stp_chARR(int n, int32_t val);
|
void stp_chARR(int n, int32_t val);
|
||||||
|
|
||||||
#endif // __STEPPERS_H__
|
#endif // STEPPERS_H__
|
||||||
|
|||||||
@ -27,8 +27,8 @@ extern volatile uint32_t Tms;
|
|||||||
|
|
||||||
static int datalen[2] = {0,0}; // received data line length (including '\n')
|
static int datalen[2] = {0,0}; // received data line length (including '\n')
|
||||||
|
|
||||||
|
static int dlen = 0; // length of data (including '\n') in current buffer
|
||||||
int linerdy = 0, // received data ready
|
int linerdy = 0, // received data ready
|
||||||
dlen = 0, // length of data (including '\n') in current buffer
|
|
||||||
bufovr = 0, // input buffer overfull
|
bufovr = 0, // input buffer overfull
|
||||||
txrdy = 1 // transmission done
|
txrdy = 1 // transmission done
|
||||||
;
|
;
|
||||||
@ -113,7 +113,7 @@ void usart1_isr(){
|
|||||||
if(!tmout) tmout = 1; // prevent 0
|
if(!tmout) tmout = 1; // prevent 0
|
||||||
#endif
|
#endif
|
||||||
// read RDR clears flag
|
// read RDR clears flag
|
||||||
uint8_t rb = USART1->RDR;
|
char rb = (char)USART1->RDR;
|
||||||
if(datalen[rbufno] < UARTBUFSZ){ // put next char into buf
|
if(datalen[rbufno] < UARTBUFSZ){ // put next char into buf
|
||||||
rbuf[rbufno][datalen[rbufno]++] = rb;
|
rbuf[rbufno][datalen[rbufno]++] = rb;
|
||||||
if(rb == '\n'){ // got newline - line ready
|
if(rb == '\n'){ // got newline - line ready
|
||||||
@ -177,13 +177,13 @@ TXstatus usart1_send(char *str){
|
|||||||
return ALL_OK;
|
return ALL_OK;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
TXstatus usart1_send(char *str){
|
TXstatus usart1_send(const char *str){
|
||||||
if(!txrdy) return LINE_BUSY;
|
if(!txrdy) return LINE_BUSY;
|
||||||
int i;
|
if(*str == 0) return ALL_OK;
|
||||||
for(i = 0; i < UARTBUFSZ; ++i){
|
for(int i = 0; i < UARTBUFSZ; ++i){
|
||||||
char c = *str++;
|
char c = *str++;
|
||||||
if(c == 0){ c = '\n'; i = UARTBUFSZ;}
|
if(c == 0){c = '\n'; i = UARTBUFSZ;}
|
||||||
USART1->TDR = c;
|
USART1->TDR = (uint16_t)c;
|
||||||
while(!(USART1->ISR & USART_ISR_TXE));
|
while(!(USART1->ISR & USART_ISR_TXE));
|
||||||
}
|
}
|
||||||
txrdy = 1;
|
txrdy = 1;
|
||||||
|
|||||||
@ -19,10 +19,11 @@
|
|||||||
* MA 02110-1301, USA.
|
* MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#ifndef __USART_H__
|
#ifndef USART_H__
|
||||||
#define __USART_H__
|
#define USART_H__
|
||||||
|
|
||||||
#include "stm32f0.h"
|
#include "stm32f0.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
// input and output buffers size
|
// input and output buffers size
|
||||||
#define UARTBUFSZ (64)
|
#define UARTBUFSZ (64)
|
||||||
@ -43,19 +44,24 @@ typedef enum{
|
|||||||
extern int linerdy, bufovr, txrdy;
|
extern int linerdy, bufovr, txrdy;
|
||||||
extern int trbufidx;
|
extern int trbufidx;
|
||||||
|
|
||||||
void USART1_config();
|
void USART1_config(void);
|
||||||
int usart1_getline(char **line);
|
int usart1_getline(char **line);
|
||||||
TXstatus usart1_send(char *str);
|
TXstatus usart1_send(const char *str);
|
||||||
#define usart1_send_blocking(str) do{}while(LINE_BUSY == usart1_send(str))
|
#define usart1_send_blocking(str) do{}while(LINE_BUSY == usart1_send(str))
|
||||||
|
#ifdef EBUG
|
||||||
|
#define DBG(str) usart1_send_blocking(str)
|
||||||
|
#else
|
||||||
|
#define DBG(str)
|
||||||
|
#endif
|
||||||
#define SENDBUF() do{usart1_send_blocking(gettrbuf()); cleartrbuf();}while(0)
|
#define SENDBUF() do{usart1_send_blocking(gettrbuf()); cleartrbuf();}while(0)
|
||||||
|
|
||||||
#define cleartrbuf() do{trbufidx = 0;}while(0)
|
#define cleartrbuf() do{trbufidx = 0;}while(0)
|
||||||
#define trbufisfull() (trbufidx)
|
#define trbufisfull() (trbufidx)
|
||||||
int put2trbuf(char c);
|
int put2trbuf(char c);
|
||||||
int write2trbuf(const char *str);
|
int write2trbuf(const char *str);
|
||||||
char *gettrbuf();
|
char *gettrbuf(void);
|
||||||
int put_int(int32_t N);
|
int put_int(int32_t N);
|
||||||
int put_uint(uint32_t N);
|
int put_uint(uint32_t N);
|
||||||
|
|
||||||
|
|
||||||
#endif // __USART_H__
|
#endif // USART_H__
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user