A lot of errors fixed

This commit is contained in:
eddyem 2015-04-17 15:58:58 +03:00
parent 6bd9724193
commit 2c87dc4af9
13 changed files with 341 additions and 156 deletions

View File

@ -1,6 +1,6 @@
update=Ср 16 июл 2014 14:03:06 update=Ср 01 апр 2015 19:30:22
version=1 version=1
last_client=pcbnew last_client=kicad
[cvpcb] [cvpcb]
version=1 version=1
NetIExt=net NetIExt=net
@ -54,11 +54,13 @@ LibName34=vreg
LibName35=open-project LibName35=open-project
[pcbnew] [pcbnew]
version=1 version=1
PageLayoutDescrFile=
LastNetListRead=ALL.net LastNetListRead=ALL.net
UseCmpFile=1 UseCmpFile=1
PadDrill=0 PadDrill=0.7999999999999999
PadSizeH=2 PadDrillOvalY=0.7999999999999999
PadSizeV=2.5 PadSizeH=1.5
PadSizeV=2
PcbTextSizeV=1.5 PcbTextSizeV=1.5
PcbTextSizeH=1.5 PcbTextSizeH=1.5
PcbTextThickness=0.3 PcbTextThickness=0.3
@ -70,30 +72,3 @@ SolderMaskMinWidth=0
DrawSegmentWidth=0.4 DrawSegmentWidth=0.4
BoardOutlineThickness=0.3 BoardOutlineThickness=0.3
ModuleOutlineThickness=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

View File

@ -23,7 +23,12 @@
#include <libopencm3/stm32/flash.h> #include <libopencm3/stm32/flash.h>
#include <string.h> #include <string.h>
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, //.magick = FLASH_MAGICK,
._ADC_multipliers = {100000,100000,100000,100000,100000,100000,100000,100000, // TRD ._ADC_multipliers = {100000,100000,100000,100000,100000,100000,100000,100000, // TRD
26, // shutter 26, // shutter
@ -33,12 +38,13 @@ const flash_data Stored_Data __attribute__ ((aligned(FLASH_BLOCK_SIZE))) = {
25, // shutter 25, // shutter
7 // power 7 // power
} }
}
}; };
uint32_t flash_write_data(uint32_t *dataptr, uint16_t datalen){ uint8_t flash_write_data(uint32_t *dataptr, uint16_t datalen){
uint32_t start_address = (uint32_t)&Stored_Data; uint32_t start_address = (uint32_t)&(Flash_Data.all_stored);
uint16_t i, rem; uint16_t i, rem;
uint32_t ret = 0; uint8_t ret = 0;
flash_unlock(); flash_unlock();
DBG("erase\n"); DBG("erase\n");
//Erasing page //Erasing page
@ -76,14 +82,18 @@ endoffunction:
return ret; return ret;
} }
uint32_t flash_store_U32(uint32_t addr, uint32_t *data){ /**
flash_data Saved_Data; * save all data from RAM to flash
uint32_t sz, ptrdiff; */
sz = (uint32_t)&Stored_Data.last_addr - (uint32_t)&Stored_Data; uint8_t save_flashdata(){
ptrdiff = addr - (uint32_t)&Stored_Data; // uint32_t sz = (uint32_t)&Stored_Data.last_addr - (uint32_t)&Stored_Data;
memcpy((void*)&Saved_Data, (void*)&Stored_Data, sz); //return flash_write_data((uint32_t*)&Stored_Data, sz);
memcpy((void*)((uint32_t)&Saved_Data + ptrdiff), (void*)data, 4); return flash_write_data((uint32_t*)&Stored_Data, sizeof(stored_data));
return flash_write_data((uint32_t*)&Saved_Data, sz); }
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); P("\nADC multipliers: ", s);
for(i = 0; i < ADC_CHANNELS_NUMBER; i++){ for(i = 0; i < ADC_CHANNELS_NUMBER; i++){
if(i) P(", ", s); if(i) P(", ", s);
print_int(ADC_multipliers[i], s); print_int(Flash_Data.all_stored._ADC_multipliers[i], s);
} }
P("\nADC divisors: ", s); P("\nADC divisors: ", s);
for(i = 0; i < ADC_CHANNELS_NUMBER; i++){ for(i = 0; i < ADC_CHANNELS_NUMBER; i++){
if(i) P(", ", s); if(i) P(", ", s);
print_int(ADC_divisors[i], s); print_int(Flash_Data.all_stored._ADC_divisors[i], s);
} }
s('\n'); s('\n');
} }

View File

@ -32,7 +32,7 @@
* align by 2k & make size 2k for using with high density devices * align by 2k & make size 2k for using with high density devices
*/ */
#define FLASH_BLOCK_SIZE (2048) #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) #define FLASH_MAGICK ((uint32_t) 0xAA55A55A)
@ -41,16 +41,21 @@ typedef struct{
// A-D value[x] = ADU * ADC_multipliers[x] / ADC_divisors[x] // A-D value[x] = ADU * ADC_multipliers[x] / ADC_divisors[x]
uint32_t _ADC_multipliers[ADC_CHANNELS_NUMBER]; uint32_t _ADC_multipliers[ADC_CHANNELS_NUMBER];
uint32_t _ADC_divisors[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 char struct_end[0] __attribute__ ((aligned(FLASH_BLOCK_SIZE))); // this pointer provides size of structure multiple of page size
} flash_data; } flash_data;
extern const flash_data Stored_Data; extern stored_data Stored_Data;
#define ADC_multipliers Stored_Data._ADC_multipliers #define ADC_multipliers Stored_Data._ADC_multipliers
#define ADC_divisors Stored_Data._ADC_divisors #define ADC_divisors Stored_Data._ADC_divisors
void dump_flash_data(sendfun s); 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__ #endif // __FLASH_H__

View File

@ -137,7 +137,8 @@ void GPIO_init(){
// Shutter control: input pull up // Shutter control: input pull up
gpio_set_mode(SHUTTER_EXT_PORT, GPIO_MODE_INPUT, gpio_set_mode(SHUTTER_EXT_PORT, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_PULL_UPDOWN, SHUTTER_CAM_PIN | SHUTTER_MAN_PIN | SHUTTER_FBSW_PIN); 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 // shutter status LED: opendrain
gpio_set_mode(LED_SHUTTER_PORT, GPIO_MODE_OUTPUT_2_MHZ, gpio_set_mode(LED_SHUTTER_PORT, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_OPENDRAIN, LED_SHUTTER_PIN); GPIO_CNF_OUTPUT_OPENDRAIN, LED_SHUTTER_PIN);

View File

@ -97,6 +97,8 @@ void ADC_calibrate_and_start();
#define MOTOR_TIM1_PIN (GPIO6) #define MOTOR_TIM1_PIN (GPIO6)
#define MOTOR_TIM2_PORT (GPIOD) #define MOTOR_TIM2_PORT (GPIOD)
#define MOTOR_TIM2_PIN (GPIO15) #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 * 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_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) #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 // Shutter pins: PC0 & PC2 are polarity & on/off pins; PC1 is feedback pin
#define SHUTTER_PORT (GPIOC) #define SHUTTER_PORT (GPIOC)
#define SHUTTER_ON_PIN (GPIO2) #define SHUTTER_ON_PIN (GPIO2)
@ -145,9 +139,9 @@ void ADC_calibrate_and_start();
#define SHUTTER_VOLTAGE_THRES (2000) #define SHUTTER_VOLTAGE_THRES (2000)
// minimum voltage that should be on capasitor if power source is on // minimum voltage that should be on capasitor if power source is on
#define SHUTTER_UNDERVOLTAGE_THRES (700) #define SHUTTER_UNDERVOLTAGE_THRES (700)
// delay in operations (open/close) in us (according to shutter's datasheet it's about 12ms) // delay in operations (open/close) in milliseconds (according to shutter's datasheet it's about 12ms -> make 15)
#define SHUTTER_DELAY (12500) #define SHUTTER_DELAY (15)
// delay for error test // delay for error test (in microseconds)
#define SHUTTER_OP_DELAY (200) #define SHUTTER_OP_DELAY (200)
// ADC_value[8] is U36, ADC_value[9] is U10 // ADC_value[8] is U36, ADC_value[9] is U10

Binary file not shown.

View File

@ -137,18 +137,20 @@ void AD7794_init(){
int main(){ int main(){
//int i; //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; int oldusbdatalen = 0;
//SPI_read_status SPI_stat; //SPI_read_status SPI_stat;
// RCC clocking: 8MHz oscillator -> 72MHz system // RCC clocking: 8MHz oscillator -> 72MHz system
rcc_clock_setup_in_hse_8mhz_out_72mhz(); 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
GPIO_init(); GPIO_init();
steppers_init(); usb_disconnect(); // turn off USB while initializing all
// init USART1 // init USART1
UART_init(USART1); UART_init(USART1);
@ -173,9 +175,13 @@ int main(){
ADC_init(); ADC_init();
ADC_calibrate_and_start(); ADC_calibrate_and_start();
steppers_init();
usb_connect(); // turn on USB usb_connect(); // turn on USB
shutter_init(); shutter_init();
read_stored_data(); // copy stored data into RAM
LED_STATUS_OK(); // All initialized - light up LED LED_STATUS_OK(); // All initialized - light up LED
while(1){ while(1){
usbd_poll(usbd_dev); usbd_poll(usbd_dev);
@ -200,9 +206,19 @@ int main(){
process_stepper_motors(); // check flags of motors' timers process_stepper_motors(); // check flags of motors' timers
process_shutter(); // shutter state machine 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 if(Timer - Old_timer > 999){ // one-second cycle
Old_timer += 1000; 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); //OW_fill_ID(0);
//gpio_toggle(GPIOC, GPIO12); // toggle LED //gpio_toggle(GPIOC, GPIO12); // toggle LED
//gpio_toggle(GPIO_BANK_SPI2_MOSI, GPIO_SPI2_MOSI); //gpio_toggle(GPIO_BANK_SPI2_MOSI, GPIO_SPI2_MOSI);

View File

@ -22,10 +22,9 @@
#include "main.h" #include "main.h"
// state of shutter - global variable to omit interface functions // state of shutter - global variable to omit interface functions
shutter_state Shutter_State = SHUTTER_NOTREADY; shutter_state Shutter_State = SHUTTER_NOTREADY;
uint16_t Shutter_delay = SHUTTER_DELAY;
int8_t manual_pin_old_state = -1; int8_t manual_pin_old_state = -1;
int8_t camera_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 // function to be runned from timer irq
//void (*shutter_timer_fn)() = NULL; //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 #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 us - pause in microseconds
* @param fn_ready - function to run at end of pause * @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; if(!fn_ready) return;
//DBG("wait for previous .. "); //DBG("wait for previous .. ");
@ -55,12 +55,36 @@ void shutter_wait(uint32_t us, void(*fn_ready)()){
// wait for us*72 cycles // wait for us*72 cycles
SCB_DEMCR |= 0x01000000; SCB_DEMCR |= 0x01000000;
DWT_CYCCNT = 0; DWT_CYCCNT = 0;
DWT_CONTROL|= 1; // enable the counter DWT_CONTROL|= 1;
// for (i = 0; i < us; i++) __asm__("nop"); // for (i = 0; i < us; i++) __asm__("nop");
while(DWT_CYCCNT < us); while(DWT_CYCCNT < us);
fn_ready(); 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 // macro to open/close/set default state
// open shutter is 0:0 -> when MCU power is off, shutter "automatically" opens // 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) #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; static shutter_state old_State = SHUTTER_NOTREADY;
// test for undervoltage // test for undervoltage
if(shutter_voltage() < SHUTTER_UNDERVOLTAGE_THRES){ if(shutter_voltage() < SHUTTER_UNDERVOLTAGE_THRES){
ERR("shutter undervoltage\n"); // ERR("shutter undervoltage\n");
Shutter_State = SHUTTER_NOTREADY; Shutter_State = SHUTTER_NOTREADY;
shutter_off(); shutter_off();
return; return;
@ -92,20 +116,20 @@ void shutter_test(){
old_State = Shutter_State; old_State = Shutter_State;
Shutter_State = SHUTTER_INITIALIZED; Shutter_State = SHUTTER_INITIALIZED;
// test for wire breakage // test for wire breakage
DBG("breakage test\n"); // DBG("breakage test\n");
shutter_hiZ(); // 1,1: breakage test shutter_hiZ(); // 1,1: breakage test
shutter_wait(SHUTTER_OP_DELAY, shutter_test); shutter_wait_block(SHUTTER_OP_DELAY, shutter_test);
}else{ // check breakage }else{ // check breakage
if(shutter_error()){ // ERR==0 -> wire breakage if(shutter_error()){ // ERR==0 -> wire breakage
ERR("shutter wire breakage\n"); // ERR("shutter wire breakage\n");
Shutter_State = SHUTTER_NOTREADY; Shutter_State = SHUTTER_NOTREADY;
}else{ }else{
if(old_State == SHUTTER_NOTREADY){ if(old_State == SHUTTER_NOTREADY){
Shutter_State = SHUTTER_CLOSING; // close shutter on power on Shutter_State = SHUTTER_CLOSING; // close shutter on power on
DBG("ready!\n"); // DBG("ready!\n");
}else{ }else{
Shutter_State = old_State; Shutter_State = old_State;
DBG("no errors\n"); // DBG("no errors\n");
} }
} }
shutter_off(); shutter_off();
@ -131,8 +155,10 @@ void shutter_ready(){
LED_SHUTTER_CLOSE(); // turn off shutter status LED LED_SHUTTER_CLOSE(); // turn off shutter status LED
else{ else{
ERR("shutter is still opened\n"); ERR("shutter is still opened\n");
if(!changed_manually) Shutter_State = SHUTTER_NOTREADY; //if(!changed_manually)
Shutter_State = SHUTTER_NOTREADY;
} }
break;
case SHUTTER_OPENED: case SHUTTER_OPENED:
if(shutter_error()){ if(shutter_error()){
ERR("shutter overtemperature or undervoltage\n"); ERR("shutter overtemperature or undervoltage\n");
@ -142,7 +168,8 @@ void shutter_ready(){
LED_SHUTTER_OPEN(); // turn on LED LED_SHUTTER_OPEN(); // turn on LED
else{ else{
ERR("shutter is still closed\n"); ERR("shutter is still closed\n");
if(!changed_manually) Shutter_State = SHUTTER_NOTREADY; //if(!changed_manually)
Shutter_State = SHUTTER_NOTREADY;
} }
} }
break; break;
@ -163,15 +190,15 @@ void shutter_ready(){
ERR("wrong shutter state\n"); ERR("wrong shutter state\n");
print_shutter_state(lastsendfun); print_shutter_state(lastsendfun);
} }
changed_manually = 0; //changed_manually = 0;
shutter_off(); shutter_off();
if(Shutter_State == SHUTTER_NOTREADY) return; if(Shutter_State == SHUTTER_NOTREADY) return;
if(test_err){ if(test_err){
//DBG("now test for err\n"); //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{ }else{
// wait a lot of time to prevent false detections // 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 // feedback: floating input
gpio_set_mode(SHUTTER_PORT, GPIO_MODE_INPUT, gpio_set_mode(SHUTTER_PORT, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_FLOAT, SHUTTER_FB_PIN); 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"); //DBG("shutter fb ready\n");
shutter_off(); shutter_off();
//shutter_timer_fn = NULL; //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 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(){ void process_shutter(){
uint8_t man_pin_state, cam_pin_state, ext_open = 0, ext_close = 0; 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; if(Shutter_State == SHUTTER_NOTREADY) return;
// test state of external control pins // test state of external control pins
@ -240,7 +274,7 @@ void process_shutter(){
manual_pin_old_state = man_pin_state; manual_pin_old_state = man_pin_state;
}else if(manual_pin_old_state != man_pin_state){ // user changed switch state -> open/close }else if(manual_pin_old_state != man_pin_state){ // user changed switch state -> open/close
manual_pin_old_state = man_pin_state; manual_pin_old_state = man_pin_state;
changed_manually = 1; //changed_manually = 1;
if(man_pin_state){ // close if(man_pin_state){ // close
ext_close = 1; ext_close = 1;
}else{ // open }else{ // open
@ -252,13 +286,13 @@ void process_shutter(){
if(ext_open){ // external signal for opening shutter if(ext_open){ // external signal for opening shutter
if(Shutter_State != SHUTTER_OPENED && Shutter_State != SHUTTER_PROC_OPENING) if(Shutter_State != SHUTTER_OPENED && Shutter_State != SHUTTER_PROC_OPENING)
Shutter_State = SHUTTER_OPENING; Shutter_State = SHUTTER_OPENING;
else //else
changed_manually = 0; // changed_manually = 0;
}else if(ext_close){ // close shutter }else if(ext_close){ // close shutter
if(Shutter_State != SHUTTER_CLOSED && Shutter_State != SHUTTER_PROC_CLOSING) if(Shutter_State != SHUTTER_CLOSED && Shutter_State != SHUTTER_PROC_CLOSING)
Shutter_State = SHUTTER_CLOSING; Shutter_State = SHUTTER_CLOSING;
else //else
changed_manually = 0; // changed_manually = 0;
} }
if(Shutter_State != SHUTTER_OPENING && Shutter_State != SHUTTER_CLOSING) if(Shutter_State != SHUTTER_OPENING && Shutter_State != SHUTTER_CLOSING)
@ -288,7 +322,7 @@ void process_shutter(){
default: default:
return; 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); if(mode == BYTE_MODE) P(")\n", s);
else if(mode == LINE_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
} }
/** /**

View File

@ -39,7 +39,6 @@ typedef enum{
} shutter_state; } shutter_state;
extern shutter_state Shutter_State; extern shutter_state Shutter_State;
extern uint16_t Shutter_delay;
shutter_state shutter_init(); shutter_state shutter_init();
void process_shutter(); void process_shutter();

View File

@ -24,29 +24,37 @@
// TODO: function "move motor to given position" // TODO: function "move motor to given position"
static uint8_t timers_activated[2] = {0, 0}; // flag of activated timers static uint8_t timers_activated[2] = {0, 0}; // flag of activated timers
uint16_t Motor_period[2] = {1300, 1300}; // one step per 1.3ms static uint16_t Motor_period[2] = {3000, 2000};
uint32_t Turrets_pause = 2 * TURRETS_PAUSE_US / 1300; // pause in half-steps static uint32_t Turrets_pause = 2 * TURRETS_PAUSE_US / 3000; // pause in half-steps
volatile uint8_t timer_flag[2] = {0,0}; static volatile uint8_t timer_flag[2] = {0,0};
// amount of steps for each motor // 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 // 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 // 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 * Wait flags: if non-zero, flag just decremented
* (we need it to wait a little on turrets' fixed positions to omit Halls' histeresis) * (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 // 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 // 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}; uint8_t move2pos[5] = {0,0,0,0,0};
// number of positions passed for given // 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 // maximum amount of positions passed to reach given
#define MAX_POSITIONS_PASS (8) #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 * Setup stepper motors' timer Tim
* N == 0 for TIM3, == 1 for TIM4 * N == 0 for TIM3, == 1 for TIM4
@ -105,9 +113,10 @@ void steppers_init(){
GPIO_CNF_OUTPUT_PUSHPULL, MOTOR_TIM2_PIN); GPIO_CNF_OUTPUT_PUSHPULL, MOTOR_TIM2_PIN);
// EN pins // EN pins
// WARNING! EN pins would be shortened to GND in case of overcurrent/overheating // 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_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); gpio_clear(MOTOR_EN_PORT, MOTOR_EN_MASK);
// DIR pins // DIR pins
gpio_set_mode(MOTOR_DIR_PORT, GPIO_MODE_OUTPUT_2_MHZ, 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_plus[2] = {STAGE_CHECK(3, PLUS), STAGE_CHECK(4, PLUS)};
const uint8_t stage_minus[2] = {STAGE_CHECK(3, MINUS), STAGE_CHECK(4, MINUS)}; const uint8_t stage_minus[2] = {STAGE_CHECK(3, MINUS), STAGE_CHECK(4, MINUS)};
uint8_t negative_dir = 0; uint8_t negative_dir = 0;
num -= 3; // convern num to index in arrays if((uint16_t)(GPIO_ODR(MOTOR_DIR_PORT) & MOTOR_DIR_PIN(num))){ // negative direction
if((uint16_t)(GPIO_IDR(MOTOR_DIR_PORT) & MOTOR_DIR_PIN(num))){ // negative direction
negative_dir = 1; negative_dir = 1;
} }
num -= 3; // convern num to index in arrays
if(stage_plus[num] == curpos){ // we are on "+" end-switch if(stage_plus[num] == curpos){ // we are on "+" end-switch
if(!negative_dir){ // and wanna move to "+" if(!negative_dir){ // and wanna move to "+"
ERR("End-switch +\n"); ERR("End-switch +\n");
@ -180,6 +189,7 @@ uint8_t check_ep(uint8_t num){
return 0; return 0;
} }
/** /**
* Move motor Motor_number to User_value steps * Move motor Motor_number to User_value steps
* return 0 if motor is still moving * return 0 if motor is still moving
@ -192,6 +202,16 @@ uint8_t move_motor(uint8_t num, int32_t steps){
ERR("moving\n"); ERR("moving\n");
return 0; 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 #ifdef EBUG
if(mode == BYTE_MODE){ if(mode == BYTE_MODE){
P("move ", lastsendfun); P("move ", lastsendfun);
@ -201,11 +221,12 @@ uint8_t move_motor(uint8_t num, int32_t steps){
lastsendfun('\n'); lastsendfun('\n');
} }
#endif #endif
Motor_abs_steps[num] += steps; // fix absolute position
if(steps < 0){ if(steps < 0){
negative_dir = 1; negative_dir = 1;
Motor_step_increment[num] = -1;
steps = -steps; steps = -steps;
} }else
Motor_step_increment[num] = 1;
curpos = check_ep(num); curpos = check_ep(num);
lastpos[num] = curpos; lastpos[num] = curpos;
if(negative_dir){ if(negative_dir){
@ -220,10 +241,21 @@ uint8_t move_motor(uint8_t num, int32_t steps){
// set all flags and variables // set all flags and variables
Motor_steps[num] = steps; // we run in full-step mode! Motor_steps[num] = steps; // we run in full-step mode!
waits[num] = 0; waits[num] = 0;
accel[num] = START_MOTORS_ACCEL_IDX_4;
Motor_active[num] = 1; Motor_active[num] = 1;
if(num < 3) // this is turret -> reset counter of passed positions if(num < 3) // this is turret -> reset counter of passed positions
positions_pass[num] = 0; 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)); 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; 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)}; const uint8_t stage_minus[2] = {STAGE_CHECK(3, MINUS), STAGE_CHECK(4, MINUS)};
//if(!) return; //if(!) return;
MSG("stop motor ", "[ " STR_STOP_ALL_MOTORS " "); 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(Motor_active[num]){
if(!gpio_get(MOTOR_EN_PORT, MOTOR_EN_PIN(num)) && mode == LINE_MODE) 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)); gpio_clear(MOTOR_EN_PORT, MOTOR_EN_PIN(num));
Motor_active[num] = 0; Motor_active[num] = 0;
} }
@ -245,24 +284,16 @@ void stop_motor(uint8_t num){
move2pos[num] = 0; // reset target position value move2pos[num] = 0; // reset target position value
if(curpos == 1){ if(curpos == 1){
Motor_abs_steps[num] = 0; Motor_abs_steps[num] = 0;
goto retn;
}else{ }else{
if(curpos == 0) // a turret is out of fixed position 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 }else{ // linear stage
if(curpos == stage_minus[num-3]){ if(curpos == stage_minus[num-3]){
Motor_abs_steps[num] = 0; 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; Motor_steps[num] = 0;
retn:
BYTE_MSG(" absolute steps: "); BYTE_MSG(" absolute steps: ");
print_int(Motor_abs_steps[num], lastsendfun); print_int(Motor_abs_steps[num], lastsendfun);
if(mode == LINE_MODE) P(" ]", 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 uint32_t pins[] = {MOTOR_TIM1_PIN, MOTOR_TIM2_PIN};
const uint8_t startno[] = {0, 3}; const uint8_t startno[] = {0, 3};
const uint8_t stopno[] = {3, 5}; const uint8_t stopno[] = {3, 5};
//static uint8_t showcurpos[5] = {0,0,0,0,0};
uint8_t curpos; uint8_t curpos;
const uint32_t Tim[2] = {TIM3, TIM4};
for(j = 0; j < 2; j++){ 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]){ if(timer_flag[j]){
timer_flag[j] = 0; 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 gpio_toggle(ports[j], pins[j]); // change clock state
if(!gpio_get(ports[j], pins[j])){ // negative pulse - omit this half-step if(!gpio_get(ports[j], pins[j])){ // negative pulse - omit this half-step
continue; continue;
@ -303,16 +342,20 @@ void process_stepper_motors(){
//(what if there's some slipping or so on?) //(what if there's some slipping or so on?)
}else{ // we should move further }else{ // we should move further
if(waits[i]){ // waiting for position stabilisation if(waits[i]){ // waiting for position stabilisation
uint8_t got_new_position = 0;
waits[i]--; waits[i]--;
if(waits[i]) continue; // there's more half-steps to skip 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; 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 // turn on motor after pause
gpio_set(MOTOR_EN_PORT, MOTOR_EN_PIN(i)); gpio_set(MOTOR_EN_PORT, MOTOR_EN_PIN(i));
if(j == 1){ // this is a linear stage 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(move2pos[i]){ // we should move to specific position
if(curpos == move2pos[i]){ // we are on position if(curpos == move2pos[i]){ // we are on position
stop_motor(i); 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){ if(++positions_pass[i] > MAX_POSITIONS_PASS){
ERR("Can't reach given position"); ERR("Can't reach given position");
stop_motor(i); stop_motor(i);
@ -341,17 +384,33 @@ void process_stepper_motors(){
} }
if(lastpos[i] != curpos){ // transition process if(lastpos[i] != curpos){ // transition process
if(lastpos[i] == 0){ // come towards position if(lastpos[i] == 0){ // come towards position
waits[i] = Turrets_pause; if(j == 0){ // this is a turret: make pause & prepare acceleration for start
// turn off motor while a pause 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)); gpio_clear(MOTOR_EN_PORT, MOTOR_EN_PIN(i));
continue; continue;
} }
lastpos[i] = curpos; lastpos[i] = curpos;
} }
Motor_steps[i]--; 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); 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 * Interrupts: just set flag
*/ */

View File

@ -25,32 +25,45 @@
#include <libopencm3/stm32/timer.h> #include <libopencm3/stm32/timer.h>
// default pause to make sure that turret is on position // 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 // 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 #ifndef CONCAT
#define CONCAT(A, B) A ## B #define CONCAT(A, B) A ## B
#endif #endif
// check status of end-switches and Halls // check status of end-switches and Halls
/*
// Motor 0 == turret 0, PD0..PD3 // Motor 0 == turret 0, PD0..PD3
#define _CHECK_EP0 ((~GPIO_IDR(GPIOD)) & 0x0f) #define _CHECK_EP0 ((~GPIO_IDR(GPIOD)) & 0x0f)
// Motor 1 == turret 1, PD4..PD6 // Motor 1 == turret 1, PD4..PD6
#define _CHECK_EP1 (((~GPIO_IDR(GPIOD)) >> 4) & 0x07) #define _CHECK_EP1 (((~GPIO_IDR(GPIOD)) >> 4) & 0x07)
// Motor 2 == turret 2, PD7, PB6, PB7 // Motor 2 == turret 2, PD7, PB6, PB7
#define _CHECK_EP2 ((((~GPIO_IDR(GPIOD)) >> 7) & 0x01) | (((~GPIO_IDR(GPIOB))>> 6) & 0x03)) #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) // Motor 3 == long (VPHG, pupil stop) stage, PC7/PC8 (down/up)
#define _CHECK_EP3 (((~GPIO_IDR(GPIOC)) >> 7) & 0x03) #define _CHECK_EP3 (((~GPIO_IDR(GPIOC)) >> 7) & 0x03)
// Motor 4 == short (focus) stage, PC9/PA8 (down/up) // 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 // this macro returns end-switches & Hall status: 0 - not active, 1 - active
#define CHECK_EP(X) CONCAT(_CHECK_EP, X) #define CHECK_EP(X) CONCAT(_CHECK_EP, X)
// end-switches for motors 3,4 (stage 1 and stage 2): stop when direction positive/negative // end-switches for motors 3,4 (stage 1 and stage 2): stop when direction positive/negative
#define EP3PLUS 2 // down is 1, up is 2
#define EP3MINUS 1 // moving down is positive
#define EP4PLUS 2 #define EP3PLUS 1
#define EP4MINUS 1 #define EP3MINUS 2
#define EP4PLUS 1
#define EP4MINUS 2
#define STAGE_CHECK(N, DIR) CONCAT(EP ## N, DIR) #define STAGE_CHECK(N, DIR) CONCAT(EP ## N, DIR)
// setup ports: PA8, PB6, PB7, PC7..PC9, PD0..PD7 // 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 stop_motor(uint8_t num);
void set_motor_period(uint8_t num, uint16_t period); void set_motor_period(uint8_t num, uint16_t period);
uint8_t check_ep(uint8_t num); uint8_t check_ep(uint8_t num);
void get_motors_position();
void show_motors_period(sendfun s);
#endif // __STEPPER_MOTORS_H__ #endif // __STEPPER_MOTORS_H__

View File

@ -41,11 +41,11 @@ enum{
UVAL_ENTERED, // value entered but not printed UVAL_ENTERED, // value entered but not printed
UVAL_BAD // entered bad value 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); 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 READINT() do{i += read_int(&buf[i+1], len-i-1);}while(0)
#define WRONG_COMMAND() do{if(mode == BYTE_MODE) command = '?';}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 * change dividers/multipliers
* work only in BYTE_MODE * 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; uint32_t val = (uint32_t) v;
if(adc_channel == -1) return 0; if(adc_channel == -1) return 0;
if(div_mul){ // != 0 - divisors if(div_mul){ // != 0 - divisors
flash_store_U32((uint32_t)&ADC_divisors[adc_channel], &val); ADC_divisors[adc_channel] = val;
}else{ // == 0 - mul }else{ // == 0 - mul
flash_store_U32((uint32_t)&ADC_multipliers[adc_channel], &val); ADC_multipliers[adc_channel] = val;
} }
adc_channel = -1; adc_channel = -1;
P("stored\n", s);
return 1; return 1;
} }
/** /**
* Change divisor (work only in BYTE_MODE) * Change divisor (work only in BYTE_MODE)
* @param v - user value (sensor number) * @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){ uint8_t endswitchstate(int32_t v, sendfun s){
int32_t i; int32_t i;
if(v < 0 || v > 4){ if(v < 0 || v > 4){ // show all end-switches
if(mode == BYTE_MODE) P("Wrong motor number\n", s); for(i = 0; i < 5; i++)
endswitchstate(i, s);
return 0; return 0;
} }
i = check_ep(v); i = check_ep(v);
@ -163,6 +164,11 @@ uint8_t endswitchstate(int32_t v, sendfun s){
if(mode == LINE_MODE) P(" ]\n", s); if(mode == LINE_MODE) P(" ]\n", s);
else s('\n'); 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; return 0;
} }
@ -170,28 +176,32 @@ uint8_t endswitchstate(int32_t v, sendfun s){
* moves turret 'active_motor' to position v * moves turret 'active_motor' to position v
*/ */
uint8_t move_turret(int32_t v, sendfun s){ 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; int32_t sign = 1;
if(active_motor > 2){ if(active_motor > 2){
if(mode == BYTE_MODE) P("Wrong turret number\n", s); if(mode == BYTE_MODE) P("Wrong turret number\n", s);
return 0; return 0;
} }
int32_t m = maxpos[active_motor]; int32_t m = maxpos[active_motor];
if(v > m){ if(v > m || v < 1){
if(mode == BYTE_MODE){ if(mode == BYTE_MODE){
P("Wrong position, shoud be not more than ", s); P("Wrong position, shoud be not more than ", s);
print_int(m, s); print_int(m, s);
} }
return 0; 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; move2pos[active_motor] = v;
// check the nearest direction // check the nearest direction
uint8_t curpos = check_ep(active_motor);
if(curpos){ // we are not between positions 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 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("D\tturn AD7794 to double conversion mode");
pr(STR_ENDSW_STATE "\tshow end-switches state for given motor"); pr(STR_ENDSW_STATE "\tshow end-switches state for given motor");
pr("F\tdump flash data"); pr("F\tdump flash data");
//pr("G"); pr(STR_SHOW_PERIOD "\tget motors' speed");
pr("H\tshow this help"); pr("H\tshow this help");
pr("I\tturn off AD7794 init flag"); pr("I\tturn off AD7794 init flag");
pr("J\tmove slits (0) wheel to Nth position"); pr("J\tmove slits (0) wheel to Nth position");
@ -226,13 +236,13 @@ void help(sendfun s){
//pr("W\t(reserved)"); //pr("W\t(reserved)");
pr("X\tset timer period for linear stages"); pr("X\tset timer period for linear stages");
//pr("Y"); //pr("Y");
//pr("Z"); pr("Z\tShow motors' positions");
//pr("a"); //pr("a");
//pr("b"); //pr("b");
pr("c\tclose shutter"); pr("c\tclose shutter");
pr("d\tchange value of ADC divisor No N"); pr("d\tchange value of ADC divisor No N");
//pr("e"); //pr("e");
//pr("f"); pr("f\tsave current values of ADC mult/div to flash");
pr("g\tchange AD7794 gain"); pr("g\tchange AD7794 gain");
pr(STR_SHTR_VOLTAGE "\tshow shutter voltage"); pr(STR_SHTR_VOLTAGE "\tshow shutter voltage");
pr(STR_EXTADC_INIT "\tinit AD7794"); 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 }else if(mode == LINE_MODE){ // text mode: check for "]\n" presence
uint8_t bad_cmd = 1; uint8_t bad_cmd = 1;
s(buf[0]);
P(" check buffer in line mode: ", s);
if(buf[0] == '['){ if(buf[0] == '['){
for(j = 1; j < len; j++){ for(j = 1; j < len; j++){
s(buf[j]);
if(buf[j] != '\n') continue; // search end of line if(buf[j] != '\n') continue; // search end of line
else{ else{
if(buf[j-1] == ']'){ if(buf[j-1] == ']'){
P("OK, good!\n", s);
bad_cmd = 0; bad_cmd = 0;
len = j; buf[j] = 0; // truncate buffer to only one command len = j; buf[j] = 0; // truncate buffer to only one command
break; break;
} }
else{ else{
P("broken command!\n",s);
return 0; // end of line without closing bracket return 0; // end of line without closing bracket
} }
} }
}} else{ }} else{
P("wrong first\n",s );
return 0; return 0;
} }
if(bad_cmd){ if(bad_cmd){
P("not full\n",s);
return len; // not enough data in buffer return len; // not enough data in buffer
} }
} }
@ -364,6 +367,16 @@ P("not full\n",s);
I = endswitchstate; I = endswitchstate;
READINT(); READINT();
break; 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) case 'F': // dump flash data (only in byte mode)
if(mode != BYTE_MODE) return 0; if(mode != BYTE_MODE) return 0;
dump_flash_data(s); dump_flash_data(s);
@ -373,6 +386,10 @@ P("not full\n",s);
I = set_ADC_gain; I = set_ADC_gain;
READINT(); READINT();
break; 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 case CMD_SHTR_VOLTAGE: // [h] show sHutter voltage * 100
if(mode == LINE_MODE) P("[ " STR_SHTR_VOLTAGE " ", s); if(mode == LINE_MODE) P("[ " STR_SHTR_VOLTAGE " ", s);
print_int(shutter_voltage(), s); print_int(shutter_voltage(), s);
@ -414,6 +431,7 @@ P("not full\n",s);
print_int(power_voltage(), s); print_int(power_voltage(), s);
if(mode == LINE_MODE) P(" ]", s); if(mode == LINE_MODE) P(" ]", s);
newline(s); newline(s);
do_echo = 0;
break; break;
case 'P': // (only for byte mode) case 'P': // (only for byte mode)
if(mode != BYTE_MODE) return 0; if(mode != BYTE_MODE) return 0;
@ -472,6 +490,25 @@ P("not full\n",s);
I = set_timr; I = set_timr;
READINT(); READINT();
break; 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 '\n': // show newline, space and tab as is
case '\r': case '\r':
case ' ': case ' ':

View File

@ -87,6 +87,8 @@ void print_hex(uint8_t *buff, uint8_t l, sendfun s);
#define STR_STOP_ALL_MOTORS "B" #define STR_STOP_ALL_MOTORS "B"
#define CMD_ENDSW_STATE 'E' #define CMD_ENDSW_STATE 'E'
#define STR_ENDSW_STATE "E" #define STR_ENDSW_STATE "E"
#define CMD_SHOW_PERIOD 'G'
#define STR_SHOW_PERIOD "G"
#define CMD_SHTR_VOLTAGE 'h' #define CMD_SHTR_VOLTAGE 'h'
#define STR_SHTR_VOLTAGE "h" #define STR_SHTR_VOLTAGE "h"
#define CMD_EXTADC_INIT 'i' #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 STR_SHTR_STATE "t"
#define CMD_PRINT_TIME 'T' #define CMD_PRINT_TIME 'T'
#define STR_PRINT_TIME "T" #define STR_PRINT_TIME "T"
#define CMD_MOTOR_POSITION 'Z'
#define STR_MOTOR_POSITION "Z"
#endif // __USER_PROTO_H__ #endif // __USER_PROTO_H__