diff --git a/Doc_rus/Readme.pdf b/Doc_rus/Readme.pdf index ba23c29..571f9ac 100644 Binary files a/Doc_rus/Readme.pdf and b/Doc_rus/Readme.pdf differ diff --git a/Doc_rus/Readme.tex b/Doc_rus/Readme.tex index b825575..796c12c 100644 --- a/Doc_rus/Readme.tex +++ b/Doc_rus/Readme.tex @@ -12,7 +12,7 @@ \nocolon \def\Z{Цейсс--1000\xspace} \title{Многорежимный фотометр--поляриметр (MMPP) телескопа \Z. Техническая документация.} -\author{Емельянов~Э.В. \and Фатхуллин~Т.А.} +\author{Емельянов~Э.В. \and Москвитин~А.С.\and Фатхуллин~Т.А.} \graphicspath{{./imgs/}} \begin{document} \maketitle @@ -20,7 +20,6 @@ \section{Описание прибора} - MMPP (Multi-Mode Photometer-Polarimeter) "--- многорежимный фотометр-поляриметр телескопа \Z предназначен для проведения фотометрических и поляриметрических исследований. Прибор оснащен двумя турелями USB-HSFW (Edmund Optics) с пятью позициями для 50-мм фильтров, анализатором линейной поляризации и @@ -673,11 +672,11 @@ PF1 & PUPD & посылок экстренного останова, сброса и т.п.). После идентификатора контроллера следует текст команды и (опционально) ее аргументы. В случае, если команда -валидна, контроллер возвращает строку <>. Если команда не распознана, возвращается маркер ошибки +валидна, контроллер возвращает строку <>. Если команда не распознана, возвращается маркер ошибки <>. В случае же ошибок в аргументах команды возвращается маркер ошибки <>. Если команда -возвращает какую-либо информацию, она следует сразу за маркером <>. Данные, занимающие более одной +возвращает какую-либо информацию, она следует сразу за маркером <>. Данные, занимающие более одной строки текста, завершаются маркером <>. Если команда лишь требует выполнения определенного действия, -маркер <> возвращается после установления возможности выполнения данного действия. В силу синхронного +маркер <> возвращается после установления возможности выполнения данного действия. В силу синхронного характера интерфейса связи, команды, требующие длительного времени на исполнение (например, перемещение объекта) не выводят в случае ошибки или достижения заданного положения никаких данных, процесс их исполнения необходимо контролировать периодическим запросом состояния модуля. @@ -716,21 +715,24 @@ PF1 & PUPD & \item[\itm{C}] получение текущих значений параметров конфигурации, например, \begin{verbatim} CONFSZ=36 -DEVID=0 -V12NUM=1 -V12DEN=10 -I12NUM=1 -I12DEN=1 +DEVID=2 +V12NUM=605 +V12DEN=94 +I12NUM=3 +I12DEN=4 V33NUM=1 V33DEN=1 -ESWTHR=150 -MOT0SPD=60 -MOT1SPD=60 -USARTSPD=115200 +ESWTHR=500 +MOT0SPD=3 +MOT1SPD=2 +MAXSTEPS0=50000 +MAXSTEPS1=50000 +USARTSPD=9600 +INTPULLUP=1 REVERSE0=0 -REVERSE1=0 -MAXSTEPS0=0 -MAXSTEPS1=0 +REVERSE1=1 +USTEPS=16 +ACCDECSTEPS=50 DATAEND \end{verbatim} @@ -745,12 +747,12 @@ DATAEND \end{description} например, \begin{verbatim} -ADC[0]=4095 -ADC[1]=2340 -ADC[2]=4095 -ADC[3]=4087 -ADC[4]=1665 -ADC[5]=1532 +ADC[0]=189 +ADC[1]=2317 +ADC[2]=4088 +ADC[3]=4090 +ADC[4]=1703 +ADC[5]=1525 DATAEND \end{verbatim} @@ -837,25 +839,32 @@ ESW11=HALL проведенных изменений и их проверки. \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{Dxnum}] установка знаменателя (\textbf{d}enominator) величины \textbf{x} (D, I или M~-- в - соответствии с геттером значения измерений АЦП) в \textbf{num}; -\item[\itm{Exnum}] установка числителя (num\textbf{e}rator) (аналогично \textbf{Dxnum}); -\item[\itm{I num}] изменение значения идентификатора (целое число) контроллера; -\item[\itm{M\#num}] установка максимального диапазона (\textbf{num} от~1 до~65535) шагового двигателя - \textbf{\#}; -\item[\itm{P num}] включение (\textbf{num} равно нулю) или отключение (\textbf{num} отсутствует или любое, - кроме нуля) внутренней подтяжки на UART Tx; -\item[\itm{R\#num}] реверсивное движение двигателя \textbf{\#} (\textbf{num} равное нулю отключает реверс), - в режиме реверса меняется только направление вращения двигателя, но не обрабатываемые концевики; -\item[\itm{S\#num}] изменение значения максимальной скорости двигателя с номером \textbf{\#} на \textbf{num} - (максимальная скорость устанавливается после окончания движения с ускорением и не зависит от - текущей скорости, \textbf{C\#num}); -\item[\itm{T num}] изменение пороговых величин (\textbf{num} в ADU) для градации состояний концевика - двигателя~0 (0..num~-- датчик Холла, 2048-num..2048+num~-- пользовательская кнопка, +\item[\itm{Dvnum}] установка знаменателя (\textbf{d}enominator, \verb'xxxDEN') величины \textbf{v} (D, I или + M~-- в соответствии с геттером значения измерений АЦП) в \textbf{num}; +\item[\itm{Evnum}] установка числителя (num\textbf{e}rator, \verb'xxxNUM') (аналогично \textbf{Dvnum}); +\item[\itm{I num}] изменение значения идентификатора (\verb'DEVID', целое число) контроллера; +\item[\itm{M\#num}] установка максимального диапазона (\verb'MAXSTEPS#', \textbf{num} от~1 до~65535) шагового + двигателя \textbf{\#}; +\item[\itm{P num}] (\verb'INTPULLUP') включение (\textbf{num} равно нулю) или отключение (\textbf{num} + отсутствует или любое, кроме нуля) внутренней подтяжки на UART Tx; +\item[\itm{R\#num}] (\verb'REVERSE#') реверсивное движение двигателя \textbf{\#} (\textbf{num} равное нулю + отключает реверс), в режиме реверса меняется только направление вращения двигателя, но не + обрабатываемые концевики; +\item[\itm{S\#num}] изменение значения максимальной скорости (\verb'MOT#SPD') двигателя с номером + \textbf{\#} на \textbf{num} (максимальная скорость устанавливается после окончания движения с + ускорением и не зависит от текущей скорости, \textbf{C\#num}); +\item[\itm{T num}] изменение пороговых величин (\verb'ESWTHR', \textbf{num} в ADU) для градации состояний + концевика двигателя~0 (0..num~-- датчик Холла, 2048-num..2048+num~-- пользовательская кнопка, 4096-num..4095~-- свободное состояние); -\item[\itm{U num}] изменение скорости UART. +\item[\itm{U num}] изменение скорости UART (\verb'USARTSPD'); +\item[\itm{u num}] установка количества микрошагов (\verb'USTEPS') в одном шаге; это число должно быть + степенью двойки (до~32 включительно). \end{description} \paragraph{Сеттеры скорости двигателей.} @@ -925,10 +934,12 @@ MOT0SPD=3 MOT1SPD=5 MAXSTEPS0=50000 MAXSTEPS1=50000 +USARTSPD=9600 INTPULLUP=1 -USARTSPD=115200 REVERSE0=1 REVERSE1=0 +USTEPS=16 +ACCDECSTEPS=50 DATAEND MMPP_control -a 2GC @@ -947,10 +958,12 @@ MOT0SPD=3 MOT1SPD=2 MAXSTEPS0=50000 MAXSTEPS1=50000 +USARTSPD=9600 INTPULLUP=1 -USARTSPD=115200 REVERSE0=0 REVERSE1=1 +USTEPS=16 +ACCDECSTEPS=50 DATAEND \end{lstlisting} @@ -959,11 +972,13 @@ DATAEND изменение уровня на концевиках двигателя~0, \verb'MOTxSPD' (предельные скорости соответствующих двигателей), \verb'MAXSTEPSx' (максимальное количество шагов данного двигателя), \verb'INTPULLUP' (при отсутствии внешней подтяжки шины~Tx контроллеров отключенная подтяжка приведет к неработоспособности), \verb'USARTSPD' (скорость -шины UART) и \verb'REVERSEx' (направление вращения двигателя). +шины UART), \verb'REVERSEx' (направление вращения двигателя) и \verb'ACCDECSTEPS' (количество шагов для +ускорения\slash замедления движения). \paragraph{Значения предельных токов DRV8825.} \label{MotCurrents} Предельные токи определяются по уровню напряжения на подстроечных резисторах DRV8825. -\TODO[ТОКИ!] +Анализатор поляризации: M0 (подвижка) 0.5\,В, M1 (ротатор) 3.1\,В. +Фазовая пластина: M0 (подвижка) 0.9\,В, M1 (ротатор) 0.25\,В. \comment[ФОТО!]{добавить табличку со значениями напряжений + фотографию, как настраивать} \end{document} diff --git a/STM32/steppers/Makefile b/STM32/steppers/Makefile index a7b076b..69944e3 100644 --- a/STM32/steppers/Makefile +++ b/STM32/steppers/Makefile @@ -52,7 +52,7 @@ LIB_DIR := $(INC_DIR)/ld CFLAGS += -O2 -g -MD -D__thumb2__=1 CFLAGS += -Wall -Werror -Wextra -Wshadow -Wimplicit-function-declaration CFLAGS += -Wredundant-decls $(INCLUDE) -# -Wmissing-prototypes -Wstrict-prototypes +#-Wmissing-prototypes -Wstrict-prototypes CFLAGS += -fno-common -ffunction-sections -fdata-sections ############################################################################### @@ -71,10 +71,6 @@ LDLIBS += $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) DEFS += -DSTM32$(FAMILY) -DSTM32$(MCU) -#.SUFFIXES: .elf .bin .hex .srec .list .map .images -#.SECONDEXPANSION: -#.SECONDARY: - ELF := $(OBJDIR)/$(BINARY).elf LIST := $(OBJDIR)/$(BINARY).list BIN := $(BINARY).bin @@ -101,9 +97,6 @@ $(OBJDIR)/%.o: %.c @echo " CC $<" $(CC) $(CFLAGS) $(DEFS) $(INCLUDE) $(ARCH_FLAGS) -o $@ -c $< -#$(OBJDIR)/%.d: %.c $(OBJDIR) -# $(CC) -MM -MG $< | sed -e 's,^\([^:]*\)\.o[ ]*:,$(@D)/\1.o $(@D)/\1.d:,' >$@ - $(BIN): $(ELF) @echo " OBJCOPY $(BIN)" $(OBJCOPY) -Obinary $(ELF) $(BIN) diff --git a/STM32/steppers/Readme.md b/STM32/steppers/Readme.md index 2e9c4fa..3648940 100644 --- a/STM32/steppers/Readme.md +++ b/STM32/steppers/Readme.md @@ -148,7 +148,7 @@ Getters returning more than one field ends with `DATAEND` meaning that's all dat ### 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: * **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 *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 # -* **D num** - set *denominator* to number *num* -* **E num** - set *numerator* +* **D$num** - set *denominator $* (*D* - Vdd, *I* - current, *M* - 12V) to number *num* +* **E$num** - set *numerator $* * **I num** - set *device ID* * **M#num** - set maxsteps (*num* is 1..65535) for motor `#` * **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 and 4096 for released state) * **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 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 Have naxt letter similar to ADC getter (**D** - Vdd, **I** - motors' I, or **M** - motors' U). diff --git a/STM32/steppers/adc.c b/STM32/steppers/adc.c index 643c9b9..5848397 100644 --- a/STM32/steppers/adc.c +++ b/STM32/steppers/adc.c @@ -20,18 +20,18 @@ * MA 02110-1301, USA. * */ -#include "stm32f0.h" -#include "flash.h" #include "adc.h" +#include "flash.h" +#include "stm32f0.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 VddValue = 0; // value of Vdd * 100 (for more precision measurements) // 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 * 1 - Input voltage 12V * 2 - EndSwitch2 of motor1 @@ -39,7 +39,32 @@ static uint32_t VddValue = 0; // value of Vdd * 100 (for more precision measurem * 4 - inner temperature * 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(){ // 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) */ DMA1_Channel1->CPAR = (uint32_t) (&(ADC1->DR)); /* (3) */ 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_EN; /* (7) */ ADC1->CR |= ADC_CR_ADSTART; /* start the ADC conversions */ @@ -96,90 +121,18 @@ void adc_setup(){ int32_t getTemp(){ CHKVDDTIME(); // make correction on Vdd value - int32_t temperature = (int32_t)ADC_array[4] * VddValue / 330; -/* -write2trbuf("getTemp()\ncal30="); -put_uint(*TEMP30_CAL_ADDR); -write2trbuf(", cal110="); -put_uint(*TEMP110_CAL_ADDR); -write2trbuf(", t="); -put_int(temperature); -SENDBUF(); -*/ + int32_t temperature = (int32_t)getADCval(4) * (int32_t)VddValue / 330; temperature = (int32_t) *TEMP30_CAL_ADDR - temperature; -/* -put_int(temperature); -SENDBUF(); -*/ temperature *= (int32_t)(1100 - 300); -/* -put_int(temperature); -SENDBUF(); -*/ temperature = temperature / (int32_t)(*TEMP30_CAL_ADDR - *TEMP110_CAL_ADDR); -/* -put_int(temperature); -SENDBUF(); -*/ temperature += 300; return(temperature); } // return Vdd * 100 (V) 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 -/* -put_uint(vdd); -SENDBUF(); -*/ - vdd /= v * the_conf.v33denominator; -/* -put_uint(vdd); -SENDBUF(); -*/ + vdd /= getADCval(5) * the_conf.v33denominator; lastVddtime = Tms; VddValue = vdd; return vdd; @@ -188,7 +141,7 @@ SENDBUF(); // return value of 12V * 100 (V) uint32_t getVmot(){ CHKVDDTIME(); - uint32_t vmot = ADC_array[1] * VddValue * the_conf.v12numerator; + uint32_t vmot = getADCval(1) * VddValue * the_conf.v12numerator; vmot >>= 12; vmot /= the_conf.v12denominator; return vmot; @@ -197,7 +150,7 @@ uint32_t getVmot(){ // return value of motors' current * 100 (A) uint32_t getImot(){ CHKVDDTIME(); - uint32_t vmot = ADC_array[0] * VddValue * the_conf.i12numerator; + uint32_t vmot = getADCval(0) * VddValue * the_conf.i12numerator; vmot >>= 12; vmot /= the_conf.i12denominator; return vmot; @@ -220,7 +173,7 @@ ESW_status eswStatus(int motnum, int eswnum){ if(eswnum) idx = 2; 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 if(val < thres) return ESW_HALL; // high signal: (4096-thres)..4096 - pullup diff --git a/STM32/steppers/adc.h b/STM32/steppers/adc.h index 4503234..3f5c9eb 100644 --- a/STM32/steppers/adc.h +++ b/STM32/steppers/adc.h @@ -22,14 +22,15 @@ */ #pragma once -#ifndef __ADC_H__ -#define __ADC_H__ +#ifndef ADC_H__ +#define ADC_H__ -// 8 channels (including inttemp & vrefint) +#include + +// 6 channels (including inttemp & vrefint) #define NUMBER_OF_ADC_CHANNELS (6) -extern uint16_t ADC_array[]; -void adc_setup(); +extern volatile uint32_t Tms; // time counter for 1-second Vdd measurement typedef enum{ ESW_RELEASED, @@ -38,10 +39,12 @@ typedef enum{ ESW_ERROR } ESW_status; -int32_t getTemp(); -uint32_t getVdd(); -uint32_t getVmot(); -uint32_t getImot(); -ESW_status eswStatus(int motnum, int eswnum); +void adc_setup(void); +uint16_t getADCval(int nch); +int32_t getTemp(void); +uint32_t getVdd(void); +uint32_t getVmot(void); +uint32_t getImot(void); +ESW_status eswStatus(int motnum, int eswnum); -#endif // __ADC_H__ +#endif // ADC_H__ diff --git a/STM32/steppers/flash.c b/STM32/steppers/flash.c index 109e619..bf22aad 100644 --- a/STM32/steppers/flash.c +++ b/STM32/steppers/flash.c @@ -41,31 +41,23 @@ user_conf the_conf = { ,.v33denominator = 1 ,.v33numerator = 1 ,.ESW_thres = 500 - ,.usartspd = (uint32_t)115200 - ,.motspd = {10, 10} // max speed: 300 steps per second + ,.usartspd = (uint32_t)9600 + ,.motspd = {10, 10} // max speed: 300 steps per second, should be LESS than 1310! ,.maxsteps = {50000, 50000} // max steps from point to point ,.reverse = {0,0} // set DIR to this value when moving to '+' ,.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(){ user_conf *c = (user_conf*) FLASH_CONF_START_ADDR; // have data - move it to `the_conf` int idx; -//write2trbuf("get_gooddata()\n"); for(idx = 0; idx < maxnum; ++idx){ // find current settings index - first good 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 == 0xffff) break; // first clear else{ @@ -93,9 +85,6 @@ int store_userconf(){ idx = 0; if(erase_flash()) return 1; }else ++idx; // take next data position -/*write2trbuf("store_userconf()\nidx="); -put_int((int32_t) idx); -SENDBUF();*/ if (FLASH->CR & FLASH_CR_LOCK){ // unloch flash FLASH->KEYR = FLASH_FKEY1; FLASH->KEYR = FLASH_FKEY2; @@ -106,23 +95,12 @@ SENDBUF();*/ FLASH->CR |= FLASH_CR_PG; uint16_t *data = (uint16_t*) &the_conf; 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){ *(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 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->CR &= ~(FLASH_CR_PG); @@ -132,17 +110,12 @@ SENDBUF(); static int erase_flash(){ int ret = 0; -/*write2trbuf("erase_flash()"); -SENDBUF();*/ /* (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_WRPERR; /* (2) */ - /* if (FLASH->SR & FLASH_SR_EOP){ - FLASH->SR |= FLASH_SR_EOP; - }*/ if ((FLASH->CR & FLASH_CR_LOCK) != 0){ /* (3) */ FLASH->KEYR = FLASH_FKEY1; /* (4) */ FLASH->KEYR = FLASH_FKEY2; diff --git a/STM32/steppers/flash.h b/STM32/steppers/flash.h index 0efa755..fde7538 100644 --- a/STM32/steppers/flash.h +++ b/STM32/steppers/flash.h @@ -22,30 +22,41 @@ */ #pragma once -#ifndef __FLASH_H__ -#define __FLASH_H__ +#ifndef FLASH_H__ +#define FLASH_H__ + +#include typedef struct{ - uint16_t userconf_sz; // size of data - 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 v12numerator; // 12V to motors + uint16_t userconf_sz; // size of data + uint16_t devID; // device address (id) + + uint16_t ESW_thres; // ADC threshold for end-switches/Hall sensors + uint16_t v12numerator; // 12V to motors + uint16_t v12denominator; - uint16_t i12numerator; // motors' current + uint16_t i12numerator; // motors' current + 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; - uint32_t usartspd; // usartspeed - 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 reverse[2]; // == 1 if positive direction when DIR is low - uint8_t intpullup; // internal pullup @ Tx + uint8_t reverse[2]; // == 1 if positive direction when DIR is low + + uint8_t intpullup; // internal pullup @ Tx + uint8_t usteps; // amount of microsteps in each step + uint8_t accdecsteps; // amount of steps need for full acceleration/deceleration cycle } user_conf; extern user_conf the_conf; -void get_userconf(); -int store_userconf(); +void get_userconf(void); +int store_userconf(void); -#endif // __FLASH_H__ +#endif // FLASH_H__ diff --git a/STM32/steppers/main.c b/STM32/steppers/main.c index d668836..49cee6c 100644 --- a/STM32/steppers/main.c +++ b/STM32/steppers/main.c @@ -19,12 +19,12 @@ * MA 02110-1301, USA. */ -#include "stm32f0.h" -#include "usart.h" #include "adc.h" #include "flash.h" #include "proto.h" #include "steppers.h" +#include "stm32f0.h" +#include "usart.h" volatile uint32_t Tms = 0; @@ -85,13 +85,14 @@ void iwdg_setup(){ } int main(void){ - uint32_t lastT = 0; + //uint32_t lastT = 0; uint32_t ostctr = 0; #if 0 //def EBUG uint32_t msgctr = 0; #endif char *txt = NULL; + const char *ret = NULL; sysreset(); SysTick_Config(6000, 1); get_userconf(); @@ -103,17 +104,13 @@ int main(void){ //pin_set(GPIOA, 1<<5); // clear extern LED while (1){ IWDG->KR = IWDG_REFRESH; // refresh watchdog - if(lastT > Tms || Tms - lastT > 499){ -/* #ifdef EBUG - pin_toggle(GPIOA, 1<<4); // blink by onboard LED once per second - #endif -*/ + /*if(lastT > Tms || Tms - lastT > 499){ lastT = Tms; - } + }*/ if(usart1rx()){ // usart1 received data, store in in buffer if(usart1_getline(&txt)){ - txt = process_command(txt); - }else txt = NULL; // buffer overflow + ret = process_command(txt); + }else ret = NULL; // buffer overflow } #if 0 //def EBUG @@ -122,15 +119,9 @@ int main(void){ txt = "hello, I'm alive!\n"; } #endif - /* - if(trbufisfull()){ - write2trbuf("ERR"); - usart1_send_blocking(gettrbuf()); - } - cleartrbuf();*/ - if(txt){ // text waits for sending - if(ALL_OK == usart1_send(txt)){ - txt = NULL; + if(ret){ // text waits for sending + if(ALL_OK == usart1_send(ret)){ + ret = NULL; } } if(ostctr != Tms){ // check steppers not frequently than once in 1ms diff --git a/STM32/steppers/proto.c b/STM32/steppers/proto.c index 64a5666..b99306f 100644 --- a/STM32/steppers/proto.c +++ b/STM32/steppers/proto.c @@ -20,41 +20,43 @@ * MA 02110-1301, USA. * */ -#include "stm32f0.h" -#include "proto.h" #include "adc.h" #include "flash.h" +#include "proto.h" +#include "steppers.h" +#include "stm32f0.h" #include "string.h" #include "usart.h" -#include "steppers.h" static const char *eodata = "DATAEND"; static const char *badcmd = "BADCMD"; -static const char *allok = "ALL OK"; +static const char *allok = "ALLOK"; static const char *err = "ERR"; -#define EODATA ((char*)eodata) -#define BADCMD ((char*)badcmd) -#define ALLOK ((char*)allok) -#define ERR ((char*)err) +#define EODATA (eodata) +#define BADCMD (badcmd) +#define ALLOK (allok) +#define ERR (err) -static char *getnum(char *buf, int32_t *N); -static char *get_something(char *str); -static char *set_something(char *str); -static char *motor_cmd(char *str); +static const char *getnum(const char *buf, int32_t *N); +static const char *get_something(const char *str); +static const char *set_something(const char *str); +static const char *motor_cmd(const char *str); -static char *get_status(); -static char *get_conf(); -static char *get_raw_adc(); -static char *get_ADCval(char *str); -static char *get_temper(); +static const char *get_status(void); +static const char *get_conf(void); +static const char *get_raw_adc(void); +static const char *get_ADCval(const char *str); +static const char *get_temper(void); -static char *setDenEn(uint8_t De, char *str); -static char *setDevId(char *str); -static char *setESWthres(char *str); -static char *setUSARTspd(char *str); -static char *setmotvals(char v, char *str); -static char *setMotSpeed(int cur, char *str); +static const char *setDenEn(uint8_t De, const char *str); +static const char *setDevId(const char *str); +static const char *setESWthres(const char *str); +static const char *setUSARTspd(const char *str); +static const char *setUSTEPS(const 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) @@ -62,9 +64,10 @@ static char *setMotSpeed(int cur, char *str); * get input buffer `cmdbuf`, parse it and change system state * @return message to send */ -char* process_command(char *cmdbuf){ +const char* process_command(const char *cmdbuf){ int32_t num; - char *str, c; + const char *str; + char c; #ifdef EBUG usart1_send_blocking(cmdbuf); #endif @@ -99,7 +102,7 @@ char* process_command(char *cmdbuf){ // 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 -static char *getnum(char *buf, int32_t *N){ +static const char *getnum(const char *buf, int32_t *N){ char c; int positive = -1; int32_t val = 0; @@ -130,7 +133,7 @@ static char *getnum(char *buf, int32_t *N){ // get conf (uint16_t) number // @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; if(!getnum(buf, &N32)) return 1; if(N32 > 0xffff || N32 < 0) return 1; @@ -138,7 +141,7 @@ static int getu16(char *buf, uint16_t *N){ return 0; } -static char *get_something(char *str){ +static const char *get_something(const char *str){ switch(*str++){ case 'A': // get ADC value: voltage or current return get_ADCval(str); @@ -159,8 +162,7 @@ static char *get_something(char *str){ return BADCMD; } -static char *get_status(){ - int i, j; +static const char *get_status(){ char str[3] = {0, '=', 0}; if(RCC->CSR & RCC_CSR_IWDGRSTF){ // watchdog reset occured write2trbuf("WDGRESET=1\n"); @@ -169,7 +171,7 @@ static char *get_status(){ write2trbuf("SOFTRESET=1\n"); } 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(str); stp_state stt = stp_getstate(i); @@ -212,7 +214,7 @@ static char *get_status(){ write2trbuf(str); put_int(stp_position(i)); SENDBUF(); - for(j = 0; j < 2; ++j){ + for(int8_t j = 0; j < 2; ++j){ write2trbuf("ESW"); put2trbuf('0' + i); put2trbuf('0' + j); put2trbuf('='); ESW_status stat = eswStatus(i, j); @@ -242,24 +244,38 @@ typedef struct{ const uint16_t *ptr; } user_conf_descr; +typedef struct{ + const char *fieldname; + const uint8_t *ptr; +} user_conf_descr8; + static const user_conf_descr descrarr[] = { - {"CONFSZ", &the_conf.userconf_sz}, - {"DEVID", &the_conf.devID}, - {"V12NUM", &the_conf.v12numerator}, - {"V12DEN", &the_conf.v12denominator}, - {"I12NUM", &the_conf.i12numerator}, - {"I12DEN", &the_conf.i12denominator}, - {"V33NUM", &the_conf.v33numerator}, - {"V33DEN", &the_conf.v33denominator}, - {"ESWTHR", &the_conf.ESW_thres}, - {"MOT0SPD",&the_conf.motspd[0]}, - {"MOT1SPD",&the_conf.motspd[1]}, - {"MAXSTEPS0",&the_conf.maxsteps[0]}, - {"MAXSTEPS1",&the_conf.maxsteps[1]}, + {"CONFSZ", &the_conf.userconf_sz}, + {"DEVID", &the_conf.devID}, + {"V12NUM", &the_conf.v12numerator}, + {"V12DEN", &the_conf.v12denominator}, + {"I12NUM", &the_conf.i12numerator}, + {"I12DEN", &the_conf.i12denominator}, + {"V33NUM", &the_conf.v33numerator}, + {"V33DEN", &the_conf.v33denominator}, + {"ESWTHR", &the_conf.ESW_thres}, + {"MOT0SPD", &the_conf.motspd[0]}, + {"MOT1SPD", &the_conf.motspd[1]}, + {"MAXSTEPS0", &the_conf.maxsteps[0]}, + {"MAXSTEPS1", &the_conf.maxsteps[1]}, {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; do{ write2trbuf(curdesc->fieldname); @@ -267,32 +283,31 @@ static char *get_conf(){ put_uint((uint32_t) *curdesc->ptr); SENDBUF(); }while((++curdesc)->fieldname); - write2trbuf("INTPULLUP="); - put2trbuf(the_conf.intpullup ? '1' : '0'); - write2trbuf("\nUSARTSPD="); + const user_conf_descr8 *curdesc8 = descrarr8; + write2trbuf("USARTSPD="); put_uint(the_conf.usartspd); SENDBUF(); - write2trbuf("REVERSE0="); - put_uint(the_conf.reverse[0]); - write2trbuf("\nREVERSE1="); - put_uint(the_conf.reverse[1]); - SENDBUF(); + do{ + write2trbuf(curdesc8->fieldname); + put2trbuf('='); + put_uint((uint32_t) *curdesc8->ptr); + SENDBUF(); + }while((++curdesc8)->fieldname); return EODATA; } -static char *get_raw_adc(){ - int i; - for(i = 0; i < NUMBER_OF_ADC_CHANNELS; ++i){ +static const char *get_raw_adc(){ + for(int8_t i = 0; i < NUMBER_OF_ADC_CHANNELS; ++i){ write2trbuf("ADC["); put2trbuf('0' + i); write2trbuf("]="); - put_uint((uint32_t) ADC_array[i]); + put_uint((uint32_t) getADCval(i)); SENDBUF(); } return EODATA; } -static char *get_ADCval(char *str){ +static const char *get_ADCval(const char *str){ uint32_t v; switch(*str){ case 'D': // vdd @@ -315,7 +330,7 @@ static char *get_ADCval(char *str){ return NULL; } -static char *get_temper(){ +static const char *get_temper(){ int32_t t = getTemp(); write2trbuf("TEMP="); put_int(t); @@ -323,8 +338,11 @@ static char *get_temper(){ return NULL; } -static char *set_something(char *str){ +static const char *set_something(const char *str){ switch(*str++){ + case 'A': // set accdecsteps + return setACCDEC(str); + break; case 'C': // set current speed return setMotSpeed(1, str); break; @@ -358,6 +376,9 @@ static char *set_something(char *str){ case 'U': // set USART speed return setUSARTspd(str); break; + case 'u': // set usteps + return setUSTEPS(str); + break; } return BADCMD; } @@ -367,7 +388,7 @@ static char *set_something(char *str){ * @param De == 1 for denominator, == 0 for numerator * @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; switch(*str++){ case 'D': @@ -387,19 +408,19 @@ static char *setDenEn(uint8_t De, char *str){ return ALLOK; } -static char *setDevId(char *str){ +static const char *setDevId(const char *str){ omitwsp(str); if(getu16(str, &the_conf.devID)) return BADCMD; return ALLOK; } -static char *setESWthres(char *str){ +static const char *setESWthres(const char *str){ omitwsp(str); if(getu16(str, &the_conf.ESW_thres)) return BADCMD; return ALLOK; } -static char *setUSARTspd(char *str){ +static const char *setUSARTspd(const char *str){ omitwsp(str); int32_t N32; 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 -static char *setMotSpeed(int cur, char *str){ +static const char *setMotSpeed(int cur, const char *str){ omitwsp(str); - uint8_t Num = *str++ - '0'; + uint8_t Num = (uint8_t)(*str++ - '0'); if(Num > 1) return ERR; int32_t spd; omitwsp(str); - if(!getnum(str, &spd)) return ERR; - if(spd < 2 || spd > 6553) return "BadSpd"; + if(!getnum(str, &spd)) return BADCMD; + if(spd < 2 || spd > (0xffff/LOWEST_SPEED_DIV)) return ERR; if(cur){ // change current speed stp_chARR(Num, spd); }else{ - the_conf.motspd[Num] = spd; + the_conf.motspd[Num] = (uint16_t)spd; stp_chspd(); } return ALLOK; } // set other motor values -static char *setmotvals(char v, char *str){ +static const char *setmotvals(char v, const char *str){ omitwsp(str); - uint8_t Num = *str++ - '0'; + uint8_t Num = (uint8_t)(*str++ - '0'); if(Num > 1) return ERR; omitwsp(str); int32_t val; - if(!getnum(str, &val)) return ERR; - if(val < 0 || val > 0xffff) return "BadUINT16"; + if(!getnum(str, &val)) return BADCMD; + if(val < 0 || val > 0xffff) return ERR; switch(v){ case 'M': // maxsteps if(val == 0) return ERR; - the_conf.maxsteps[Num] = val; + the_conf.maxsteps[Num] = (uint16_t)val; break; case 'R': // reverse if(val && val != 1) return ERR; - the_conf.reverse[Num] = val; + the_conf.reverse[Num] = (uint8_t)val; break; default: return ERR; } @@ -449,12 +470,12 @@ static char *setmotvals(char v, char *str){ } // process motor command: start/stop -static char *motor_cmd(char *str){ +static const char *motor_cmd(const char *str){ omitwsp(str); - uint8_t Num = *str++ - '0'; + uint8_t Num = (uint8_t)(*str++ - '0'); int32_t steps; stp_status st; - if(Num > 1) return "Num>1"; + if(Num > 1) return ERR; omitwsp(str); switch(*str++){ case 'M': @@ -485,3 +506,34 @@ static char *motor_cmd(char *str){ } 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; +} diff --git a/STM32/steppers/proto.h b/STM32/steppers/proto.h index 405d7cf..d76e8f4 100644 --- a/STM32/steppers/proto.h +++ b/STM32/steppers/proto.h @@ -21,9 +21,9 @@ * */ #pragma once -#ifndef __PROTO_H__ -#define __PROTO_H__ +#ifndef PROTO_H__ +#define PROTO_H__ -char* process_command(char *cmdbuf); +const char* process_command(const char *cmdbuf); -#endif // __PROTO_H__ +#endif // PROTO_H__ diff --git a/STM32/steppers/rme.html b/STM32/steppers/rme.html index 21e9901..286f3ec 100644 --- a/STM32/steppers/rme.html +++ b/STM32/steppers/rme.html @@ -237,7 +237,7 @@ just ALL OK if succeed.

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:

    @@ -261,9 +261,10 @@ There’s only two commands in this section:

    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 #
    • -
    • D num - set denominator to number num
    • -
    • E num - set numerator
    • +
    • D$num - set denominator $ (D - Vdd, I - current, M - 12V) to number num
    • +
    • E$num - set numerator $
    • I num - set device ID
    • M#num - set maxsteps (num is 1..65535) for motor #
    • P num - properties of internal pullup (0 - disabled, other or without num - enabled)
    • @@ -272,13 +273,14 @@ There’s only two commands in this section:

    • T num - set end-switches threshold (in ADU, near 0 for Hall switch, 2048 for user button and 4096 for released state)
    • 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

    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

    diff --git a/STM32/steppers/steppers.bin b/STM32/steppers/steppers.bin index 39d0ced..ae9c948 100755 Binary files a/STM32/steppers/steppers.bin and b/STM32/steppers/steppers.bin differ diff --git a/STM32/steppers/steppers.c b/STM32/steppers/steppers.c index e0ad321..a198bc7 100644 --- a/STM32/steppers/steppers.c +++ b/STM32/steppers/steppers.c @@ -27,9 +27,9 @@ #include "usart.h" // amount of steps need for full acceleration/deceleration cycle -#define ACCDECSTEPS (50) +#define ACCDECSTEPS (the_conf.accdecsteps) // amount of microsteps in each step -#define USTEPS (16) +#define USTEPS (the_conf.usteps) static GPIO_TypeDef* const MPORT[2] = {GPIOF, GPIOA}; 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){ uint16_t spd = the_conf.motspd[i]; stplowarr[i] = spd; - stphigharr[i] = spd * 10; - stpsteparr[i] = (spd * 9) / ACCDECSTEPS + 1; + stphigharr[i] = spd * LOWEST_SPEED_DIV; + stpsteparr[i] = (spd * (LOWEST_SPEED_DIV - 1)) / ((uint16_t)ACCDECSTEPS) + 1; } } @@ -106,34 +106,25 @@ void stp_process(){ esw[0] = eswStatus(0, 0); esw[1] = eswStatus(0, 1); if(esw[0] == ESW_BUTTON || esw[1] == ESW_BUTTON){ - if(lastbtnpressed++ == 3){ // stop all motors @ button -//~ write2trbuf("1stpress"); -//~ SENDBUF(); + if(lastbtnpressed++ == 5){ // stop all motors @ button uint8_t stopped = 0; if(state[0] != STP_SLEEP){ -//~ write2trbuf("stopmot0"); -//~ SENDBUF(); state[0] = STP_STOP; stopped = 1; } if(state[1] != STP_SLEEP){ -//~ write2trbuf("stopmot1"); -//~ SENDBUF(); state[1] = STP_STOP; stopped = 1; } - if(stopped) lastbtnpressed = 111; // override value - }else if(lastbtnpressed == 100){ // one or both buttons pressed, run only after ~100ms -//~ write2trbuf("lastbtnpressed"); -//~ SENDBUF(); + if(stopped){ + DBG("S(btn)\n"); + lastbtnpressed = 51; // override value + } + }else if(lastbtnpressed == 50){ // one or both buttons pressed, run only after ~100ms if(esw[0] == ESW_BUTTON && esw[1] == ESW_BUTTON){ -//~ write2trbuf("both"); -//~ SENDBUF(); // both buttons pressed - move MOTOR1 to zero state[1] = STP_MOVE0; }else{ // move motor 0 to 0 or 1 -//~ write2trbuf("single"); -//~ SENDBUF(); if(esw[0] == ESW_BUTTON) state[0] = STP_MOVE0; else state[0] = STP_MOVE1; } @@ -148,35 +139,21 @@ void stp_process(){ case STP_MOVE0: // move towards zero endswitch state[i] = STP_SLEEP; stp_move(i, -the_conf.maxsteps[i]); // won't move if the_conf.maxsteps == 0 -//~ write2trbuf("MOTOR"); -//~ put2trbuf('0'+i); -//~ write2trbuf(" move0"); -//~ SENDBUF(); break; case STP_MOVE1: state[i] = STP_SLEEP; stp_move(i, the_conf.maxsteps[i]); -//~ write2trbuf("MOTOR"); -//~ put2trbuf('0'+i); -//~ write2trbuf(" move1"); -//~ SENDBUF(); break; case STP_ACCEL: // @ any move check esw case STP_DECEL: case STP_MOVE: case STP_MVSLOW: // check end-switches status if(esw[0] == ESW_HALL && dir[i] == -1){ + DBG("S@0\n"); 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){ state[i] = STP_STOP; // stop @ end-switch 1 -//~ write2trbuf("MOTOR"); -//~ put2trbuf('0'+i); -//~ write2trbuf(" stop on sw1"); -//~ SENDBUF(); + DBG("S@1\n"); } } 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(steps == 0) return STPS_ZEROMOVE; + if(the_conf.maxsteps[nmotor] && steps > the_conf.maxsteps[nmotor]) return STPS_TOOBIG; int8_t d; if(steps < 0){ d = -1; steps = -steps; }else d = 1; // positive direction - if(the_conf.maxsteps[nmotor] && steps > the_conf.maxsteps[nmotor]) return STPS_TOOBIG; // check end-switches if(eswStatus(nmotor, 0) == 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) pin_clear(MPORT[nmotor], MENPIN[nmotor]); - steps_left[nmotor] = steps; + steps_left[nmotor] = (uint32_t)steps; // setup timer & start it TIM_TypeDef *TIMx = nmotor ? TIM3 : TIM14; 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){ TIM_TypeDef *TIMx = n ? TIM3 : TIM14; 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 @@ -265,25 +242,30 @@ static void stpr_int(int n){ }else return; switch(state[n]){ case STP_ACCEL: // acceleration phase - arrval = TIMx->ARR - stpsteparr[n]; + arrval = (uint16_t)TIMx->ARR - stpsteparr[n]; tmp = stplowarr[n]; if(arrval <= tmp || arrval > stphigharr[n]){ arrval = tmp; state[n] = STP_MOVE; // end of acceleration phase + DBG("AccEnd\n"); } TIMx->ARR = arrval; break; case STP_DECEL: // deceleration phase - arrval = TIMx->ARR + stpsteparr[n]; + arrval = (uint16_t)TIMx->ARR + stpsteparr[n]; tmp = stphigharr[n]; if(arrval >= tmp || arrval < stplowarr[n]){ arrval = tmp; state[n] = STP_MVSLOW; // end of deceleration phase, move @ lowest speed + DBG("DecEnd\n"); } TIMx->ARR = arrval; break; 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; case STP_MVSLOW: // nothing to do here: all done before switch() @@ -296,6 +278,7 @@ static void stpr_int(int n){ dir[n] = 0; steps_left[n] = 0; state[n] = STP_SLEEP; + DBG("Stop\n"); break; } } diff --git a/STM32/steppers/steppers.geany b/STM32/steppers/steppers.geany deleted file mode 100644 index 7185bb8..0000000 --- a/STM32/steppers/steppers.geany +++ /dev/null @@ -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 diff --git a/STM32/steppers/steppers.h b/STM32/steppers/steppers.h index f028a7b..1e89715 100644 --- a/STM32/steppers/steppers.h +++ b/STM32/steppers/steppers.h @@ -21,10 +21,16 @@ * */ #pragma once -#ifndef __STEPPERS_H__ -#define __STEPPERS_H__ +#ifndef STEPPERS_H__ +#define STEPPERS_H__ #include "stm32f0.h" +#include + +// 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 uint32_t steps_left[]; @@ -54,12 +60,12 @@ typedef enum{ #define stp_stepsleft(n) (steps_left[n]) stp_state stp_getstate(int motnum); -void stp_setup(); -void stp_chspd(); +void stp_setup(void); +void stp_chspd(void); stp_status stp_move(int nmotor, int32_t steps); void stp_stop(int n); -void stp_process(); -void stp_disable(); +void stp_process(void); +void stp_disable(void); void stp_chARR(int n, int32_t val); -#endif // __STEPPERS_H__ +#endif // STEPPERS_H__ diff --git a/STM32/steppers/usart.c b/STM32/steppers/usart.c index b1640b1..b635a3f 100644 --- a/STM32/steppers/usart.c +++ b/STM32/steppers/usart.c @@ -27,8 +27,8 @@ extern volatile uint32_t Tms; 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 - dlen = 0, // length of data (including '\n') in current buffer bufovr = 0, // input buffer overfull txrdy = 1 // transmission done ; @@ -113,7 +113,7 @@ void usart1_isr(){ if(!tmout) tmout = 1; // prevent 0 #endif // read RDR clears flag - uint8_t rb = USART1->RDR; + char rb = (char)USART1->RDR; if(datalen[rbufno] < UARTBUFSZ){ // put next char into buf rbuf[rbufno][datalen[rbufno]++] = rb; if(rb == '\n'){ // got newline - line ready @@ -177,13 +177,13 @@ TXstatus usart1_send(char *str){ return ALL_OK; }*/ -TXstatus usart1_send(char *str){ +TXstatus usart1_send(const char *str){ if(!txrdy) return LINE_BUSY; - int i; - for(i = 0; i < UARTBUFSZ; ++i){ + if(*str == 0) return ALL_OK; + for(int i = 0; i < UARTBUFSZ; ++i){ char c = *str++; - if(c == 0){ c = '\n'; i = UARTBUFSZ;} - USART1->TDR = c; + if(c == 0){c = '\n'; i = UARTBUFSZ;} + USART1->TDR = (uint16_t)c; while(!(USART1->ISR & USART_ISR_TXE)); } txrdy = 1; diff --git a/STM32/steppers/usart.h b/STM32/steppers/usart.h index a695020..02b92b0 100644 --- a/STM32/steppers/usart.h +++ b/STM32/steppers/usart.h @@ -19,10 +19,11 @@ * MA 02110-1301, USA. */ #pragma once -#ifndef __USART_H__ -#define __USART_H__ +#ifndef USART_H__ +#define USART_H__ #include "stm32f0.h" +#include // input and output buffers size #define UARTBUFSZ (64) @@ -43,19 +44,24 @@ typedef enum{ extern int linerdy, bufovr, txrdy; extern int trbufidx; -void USART1_config(); +void USART1_config(void); 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)) +#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 cleartrbuf() do{trbufidx = 0;}while(0) #define trbufisfull() (trbufidx) int put2trbuf(char c); int write2trbuf(const char *str); -char *gettrbuf(); +char *gettrbuf(void); int put_int(int32_t N); int put_uint(uint32_t N); -#endif // __USART_H__ +#endif // USART_H__