From 2c87dc4af92e43c9fb347cf9df7b42b3e41a425a Mon Sep 17 00:00:00 2001 From: eddyem Date: Fri, 17 Apr 2015 15:58:58 +0300 Subject: [PATCH] A lot of errors fixed --- schematic/ALL.pro | 39 ++------- with_opencm3/flash.c | 38 +++++--- with_opencm3/flash.h | 13 ++- with_opencm3/hardware_ini.c | 3 +- with_opencm3/hardware_ini.h | 16 ++-- with_opencm3/ircontroller.bin | Bin 25152 -> 27272 bytes with_opencm3/main.c | 24 +++++- with_opencm3/powerhw.c | 89 ++++++++++++++----- with_opencm3/powerhw.h | 1 - with_opencm3/stepper_motors.c | 158 ++++++++++++++++++++++++++-------- with_opencm3/stepper_motors.h | 29 +++++-- with_opencm3/user_proto.c | 83 +++++++++++++----- with_opencm3/user_proto.h | 4 + 13 files changed, 341 insertions(+), 156 deletions(-) diff --git a/schematic/ALL.pro b/schematic/ALL.pro index 3503ec5..0341989 100644 --- a/schematic/ALL.pro +++ b/schematic/ALL.pro @@ -1,6 +1,6 @@ -update=Ср 16 июл 2014 14:03:06 +update=Ср 01 апр 2015 19:30:22 version=1 -last_client=pcbnew +last_client=kicad [cvpcb] version=1 NetIExt=net @@ -54,11 +54,13 @@ LibName34=vreg LibName35=open-project [pcbnew] version=1 +PageLayoutDescrFile= LastNetListRead=ALL.net UseCmpFile=1 -PadDrill=0 -PadSizeH=2 -PadSizeV=2.5 +PadDrill=0.7999999999999999 +PadDrillOvalY=0.7999999999999999 +PadSizeH=1.5 +PadSizeV=2 PcbTextSizeV=1.5 PcbTextSizeH=1.5 PcbTextThickness=0.3 @@ -70,30 +72,3 @@ SolderMaskMinWidth=0 DrawSegmentWidth=0.4 BoardOutlineThickness=0.3 ModuleOutlineThickness=0.3 -[pcbnew/libraries] -LibDir=/home/eddy/kicad;/home/eddy/kicad/CYB3R_from_LOR/kicad;/home/eddy/kicad/Kicad-Libraries/modules;/home/eddy/kicad/kicadlibrary;mod -LibName1=sockets -LibName2=connect -LibName3=discret -LibName4=pin_array -LibName5=divers -LibName6=libcms -LibName7=display -LibName8=led -LibName9=dip_sockets -LibName10=pga_sockets -LibName11=valves -LibName12=open-project -LibName13=dip -LibName14=pinhead -LibName15=pinhead-double -LibName16=pinhead-double-smd -LibName17=qfp -LibName18=smd -LibName19=sot -LibName20=quartz -LibName21=w_crystal -LibName22=capacitors -LibName23=gprm1-45-61 -LibName24=my_modules -LibName25=smd_diodes diff --git a/with_opencm3/flash.c b/with_opencm3/flash.c index 8fc7355..4d080e4 100644 --- a/with_opencm3/flash.c +++ b/with_opencm3/flash.c @@ -23,7 +23,12 @@ #include #include -const flash_data Stored_Data __attribute__ ((aligned(FLASH_BLOCK_SIZE))) = { +// this is variable structure saved in RAM for ability of data changing +stored_data Stored_Data; + +// this is constant structure saved in flash. It have to be copied to Stored_Data after run +const flash_data Flash_Data __attribute__ ((aligned(FLASH_BLOCK_SIZE))) = { +.all_stored = { //.magick = FLASH_MAGICK, ._ADC_multipliers = {100000,100000,100000,100000,100000,100000,100000,100000, // TRD 26, // shutter @@ -33,12 +38,13 @@ const flash_data Stored_Data __attribute__ ((aligned(FLASH_BLOCK_SIZE))) = { 25, // shutter 7 // power } +} }; -uint32_t flash_write_data(uint32_t *dataptr, uint16_t datalen){ - uint32_t start_address = (uint32_t)&Stored_Data; +uint8_t flash_write_data(uint32_t *dataptr, uint16_t datalen){ + uint32_t start_address = (uint32_t)&(Flash_Data.all_stored); uint16_t i, rem; - uint32_t ret = 0; + uint8_t ret = 0; flash_unlock(); DBG("erase\n"); //Erasing page @@ -76,14 +82,18 @@ endoffunction: return ret; } -uint32_t flash_store_U32(uint32_t addr, uint32_t *data){ - flash_data Saved_Data; - uint32_t sz, ptrdiff; - sz = (uint32_t)&Stored_Data.last_addr - (uint32_t)&Stored_Data; - ptrdiff = addr - (uint32_t)&Stored_Data; - memcpy((void*)&Saved_Data, (void*)&Stored_Data, sz); - memcpy((void*)((uint32_t)&Saved_Data + ptrdiff), (void*)data, 4); - return flash_write_data((uint32_t*)&Saved_Data, sz); +/** + * save all data from RAM to flash + */ +uint8_t save_flashdata(){ +// uint32_t sz = (uint32_t)&Stored_Data.last_addr - (uint32_t)&Stored_Data; + //return flash_write_data((uint32_t*)&Stored_Data, sz); + return flash_write_data((uint32_t*)&Stored_Data, sizeof(stored_data)); +} + +void read_stored_data(){ +// uint32_t sz = (uint32_t)&Stored_Data.last_addr - (uint32_t)&Stored_Data; + memcpy((void*)&Stored_Data, (void*)&(Flash_Data.all_stored), sizeof(stored_data)); } /** @@ -96,12 +106,12 @@ void dump_flash_data(sendfun s){ P("\nADC multipliers: ", s); for(i = 0; i < ADC_CHANNELS_NUMBER; i++){ if(i) P(", ", s); - print_int(ADC_multipliers[i], s); + print_int(Flash_Data.all_stored._ADC_multipliers[i], s); } P("\nADC divisors: ", s); for(i = 0; i < ADC_CHANNELS_NUMBER; i++){ if(i) P(", ", s); - print_int(ADC_divisors[i], s); + print_int(Flash_Data.all_stored._ADC_divisors[i], s); } s('\n'); } diff --git a/with_opencm3/flash.h b/with_opencm3/flash.h index 8e23186..f10677a 100644 --- a/with_opencm3/flash.h +++ b/with_opencm3/flash.h @@ -32,7 +32,7 @@ * align by 2k & make size 2k for using with high density devices */ #define FLASH_BLOCK_SIZE (2048) -#define FLASH_WRONG_DATA_WRITTEN 0x80 +#define FLASH_WRONG_DATA_WRITTEN ((uint8_t)0x80) #define FLASH_MAGICK ((uint32_t) 0xAA55A55A) @@ -41,16 +41,21 @@ typedef struct{ // A-D value[x] = ADU * ADC_multipliers[x] / ADC_divisors[x] uint32_t _ADC_multipliers[ADC_CHANNELS_NUMBER]; uint32_t _ADC_divisors[ADC_CHANNELS_NUMBER]; - char last_addr[0]; // we need this pointer to calculate real size of structure +// char last_addr[0]; // we need this pointer to calculate real size of structure +}stored_data; + +typedef struct{ + stored_data all_stored; char struct_end[0] __attribute__ ((aligned(FLASH_BLOCK_SIZE))); // this pointer provides size of structure multiple of page size } flash_data; -extern const flash_data Stored_Data; +extern stored_data Stored_Data; #define ADC_multipliers Stored_Data._ADC_multipliers #define ADC_divisors Stored_Data._ADC_divisors void dump_flash_data(sendfun s); -uint32_t flash_store_U32(uint32_t addr, uint32_t *data); +uint8_t save_flashdata(); +void read_stored_data(); #endif // __FLASH_H__ diff --git a/with_opencm3/hardware_ini.c b/with_opencm3/hardware_ini.c index 8f2df8c..007591a 100644 --- a/with_opencm3/hardware_ini.c +++ b/with_opencm3/hardware_ini.c @@ -137,7 +137,8 @@ void GPIO_init(){ // Shutter control: input pull up gpio_set_mode(SHUTTER_EXT_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, SHUTTER_CAM_PIN | SHUTTER_MAN_PIN | SHUTTER_FBSW_PIN); - gpio_set(SHUTTER_EXT_PORT, SHUTTER_CAM_PIN | SHUTTER_MAN_PIN | SHUTTER_FBSW_PIN); // turn on pull up + //gpio_set(SHUTTER_EXT_PORT, SHUTTER_CAM_PIN | SHUTTER_MAN_PIN | SHUTTER_FBSW_PIN); // turn on pull up + GPIO_ODR(SHUTTER_EXT_PORT) |= SHUTTER_CAM_PIN | SHUTTER_MAN_PIN | SHUTTER_FBSW_PIN; // shutter status LED: opendrain gpio_set_mode(LED_SHUTTER_PORT, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, LED_SHUTTER_PIN); diff --git a/with_opencm3/hardware_ini.h b/with_opencm3/hardware_ini.h index 9d9c42a..ee242b4 100644 --- a/with_opencm3/hardware_ini.h +++ b/with_opencm3/hardware_ini.h @@ -97,6 +97,8 @@ void ADC_calibrate_and_start(); #define MOTOR_TIM1_PIN (GPIO6) #define MOTOR_TIM2_PORT (GPIOD) #define MOTOR_TIM2_PIN (GPIO15) +// don't even try to move motor if motors' voltage less than 9.5V +#define MOTORS_VOLTAGE_THRES (950) /* * One Wire interface @@ -128,14 +130,6 @@ void ADC_calibrate_and_start(); #define LED_SHUTTER_OPEN() do{gpio_clear(LED_SHUTTER_PORT, LED_SHUTTER_PIN);}while(0) #define LED_SHUTTER_CLOSE() do{gpio_set(LED_SHUTTER_PORT, LED_SHUTTER_PIN);}while(0) -/* -// We use timer 1 to process pauses with shutter -#define Shutter_tim_isr tim1_isr -#define SHUTTER_TIM TIM1 -//#define NVIC_SHUTTER_IRQ NVIC_TIM5_IRQ -#define NVIC_SHUTTER_IRQ NVIC_TIM1_UP_IRQ -#define RCC_SHUTTER_TIM RCC_TIM1 -*/ // Shutter pins: PC0 & PC2 are polarity & on/off pins; PC1 is feedback pin #define SHUTTER_PORT (GPIOC) #define SHUTTER_ON_PIN (GPIO2) @@ -145,9 +139,9 @@ void ADC_calibrate_and_start(); #define SHUTTER_VOLTAGE_THRES (2000) // minimum voltage that should be on capasitor if power source is on #define SHUTTER_UNDERVOLTAGE_THRES (700) -// delay in operations (open/close) in us (according to shutter's datasheet it's about 12ms) -#define SHUTTER_DELAY (12500) -// delay for error test +// delay in operations (open/close) in milliseconds (according to shutter's datasheet it's about 12ms -> make 15) +#define SHUTTER_DELAY (15) +// delay for error test (in microseconds) #define SHUTTER_OP_DELAY (200) // ADC_value[8] is U36, ADC_value[9] is U10 diff --git a/with_opencm3/ircontroller.bin b/with_opencm3/ircontroller.bin index 99866598c35c45de052a55307f2b53cb55b3e6b1..c88648d99715025c35ab8de077cf90ad2d0a6a3d 100755 GIT binary patch delta 10511 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 RB2$6p8}bcg;*SW0{{sWow-f*X diff --git a/with_opencm3/main.c b/with_opencm3/main.c index 843cbfd..6bc00c1 100644 --- a/with_opencm3/main.c +++ b/with_opencm3/main.c @@ -137,18 +137,20 @@ void AD7794_init(){ int main(){ //int i; - uint32_t Old_timer = 0, lastTRDread = 0, lastTmon = 0; + uint32_t Shtr_blink_timer = 0, Old_timer = 0, lastTRDread = 0, lastTmon = 0; int oldusbdatalen = 0; //SPI_read_status SPI_stat; // RCC clocking: 8MHz oscillator -> 72MHz system rcc_clock_setup_in_hse_8mhz_out_72mhz(); - usb_disconnect(); // turn off USB while initializing all + + // turn off SWJ/JTAG + AFIO_MAPR = AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_OFF; // GPIO GPIO_init(); - steppers_init(); + usb_disconnect(); // turn off USB while initializing all // init USART1 UART_init(USART1); @@ -173,9 +175,13 @@ int main(){ ADC_init(); ADC_calibrate_and_start(); + steppers_init(); + usb_connect(); // turn on USB shutter_init(); + read_stored_data(); // copy stored data into RAM + LED_STATUS_OK(); // All initialized - light up LED while(1){ usbd_poll(usbd_dev); @@ -200,9 +206,19 @@ int main(){ process_stepper_motors(); // check flags of motors' timers process_shutter(); // shutter state machine + if(Timer - Shtr_blink_timer > 500 || Timer < Shtr_blink_timer){ + Shtr_blink_timer = Timer; + // shutter LED will be blinking until init occurs + if(Shutter_State == SHUTTER_NOTREADY) + gpio_toggle(LED_SHUTTER_PORT, LED_SHUTTER_PIN); + } + if(Timer - Old_timer > 999){ // one-second cycle Old_timer += 1000; - // if(Shutter_State == SHUTTER_NOTREADY) shutter_init(); + // init shutter if error occurs + if(Shutter_State == SHUTTER_NOTREADY){ + shutter_init(); + } //OW_fill_ID(0); //gpio_toggle(GPIOC, GPIO12); // toggle LED //gpio_toggle(GPIO_BANK_SPI2_MOSI, GPIO_SPI2_MOSI); diff --git a/with_opencm3/powerhw.c b/with_opencm3/powerhw.c index 7029b1c..4f300d3 100644 --- a/with_opencm3/powerhw.c +++ b/with_opencm3/powerhw.c @@ -22,10 +22,9 @@ #include "main.h" // state of shutter - global variable to omit interface functions shutter_state Shutter_State = SHUTTER_NOTREADY; -uint16_t Shutter_delay = SHUTTER_DELAY; int8_t manual_pin_old_state = -1; int8_t camera_pin_old_state = -1; -uint8_t changed_manually = 0; // ==1 if shutter state was changed by manual switch +//uint8_t changed_manually = 0; // ==1 if shutter state was changed by manual switch // function to be runned from timer irq //void (*shutter_timer_fn)() = NULL; @@ -35,11 +34,12 @@ uint8_t changed_manually = 0; // ==1 if shutter state was changed by manual swit #define SCB_DEMCR *(volatile uint32_t *)0xE000EDFC /** - * Make background pause in 'us' microsecond, after which run function fn_ready + * Make blocking pause in 'us' microsecond, after which run function fn_ready * @param us - pause in microseconds * @param fn_ready - function to run at end of pause + * @param block - == 0 if calling is non-blocking, otherwice == 1 */ -void shutter_wait(uint32_t us, void(*fn_ready)()){ +void shutter_wait_block(uint32_t us, void(*fn_ready)()){ /* if(!fn_ready) return; //DBG("wait for previous .. "); @@ -55,12 +55,36 @@ void shutter_wait(uint32_t us, void(*fn_ready)()){ // wait for us*72 cycles SCB_DEMCR |= 0x01000000; DWT_CYCCNT = 0; - DWT_CONTROL|= 1; // enable the counter + DWT_CONTROL|= 1; // for (i = 0; i < us; i++) __asm__("nop"); while(DWT_CYCCNT < us); fn_ready(); } +/** + * Make nonblocking pause in 'ms' millisecond, after which we should run function fn_ready + * run it with us == 0 and/or fn_ready == 0 to check old pause + */ +void shutter_wait_nonblock(uint32_t ms, void(*fn_ready)()){ + static uint8_t waiting_for = 0; // == 1 if we are waiting for something + static uint32_t wait_till = 0; // time counter for waiting + static void(*fn_ready_saved)() = NULL; + if(ms == 0 || fn_ready == 0){ // check + if(waiting_for && Timer >= wait_till){ // it's time + waiting_for = 0; + if(fn_ready_saved){ + void(*f)() = fn_ready_saved; + fn_ready_saved = NULL; + f(); + } + } + }else{ + waiting_for = 1; + fn_ready_saved = fn_ready; + wait_till = Timer + ms; // "automatic" overload + } +} + // macro to open/close/set default state // open shutter is 0:0 -> when MCU power is off, shutter "automatically" opens #define shutter_close() do{gpio_clear(SHUTTER_PORT, SHUTTER_ON_PIN | SHUTTER_POLARITY_PIN);}while(0) @@ -83,7 +107,7 @@ void shutter_test(){ static shutter_state old_State = SHUTTER_NOTREADY; // test for undervoltage if(shutter_voltage() < SHUTTER_UNDERVOLTAGE_THRES){ - ERR("shutter undervoltage\n"); + // ERR("shutter undervoltage\n"); Shutter_State = SHUTTER_NOTREADY; shutter_off(); return; @@ -92,20 +116,20 @@ void shutter_test(){ old_State = Shutter_State; Shutter_State = SHUTTER_INITIALIZED; // test for wire breakage - DBG("breakage test\n"); + // DBG("breakage test\n"); shutter_hiZ(); // 1,1: breakage test - shutter_wait(SHUTTER_OP_DELAY, shutter_test); + shutter_wait_block(SHUTTER_OP_DELAY, shutter_test); }else{ // check breakage if(shutter_error()){ // ERR==0 -> wire breakage - ERR("shutter wire breakage\n"); + // ERR("shutter wire breakage\n"); Shutter_State = SHUTTER_NOTREADY; }else{ if(old_State == SHUTTER_NOTREADY){ Shutter_State = SHUTTER_CLOSING; // close shutter on power on - DBG("ready!\n"); + // DBG("ready!\n"); }else{ Shutter_State = old_State; - DBG("no errors\n"); + // DBG("no errors\n"); } } shutter_off(); @@ -131,8 +155,10 @@ void shutter_ready(){ LED_SHUTTER_CLOSE(); // turn off shutter status LED else{ ERR("shutter is still opened\n"); - if(!changed_manually) Shutter_State = SHUTTER_NOTREADY; + //if(!changed_manually) + Shutter_State = SHUTTER_NOTREADY; } + break; case SHUTTER_OPENED: if(shutter_error()){ ERR("shutter overtemperature or undervoltage\n"); @@ -142,7 +168,8 @@ void shutter_ready(){ LED_SHUTTER_OPEN(); // turn on LED else{ ERR("shutter is still closed\n"); - if(!changed_manually) Shutter_State = SHUTTER_NOTREADY; + //if(!changed_manually) + Shutter_State = SHUTTER_NOTREADY; } } break; @@ -163,15 +190,15 @@ void shutter_ready(){ ERR("wrong shutter state\n"); print_shutter_state(lastsendfun); } - changed_manually = 0; + //changed_manually = 0; shutter_off(); if(Shutter_State == SHUTTER_NOTREADY) return; if(test_err){ //DBG("now test for err\n"); - shutter_wait(SHUTTER_OP_DELAY, shutter_ready); // test for overtemp or undervoltage + shutter_wait_nonblock(SHUTTER_DELAY, shutter_ready); // test for overtemp or undervoltage }else{ // wait a lot of time to prevent false detections - shutter_wait(SHUTTER_DELAY, shutter_test); + shutter_wait_nonblock(SHUTTER_DELAY, shutter_test); } } @@ -208,10 +235,14 @@ shutter_state shutter_init(){ // feedback: floating input gpio_set_mode(SHUTTER_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, SHUTTER_FB_PIN); + // Shutter control: input pull up +// gpio_set_mode(SHUTTER_EXT_PORT, GPIO_MODE_INPUT, +// GPIO_CNF_INPUT_FLOAT, SHUTTER_CAM_PIN | SHUTTER_MAN_PIN | SHUTTER_FBSW_PIN); +// gpio_set(SHUTTER_EXT_PORT, SHUTTER_CAM_PIN | SHUTTER_MAN_PIN | SHUTTER_FBSW_PIN); // turn on pull up //DBG("shutter fb ready\n"); shutter_off(); //shutter_timer_fn = NULL; - shutter_wait(SHUTTER_OP_DELAY, shutter_test); + shutter_wait_block(SHUTTER_OP_DELAY, shutter_test); return SHUTTER_INITIALIZED; // we return this state in spite of the shutter isn't really initialized yet } @@ -221,6 +252,9 @@ shutter_state shutter_init(){ */ void process_shutter(){ uint8_t man_pin_state, cam_pin_state, ext_open = 0, ext_close = 0; + + shutter_wait_nonblock(0, NULL); // check for holded over functions + if(Shutter_State == SHUTTER_NOTREADY) return; // test state of external control pins @@ -240,7 +274,7 @@ void process_shutter(){ manual_pin_old_state = man_pin_state; }else if(manual_pin_old_state != man_pin_state){ // user changed switch state -> open/close manual_pin_old_state = man_pin_state; - changed_manually = 1; + //changed_manually = 1; if(man_pin_state){ // close ext_close = 1; }else{ // open @@ -252,13 +286,13 @@ void process_shutter(){ if(ext_open){ // external signal for opening shutter if(Shutter_State != SHUTTER_OPENED && Shutter_State != SHUTTER_PROC_OPENING) Shutter_State = SHUTTER_OPENING; - else - changed_manually = 0; + //else + // changed_manually = 0; }else if(ext_close){ // close shutter if(Shutter_State != SHUTTER_CLOSED && Shutter_State != SHUTTER_PROC_CLOSING) Shutter_State = SHUTTER_CLOSING; - else - changed_manually = 0; + //else + // changed_manually = 0; } if(Shutter_State != SHUTTER_OPENING && Shutter_State != SHUTTER_CLOSING) @@ -288,7 +322,7 @@ void process_shutter(){ default: return; } - shutter_wait(Shutter_delay, shutter_ready); + shutter_wait_nonblock(SHUTTER_DELAY, shutter_ready); } /* @@ -350,6 +384,15 @@ void print_shutter_state(sendfun s){ } if(mode == BYTE_MODE) P(")\n", s); else if(mode == LINE_MODE) P(") ]\n", s); +#ifdef EBUG + if(mode == BYTE_MODE){ + P("MAN: ",s); + if(gpio_get(SHUTTER_EXT_PORT, SHUTTER_MAN_PIN)) P("not ",s); + P("pressed, EXT: ",s); + if(gpio_get(SHUTTER_EXT_PORT, SHUTTER_CAM_PIN)) P("not ",s); + P("pressed\n", s); + } +#endif } /** diff --git a/with_opencm3/powerhw.h b/with_opencm3/powerhw.h index 1716ae2..670e569 100644 --- a/with_opencm3/powerhw.h +++ b/with_opencm3/powerhw.h @@ -39,7 +39,6 @@ typedef enum{ } shutter_state; extern shutter_state Shutter_State; -extern uint16_t Shutter_delay; shutter_state shutter_init(); void process_shutter(); diff --git a/with_opencm3/stepper_motors.c b/with_opencm3/stepper_motors.c index faf7785..7a46731 100644 --- a/with_opencm3/stepper_motors.c +++ b/with_opencm3/stepper_motors.c @@ -24,29 +24,37 @@ // TODO: function "move motor to given position" static uint8_t timers_activated[2] = {0, 0}; // flag of activated timers -uint16_t Motor_period[2] = {1300, 1300}; // one step per 1.3ms -uint32_t Turrets_pause = 2 * TURRETS_PAUSE_US / 1300; // pause in half-steps -volatile uint8_t timer_flag[2] = {0,0}; +static uint16_t Motor_period[2] = {3000, 2000}; +static uint32_t Turrets_pause = 2 * TURRETS_PAUSE_US / 3000; // pause in half-steps +static volatile uint8_t timer_flag[2] = {0,0}; // amount of steps for each motor -volatile uint32_t Motor_steps[5] = {0, 0, 0, 0, 0}; +static volatile uint32_t Motor_steps[5] = {0, 0, 0, 0, 0}; // absolute value of current position, usefull for stages -volatile int32_t Motor_abs_steps[5] = {0, 0, 0, 0, 0}; +static volatile int32_t Motor_abs_steps[5] = {0, 0, 0, 0, 0}; +// increments that will be added each step to Motor_abs_steps (+1/-1) +static int8_t Motor_step_increment[5] = {1,1,1,1,1}; // flag of active motor -volatile uint8_t Motor_active[5] = {0, 0, 0, 0, 0}; +static volatile uint8_t Motor_active[5] = {0, 0, 0, 0, 0}; /* * Wait flags: if non-zero, flag just decremented * (we need it to wait a little on turrets' fixed positions to omit Halls' histeresis) */ -uint8_t waits[5] = {0,0,0,0,0}; +static uint8_t waits[5] = {0,0,0,0,0}; +// acceleration: if non-zero we will omit N steps after each step & decrement accell value +static uint8_t accel[5] = {0,0,0,0,0}; // Halls & end-switches values on previous step -uint8_t lastpos[5] = {0,0,0,0,0}; +static uint8_t lastpos[5] = {0,0,0,0,0}; // number of position to move turret or stage, zero to move only for N given steps uint8_t move2pos[5] = {0,0,0,0,0}; // number of positions passed for given -uint8_t positions_pass[3] = {0,0,0}; +static uint8_t positions_pass[3] = {0,0,0}; // maximum amount of positions passed to reach given #define MAX_POSITIONS_PASS (8) +// multipliers for linear acceleration (in reverce order) +static const uint8_t accel_mults[16] = {1, 2, 2, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 8, 10, 16}; + + /** * Setup stepper motors' timer Tim * N == 0 for TIM3, == 1 for TIM4 @@ -105,9 +113,10 @@ void steppers_init(){ GPIO_CNF_OUTPUT_PUSHPULL, MOTOR_TIM2_PIN); // EN pins // WARNING! EN pins would be shortened to GND in case of overcurrent/overheating - // so, they should be pull-up inputs in active mode & pull-down inputs in inactive mode!!! + // so, when active they should be opendrain outputs with 100k external resistor to +5V or pullup inputs!!! + // inactive: opendrain output gpio_set_mode(MOTOR_EN_PORT, GPIO_MODE_OUTPUT_2_MHZ, - GPIO_CNF_INPUT_PULL_UPDOWN, MOTOR_EN_MASK); + GPIO_CNF_OUTPUT_OPENDRAIN, MOTOR_EN_MASK); gpio_clear(MOTOR_EN_PORT, MOTOR_EN_MASK); // DIR pins gpio_set_mode(MOTOR_DIR_PORT, GPIO_MODE_OUTPUT_2_MHZ, @@ -130,10 +139,10 @@ uint8_t test_stages_endpos(uint8_t num, uint8_t curpos){ const uint8_t stage_plus[2] = {STAGE_CHECK(3, PLUS), STAGE_CHECK(4, PLUS)}; const uint8_t stage_minus[2] = {STAGE_CHECK(3, MINUS), STAGE_CHECK(4, MINUS)}; uint8_t negative_dir = 0; - num -= 3; // convern num to index in arrays - if((uint16_t)(GPIO_IDR(MOTOR_DIR_PORT) & MOTOR_DIR_PIN(num))){ // negative direction + if((uint16_t)(GPIO_ODR(MOTOR_DIR_PORT) & MOTOR_DIR_PIN(num))){ // negative direction negative_dir = 1; } + num -= 3; // convern num to index in arrays if(stage_plus[num] == curpos){ // we are on "+" end-switch if(!negative_dir){ // and wanna move to "+" ERR("End-switch +\n"); @@ -180,6 +189,7 @@ uint8_t check_ep(uint8_t num){ return 0; } + /** * Move motor Motor_number to User_value steps * return 0 if motor is still moving @@ -192,6 +202,16 @@ uint8_t move_motor(uint8_t num, int32_t steps){ ERR("moving\n"); return 0; } + int voltage = power_voltage(); + if(voltage < MOTORS_VOLTAGE_THRES){ + ERR("undervoltage!\n"); + if(mode == LINE_MODE){ + P("[ " STR_MOTORS_VOLTAGE " ", lastsendfun); + print_int(voltage, lastsendfun); + P(" ]\n", lastsendfun); + } + return 0; + } #ifdef EBUG if(mode == BYTE_MODE){ P("move ", lastsendfun); @@ -201,11 +221,12 @@ uint8_t move_motor(uint8_t num, int32_t steps){ lastsendfun('\n'); } #endif - Motor_abs_steps[num] += steps; // fix absolute position if(steps < 0){ negative_dir = 1; + Motor_step_increment[num] = -1; steps = -steps; - } + }else + Motor_step_increment[num] = 1; curpos = check_ep(num); lastpos[num] = curpos; if(negative_dir){ @@ -220,10 +241,21 @@ uint8_t move_motor(uint8_t num, int32_t steps){ // set all flags and variables Motor_steps[num] = steps; // we run in full-step mode! waits[num] = 0; + accel[num] = START_MOTORS_ACCEL_IDX_4; Motor_active[num] = 1; if(num < 3) // this is turret -> reset counter of passed positions positions_pass[num] = 0; + // pullup input when active + gpio_set_mode(MOTOR_EN_PORT, GPIO_MODE_INPUT, + GPIO_CNF_INPUT_PULL_UPDOWN, MOTOR_EN_PIN(num)); gpio_set(MOTOR_EN_PORT, MOTOR_EN_PIN(num)); +/* + P("set: ", lastsendfun); + print_int(GPIO_ODR(MOTOR_EN_PORT) & MOTOR_EN_MASK, lastsendfun); + P(", get: ", lastsendfun); + print_int(GPIO_IDR(MOTOR_EN_PORT) & MOTOR_EN_MASK, lastsendfun); + lastsendfun('\n'); +*/ return 1; } @@ -232,10 +264,17 @@ void stop_motor(uint8_t num){ const uint8_t stage_minus[2] = {STAGE_CHECK(3, MINUS), STAGE_CHECK(4, MINUS)}; //if(!) return; MSG("stop motor ", "[ " STR_STOP_ALL_MOTORS " "); - if(mode != BINARY_MODE) lastsendfun('0' + num); + if(mode != BINARY_MODE){ + lastsendfun('0' + num); + lastsendfun(' '); + } + // this function could be called simply to check motors' position + // so, we should check wether motor is active before changing EN state if(Motor_active[num]){ if(!gpio_get(MOTOR_EN_PORT, MOTOR_EN_PIN(num)) && mode == LINE_MODE) - P(" HEAT ", lastsendfun); + P("HEAT ", lastsendfun); + gpio_set_mode(MOTOR_EN_PORT, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_OPENDRAIN, MOTOR_EN_PIN(num)); gpio_clear(MOTOR_EN_PORT, MOTOR_EN_PIN(num)); Motor_active[num] = 0; } @@ -245,24 +284,16 @@ void stop_motor(uint8_t num){ move2pos[num] = 0; // reset target position value if(curpos == 1){ Motor_abs_steps[num] = 0; - goto retn; }else{ if(curpos == 0) // a turret is out of fixed position - MSG(" stop out of position", "ERR "); + MSG("stop out of position", "ERR "); } }else{ // linear stage if(curpos == stage_minus[num-3]){ Motor_abs_steps[num] = 0; - goto retn; } } - int32_t sign = 1; - if(GPIO_IDR(MOTOR_DIR_PORT) & MOTOR_DIR_PIN(num)){ // negative direction - sign = -1; - } - Motor_abs_steps[num] -= Motor_steps[num] * sign; Motor_steps[num] = 0; -retn: BYTE_MSG(" absolute steps: "); print_int(Motor_abs_steps[num], lastsendfun); if(mode == LINE_MODE) P(" ]", lastsendfun); @@ -287,10 +318,18 @@ void process_stepper_motors(){ const uint32_t pins[] = {MOTOR_TIM1_PIN, MOTOR_TIM2_PIN}; const uint8_t startno[] = {0, 3}; const uint8_t stopno[] = {3, 5}; + //static uint8_t showcurpos[5] = {0,0,0,0,0}; uint8_t curpos; + const uint32_t Tim[2] = {TIM3, TIM4}; for(j = 0; j < 2; j++){ + // new period of motors' timer -- maximum value for all periods in group + uint16_t new_period = 0; if(timer_flag[j]){ timer_flag[j] = 0; + uint8_t is_active = 0; + for(i = startno[j]; i < stopno[j]; i++) + if(Motor_active[i]) is_active = 1; + if(!is_active) continue; // don't generate clock pulses when there's no moving motors gpio_toggle(ports[j], pins[j]); // change clock state if(!gpio_get(ports[j], pins[j])){ // negative pulse - omit this half-step continue; @@ -303,16 +342,20 @@ void process_stepper_motors(){ //(what if there's some slipping or so on?) }else{ // we should move further if(waits[i]){ // waiting for position stabilisation + uint8_t got_new_position = 0; waits[i]--; if(waits[i]) continue; // there's more half-steps to skip + // tell user current position if we was stopped at fixed pos + if(lastpos[i] == 0 && curpos != 0){ + got_new_position = 1; + MSG("position of motor ", "[ " STR_ENDSW_STATE " "); + print_int(i, lastsendfun); + lastsendfun(' '); + print_int(curpos, lastsendfun); + if(mode == LINE_MODE) P(" ]", lastsendfun); + lastsendfun('\n'); + } lastpos[i] = curpos; - // tell user current position - MSG("position of motor ", "[ " STR_ENDSW_STATE " "); - print_int(i, lastsendfun); - lastsendfun(' '); - print_int(curpos, lastsendfun); - if(mode == LINE_MODE) P(" ]", lastsendfun); - lastsendfun('\n'); // turn on motor after pause gpio_set(MOTOR_EN_PORT, MOTOR_EN_PIN(i)); if(j == 1){ // this is a linear stage @@ -323,7 +366,7 @@ void process_stepper_motors(){ if(move2pos[i]){ // we should move to specific position if(curpos == move2pos[i]){ // we are on position stop_motor(i); - }else{ // add some steps to move to next position + }else if(got_new_position){ // add some steps to move to next position if(++positions_pass[i] > MAX_POSITIONS_PASS){ ERR("Can't reach given position"); stop_motor(i); @@ -341,17 +384,33 @@ void process_stepper_motors(){ } if(lastpos[i] != curpos){ // transition process if(lastpos[i] == 0){ // come towards position - waits[i] = Turrets_pause; - // turn off motor while a pause + if(j == 0){ // this is a turret: make pause & prepare acceleration for start + waits[i] = Turrets_pause; + accel[i] = START_MOTORS_ACCEL_IDX_4; + }else{ + waits[i] = 1; + } + // turn off motor while a pause (turret will be locked at fixed position by spring) + // for this short pause we can simply do a pulldown gpio_clear(MOTOR_EN_PORT, MOTOR_EN_PIN(i)); continue; } lastpos[i] = curpos; } Motor_steps[i]--; + // change value of current motor's position + Motor_abs_steps[i] += Motor_step_increment[i]; + if(accel[i]){ // we are starting + uint32_t NP = (uint32_t)Motor_period[j] * accel_mults[(accel[i]--)/4]; + if(NP > 0xffff) NP = 0xffff; + if(new_period < NP) new_period = (uint16_t)NP; + } } } } + if(new_period){ // we have to change motors' speed when accelerating + timer_set_period(Tim[j], new_period); + } } } } @@ -401,6 +460,33 @@ void set_motor_period(uint8_t num, uint16_t period){ else timer_set_period(Tim, period); } +void get_motors_position(){ + uint8_t i; + for(i = 0; i < 5; i++){ + MSG("position of ", "[ " STR_MOTOR_POSITION " "); + lastsendfun(i+'0'); + MSG(" is ", " "); + print_int(Motor_abs_steps[i], lastsendfun); + if(Motor_active[i]){ + lastsendfun(' '); + P("moving", lastsendfun); + } + if(mode == LINE_MODE) P(" ]", lastsendfun); + lastsendfun('\n'); + } +} + +/** + * displays periods of both generators + */ +void show_motors_period(sendfun s){ + P("[ " STR_SHOW_PERIOD " ", s); + print_int((int32_t)Motor_period[0],s); + s(' '); + print_int((int32_t)Motor_period[1],s); + P(" ]\n", s); +} + /* * Interrupts: just set flag */ diff --git a/with_opencm3/stepper_motors.h b/with_opencm3/stepper_motors.h index 135795d..c23e252 100644 --- a/with_opencm3/stepper_motors.h +++ b/with_opencm3/stepper_motors.h @@ -25,32 +25,45 @@ #include // default pause to make sure that turret is on position -#define TURRETS_PAUSE_US 30000 +#define TURRETS_PAUSE_US (50000) // max amount of steps to add to turret for moving to next position -#define TURRETS_NEXT_POS_STEPS 300 +#define TURRETS_NEXT_POS_STEPS (500) +// (index/4) in accel_mults[] for started acceleration +#define START_MOTORS_ACCEL_IDX_4 (63) #ifndef CONCAT #define CONCAT(A, B) A ## B #endif // check status of end-switches and Halls +/* // Motor 0 == turret 0, PD0..PD3 #define _CHECK_EP0 ((~GPIO_IDR(GPIOD)) & 0x0f) // Motor 1 == turret 1, PD4..PD6 #define _CHECK_EP1 (((~GPIO_IDR(GPIOD)) >> 4) & 0x07) // Motor 2 == turret 2, PD7, PB6, PB7 #define _CHECK_EP2 ((((~GPIO_IDR(GPIOD)) >> 7) & 0x01) | (((~GPIO_IDR(GPIOB))>> 6) & 0x03)) +*/ +// Motor 0 == turret 0, PD0..PD2 +#define _CHECK_EP0 ((~GPIO_IDR(GPIOD)) & 0x07) +// Motor 1 == turret 1, PD3..PD5 +#define _CHECK_EP1 (((~GPIO_IDR(GPIOD)) >> 3) & 0x07) +// Motor 2 == turret 2, PD6, PD7, PB6, PB7 +#define _CHECK_EP2 ((((~GPIO_IDR(GPIOD)) >> 6) & 0x03) | (((~GPIO_IDR(GPIOB))>> 4) & 0x0c)) // Motor 3 == long (VPHG, pupil stop) stage, PC7/PC8 (down/up) #define _CHECK_EP3 (((~GPIO_IDR(GPIOC)) >> 7) & 0x03) // Motor 4 == short (focus) stage, PC9/PA8 (down/up) -#define _CHECK_EP4 ((((~GPIO_IDR(GPIOC)) >> 9) & 0x01) | (((~GPIO_IDR(GPIOA)) >> 8) & 0x01)) +#define _CHECK_EP4 ((((~GPIO_IDR(GPIOC)) >> 9) & 0x01) | (((~GPIO_IDR(GPIOA)) >> 7) & 0x02)) + // this macro returns end-switches & Hall status: 0 - not active, 1 - active #define CHECK_EP(X) CONCAT(_CHECK_EP, X) // end-switches for motors 3,4 (stage 1 and stage 2): stop when direction positive/negative -#define EP3PLUS 2 -#define EP3MINUS 1 -#define EP4PLUS 2 -#define EP4MINUS 1 +// down is 1, up is 2 +// moving down is positive +#define EP3PLUS 1 +#define EP3MINUS 2 +#define EP4PLUS 1 +#define EP4MINUS 2 #define STAGE_CHECK(N, DIR) CONCAT(EP ## N, DIR) // setup ports: PA8, PB6, PB7, PC7..PC9, PD0..PD7 @@ -79,6 +92,8 @@ uint8_t move_motor(uint8_t num, int32_t steps); void stop_motor(uint8_t num); void set_motor_period(uint8_t num, uint16_t period); uint8_t check_ep(uint8_t num); +void get_motors_position(); +void show_motors_period(sendfun s); #endif // __STEPPER_MOTORS_H__ diff --git a/with_opencm3/user_proto.c b/with_opencm3/user_proto.c index 828a0f0..73d8cc2 100644 --- a/with_opencm3/user_proto.c +++ b/with_opencm3/user_proto.c @@ -41,11 +41,11 @@ enum{ UVAL_ENTERED, // value entered but not printed UVAL_BAD // entered bad value }; -uint8_t Uval_ready = UVAL_PRINTED; +static uint8_t Uval_ready = UVAL_PRINTED; int read_int(char *buf, int cnt); -intfun I = NULL; // function to process entered integer +static intfun I = NULL; // function to process entered integer #define READINT() do{i += read_int(&buf[i+1], len-i-1);}while(0) #define WRONG_COMMAND() do{if(mode == BYTE_MODE) command = '?';}while(0) @@ -110,18 +110,18 @@ int div_mul = 0; // 0 - multip., !0 - div. * change dividers/multipliers * work only in BYTE_MODE */ -uint8_t ch_divmul(int32_t v, sendfun s){ +uint8_t ch_divmul(int32_t v, _U_ sendfun s){ uint32_t val = (uint32_t) v; if(adc_channel == -1) return 0; if(div_mul){ // != 0 - divisors - flash_store_U32((uint32_t)&ADC_divisors[adc_channel], &val); + ADC_divisors[adc_channel] = val; }else{ // == 0 - mul - flash_store_U32((uint32_t)&ADC_multipliers[adc_channel], &val); + ADC_multipliers[adc_channel] = val; } adc_channel = -1; - P("stored\n", s); return 1; } + /** * Change divisor (work only in BYTE_MODE) * @param v - user value (sensor number) @@ -144,8 +144,9 @@ uint8_t try_ch_divmul(int32_t v, sendfun s){ */ uint8_t endswitchstate(int32_t v, sendfun s){ int32_t i; - if(v < 0 || v > 4){ - if(mode == BYTE_MODE) P("Wrong motor number\n", s); + if(v < 0 || v > 4){ // show all end-switches + for(i = 0; i < 5; i++) + endswitchstate(i, s); return 0; } i = check_ep(v); @@ -163,6 +164,11 @@ uint8_t endswitchstate(int32_t v, sendfun s){ if(mode == LINE_MODE) P(" ]\n", s); else s('\n'); } +/* +uint32_t h = (GPIO_IDR(GPIOD) & 0xff) | ((GPIO_IDR(GPIOB)<<2) & 0x300) | + ((GPIO_IDR(GPIOC)<<3) & 0x1C00) | ((GPIO_IDR(GPIOA)&0x100)<<5); +print_hex((uint8_t*)&h, 4, lastsendfun); +*/ return 0; } @@ -170,28 +176,32 @@ uint8_t endswitchstate(int32_t v, sendfun s){ * moves turret 'active_motor' to position v */ uint8_t move_turret(int32_t v, sendfun s){ - const int32_t maxpos[3] = {8, 6, 6}; // maximum position number for given turret + const int32_t maxpos[3] = {6, 6, 8}; // maximum position number for given turret int32_t sign = 1; if(active_motor > 2){ if(mode == BYTE_MODE) P("Wrong turret number\n", s); return 0; } int32_t m = maxpos[active_motor]; - if(v > m){ + if(v > m || v < 1){ if(mode == BYTE_MODE){ P("Wrong position, shoud be not more than ", s); print_int(m, s); } return 0; } + uint8_t curpos = check_ep(active_motor); + if(curpos == v){ // we are in that position + endswitchstate(active_motor, s); + return 1; + } move2pos[active_motor] = v; // check the nearest direction - uint8_t curpos = check_ep(active_motor); if(curpos){ // we are not between positions - if((v + m - curpos) > m/2) // rotation in positive direction will take more steps than in negative + if(((v + m - curpos) % m) > m/2) // rotation in positive direction will take more steps than in negative sign = -1; // move CCV } - return move_motor(active_motor, TURRETS_NEXT_POS_STEPS * sign); + return move_motor(active_motor, sign * TURRETS_NEXT_POS_STEPS); } /** @@ -207,7 +217,7 @@ void help(sendfun s){ pr("D\tturn AD7794 to double conversion mode"); pr(STR_ENDSW_STATE "\tshow end-switches state for given motor"); pr("F\tdump flash data"); - //pr("G"); + pr(STR_SHOW_PERIOD "\tget motors' speed"); pr("H\tshow this help"); pr("I\tturn off AD7794 init flag"); pr("J\tmove slits (0) wheel to Nth position"); @@ -226,13 +236,13 @@ void help(sendfun s){ //pr("W\t(reserved)"); pr("X\tset timer period for linear stages"); //pr("Y"); - //pr("Z"); + pr("Z\tShow motors' positions"); //pr("a"); //pr("b"); pr("c\tclose shutter"); pr("d\tchange value of ADC divisor No N"); //pr("e"); - //pr("f"); + pr("f\tsave current values of ADC mult/div to flash"); pr("g\tchange AD7794 gain"); pr(STR_SHTR_VOLTAGE "\tshow shutter voltage"); pr(STR_EXTADC_INIT "\tinit AD7794"); @@ -283,31 +293,24 @@ int parce_incoming_buf(char *buf, int len, sendfun s){ } }else if(mode == LINE_MODE){ // text mode: check for "]\n" presence uint8_t bad_cmd = 1; -s(buf[0]); -P(" check buffer in line mode: ", s); if(buf[0] == '['){ for(j = 1; j < len; j++){ -s(buf[j]); if(buf[j] != '\n') continue; // search end of line else{ if(buf[j-1] == ']'){ -P("OK, good!\n", s); bad_cmd = 0; len = j; buf[j] = 0; // truncate buffer to only one command break; } else{ -P("broken command!\n",s); return 0; // end of line without closing bracket } } }} else{ -P("wrong first\n",s ); return 0; } if(bad_cmd){ -P("not full\n",s); return len; // not enough data in buffer } } @@ -364,6 +367,16 @@ P("not full\n",s); I = endswitchstate; READINT(); break; + case 'f': // store flash data + if(mode != BYTE_MODE) return 0; + uint8_t f_flag = save_flashdata();// == 0 if all OK, or return error flag + if(f_flag){ + P("error! can't store data, errno: ", s); + print_int((int32_t) f_flag, s); + s('\n'); + }else + P("data stored successfully\n", s); + break; case 'F': // dump flash data (only in byte mode) if(mode != BYTE_MODE) return 0; dump_flash_data(s); @@ -373,6 +386,10 @@ P("not full\n",s); I = set_ADC_gain; READINT(); break; + case CMD_SHOW_PERIOD: // [G] get motors' speed + show_motors_period(s); + do_echo = 0; + break; case CMD_SHTR_VOLTAGE: // [h] show sHutter voltage * 100 if(mode == LINE_MODE) P("[ " STR_SHTR_VOLTAGE " ", s); print_int(shutter_voltage(), s); @@ -414,6 +431,7 @@ P("not full\n",s); print_int(power_voltage(), s); if(mode == LINE_MODE) P(" ]", s); newline(s); + do_echo = 0; break; case 'P': // (only for byte mode) if(mode != BYTE_MODE) return 0; @@ -472,6 +490,25 @@ P("not full\n",s); I = set_timr; READINT(); break; + case CMD_MOTOR_POSITION: // [Z]: show positions of all motors + get_motors_position(); + do_echo = 0; + break; +/* + case '_': + P("set: ", s); + print_int(GPIO_ODR(MOTOR_EN_PORT) & MOTOR_EN_MASK, s); + P(", get: ", s); + print_int(gpio_get(MOTOR_EN_PORT, MOTOR_EN_MASK), s); + s('\n'); + break; + case '(': + gpio_set(MOTOR_EN_PORT, MOTOR_EN_MASK); + break; + case ')': + gpio_clear(MOTOR_EN_PORT, MOTOR_EN_MASK); + break; +*/ case '\n': // show newline, space and tab as is case '\r': case ' ': diff --git a/with_opencm3/user_proto.h b/with_opencm3/user_proto.h index 8c19c96..11f7216 100644 --- a/with_opencm3/user_proto.h +++ b/with_opencm3/user_proto.h @@ -87,6 +87,8 @@ void print_hex(uint8_t *buff, uint8_t l, sendfun s); #define STR_STOP_ALL_MOTORS "B" #define CMD_ENDSW_STATE 'E' #define STR_ENDSW_STATE "E" +#define CMD_SHOW_PERIOD 'G' +#define STR_SHOW_PERIOD "G" #define CMD_SHTR_VOLTAGE 'h' #define STR_SHTR_VOLTAGE "h" #define CMD_EXTADC_INIT 'i' @@ -99,5 +101,7 @@ void print_hex(uint8_t *buff, uint8_t l, sendfun s); #define STR_SHTR_STATE "t" #define CMD_PRINT_TIME 'T' #define STR_PRINT_TIME "T" +#define CMD_MOTOR_POSITION 'Z' +#define STR_MOTOR_POSITION "Z" #endif // __USER_PROTO_H__