some modifications, shutter not work :(

This commit is contained in:
eddyem 2015-02-03 18:16:28 +03:00
parent 48b8dd8f88
commit f600aa9e8e
19 changed files with 839 additions and 73 deletions

Binary file not shown.

View File

@ -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:power
LIBS:device LIBS:device
LIBS:transistors LIBS:transistors
@ -41,7 +41,7 @@ $Descr A3 16535 11693
encoding utf-8 encoding utf-8
Sheet 1 12 Sheet 1 12
Title "IR-spectrometer Control System" Title "IR-spectrometer Control System"
Date "30 nov 2014" Date "28 jan 2015"
Rev "" Rev ""
Comp "SAO RAS" Comp "SAO RAS"
Comment1 "" Comment1 ""
@ -1818,6 +1818,4 @@ F 3 "" H 5700 2550 60 0000 C CNN
$EndComp $EndComp
Wire Wire Line Wire Wire Line
5700 2550 5700 2450 5700 2550 5700 2450
Entry Wire Line
8950 2200 9050 2300
$EndSCHEMATC $EndSCHEMATC

View File

@ -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:power
LIBS:device LIBS:device
LIBS:transistors LIBS:transistors
@ -41,7 +41,7 @@ $Descr A3 16535 11693
encoding utf-8 encoding utf-8
Sheet 3 12 Sheet 3 12
Title "MCU module on STM32F103" Title "MCU module on STM32F103"
Date "30 nov 2014" Date "28 jan 2015"
Rev "" Rev ""
Comp "SAO RAS" Comp "SAO RAS"
Comment1 "" Comment1 ""

View File

@ -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:power
LIBS:device LIBS:device
LIBS:transistors LIBS:transistors
@ -41,7 +41,7 @@ $Descr A4 11693 8268
encoding utf-8 encoding utf-8
Sheet 5 12 Sheet 5 12
Title "RS-232 level converter" Title "RS-232 level converter"
Date "30 nov 2014" Date "28 jan 2015"
Rev "" Rev ""
Comp "SAO RAS" Comp "SAO RAS"
Comment1 "" Comment1 ""

View File

@ -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:power
LIBS:device LIBS:device
LIBS:transistors LIBS:transistors
@ -41,7 +41,7 @@ $Descr A4 11693 8268
encoding utf-8 encoding utf-8
Sheet 12 12 Sheet 12 12
Title "Power load module" Title "Power load module"
Date "30 nov 2014" Date "28 jan 2015"
Rev "" Rev ""
Comp "SAO RAS" Comp "SAO RAS"
Comment1 "" Comment1 ""

View File

@ -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:power
LIBS:device LIBS:device
LIBS:transistors LIBS:transistors
@ -41,7 +41,7 @@ $Descr A4 11693 8268
encoding utf-8 encoding utf-8
Sheet 4 12 Sheet 4 12
Title "USB input circuit" Title "USB input circuit"
Date "30 nov 2014" Date "28 jan 2015"
Rev "" Rev ""
Comp "SAO RAS" Comp "SAO RAS"
Comment1 "" Comment1 ""

View File

@ -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:power
LIBS:device LIBS:device
LIBS:transistors LIBS:transistors
@ -41,7 +41,7 @@ $Descr A4 11693 8268
encoding utf-8 encoding utf-8
Sheet 8 12 Sheet 8 12
Title "Stepper motor module" Title "Stepper motor module"
Date "30 nov 2014" Date "28 jan 2015"
Rev "" Rev ""
Comp "SAO RAS" Comp "SAO RAS"
Comment1 "" Comment1 ""

View File

@ -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:power
LIBS:device LIBS:device
LIBS:transistors LIBS:transistors
@ -41,7 +41,7 @@ $Descr A4 11693 8268
encoding utf-8 encoding utf-8
Sheet 11 12 Sheet 11 12
Title "Power load module" Title "Power load module"
Date "30 nov 2014" Date "28 jan 2015"
Rev "" Rev ""
Comp "SAO RAS" Comp "SAO RAS"
Comment1 "" Comment1 ""

View File

@ -29,7 +29,23 @@
#include "hardware_ini.h" #include "hardware_ini.h"
#include "onewire.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 * Configure SPI ports
@ -129,21 +145,6 @@ void SysTick_init(){
systick_counter_enable(); 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 * Turn on ADC DMA for filling temperatures buffer
*/ */
@ -180,11 +181,11 @@ void ADC_init(){
rcc_periph_clock_enable(RCC_ADC1); rcc_periph_clock_enable(RCC_ADC1);
rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV4); rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV4);
rcc_periph_clock_enable(RCC_GPIOA | RCC_GPIOB | RCC_GPIOC); // clocking for ADC ports rcc_periph_clock_enable(RCC_GPIOA | RCC_GPIOB | RCC_GPIOC); // clocking for ADC ports
// channels 4-7: PA7-PA4 // 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); gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO4|GPIO5|GPIO6|GPIO7|GPIO1|GPIO0);
// channels 0,1: PB1, PB0 // channels 0,1: PB1, PB0 (ADC IN 8, 9)
gpio_set_mode(GPIOB, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO0|GPIO1); 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); gpio_set_mode(GPIOC, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO4|GPIO5);
// Make sure the ADC doesn't run during config // Make sure the ADC doesn't run during config
@ -215,9 +216,42 @@ void ADC_calibrate_and_start(){
adc_start_conversion_direct(ADC1); 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]; uint16_t tim2_buff[TIM2_DMABUFF_SIZE];

View File

@ -23,6 +23,16 @@
#ifndef __HARDWARE_INI_H__ #ifndef __HARDWARE_INI_H__
#define __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 #define TIM2_DMABUFF_SIZE 128
// 1-wire zero-state lengths (in us minus 1) // 1-wire zero-state lengths (in us minus 1)
#define OW_1 (9) #define OW_1 (9)
@ -96,6 +106,31 @@ void ADC_calibrate_and_start();
#define OW_RX_PORT GPIO_BANK_USART2_RX #define OW_RX_PORT GPIO_BANK_USART2_RX
#define OW_RX_PIN GPIO_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 init_ow_dmatimer();
void run_dmatimer(); void run_dmatimer();
extern uint8_t ow_done; extern uint8_t ow_done;

View File

@ -172,7 +172,9 @@ int main(){
// init ADC // init ADC
ADC_init(); ADC_init();
ADC_calibrate_and_start(); ADC_calibrate_and_start();
usb_connect(); // turn on USB usb_connect(); // turn on USB
shutter_init();
while(1){ while(1){
usbd_poll(usbd_dev); usbd_poll(usbd_dev);
if(usbdatalen){ // there's something in USB buffer if(usbdatalen){ // there's something in USB buffer
@ -194,6 +196,8 @@ int main(){
#endif #endif
} }
process_stepper_motors(); // check flags of motors' timers process_stepper_motors(); // check flags of motors' timers
process_shutter(); // shutter state machine
if(Timer - Old_timer > 999){ // one-second cycle if(Timer - Old_timer > 999){ // one-second cycle
Old_timer += 1000; Old_timer += 1000;
//OW_fill_ID(0); //OW_fill_ID(0);
@ -213,7 +217,7 @@ int main(){
print_time(lastsendfun); print_time(lastsendfun);
lastsendfun(' '); lastsendfun(' ');
for(i = 0; i < 8; i++){ for(i = 0; i < 8; i++){
print_int(ADC_value[i], lastsendfun); print_int(TRD_value(i), lastsendfun);
lastsendfun(' '); lastsendfun(' ');
} }
print_ad_vals(lastsendfun); print_ad_vals(lastsendfun);

View File

@ -42,7 +42,7 @@
#include "AD7794.h" #include "AD7794.h"
#include "onewire.h" #include "onewire.h"
#include "stepper_motors.h" #include "stepper_motors.h"
#include "sensors.h" #include "powerhw.h"
#define _U_ __attribute__((__unused__)) #define _U_ __attribute__((__unused__))
#define U8(x) ((uint8_t) x) #define U8(x) ((uint8_t) x)

259
with_opencm3/onewire.c.old Normal file
View File

@ -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<<cnt_bit);
//(write 'bit' to the 1-wire bus)
OW_SendBits(bit, 1);
OW_Wait_TX();
}
}
path=next;
cnt_num++;
}while(path && cnt_num < num);
return cnt_num;
}*/
uint8_t OW_Scan(uint8_t *buf, uint8_t num){
uint8_t flg, b[11], i;
flg = OW_Send(1, (uint8_t*)"\xcc\x33\xff\xff\xff\xff\xff\xff\xff\xff\xff", 11);
if(!flg) return 0;
OW_Wait_TX();
if(!OW_Get(11, b, 0)) return 0;
num += 2;
for(i = 2; i < num; i++) *buf++ = b[i];
return 1;
}
//OW_USART_X
/*
void OW_getTemp(){
uint8_t buf[9], i;
void printTBuf(){
uint8_t j;
OW_Send(0, (uint8_t*)"\xbe\xff\xff\xff\xff\xff\xff\xff\xff\xff", 10, buf, 9, 1);
for(j = 0; j != 9; j++)
printInt(&buf[j], 1);
newline();
}
// send broadcast message to start measurement
if(!OW_Send(1, (uint8_t*)"\xcc\x44", 2)) return;
Delay(1000);
// read values
if(dev_amount == 1){
if(OW_WriteCmd(OW_SKIP_ROM)) printTBuf();
}else{
for(i = 0; i < dev_amount; i++){
MSG("Device ", "ow");
USB_Send_Data(i + '0');
MSG(": ", 0);
if(OW_WriteCmd(OW_MATCH_ROM)){
OW_SendOnly(0, &ID_buf[i*8], 8);
printTBuf();
}
}
}
}
*/

196
with_opencm3/onewire.c__ Normal file
View File

@ -0,0 +1,196 @@
/*
* 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
// In/Out buffer
// uint8_t ow_buf[8];
/**
* 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;
}
}
/*
* 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<<cnt_bit);
//(write 'bit' to the 1-wire bus)
OW_SendBits(bit, 1);
}
}
//(output the just-completed ROM value)
path=next;
cnt_num++;
}while(path && cnt_num < num);
return cnt_num;
}

221
with_opencm3/powerhw.c Normal file
View File

@ -0,0 +1,221 @@
/*
* powerhw.c - functions to work with other power loads (shutter, heaters and so on)
*
* Copyright 2015 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* 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:
}
*/

View File

@ -1,7 +1,7 @@
/* /*
* sensors.h * powerhw.h
* *
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com> * Copyright 2015 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
* *
* This program is free software; you can redistribute it and/or modify * 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 * 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, * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA. * MA 02110-1301, USA.
*/ */
#pragma once #pragma once
#ifndef __SENSORS_H__ #ifndef __POWERHW_H__
#define __SENSORS_H__ #define __POWERHW_H__
#include "hardware_ini.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__

View File

@ -1,24 +0,0 @@
/*
* sensors.c - funtions to work with end-switches & MOSFETs
*
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* 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"

View File

@ -66,7 +66,7 @@ static void setup_timer(uint8_t N){
// 72MHz div 36 = 2MHz // 72MHz div 36 = 2MHz
timer_set_prescaler(Tim, 35); // prescaler is (div - 1) timer_set_prescaler(Tim, 35); // prescaler is (div - 1)
timer_continuous_mode(Tim); // automatically reload 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_set_period(Tim, Motor_period[N] - 1);
timer_enable_update_event(Tim); timer_enable_update_event(Tim);
timer_enable_irq(Tim, TIM_DIER_UIE); // update IRQ enable timer_enable_irq(Tim, TIM_DIER_UIE); // update IRQ enable

View File

@ -59,6 +59,8 @@ void print_ad_vals(sendfun s){
s(' '); s(' ');
} }
newline(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 case 'D': // double conversion
doubleconv = 1; doubleconv = 1;
break; break;
case 'A': // show ADC value case 'A': // show TRD values
//adc_start_conversion_direct(ADC1); //adc_start_conversion_direct(ADC1);
P("\n ADC value: ", s); P("\nTRD resistance: ", s);
for(j = 0; j < 8; j++){ for(j = 0; j < 8; j++){
print_int(ADC_value[j], s); print_int(TRD_value(i), s);
P("\t", s); s('\t');
} }
newline(s); newline(s);
break; break;
@ -168,6 +170,30 @@ void parce_incoming_buf(char *buf, int len, sendfun s){
/* case 'U': // test: init USART1 /* case 'U': // test: init USART1
UART_init(USART1); UART_init(USART1);
break; */ 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 case '\n': // show newline as is
break; break;
case '\r': case '\r':