diff --git a/schematic/ALL.pdf b/schematic/ALL.pdf index 7cb4367..e5ba1ce 100644 Binary files a/schematic/ALL.pdf and b/schematic/ALL.pdf differ diff --git a/schematic/ALL.sch b/schematic/ALL.sch index 903c7ed..2bb98cf 100644 --- a/schematic/ALL.sch +++ b/schematic/ALL.sch @@ -1,4 +1,4 @@ -EESchema Schematic File Version 2 date Вс 30 ноя 2014 15:36:58 +EESchema Schematic File Version 2 date Ср 28 янв 2015 08:47:22 LIBS:power LIBS:device LIBS:transistors @@ -41,7 +41,7 @@ $Descr A3 16535 11693 encoding utf-8 Sheet 1 12 Title "IR-spectrometer Control System" -Date "30 nov 2014" +Date "28 jan 2015" Rev "" Comp "SAO RAS" Comment1 "" @@ -1818,6 +1818,4 @@ F 3 "" H 5700 2550 60 0000 C CNN $EndComp Wire Wire Line 5700 2550 5700 2450 -Entry Wire Line - 8950 2200 9050 2300 $EndSCHEMATC diff --git a/schematic/MCU_module.sch b/schematic/MCU_module.sch index fecbf33..7e13759 100644 --- a/schematic/MCU_module.sch +++ b/schematic/MCU_module.sch @@ -1,4 +1,4 @@ -EESchema Schematic File Version 2 date Вс 30 ноя 2014 15:36:58 +EESchema Schematic File Version 2 date Ср 28 янв 2015 08:47:22 LIBS:power LIBS:device LIBS:transistors @@ -41,7 +41,7 @@ $Descr A3 16535 11693 encoding utf-8 Sheet 3 12 Title "MCU module on STM32F103" -Date "30 nov 2014" +Date "28 jan 2015" Rev "" Comp "SAO RAS" Comment1 "" diff --git a/schematic/ST3232.sch b/schematic/ST3232.sch index 2c217d7..edbcd7c 100644 --- a/schematic/ST3232.sch +++ b/schematic/ST3232.sch @@ -1,4 +1,4 @@ -EESchema Schematic File Version 2 date Вс 30 ноя 2014 15:36:58 +EESchema Schematic File Version 2 date Ср 28 янв 2015 08:47:22 LIBS:power LIBS:device LIBS:transistors @@ -41,7 +41,7 @@ $Descr A4 11693 8268 encoding utf-8 Sheet 5 12 Title "RS-232 level converter" -Date "30 nov 2014" +Date "28 jan 2015" Rev "" Comp "SAO RAS" Comment1 "" diff --git a/schematic/Shutter_MOSFET.sch b/schematic/Shutter_MOSFET.sch index cd48994..27c599c 100644 --- a/schematic/Shutter_MOSFET.sch +++ b/schematic/Shutter_MOSFET.sch @@ -1,4 +1,4 @@ -EESchema Schematic File Version 2 date Вс 30 ноя 2014 15:36:58 +EESchema Schematic File Version 2 date Ср 28 янв 2015 08:47:22 LIBS:power LIBS:device LIBS:transistors @@ -41,7 +41,7 @@ $Descr A4 11693 8268 encoding utf-8 Sheet 12 12 Title "Power load module" -Date "30 nov 2014" +Date "28 jan 2015" Rev "" Comp "SAO RAS" Comment1 "" diff --git a/schematic/USB_inp.sch b/schematic/USB_inp.sch index 03018ab..af29db8 100644 --- a/schematic/USB_inp.sch +++ b/schematic/USB_inp.sch @@ -1,4 +1,4 @@ -EESchema Schematic File Version 2 date Вс 30 ноя 2014 15:36:58 +EESchema Schematic File Version 2 date Ср 28 янв 2015 08:47:22 LIBS:power LIBS:device LIBS:transistors @@ -41,7 +41,7 @@ $Descr A4 11693 8268 encoding utf-8 Sheet 4 12 Title "USB input circuit" -Date "30 nov 2014" +Date "28 jan 2015" Rev "" Comp "SAO RAS" Comment1 "" diff --git a/schematic/motors.sch b/schematic/motors.sch index 692c3b4..70c9828 100644 --- a/schematic/motors.sch +++ b/schematic/motors.sch @@ -1,4 +1,4 @@ -EESchema Schematic File Version 2 date Вс 30 ноя 2014 15:36:58 +EESchema Schematic File Version 2 date Ср 28 янв 2015 08:47:22 LIBS:power LIBS:device LIBS:transistors @@ -41,7 +41,7 @@ $Descr A4 11693 8268 encoding utf-8 Sheet 8 12 Title "Stepper motor module" -Date "30 nov 2014" +Date "28 jan 2015" Rev "" Comp "SAO RAS" Comment1 "" diff --git a/schematic/power_MOSFET.sch b/schematic/power_MOSFET.sch index 881d0ec..7e7bc69 100644 --- a/schematic/power_MOSFET.sch +++ b/schematic/power_MOSFET.sch @@ -1,4 +1,4 @@ -EESchema Schematic File Version 2 date Вс 30 ноя 2014 15:36:58 +EESchema Schematic File Version 2 date Ср 28 янв 2015 08:47:22 LIBS:power LIBS:device LIBS:transistors @@ -41,7 +41,7 @@ $Descr A4 11693 8268 encoding utf-8 Sheet 11 12 Title "Power load module" -Date "30 nov 2014" +Date "28 jan 2015" Rev "" Comp "SAO RAS" Comment1 "" diff --git a/with_opencm3/hardware_ini.c b/with_opencm3/hardware_ini.c index 7f4cb1f..1885d68 100644 --- a/with_opencm3/hardware_ini.c +++ b/with_opencm3/hardware_ini.c @@ -29,7 +29,23 @@ #include "hardware_ini.h" #include "onewire.h" -volatile uint16_t ADC_value[8]; // ADC DMA value +#define ADC_CHANNELS_NUMBER 10 +/* + * Due to inconvenient pins position on STM32F103VxT6 I had to make this strange location: + * my channel # -> ADC1/2 channel # + * 0 -> 9 PB1 + * 1 -> 8 PB0 + * 2 -> 15 PC5 + * 3 -> 14 PC4 + * 4 -> 7 PA7 + * 5 -> 6 PA6 + * 6 -> 5 PA5 + * 7 -> 4 PA4 + * U36 -> 1 PA1 + * U10 -> 0 PA0 + */ +uint8_t adc_channel_array[16] = {9,8,15,14,7,6,5,4,1,0}; +volatile uint16_t ADC_value[ADC_CHANNELS_NUMBER]; // ADC DMA value /* * Configure SPI ports @@ -129,21 +145,6 @@ void SysTick_init(){ systick_counter_enable(); } -/* - * Due to inconvenient pins position on STM32F103VxT6 I had to make this strange location: - * my channel # -> ADC1/2 channel # - * 0 -> 9 PB1 - * 1 -> 8 PB0 - * 2 -> 15 PC5 - * 3 -> 14 PC4 - * 4 -> 7 PA7 - * 5 -> 6 PA6 - * 6 -> 5 PA5 - * 7 -> 4 PA4 - */ -uint8_t adc_channel_array[16] = {9,8,15,14,7,6,5,4}; -#define ADC_CHANNELS_NUMBER 8 - /** * Turn on ADC DMA for filling temperatures buffer */ @@ -180,11 +181,11 @@ void ADC_init(){ rcc_periph_clock_enable(RCC_ADC1); rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV4); rcc_periph_clock_enable(RCC_GPIOA | RCC_GPIOB | RCC_GPIOC); // clocking for ADC ports - // channels 4-7: PA7-PA4 - gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO4|GPIO5|GPIO6|GPIO7); - // channels 0,1: PB1, PB0 + // channels 4-7: PA7-PA4 (ADC IN 4..7); U10 (PA0); U36 (PA1) + gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO4|GPIO5|GPIO6|GPIO7|GPIO1|GPIO0); + // channels 0,1: PB1, PB0 (ADC IN 8, 9) gpio_set_mode(GPIOB, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO0|GPIO1); - // channels 2,3: PC5, PC4 + // channels 2,3: PC5, PC4 (ADC IN14, 15) gpio_set_mode(GPIOC, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO4|GPIO5); // Make sure the ADC doesn't run during config @@ -215,9 +216,42 @@ void ADC_calibrate_and_start(){ adc_start_conversion_direct(ADC1); } +/** + * get shutter voltage in value of U*100 + * 3.3V == 4096 ADU, 36V comes to ADC in through resistor divider 4.7k:56k, so + * U36(V/100) = Uadc(ADU) * 607/47 * 33/40960 * 100 = Uadc(ADU) * 20031 / 19251 + * ==> approximately this is equal to val*26/25 or val + val/25 + */ +int shutter_voltage(){ + int val = SHUTTER_SENSE_VALUE; + val += val/25; + return val; +} +/** + * get power voltage in value of U*100 + * 3.3V == 4096 ADU, 10..12V comes to ADC in through resistor divider 4.7k:12k, so + * U10(V/100) = Uadc(ADU) * 167/47 * 33/40960 * 100 = Uadc(ADU) * 5511 / 19251 + * ==> approximately this is equal to val*2/7 + */ +int power_voltage(){ + int val = POWER_SENSE_VALUE * 2; + val /= 7; + return val; +} - +/** + * Resistance of TRD + * @param num - number of sensor + * @return R*100 + * we measure + */ +int TRD_value(uint8_t num){ + uint32_t v = ADC_value[num]; + uint32_t r = 100000 * v; + r /= (uint32_t)(4096 - v); + return (int) r; +} uint16_t tim2_buff[TIM2_DMABUFF_SIZE]; diff --git a/with_opencm3/hardware_ini.h b/with_opencm3/hardware_ini.h index f1b1d92..263f007 100644 --- a/with_opencm3/hardware_ini.h +++ b/with_opencm3/hardware_ini.h @@ -23,6 +23,16 @@ #ifndef __HARDWARE_INI_H__ #define __HARDWARE_INI_H__ +/* + * Timers: + * SysTick - system time + * TIM1 - not used + * TIM2 - 1-wire + * TIM3, TIM4 - stepper motors + * TIM5 - pause for shutter + */ + + #define TIM2_DMABUFF_SIZE 128 // 1-wire zero-state lengths (in us minus 1) #define OW_1 (9) @@ -96,6 +106,31 @@ void ADC_calibrate_and_start(); #define OW_RX_PORT GPIO_BANK_USART2_RX #define OW_RX_PIN GPIO_USART2_RX +/* + * Shutter defines + */ +// We use timer 5 to process pauses with shutter +#define Shutter_tim_isr tim5_isr +#define SHUTTER_TIM TIM5 +#define NVIC_SHUTTER_IRQ NVIC_TIM5_IRQ +// Shutter pins: PC0 & PC2 are polarity & on/off pins; PC1 is feedback pin +#define SHUTTER_PORT (GPIOC) +#define SHUTTER_ON_PIN (GPIO2) +#define SHUTTER_POLARITY_PIN (GPIO0) +#define SHUTTER_FB_PIN (GPIO1) +// voltage (*100) threshold to run shutter +#define SHUTTER_VOLTAGE_THRES (1000) +#define SHUTTER_UNDERVOLTAGE_THRES (500) +// delay in operations in us +#define SHUTTER_DELAY (10000) + +// ADC_value[8] is U36, ADC_value[9] is U10 +#define SHUTTER_SENSE_VALUE (ADC_value[8]) +#define POWER_SENSE_VALUE (ADC_value[9]) +int shutter_voltage(); +int power_voltage(); +int TRD_value(uint8_t num); + void init_ow_dmatimer(); void run_dmatimer(); extern uint8_t ow_done; diff --git a/with_opencm3/main.c b/with_opencm3/main.c index 7d091ee..2ab8138 100644 --- a/with_opencm3/main.c +++ b/with_opencm3/main.c @@ -172,7 +172,9 @@ int main(){ // init ADC ADC_init(); ADC_calibrate_and_start(); + usb_connect(); // turn on USB + shutter_init(); while(1){ usbd_poll(usbd_dev); if(usbdatalen){ // there's something in USB buffer @@ -194,6 +196,8 @@ int main(){ #endif } process_stepper_motors(); // check flags of motors' timers + process_shutter(); // shutter state machine + if(Timer - Old_timer > 999){ // one-second cycle Old_timer += 1000; //OW_fill_ID(0); @@ -213,7 +217,7 @@ int main(){ print_time(lastsendfun); lastsendfun(' '); for(i = 0; i < 8; i++){ - print_int(ADC_value[i], lastsendfun); + print_int(TRD_value(i), lastsendfun); lastsendfun(' '); } print_ad_vals(lastsendfun); diff --git a/with_opencm3/main.h b/with_opencm3/main.h index 00f2da0..7af7ddd 100644 --- a/with_opencm3/main.h +++ b/with_opencm3/main.h @@ -42,7 +42,7 @@ #include "AD7794.h" #include "onewire.h" #include "stepper_motors.h" -#include "sensors.h" +#include "powerhw.h" #define _U_ __attribute__((__unused__)) #define U8(x) ((uint8_t) x) diff --git a/with_opencm3/onewire.c.old b/with_opencm3/onewire.c.old new file mode 100644 index 0000000..3f574ee --- /dev/null +++ b/with_opencm3/onewire.c.old @@ -0,0 +1,259 @@ +/* + * onewire.c - functions to work with 1-wire devices + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#include "onewire.h" + +#define OW_0 0x00 +#define OW_1 0xff +#define OW_R 0xff +#define OW_RST 0xf0 + + +uint8_t dev_amount = 0; // amount of 1-wire devices +uint8_t ID_buf[64] = {0}; // 1-wire devices ID buffer (8 bytes for every device) +uint8_t NUM_buf[8] = {0}; // numerical identificators for each sensor + +/** + * this function sends bits of ow_byte (LSB first) to 1-wire line + * @param ow_byte - byte to convert + * @param Nbits - number of bits to send + */ +void OW_SendBits(uint8_t ow_byte, uint8_t Nbits){ + uint8_t i, byte; + if(Nbits == 0) return; + if(Nbits > 8) Nbits = 8; + for(i = 0; i < Nbits; i++){ + if(ow_byte & 0x01){ + byte = OW_1; + }else{ + byte = OW_0; + } + fill_uart_buff(OW_USART_X, byte); // send next "bit" + ow_byte = ow_byte >> 1; + } +} + +void OW_ClearBuff(){ + UART_buff *curbuff = get_uart_buffer(OW_USART_X); + curbuff->end = 0; +} + +/* + * Inverce conversion - read data (not more than 8 bits) + */ +uint8_t OW_ConvertByte(uint8_t *bits, uint8_t L){ + uint8_t ow_byte = 0, i, *st = bits; + if(L > 8) L = 8; // forget all other data + for(i = 0; i < L; i++, st++){ + ow_byte = ow_byte >> 1; // prepare for next bit filling + if(*st == OW_1){ + ow_byte |= 0x80; // MSB = 1 + } + } + ow_byte >>= (8 - L); +print_hex(bits, L, lastsendfun); +lastsendfun(' '); +print_hex(&ow_byte, 1, lastsendfun); +newline(lastsendfun); + return ow_byte; // shift to the end: L could be != 8 ??? +} + + +/* + * Configure peripherial ports (USART2) for 1-wire + */ +void OW_Init(){ + struct usb_cdc_line_coding owlc = { + .dwDTERate = 115200, + .bCharFormat = USB_CDC_1_STOP_BITS, + .bParityType = USB_CDC_NO_PARITY, + .bDataBits = 8, + }; + UART_init(OW_USART_X); + UART_setspeed(OW_USART_X, &owlc); +} + +/* + * 1-wire reset + * Reset procedure: USART settings are 9600,8,n,1, + * send 0xf0 then check what we get + * if not 0xf0 line is busy. + * Other operations work with next USART settings: 115200,8,n,1 + * + * return 1 in case of 1-wire devices present; otherwise return 0 + */ +uint8_t OW_Reset(){ + uint8_t ow_presence; + UART_buff *curbuff; + // change speed to 9600 + usart_set_baudrate(OW_USART_X, 9600); + //USART_ClearFlag(OW_USART_X, USART_FLAG_TC); + fill_uart_buff(OW_USART_X, OW_RST); // send 1 byte data + // wait for end of transmission + while(!(USART_SR(OW_USART_X) & USART_SR_TC)); + curbuff = get_uart_buffer(OW_USART_X); + if(!curbuff || !(curbuff->end)) return 0; // error reading + curbuff->end = 0; // zero counter + ow_presence = curbuff->buf[0]; + // change speed back + usart_set_baudrate(OW_USART_X, 115200); + // if there is any device on bus, it will pull it, so we'll get not 0xf0 + if(ow_presence != OW_RST){ + return 1; + } + // we get 0xf0 -> there's nothing on the bus + return 0; +} + +/** + * Procedure of 1-wire communications + * variables: + * @param sendReset - send RESET before transmission + * @param command - bytes sent to the bus (if we want to read, send OW_READ_SLOT) + * @param cLen - command buffer length (how many bytes to send) + * @return 1 if succeed, 0 if failure + */ +uint8_t OW_Send(uint8_t sendReset, uint8_t *command, uint8_t cLen){ + // if reset needed - send RESET and check bus + if(sendReset){ + if(OW_Reset() == 0){ + return 0; + } + } + while(cLen-- > 0){ + OW_SendBits(*command, 8); + command++; + } + return 1; +} + +/** + * Check USART IN buffer for ready & fill user buffer with data on success + * @param buflen - expected buffer length + * @param data - pointer for reading buffer (if reading needed must be at least buflen-readStart bytes) + * @param readStart - first byte to read (starts from 0) or OW_NO_READ (not read) + * @return 0 if buffer not ready; 1 if OK + */ +uint8_t OW_Get(uint8_t buflen, uint8_t *data, uint8_t readStart){ + UART_buff *curbuff = get_uart_buffer(OW_USART_X); + uint8_t *buff = curbuff->buf; + if(curbuff->end < buflen/8) return 0; + while(buflen-- > 0){ + if(readStart == 0){ + *data++ = OW_ConvertByte(buff, 8); + }else{ + if(readStart != OW_NO_READ){ + readStart--; + } + } + buff += 8; + } + curbuff->end = 0; // zero counter + return 1; +} + +/* + * scan 1-wire bus + * WARNING! The procedure works in real-time, so it is VERY LONG + * num - max number of devices + * buf - array for devices' ID's (8*num bytes) + * return amount of founded devices + * +uint8_t OW_Scan(uint8_t *buf, uint8_t num){ + unsigned long path,next,pos; + uint8_t bit,chk; + uint8_t cnt_bit, cnt_byte, cnt_num; + path=0; + cnt_num=0; + do{ + //(issue the 'ROM search' command) + if( 0 == OW_WriteCmd(OW_SEARCH_ROM) ) return 0; + OW_Wait_TX(); + OW_ClearBuff(); // clear RX buffer + next = 0; // next path to follow + pos = 1; // path bit pointer + for(cnt_byte = 0; cnt_byte != 8; cnt_byte++){ + buf[cnt_num*8 + cnt_byte] = 0; + for(cnt_bit = 0; cnt_bit != 8; cnt_bit++){ + //(read two bits, 'bit' and 'chk', from the 1-wire bus) + OW_SendBits(OW_R, 2); + OW_Wait_TX(); + bit = -----OW_ReadByte(); + chk = bit & 0x02; // bit 1 + bit = bit & 0x01; // bit 0 + if(bit && chk) return 0; // error + if(!bit && !chk){ // collision, both are zero + if (pos & path) bit = 1; // if we've been here before + else next = (path&(pos-1)) | pos; // else, new branch for next + pos <<= 1; + } + //(save this bit as part of the current ROM value) + if (bit) buf[cnt_num*8 + cnt_byte]|=(1< 8) Nbits = 8; + for(i = 0; i < Nbits; i++){ + if(ow_byte & 0x01){ + byte = OW_1; + }else{ + byte = OW_0; + } + fill_uart_buff(OW_USART_X, byte); // send next "bit" + ow_byte = ow_byte >> 1; + } +} + +/* + * Inverce conversion - read data (not more than 8 bits) + */ +uint8_t OW_ReadByte(){ + UART_buff *curbuff = get_uart_buffer(OW_USART_X); + uint8_t ow_byte = 0, i, L, *buf; + if(!curbuff || !(L = curbuff->end)) return 0; // no data? + if(L > 8) L = 8; // forget all other data + buf = curbuff->buf; + for(i = 0; i < L; i++, buf++){ + ow_byte = ow_byte >> 1; // prepare for next bit filling + if(*buf == OW_1){ + ow_byte |= 0x80; // MSB = 1 + } + } + return ow_byte >> (8 - L); // shift to the end: L could be != 8 ??? +} + + +/* + * Configure peripherial ports (USART2) for 1-wire + */ +void OW_Init(){ + struct usb_cdc_line_coding owlc = { + .dwDTERate = 115200, + .bCharFormat = USB_CDC_1_STOP_BITS, + .bParityType = USB_CDC_NO_PARITY, + .bDataBits = 8, + }; + UART_init(OW_USART_X); + UART_setspeed(OW_USART_X, &owlc); +} + +/* + * 1-wire reset + * Reset procedure: USART settings are 9600,8,n,1, + * send 0xf0 then check what we get + * if not 0xf0 line is busy. + * Other operations work with next USART settings: 115200,8,n,1 + * + * return 1 in case of 1-wire devices present; otherwise return 0 + */ +uint8_t OW_Reset() { + uint8_t ow_presence; + UART_buff *curbuff; + // change speed to 9600 + usart_set_baudrate(OW_USART_X, 9600); + //USART_ClearFlag(OW_USART_X, USART_FLAG_TC); + fill_uart_buff(OW_USART_X, OW_RST); // send 1 byte data + // wait for end of transmission + while(!(USART_SR(OW_USART_X) & USART_SR_TC)); + curbuff = get_uart_buffer(OW_USART_X); + if(!curbuff || !(curbuff->end)) return 0; // error reading + curbuff->end = 0; // zero counter + ow_presence = curbuff->buf[0]; + // change speed back + usart_set_baudrate(OW_USART_X, 115200); + // if there is any device on bus, it will pull it, so we'll get not 0xf0 + if(ow_presence != OW_RST){ + return 1; + } + // we get 0xf0 -> there's nothing on the bus + return 0; +} + +/* + * Procedure of 1-wire communications + * variables: + * sendReset - send RESET before transmission + * command - bytes sent to the bus (if we want to read, send OW_READ_SLOT) + * cLen - command buffer length (how many bytes to send) + * data - pointer for reading buffer (if reading needed) + * readStart - first byte to read (starts from 0) or OW_NO_READ (not read) + * + * return 1 if succeed, 0 if failure + */ +uint8_t OW_Send(uint8_t sendReset, uint8_t *command, uint8_t cLen, + uint8_t *data, uint8_t dLen, uint8_t readStart) { + // if reset needed - send RESET and check bus + if(sendReset){ + if(OW_Reset() == 0){ + return 0; + } + } + while(cLen > 0){ + OW_SendBits(*command, 8); + command++; + cLen--; + // wait for EOT + while(!(USART_SR(OW_USART_X) & USART_SR_TC)); + // put data from bus into user buffer + if(readStart == 0 && dLen > 0){ + *data = OW_ReadByte(); + data++; + dLen--; + }else{ + if(readStart != OW_NO_READ){ + readStart--; + } + } + } + return 1; +} + +/* + * scan 1-wire bus + * num - max number of devices + * buf - array for devices' ID's (8*num bytes) + * return amount of founded devices + */ +uint8_t OW_Scan(uint8_t *buf, uint8_t num) { + unsigned long path,next,pos; + uint8_t bit,chk; + uint8_t cnt_bit, cnt_byte, cnt_num; + path=0; + cnt_num=0; + do{ + //(issue the 'ROM search' command) + if( 0 == OW_WriteCmd(OW_SEARCH_ROM) ) return 0; + next=0; // next path to follow + pos=1; // path bit pointer + for(cnt_byte = 0; cnt_byte != 8; cnt_byte++){ + buf[cnt_num*8 + cnt_byte] = 0; + for(cnt_bit = 0; cnt_bit != 8; cnt_bit++){ + //(read two bits, 'bit' and 'chk', from the 1-wire bus) + OW_SendBits(OW_R, 2); + bit = OW_ReadByte(); + chk = bit & 0x02; // bit 1 + bit = bit & 0x01; // bit 0 + //bit = (ow_buf[0] == OW_1); chk = (ow_buf[1] == OW_1); + if(bit && chk) return 0; // error + if(!bit && !chk){ // collision, both are zero + if (pos & path) bit = 1; // if we've been here before + else next = (path&(pos-1)) | pos; // else, new branch for next + pos <<= 1; + } + //(save this bit as part of the current ROM value) + if (bit) buf[cnt_num*8 + cnt_byte]|=(1< + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include "main.h" +// state of shutter - global variable to omit interface functions +shutter_state Shutter_State = SHUTTER_NOTREADY; + +// function to be runned from timer irq +void (*shutter_timer_fn)() = NULL; + +/** + * Make background 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 + */ +void shutter_wait(int us, void(*fn_ready)()){ + if(!fn_ready) return; + while(shutter_timer_fn); // wait for ending of previous operation + shutter_timer_fn = fn_ready; + timer_set_period(SHUTTER_TIM, us); + timer_enable_counter(SHUTTER_TIM); +} + +// macro to open/close/set default state +#define shutter_open() do{gpio_clear(SHUTTER_PORT, SHUTTER_ON_PIN | SHUTTER_POLARITY_PIN);}while(0) +#define shutter_close() do{gpio_clear(SHUTTER_PORT, SHUTTER_ON_PIN); \ + gpio_set(SHUTTER_PORT, SHUTTER_POLARITY_PIN);}while(0) +#define shutter_hiZ() do{gpio_set(SHUTTER_PORT, SHUTTER_ON_PIN | SHUTTER_POLARITY_PIN);}while(0) +#define shutter_off() do{gpio_set(SHUTTER_PORT, SHUTTER_ON_PIN); \ + gpio_clear(SHUTTER_PORT, SHUTTER_POLARITY_PIN);}while(0) +#define shutter_error() ((gpio_get(SHUTTER_PORT, SHUTTER_FB_PIN) == 0)) + +/** + * after open/close pulse we should return bridge to default state + */ +void shutter_ready(){ + uint8_t test_err = 0; + switch (Shutter_State){ + case SHUTTER_CLOSED: // repeated pulse to check errors + case SHUTTER_OPENED: + if(shutter_error()){ + ERR("shutter vertemperature or undervoltage\n"); + Shutter_State = SHUTTER_NOTREADY; + } + break; + case SHUTTER_PROC_CLOSING: // closing - set to closed state + case SHUTTER_PROC_OPENING: // opening - set to opened state + if(shutter_error()){ + ERR("shutter short-circuit\n"); + Shutter_State = SHUTTER_NOTREADY; + shutter_off(); + }else{ + test_err = 1; + if(Shutter_State == SHUTTER_PROC_CLOSING) + Shutter_State = SHUTTER_CLOSED; + if(Shutter_State == SHUTTER_PROC_OPENING) + Shutter_State = SHUTTER_OPENED; + } + break; + default: + ERR("wrong shutter state\n"); + } + shutter_off(); + if(test_err) shutter_wait(SHUTTER_DELAY, shutter_ready); // test for overtemp or undervoltage +} + +/** + * Initialisation of shutter ports & test for shutter presense + * @return 1 if all OK, 0 in case of error + */ +shutter_state shutter_init(){ + Shutter_State = SHUTTER_NOTREADY; + // setup timer + rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_TIM5EN);// enable timer clocking + nvic_enable_irq(NVIC_SHUTTER_IRQ); + timer_reset(SHUTTER_TIM); + // timer have frequency of 1MHz, so, to make pause in Xus set period to X + // 36MHz of APB1 + timer_set_mode(SHUTTER_TIM, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); + // 72MHz div 72 = 1MHz + timer_set_prescaler(SHUTTER_TIM, 71); + timer_one_shot_mode(SHUTTER_TIM); // single pulse mode + timer_enable_preload(SHUTTER_TIM); // force changing period + timer_enable_update_event(SHUTTER_TIM); + timer_enable_irq(SHUTTER_TIM, TIM_DIER_UIE); // update IRQ enable + //DBG("shutter timer ready\n"); + // setup pins + // on/off & polarity: open drain + gpio_set_mode(SHUTTER_PORT, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_OPENDRAIN, SHUTTER_ON_PIN | SHUTTER_POLARITY_PIN); + // feedback: floating input + gpio_set_mode(SHUTTER_PORT, GPIO_MODE_INPUT, + GPIO_CNF_INPUT_FLOAT, SHUTTER_FB_PIN); + // test for wire breakage + shutter_hiZ(); // 1,1: breakage test + Delay(1); // wait for 1ms + if(shutter_error()){ // ERR==0 -> wire breakage + if(shutter_voltage() < SHUTTER_UNDERVOLTAGE_THRES) + ERR("shutter undervoltage\n"); + else + ERR("shutter wire breakage\n"); + }else{ + // Shutter_State = SHUTTER_CLOSING; // now try to close shutter + Shutter_State = SHUTTER_READY; + } + shutter_off(); + return Shutter_State; +} + +/** + * Finite-state machine processing for shutter + * (wait for capasitor charge and run needed functions + */ +void process_shutter(){ + if(Shutter_State == SHUTTER_NOTREADY) return; + if(shutter_error()){ + ERR("shutter some error\n"); + Shutter_State = SHUTTER_NOTREADY; + shutter_off(); + return; + } + if(Shutter_State != SHUTTER_OPENING && Shutter_State != SHUTTER_CLOSING) + return; + if(shutter_voltage() < SHUTTER_VOLTAGE_THRES) return; // capasitor isn't charged + switch (Shutter_State){ + case SHUTTER_OPENING: + Shutter_State = SHUTTER_PROC_OPENING; + shutter_open(); + break; + case SHUTTER_CLOSING: + Shutter_State = SHUTTER_PROC_CLOSING; + shutter_close(); + break; + default: + return; + } + shutter_wait(SHUTTER_DELAY, shutter_ready); +} + +void Shutter_tim_isr(){ + if(timer_get_flag(SHUTTER_TIM, TIM_SR_UIF)){ + // Clear compare interrupt flag + timer_clear_flag(SHUTTER_TIM, TIM_SR_UIF); + // and run needed function + if(shutter_timer_fn){ + shutter_timer_fn(); + shutter_timer_fn = NULL; + } + } +} + +/* + * printout shutter state + */ +void print_shutter_state(sendfun s){ + P("shutter ", s); +if(shutter_error()){ // ERR==0 -> wire breakage + P("(error) ", s); +} + switch (Shutter_State){ + case SHUTTER_READY: + P("ready", s); + break; + case SHUTTER_OPENED: + P("opened", s); + break; + case SHUTTER_CLOSED: + P("closed", s); + break; + case SHUTTER_OPENING: + case SHUTTER_CLOSING: + P("charged for ", s); + if(Shutter_State == SHUTTER_OPENING) P("opening", s); + else P("closing", s); + break; + case SHUTTER_PROC_OPENING: + case SHUTTER_PROC_CLOSING: + P("in process", s); + break; + default: // not ready or error + P("not initialised or broken", s); + } + newline(s); +} + + +/* + switch (Shutter_State){ + case SHUTTER_OPENED: + break; + case SHUTTER_CLOSED: + break; + case SHUTTER_OPENING: + break; + case SHUTTER_CLOSING: + break; + case SHUTTER_PROC_OPENING: + break; + case SHUTTER_PROC_CLOSING: + break; + default: + } +*/ diff --git a/with_opencm3/sensors.h b/with_opencm3/powerhw.h similarity index 50% rename from with_opencm3/sensors.h rename to with_opencm3/powerhw.h index b1584aa..081763a 100644 --- a/with_opencm3/sensors.h +++ b/with_opencm3/powerhw.h @@ -1,7 +1,7 @@ /* - * sensors.h + * powerhw.h * - * Copyright 2014 Edward V. Emelianov + * Copyright 2015 Edward V. Emelianov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,12 +18,29 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ + #pragma once -#ifndef __SENSORS_H__ -#define __SENSORS_H__ +#ifndef __POWERHW_H__ +#define __POWERHW_H__ #include "hardware_ini.h" +// Shutter finite-state machine states +typedef enum{ + SHUTTER_NOTREADY = 0, // initialisation - not ready, or error in work + SHUTTER_READY, + SHUTTER_OPENED, // shutter is in opened state + SHUTTER_CLOSED, // shutter is in closed state + SHUTTER_OPENING, // user is waiting for opening + SHUTTER_CLOSING, // user is waiting for closing + SHUTTER_PROC_OPENING, // shuter in work - waits for opening + SHUTTER_PROC_CLOSING // shuter in work - waits for closing +} shutter_state; +extern shutter_state Shutter_State; -#endif // __SENSORS_H__ +shutter_state shutter_init(); +void process_shutter(); +void print_shutter_state(sendfun s); + +#endif // __POWERHW_H__ diff --git a/with_opencm3/sensors.c b/with_opencm3/sensors.c deleted file mode 100644 index 2a1e647..0000000 --- a/with_opencm3/sensors.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * sensors.c - funtions to work with end-switches & MOSFETs - * - * Copyright 2014 Edward V. Emelianov - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -#include "main.h" -#include "sensors.h" - diff --git a/with_opencm3/stepper_motors.c b/with_opencm3/stepper_motors.c index 79bbef0..e5f922c 100644 --- a/with_opencm3/stepper_motors.c +++ b/with_opencm3/stepper_motors.c @@ -66,7 +66,7 @@ static void setup_timer(uint8_t N){ // 72MHz div 36 = 2MHz timer_set_prescaler(Tim, 35); // prescaler is (div - 1) timer_continuous_mode(Tim); // automatically reload - timer_enable_preload(Tim); // force changing period + timer_disable_preload(Tim); // force changing period timer_set_period(Tim, Motor_period[N] - 1); timer_enable_update_event(Tim); timer_enable_irq(Tim, TIM_DIER_UIE); // update IRQ enable diff --git a/with_opencm3/user_proto.c b/with_opencm3/user_proto.c index b1e0f36..039be47 100644 --- a/with_opencm3/user_proto.c +++ b/with_opencm3/user_proto.c @@ -59,6 +59,8 @@ void print_ad_vals(sendfun s){ s(' '); } newline(s); + }else{ + P("no AD7794 found\n", s); } } @@ -117,12 +119,12 @@ void parce_incoming_buf(char *buf, int len, sendfun s){ case 'D': // double conversion doubleconv = 1; break; - case 'A': // show ADC value + case 'A': // show TRD values //adc_start_conversion_direct(ADC1); - P("\n ADC value: ", s); + P("\nTRD resistance: ", s); for(j = 0; j < 8; j++){ - print_int(ADC_value[j], s); - P("\t", s); + print_int(TRD_value(i), s); + s('\t'); } newline(s); break; @@ -168,6 +170,30 @@ void parce_incoming_buf(char *buf, int len, sendfun s){ /* case 'U': // test: init USART1 UART_init(USART1); break; */ + case 'p': // show motors voltage * 100 + print_int(power_voltage(), s); + newline(s); + break; + case 'h': // show sHutter voltage * 100 + print_int(shutter_voltage(), s); + newline(s); + break; + case 'r': // reinit shutter + shutter_init(); + break; + case 't': // print shutter state + print_shutter_state(s); + break; + case 'c': // close shutter + if(Shutter_State != SHUTTER_CLOSED) + Shutter_State = SHUTTER_CLOSING; + else P("alerady closed\n", s); + break; + case 'o': // open shutter + if(Shutter_State != SHUTTER_OPENED) + Shutter_State = SHUTTER_OPENING; + else P("alerady opened\n", s); + break; case '\n': // show newline as is break; case '\r':