fixed bugs in shutter; need to check its work and finish readme

This commit is contained in:
Edward Emelianov 2023-12-07 18:02:30 +03:00
parent c9a264c46b
commit 33e4eb9e6a
16 changed files with 236 additions and 94 deletions

View File

@ -3,10 +3,12 @@
"active_layer": 0, "active_layer": 0,
"active_layer_preset": "All Layers", "active_layer_preset": "All Layers",
"auto_track_width": true, "auto_track_width": true,
"hidden_netclasses": [],
"hidden_nets": [], "hidden_nets": [],
"high_contrast_mode": 0, "high_contrast_mode": 0,
"net_color_mode": 1, "net_color_mode": 1,
"opacity": { "opacity": {
"images": 0.6,
"pads": 1.0, "pads": 1.0,
"tracks": 1.0, "tracks": 1.0,
"vias": 1.0, "vias": 1.0,

View File

@ -1,5 +1,6 @@
{ {
"board": { "board": {
"3dviewports": [],
"design_settings": { "design_settings": {
"defaults": { "defaults": {
"board_outline_line_width": 0.15, "board_outline_line_width": 0.15,
@ -138,7 +139,8 @@
"zones_allow_external_fillets": false, "zones_allow_external_fillets": false,
"zones_use_no_outline": true "zones_use_no_outline": true
}, },
"layer_presets": [] "layer_presets": [],
"viewports": []
}, },
"boards": [], "boards": [],
"cvpcb": { "cvpcb": {
@ -322,18 +324,23 @@
"rule_severities": { "rule_severities": {
"bus_definition_conflict": "error", "bus_definition_conflict": "error",
"bus_entry_needed": "error", "bus_entry_needed": "error",
"bus_label_syntax": "error",
"bus_to_bus_conflict": "error", "bus_to_bus_conflict": "error",
"bus_to_net_conflict": "error", "bus_to_net_conflict": "error",
"conflicting_netclasses": "error",
"different_unit_footprint": "error", "different_unit_footprint": "error",
"different_unit_net": "error", "different_unit_net": "error",
"duplicate_reference": "error", "duplicate_reference": "error",
"duplicate_sheet_names": "error", "duplicate_sheet_names": "error",
"endpoint_off_grid": "warning",
"extra_units": "error", "extra_units": "error",
"global_label_dangling": "warning", "global_label_dangling": "warning",
"hier_label_mismatch": "error", "hier_label_mismatch": "error",
"label_dangling": "error", "label_dangling": "error",
"lib_symbol_issues": "warning", "lib_symbol_issues": "warning",
"missing_bidi_pin": "warning",
"missing_input_pin": "warning",
"missing_power_pin": "error",
"missing_unit": "warning",
"multiple_net_names": "warning", "multiple_net_names": "warning",
"net_not_bus_member": "warning", "net_not_bus_member": "warning",
"no_connect_connected": "warning", "no_connect_connected": "warning",
@ -343,6 +350,7 @@
"pin_to_pin": "warning", "pin_to_pin": "warning",
"power_pin_not_driven": "error", "power_pin_not_driven": "error",
"similar_labels": "warning", "similar_labels": "warning",
"simulation_model_issue": "ignore",
"unannotated": "error", "unannotated": "error",
"unit_value_mismatch": "error", "unit_value_mismatch": "error",
"unresolved_variable": "error", "unresolved_variable": "error",
@ -360,7 +368,7 @@
"net_settings": { "net_settings": {
"classes": [ "classes": [
{ {
"bus_width": 12.0, "bus_width": 12,
"clearance": 0.2, "clearance": 0.2,
"diff_pair_gap": 0.25, "diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25, "diff_pair_via_gap": 0.25,
@ -374,10 +382,10 @@
"track_width": 0.2, "track_width": 0.2,
"via_diameter": 0.8, "via_diameter": 0.8,
"via_drill": 0.4, "via_drill": 0.4,
"wire_width": 6.0 "wire_width": 6
}, },
{ {
"bus_width": 12.0, "bus_width": 12,
"clearance": 0.3, "clearance": 0.3,
"diff_pair_gap": 0.25, "diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25, "diff_pair_via_gap": 0.25,
@ -386,16 +394,15 @@
"microvia_diameter": 0.3, "microvia_diameter": 0.3,
"microvia_drill": 0.1, "microvia_drill": 0.1,
"name": "0.5", "name": "0.5",
"nets": [],
"pcb_color": "rgba(0, 0, 0, 0.000)", "pcb_color": "rgba(0, 0, 0, 0.000)",
"schematic_color": "rgba(0, 0, 0, 0.000)", "schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.5, "track_width": 0.5,
"via_diameter": 1.2, "via_diameter": 1.2,
"via_drill": 0.6, "via_drill": 0.6,
"wire_width": 6.0 "wire_width": 6
}, },
{ {
"bus_width": 12.0, "bus_width": 12,
"clearance": 0.5, "clearance": 0.5,
"diff_pair_gap": 0.25, "diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25, "diff_pair_via_gap": 0.25,
@ -404,19 +411,20 @@
"microvia_diameter": 0.3, "microvia_diameter": 0.3,
"microvia_drill": 0.1, "microvia_drill": 0.1,
"name": "1", "name": "1",
"nets": [],
"pcb_color": "rgba(0, 0, 0, 0.000)", "pcb_color": "rgba(0, 0, 0, 0.000)",
"schematic_color": "rgba(0, 0, 0, 0.000)", "schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 1.0, "track_width": 1.0,
"via_diameter": 1.2, "via_diameter": 1.2,
"via_drill": 0.6, "via_drill": 0.6,
"wire_width": 6.0 "wire_width": 6
} }
], ],
"meta": { "meta": {
"version": 2 "version": 3
}, },
"net_colors": null "net_colors": null,
"netclass_assignments": null,
"netclass_patterns": []
}, },
"pcbnew": { "pcbnew": {
"last_paths": { "last_paths": {
@ -432,6 +440,8 @@
"schematic": { "schematic": {
"annotate_start_num": 0, "annotate_start_num": 0,
"drawing": { "drawing": {
"dashed_lines_dash_length_ratio": 12.0,
"dashed_lines_gap_length_ratio": 3.0,
"default_bus_thickness": 12.0, "default_bus_thickness": 12.0,
"default_junction_size": 40.0, "default_junction_size": 40.0,
"default_line_thickness": 6.0, "default_line_thickness": 6.0,
@ -466,7 +476,11 @@
"page_layout_descr_file": "", "page_layout_descr_file": "",
"plot_directory": "", "plot_directory": "",
"spice_adjust_passive_values": false, "spice_adjust_passive_values": false,
"spice_current_sheet_as_root": false,
"spice_external_command": "spice \"%I\"", "spice_external_command": "spice \"%I\"",
"spice_model_current_sheet_as_root": true,
"spice_save_all_currents": false,
"spice_save_all_voltages": false,
"subpart_first_id": 65, "subpart_first_id": 65,
"subpart_id_separator": 0 "subpart_id_separator": 0
}, },

View File

@ -26,9 +26,27 @@ You can find the device in `/dev/shutterX` (symlink to `/dev/ttyUSBX`).
## Commands ## Commands
* '0' - shutter CLO ### debugging options:
* '1' - shutter OPE * '0' - shutter OPE
* '2' - shutter HIZ * '1' - shutter CLO
* '2' - shutter OFF
* '3' - shutter HIZ
* 'W' - test watchdog
### configuration:
* '< n' - voltage on discharged capacitor (*100)
* '> n' - voltage on fully charged capacitor (*100)
* '# n' - duration of electrical pulse to open/close shutter (ms)
* '$ n' - duration of mechanical work to completely open/close shutter (ms)
* '* n' - shutter voltage multiplier
* '/ n' - shutter voltage divider (V=Vadc*M/D)
* 'c n' - open shutter when CCD ext level is n (0/1)
* 'd' - dump current config
* 'e' - erase flash storage
* 'h n' - shutter is opened when hall level is n (0/1)
* 's' - save configuration into flash
### common control:
* 'A' - get raw ADC values * 'A' - get raw ADC values
* 'C' - close shutter / abort exposition * 'C' - close shutter / abort exposition
* 'E n' - expose for n milliseconds * 'E n' - expose for n milliseconds
@ -39,11 +57,11 @@ You can find the device in `/dev/shutterX` (symlink to `/dev/ttyUSBX`).
* 'T' - get Tms * 'T' - get Tms
* 'v' - get Vdd (/100V) * 'v' - get Vdd (/100V)
* 'V' - get shutter voltage (/100V) * 'V' - get shutter voltage (/100V)
* 'W' - test watchdog
If you will enter wrong long message, will receive its echo back. Any wrong short command will show help list. If you will enter wrong long message, will receive its echo back. Any wrong short command will show help list.
### Shutter control ## Shutter control
Commands '0', '1' and '2' should be used only for debugging purposes. Commands '0', '1' and '2' should be used only for debugging purposes.
To open/close shutter use only 'O', 'C' and 'E' commands. To open/close shutter use only 'O', 'C' and 'E' commands.
@ -55,7 +73,7 @@ Command 'E' could return `OK`, `ERR` or `ERRNUM`/`I32OVERFLOW` in wrong number f
When exposition starts you will receive message `OK` and `shutter=opened`. After its end you'll got `exptime=...`, `shutter=closed`. When exposition starts you will receive message `OK` and `shutter=opened`. After its end you'll got `exptime=...`, `shutter=closed`.
If shutter can't be closed, you will give a lots of "exp=cantclose" and different error messages until problem be solved. To stop this error messages give command 'O'. If shutter can't be closed, you will give a lots of "exp=cantclose" and different error messages until problem be solved. To stop this error messages give command 'O'.
### Different commands ## Different commands
* 'A' will show raw values for all ADC channels: 0. - capacitor voltage, 1 - MCU temperature, 2 - MCU Vdd. You will give messages like `adcX=val`. * 'A' will show raw values for all ADC channels: 0. - capacitor voltage, 1 - MCU temperature, 2 - MCU Vdd. You will give messages like `adcX=val`.
* 't' - `mcut=val`, where val = T*10 degrC. * 't' - `mcut=val`, where val = T*10 degrC.
@ -68,8 +86,27 @@ If shutter can't be closed, you will give a lots of "exp=cantclose" and differen
* 'S' - several answers: * 'S' - several answers:
* `shutter=`: `closed`, `opened`, `error`, `process`, `wait` or `exposing` - shutter state * `shutter=`: `closed`, `opened`, `error`, `process`, `wait` or `exposing` - shutter state
* `expfor=...` (only when exposing by command Exxx) - show given exposition time
* `exptime=...` (only when shutter is opened) - show time since opening * `exptime=...` (only when shutter is opened) - show time since opening
* `regstate=`: `open`, `close`, `off` or `hiZ` - TLE5205 outputs state * `regstate=`: `open`, `close`, `off` or `hiZ` - TLE5205 outputs state
* `fbstate=`: `0` or `1` - TLE5205 FB out state (1 - error) * `fbstate=`: `0` or `1` - TLE5205 FB out state (1 - error: insufficient voltage or shutter absent)
* `hall=`: `0` or `1` - 1 for opened shutter, 0 for closed * `hall=`: `0` or `1` - 1 for opened shutter, 0 for closed
* `ccd=`: `0` or `1` - 1 for active (closed contacts) state of "CCD" input * `ccd=`: `0` or `1` - 1 for active (closed contacts) state of "CCD" input
## Configuration
All configuration stored in MCU flash memory, to dump current config just enter command 'd' and you will give an answer like
```
userconf_sz=16
ccdactive=1
hallactive=0
minvoltage=400
workvoltage=700
shuttertime=20
waitingtime=30
shtrvmul=143
shtrdiv=25
```
* ``
* `ccdactive` - is level of 'CCD' input to open shutter (1 to open on high and 0 to open on low signal)
* `hallactive`

View File

@ -44,8 +44,11 @@ void adc_setup(){
ADC1->SQR3 = (3 << 0) | (16<<5) | (17 << 10); ADC1->SQR3 = (3 << 0) | (16<<5) | (17 << 10);
ADC1->SQR1 = (NUMBER_OF_ADC_CHANNELS - 1) << 20; // amount of conversions ADC1->SQR1 = (NUMBER_OF_ADC_CHANNELS - 1) << 20; // amount of conversions
ADC1->CR1 = ADC_CR1_SCAN; // scan mode ADC1->CR1 = ADC_CR1_SCAN; // scan mode
// continuous mode & DMA; enable vref & Tsens; wake up ADC // DMA, continuous mode; enable vref & Tsens; enable SWSTART as trigger
ADC1->CR2 = ADC_CR2_DMA | ADC_CR2_TSVREFE | ADC_CR2_CONT | ADC_CR2_ADON; ADC1->CR2 = ADC_CR2_DMA | ADC_CR2_TSVREFE | ADC_CR2_CONT | ADC_CR2_EXTSEL | ADC_CR2_EXTTRIG;
// wake up ADC
ADC1->CR2 |= ADC_CR2_ADON;
__DSB();
// wait for Tstab - at least 1us // wait for Tstab - at least 1us
while(++ctr < 0xff) nop(); while(++ctr < 0xff) nop();
// calibration // calibration
@ -53,12 +56,9 @@ void adc_setup(){
ctr = 0; while((ADC1->CR2 & ADC_CR2_RSTCAL) && ++ctr < 0xfffff); ctr = 0; while((ADC1->CR2 & ADC_CR2_RSTCAL) && ++ctr < 0xfffff);
ADC1->CR2 |= ADC_CR2_CAL; ADC1->CR2 |= ADC_CR2_CAL;
ctr = 0; while((ADC1->CR2 & ADC_CR2_CAL) && ++ctr < 0xfffff); ctr = 0; while((ADC1->CR2 & ADC_CR2_CAL) && ++ctr < 0xfffff);
// turn ON ADC // clear possible errors and start
//ADC1->CR2 |= ADC_CR2_ADON;
__DSB();
ADC1->SR = 0; ADC1->SR = 0;
ADC1->CR2 |= ADC_CR2_SWSTART; ADC1->CR2 |= ADC_CR2_SWSTART;
} }

View File

@ -31,8 +31,12 @@ static uint32_t maxCnum = 1024 / sizeof(user_conf); // can't use blocksize here
.userconf_sz = sizeof(user_conf) \ .userconf_sz = sizeof(user_conf) \
,.hallactive = 0 \ ,.hallactive = 0 \
,.ccdactive = 1 \ ,.ccdactive = 1 \
,.minvoltage = 500 \ ,.minvoltage = 400 \
,.workvoltage = 1300 \ ,.workvoltage = 700 \
,.shutterrime = 20 \
,.waitingtime = 30 \
,.shtrVmul = 143 \
,.shtrVdiv = 25 \
} }
static int write2flash(const void*, const void*, uint32_t); static int write2flash(const void*, const void*, uint32_t);
@ -180,5 +184,9 @@ void dump_userconf(){
USB_sendstr("\nhallactive="); USB_putbyte('0' + the_conf.hallactive); USB_sendstr("\nhallactive="); USB_putbyte('0' + the_conf.hallactive);
USB_sendstr("\nminvoltage="); USB_sendstr(u2str(the_conf.minvoltage)); USB_sendstr("\nminvoltage="); USB_sendstr(u2str(the_conf.minvoltage));
USB_sendstr("\nworkvoltage="); USB_sendstr(u2str(the_conf.workvoltage)); USB_sendstr("\nworkvoltage="); USB_sendstr(u2str(the_conf.workvoltage));
USB_sendstr("\nshuttertime="); USB_sendstr(u2str(the_conf.shutterrime));
USB_sendstr("\nwaitingtime="); USB_sendstr(u2str(the_conf.waitingtime));
USB_sendstr("\nshtrvmul="); USB_sendstr(u2str(the_conf.shtrVmul));
USB_sendstr("\nshtrdiv="); USB_sendstr(u2str(the_conf.shtrVdiv));
newline(); newline();
} }

View File

@ -32,6 +32,10 @@ typedef struct __attribute__((packed, aligned(4))){
uint8_t hallactive : 1; // hall sensor active (shutter is opened when): 0 - low, 1 - high uint8_t hallactive : 1; // hall sensor active (shutter is opened when): 0 - low, 1 - high
uint16_t minvoltage; // minimal voltage on C (*100) uint16_t minvoltage; // minimal voltage on C (*100)
uint16_t workvoltage; // working voltage (*100) uint16_t workvoltage; // working voltage (*100)
uint16_t shutterrime; // opening/closing time (ms)
uint16_t waitingtime; // time to wait for mechanical work done (ms)
uint16_t shtrVmul; // multiplier of shutter voltage calculation
uint16_t shtrVdiv; // divider -//-
} user_conf; } user_conf;
extern user_conf the_conf; extern user_conf the_conf;

View File

@ -17,6 +17,7 @@
*/ */
#include "adc.h" #include "adc.h"
#include "flash.h"
#include "hardware.h" #include "hardware.h"
static inline void iwdg_setup(){ static inline void iwdg_setup(){
@ -71,8 +72,9 @@ static inline void gpio_setup(){
CRL(7, CNF_PUDINPUT | MODE_INPUT); CRL(7, CNF_PUDINPUT | MODE_INPUT);
// USB pullup (PA10) - pushpull output // USB pullup (PA10) - pushpull output
GPIOA->CRH = CRH(8, CNF_PPOUTPUT | MODE_SLOW) | CRH(10, CNF_PPOUTPUT | MODE_SLOW); GPIOA->CRH = CRH(8, CNF_PPOUTPUT | MODE_SLOW) | CRH(10, CNF_PPOUTPUT | MODE_SLOW);
// hall/ccd // hall/ccd: pulled up or down depending on settings
GPIOB->ODR = 1 | 1<<11; // if ccdactive==0 - shutter is closed when no output signals
GPIOB->ODR = ((the_conf.hallactive) ? 0: 1) | ((the_conf.ccdactive) ? 0 : 1<<11);
GPIOB->CRL = CRL(0, CNF_PUDINPUT | MODE_INPUT); GPIOB->CRL = CRL(0, CNF_PUDINPUT | MODE_INPUT);
GPIOB->CRH = CRH(11, CNF_PUDINPUT | MODE_INPUT); GPIOB->CRH = CRH(11, CNF_PUDINPUT | MODE_INPUT);
} }
@ -83,3 +85,8 @@ void hw_setup(){
adc_setup(); adc_setup();
} }
uint32_t getShutterVoltage(){
uint32_t val = getADCvoltage(CHSHTR);
val *= the_conf.shtrVmul;
return val / the_conf.shtrVdiv;
}

View File

@ -57,10 +57,7 @@ typedef enum{
#define CHKHALL() ((HALLPIN == (BTNPORT->IDR & HALLPIN)) == the_conf.hallactive) #define CHKHALL() ((HALLPIN == (BTNPORT->IDR & HALLPIN)) == the_conf.hallactive)
#define CHKCCD() ((CCDPIN == (BTNPORT->IDR & CCDPIN)) == the_conf.ccdactive) #define CHKCCD() ((CCDPIN == (BTNPORT->IDR & CCDPIN)) == the_conf.ccdactive)
// multiplyer of shutter voltage (due to R divider)
#define SHTRVMUL (13)
extern volatile uint32_t Tms; extern volatile uint32_t Tms;
void hw_setup(); void hw_setup();
uint32_t getShutterVoltage();

View File

@ -35,16 +35,15 @@ void sys_tick_handler(void){
int main(void){ int main(void){
char inbuff[MAXSTRLEN+1]; char inbuff[MAXSTRLEN+1];
StartHSE(); StartHSE();
hw_setup();
SysTick_Config(72000); SysTick_Config(72000);
USBPU_OFF(); USBPU_OFF();
hw_setup();
flashstorage_init(); flashstorage_init();
hw_setup();
USB_setup(); USB_setup();
// close shutter and only after that turn on USB pullup
while(!close_shutter() && Tms < the_conf.waitingtime) IWDG->KR = IWDG_REFRESH;
USBPU_ON(); USBPU_ON();
close_shutter();
uint32_t Terr = Tms + 2*ERRPERIOD; uint32_t Terr = Tms + 2*ERRPERIOD;
while(1){ while(1){
IWDG->KR = IWDG_REFRESH; // refresh watchdog IWDG->KR = IWDG_REFRESH; // refresh watchdog

View File

@ -156,16 +156,7 @@ char *getnum(const char *txt, uint32_t *N){
const char* helpmsg = const char* helpmsg =
"https://github.com/eddyem/stm32samples/tree/master/F1:F103/shutter build#" BUILD_NUMBER " @ " BUILD_DATE "\n" "https://github.com/eddyem/stm32samples/tree/master/F1:F103/shutter build#" BUILD_NUMBER " @ " BUILD_DATE "\n"
"'0' - shutter CLO\n" " common control:\n"
"'1' - shutter OPE\n"
"'2' - shutter HIZ\n"
"'< n' - voltage on discharged capacitor (*100)\n"
"'> n' - voltage on fully charged capacitor (*100)\n"
"'c n' - open shutter when CCD ext level is n (0/1)\n"
"'d' - dump current config\n"
"'e' - erase flash storage\n"
"'h n' - shutter is opened when hall level is n (0/1)\n"
"'s' - save configuration into flash\n"
"'A' - get raw ADC values\n" "'A' - get raw ADC values\n"
"'C' - close shutter / abort exposition\n" "'C' - close shutter / abort exposition\n"
"'E n' - expose for n milliseconds\n" "'E n' - expose for n milliseconds\n"
@ -176,6 +167,23 @@ const char* helpmsg =
"'T' - get Tms\n" "'T' - get Tms\n"
"'v' - get Vdd (/100V)\n" "'v' - get Vdd (/100V)\n"
"'V' - get shutter voltage (/100V)\n" "'V' - get shutter voltage (/100V)\n"
" configuration:\n"
"'< n' - voltage on discharged capacitor (*100)\n"
"'> n' - voltage on fully charged capacitor (*100)\n"
"'# n' - duration of electrical pulse to open/close shutter (ms)\n"
"'$ n' - duration of mechanical work to completely open/close shutter (ms)\n"
"'* n' - shutter voltage multiplier\n"
"'/ n' - shutter voltage divider (V=Vadc*M/D)\n"
"'c n' - open shutter when CCD ext level is n (0/1)\n"
"'d' - dump current config\n"
"'e' - erase flash storage\n"
"'h n' - shutter is opened when hall level is n (0/1)\n"
"'s' - save configuration into flash\n"
" debugging options:\n"
"'0' - shutter OPE\n"
"'1' - shutter CLO\n"
"'2' - shutter OFF\n"
"'3' - shutter HIZ\n"
"'W' - test watchdog\n" "'W' - test watchdog\n"
; ;
@ -198,19 +206,22 @@ void bufputchar(char c){
static const char *OK = "OK", *ERR = "ERR"; static const char *OK = "OK", *ERR = "ERR";
const char *parse_cmd(const char *buf){ const char *parse_cmd(const char *buf){
uint32_t u3;
initbuf(); initbuf();
if(buf[1] == '\n' || buf[1] == '\r' || !buf[1]){ // one symbol commands if(buf[1] == '\n' || buf[1] == '\r' || !buf[1]){ // one symbol commands
switch(*buf){ switch(*buf){
case '0': case '0':
SHTRCLOSE();
add2buf("regstate=close");
break;
case '1':
SHTROPEN(); SHTROPEN();
add2buf("regstate=open"); add2buf("regstate=open");
break; break;
case '1':
SHTRCLOSE();
add2buf("regstate=close");
break;
case '2': case '2':
SHTROFF();
add2buf("regstate=off");
break;
case '3':
SHTRHIZ(); SHTRHIZ();
add2buf("regstate=hiz"); add2buf("regstate=hiz");
break; break;
@ -267,9 +278,8 @@ const char *parse_cmd(const char *buf){
add2buf(u2str(getVdd())); add2buf(u2str(getVdd()));
break; break;
case 'V': case 'V':
u3 = getADCvoltage(CHSHTR) * SHTRVMUL;
add2buf("voltage="); add2buf("voltage=");
add2buf(u2str(u3)); add2buf(u2str(getShutterVoltage()));
break; break;
case 'W': case 'W':
USB_sendstr("Wait for reboot\n"); USB_sendstr("Wait for reboot\n");
@ -301,6 +311,30 @@ const char *parse_cmd(const char *buf){
the_conf.workvoltage = Num; the_conf.workvoltage = Num;
add2buf("workvoltage="); add2buf(u2str(the_conf.workvoltage)); add2buf("workvoltage="); add2buf(u2str(the_conf.workvoltage));
break; break;
case '#': // shuttertime
if(errnum) break;
if(Num < 5 || Num > 1000) return "ERRVAL\n";
the_conf.shutterrime = Num;
add2buf("shuttertime="); add2buf(u2str(the_conf.shutterrime));
break;
case '$': // waitingtime
if(errnum) break;
if(Num < 5 || Num > 1000) return "ERRVAL\n";
the_conf.waitingtime = Num;
add2buf("waitingtime="); add2buf(u2str(the_conf.waitingtime));
break;
case '*': // mult
if(errnum) break;
if(Num < 1) return "ERRVAL\n"; // avoid zeroing
the_conf.shtrVmul = Num;
add2buf("shtrvmul="); add2buf(u2str(the_conf.shtrVmul));
break;
case '/': // div
if(errnum) break;
if(Num < 1) return "ERRVAL\n"; // avoid zero dividing
the_conf.shtrVdiv = Num;
add2buf("shtrvdiv="); add2buf(u2str(the_conf.shtrVdiv));
break;
case 'c': // CCD active @ case 'c': // CCD active @
if(errnum) break; if(errnum) break;
the_conf.ccdactive = Num; the_conf.ccdactive = Num;

Binary file not shown.

View File

@ -30,7 +30,12 @@ static const char *states[SHUTTER_STATE_AMOUNT] = {
[SHUTTER_EXPOSE] = "exposing", [SHUTTER_EXPOSE] = "exposing",
}; };
static const char *regstates[4] = {"open", "close", "off", "hiZ"}; static const char *regstates[4] = {
[REG_OPEN] = "open",
[REG_CLOSE] = "close",
[REG_OFF] = "off",
[REG_HIZ] = "hiZ"
};
static const char *opcl[2] = {"closed", "opened"}; static const char *opcl[2] = {"closed", "opened"};
@ -39,13 +44,18 @@ static shutter_state nextstate = SHUTTER_RELAX;
static uint32_t Tstart = 0, Texp = 0, Topened = 0; static uint32_t Tstart = 0, Texp = 0, Topened = 0;
/**
* @brief changestate - open/close shutter and set next state to nxt
* @return TRUE if success
*/
static int changestate(int open, shutter_state nxt){ static int changestate(int open, shutter_state nxt){
if(shutterstate != SHUTTER_RELAX && shutterstate != SHUTTER_EXPOSE) return FALSE; // don't ready
if(open == CHKHALL()){ if(open == CHKHALL()){
shutterstate = SHUTTER_RELAX; //shutterstate = SHUTTER_RELAX;
return TRUE; // already opened or closed return TRUE; // already opened or closed
} }
if(getADCvoltage(CHSHTR) < the_conf.workvoltage / SHTRVMUL) return FALSE; if(getShutterVoltage() < the_conf.workvoltage) return FALSE;
if(shutterstate == SHUTTER_ERROR) return FALSE; //if(shutterstate == SHUTTER_ERROR) return FALSE;
if(open) SHTROPEN(); if(open) SHTROPEN();
else SHTRCLOSE(); else SHTRCLOSE();
shutterstate = SHUTTER_PROCESS; shutterstate = SHUTTER_PROCESS;
@ -74,12 +84,23 @@ int expose_shutter(uint32_t exptime){
void process_shutter(){ void process_shutter(){
static uint32_t T = 0; static uint32_t T = 0;
uint32_t V = getADCvoltage(CHSHTR)*SHTRVMUL; uint32_t V = getShutterVoltage();
switch(shutterstate){ switch(shutterstate){
case SHUTTER_ERROR: // error state: no shutter? case SHUTTER_ERROR: // error state: no shutter? - switch HIZ/OFF each 10ms
SHTROFF(); if(SHTRSTATE() == REG_HIZ){ // check in HiZ state: if the error still occurs?
shutterstate = SHUTTER_WAIT; if(!CHKFB()){
Tstart = Tms; shutterstate = SHUTTER_RELAX;
nextstate = SHUTTER_RELAX;
}else if(Tms - T > 10){
T = Tms;
SHTROFF(); // turn off for 10ms
}
}else{
if(Tms - T > 10){
T = Tms;
SHTRHIZ(); // and check error again
}
}
break; break;
case SHUTTER_PROCESS: // process opening or closing case SHUTTER_PROCESS: // process opening or closing
#ifdef EBUG #ifdef EBUG
@ -89,21 +110,21 @@ void process_shutter(){
USB_putbyte('\n'); USB_putbyte('\n');
} }
#endif #endif
if(Tms - Tstart > SHUTTER_TIME || V < the_conf.minvoltage){ if(Tms - Tstart > the_conf.shutterrime || V < the_conf.minvoltage){
SHTROFF(); SHTROFF();
shutterstate = SHUTTER_WAIT; shutterstate = SHUTTER_WAIT;
Tstart = Tms; Tstart = Tms;
} }
break; break;
case SHUTTER_WAIT: // wait for mechanical work done case SHUTTER_WAIT: // wait for mechanical work done
if(Tms - Tstart > WAITING_TIME){ if(Tms - Tstart > the_conf.waitingtime){
SHTRHIZ(); SHTRHIZ();
shutterstate = nextstate; shutterstate = nextstate;
int h = CHKHALL(); int h = CHKHALL();
if(h) Topened = Tms; if(h) Topened = Tms;
else{ else{
USB_sendstr("exptime="); USB_sendstr("exptime=");
USB_sendstr(u2str(Tms - Topened - SHUTTER_TIME)); USB_sendstr(u2str(Tms - Topened - the_conf.shutterrime));
USB_putbyte('\n'); USB_putbyte('\n');
} }
USB_sendstr("shutter="); USB_sendstr("shutter=");
@ -115,10 +136,18 @@ void process_shutter(){
// now Tstart is time when shutter was opened; wait until Tms - Tstart >= Texp // now Tstart is time when shutter was opened; wait until Tms - Tstart >= Texp
if(Tms - Tstart < Texp || T == Tms) break; // once per 1ms if(Tms - Tstart < Texp || T == Tms) break; // once per 1ms
T = Tms; T = Tms;
if(!close_shutter()) USB_sendstr("exp=cantclose\n"); if(!close_shutter()){
if(Tms - Tstart > Texp + the_conf.waitingtime){ // try to close not more than `waitingtime` ms
USB_sendstr("exp=cantclose\n");
shutterstate = SHUTTER_ERROR;
}
}
break; break;
default: default:
if(CHKFB()) shutterstate = SHUTTER_ERROR; if(CHKFB()){
shutterstate = SHUTTER_ERROR;
T = Tms;
}
break; break;
} }
static uint8_t oldbtnstate = 0; static uint8_t oldbtnstate = 0;
@ -141,6 +170,9 @@ void print_shutter_state(){
if(shutterstate != SHUTTER_RELAX) add2buf(states[shutterstate]); if(shutterstate != SHUTTER_RELAX) add2buf(states[shutterstate]);
else add2buf(opcl[CHKHALL()]); else add2buf(opcl[CHKHALL()]);
if(CHKHALL()){ if(CHKHALL()){
if(shutterstate == SHUTTER_EXPOSE){
add2buf("\nexpfor="); add2buf(u2str(Texp));
}
add2buf("\nexptime="); add2buf("\nexptime=");
add2buf(u2str(Tms - Topened)); add2buf(u2str(Tms - Topened));
} }

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject> <!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 8.0.2, 2023-09-20T11:20:10. --> <!-- Written by QtCreator 11.0.3, 2023-11-29T09:35:47. -->
<qtcreator> <qtcreator>
<data> <data>
<variable>EnvironmentId</variable> <variable>EnvironmentId</variable>
@ -8,7 +8,7 @@
</data> </data>
<data> <data>
<variable>ProjectExplorer.Project.ActiveTarget</variable> <variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="int">0</value> <value type="qlonglong">0</value>
</data> </data>
<data> <data>
<variable>ProjectExplorer.Project.EditorSettings</variable> <variable>ProjectExplorer.Project.EditorSettings</variable>
@ -28,7 +28,7 @@
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value> <value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap> </valuemap>
</valuemap> </valuemap>
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value> <value type="qlonglong" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">KOI8-R</value> <value type="QByteArray" key="EditorConfiguration.Codec">KOI8-R</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value> <value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value> <value type="int" key="EditorConfiguration.IndentSize">4</value>
@ -54,16 +54,29 @@
<value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value> <value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">true</value> <value type="bool" key="EditorConfiguration.inEntireDocument">true</value>
<value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value> <value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value>
<value type="bool" key="EditorConfiguration.tintMarginArea">true</value>
</valuemap> </valuemap>
</data> </data>
<data> <data>
<variable>ProjectExplorer.Project.PluginSettings</variable> <variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap"> <valuemap type="QVariantMap">
<valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks">
<value type="bool" key="AutoTest.Framework.Boost">true</value>
<value type="bool" key="AutoTest.Framework.CTest">false</value>
<value type="bool" key="AutoTest.Framework.Catch">true</value>
<value type="bool" key="AutoTest.Framework.GTest">true</value>
<value type="bool" key="AutoTest.Framework.QtQuickTest">true</value>
<value type="bool" key="AutoTest.Framework.QtTest">true</value>
</valuemap>
<valuemap type="QVariantMap" key="AutoTest.CheckStates"/>
<value type="int" key="AutoTest.RunAfterBuild">0</value>
<value type="bool" key="AutoTest.UseGlobal">true</value>
<valuemap type="QVariantMap" key="ClangTools"> <valuemap type="QVariantMap" key="ClangTools">
<value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value> <value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value>
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value> <value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value> <value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
<value type="int" key="ClangTools.ParallelJobs">4</value> <value type="int" key="ClangTools.ParallelJobs">4</value>
<value type="bool" key="ClangTools.PreferConfigFile">false</value>
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/> <valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/> <valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/> <valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
@ -78,9 +91,9 @@
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{91347f2c-5221-46a7-80b1-0a054ca02f79}</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{91347f2c-5221-46a7-80b1-0a054ca02f79}</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value> <value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value> <value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value> <value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0"> <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/eddy/Docs/SAO/ELECTRONICS/STM32/F1-srcs/shutter</value> <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/eddy/Docs/SAO/ELECTRONICS/STM32/F1-srcs/shutter</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
@ -91,7 +104,7 @@
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
</valuemap> </valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Сборка</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Сборка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Сборка</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Сборка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
@ -104,7 +117,7 @@
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
</valuemap> </valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Очистка</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Очистка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Очистка</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Очистка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
@ -117,10 +130,10 @@
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">По умолчанию</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">По умолчанию</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericBuildConfiguration</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericBuildConfiguration</value>
</valuemap> </valuemap>
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">1</value> <value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0"> <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value> <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Развёртывание</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Развёртывание</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Развёртывание</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Развёртывание</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
@ -130,24 +143,26 @@
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value> <value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap> </valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value> <value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0"> <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<valuelist type="QVariantList" key="CustomOutputParsers"/> <valuelist type="QVariantList" key="CustomOutputParsers"/>
<value type="int" key="PE.EnvironmentAspect.Base">2</value> <value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/> <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value> <value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value> <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value> <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
</valuemap> </valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value> <value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap> </valuemap>
</data> </data>
<data> <data>
<variable>ProjectExplorer.Project.TargetCount</variable> <variable>ProjectExplorer.Project.TargetCount</variable>
<value type="int">1</value> <value type="qlonglong">1</value>
</data> </data>
<data> <data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable> <variable>ProjectExplorer.Project.Updater.FileVersion</variable>

View File

@ -20,11 +20,6 @@
#include <stm32f1.h> #include <stm32f1.h>
// opening/closing time (ms)
#define SHUTTER_TIME (20)
// waiting for getting status time (ms)
#define WAITING_TIME (60)
typedef enum{ typedef enum{
SHUTTER_ERROR, // shutter is absent? SHUTTER_ERROR, // shutter is absent?
SHUTTER_RELAX, // powered off SHUTTER_RELAX, // powered off

View File

@ -23,7 +23,6 @@
void USB_setup(){ void USB_setup(){
NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn); NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn);
NVIC_DisableIRQ(USB_HP_CAN1_TX_IRQn); NVIC_DisableIRQ(USB_HP_CAN1_TX_IRQn);
USBPU_OFF();
RCC->APB1ENR |= RCC_APB1ENR_USBEN; RCC->APB1ENR |= RCC_APB1ENR_USBEN;
RCC->APB2ENR |= USB_RCC; RCC->APB2ENR |= USB_RCC;
USB->CNTR = USB_CNTR_FRES; // Force USB Reset USB->CNTR = USB_CNTR_FRES; // Force USB Reset
@ -35,7 +34,6 @@ void USB_setup(){
USB->ISTR = 0; USB->ISTR = 0;
USB->CNTR = USB_CNTR_RESETM | USB_CNTR_WKUPM; // allow only wakeup & reset interrupts USB->CNTR = USB_CNTR_RESETM | USB_CNTR_WKUPM; // allow only wakeup & reset interrupts
NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn); NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
USBPU_ON();
} }
static uint16_t lastaddr = LASTADDR_DEFAULT; static uint16_t lastaddr = LASTADDR_DEFAULT;

View File

@ -1,2 +1,2 @@
#define BUILD_NUMBER "84" #define BUILD_NUMBER "103"
#define BUILD_DATE "2023-11-29" #define BUILD_DATE "2023-12-07"