restructuring
147
F0:F030,F042,F072/Socket_fans/Makefile
Normal file
@@ -0,0 +1,147 @@
|
||||
BINARY = sockfans
|
||||
BOOTPORT ?= /dev/ttyUSB0
|
||||
BOOTSPEED ?= 57600
|
||||
# MCU FAMILY
|
||||
FAMILY = F0
|
||||
# MCU code
|
||||
MCU = F072xB
|
||||
# hardware definitions
|
||||
#DEFS += -DEBUG
|
||||
# change this linking script depending on particular MCU model,
|
||||
# for example, if you have STM32F103VBT6, you should write:
|
||||
LDSCRIPT = stm32f0728.ld
|
||||
|
||||
INDEPENDENT_HEADERS=
|
||||
|
||||
FP_FLAGS ?= -msoft-float
|
||||
ASM_FLAGS = -mthumb -mcpu=cortex-m0 -march=armv6-m -mtune=cortex-m0
|
||||
ARCH_FLAGS = $(ASM_FLAGS) $(FP_FLAGS)
|
||||
|
||||
###############################################################################
|
||||
# Executables
|
||||
OPREFIX ?= /opt/bin/arm-none-eabi
|
||||
#PREFIX ?= /usr/x86_64-pc-linux-gnu/arm-none-eabi/gcc-bin/7.3.0/arm-none-eabi
|
||||
PREFIX ?= $(OPREFIX)
|
||||
|
||||
RM := rm -f
|
||||
RMDIR := rmdir
|
||||
CC := $(PREFIX)-gcc
|
||||
LD := $(PREFIX)-gcc
|
||||
AR := $(PREFIX)-ar
|
||||
AS := $(PREFIX)-as
|
||||
OBJCOPY := $(OPREFIX)-objcopy
|
||||
OBJDUMP := $(OPREFIX)-objdump
|
||||
GDB := $(OPREFIX)-gdb
|
||||
STFLASH := $(shell which st-flash)
|
||||
STBOOT := $(shell which stm32flash)
|
||||
DFUUTIL := $(shell which dfu-util)
|
||||
|
||||
###############################################################################
|
||||
# Source files
|
||||
OBJDIR = mk
|
||||
LDSCRIPT ?= $(BINARY).ld
|
||||
SRC := $(wildcard *.c)
|
||||
OBJS := $(addprefix $(OBJDIR)/, $(SRC:%.c=%.o))
|
||||
STARTUP = $(OBJDIR)/startup.o
|
||||
OBJS += $(STARTUP)
|
||||
DEPS := $(OBJS:.o=.d)
|
||||
|
||||
INC_DIR ?= ../inc
|
||||
|
||||
INCLUDE := -I$(INC_DIR)/Fx -I$(INC_DIR)/cm
|
||||
LIB_DIR := $(INC_DIR)/ld
|
||||
|
||||
###############################################################################
|
||||
# C flags
|
||||
CFLAGS += -O2 -g -MD -D__thumb2__=1
|
||||
CFLAGS += -Wall -Werror -Wextra -Wshadow -Wimplicit-function-declaration
|
||||
CFLAGS += -Wredundant-decls $(INCLUDE)
|
||||
# -Wmissing-prototypes -Wstrict-prototypes
|
||||
CFLAGS += -fno-common -ffunction-sections -fdata-sections
|
||||
|
||||
###############################################################################
|
||||
# Linker flags
|
||||
LDFLAGS += --static -nostartfiles
|
||||
#--specs=nano.specs
|
||||
LDFLAGS += -L$(LIB_DIR)
|
||||
LDFLAGS += -T$(LDSCRIPT)
|
||||
LDFLAGS += -Wl,-Map=$(OBJDIR)/$(BINARY).map
|
||||
LDFLAGS += -Wl,--gc-sections
|
||||
|
||||
###############################################################################
|
||||
# Used libraries
|
||||
LDLIBS += -Wl,--start-group -lc -lgcc -Wl,--end-group
|
||||
LDLIBS += $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
|
||||
|
||||
DEFS += -DSTM32$(FAMILY) -DSTM32$(MCU)
|
||||
|
||||
#.SUFFIXES: .elf .bin .hex .srec .list .map .images
|
||||
#.SECONDEXPANSION:
|
||||
#.SECONDARY:
|
||||
|
||||
ELF := $(OBJDIR)/$(BINARY).elf
|
||||
LIST := $(OBJDIR)/$(BINARY).list
|
||||
BIN := $(BINARY).bin
|
||||
HEX := $(BINARY).hex
|
||||
|
||||
all: bin list
|
||||
|
||||
elf: $(ELF)
|
||||
bin: $(BIN)
|
||||
hex: $(HEX)
|
||||
list: $(LIST)
|
||||
|
||||
ifneq ($(MAKECMDGOALS),clean)
|
||||
-include $(DEPS)
|
||||
endif
|
||||
|
||||
$(OBJDIR):
|
||||
mkdir $(OBJDIR)
|
||||
|
||||
$(STARTUP): $(INC_DIR)/startup/vector.c
|
||||
$(CC) $(CFLAGS) $(DEFS) $(INCLUDE) $(ARCH_FLAGS) -o $@ -c $<
|
||||
|
||||
$(OBJDIR)/%.o: %.c
|
||||
@echo " CC $<"
|
||||
$(CC) $(CFLAGS) $(DEFS) $(INCLUDE) $(ARCH_FLAGS) -o $@ -c $<
|
||||
|
||||
#$(OBJDIR)/%.d: %.c $(OBJDIR)
|
||||
# $(CC) -MM -MG $< | sed -e 's,^\([^:]*\)\.o[ ]*:,$(@D)/\1.o $(@D)/\1.d:,' >$@
|
||||
|
||||
$(BIN): $(ELF)
|
||||
@echo " OBJCOPY $(BIN)"
|
||||
$(OBJCOPY) -Obinary $(ELF) $(BIN)
|
||||
|
||||
$(HEX): $(ELF)
|
||||
@echo " OBJCOPY $(HEX)"
|
||||
$(OBJCOPY) -Oihex $(ELF) $(HEX)
|
||||
|
||||
$(LIST): $(ELF)
|
||||
@echo " OBJDUMP $(LIST)"
|
||||
$(OBJDUMP) -S $(ELF) > $(LIST)
|
||||
|
||||
$(ELF): $(OBJDIR) $(OBJS)
|
||||
@echo " LD $(ELF)"
|
||||
$(LD) $(LDFLAGS) $(ARCH_FLAGS) $(OBJS) $(LDLIBS) -o $(ELF)
|
||||
|
||||
clean:
|
||||
@echo " CLEAN"
|
||||
$(RM) $(OBJS) $(DEPS) $(ELF) $(HEX) $(LIST) $(OBJDIR)/*.map *.d
|
||||
@rmdir $(OBJDIR) 2>/dev/null || true
|
||||
|
||||
dfuboot: $(BIN)
|
||||
@echo " LOAD $(BIN) THROUGH DFU"
|
||||
$(DFUUTIL) -a0 -D $(BIN) -s 0x08000000
|
||||
|
||||
flash: $(BIN)
|
||||
@echo " FLASH $(BIN)"
|
||||
$(STFLASH) write $(BIN) 0x8000000
|
||||
|
||||
boot: $(BIN)
|
||||
@echo " LOAD $(BIN) through bootloader"
|
||||
$(STBOOT) -b$(BOOTSPEED) $(BOOTPORT) -w $(BIN)
|
||||
|
||||
gentags:
|
||||
CFLAGS="$(CFLAGS) $(DEFS)" geany -g $(BINARY).c.tags *[hc] 2>/dev/null
|
||||
|
||||
.PHONY: clean flash boot gentags
|
||||
164
F0:F030,F042,F072/Socket_fans/Readme.md
Normal file
@@ -0,0 +1,164 @@
|
||||
Контроллер питания и охлаждения.
|
||||
===============================
|
||||
|
||||
-- Четыре канала измерения температуры с точностью +-1degrC (три канала управляют активностью кулеров, четвертый - для общего отключения питания в случае достижения критической температуры).
|
||||
-- Два канала управления четырехпроводными кулерами с контролем их активности.
|
||||
-- Две кнопки управления (включить/экстренно выключить нагрузку).
|
||||
-- Внешний сигнал (пищалка 12В): короткий сигнал раз в 10 секунд - один из кулеров не вращается (а должен), непрерывные сигналы - критическая ситуация, питание скоро будет отключено, (сигналы в течение 4с с паузой в 6с - резерв).
|
||||
-- Режим ручного управления (без контроля температур с соответствующими действиями) или мониторинга (в этом режиме нельзя вручную задавать параметры кулера или внешнего сигнала).
|
||||
|
||||
== help ==
|
||||
```
|
||||
'0x' - turn cooler0 on/off (x=1/0) or get status (x - any other)
|
||||
'1x' - turn cooler1 on/off (x=1/0) or get status (x - any other)
|
||||
'Ax' - get ADC raw value (x=0..7)
|
||||
'B' - buttons' state
|
||||
'bx' - buzzer: x==0 - off, x==1 - on, x==l - long beeps, x==s - short beeps
|
||||
'Cx' - get cooler x (0/1) RPS
|
||||
'D' - activate DFU mode
|
||||
'E' - show current state
|
||||
'Gx' - get cooler x (0..3) PWM settings
|
||||
'M' - get MCU temperature
|
||||
'm' - toggle monitoring
|
||||
'R' - software reset
|
||||
'rx' - relay on/off (x=1/0) or get status
|
||||
'Sx y' - set coolerx PWM to y
|
||||
's' - show settings
|
||||
'T' - get time from start (ms)
|
||||
'tx' - get temperature x (0..3)
|
||||
'V' - get voltage
|
||||
'Z' - reinit ADC
|
||||
'!' - switch between manual and automatic modes
|
||||
```
|
||||
|
||||
=== 0x,1x ===
|
||||
x=='0' - выключить питание кулера; x=='1' - включить питание; любое другое значение - проверить состояние.
|
||||
|
||||
=== Ax ===
|
||||
x=={0..7} - получить "сырое значение" x-го канала АЦП (в ADU).
|
||||
Каналы: 0..3 - термометры, 4 - измерение 12В, 5 - измерение 5В, 6 - температура МК, 7 - уровень 3.3В.
|
||||
|
||||
=== B ===
|
||||
Состояние обеих кнопок, например:
|
||||
```
|
||||
BUTTON0=0
|
||||
BUTTON1=0
|
||||
```
|
||||
|
||||
Нажатие кнопок проверяется один раз в секунду. Кнопка BUTTON0 переводит систему в автоматический режим и включает реле. Кнопка BUTTON1 отключает реле, отключает все кулеры и сигнал и переводит систему в ручной режим.
|
||||
|
||||
=== bx ===
|
||||
Изменить состояние внешнего сигнала. 0 - выключить, 1 - включить серию непрерывных сигналов, l - включить серию коротких сигналов в течение 4 секунд с паузой в 6 секунд, s - включить короткий сигнал (0.5с) с паузой 9.5с.
|
||||
|
||||
=== Cx ===
|
||||
Получить значения скорости вращения четырехпроводного кулера (обороты в секунду). Например:
|
||||
```
|
||||
C0
|
||||
RPM0=78
|
||||
C1
|
||||
RPM1=0
|
||||
```
|
||||
|
||||
=== D ===
|
||||
Активировать режим DFU для перепрошивки. После прошивки нужно перезапустить МК, закоротив контакты "reset" или кратковременно отключив от питания.
|
||||
|
||||
=== E ===
|
||||
Отобразить текущее состояние системы, например:
|
||||
```
|
||||
TIME=1229247
|
||||
T0=293
|
||||
T1=264
|
||||
T2=262
|
||||
T3=254
|
||||
BUZZER=OFF
|
||||
BUTTON0=0
|
||||
BUTTON1=0
|
||||
RPS0=82
|
||||
RPS1=107
|
||||
PWM0=30
|
||||
PWM1=40
|
||||
PWM2=33
|
||||
COOLER0=1
|
||||
COOLER1=1
|
||||
RELAY=1
|
||||
```
|
||||
Где
|
||||
TIME - время с момента включения (мс, приблизительно);
|
||||
Tx - температуры (x10) соответствующих каналов в градусах Цельсия;
|
||||
BUZZER - состояние сигнала;
|
||||
BUTTONx - состояние кнопок (1 - нажата, 0 - отпущена);
|
||||
RPSx - скорость вращения кулера x (оборотов в секунду);
|
||||
PWMx - установленное значение ШИМ (в процентах, 0..100) канала x;
|
||||
COOLERx - включено ли питание кулера x (0..1), из-за неправильной схемотехники не рекомендуется отключать питание четырехпроводных кулеров (+12В поступает в этом случае на измерительный вход);
|
||||
RELAY - состояние реле (1 - включено, 0 - выключено).
|
||||
|
||||
=== Gx ===
|
||||
Отобразить значения настройки ШИМ кулера x.
|
||||
|
||||
=== M ===
|
||||
Отобразить температуру МК (приближенная температура, x10 градусов Цельсия).
|
||||
|
||||
=== m ===
|
||||
Переключить (вкл/выкл) режим мониторинга, когда каждые 5 секунд отображается состояние системы.
|
||||
|
||||
=== R ===
|
||||
Программный перезапуск системы.
|
||||
|
||||
=== rx ===
|
||||
x==0 - выключить реле, x==1 - включить реле, любое другое значение - получить состояние реле.
|
||||
|
||||
=== Sx y ===
|
||||
Установить значение заполнения ШИМ кулера x (0..2) в y (0..100). Согласно опыту, четырехпроводные кулеры не стартуют при значении PWM<15, а двухпроводные не стартуют при PWM<35, поэтому для получения малых оборотов необходимо стартовать на большей скорости, а затем уже установить нужное значение заполнения ШИМ.
|
||||
|
||||
=== s ===
|
||||
Отобразить "вшитые" в код настройки, например:
|
||||
```
|
||||
Thysteresis=30
|
||||
Tmin={400, 350, 350}
|
||||
Tmax={900, 800, 600}
|
||||
T3max=850
|
||||
```
|
||||
|
||||
В данном случае гистерезис температуры установлен в 3 градуса, область допустимых значений температур - 40..90 градусов для канала 0, 35..80 градусов для канала 1 и 35..60 градусов для канала 2. Критическая температура канала 3 установлена в 85 градусов. Если в течение 20 секунд превышено значение одной из критических температур (для T0..2 они равны Tmax+Thysteresis), то реле отключается, система остается в автоматическом режиме.
|
||||
|
||||
=== T ===
|
||||
Отобразить время (условное) в миллисекундах со старта.
|
||||
|
||||
=== tx ===
|
||||
Получить значение температуры x-го канала (0..3). Температура умножена на 10. Например:
|
||||
```
|
||||
t0
|
||||
T0=294
|
||||
t1
|
||||
T1=265
|
||||
t2
|
||||
T2=264
|
||||
t3
|
||||
T3=256
|
||||
```
|
||||
|
||||
Соответственно, температуры равны: t0=29.4, t1=26.5, t2=26.4 и t3=25.6.
|
||||
Учитывая то, что величина вычисляется кусочно-линейной аппроксимацией с погрешностью до 0.1 градуса, а сами NTC дают разброс не лучше +-0.5 градуса, не стоит надеяться на то, что температуры будут достаточно точными.
|
||||
|
||||
=== V ===
|
||||
Получить значения напряжения (x100) в каналах, например:
|
||||
```
|
||||
V3_3=330
|
||||
V5=428
|
||||
V12=1055
|
||||
```
|
||||
Означает, что питание МК =3.3В, на входе 5В присутствует 4.28В, а на входе 12В присутствует 10.55В.
|
||||
|
||||
=== Z ===
|
||||
Реинициализация АЦП (ХЗ, зачем я это добавил).
|
||||
|
||||
=== ! ===
|
||||
Переключение между автоматическим и ручным режимами управления.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
138
F0:F030,F042,F072/Socket_fans/adc.c
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* This file is part of the Chiller project.
|
||||
* Copyright 2018 Edward V. Emelianov <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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "adc.h"
|
||||
|
||||
/**
|
||||
* @brief ADC_array - array for ADC channels with median filtering:
|
||||
* 0..3 - external NTC
|
||||
* 4 - ext 12V
|
||||
* 5 - ext 5V
|
||||
* 6 - internal Tsens
|
||||
* 7 - Vref
|
||||
*/
|
||||
uint16_t ADC_array[NUMBER_OF_ADC_CHANNELS*9];
|
||||
|
||||
/**
|
||||
* @brief getADCval - calculate median value for `nch` channel
|
||||
* @param nch - number of channel
|
||||
* @return
|
||||
*/
|
||||
uint16_t getADCval(int nch){
|
||||
int i, addr = nch;
|
||||
register uint16_t temp;
|
||||
#define PIX_SORT(a,b) { if ((a)>(b)) PIX_SWAP((a),(b)); }
|
||||
#define PIX_SWAP(a,b) { temp=(a);(a)=(b);(b)=temp; }
|
||||
uint16_t p[9];
|
||||
for(i = 0; i < 9; ++i, addr += NUMBER_OF_ADC_CHANNELS) // first we should prepare array for optmed
|
||||
p[i] = ADC_array[addr];
|
||||
PIX_SORT(p[1], p[2]) ; PIX_SORT(p[4], p[5]) ; PIX_SORT(p[7], p[8]) ;
|
||||
PIX_SORT(p[0], p[1]) ; PIX_SORT(p[3], p[4]) ; PIX_SORT(p[6], p[7]) ;
|
||||
PIX_SORT(p[1], p[2]) ; PIX_SORT(p[4], p[5]) ; PIX_SORT(p[7], p[8]) ;
|
||||
PIX_SORT(p[0], p[3]) ; PIX_SORT(p[5], p[8]) ; PIX_SORT(p[4], p[7]) ;
|
||||
PIX_SORT(p[3], p[6]) ; PIX_SORT(p[1], p[4]) ; PIX_SORT(p[2], p[5]) ;
|
||||
PIX_SORT(p[4], p[7]) ; PIX_SORT(p[4], p[2]) ; PIX_SORT(p[6], p[4]) ;
|
||||
PIX_SORT(p[4], p[2]) ;
|
||||
return p[4];
|
||||
#undef PIX_SORT
|
||||
#undef PIX_SWAP
|
||||
}
|
||||
|
||||
// return MCU temperature (degrees of celsius * 10)
|
||||
int32_t getMCUtemp(){
|
||||
// getVdd();
|
||||
// make correction on Vdd value
|
||||
// int32_t temperature = (int32_t)ADC_array[4] * VddValue / 330;
|
||||
int32_t ADval = getADCval(6);
|
||||
int32_t temperature = (int32_t) *TEMP30_CAL_ADDR - ADval;
|
||||
temperature *= (int32_t)(1100 - 300);
|
||||
temperature /= (int32_t)(*TEMP30_CAL_ADDR - *TEMP110_CAL_ADDR);
|
||||
temperature += 300;
|
||||
return(temperature);
|
||||
}
|
||||
|
||||
// return Vdd * 100 (V)
|
||||
uint32_t getVdd(){
|
||||
uint32_t vdd = ((uint32_t) *VREFINT_CAL_ADDR) * (uint32_t)330; // 3.3V
|
||||
vdd /= getADCval(7);
|
||||
return vdd;
|
||||
}
|
||||
|
||||
// convert ADU into Volts (*100)
|
||||
static inline uint32_t Ufromadu(uint8_t nch){
|
||||
uint32_t ADU = getADCval(nch);
|
||||
ADU *= getVdd();
|
||||
ADU >>= 12; // /4096
|
||||
return ADU;
|
||||
}
|
||||
|
||||
// get 12V (*100)
|
||||
uint32_t getU12(){
|
||||
uint32_t V = Ufromadu(4) * 493;
|
||||
return V / 100;
|
||||
}
|
||||
|
||||
// get 5V (*100)
|
||||
uint32_t getU5(){
|
||||
return Ufromadu(5) * 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief getNTC - return temperature of NTC (*10 degrC)
|
||||
* @param nch - NTC channel number (0..3)
|
||||
* @return
|
||||
*/
|
||||
int16_t getNTC(int nch){
|
||||
#define NKNOTS (14)
|
||||
const int16_t ADU[NKNOTS] = {732, 945, 1197, 2035, 2309, 2542, 2739, 2859, 2969, 3068, 3154, 3228, 3293, 3347};
|
||||
const int16_t T[NKNOTS] = {100, 160, 227, 438, 508, 571, 628, 666, 702, 738, 772, 805, 837, 869};
|
||||
/*
|
||||
* coefficients: 0.028261 0.026536 0.025136 0.025738 0.027044 0.028922 0.031038 0.033255 0.036056 0.039606 0.044173 0.050296 0.058920 0.071729
|
||||
* use
|
||||
* [N D] = rat(K*10); printf("N="); printf("%d, ", N); printf("\nD="); printf("%d, ", D);printf("\n");
|
||||
*/
|
||||
const int16_t N[NKNOTS] = {13, 95, 185, 96, 43, 153, 347, 141, 128, 261, 235, 85, 393, 307};
|
||||
const int16_t D[NKNOTS] = {46, 358, 736, 373, 159, 529, 1118, 424, 355, 659, 532, 169, 667, 428};
|
||||
|
||||
if(nch < 0 || nch > 3) return -30000;
|
||||
uint16_t val = getADCval(nch);
|
||||
// find interval
|
||||
int idx = (NKNOTS)/2, left = 0, right = NKNOTS-1; // left, right, middle
|
||||
while(idx > left && idx < right){
|
||||
int16_t midval = ADU[idx];
|
||||
if(val < midval){
|
||||
if(idx == 0) break;
|
||||
if(val > ADU[idx-1]){ // found
|
||||
--idx;
|
||||
break;
|
||||
}
|
||||
right = idx - 1;
|
||||
idx = (left + right)/2;
|
||||
}else{
|
||||
if(val < ADU[idx+1]) break; // found
|
||||
left = idx + 1;
|
||||
idx = (left + right)/2;
|
||||
}
|
||||
}
|
||||
if(idx < 0) idx = 0;
|
||||
else if(idx > NKNOTS-1) idx = NKNOTS - 1;
|
||||
// T = Y0(idx) + K(idx) * (ADU - X0(idx));
|
||||
int16_t valT = T[idx] + (N[idx]*(val - ADU[idx]))/D[idx];
|
||||
#undef NKNOTS
|
||||
return valT;
|
||||
}
|
||||
33
F0:F030,F042,F072/Socket_fans/adc.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* This file is part of the Chiller project.
|
||||
* Copyright 2018 Edward V. Emelianov <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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef ADC_H
|
||||
#define ADC_H
|
||||
#include "stm32f0.h"
|
||||
|
||||
// 6 channels + vref + Tmcu
|
||||
#define NUMBER_OF_ADC_CHANNELS (8)
|
||||
|
||||
extern uint16_t ADC_array[];
|
||||
int32_t getMCUtemp();
|
||||
uint32_t getVdd();
|
||||
uint16_t getADCval(int nch);
|
||||
int16_t getNTC(int nch);
|
||||
uint32_t getU12();
|
||||
uint32_t getU5();
|
||||
|
||||
#endif // ADC_H
|
||||
196
F0:F030,F042,F072/Socket_fans/flash.c
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* This file is part of the SockFans project.
|
||||
* Copyright 2020 Edward V. Emelianov <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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stm32f0.h>
|
||||
#include "adc.h"
|
||||
#include "flash.h"
|
||||
#include "proto.h" // printout
|
||||
#include <string.h> // memcpy
|
||||
|
||||
// max amount of Config records stored (will be recalculate in flashstorage_init()
|
||||
static uint32_t maxCnum = FLASH_BLOCK_SIZE / sizeof(user_conf);
|
||||
|
||||
#define USERCONF_INITIALIZER { \
|
||||
.userconf_sz = sizeof(user_conf) \
|
||||
,.Tturnoff = 20000 \
|
||||
,.Thyst = 30 \
|
||||
,.Tmin = {400, 400, 400} \
|
||||
,.Tmax = {900, 800, 800, 800} \
|
||||
}
|
||||
|
||||
static int erase_flash(const void*, const void*);
|
||||
static int write2flash(const void*, const void*, uint32_t);
|
||||
// don't write `static` here, or get error:
|
||||
// 'memcpy' forming offset 8 is out of the bounds [0, 4] of object '__varsstart' with type 'uint32_t'
|
||||
const user_conf *Flash_Data = (const user_conf *)(&__varsstart);
|
||||
|
||||
user_conf the_conf = USERCONF_INITIALIZER;
|
||||
|
||||
static int currentconfidx = -1; // index of current configuration
|
||||
|
||||
/**
|
||||
* @brief binarySearch - binary search in flash for last non-empty cell
|
||||
* any struct searched should have its sizeof() @ the first field!!!
|
||||
* @param l - left index
|
||||
* @param r - right index (should be @1 less than last index!)
|
||||
* @param start - starting address
|
||||
* @param stor_size - size of structure to search
|
||||
* @return index of non-empty cell or -1
|
||||
*/
|
||||
static int binarySearch(int r, const uint8_t *start, int stor_size){
|
||||
int l = 0;
|
||||
while(r >= l){
|
||||
int mid = l + (r - l) / 2;
|
||||
const uint8_t *s = start + mid * stor_size;
|
||||
if(*((const uint16_t*)s) == stor_size){
|
||||
if(*((const uint16_t*)(s + stor_size)) == 0xffff){
|
||||
return mid;
|
||||
}else{ // element is to the right
|
||||
l = mid + 1;
|
||||
}
|
||||
}else{ // element is to the left
|
||||
r = mid - 1;
|
||||
}
|
||||
}
|
||||
return -1; // not found
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief flashstorage_init - initialization of user conf storage
|
||||
* run in once @ start
|
||||
*/
|
||||
void flashstorage_init(){
|
||||
if(FLASH_SIZE > 0 && FLASH_SIZE < 20000){
|
||||
uint32_t flsz = FLASH_SIZE * 1024; // size in bytes
|
||||
flsz -= (uint32_t)(&__varsstart) - FLASH_BASE;
|
||||
maxCnum = flsz / sizeof(user_conf);
|
||||
//SEND("flsz="); printu(flsz);
|
||||
//SEND("\nmaxCnum="); printu(maxCnum); newline(); sendbuf();
|
||||
}
|
||||
// -1 if there's no data at all & flash is clear; maxnum-1 if flash is full
|
||||
currentconfidx = binarySearch((int)maxCnum-2, (const uint8_t*)Flash_Data, sizeof(user_conf));
|
||||
if(currentconfidx > -1){
|
||||
memcpy(&the_conf, &Flash_Data[currentconfidx], sizeof(user_conf));
|
||||
}
|
||||
}
|
||||
|
||||
// store new configuration
|
||||
// @return 0 if all OK
|
||||
int store_userconf(){
|
||||
// maxnum - 3 means that there always should be at least one empty record after last data
|
||||
// for binarySearch() checking that there's nothing more after it!
|
||||
if(currentconfidx > (int)maxCnum - 3){ // there's no more place
|
||||
currentconfidx = 0;
|
||||
if(erase_flash(Flash_Data, (&__varsstart))) return 1;
|
||||
}else ++currentconfidx; // take next data position (0 - within first run after firmware flashing)
|
||||
return write2flash((const void*)&Flash_Data[currentconfidx], &the_conf, sizeof(the_conf));
|
||||
}
|
||||
|
||||
static int write2flash(const void *start, const void *wrdata, uint32_t stor_size){
|
||||
int ret = 0;
|
||||
if (FLASH->CR & FLASH_CR_LOCK){ // unloch flash
|
||||
FLASH->KEYR = FLASH_KEY1;
|
||||
FLASH->KEYR = FLASH_KEY2;
|
||||
}
|
||||
while (FLASH->SR & FLASH_SR_BSY);
|
||||
if(FLASH->SR & FLASH_SR_WRPRTERR){
|
||||
MSG("Can't remove write protection\n");
|
||||
return 1; // write protection
|
||||
}
|
||||
FLASH->SR = FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPRTERR; // clear all flags
|
||||
FLASH->CR |= FLASH_CR_PG;
|
||||
const uint16_t *data = (const uint16_t*) wrdata;
|
||||
volatile uint16_t *address = (volatile uint16_t*) start;
|
||||
uint32_t i, count = (stor_size + 1) / 2;
|
||||
for (i = 0; i < count; ++i){
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
*(volatile uint16_t*)(address + i) = data[i];
|
||||
while (FLASH->SR & FLASH_SR_BSY);
|
||||
if(FLASH->SR & FLASH_SR_PGERR){
|
||||
ret = 1; // program error - meet not 0xffff
|
||||
MSG("FLASH_SR_PGERR\n");
|
||||
break;
|
||||
}else while (!(FLASH->SR & FLASH_SR_EOP));
|
||||
FLASH->SR = FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPRTERR;
|
||||
}
|
||||
FLASH->CR |= FLASH_CR_LOCK; // lock it back
|
||||
FLASH->CR &= ~(FLASH_CR_PG);
|
||||
MSG("Flash stored\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief erase_flash - erase N pages of flash memory
|
||||
* @param start - first address
|
||||
* @param end - last address (or NULL if need to erase all flash remaining)
|
||||
* @return 0 if succeed
|
||||
*/
|
||||
static int erase_flash(const void *start, const void *end){
|
||||
int ret = 0;
|
||||
uint32_t nblocks = 1, flsz = 0;
|
||||
if(!end){ // erase all remaining
|
||||
if(FLASH_SIZE > 0 && FLASH_SIZE < 20000){
|
||||
flsz = FLASH_SIZE * 1024; // size in bytes
|
||||
flsz -= (uint32_t)start - FLASH_BASE;
|
||||
}
|
||||
}else{ // erase a part
|
||||
flsz = (uint32_t)end - (uint32_t)start;
|
||||
}
|
||||
nblocks = flsz / FLASH_BLOCK_SIZE;
|
||||
if(nblocks == 0 || nblocks >= FLASH_SIZE) return 1;
|
||||
for(uint32_t i = 0; i < nblocks; ++i){
|
||||
#ifdef EBUG
|
||||
SEND("Try to erase page #"); printu(i); newline(); sendbuf();
|
||||
#endif
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
/* (1) Wait till no operation is on going */
|
||||
/* (2) Clear error & EOP bits */
|
||||
/* (3) Check that the Flash is unlocked */
|
||||
/* (4) Perform unlock sequence */
|
||||
while ((FLASH->SR & FLASH_SR_BSY) != 0){} /* (1) */
|
||||
FLASH->SR = FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPRTERR; /* (2) */
|
||||
/* if (FLASH->SR & FLASH_SR_EOP){
|
||||
FLASH->SR |= FLASH_SR_EOP;
|
||||
}*/
|
||||
if ((FLASH->CR & FLASH_CR_LOCK) != 0){ /* (3) */
|
||||
FLASH->KEYR = FLASH_KEY1; /* (4) */
|
||||
FLASH->KEYR = FLASH_KEY2;
|
||||
}
|
||||
/* (1) Set the PER bit in the FLASH_CR register to enable page erasing */
|
||||
/* (2) Program the FLASH_AR register to select a page to erase */
|
||||
/* (3) Set the STRT bit in the FLASH_CR register to start the erasing */
|
||||
/* (4) Wait until the EOP flag in the FLASH_SR register set */
|
||||
/* (5) Clear EOP flag by software by writing EOP at 1 */
|
||||
/* (6) Reset the PER Bit to disable the page erase */
|
||||
FLASH->CR |= FLASH_CR_PER; /* (1) */
|
||||
FLASH->AR = (uint32_t)Flash_Data + i*FLASH_BLOCK_SIZE; /* (2) */
|
||||
FLASH->CR |= FLASH_CR_STRT; /* (3) */
|
||||
while(!(FLASH->SR & FLASH_SR_EOP));
|
||||
FLASH->SR |= FLASH_SR_EOP; /* (5)*/
|
||||
if(FLASH->SR & FLASH_SR_WRPRTERR){ /* Check Write protection error */
|
||||
ret = 1;
|
||||
MSG("Write protection error!\n");
|
||||
FLASH->SR |= FLASH_SR_WRPRTERR; /* Clear the flag by software by writing it at 1*/
|
||||
break;
|
||||
}
|
||||
FLASH->CR &= ~FLASH_CR_PER; /* (6) */
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
51
F0:F030,F042,F072/Socket_fans/flash.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* This file is part of the SockFans project.
|
||||
* Copyright 2020 Edward V. Emelianov <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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef FLASH_H__
|
||||
#define FLASH_H__
|
||||
|
||||
#include "hardware.h"
|
||||
|
||||
#define FLASH_BLOCK_SIZE (1024)
|
||||
#define FLASH_SIZE_REG ((uint32_t)0x1FFFF7CC)
|
||||
#define FLASH_SIZE *((uint16_t*)FLASH_SIZE_REG)
|
||||
|
||||
#define TMINNO (3)
|
||||
#define TMAXNO (4)
|
||||
|
||||
/*
|
||||
* struct to save user configurations
|
||||
*/
|
||||
typedef struct __attribute__((packed, aligned(4))){
|
||||
uint16_t userconf_sz; // "magick number"
|
||||
uint32_t Tturnoff; // wait for Tturnoff ms before turning power off
|
||||
uint32_t Thyst; // Thysteresis
|
||||
int16_t Tmin[TMINNO]; // minT
|
||||
int16_t Tmax[TMAXNO]; // maxT
|
||||
} user_conf;
|
||||
|
||||
extern user_conf the_conf; // global user config (read from FLASH to RAM)
|
||||
// data from ld-file: start address of storage
|
||||
extern const uint32_t __varsstart;
|
||||
|
||||
void flashstorage_init();
|
||||
int store_userconf();
|
||||
void dump_userconf();
|
||||
|
||||
#endif // FLASH_H__
|
||||
246
F0:F030,F042,F072/Socket_fans/hardware.c
Normal file
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* geany_encoding=koi8-r
|
||||
* hardware.c - hardware-dependent macros & functions
|
||||
*
|
||||
* Copyright 2018 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 "adc.h"
|
||||
#include "hardware.h"
|
||||
#include "proto.h"
|
||||
|
||||
volatile uint32_t Cooler1RPM; // Cooler1 RPM counter by EXTI @PA7
|
||||
buzzer_state buzzer = BUZZER_OFF; // buzzer state
|
||||
|
||||
void adc_setup(){
|
||||
uint16_t ctr = 0; // 0xfff0 - more than 1.3ms
|
||||
ADC1->CR &= ~ADC_CR_ADEN;
|
||||
DMA1_Channel1->CCR &= ~DMA_CCR_EN;
|
||||
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; // Enable the peripheral clock of the ADC
|
||||
RCC->CR2 |= RCC_CR2_HSI14ON; // Start HSI14 RC oscillator
|
||||
while ((RCC->CR2 & RCC_CR2_HSI14RDY) == 0 && ++ctr < 0xfff0){}; // Wait HSI14 is ready
|
||||
// calibration
|
||||
if(ADC1->CR & ADC_CR_ADEN){ // Ensure that ADEN = 0
|
||||
ADC1->CR &= (uint32_t)(~ADC_CR_ADEN); // Clear ADEN
|
||||
}
|
||||
ADC1->CR |= ADC_CR_ADCAL; // Launch the calibration by setting ADCAL
|
||||
ctr = 0; // ADC calibration time is 5.9us
|
||||
while(ADC1->CR & ADC_CR_ADCAL && ++ctr < 0xfff0); // Wait until ADCAL=0
|
||||
// enable ADC
|
||||
ctr = 0;
|
||||
do{
|
||||
ADC1->CR |= ADC_CR_ADEN;
|
||||
}while((ADC1->ISR & ADC_ISR_ADRDY) == 0 && ++ctr < 0xfff0);
|
||||
// configure ADC
|
||||
ADC1->CFGR1 |= ADC_CFGR1_CONT; // Select the continuous mode
|
||||
ADC1->CHSELR = ADC_CHSELR_CHSEL0 | ADC_CHSELR_CHSEL1 | ADC_CHSELR_CHSEL2 |
|
||||
ADC_CHSELR_CHSEL3 | ADC_CHSELR_CHSEL4 | ADC_CHSELR_CHSEL5 |
|
||||
ADC_CHSELR_CHSEL16 | ADC_CHSELR_CHSEL17; // Select CHSEL0..5 - ADC inputs, 16,17 - t. sensor and vref
|
||||
ADC1->SMPR |= ADC_SMPR_SMP; // Select a sampling mode of 111 i.e. 239.5 ADC clk to be greater than 17.1us
|
||||
ADC->CCR |= ADC_CCR_TSEN | ADC_CCR_VREFEN; // Wake-up the VREFINT and Temperature sensor
|
||||
// configure DMA for ADC
|
||||
RCC->AHBENR |= RCC_AHBENR_DMA1EN; // Enable the peripheral clock on DMA
|
||||
ADC1->CFGR1 |= ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG; // Enable DMA transfer on ADC and circular mode
|
||||
DMA1_Channel1->CPAR = (uint32_t) (&(ADC1->DR)); // Configure the peripheral data register address
|
||||
DMA1_Channel1->CMAR = (uint32_t)(ADC_array); // Configure the memory address
|
||||
DMA1_Channel1->CNDTR = NUMBER_OF_ADC_CHANNELS * 9; // Configure the number of DMA tranfer to be performs on DMA channel 1
|
||||
DMA1_Channel1->CCR |= DMA_CCR_MINC | DMA_CCR_MSIZE_0 | DMA_CCR_PSIZE_0 | DMA_CCR_CIRC; // Configure increment, size, interrupts and circular mode
|
||||
DMA1_Channel1->CCR |= DMA_CCR_EN; // Enable DMA Channel 1
|
||||
ADC1->CR |= ADC_CR_ADSTART; // start the ADC conversions
|
||||
}
|
||||
|
||||
|
||||
static inline void gpio_setup(void){
|
||||
RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_GPIOCEN;
|
||||
OFF(BUZZER); OFF(RELAY); OFF(COOLER0); OFF(COOLER1);
|
||||
// All outputs are pullups
|
||||
// PA0..5 - ADC, PA6, PA8..10 - timers (PA6, PA7 - pullup, PA7 - exti), PA14 - buzzer
|
||||
GPIOA->MODER = GPIO_MODER_MODER0_AI | GPIO_MODER_MODER1_AI |
|
||||
GPIO_MODER_MODER2_AI | GPIO_MODER_MODER3_AI |
|
||||
GPIO_MODER_MODER4_AI | GPIO_MODER_MODER5_AI |
|
||||
GPIO_MODER_MODER6_AF | GPIO_MODER_MODER8_AF |
|
||||
GPIO_MODER_MODER9_AF | GPIO_MODER_MODER10_AF|
|
||||
GPIO_MODER_MODER14_O;
|
||||
GPIOA->PUPDR = GPIO_PUPDR6_PU | GPIO_PUPDR7_PU;
|
||||
// EXTI @ PA7
|
||||
SYSCFG->EXTICR[1] = SYSCFG_EXTICR2_EXTI7_PA; // PORTA for EXTI
|
||||
EXTI->IMR = EXTI_IMR_MR7; // select pin 7
|
||||
EXTI->RTSR = EXTI_RTSR_TR7; // rising edge @ pin 7
|
||||
NVIC_EnableIRQ(EXTI4_15_IRQn); // enable interrupt
|
||||
NVIC_SetPriority(EXTI4_15_IRQn, 4); // set low priority
|
||||
// PB4/5 - cooler, PB14/15 - buttons (pullup)
|
||||
GPIOB->MODER = GPIO_MODER_MODER4_O | GPIO_MODER_MODER5_O;
|
||||
GPIOB->PUPDR = GPIO_PUPDR14_PU | GPIO_PUPDR15_PU;
|
||||
// PC13 - relay
|
||||
GPIOC->MODER = GPIO_MODER_MODER13_O;
|
||||
/* Alternate functions:
|
||||
* PA6 - TIM3_CH1 AF1
|
||||
* PA8 - TIM1_CH1 AF2
|
||||
* PA9 - TIM1_CH2 AF2
|
||||
* PA10 - TIM1_CH3 AF2
|
||||
*/
|
||||
GPIOA->AFR[0] = (1 << (6*4));
|
||||
GPIOA->AFR[1] = (2 << (0*4)) | (2 << (1*4)) | (2 << (2*4));
|
||||
}
|
||||
|
||||
static inline void timers_setup(){
|
||||
// TIM1 channels 1..3 - PWM output
|
||||
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; // enable clocking
|
||||
TIM1->PSC = 19; // F=48/20 = 2.4MHz
|
||||
TIM1->ARR = 100; // PWM frequency = 2.4/101 = 23.76kHz
|
||||
// PWM mode 1 (OCxM = 110), preload enable
|
||||
TIM1->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1PE |
|
||||
TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2PE;
|
||||
TIM1->CCMR2 = TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3PE;
|
||||
TIM1->CCER = TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E; // active high (CC1P=0), enable outputs
|
||||
TIM1->BDTR |= TIM_BDTR_MOE; // enable main output
|
||||
TIM1->CR1 |= TIM_CR1_CEN; // enable timer
|
||||
TIM1->EGR |= TIM_EGR_UG; // force update generation
|
||||
// TIM3 channel 1 - external counter on channel1
|
||||
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
|
||||
TIM3->SMCR = TIM_SMCR_TS_2 | TIM_SMCR_TS_0 | TIM_SMCR_SMS; // TS=101, SMS=111 - external trigger on input1
|
||||
TIM3->CCMR1 = TIM_CCMR1_CC1S_0; // CC1 is input mapped on channel TI1
|
||||
TIM3->CR1 = TIM_CR1_CEN;
|
||||
}
|
||||
|
||||
void HW_setup(){
|
||||
gpio_setup();
|
||||
adc_setup();
|
||||
timers_setup();
|
||||
}
|
||||
|
||||
void iwdg_setup(){
|
||||
uint32_t tmout = 16000000;
|
||||
/* Enable the peripheral clock RTC */
|
||||
/* (1) Enable the LSI (40kHz) */
|
||||
/* (2) Wait while it is not ready */
|
||||
RCC->CSR |= RCC_CSR_LSION; /* (1) */
|
||||
while((RCC->CSR & RCC_CSR_LSIRDY) != RCC_CSR_LSIRDY){if(--tmout == 0) break;} /* (2) */
|
||||
/* Configure IWDG */
|
||||
/* (1) Activate IWDG (not needed if done in option bytes) */
|
||||
/* (2) Enable write access to IWDG registers */
|
||||
/* (3) Set prescaler by 64 (1.6ms for each tick) */
|
||||
/* (4) Set reload value to have a rollover each 2s */
|
||||
/* (5) Check if flags are reset */
|
||||
/* (6) Refresh counter */
|
||||
IWDG->KR = IWDG_START; /* (1) */
|
||||
IWDG->KR = IWDG_WRITE_ACCESS; /* (2) */
|
||||
IWDG->PR = IWDG_PR_PR_1; /* (3) */
|
||||
IWDG->RLR = 1250; /* (4) */
|
||||
tmout = 16000000;
|
||||
while(IWDG->SR){if(--tmout == 0) break;} /* (5) */
|
||||
IWDG->KR = IWDG_REFRESH; /* (6) */
|
||||
}
|
||||
|
||||
// pause in milliseconds for some purposes
|
||||
void pause_ms(uint32_t pause){
|
||||
uint32_t Tnxt = Tms + pause;
|
||||
while(Tms < Tnxt) nop();
|
||||
}
|
||||
|
||||
void Jump2Boot(){
|
||||
void (*SysMemBootJump)(void);
|
||||
volatile uint32_t addr = SystemMem;
|
||||
// reset systick
|
||||
SysTick->CTRL = 0;
|
||||
// reset clocks
|
||||
RCC->APB1RSTR = RCC_APB1RSTR_CECRST | RCC_APB1RSTR_DACRST | RCC_APB1RSTR_PWRRST | RCC_APB1RSTR_CRSRST |
|
||||
RCC_APB1RSTR_CANRST | RCC_APB1RSTR_USBRST | RCC_APB1RSTR_I2C2RST | RCC_APB1RSTR_I2C1RST |
|
||||
RCC_APB1RSTR_USART4RST | RCC_APB1RSTR_USART3RST | RCC_APB1RSTR_USART2RST | RCC_APB1RSTR_SPI2RST |
|
||||
RCC_APB1RSTR_WWDGRST | RCC_APB1RSTR_TIM14RST |
|
||||
#ifdef STM32F072xB
|
||||
RCC_APB1RSTR_TIM7RST | RCC_APB1RSTR_TIM6RST |
|
||||
#endif
|
||||
RCC_APB1RSTR_TIM3RST | RCC_APB1RSTR_TIM2RST;
|
||||
RCC->APB2RSTR = RCC_APB2RSTR_DBGMCURST | RCC_APB2RSTR_TIM17RST | RCC_APB2RSTR_TIM16RST |
|
||||
#ifdef STM32F072xB
|
||||
RCC_APB2RSTR_TIM15RST |
|
||||
#endif
|
||||
RCC_APB2RSTR_USART1RST | RCC_APB2RSTR_SPI1RST | RCC_APB2RSTR_TIM1RST | RCC_APB2RSTR_ADCRST | RCC_APB2RSTR_SYSCFGRST;
|
||||
RCC->AHBRSTR = 0;
|
||||
RCC->APB1RSTR = 0;
|
||||
RCC->APB2RSTR = 0;
|
||||
/* // reset GPIO - DON'T WORK! ???
|
||||
GPIOA->MODER = 0; GPIOA->PUPDR = 0; GPIOA->ODR = 0;
|
||||
GPIOB->MODER = 0; GPIOB->PUPDR = 0; GPIOB->ODR = 0;
|
||||
GPIOC->MODER = 0; GPIOC->PUPDR = 0; GPIOC->ODR = 0;
|
||||
#ifdef STM32F072xB
|
||||
GPIOD->MODER = 0; GPIOD->PUPDR = 0; GPIOD->ODR = 0;
|
||||
GPIOE->MODER = 0; GPIOE->PUPDR = 0; GPIOE->ODR = 0;
|
||||
#endif
|
||||
GPIOF->MODER = 0; GPIOF->PUPDR = 0; GPIOF->ODR = 0; */
|
||||
// remap memory to 0 (only for STM32F0)
|
||||
SYSCFG->CFGR1 = 0x01; __DSB(); __ISB();
|
||||
SysMemBootJump = (void (*)(void)) (*((uint32_t *)(addr + 4)));
|
||||
// set main stack pointer
|
||||
__set_MSP(*((uint32_t *)addr));
|
||||
// jump to bootloader
|
||||
SysMemBootJump();
|
||||
}
|
||||
|
||||
void buzzer_chk(){ // check buzzer state
|
||||
static uint32_t lastTms = 0;
|
||||
static buzzer_state oldstate = BUZZER_OFF;
|
||||
uint32_t B, S; // length of beep and silence
|
||||
if(buzzer == oldstate){ // keep current state
|
||||
if(lastTms > Tms) return;
|
||||
switch(buzzer){ // beep on/off
|
||||
case BUZZER_LONG:
|
||||
B = LONG_BUZZER_PERIOD;
|
||||
S = LONG_BUZZER_PAUSE;
|
||||
break;
|
||||
case BUZZER_SHORT:
|
||||
B = SHORT_BUZZER_PERIOD;
|
||||
S = SHORT_BUZZER_PAUSE;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
if(CHK(BUZZER)){ // is ON
|
||||
OFF(BUZZER);
|
||||
lastTms = Tms + S;
|
||||
}else{ // is OFF
|
||||
ON(BUZZER);
|
||||
lastTms = Tms + B;
|
||||
}
|
||||
return;
|
||||
}
|
||||
switch(buzzer){ // change buzzer state
|
||||
case BUZZER_ON:
|
||||
ON(BUZZER);
|
||||
break;
|
||||
case BUZZER_OFF:
|
||||
OFF(BUZZER);
|
||||
break;
|
||||
case BUZZER_LONG:
|
||||
ON(BUZZER);
|
||||
lastTms = Tms + LONG_BUZZER_PERIOD;
|
||||
break;
|
||||
case BUZZER_SHORT:
|
||||
ON(BUZZER);
|
||||
lastTms = Tms + SHORT_BUZZER_PERIOD;
|
||||
break;
|
||||
}
|
||||
oldstate = buzzer;
|
||||
}
|
||||
|
||||
void exti4_15_isr(){
|
||||
EXTI->PR |= EXTI_PR_PR7; // clear pending bit
|
||||
++Cooler1RPM;
|
||||
}
|
||||
89
F0:F030,F042,F072/Socket_fans/hardware.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* geany_encoding=koi8-r
|
||||
* hardware.h
|
||||
*
|
||||
* Copyright 2018 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.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef __HARDWARE_H__
|
||||
#define __HARDWARE_H__
|
||||
|
||||
#include <stm32f0.h>
|
||||
|
||||
#define SYSMEM03x 0x1FFFEC00
|
||||
#define SYSMEM04x 0x1FFFC400
|
||||
#define SYSMEM05x 0x1FFFEC00
|
||||
#define SYSMEM07x 0x1FFFC800
|
||||
#define SYSMEM09x 0x1FFFD800
|
||||
|
||||
#define SystemMem SYSMEM07x
|
||||
|
||||
|
||||
#define CONCAT(a,b) a ## b
|
||||
#define STR_HELPER(s) #s
|
||||
#define STR(s) STR_HELPER(s)
|
||||
|
||||
// Buzzer: PA14
|
||||
#define BUZZER_port GPIOA
|
||||
#define BUZZER_pin (1<<14)
|
||||
// Cooler0/1 power on/off: PB4, PB5
|
||||
#define COOLER0_port GPIOB
|
||||
#define COOLER0_pin (1<<4)
|
||||
#define COOLER1_port GPIOB
|
||||
#define COOLER1_pin (1<<5)
|
||||
// Relay: PC13
|
||||
#define RELAY_port GPIOC
|
||||
#define RELAY_pin (1<<13)
|
||||
// Buttons: PB14/15
|
||||
#define BUTTON0_port GPIOB
|
||||
#define BUTTON0_pin (1<<14)
|
||||
#define BUTTON1_port GPIOB
|
||||
#define BUTTON1_pin (1<<15)
|
||||
// common macro for getting status
|
||||
#define CHK(x) ((x ## _port->IDR & (x ## _pin)) ? 1 : 0)
|
||||
|
||||
#define ON(x) do{pin_set(x ## _port, x ## _pin);}while(0)
|
||||
#define OFF(x) do{pin_clear(x ## _port, x ## _pin);}while(0)
|
||||
|
||||
typedef enum{
|
||||
BUZZER_OFF, // buzzer is off
|
||||
BUZZER_ON, // continuous beeep
|
||||
BUZZER_SHORT, // short beeps with longer pause
|
||||
BUZZER_LONG // long beeps with shorter pause
|
||||
} buzzer_state;
|
||||
|
||||
// Length of long and short time periods (ms)
|
||||
#define LONG_BUZZER_PERIOD (4000)
|
||||
#define LONG_BUZZER_PAUSE (6000)
|
||||
#define SHORT_BUZZER_PERIOD (500)
|
||||
#define SHORT_BUZZER_PAUSE (9500)
|
||||
|
||||
extern volatile uint32_t Tms;
|
||||
extern volatile uint32_t Coolerspeed[2];
|
||||
extern volatile uint32_t Cooler1RPM;
|
||||
extern buzzer_state buzzer;
|
||||
|
||||
void HW_setup(void);
|
||||
void adc_setup();
|
||||
void iwdg_setup();
|
||||
void pause_ms(uint32_t pause);
|
||||
void Jump2Boot();
|
||||
void buzzer_chk();
|
||||
|
||||
#endif // __HARDWARE_H__
|
||||
22
F0:F030,F042,F072/Socket_fans/kicad/acs712.lib
Normal file
@@ -0,0 +1,22 @@
|
||||
EESchema-LIBRARY Version 2.3 Date: Sun 04 May 2014 09:27:50 PM MSK
|
||||
#encoding utf-8
|
||||
#
|
||||
# ACS712
|
||||
#
|
||||
DEF ACS712 U 0 40 Y Y 1 F N
|
||||
F0 "U" 0 300 60 H V C CNN
|
||||
F1 "ACS712" 0 -350 60 H V C CNN
|
||||
DRAW
|
||||
S -450 250 450 -300 0 1 0 N
|
||||
X IP+ 1 -550 150 300 R 50 50 1 1 I
|
||||
X IP+ 2 -550 50 300 R 50 50 1 1 I
|
||||
X IP- 3 -550 -100 300 R 50 50 1 1 I
|
||||
X IP- 4 -550 -200 300 R 50 50 1 1 I
|
||||
X GND 5 550 -200 300 L 50 50 1 1 I
|
||||
X FILTER 6 550 -100 300 L 50 50 1 1 I
|
||||
X VIOUT 7 550 50 300 L 50 50 1 1 I
|
||||
X Vcc 8 550 150 300 L 50 50 1 1 I
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
#End Library
|
||||
190
F0:F030,F042,F072/Socket_fans/kicad/elements.lib
Normal file
@@ -0,0 +1,190 @@
|
||||
EESchema-LIBRARY Version 2.3
|
||||
#encoding utf-8
|
||||
#
|
||||
# 74HC4051
|
||||
#
|
||||
DEF 74HC4051 U 0 10 Y Y 1 F N
|
||||
F0 "U" 0 0 50 H V C CNN
|
||||
F1 "74HC4051" 0 -150 50 H V C CNN
|
||||
F2 "" 0 0 50 H V C CNN
|
||||
F3 "" 0 0 50 H V C CNN
|
||||
$FPLIST
|
||||
SO16
|
||||
TSSOP16
|
||||
SSOP16
|
||||
DHVQFN16
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
S -400 450 400 -450 0 1 0 N
|
||||
X Y4 1 700 -50 300 L 50 50 1 1 B
|
||||
X Y6 2 700 -250 300 L 50 50 1 1 B
|
||||
X Z 3 0 -750 300 U 50 50 1 1 B
|
||||
X Y7 4 700 -350 300 L 50 50 1 1 B
|
||||
X Y5 5 700 -150 300 L 50 50 1 1 B
|
||||
X ~E 6 -700 -350 300 R 50 50 1 1 I I
|
||||
X VEE 7 -700 0 300 R 50 50 1 1 W
|
||||
X GND 8 -700 -200 300 R 50 50 1 1 W
|
||||
X S2 9 -700 150 300 R 50 50 1 1 I
|
||||
X S1 10 -700 250 300 R 50 50 1 1 I
|
||||
X S0 11 -700 350 300 R 50 50 1 1 I
|
||||
X Y3 12 700 50 300 L 50 50 1 1 B
|
||||
X Y0 13 700 350 300 L 50 50 1 1 B
|
||||
X Y1 14 700 250 300 L 50 50 1 1 B
|
||||
X Y2 15 700 150 300 L 50 50 1 1 B
|
||||
X VCC 16 -700 -100 300 R 50 50 1 1 W
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# D_Schottky_x2_ACom_AKK
|
||||
#
|
||||
DEF D_Schottky_x2_ACom_AKK D 0 30 Y N 1 F N
|
||||
F0 "D" 50 -100 50 H V C CNN
|
||||
F1 "D_Schottky_x2_ACom_AKK" 0 100 50 H V C CNN
|
||||
F2 "" 0 0 50 H V C CNN
|
||||
F3 "" 0 0 50 H V C CNN
|
||||
DRAW
|
||||
P 2 0 1 0 -140 0 150 0 N
|
||||
P 2 0 1 0 0 0 0 -100 N
|
||||
P 3 0 1 8 -150 50 -150 -50 -150 -50 N
|
||||
P 3 0 1 8 150 50 150 -50 150 -50 N
|
||||
P 4 0 1 8 -150 50 -170 50 -170 40 -170 40 N
|
||||
P 4 0 1 8 150 -50 170 -50 170 -40 170 -40 N
|
||||
P 4 0 1 8 150 50 130 50 130 40 130 40 N
|
||||
P 5 0 1 8 -130 -40 -130 -50 -150 -50 -150 -50 -150 -50 N
|
||||
P 6 0 1 8 -50 -50 -150 0 -50 50 -50 -50 -50 -50 -50 -50 N
|
||||
P 6 0 1 8 50 50 150 0 50 -50 50 50 50 50 50 50 N
|
||||
X A 1 0 -200 100 U 50 50 0 1 P
|
||||
X K 2 -300 0 150 R 50 50 0 1 P
|
||||
X K 3 300 0 150 L 50 50 0 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# LM1117-ADJ
|
||||
#
|
||||
DEF LM1117-ADJ U 0 30 Y Y 1 F N
|
||||
F0 "U" 100 -250 50 H V C CNN
|
||||
F1 "LM1117-ADJ" 0 250 50 H V C CNN
|
||||
F2 "" 0 0 50 H V C CNN
|
||||
F3 "" 0 0 50 H V C CNN
|
||||
ALIAS LM1117-1.8 LM1117-2.5 LM1117-3.3 LM1117-5.0
|
||||
$FPLIST
|
||||
SOT-223*
|
||||
TO-263*
|
||||
TO-252*
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
S -200 -200 200 200 0 1 10 f
|
||||
X GND/ADJ 1 0 -300 100 U 50 50 1 1 W
|
||||
X VO 2 300 0 100 L 50 50 1 1 w
|
||||
X VI 3 -300 0 100 R 50 50 1 1 W
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# PESD1CAN
|
||||
#
|
||||
DEF PESD1CAN D 0 30 Y N 1 F N
|
||||
F0 "D" 0 -350 50 H V C CNN
|
||||
F1 "PESD1CAN" 50 150 50 H V C CNN
|
||||
F2 "" 0 0 50 H V C CNN
|
||||
F3 "" 0 0 50 H V C CNN
|
||||
$FPLIST
|
||||
SOT23
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
S -200 100 300 -300 0 1 0 N
|
||||
P 2 0 1 0 -140 -200 150 -200 N
|
||||
P 2 0 1 0 -140 0 150 0 N
|
||||
P 3 0 1 8 -150 -150 -150 -250 -150 -250 N
|
||||
P 3 0 1 8 -150 50 -150 -50 -150 -50 N
|
||||
P 3 0 1 8 150 -150 150 -250 150 -250 N
|
||||
P 3 0 1 8 150 50 150 -50 150 -50 N
|
||||
P 4 0 1 8 -150 -150 -170 -150 -170 -160 -170 -160 N
|
||||
P 4 0 1 8 -150 50 -170 50 -170 40 -170 40 N
|
||||
P 4 0 1 8 150 -250 170 -250 170 -240 170 -240 N
|
||||
P 4 0 1 8 150 -150 130 -150 130 -160 130 -160 N
|
||||
P 4 0 1 8 150 -50 170 -50 170 -40 170 -40 N
|
||||
P 4 0 1 0 150 0 250 0 250 -200 150 -200 N
|
||||
P 4 0 1 8 150 50 130 50 130 40 130 40 N
|
||||
P 5 0 1 8 -130 -240 -130 -250 -150 -250 -150 -250 -150 -250 N
|
||||
P 5 0 1 8 -130 -40 -130 -50 -150 -50 -150 -50 -150 -50 N
|
||||
P 6 0 1 8 -50 -250 -150 -200 -50 -150 -50 -250 -50 -250 -50 -250 N
|
||||
P 6 0 1 8 -50 -50 -150 0 -50 50 -50 -50 -50 -50 -50 -50 N
|
||||
P 6 0 1 8 50 -150 150 -200 50 -250 50 -150 50 -150 50 -150 N
|
||||
P 6 0 1 8 50 50 150 0 50 -50 50 50 50 50 50 50 N
|
||||
X K 1 -300 0 150 R 50 50 0 1 P
|
||||
X K 2 -300 -200 150 R 50 50 0 1 P
|
||||
X O 3 400 -100 150 L 50 50 0 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# TPS2051
|
||||
#
|
||||
DEF TPS2051 U 0 40 Y Y 1 F N
|
||||
F0 "U" 0 -300 60 H V C CNN
|
||||
F1 "TPS2051" 0 300 60 H V C CNN
|
||||
F2 "" 0 0 60 H I C CNN
|
||||
F3 "" 0 0 60 H I C CNN
|
||||
DRAW
|
||||
S -250 250 250 -250 0 1 0 N
|
||||
X GND 1 -450 150 200 R 50 50 1 1 W
|
||||
X IN 2 -450 50 200 R 50 50 1 1 W
|
||||
X IN 3 -450 -50 200 R 50 50 1 1 P
|
||||
X EN 4 -450 -150 200 R 50 50 1 1 I
|
||||
X ~OC 5 450 -150 200 L 50 50 1 1 O
|
||||
X OUT 6 450 -50 200 L 50 50 1 1 P
|
||||
X OUT 7 450 50 200 L 50 50 1 1 P
|
||||
X OUT 8 450 150 200 L 50 50 1 1 w
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# USB6B1
|
||||
#
|
||||
DEF USB6B1 D 0 30 Y N 1 F N
|
||||
F0 "D" 0 -450 50 H V C CNN
|
||||
F1 "USB6B1" 0 400 50 H V C CNN
|
||||
F2 "" 200 -100 50 V V C CNN
|
||||
F3 "" 200 -100 50 V V C CNN
|
||||
$FPLIST
|
||||
SO8
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
C -150 -300 7 0 1 0 N
|
||||
C -150 100 7 0 1 0 N
|
||||
C -150 300 7 0 1 0 N
|
||||
C 0 -300 7 0 1 0 N
|
||||
C 0 -100 7 0 1 0 N
|
||||
C 0 300 7 0 1 0 N
|
||||
C 200 -300 7 0 1 0 N
|
||||
C 200 300 7 0 1 0 N
|
||||
S -300 -100 300 -100 0 1 0 N
|
||||
S -300 300 300 300 0 1 0 N
|
||||
S -200 -150 -100 -150 0 1 0 N
|
||||
S -200 250 -100 250 0 1 0 N
|
||||
S -150 300 -150 -300 0 1 0 N
|
||||
S -50 -150 50 -150 0 1 0 N
|
||||
S -50 250 50 250 0 1 0 N
|
||||
S 0 300 0 -300 0 1 0 N
|
||||
S 200 300 200 -300 0 1 0 N
|
||||
S 300 -300 -300 -300 0 1 0 N
|
||||
S 300 100 -300 100 0 1 0 N
|
||||
P 3 0 1 8 150 50 250 50 250 50 N
|
||||
P 4 0 1 8 150 50 150 30 160 30 160 30 N
|
||||
P 4 0 1 8 250 50 250 70 240 70 240 70 N
|
||||
P 5 0 1 0 -250 350 300 350 300 -350 -250 -350 -250 350 N
|
||||
P 6 0 1 8 -200 -250 -150 -150 -100 -250 -200 -250 -200 -250 -200 -250 N
|
||||
P 6 0 1 8 -200 150 -150 250 -100 150 -200 150 -200 150 -200 150 N
|
||||
P 6 0 1 8 -50 -250 0 -150 50 -250 -50 -250 -50 -250 -50 -250 N
|
||||
P 6 0 1 8 -50 150 0 250 50 150 -50 150 -50 150 -50 150 N
|
||||
P 6 0 1 8 150 -50 200 50 250 -50 150 -50 150 -50 150 -50 N
|
||||
X VCC 1 -500 300 200 R 50 50 1 1 P
|
||||
X I/O1 2 -500 100 200 R 50 50 1 1 P
|
||||
X I/O2 3 -500 -100 200 R 50 50 1 1 P
|
||||
X GND 4 -500 -300 200 R 50 50 1 1 P
|
||||
X GND 5 500 -300 200 L 50 50 1 1 P
|
||||
X I/O2 6 500 -100 200 L 50 50 1 1 P
|
||||
X I/O1 7 500 100 200 L 50 50 1 1 P
|
||||
X VCC 8 500 300 200 L 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
#End Library
|
||||
2626
F0:F030,F042,F072/Socket_fans/kicad/fp-info-cache
Normal file
6
F0:F030,F042,F072/Socket_fans/kicad/fp-lib-table
Normal file
@@ -0,0 +1,6 @@
|
||||
(fp_lib_table
|
||||
(lib (name TestPoint)(type KiCad)(uri ${KISYSMOD}/TestPoint.pretty)(options "")(descr ""))
|
||||
(lib (name Fuse)(type KiCad)(uri ${KISYSMOD}/Fuse.pretty)(options "")(descr ""))
|
||||
(lib (name MyFootprints)(type KiCad)(uri /home/eddy/Docs/SAO/ELECTRONICS/STM32/F0-srcs/CANbus_stepper/my_footprints.pretty)(options "")(descr ""))
|
||||
(lib (name Connector_Dsub)(type KiCad)(uri /usr/share/kicad/kicad-footprints/Connector_Dsub.pretty)(options "")(descr ""))
|
||||
)
|
||||
@@ -0,0 +1,9 @@
|
||||
(module Hole_3mm (layer F.Cu) (tedit 5913F6E4)
|
||||
(fp_text reference REF** (at 0 3.81) (layer F.SilkS) hide
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
)
|
||||
(fp_text value Hole_3mm (at 0 -7.62) (layer F.Fab) hide
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
)
|
||||
(pad 1 thru_hole circle (at 0 0) (size 5 5) (drill 3) (layers *.Cu *.Mask))
|
||||
)
|
||||
@@ -0,0 +1,10 @@
|
||||
(module TH_via (layer F.Cu) (tedit 5A5E619A)
|
||||
(fp_text reference REF** (at 0 0.5) (layer F.SilkS) hide
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
)
|
||||
(fp_text value TH_via (at 0 -0.5) (layer F.Fab) hide
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
)
|
||||
(pad 1 thru_hole circle (at 0 0) (size 1.5 1.5) (drill 0.8) (layers *.Cu *.Mask)
|
||||
(zone_connect 1))
|
||||
)
|
||||
4051
F0:F030,F042,F072/Socket_fans/kicad/pcb/stm32-B_Cu.gbr
Normal file
169
F0:F030,F042,F072/Socket_fans/kicad/pcb/stm32-B_Mask.gbr
Normal file
@@ -0,0 +1,169 @@
|
||||
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,5.1.6*
|
||||
G04 #@! TF.CreationDate,2020-10-24T20:22:56+03:00*
|
||||
G04 #@! TF.ProjectId,stm32,73746d33-322e-46b6-9963-61645f706362,rev?*
|
||||
G04 #@! TF.SameCoordinates,Original*
|
||||
G04 #@! TF.FileFunction,Soldermask,Bot*
|
||||
G04 #@! TF.FilePolarity,Negative*
|
||||
%FSLAX46Y46*%
|
||||
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
|
||||
G04 Created by KiCad (PCBNEW 5.1.6) date 2020-10-24 20:22:56*
|
||||
%MOMM*%
|
||||
%LPD*%
|
||||
G01*
|
||||
G04 APERTURE LIST*
|
||||
G04 #@! TA.AperFunction,Profile*
|
||||
%ADD10C,0.150000*%
|
||||
G04 #@! TD*
|
||||
%ADD11R,2.130000X2.430000*%
|
||||
%ADD12O,2.130000X2.430000*%
|
||||
%ADD13R,3.000000X3.000000*%
|
||||
%ADD14C,3.000000*%
|
||||
%ADD15R,2.100000X2.100000*%
|
||||
%ADD16O,2.100000X2.100000*%
|
||||
%ADD17O,2.100000X2.400000*%
|
||||
%ADD18C,3.400000*%
|
||||
%ADD19C,2.900000*%
|
||||
%ADD20C,2.100000*%
|
||||
%ADD21C,3.900000*%
|
||||
%ADD22C,3.600000*%
|
||||
%ADD23R,2.400000X2.305000*%
|
||||
%ADD24O,2.400000X2.305000*%
|
||||
%ADD25R,2.000000X2.000000*%
|
||||
%ADD26C,2.000000*%
|
||||
G04 APERTURE END LIST*
|
||||
D10*
|
||||
X38000000Y-104500000D02*
|
||||
X38000000Y-52000000D01*
|
||||
X113500000Y-104500000D02*
|
||||
X38000000Y-104500000D01*
|
||||
X113500000Y-52000000D02*
|
||||
X113500000Y-104500000D01*
|
||||
X38000000Y-52000000D02*
|
||||
X113500000Y-52000000D01*
|
||||
D11*
|
||||
X94500000Y-56000000D03*
|
||||
D12*
|
||||
X97040000Y-56000000D03*
|
||||
X99580000Y-56000000D03*
|
||||
X102120000Y-56000000D03*
|
||||
X86620000Y-56000000D03*
|
||||
X84080000Y-56000000D03*
|
||||
X81540000Y-56000000D03*
|
||||
D11*
|
||||
X79000000Y-56000000D03*
|
||||
D13*
|
||||
X52000000Y-98500000D03*
|
||||
D14*
|
||||
X57000000Y-98500000D03*
|
||||
D15*
|
||||
X74602000Y-98255500D03*
|
||||
D16*
|
||||
X74602000Y-100795500D03*
|
||||
X72062000Y-98255500D03*
|
||||
X72062000Y-100795500D03*
|
||||
X69522000Y-98255500D03*
|
||||
X69522000Y-100795500D03*
|
||||
X66982000Y-98255500D03*
|
||||
X66982000Y-100795500D03*
|
||||
D17*
|
||||
X109000000Y-68500000D03*
|
||||
G36*
|
||||
G01*
|
||||
X105450000Y-69391177D02*
|
||||
X105450000Y-67608823D01*
|
||||
G75*
|
||||
G02*
|
||||
X105758823Y-67300000I308823J0D01*
|
||||
G01*
|
||||
X107241177Y-67300000D01*
|
||||
G75*
|
||||
G02*
|
||||
X107550000Y-67608823I0J-308823D01*
|
||||
G01*
|
||||
X107550000Y-69391177D01*
|
||||
G75*
|
||||
G02*
|
||||
X107241177Y-69700000I-308823J0D01*
|
||||
G01*
|
||||
X105758823Y-69700000D01*
|
||||
G75*
|
||||
G02*
|
||||
X105450000Y-69391177I0J308823D01*
|
||||
G01*
|
||||
G37*
|
||||
G36*
|
||||
G01*
|
||||
X65950000Y-55891177D02*
|
||||
X65950000Y-54108823D01*
|
||||
G75*
|
||||
G02*
|
||||
X66258823Y-53800000I308823J0D01*
|
||||
G01*
|
||||
X67741177Y-53800000D01*
|
||||
G75*
|
||||
G02*
|
||||
X68050000Y-54108823I0J-308823D01*
|
||||
G01*
|
||||
X68050000Y-55891177D01*
|
||||
G75*
|
||||
G02*
|
||||
X67741177Y-56200000I-308823J0D01*
|
||||
G01*
|
||||
X66258823Y-56200000D01*
|
||||
G75*
|
||||
G02*
|
||||
X65950000Y-55891177I0J308823D01*
|
||||
G01*
|
||||
G37*
|
||||
X69500000Y-55000000D03*
|
||||
D13*
|
||||
X56885500Y-58000000D03*
|
||||
D14*
|
||||
X51885500Y-58000000D03*
|
||||
D18*
|
||||
X57025200Y-74107720D03*
|
||||
D19*
|
||||
X55075200Y-68157720D03*
|
||||
D18*
|
||||
X42825200Y-68107720D03*
|
||||
X42875200Y-80157720D03*
|
||||
D19*
|
||||
X55075200Y-80157720D03*
|
||||
D15*
|
||||
X105463000Y-82063000D03*
|
||||
D20*
|
||||
X105463000Y-79563000D03*
|
||||
X107463000Y-79563000D03*
|
||||
X107463000Y-82063000D03*
|
||||
D21*
|
||||
X110173000Y-86833000D03*
|
||||
X110173000Y-74793000D03*
|
||||
D22*
|
||||
X44500000Y-100500000D03*
|
||||
X107500000Y-61000000D03*
|
||||
X44500000Y-61000000D03*
|
||||
X107500000Y-100500000D03*
|
||||
D16*
|
||||
X89588000Y-94001000D03*
|
||||
D15*
|
||||
X89588000Y-96541000D03*
|
||||
X93334500Y-96541000D03*
|
||||
D16*
|
||||
X93334500Y-94001000D03*
|
||||
D23*
|
||||
X42153500Y-88349500D03*
|
||||
D24*
|
||||
X42153500Y-90889500D03*
|
||||
X42153500Y-93429500D03*
|
||||
D15*
|
||||
X79682000Y-70950500D03*
|
||||
D16*
|
||||
X82222000Y-70950500D03*
|
||||
X71460000Y-77872000D03*
|
||||
D15*
|
||||
X74000000Y-77872000D03*
|
||||
D25*
|
||||
X63844500Y-82734000D03*
|
||||
D26*
|
||||
X63844500Y-86234000D03*
|
||||
M02*
|
||||
1604
F0:F030,F042,F072/Socket_fans/kicad/pcb/stm32-B_SilkS.gbr
Normal file
14162
F0:F030,F042,F072/Socket_fans/kicad/pcb/stm32-F_Cu.gbr
Normal file
3919
F0:F030,F042,F072/Socket_fans/kicad/pcb/stm32-F_Mask.gbr
Normal file
2592
F0:F030,F042,F072/Socket_fans/kicad/pcb/stm32-F_SilkS.gbr
Normal file
498
F0:F030,F042,F072/Socket_fans/kicad/pcb/stm32-NPTH-drl_map.gbr
Normal file
@@ -0,0 +1,498 @@
|
||||
%FSLAX45Y45*%
|
||||
G04 Gerber Fmt 4.5, Leading zero omitted, Abs format (unit mm)*
|
||||
G04 Created by KiCad (PCBNEW 5.1.6) date 2020-10-24 20:22:54*
|
||||
%MOMM*%
|
||||
%LPD*%
|
||||
G01*
|
||||
G04 APERTURE LIST*
|
||||
%TA.AperFunction,Profile*%
|
||||
%ADD10C,0.150000*%
|
||||
%TD*%
|
||||
%ADD11C,0.200000*%
|
||||
%ADD12C,0.300000*%
|
||||
G04 APERTURE END LIST*
|
||||
D10*
|
||||
X3800000Y-10450000D02*
|
||||
X3800000Y-5200000D01*
|
||||
X11350000Y-10450000D02*
|
||||
X3800000Y-10450000D01*
|
||||
X11350000Y-5200000D02*
|
||||
X11350000Y-10450000D01*
|
||||
X3800000Y-5200000D02*
|
||||
X11350000Y-5200000D01*
|
||||
D11*
|
||||
X10590000Y-9890000D02*
|
||||
X10910000Y-10210000D01*
|
||||
X10910000Y-9890000D02*
|
||||
X10590000Y-10210000D01*
|
||||
X4290000Y-5940000D02*
|
||||
X4610000Y-6260000D01*
|
||||
X4610000Y-5940000D02*
|
||||
X4290000Y-6260000D01*
|
||||
X10590000Y-5940000D02*
|
||||
X10910000Y-6260000D01*
|
||||
X10910000Y-5940000D02*
|
||||
X10590000Y-6260000D01*
|
||||
X4290000Y-9890000D02*
|
||||
X4610000Y-10210000D01*
|
||||
X4610000Y-9890000D02*
|
||||
X4290000Y-10210000D01*
|
||||
D12*
|
||||
X4078928Y-10923214D02*
|
||||
X4078928Y-10623214D01*
|
||||
X4150357Y-10623214D01*
|
||||
X4193214Y-10637500D01*
|
||||
X4221786Y-10666072D01*
|
||||
X4236071Y-10694643D01*
|
||||
X4250357Y-10751786D01*
|
||||
X4250357Y-10794643D01*
|
||||
X4236071Y-10851786D01*
|
||||
X4221786Y-10880357D01*
|
||||
X4193214Y-10908929D01*
|
||||
X4150357Y-10923214D01*
|
||||
X4078928Y-10923214D01*
|
||||
X4378928Y-10923214D02*
|
||||
X4378928Y-10723214D01*
|
||||
X4378928Y-10780357D02*
|
||||
X4393214Y-10751786D01*
|
||||
X4407500Y-10737500D01*
|
||||
X4436071Y-10723214D01*
|
||||
X4464643Y-10723214D01*
|
||||
X4564643Y-10923214D02*
|
||||
X4564643Y-10723214D01*
|
||||
X4564643Y-10623214D02*
|
||||
X4550357Y-10637500D01*
|
||||
X4564643Y-10651786D01*
|
||||
X4578928Y-10637500D01*
|
||||
X4564643Y-10623214D01*
|
||||
X4564643Y-10651786D01*
|
||||
X4750357Y-10923214D02*
|
||||
X4721786Y-10908929D01*
|
||||
X4707500Y-10880357D01*
|
||||
X4707500Y-10623214D01*
|
||||
X4907500Y-10923214D02*
|
||||
X4878928Y-10908929D01*
|
||||
X4864643Y-10880357D01*
|
||||
X4864643Y-10623214D01*
|
||||
X5250357Y-10923214D02*
|
||||
X5250357Y-10623214D01*
|
||||
X5350357Y-10837500D01*
|
||||
X5450357Y-10623214D01*
|
||||
X5450357Y-10923214D01*
|
||||
X5721786Y-10923214D02*
|
||||
X5721786Y-10766072D01*
|
||||
X5707500Y-10737500D01*
|
||||
X5678928Y-10723214D01*
|
||||
X5621786Y-10723214D01*
|
||||
X5593214Y-10737500D01*
|
||||
X5721786Y-10908929D02*
|
||||
X5693214Y-10923214D01*
|
||||
X5621786Y-10923214D01*
|
||||
X5593214Y-10908929D01*
|
||||
X5578928Y-10880357D01*
|
||||
X5578928Y-10851786D01*
|
||||
X5593214Y-10823214D01*
|
||||
X5621786Y-10808929D01*
|
||||
X5693214Y-10808929D01*
|
||||
X5721786Y-10794643D01*
|
||||
X5864643Y-10723214D02*
|
||||
X5864643Y-11023214D01*
|
||||
X5864643Y-10737500D02*
|
||||
X5893214Y-10723214D01*
|
||||
X5950357Y-10723214D01*
|
||||
X5978928Y-10737500D01*
|
||||
X5993214Y-10751786D01*
|
||||
X6007500Y-10780357D01*
|
||||
X6007500Y-10866072D01*
|
||||
X5993214Y-10894643D01*
|
||||
X5978928Y-10908929D01*
|
||||
X5950357Y-10923214D01*
|
||||
X5893214Y-10923214D01*
|
||||
X5864643Y-10908929D01*
|
||||
X6136071Y-10894643D02*
|
||||
X6150357Y-10908929D01*
|
||||
X6136071Y-10923214D01*
|
||||
X6121786Y-10908929D01*
|
||||
X6136071Y-10894643D01*
|
||||
X6136071Y-10923214D01*
|
||||
X6136071Y-10737500D02*
|
||||
X6150357Y-10751786D01*
|
||||
X6136071Y-10766072D01*
|
||||
X6121786Y-10751786D01*
|
||||
X6136071Y-10737500D01*
|
||||
X6136071Y-10766072D01*
|
||||
X3472500Y-11257500D02*
|
||||
X3792500Y-11577500D01*
|
||||
X3792500Y-11257500D02*
|
||||
X3472500Y-11577500D01*
|
||||
X4050357Y-11253214D02*
|
||||
X4236071Y-11253214D01*
|
||||
X4136071Y-11367500D01*
|
||||
X4178928Y-11367500D01*
|
||||
X4207500Y-11381786D01*
|
||||
X4221786Y-11396071D01*
|
||||
X4236071Y-11424643D01*
|
||||
X4236071Y-11496071D01*
|
||||
X4221786Y-11524643D01*
|
||||
X4207500Y-11538929D01*
|
||||
X4178928Y-11553214D01*
|
||||
X4093214Y-11553214D01*
|
||||
X4064643Y-11538929D01*
|
||||
X4050357Y-11524643D01*
|
||||
X4364643Y-11524643D02*
|
||||
X4378928Y-11538929D01*
|
||||
X4364643Y-11553214D01*
|
||||
X4350357Y-11538929D01*
|
||||
X4364643Y-11524643D01*
|
||||
X4364643Y-11553214D01*
|
||||
X4493214Y-11281786D02*
|
||||
X4507500Y-11267500D01*
|
||||
X4536071Y-11253214D01*
|
||||
X4607500Y-11253214D01*
|
||||
X4636071Y-11267500D01*
|
||||
X4650357Y-11281786D01*
|
||||
X4664643Y-11310357D01*
|
||||
X4664643Y-11338929D01*
|
||||
X4650357Y-11381786D01*
|
||||
X4478928Y-11553214D01*
|
||||
X4664643Y-11553214D01*
|
||||
X4850357Y-11253214D02*
|
||||
X4878928Y-11253214D01*
|
||||
X4907500Y-11267500D01*
|
||||
X4921786Y-11281786D01*
|
||||
X4936071Y-11310357D01*
|
||||
X4950357Y-11367500D01*
|
||||
X4950357Y-11438929D01*
|
||||
X4936071Y-11496071D01*
|
||||
X4921786Y-11524643D01*
|
||||
X4907500Y-11538929D01*
|
||||
X4878928Y-11553214D01*
|
||||
X4850357Y-11553214D01*
|
||||
X4821786Y-11538929D01*
|
||||
X4807500Y-11524643D01*
|
||||
X4793214Y-11496071D01*
|
||||
X4778928Y-11438929D01*
|
||||
X4778928Y-11367500D01*
|
||||
X4793214Y-11310357D01*
|
||||
X4807500Y-11281786D01*
|
||||
X4821786Y-11267500D01*
|
||||
X4850357Y-11253214D01*
|
||||
X5078928Y-11553214D02*
|
||||
X5078928Y-11353214D01*
|
||||
X5078928Y-11381786D02*
|
||||
X5093214Y-11367500D01*
|
||||
X5121786Y-11353214D01*
|
||||
X5164643Y-11353214D01*
|
||||
X5193214Y-11367500D01*
|
||||
X5207500Y-11396071D01*
|
||||
X5207500Y-11553214D01*
|
||||
X5207500Y-11396071D02*
|
||||
X5221786Y-11367500D01*
|
||||
X5250357Y-11353214D01*
|
||||
X5293214Y-11353214D01*
|
||||
X5321786Y-11367500D01*
|
||||
X5336071Y-11396071D01*
|
||||
X5336071Y-11553214D01*
|
||||
X5478928Y-11553214D02*
|
||||
X5478928Y-11353214D01*
|
||||
X5478928Y-11381786D02*
|
||||
X5493214Y-11367500D01*
|
||||
X5521786Y-11353214D01*
|
||||
X5564643Y-11353214D01*
|
||||
X5593214Y-11367500D01*
|
||||
X5607500Y-11396071D01*
|
||||
X5607500Y-11553214D01*
|
||||
X5607500Y-11396071D02*
|
||||
X5621786Y-11367500D01*
|
||||
X5650357Y-11353214D01*
|
||||
X5693214Y-11353214D01*
|
||||
X5721786Y-11367500D01*
|
||||
X5736071Y-11396071D01*
|
||||
X5736071Y-11553214D01*
|
||||
X6321786Y-11238929D02*
|
||||
X6064643Y-11624643D01*
|
||||
X6707500Y-11253214D02*
|
||||
X6736071Y-11253214D01*
|
||||
X6764643Y-11267500D01*
|
||||
X6778928Y-11281786D01*
|
||||
X6793214Y-11310357D01*
|
||||
X6807500Y-11367500D01*
|
||||
X6807500Y-11438929D01*
|
||||
X6793214Y-11496071D01*
|
||||
X6778928Y-11524643D01*
|
||||
X6764643Y-11538929D01*
|
||||
X6736071Y-11553214D01*
|
||||
X6707500Y-11553214D01*
|
||||
X6678928Y-11538929D01*
|
||||
X6664643Y-11524643D01*
|
||||
X6650357Y-11496071D01*
|
||||
X6636071Y-11438929D01*
|
||||
X6636071Y-11367500D01*
|
||||
X6650357Y-11310357D01*
|
||||
X6664643Y-11281786D01*
|
||||
X6678928Y-11267500D01*
|
||||
X6707500Y-11253214D01*
|
||||
X6936071Y-11524643D02*
|
||||
X6950357Y-11538929D01*
|
||||
X6936071Y-11553214D01*
|
||||
X6921786Y-11538929D01*
|
||||
X6936071Y-11524643D01*
|
||||
X6936071Y-11553214D01*
|
||||
X7236071Y-11553214D02*
|
||||
X7064643Y-11553214D01*
|
||||
X7150357Y-11553214D02*
|
||||
X7150357Y-11253214D01*
|
||||
X7121786Y-11296071D01*
|
||||
X7093214Y-11324643D01*
|
||||
X7064643Y-11338929D01*
|
||||
X7350357Y-11281786D02*
|
||||
X7364643Y-11267500D01*
|
||||
X7393214Y-11253214D01*
|
||||
X7464643Y-11253214D01*
|
||||
X7493214Y-11267500D01*
|
||||
X7507500Y-11281786D01*
|
||||
X7521786Y-11310357D01*
|
||||
X7521786Y-11338929D01*
|
||||
X7507500Y-11381786D01*
|
||||
X7336071Y-11553214D01*
|
||||
X7521786Y-11553214D01*
|
||||
X7778928Y-11253214D02*
|
||||
X7721786Y-11253214D01*
|
||||
X7693214Y-11267500D01*
|
||||
X7678928Y-11281786D01*
|
||||
X7650357Y-11324643D01*
|
||||
X7636071Y-11381786D01*
|
||||
X7636071Y-11496071D01*
|
||||
X7650357Y-11524643D01*
|
||||
X7664643Y-11538929D01*
|
||||
X7693214Y-11553214D01*
|
||||
X7750357Y-11553214D01*
|
||||
X7778928Y-11538929D01*
|
||||
X7793214Y-11524643D01*
|
||||
X7807500Y-11496071D01*
|
||||
X7807500Y-11424643D01*
|
||||
X7793214Y-11396071D01*
|
||||
X7778928Y-11381786D01*
|
||||
X7750357Y-11367500D01*
|
||||
X7693214Y-11367500D01*
|
||||
X7664643Y-11381786D01*
|
||||
X7650357Y-11396071D01*
|
||||
X7636071Y-11424643D01*
|
||||
X7921786Y-11253214D02*
|
||||
X7921786Y-11310357D01*
|
||||
X8036071Y-11253214D02*
|
||||
X8036071Y-11310357D01*
|
||||
X8478928Y-11667500D02*
|
||||
X8464643Y-11653214D01*
|
||||
X8436071Y-11610357D01*
|
||||
X8421786Y-11581786D01*
|
||||
X8407500Y-11538929D01*
|
||||
X8393214Y-11467500D01*
|
||||
X8393214Y-11410357D01*
|
||||
X8407500Y-11338929D01*
|
||||
X8421786Y-11296071D01*
|
||||
X8436071Y-11267500D01*
|
||||
X8464643Y-11224643D01*
|
||||
X8478928Y-11210357D01*
|
||||
X8721786Y-11353214D02*
|
||||
X8721786Y-11553214D01*
|
||||
X8650357Y-11238929D02*
|
||||
X8578928Y-11453214D01*
|
||||
X8764643Y-11453214D01*
|
||||
X9107500Y-11553214D02*
|
||||
X9107500Y-11253214D01*
|
||||
X9236071Y-11553214D02*
|
||||
X9236071Y-11396071D01*
|
||||
X9221786Y-11367500D01*
|
||||
X9193214Y-11353214D01*
|
||||
X9150357Y-11353214D01*
|
||||
X9121786Y-11367500D01*
|
||||
X9107500Y-11381786D01*
|
||||
X9421786Y-11553214D02*
|
||||
X9393214Y-11538929D01*
|
||||
X9378928Y-11524643D01*
|
||||
X9364643Y-11496071D01*
|
||||
X9364643Y-11410357D01*
|
||||
X9378928Y-11381786D01*
|
||||
X9393214Y-11367500D01*
|
||||
X9421786Y-11353214D01*
|
||||
X9464643Y-11353214D01*
|
||||
X9493214Y-11367500D01*
|
||||
X9507500Y-11381786D01*
|
||||
X9521786Y-11410357D01*
|
||||
X9521786Y-11496071D01*
|
||||
X9507500Y-11524643D01*
|
||||
X9493214Y-11538929D01*
|
||||
X9464643Y-11553214D01*
|
||||
X9421786Y-11553214D01*
|
||||
X9693214Y-11553214D02*
|
||||
X9664643Y-11538929D01*
|
||||
X9650357Y-11510357D01*
|
||||
X9650357Y-11253214D01*
|
||||
X9921786Y-11538929D02*
|
||||
X9893214Y-11553214D01*
|
||||
X9836071Y-11553214D01*
|
||||
X9807500Y-11538929D01*
|
||||
X9793214Y-11510357D01*
|
||||
X9793214Y-11396071D01*
|
||||
X9807500Y-11367500D01*
|
||||
X9836071Y-11353214D01*
|
||||
X9893214Y-11353214D01*
|
||||
X9921786Y-11367500D01*
|
||||
X9936071Y-11396071D01*
|
||||
X9936071Y-11424643D01*
|
||||
X9793214Y-11453214D01*
|
||||
X10050357Y-11538929D02*
|
||||
X10078928Y-11553214D01*
|
||||
X10136071Y-11553214D01*
|
||||
X10164643Y-11538929D01*
|
||||
X10178928Y-11510357D01*
|
||||
X10178928Y-11496071D01*
|
||||
X10164643Y-11467500D01*
|
||||
X10136071Y-11453214D01*
|
||||
X10093214Y-11453214D01*
|
||||
X10064643Y-11438929D01*
|
||||
X10050357Y-11410357D01*
|
||||
X10050357Y-11396071D01*
|
||||
X10064643Y-11367500D01*
|
||||
X10093214Y-11353214D01*
|
||||
X10136071Y-11353214D01*
|
||||
X10164643Y-11367500D01*
|
||||
X10278928Y-11667500D02*
|
||||
X10293214Y-11653214D01*
|
||||
X10321786Y-11610357D01*
|
||||
X10336071Y-11581786D01*
|
||||
X10350357Y-11538929D01*
|
||||
X10364643Y-11467500D01*
|
||||
X10364643Y-11410357D01*
|
||||
X10350357Y-11338929D01*
|
||||
X10336071Y-11296071D01*
|
||||
X10321786Y-11267500D01*
|
||||
X10293214Y-11224643D01*
|
||||
X10278928Y-11210357D01*
|
||||
X10821786Y-11667500D02*
|
||||
X10807500Y-11653214D01*
|
||||
X10778928Y-11610357D01*
|
||||
X10764643Y-11581786D01*
|
||||
X10750357Y-11538929D01*
|
||||
X10736071Y-11467500D01*
|
||||
X10736071Y-11410357D01*
|
||||
X10750357Y-11338929D01*
|
||||
X10764643Y-11296071D01*
|
||||
X10778928Y-11267500D01*
|
||||
X10807500Y-11224643D01*
|
||||
X10821786Y-11210357D01*
|
||||
X10936071Y-11353214D02*
|
||||
X10936071Y-11553214D01*
|
||||
X10936071Y-11381786D02*
|
||||
X10950357Y-11367500D01*
|
||||
X10978928Y-11353214D01*
|
||||
X11021786Y-11353214D01*
|
||||
X11050357Y-11367500D01*
|
||||
X11064643Y-11396071D01*
|
||||
X11064643Y-11553214D01*
|
||||
X11250357Y-11553214D02*
|
||||
X11221786Y-11538929D01*
|
||||
X11207500Y-11524643D01*
|
||||
X11193214Y-11496071D01*
|
||||
X11193214Y-11410357D01*
|
||||
X11207500Y-11381786D01*
|
||||
X11221786Y-11367500D01*
|
||||
X11250357Y-11353214D01*
|
||||
X11293214Y-11353214D01*
|
||||
X11321786Y-11367500D01*
|
||||
X11336071Y-11381786D01*
|
||||
X11350357Y-11410357D01*
|
||||
X11350357Y-11496071D01*
|
||||
X11336071Y-11524643D01*
|
||||
X11321786Y-11538929D01*
|
||||
X11293214Y-11553214D01*
|
||||
X11250357Y-11553214D01*
|
||||
X11436071Y-11353214D02*
|
||||
X11550357Y-11353214D01*
|
||||
X11478928Y-11253214D02*
|
||||
X11478928Y-11510357D01*
|
||||
X11493214Y-11538929D01*
|
||||
X11521786Y-11553214D01*
|
||||
X11550357Y-11553214D01*
|
||||
X11878928Y-11353214D02*
|
||||
X11878928Y-11653214D01*
|
||||
X11878928Y-11367500D02*
|
||||
X11907500Y-11353214D01*
|
||||
X11964643Y-11353214D01*
|
||||
X11993214Y-11367500D01*
|
||||
X12007500Y-11381786D01*
|
||||
X12021786Y-11410357D01*
|
||||
X12021786Y-11496071D01*
|
||||
X12007500Y-11524643D01*
|
||||
X11993214Y-11538929D01*
|
||||
X11964643Y-11553214D01*
|
||||
X11907500Y-11553214D01*
|
||||
X11878928Y-11538929D01*
|
||||
X12193214Y-11553214D02*
|
||||
X12164643Y-11538929D01*
|
||||
X12150357Y-11510357D01*
|
||||
X12150357Y-11253214D01*
|
||||
X12436071Y-11553214D02*
|
||||
X12436071Y-11396071D01*
|
||||
X12421786Y-11367500D01*
|
||||
X12393214Y-11353214D01*
|
||||
X12336071Y-11353214D01*
|
||||
X12307500Y-11367500D01*
|
||||
X12436071Y-11538929D02*
|
||||
X12407500Y-11553214D01*
|
||||
X12336071Y-11553214D01*
|
||||
X12307500Y-11538929D01*
|
||||
X12293214Y-11510357D01*
|
||||
X12293214Y-11481786D01*
|
||||
X12307500Y-11453214D01*
|
||||
X12336071Y-11438929D01*
|
||||
X12407500Y-11438929D01*
|
||||
X12436071Y-11424643D01*
|
||||
X12536071Y-11353214D02*
|
||||
X12650357Y-11353214D01*
|
||||
X12578928Y-11253214D02*
|
||||
X12578928Y-11510357D01*
|
||||
X12593214Y-11538929D01*
|
||||
X12621786Y-11553214D01*
|
||||
X12650357Y-11553214D01*
|
||||
X12864643Y-11538929D02*
|
||||
X12836071Y-11553214D01*
|
||||
X12778928Y-11553214D01*
|
||||
X12750357Y-11538929D01*
|
||||
X12736071Y-11510357D01*
|
||||
X12736071Y-11396071D01*
|
||||
X12750357Y-11367500D01*
|
||||
X12778928Y-11353214D01*
|
||||
X12836071Y-11353214D01*
|
||||
X12864643Y-11367500D01*
|
||||
X12878928Y-11396071D01*
|
||||
X12878928Y-11424643D01*
|
||||
X12736071Y-11453214D01*
|
||||
X13136071Y-11553214D02*
|
||||
X13136071Y-11253214D01*
|
||||
X13136071Y-11538929D02*
|
||||
X13107500Y-11553214D01*
|
||||
X13050357Y-11553214D01*
|
||||
X13021786Y-11538929D01*
|
||||
X13007500Y-11524643D01*
|
||||
X12993214Y-11496071D01*
|
||||
X12993214Y-11410357D01*
|
||||
X13007500Y-11381786D01*
|
||||
X13021786Y-11367500D01*
|
||||
X13050357Y-11353214D01*
|
||||
X13107500Y-11353214D01*
|
||||
X13136071Y-11367500D01*
|
||||
X13250357Y-11667500D02*
|
||||
X13264643Y-11653214D01*
|
||||
X13293214Y-11610357D01*
|
||||
X13307500Y-11581786D01*
|
||||
X13321786Y-11538929D01*
|
||||
X13336071Y-11467500D01*
|
||||
X13336071Y-11410357D01*
|
||||
X13321786Y-11338929D01*
|
||||
X13307500Y-11296071D01*
|
||||
X13293214Y-11267500D01*
|
||||
X13264643Y-11224643D01*
|
||||
X13250357Y-11210357D01*
|
||||
M02*
|
||||
2693
F0:F030,F042,F072/Socket_fans/kicad/pcb/stm32-PTH-drl_map.gbr
Normal file
40
F0:F030,F042,F072/Socket_fans/kicad/stm32
Normal file
@@ -0,0 +1,40 @@
|
||||
"Source:","/home/eddy/Yandex.Disk/Projects/stm32samples/F0-nolib/Socket_fans/kicad/stm32.sch"
|
||||
"Date:","ðÎ 02 ÎÏÑ 2020 23:57:22"
|
||||
"Tool:","Eeschema 5.1.6"
|
||||
"Generator:","/usr/share/kicad/plugins/bom_csv_grouped_by_value_with_fp.py"
|
||||
"Component Count:","89"
|
||||
"Ref","Qnty","Value","Cmp name","Footprint","Description","Vendor"
|
||||
"C1, C2, C3, C4, C5, C6, C8, C13, C14, C15, C16, C17, C18, C19, C20, ","15","0.1","C","Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder","Unpolarized capacitor",""
|
||||
"C7, ","1","47uF, 10V","CP","Capacitor_Tantalum_SMD:CP_EIA-6032-28_Kemet-C_Pad2.25x2.35mm_HandSolder","Polarized capacitor",""
|
||||
"C9, ","1","10uF, 10V","C","Capacitor_SMD:C_1206_3216Metric_Pad1.42x1.75mm_HandSolder","Unpolarized capacitor",""
|
||||
"C10, ","1","47u, 25V","CP","Capacitor_THT:CP_Radial_D8.0mm_P3.50mm","Polarized capacitor",""
|
||||
"D1, D2, D4, D5, D6, D9, ","6","1N5819","D_Schottky","Diode_SMD:D_SOD-323_HandSoldering","Schottky diode",""
|
||||
"D3, ","1","MM3Z7V5","D_Zener","Diode_SMD:D_0805_2012Metric_Pad1.15x1.40mm_HandSolder","Zener diode",""
|
||||
"D7, ","1","MM3Z4V3","D_Zener","Diode_SMD:D_0805_2012Metric_Pad1.15x1.40mm_HandSolder","Zener diode",""
|
||||
"D8, D10, ","2","MM3Z3V6","D_Zener","Diode_SMD:D_0805_2012Metric_Pad1.15x1.40mm_HandSolder","Zener diode",""
|
||||
"J1, ","1","12VIN","Conn_01x02-Chiller_control-rescue","TerminalBlock_Phoenix:TerminalBlock_Phoenix_MKDS-1,5-2_1x02_P5.00mm_Horizontal","",""
|
||||
"J2, ","1","thermal","Conn_02x04_Odd_Even","Connector_PinSocket_2.54mm:PinSocket_2x04_P2.54mm_Vertical","Generic connector, double row, 02x04, odd/even pin numbering scheme (row 1 odd numbers, row 2 even numbers), script generated (kicad-library-utils/schlib/autogen/connector/)",""
|
||||
"J3, ","1","Buzzer","Conn_01x02_Male","Connector_JST:JST_EH_B2B-EH-A_1x02_P2.50mm_Vertical","Generic connector, single row, 01x02, script generated (kicad-library-utils/schlib/autogen/connector/)",""
|
||||
"J4, ","1","cooler3","Conn_01x02_Male","Connector_JST:JST_EH_B2B-EH-A_1x02_P2.50mm_Vertical","Generic connector, single row, 01x02, script generated (kicad-library-utils/schlib/autogen/connector/)",""
|
||||
"J5, J6, ","2","FAN","Conn_01x04_Male","Connector:FanPinHeader_1x04_P2.54mm_Vertical","Generic connector, single row, 01x04, script generated (kicad-library-utils/schlib/autogen/connector/)",""
|
||||
"J7, J10, ","2","Conn_01x02_Female","Conn_01x02_Female","Connector_PinSocket_2.54mm:PinSocket_1x02_P2.54mm_Vertical","Generic connector, single row, 01x02, script generated (kicad-library-utils/schlib/autogen/connector/)",""
|
||||
"J8, ","1","MKDS","Conn_01x02_Female","TerminalBlock_Phoenix:TerminalBlock_Phoenix_MKDS-1,5-2_1x02_P5.00mm_Horizontal","Generic connector, single row, 01x02, script generated (kicad-library-utils/schlib/autogen/connector/)",""
|
||||
"K1, ","1","SRD-12VDC","G5LE-1-socket-rescue","Relay_THT:Relay_SPDT_SANYOU_SRD_Series_Form_C","",""
|
||||
"L1, ","1","BMBA 0.1mH","L-Chiller_control-rescue","Inductor_SMD:L_0805_2012Metric_Pad1.15x1.40mm_HandSolder","",""
|
||||
"P1, ","1","USB_A","USB_B","Connector_USB:USB_B_OST_USB-B1HSxx_Horizontal","USB Type B connector",""
|
||||
"P2, P3, P4, P5, ","4","Hole","Conn_01x01","MountingHole:MountingHole_3.2mm_M3","Generic connector, single row, 01x01, script generated (kicad-library-utils/schlib/autogen/connector/)",""
|
||||
"Q1, ","1","AO3401","Q_PMOS_GSD","Package_TO_SOT_SMD:SOT-23_Handsoldering","P-MOSFET transistor, gate/source/drain",""
|
||||
"Q2, Q3, Q4, Q5, Q6, ","5","IRLML2502","Q_NMOS_GSD-socket-rescue","Package_TO_SOT_SMD:SOT-23_Handsoldering","",""
|
||||
"R1, R2, R4, R6, R8, R13, R14, R16, R17, R34, ","10","10k","R-socket-rescue","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder","",""
|
||||
"R3, R5, R7, R9, ","4","4k7, 1%","R-Chiller_control-rescue","Resistor_SMD:R_0805_2012Metric_Pad1.15x1.40mm_HandSolder","",""
|
||||
"R10, R11, R12, R15, R18, R19, R20, R21, R24, R25, R32, ","11","510","R-socket-rescue","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder","",""
|
||||
"R22, ","1","47k","R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder","Resistor",""
|
||||
"R23, R30, R31, ","3","22","R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder","Resistor",""
|
||||
"R26, ","1","3.3k","R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder","Resistor",""
|
||||
"R27, ","1","1k","R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder","Resistor",""
|
||||
"R28, R29, ","2","4.7k","R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder","Resistor",""
|
||||
"SW1, SW2, ","2","SW_Push","SW_Push","Connector_PinSocket_2.54mm:PinSocket_1x02_P2.54mm_Vertical","Push button switch, generic, two pins",""
|
||||
"U1, ","1","LM1117-3.3","LM1117-3.3","Package_TO_SOT_SMD:SOT-223-3_TabPin2","800mA Low-Dropout Linear Regulator, 3.3V fixed output, TO-220/TO-252/TO-263/SOT-223",""
|
||||
"U2, ","1","L7805","L7805","Package_TO_SOT_THT:TO-220-3_Vertical","Positive 1.5A 35V Linear Regulator, Fixed Output 5V, TO-220/TO-263/TO-252",""
|
||||
"U3, ","1","STM32F072CBTx","STM32F072CBTx","Package_QFP:LQFP-48_7x7mm_P0.5mm","ARM Cortex-M0 MCU, 128KB flash, 16KB RAM, 48MHz, 2-3.6V, 37 GPIO, LQFP-48",""
|
||||
"U4, ","1","USBLC6-2SC6","USBLC6-2SC6","Package_TO_SOT_SMD:SOT-23-6","Bidirectional ESD Protection Diode, SOT-23-6",""
|
||||
307
F0:F030,F042,F072/Socket_fans/kicad/stm32-rescue.lib
Normal file
@@ -0,0 +1,307 @@
|
||||
EESchema-LIBRARY Version 2.4
|
||||
#encoding utf-8
|
||||
#
|
||||
# +12V-Chiller_control-rescue
|
||||
#
|
||||
DEF +12V-Chiller_control-rescue #PWR 0 0 Y Y 1 F P
|
||||
F0 "#PWR" 0 -150 50 H I C CNN
|
||||
F1 "+12V-Chiller_control-rescue" 0 140 50 H V C CNN
|
||||
F2 "" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
DRAW
|
||||
P 2 0 1 0 -30 50 0 100 N
|
||||
P 2 0 1 0 0 0 0 100 N
|
||||
P 2 0 1 0 0 100 30 50 N
|
||||
X +12V 1 0 0 0 U 50 50 1 1 W N
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# +3.3V-Chiller_control-rescue
|
||||
#
|
||||
DEF +3.3V-Chiller_control-rescue #PWR 0 0 Y Y 1 F P
|
||||
F0 "#PWR" 0 -150 50 H I C CNN
|
||||
F1 "+3.3V-Chiller_control-rescue" 0 140 50 H V C CNN
|
||||
F2 "" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
DRAW
|
||||
P 2 0 1 0 -30 50 0 100 N
|
||||
P 2 0 1 0 0 0 0 100 N
|
||||
P 2 0 1 0 0 100 30 50 N
|
||||
X +3V3 1 0 0 0 U 50 50 1 1 W N
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# C-Chiller_control-rescue
|
||||
#
|
||||
DEF C-Chiller_control-rescue C 0 10 N Y 1 F N
|
||||
F0 "C" 25 100 50 H V L CNN
|
||||
F1 "C-Chiller_control-rescue" 25 -100 50 H V L CNN
|
||||
F2 "" 38 -150 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
$FPLIST
|
||||
C_*
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
P 2 0 1 20 -80 -30 80 -30 N
|
||||
P 2 0 1 20 -80 30 80 30 N
|
||||
X ~ 1 0 150 110 D 50 50 1 1 P
|
||||
X ~ 2 0 -150 110 U 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# CP-Chiller_control-rescue
|
||||
#
|
||||
DEF CP-Chiller_control-rescue C 0 10 N Y 1 F N
|
||||
F0 "C" 25 100 50 H V L CNN
|
||||
F1 "CP-Chiller_control-rescue" 25 -100 50 H V L CNN
|
||||
F2 "" 38 -150 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
$FPLIST
|
||||
CP_*
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
S -90 20 -90 40 0 1 0 N
|
||||
S -90 20 90 20 0 1 0 N
|
||||
S 90 -20 -90 -40 0 1 0 F
|
||||
S 90 40 -90 40 0 1 0 N
|
||||
S 90 40 90 20 0 1 0 N
|
||||
P 2 0 1 0 -70 90 -30 90 N
|
||||
P 2 0 1 0 -50 110 -50 70 N
|
||||
X ~ 1 0 150 110 D 50 50 1 1 P
|
||||
X ~ 2 0 -150 110 U 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# Conn_01x02-Chiller_control-rescue
|
||||
#
|
||||
DEF Conn_01x02-Chiller_control-rescue J 0 40 Y N 1 F N
|
||||
F0 "J" 0 100 50 H V C CNN
|
||||
F1 "Conn_01x02-Chiller_control-rescue" 0 -200 50 H V C CNN
|
||||
F2 "" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
$FPLIST
|
||||
Connector*:*_??x*mm*
|
||||
Connector*:*1x??x*mm*
|
||||
Pin?Header?Straight?1X*
|
||||
Pin?Header?Angled?1X*
|
||||
Socket?Strip?Straight?1X*
|
||||
Socket?Strip?Angled?1X*
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
S -50 -95 0 -105 1 1 6 N
|
||||
S -50 5 0 -5 1 1 6 N
|
||||
S -50 50 50 -150 1 1 10 f
|
||||
X Pin_1 1 -200 0 150 R 50 50 1 1 P
|
||||
X Pin_2 2 -200 -100 150 R 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# D-Chiller_control-rescue
|
||||
#
|
||||
DEF D-Chiller_control-rescue D 0 40 N N 1 F N
|
||||
F0 "D" 0 100 50 H V C CNN
|
||||
F1 "D-Chiller_control-rescue" 0 -100 50 H V C CNN
|
||||
F2 "" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
$FPLIST
|
||||
TO-???*
|
||||
*SingleDiode
|
||||
*_Diode_*
|
||||
*SingleDiode*
|
||||
D_*
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
P 2 0 1 8 -50 50 -50 -50 N
|
||||
P 2 0 1 0 50 0 -50 0 N
|
||||
P 4 0 1 8 50 50 50 -50 -50 0 50 50 N
|
||||
X K 1 -150 0 100 R 50 50 1 1 P
|
||||
X A 2 150 0 100 L 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# G5LE-1-socket-rescue
|
||||
#
|
||||
DEF G5LE-1-socket-rescue K 0 40 Y Y 1 F N
|
||||
F0 "K" 450 150 50 H V L CNN
|
||||
F1 "G5LE-1-socket-rescue" 450 50 50 H V L CNN
|
||||
F2 "Relay_THT:Relay_SPDT_OMRON-G5LE-1" 450 -50 50 H I L CNN
|
||||
F3 "" 0 -400 50 H I C CNN
|
||||
$FPLIST
|
||||
Relay*SPDT*Omron*G5LE?1*
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
S -400 200 400 -200 0 1 10 f
|
||||
S -325 75 -75 -75 0 1 10 N
|
||||
P 2 0 0 0 100 150 100 200 N
|
||||
P 2 0 0 0 300 150 300 200 N
|
||||
P 4 0 0 0 300 150 300 100 275 125 300 150 N
|
||||
P 2 0 1 10 -300 -75 -100 75 N
|
||||
P 2 0 1 0 -200 -200 -200 -75 N
|
||||
P 2 0 1 0 -200 200 -200 75 N
|
||||
P 2 0 1 10 -75 0 -50 0 N
|
||||
P 2 0 1 10 -25 0 0 0 N
|
||||
P 2 0 1 10 25 0 50 0 N
|
||||
P 2 0 1 10 25 0 50 0 N
|
||||
P 2 0 1 10 75 0 100 0 N
|
||||
P 2 0 1 10 125 0 150 0 N
|
||||
P 2 0 1 20 200 -100 125 150 N
|
||||
P 2 0 1 0 200 -100 200 -200 N
|
||||
P 3 0 1 0 100 100 125 125 100 150 F
|
||||
X ~ 1 200 -300 100 U 50 50 1 1 P
|
||||
X ~ 2 -200 -300 100 U 50 50 1 1 P
|
||||
X ~ 3 300 300 100 D 50 50 1 1 P
|
||||
X ~ 4 100 300 100 D 50 50 1 1 P
|
||||
X ~ 5 -200 300 100 D 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# GND-Chiller_control-rescue
|
||||
#
|
||||
DEF GND-Chiller_control-rescue #PWR 0 0 Y Y 1 F P
|
||||
F0 "#PWR" 0 -250 50 H I C CNN
|
||||
F1 "GND-Chiller_control-rescue" 0 -150 50 H V C CNN
|
||||
F2 "" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
DRAW
|
||||
P 6 0 1 0 0 0 0 -50 50 -50 0 -100 -50 -50 0 -50 N
|
||||
X GND 1 0 0 0 D 50 50 1 1 W N
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# GND-socket-rescue
|
||||
#
|
||||
DEF GND-socket-rescue #PWR 0 0 Y Y 1 F P
|
||||
F0 "#PWR" 0 -250 50 H I C CNN
|
||||
F1 "GND-socket-rescue" 0 -150 50 H V C CNN
|
||||
F2 "" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
DRAW
|
||||
P 6 0 1 0 0 0 0 -50 50 -50 0 -100 -50 -50 0 -50 N
|
||||
X GND 1 0 0 0 D 50 50 1 1 W N
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# L-Chiller_control-rescue
|
||||
#
|
||||
DEF L-Chiller_control-rescue L 0 40 N N 1 F N
|
||||
F0 "L" -50 0 50 V V C CNN
|
||||
F1 "L-Chiller_control-rescue" 75 0 50 V V C CNN
|
||||
F2 "" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
$FPLIST
|
||||
Choke_*
|
||||
*Coil*
|
||||
Inductor_*
|
||||
L_*
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
A 0 -75 25 -899 899 0 1 0 N 0 -100 0 -50
|
||||
A 0 -25 25 -899 899 0 1 0 N 0 -50 0 0
|
||||
A 0 25 25 -899 899 0 1 0 N 0 0 0 50
|
||||
A 0 75 25 -899 899 0 1 0 N 0 50 0 100
|
||||
X 1 1 0 150 50 D 50 50 1 1 P
|
||||
X 2 2 0 -150 50 U 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# Q_NMOS_GSD-Chiller_control-rescue
|
||||
#
|
||||
DEF Q_NMOS_GSD-Chiller_control-rescue Q 0 0 Y N 1 F N
|
||||
F0 "Q" 200 50 50 H V L CNN
|
||||
F1 "Q_NMOS_GSD-Chiller_control-rescue" 200 -50 50 H V L CNN
|
||||
F2 "" 200 100 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
DRAW
|
||||
C 65 0 111 0 1 10 N
|
||||
C 100 -70 11 0 1 0 F
|
||||
C 100 70 11 0 1 0 F
|
||||
P 2 0 1 0 2 0 10 0 N
|
||||
P 2 0 1 0 30 -70 100 -70 N
|
||||
P 2 0 1 10 30 -50 30 -90 N
|
||||
P 2 0 1 0 30 0 100 0 N
|
||||
P 2 0 1 10 30 20 30 -20 N
|
||||
P 2 0 1 0 30 70 100 70 N
|
||||
P 2 0 1 10 30 90 30 50 N
|
||||
P 2 0 1 0 100 -70 100 -100 N
|
||||
P 2 0 1 0 100 -70 100 0 N
|
||||
P 2 0 1 0 100 100 100 70 N
|
||||
P 3 0 1 10 10 75 10 -75 10 -75 N
|
||||
P 4 0 1 0 40 0 80 15 80 -15 40 0 F
|
||||
P 4 0 1 0 100 -70 130 -70 130 70 100 70 N
|
||||
P 4 0 1 0 110 20 115 15 145 15 150 10 N
|
||||
P 4 0 1 0 130 15 115 -10 145 -10 130 15 N
|
||||
X G 1 -200 0 200 R 50 50 1 1 I
|
||||
X S 2 100 -200 100 U 50 50 1 1 P
|
||||
X D 3 100 200 100 D 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# Q_NMOS_GSD-socket-rescue
|
||||
#
|
||||
DEF Q_NMOS_GSD-socket-rescue Q 0 0 Y N 1 F N
|
||||
F0 "Q" 200 50 50 H V L CNN
|
||||
F1 "Q_NMOS_GSD-socket-rescue" 200 -50 50 H V L CNN
|
||||
F2 "" 200 100 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
DRAW
|
||||
C 65 0 111 0 1 10 N
|
||||
C 100 -70 11 0 1 0 F
|
||||
C 100 70 11 0 1 0 F
|
||||
P 2 0 1 0 2 0 10 0 N
|
||||
P 2 0 1 0 30 -70 100 -70 N
|
||||
P 2 0 1 10 30 -50 30 -90 N
|
||||
P 2 0 1 0 30 0 100 0 N
|
||||
P 2 0 1 10 30 20 30 -20 N
|
||||
P 2 0 1 0 30 70 100 70 N
|
||||
P 2 0 1 10 30 90 30 50 N
|
||||
P 2 0 1 0 100 -70 100 -100 N
|
||||
P 2 0 1 0 100 -70 100 0 N
|
||||
P 2 0 1 0 100 100 100 70 N
|
||||
P 3 0 1 10 10 75 10 -75 10 -75 N
|
||||
P 4 0 1 0 40 0 80 15 80 -15 40 0 F
|
||||
P 4 0 1 0 100 -70 130 -70 130 70 100 70 N
|
||||
P 4 0 1 0 110 20 115 15 145 15 150 10 N
|
||||
P 4 0 1 0 130 15 115 -10 145 -10 130 15 N
|
||||
X G 1 -200 0 200 R 50 50 1 1 I
|
||||
X S 2 100 -200 100 U 50 50 1 1 P
|
||||
X D 3 100 200 100 D 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# R-Chiller_control-rescue
|
||||
#
|
||||
DEF R-Chiller_control-rescue R 0 0 N Y 1 F N
|
||||
F0 "R" 80 0 50 V V C CNN
|
||||
F1 "R-Chiller_control-rescue" 0 0 50 V V C CNN
|
||||
F2 "" -70 0 50 V I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
$FPLIST
|
||||
R_*
|
||||
R_*
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
S -40 -100 40 100 0 1 10 N
|
||||
X ~ 1 0 150 50 D 50 50 1 1 P
|
||||
X ~ 2 0 -150 50 U 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# R-socket-rescue
|
||||
#
|
||||
DEF R-socket-rescue R 0 0 N Y 1 F N
|
||||
F0 "R" 80 0 50 V V C CNN
|
||||
F1 "R-socket-rescue" 0 0 50 V V C CNN
|
||||
F2 "" -70 0 50 V I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
$FPLIST
|
||||
R_*
|
||||
R_*
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
S -40 -100 40 100 0 1 10 N
|
||||
X ~ 1 0 150 50 D 50 50 1 1 P
|
||||
X ~ 2 0 -150 50 U 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
#End Library
|
||||
5951
F0:F030,F042,F072/Socket_fans/kicad/stm32.kicad_pcb
Normal file
1280
F0:F030,F042,F072/Socket_fans/kicad/stm32.net
Normal file
276
F0:F030,F042,F072/Socket_fans/kicad/stm32.pro
Normal file
@@ -0,0 +1,276 @@
|
||||
update=Пн 03 фев 2020 17:18:45
|
||||
version=1
|
||||
last_client=kicad
|
||||
[cvpcb]
|
||||
version=1
|
||||
NetIExt=net
|
||||
[general]
|
||||
version=1
|
||||
[eeschema]
|
||||
version=1
|
||||
LibDir=
|
||||
[schematic_editor]
|
||||
version=1
|
||||
PageLayoutDescrFile=
|
||||
PlotDirectoryName=
|
||||
SubpartIdSeparator=46
|
||||
SubpartFirstId=49
|
||||
NetFmtName=Pcbnew
|
||||
SpiceAjustPassiveValues=0
|
||||
LabSize=50
|
||||
ERC_TestSimilarLabels=1
|
||||
[pcbnew]
|
||||
version=1
|
||||
PageLayoutDescrFile=
|
||||
LastNetListRead=stm32.net
|
||||
CopperLayerCount=2
|
||||
BoardThickness=2.5
|
||||
AllowMicroVias=0
|
||||
AllowBlindVias=0
|
||||
RequireCourtyardDefinitions=0
|
||||
ProhibitOverlappingCourtyards=1
|
||||
MinTrackWidth=0.2
|
||||
MinViaDiameter=0.7999999999999999
|
||||
MinViaDrill=0.5
|
||||
MinMicroViaDiameter=0.2
|
||||
MinMicroViaDrill=0.09999999999999999
|
||||
MinHoleToHole=0.25
|
||||
TrackWidth1=0.2
|
||||
TrackWidth2=0.2
|
||||
TrackWidth3=0.3
|
||||
TrackWidth4=0.5
|
||||
TrackWidth5=1
|
||||
TrackWidth6=2
|
||||
ViaDiameter1=1
|
||||
ViaDrill1=0.6
|
||||
ViaDiameter2=1
|
||||
ViaDrill2=0.6
|
||||
ViaDiameter3=1.5
|
||||
ViaDrill3=0.8
|
||||
dPairWidth1=0.2
|
||||
dPairGap1=0.25
|
||||
dPairViaGap1=0.25
|
||||
SilkLineWidth=0.15
|
||||
SilkTextSizeV=1
|
||||
SilkTextSizeH=1
|
||||
SilkTextSizeThickness=0.15
|
||||
SilkTextItalic=0
|
||||
SilkTextUpright=1
|
||||
CopperLineWidth=0.2
|
||||
CopperTextSizeV=1.5
|
||||
CopperTextSizeH=1.5
|
||||
CopperTextThickness=0.3
|
||||
CopperTextItalic=0
|
||||
CopperTextUpright=1
|
||||
EdgeCutLineWidth=0.15
|
||||
CourtyardLineWidth=0.05
|
||||
OthersLineWidth=0.15
|
||||
OthersTextSizeV=1
|
||||
OthersTextSizeH=1
|
||||
OthersTextSizeThickness=0.15
|
||||
OthersTextItalic=0
|
||||
OthersTextUpright=1
|
||||
SolderMaskClearance=0.2
|
||||
SolderMaskMinWidth=0
|
||||
SolderPasteClearance=0
|
||||
SolderPasteRatio=-0
|
||||
[pcbnew/Layer.F.Cu]
|
||||
Name=F.Cu
|
||||
Type=0
|
||||
Enabled=1
|
||||
[pcbnew/Layer.In1.Cu]
|
||||
Name=In1.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In2.Cu]
|
||||
Name=In2.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In3.Cu]
|
||||
Name=In3.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In4.Cu]
|
||||
Name=In4.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In5.Cu]
|
||||
Name=In5.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In6.Cu]
|
||||
Name=In6.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In7.Cu]
|
||||
Name=In7.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In8.Cu]
|
||||
Name=In8.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In9.Cu]
|
||||
Name=In9.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In10.Cu]
|
||||
Name=In10.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In11.Cu]
|
||||
Name=In11.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In12.Cu]
|
||||
Name=In12.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In13.Cu]
|
||||
Name=In13.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In14.Cu]
|
||||
Name=In14.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In15.Cu]
|
||||
Name=In15.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In16.Cu]
|
||||
Name=In16.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In17.Cu]
|
||||
Name=In17.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In18.Cu]
|
||||
Name=In18.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In19.Cu]
|
||||
Name=In19.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In20.Cu]
|
||||
Name=In20.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In21.Cu]
|
||||
Name=In21.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In22.Cu]
|
||||
Name=In22.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In23.Cu]
|
||||
Name=In23.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In24.Cu]
|
||||
Name=In24.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In25.Cu]
|
||||
Name=In25.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In26.Cu]
|
||||
Name=In26.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In27.Cu]
|
||||
Name=In27.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In28.Cu]
|
||||
Name=In28.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In29.Cu]
|
||||
Name=In29.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In30.Cu]
|
||||
Name=In30.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.B.Cu]
|
||||
Name=B.Cu
|
||||
Type=0
|
||||
Enabled=1
|
||||
[pcbnew/Layer.B.Adhes]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.F.Adhes]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.B.Paste]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.F.Paste]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.B.SilkS]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.F.SilkS]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.B.Mask]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.F.Mask]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.Dwgs.User]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.Cmts.User]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.Eco1.User]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.Eco2.User]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.Edge.Cuts]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.Margin]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.B.CrtYd]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.F.CrtYd]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.B.Fab]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.F.Fab]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.Rescue]
|
||||
Enabled=0
|
||||
[pcbnew/Netclasses]
|
||||
[pcbnew/Netclasses/Default]
|
||||
Name=Default
|
||||
Clearance=0.2
|
||||
TrackWidth=0.2
|
||||
ViaDiameter=1
|
||||
ViaDrill=0.6
|
||||
uViaDiameter=0.3
|
||||
uViaDrill=0.1
|
||||
dPairWidth=0.2
|
||||
dPairGap=0.25
|
||||
dPairViaGap=0.25
|
||||
[pcbnew/Netclasses/1]
|
||||
Name=0.5
|
||||
Clearance=0.3
|
||||
TrackWidth=0.5
|
||||
ViaDiameter=1
|
||||
ViaDrill=0.6
|
||||
uViaDiameter=0.3
|
||||
uViaDrill=0.1
|
||||
dPairWidth=0.2
|
||||
dPairGap=0.25
|
||||
dPairViaGap=0.25
|
||||
[pcbnew/Netclasses/2]
|
||||
Name=1
|
||||
Clearance=0.5
|
||||
TrackWidth=1
|
||||
ViaDiameter=1.5
|
||||
ViaDrill=0.8
|
||||
uViaDiameter=0.3
|
||||
uViaDrill=0.1
|
||||
dPairWidth=0.2
|
||||
dPairGap=0.25
|
||||
dPairViaGap=0.25
|
||||
2044
F0:F030,F042,F072/Socket_fans/kicad/stm32.sch
Normal file
4
F0:F030,F042,F072/Socket_fans/kicad/sym-lib-table
Normal file
@@ -0,0 +1,4 @@
|
||||
(sym_lib_table
|
||||
(lib (name elements)(type Legacy)(uri ${KIPRJMOD}/elements.lib)(options "")(descr ""))
|
||||
(lib (name stm32-rescue)(type Legacy)(uri ${KIPRJMOD}/stm32-rescue.lib)(options "")(descr ""))
|
||||
)
|
||||
13
F0:F030,F042,F072/Socket_fans/knots/buildk.m
Normal file
@@ -0,0 +1,13 @@
|
||||
function [X0 Y0 K] = buildk(X, Y, dYmax)
|
||||
%
|
||||
% [X0 Y0 K] = buildk(X, Y, dYmax) - build arrays of knots (X0, Y0) and linear koefficients K
|
||||
% for piecewise-linear approximation of Y(X) with max deviation `dYmax`
|
||||
%
|
||||
X0 = []; Y0 = []; K = [];
|
||||
knots = [1 getknots(X, Y, dYmax) max(size(X))];
|
||||
for i = 1:max(size(knots))-1
|
||||
idx = knots(i):knots(i+1);
|
||||
[x y k] = linearapprox(X(idx), Y(idx));
|
||||
X0 = [X0 x]; Y0 = [Y0 y]; K = [K k];
|
||||
endfor
|
||||
endfunction
|
||||
29
F0:F030,F042,F072/Socket_fans/knots/calcT.m
Normal file
@@ -0,0 +1,29 @@
|
||||
function T = calcT(ADU)
|
||||
%
|
||||
% T = calcT(ADU) - piecewise calculation prototype
|
||||
%
|
||||
X0 = [732.44 944.75 1197.23 2034.68 2308.60 2541.55 2738.63 2859.45 2969.21 3067.67 3153.52 3228.22 3292.84 3347.15];
|
||||
Y0 = [10.000 16.000 22.700 43.750 50.800 57.100 62.800 66.550 70.200 73.750 77.150 80.450 83.700 86.900];
|
||||
K = [0.028261 0.026536 0.025136 0.025738 0.027044 0.028922 0.031038 0.033255 0.036056 0.039606 0.044173 0.050296 0.058920 0.071729];
|
||||
imax = max(size(X0)); idx = int32((imax+1)/2);
|
||||
T = [];
|
||||
% find index
|
||||
while(idx > 0 && idx <= imax)
|
||||
x = X0(idx);
|
||||
half = int32(idx/2);
|
||||
if(ADU < x)
|
||||
%printf("%g < %g\n", ADU, x);
|
||||
if(idx == 1) break; endif; % less than first index
|
||||
if(ADU > X0(idx-1)) idx -= 1; break; endif; % found
|
||||
idx = half; % another half
|
||||
else
|
||||
%printf("%g > %g\n", ADU, x);
|
||||
if(idx == imax) break; endif; % more than last index
|
||||
if(ADU < X0(idx+1)) break; endif; % found
|
||||
idx += half;
|
||||
endif
|
||||
endwhile
|
||||
if(idx < 1) printf("too low (<%g)!\n", X0(1)); idx = 1; endif
|
||||
if(idx > imax) idx = imax; endif;
|
||||
T = Y0(idx) + K(idx) * (ADU - X0(idx));
|
||||
endfunction
|
||||
13
F0:F030,F042,F072/Socket_fans/knots/getknots.m
Normal file
@@ -0,0 +1,13 @@
|
||||
function idx = getknots(X, Y, dYmax)
|
||||
%
|
||||
% idx = getknots(X, Y, dYmax) - calculate piecewise-linear approximation knots for Y(X)
|
||||
% dYmax - maximal deviation
|
||||
%
|
||||
idx = [];
|
||||
I = getnewpt(X, Y, dYmax);
|
||||
if(I > 0)
|
||||
L = getknots(X(1:I), Y(1:I), dYmax);
|
||||
R = I-1 + getknots(X(I:end), Y(I:end), dYmax);
|
||||
idx = [L I R];
|
||||
endif
|
||||
endfunction
|
||||
17
F0:F030,F042,F072/Socket_fans/knots/getnewpt.m
Normal file
@@ -0,0 +1,17 @@
|
||||
function idx = getnewpt(X, Y, delt)
|
||||
%
|
||||
% idx = getnewpt(X, Y, delt)
|
||||
% find point where Y-`linear approx` is maximal
|
||||
% return index of max deviation or -1 if it is less than `delt`
|
||||
%
|
||||
% make approximation
|
||||
[x0 y0 k] = linearapprox(X,Y);
|
||||
% find new knot
|
||||
adiff = abs(Y - (y0 + k*(X-x0)));
|
||||
maxadiff = max(adiff);
|
||||
if(maxadiff < delt)
|
||||
idx = -1;
|
||||
else
|
||||
idx = find(adiff == max(adiff));
|
||||
endif
|
||||
endfunction
|
||||
8
F0:F030,F042,F072/Socket_fans/knots/linearapprox.m
Normal file
@@ -0,0 +1,8 @@
|
||||
function [x0 y0 k] = linearapprox(X,Y)
|
||||
%
|
||||
% [a b] = linearapprox(X,Y) - find linear approximation of function Y(X) through first and last points
|
||||
% y = y0 + k*(X-x0)
|
||||
%
|
||||
x0 = X(1); y0 = Y(1);
|
||||
k = (Y(end) - y0) / (X(end) - x0);
|
||||
endfunction
|
||||
1364
F0:F030,F042,F072/Socket_fans/knots/piecevise.html
Normal file
BIN
F0:F030,F042,F072/Socket_fans/knots/piecevise_files/13303023.jpe
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
F0:F030,F042,F072/Socket_fans/knots/piecevise_files/43568408.jpe
Normal file
|
After Width: | Height: | Size: 6.8 KiB |
BIN
F0:F030,F042,F072/Socket_fans/knots/piecevise_files/50295594.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
F0:F030,F042,F072/Socket_fans/knots/piecevise_files/52273253.jpe
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
F0:F030,F042,F072/Socket_fans/knots/piecevise_files/62383590.gif
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 44 KiB |
10
F0:F030,F042,F072/Socket_fans/knots/piecevise_files/a.css
Normal file
@@ -0,0 +1,8 @@
|
||||
<html><head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="a_data/a.js" async="false"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
</body></html>
|
||||
753
F0:F030,F042,F072/Socket_fans/knots/piecevise_files/a.js
Normal file
|
After Width: | Height: | Size: 37 KiB |
115
F0:F030,F042,F072/Socket_fans/knots/piecevise_files/a_002.css
Normal file
678
F0:F030,F042,F072/Socket_fans/knots/piecevise_files/a_002.js
Normal file
@@ -0,0 +1,5 @@
|
||||
/* >>> file start: js/crossStorageServ.js */
|
||||
var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};!function(){function e(e){var t="LJ.CrossStorage"===e.data.source;if(!t)return null;var n=e.data;if("object"===("undefined"==typeof n?"undefined":_typeof(n))&&n.fn&&("getItem"===n.fn&&o.parent.postMessage({crossStorageServResponse:localStorage.getItem(n.args[0]),requestID:n.requestID},"*"),"setItem"===n.fn)){var r=n.args[1],f="";"string"==typeof r?f=r:"object"===("undefined"==typeof r?"undefined":_typeof(r))&&(f=JSON.stringify(r)),localStorage.setItem(n.args[0],f)}}function t(){try{return window.self!==window.top}catch(e){return!0}}if(!t())return null;var o=window;"object"===("undefined"==typeof LJMocks?"undefined":_typeof(LJMocks))&&LJMocks.window&&(o=LJMocks.window),o.addEventListener("message",e)}();
|
||||
/* <<< file end: js/crossStorageServ.js */
|
||||
|
||||
//# map link was there [crossStorageServ.js.map]
|
||||
BIN
F0:F030,F042,F072/Socket_fans/knots/piecevise_files/btn_del.gif
Normal file
|
After Width: | Height: | Size: 655 B |
BIN
F0:F030,F042,F072/Socket_fans/knots/piecevise_files/btn_edit.gif
Normal file
|
After Width: | Height: | Size: 632 B |
|
After Width: | Height: | Size: 612 B |
|
After Width: | Height: | Size: 664 B |
|
After Width: | Height: | Size: 820 B |
BIN
F0:F030,F042,F072/Socket_fans/knots/piecevise_files/btn_next.gif
Normal file
|
After Width: | Height: | Size: 613 B |
BIN
F0:F030,F042,F072/Socket_fans/knots/piecevise_files/btn_prev.gif
Normal file
|
After Width: | Height: | Size: 628 B |
BIN
F0:F030,F042,F072/Socket_fans/knots/piecevise_files/btn_scr.gif
Normal file
|
After Width: | Height: | Size: 640 B |
|
After Width: | Height: | Size: 1.2 KiB |
BIN
F0:F030,F042,F072/Socket_fans/knots/piecevise_files/btn_spam.gif
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 607 B |
|
After Width: | Height: | Size: 355 B |
101
F0:F030,F042,F072/Socket_fans/knots/piecevise_files/top100.js
Normal file
@@ -0,0 +1,101 @@
|
||||
(function(){var f,h=h||{},k=this;function n(a){return void 0!==a}function p(){}function aa(a){a.B=function(){return a.vb?a.vb:a.vb=new a}}
|
||||
function ba(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("call"))return"function"}else return"null";
|
||||
else if("function"==b&&"undefined"==typeof a.call)return"object";return b}function q(a){return"array"==ba(a)}function ca(a){var b=ba(a);return"array"==b||"object"==b&&"number"==typeof a.length}function t(a){return"string"==typeof a}function u(a){return"function"==ba(a)}var da="closure_uid_"+(1E9*Math.random()>>>0),ea=0;function fa(a,b,c){return a.call.apply(a.bind,arguments)}
|
||||
function ga(a,b,c){if(!a)throw Error();if(2<arguments.length){var d=Array.prototype.slice.call(arguments,2);return function(){var c=Array.prototype.slice.call(arguments);Array.prototype.unshift.apply(c,d);return a.apply(b,c)}}return function(){return a.apply(b,arguments)}}function v(a,b,c){v=Function.prototype.bind&&-1!=Function.prototype.bind.toString().indexOf("native code")?fa:ga;return v.apply(null,arguments)}var w=Date.now||function(){return+new Date};
|
||||
function x(a,b){function c(){}c.prototype=b.prototype;a.yc=b.prototype;a.prototype=new c;a.prototype.constructor=a;a.Lc=function(a,c,g){for(var l=Array(arguments.length-2),m=2;m<arguments.length;m++)l[m-2]=arguments[m];return b.prototype[c].apply(a,l)}};var ha={};function ia(){}ia.prototype.send=function(a,b,c){k.navigator.sendBeacon(a,b)?c.eb():c.error()};function ja(){this.b=this.a=void 0}ja.prototype.send=function(a,b){this.a=new Image;this.a.onload=v(this.f,this,b.eb);this.a.onerror=v(this.c,this,b.error);this.a.onabort=v(this.c,this,b.error);this.a.src=a;this.b=k.setTimeout(v(this.c,this,b.error),ka)};function la(a){a.b&&(k.clearTimeout(a.b),a.b=null)}function ma(a){a.a.src="";a.a.onload=function(){};a.a.onabort=function(){};a.a.onerror=function(){}}ja.prototype.f=function(a){la(this);a()};ja.prototype.c=function(a){ma(this);la(this);a()};y.a={};y.a.Nc=/iPad|iPhone|iPod/.test(k.navigator.userAgent)&&!k.Ic;y.a.i={};y.a.i.Bb=!1;y.a.i.Jb="Silverlight Plug-In";y.a.i.qa="application/x-silverlight";y.a.i.Ib=[y.a.i.qa,y.a.i.qa+"-2",y.a.i.qa+"-2-b2",y.a.i.qa+"-2-b1"];y.a.i.Db="AgControl.AgControl";y.a.i.oa=!1;y.a.i.va="";
|
||||
y.a.i.tc=function(){var a=k.navigator;if(a.plugins&&a.plugins.length){var b=a.plugins[y.a.i.Jb];b&&(y.a.i.oa=!0,b.description&&(y.a.i.va=y.a.i.Xa(b.description)))}else if(a.mimeTypes&&a.mimeTypes.length)for(var c=y.a.i.Ib,b=0;b<c.length;b++){var d=a.mimeTypes[c[b]];if(d&&d.enabledPlugin){y.a.i.oa=!!d.enabledPlugin;y.a.i.oa&&(y.a.i.va=y.a.i.Xa(d.enabledPlugin.description));break}}else{a=[0,0,0,0];try{c=new ActiveXObject(y.a.i.Db);y.a.i.oa=!0;for(b=0;b<a.length;b++){for(var e=0,g=1048575,l=0;e<g;)d=
|
||||
a[b]=e+(g-e>>1),c.IsVersionSupported(a.join("."))?(l=d,e=d+1):g=d;a[b]=l}y.a.i.va=y.a.i.Xa(a.join("."))}catch(m){}}};y.a.i.Xa=function(a){return"1.0.30226.2"===a?"2.0.30226.2":a};y.a.i.Bb||y.a.i.tc();y.a.i.Cc=y.a.i.oa;y.a.i.VERSION=y.a.i.va;y.u={};
|
||||
y.u.zc=function(a){var b=typeof a;if("object"===b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"===c)return"object";if("[object Array]"===c||"number"===typeof a.length&&"undefined"!==typeof a.splice&&"undefined"!==typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"===c||"undefined"!==typeof a.call&&"undefined"!==typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("call"))return"function"}else return"null";else if("function"===
|
||||
b&&"undefined"===typeof a.call)return"object";return b};y.u.uc=function(a){var b=typeof a;return"object"==b&&null!=a||"function"==b};y.u.isArray=function(a){return"array"===y.u.zc(a)};y.W={};y.W.wc=function(){console.warn("\u0412\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 syncUserId.\n\u041e\u0431 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u044d\u0442\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u043f\u043e\u0447\u0438\u0442\u0430\u0439\u0442\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 http://top100.rambler.ru/doc/guide-rambler-top100.pdf")};
|
||||
y.W.log=function(){if(k.console){var a=new Date;console.log([a.getHours(),a.getMinutes(),a.getSeconds(),a.getMilliseconds()].join(":")+"\t",Array.prototype.slice.call(arguments).join(" "))}};y.G={};y.G.Vb=function(a){if("function"===typeof k.CustomEvent)return new k.CustomEvent(a);var b=document.createEvent("CustomEvent");b.initCustomEvent(a,!0,!0,!0);return b};y.G.oc=function(a){try{var b=y.G.Vb(a);b&&document.dispatchEvent(b)}catch(c){console.error("Event initKraken unsupported!")}};var na=!1;function z(){var a=void 0;na?a={$:!0,vc:!0}:a=!0;return a}try{var qa=Object.defineProperty&&Object.defineProperty({},"passive",{get:function(){na=!0}});k.addEventListener&&k.addEventListener("testPassiveEvents",null,qa)}catch(a){console.error(a)};y.H={};y.H.fb=function(a,b){function c(){e=k.setTimeout(d,1E3);a.apply(null,l)}function d(){e=null;g&&(g=!1,c())}b&&(a=v(a,b));var e=null,g=!1,l=[];return function(a){l=arguments;e?g=!0:c()}};y.g={};y.g.Ba=function(){return Math.round(2147483647*Math.random())};y.g.trunc=function(a,b){var c=b||1;return(a/c>>0)*c};y.g.wb=function(a){return"number"==typeof a&&!k.isNaN(a)&&k.isFinite(a)};y.g.Aa=function(a){return y.g.wb(a)&&0<a};function ra(a,b){this.b=a;this.a=b}ra.prototype.toString=function(){return this.b+"x"+this.a};function sa(a,b){this.c=a;this.f=b||ta;this.b=!1;this.a=void 0}var ta=1E3;sa.prototype.start=function(){this.b=!0;this.a||ua(this)};sa.prototype.g=function(){this.b&&(this.a&&va(this),this.c(),this.b&&ua(this))};function ua(a){a.a=k.setTimeout(v(a.g,a),a.f)}function va(a){a.a&&(k.clearTimeout(a.a),a.a=null)};y.Gc={};function wa(a,b){this.a=a;this.I=b};function A(){this.c=this.b=0;this.a=[]}A.prototype.enqueue=function(a){return this.a[this.c++]=a};A.prototype.na=function(){return this.D()?null:this.a[this.b++]};A.prototype.M=function(){return this.a[this.b]};A.prototype.D=function(){return this.b>=this.c};y.c={};y.c.ta="top100_id";y.c.$b=864E5;y.c.I="";y.c.Oa=function(a){for(var b=1,c=0,d=0;d<a.length;d++)c=a.charCodeAt(d),b=(b<<7&4294967295)+(c<<16)+c,c=b&4278190080,0!==c&&(b=b^c>>24);return b};y.c.Xb=function(){return"."+k.document.location.hostname.split(".").reverse().splice(0,2).reverse().join(".")};y.c.Wb=function(a){var b=k.navigator.userAgent+h.cookie+h.referrer+h.innerWidth+h.innerHeight+Math.random().toString(36).substr(2,9);return["t1",a,y.c.Oa(b),+new Date].join(".")};
|
||||
y.c.pb=function(a,b){var c=b||y.c.Wb(a);B.set(y.c.ta,c,y.c.$b,"/",y.c.Xb());y.c.I=c};y.c.ub=function(){return!!y.c.I};y.c.xa=function(a){var b=B.get(y.c.ta);b||y.c.ub()?b&&!y.c.ub()&&y.c.pb(a,b):y.c.pb(a);return y.c.I};y.j={};y.j.Lb=0;y.j.Ma="kraken_uid_property_"+y.g.Ba();y.j.sc=function(a){return!!a[y.j.Ma]};y.j.qc=function(a){y.j.sc(a)||(a[y.j.Ma]=++y.j.Lb);return a[y.j.Ma]};y.l={};y.l.xc=function(a){for(var b=[],c={},d=0;d<a.length;){var e=a[d++],g;g=e;var l=void 0;g=l=y.u.uc(g)?"o"+y.j.qc(g):(typeof g).charAt(0)+g;c[g]||(c[g]=!0,b.push(e))}return b};y.l.map=function(a,b,c){if(Array.prototype.map)return Array.prototype.map.call(a,b,c);for(var d=[],e=a.length,g=0;g<e;++g)d[g]=b.call(c,a[g],g,a);return d};y.l.includes=function(a,b,c){var d=a.length;for(c=c||0;c<d;++c)if(a[c]===b)return!0;return!1};y.h={};y.h.ta="_ym_uid";y.h.I="";y.h.mc=function(a){y.h.I=a};y.h.Yb=function(){return y.h.I};y.h.rc=function(){var a=B.get(y.h.ta);a&&y.h.mc(a);return y.h.Yb()};function xa(a,b,c){this.f=c;this.c=a;this.g=b;this.b=0;this.a=null}xa.prototype.get=function(){var a;0<this.b?(this.b--,a=this.a,this.a=a.next,a.next=null):a=this.c();return a};function ya(a,b){a.g(b);a.b<a.f&&(a.b++,b.next=a.a,a.a=b)};function C(a){if(Error.captureStackTrace)Error.captureStackTrace(this,C);else{var b=Error().stack;b&&(this.stack=b)}a&&(this.message=String(a))}x(C,Error);C.prototype.name="CustomError";function za(a,b,c,d,e){this.reset(a,b,c,d,e)}za.prototype.a=null;var Aa=0;za.prototype.reset=function(a,b,c,d,e){"number"==typeof e||Aa++;d||w();this.b=b;delete this.a};function Ba(){0!=Ca&&(this[da]||(this[da]=++ea));this.H=this.H;this.Ia=this.Ia}var Ca=0;Ba.prototype.H=!1;function Da(a,b){this.type=a;this.a=this.target=b}Da.prototype.c=function(){};var Ea="closure_listenable_"+(1E6*Math.random()|0),Fa=0;function Ga(a,b,c,d,e){this.listener=a;this.a=null;this.src=b;this.type=c;this.$=!!d;this.za=e;++Fa;this.da=this.ua=!1}function Ha(a){a.da=!0;a.listener=null;a.a=null;a.src=null;a.za=null};var Ia;function Ja(a){var b=[];Ka(new La,a,b);return b.join("")}function La(){}
|
||||
function Ka(a,b,c){if(null==b)c.push("null");else{if("object"==typeof b){if(q(b)){var d=b;b=d.length;c.push("[");for(var e="",g=0;g<b;g++)c.push(e),Ka(a,d[g],c),e=",";c.push("]");return}if(b instanceof String||b instanceof Number||b instanceof Boolean)b=b.valueOf();else{c.push("{");e="";for(d in b)Object.prototype.hasOwnProperty.call(b,d)&&(g=b[d],"function"!=typeof g&&(c.push(e),Ma(d,c),c.push(":"),Ka(a,g,c),e=","));c.push("}");return}}switch(typeof b){case "string":Ma(b,c);break;case "number":c.push(isFinite(b)&&
|
||||
!isNaN(b)?String(b):"null");break;case "boolean":c.push(String(b));break;case "function":c.push("null");break;default:throw Error("Unknown type: "+typeof b);}}}var Na={'"':'\\"',"\\":"\\\\","/":"\\/","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\x0B":"\\u000b"},Oa=/\uffff/.test("\uffff")?/[\\\"\x00-\x1f\x7f-\uffff]/g:/[\\\"\x00-\x1f\x7f-\xff]/g;
|
||||
function Ma(a,b){b.push('"',a.replace(Oa,function(a){var b=Na[a];b||(b="\\u"+(a.charCodeAt(0)|65536).toString(16).substr(1),Na[a]=b);return b}),'"')};function Pa(a,b){for(var c in a)b.call(void 0,a[c],c,a)}function Qa(a){var b=[],c=0,d;for(d in a)b[c++]=a[d];return b}function Ra(a){var b=[],c=0,d;for(d in a)b[c++]=d;return b}function Sa(a){return null!==a&&"withCredentials"in a}var Ta="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" ");
|
||||
function Ua(a,b){for(var c,d,e=1;e<arguments.length;e++){d=arguments[e];for(c in d)a[c]=d[c];for(var g=0;g<Ta.length;g++)c=Ta[g],Object.prototype.hasOwnProperty.call(d,c)&&(a[c]=d[c])}};function Va(a,b){this.b=a;this.a=b}f=Va.prototype;f.clone=function(){return new Va(this.b,this.a)};f.toString=function(){return"("+this.b+" x "+this.a+")"};f.nc=function(){return this.b*this.a};f.D=function(){return!this.nc()};f.ceil=function(){this.b=Math.ceil(this.b);this.a=Math.ceil(this.a);return this};f.floor=function(){this.b=Math.floor(this.b);this.a=Math.floor(this.a);return this};f.round=function(){this.b=Math.round(this.b);this.a=Math.round(this.a);return this};function Wa(a){a.prototype.then=a.prototype.then;a.prototype.$goog_Thenable=!0}function Xa(a){if(!a)return!1;try{return!!a.$goog_Thenable}catch(b){return!1}};function Ya(a){this.a=a}var Za=/\s*;\s*/;f=Ya.prototype;f.set=function(a,b,c,d,e,g){if(/[;=\s]/.test(a))throw Error('Invalid cookie name "'+a+'"');if(/[;\r\n]/.test(b))throw Error('Invalid cookie value "'+b+'"');n(c)||(c=-1);e=e?";domain="+e:"";d=d?";path="+d:"";g=g?";secure":"";c=0>c?"":0==c?";expires="+(new Date(1970,1,1)).toUTCString():";expires="+(new Date(w()+1E3*c)).toUTCString();this.a.cookie=a+"="+b+e+d+c+g};
|
||||
f.get=function(a,b){for(var c=a+"=",d=(this.a.cookie||"").split(Za),e=0,g;g=d[e];e++){if(0==g.lastIndexOf(c,0))return g.substr(c.length);if(g==a)return""}return b};f.remove=function(a,b,c){var d=n(this.get(a));this.set(a,"",0,b,c);return d};f.R=function(){return $a(this).keys};f.S=function(){return $a(this).values};f.D=function(){return!this.a.cookie};f.clear=function(){for(var a=$a(this).keys,b=a.length-1;0<=b;b--)this.remove(a[b])};
|
||||
function $a(a){a=(a.a.cookie||"").split(Za);for(var b=[],c=[],d,e,g=0;e=a[g];g++)d=e.indexOf("="),-1==d?(b.push(""),c.push(e)):(b.push(e.substring(0,d)),c.push(e.substring(d+1)));return{keys:b,values:c}}var B=new Ya(document);B.b=3950;function ab(){}ab.prototype.a=null;function bb(a){var b;(b=a.a)||(b={},cb(a)&&(b[0]=!0,b[1]=!0),b=a.a=b);return b};function db(a){db[" "](a);return a}db[" "]=p;function eb(a,b){for(var c=a.split("%s"),d="",e=Array.prototype.slice.call(arguments,1);e.length&&1<c.length;)d+=c.shift()+e.shift();return d+c.join("%s")}var fb=String.prototype.trim?function(a){return a.trim()}:function(a){return a.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")};function gb(a,b){return a<b?-1:a>b?1:0};function D(a){this.b=[];this.f=[];this.a={};this.h=this.c=0;this.g=a||!1}f=D.prototype;f.D=function(){return 0===this.c&&0===this.h};f.clone=function(){for(var a=new D(this.g),b=this.f.concat(),c=this.b.concat(),d=0,e=b.length;d<e;++d)a.K(b[d],this.a[b[d]]);d=0;for(e=c.length;d<e;++d)a.set(c[d],this.a[c[d]]);return a};f.get=function(a,b){a=hb(this,a);return Object.prototype.hasOwnProperty.call(this.a,a)?this.a[a]:b};
|
||||
f.set=function(a,b){a=hb(this,a);Object.prototype.hasOwnProperty.call(this.a,a)||(this.c++,this.b.push(a));this.a[a]=b};f.remove=function(a){a=hb(this,a);if(Object.prototype.hasOwnProperty.call(this.a,a)){delete this.a[a];for(var b=[],c=0,d=this.b.length;c<d;++c)this.b[c]!==a&&b.push(this.b[c]);this.b=b;this.c=b.length}};f.K=function(a,b){a=hb(this,a);Object.prototype.hasOwnProperty.call(this.a,a)||(this.h++,this.f.push(a));this.a[a]=b};
|
||||
f.toString=function(){if(this.D())return"";for(var a=[],b=this.f.concat().concat(this.b.concat()),c=void 0,d=void 0,c="",e=0,g=b.length;e<g;++e)c=b[e],d=this.get(c),c=encodeURIComponent(String(c)),""!==d&&(c+="="+encodeURIComponent(String(d))),a.push(c);return a.join("&")};function hb(a,b){var c=String(b);a.g&&(c=c.toLowerCase());return c}var E=D.prototype;E.set=E.set;E.get=E.get;E.setMeta=E.K;E.remove=E.remove;E.isEmpty=E.D;E.toString=E.toString;y.ia={};y.ia.Va=function(){var a=new D;a.K("et","uid");return a};y.ga={};y.ga.zb=function(a){var b=new D,c;for(c in a)a.hasOwnProperty(c)&&b.set(c,a[c]);return b};y.ha={};y.ha.Va=function(a){var b=new D;a=y.ga.zb(a);b.K("et","cv");b.set("cv",a.toString());return b};function ib(a,b){b.unshift(a);C.call(this,eb.apply(null,b));b.shift()}x(ib,C);ib.prototype.name="AssertionError";function jb(a,b){throw new ib("Failure"+(a?": "+a:""),Array.prototype.slice.call(arguments,1));};var F=Array.prototype.indexOf?function(a,b,c){return Array.prototype.indexOf.call(a,b,c)}:function(a,b,c){c=null==c?0:0>c?Math.max(0,a.length+c):c;if(t(a))return t(b)&&1==b.length?a.indexOf(b,c):-1;for(;c<a.length;c++)if(c in a&&a[c]===b)return c;return-1},kb=Array.prototype.forEach?function(a,b,c){Array.prototype.forEach.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=t(a)?a.split(""):a,g=0;g<d;g++)g in e&&b.call(c,e[g],g,a)},lb=Array.prototype.filter?function(a,b,c){return Array.prototype.filter.call(a,
|
||||
b,c)}:function(a,b,c){for(var d=a.length,e=[],g=0,l=t(a)?a.split(""):a,m=0;m<d;m++)if(m in l){var r=l[m];b.call(c,r,m,a)&&(e[g++]=r)}return e},mb=Array.prototype.some?function(a,b,c){return Array.prototype.some.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=t(a)?a.split(""):a,g=0;g<d;g++)if(g in e&&b.call(c,e[g],g,a))return!0;return!1};
|
||||
function nb(a,b){var c;a:{c=a.length;for(var d=t(a)?a.split(""):a,e=0;e<c;e++)if(e in d&&b.call(void 0,d[e],e,a)){c=e;break a}c=-1}return 0>c?null:t(a)?a.charAt(c):a[c]}function ob(a,b){var c=F(a,b),d;(d=0<=c)&&Array.prototype.splice.call(a,c,1);return d}function pb(a){return Array.prototype.concat.apply(Array.prototype,arguments)}function qb(a){for(var b=[],c=0;c<a;c++)b[c]=0;return b};function rb(){this.a=[]}rb.prototype.remove=function(){var a=this.a,b=a.length,c=a[0];if(0!==b){if(1===b){if(!q(a))for(b=a.length-1;0<=b;b--)delete a[b];a.length=0}else{a[0]=a.pop();for(var a=0,b=this.a,d=b.length,e=void 0,g=void 0,e=void 0,l=b[a];a<d>>1;){e=2*a+1;g=2*a+2;e=g<d&&b[g].a<b[e].a?g:e;if(b[e].a>l.a)break;b[a]=b[e];a=e}b[a]=l}return c.I}};rb.prototype.M=function(){return 0===this.a.length?void 0:this.a[0].I};rb.prototype.D=function(){return 0==this.a.length};function sb(){this.a=new rb}sb.prototype.enqueue=function(a,b){var c=this.a;c.a.push(new wa(a,b));for(var d=c.a.length-1,c=c.a,e=c[d],g=void 0;0<d;)if(g=d-1>>1,c[g].a>e.a)c[d]=c[g],d=g;else break;c[d]=e};sb.prototype.na=function(){return this.a.remove()};sb.prototype.M=function(){return this.a.M()};sb.prototype.D=function(){return this.a.D()};function tb(){this.b=this.a=null}var vb=new xa(function(){return new ub},function(a){a.reset()},100);tb.prototype.remove=function(){var a=null;this.a&&(a=this.a,this.a=this.a.next,this.a||(this.b=null),a.next=null);return a};function ub(){this.next=this.b=this.a=null}ub.prototype.set=function(a,b){this.a=a;this.b=b;this.next=null};ub.prototype.reset=function(){this.next=this.b=this.a=null};function wb(a){this.src=a;this.A={};this.a=0}function xb(a,b,c,d,e){var g=b.toString();b=a.A[g];b||(b=a.A[g]=[],a.a++);var l=yb(b,c,d,e);-1<l?(a=b[l],a.ua=!1):(a=new Ga(c,a.src,g,!!d,e),a.ua=!1,b.push(a));return a}wb.prototype.remove=function(a,b,c,d){a=a.toString();if(!(a in this.A))return!1;var e=this.A[a];b=yb(e,b,c,d);return-1<b?(Ha(e[b]),Array.prototype.splice.call(e,b,1),0==e.length&&(delete this.A[a],this.a--),!0):!1};
|
||||
function zb(a,b){var c=b.type;c in a.A&&ob(a.A[c],b)&&(Ha(b),0==a.A[c].length&&(delete a.A[c],a.a--))}function yb(a,b,c,d){for(var e=0;e<a.length;++e){var g=a[e];if(!g.da&&g.listener==b&&g.$==!!c&&g.za==d)return e}return-1};function Ab(a,b){this.a=n(a)?a:0;this.J=n(b)?b:0}f=Ab.prototype;f.clone=function(){return new Ab(this.a,this.J)};f.toString=function(){return"("+this.a+", "+this.J+")"};f.ceil=function(){this.a=Math.ceil(this.a);this.J=Math.ceil(this.J);return this};f.floor=function(){this.a=Math.floor(this.a);this.J=Math.floor(this.J);return this};f.round=function(){this.a=Math.round(this.a);this.J=Math.round(this.J);return this};var Bb;function Cb(){}x(Cb,ab);function Db(a){return(a=cb(a))?new ActiveXObject(a):new XMLHttpRequest}function cb(a){if(!a.b&&"undefined"==typeof XMLHttpRequest&&"undefined"!=typeof ActiveXObject){for(var b=["MSXML2.XMLHTTP.6.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP"],c=0;c<b.length;c++){var d=b[c];try{return new ActiveXObject(d),a.b=d}catch(e){}}throw Error("Could not create ActiveXObject. ActiveX might be disabled, or MSXML might not be installed");}return a.b}Bb=new Cb;function Eb(a,b){this.b={};this.a=[];this.c=0;var c=arguments.length;if(1<c){if(c%2)throw Error("Uneven number of arguments");for(var d=0;d<c;d+=2)this.set(arguments[d],arguments[d+1])}else if(a){a instanceof Eb?(c=a.R(),d=a.S()):(c=Ra(a),d=Qa(a));for(var e=0;e<c.length;e++)this.set(c[e],d[e])}}f=Eb.prototype;f.S=function(){Fb(this);for(var a=[],b=0;b<this.a.length;b++)a.push(this.b[this.a[b]]);return a};f.R=function(){Fb(this);return this.a.concat()};f.D=function(){return 0==this.c};
|
||||
f.clear=function(){this.b={};this.c=this.a.length=0};f.remove=function(a){return Object.prototype.hasOwnProperty.call(this.b,a)?(delete this.b[a],this.c--,this.a.length>2*this.c&&Fb(this),!0):!1};function Fb(a){if(a.c!=a.a.length){for(var b=0,c=0;b<a.a.length;){var d=a.a[b];Object.prototype.hasOwnProperty.call(a.b,d)&&(a.a[c++]=d);b++}a.a.length=c}if(a.c!=a.a.length){for(var e={},c=b=0;b<a.a.length;)d=a.a[b],Object.prototype.hasOwnProperty.call(e,d)||(a.a[c++]=d,e[d]=1),b++;a.a.length=c}}
|
||||
f.get=function(a,b){return Object.prototype.hasOwnProperty.call(this.b,a)?this.b[a]:b};f.set=function(a,b){Object.prototype.hasOwnProperty.call(this.b,a)||(this.c++,this.a.push(a));this.b[a]=b};f.forEach=function(a,b){for(var c=this.R(),d=0;d<c.length;d++){var e=c[d],g=this.get(e);a.call(b,g,e,this)}};f.clone=function(){return new Eb(this)};function Gb(a){if(a.S&&"function"==typeof a.S)return a.S();if(t(a))return a.split("");if(ca(a)){for(var b=[],c=a.length,d=0;d<c;d++)b.push(a[d]);return b}return Qa(a)}
|
||||
function Hb(a,b){if(a.forEach&&"function"==typeof a.forEach)a.forEach(b,void 0);else if(ca(a)||t(a))kb(a,b,void 0);else{var c;if(a.R&&"function"==typeof a.R)c=a.R();else if(a.S&&"function"==typeof a.S)c=void 0;else if(ca(a)||t(a)){c=[];for(var d=a.length,e=0;e<d;e++)c.push(e)}else c=Ra(a);for(var d=Gb(a),e=d.length,g=0;g<e;g++)b.call(void 0,d[g],c&&c[g],a)}};var Ib=/^(?:([^:/?#.]+):)?(?:\/\/(?:([^/?#]*)@)?([^/#?]*?)(?::([0-9]+))?(?=[/#?]|$))?([^?#]+)?(?:\?([^#]*))?(?:#(.*))?$/;var Jb=!1,G="";function Kb(a){a=a.match(/[\d]+/g);if(!a)return"";a.length=3;return a.join(".")}
|
||||
(function(){if(navigator.plugins&&navigator.plugins.length){var a=navigator.plugins["Shockwave Flash"];if(a&&(Jb=!0,a.description)){G=Kb(a.description);return}if(navigator.plugins["Shockwave Flash 2.0"]){Jb=!0;G="2.0.0.11";return}}if(navigator.mimeTypes&&navigator.mimeTypes.length&&(a=navigator.mimeTypes["application/x-shockwave-flash"],Jb=!!a&&a.enabledPlugin)){G=Kb(a.enabledPlugin.description);return}try{var b=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");Jb=!0;G=Kb(b.GetVariable("$version"));
|
||||
return}catch(c){}try{b=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");Jb=!0;G="6.0.21";return}catch(c){}try{b=new ActiveXObject("ShockwaveFlash.ShockwaveFlash"),Jb=!0,G=Kb(b.GetVariable("$version"))}catch(c){}})();var Lb=G;var Mb;a:{var Nb=k.navigator;if(Nb){var Ob=Nb.userAgent;if(Ob){Mb=Ob;break a}}Mb=""}function H(a){return-1!=Mb.indexOf(a)};function Pb(a){k.setTimeout(function(){throw a;},0)}var Qb;
|
||||
function Rb(){var a=k.MessageChannel;"undefined"===typeof a&&"undefined"!==typeof window&&window.postMessage&&window.addEventListener&&!H("Presto")&&(a=function(){var a=document.createElement("IFRAME");a.style.display="none";a.src="";document.documentElement.appendChild(a);var b=a.contentWindow,a=b.document;a.open();a.write("");a.close();var c="callImmediate"+Math.random(),d="file:"==b.location.protocol?"*":b.location.protocol+"//"+b.location.host,a=v(function(a){if(("*"==d||a.origin==d)&&a.data==
|
||||
c)this.port1.onmessage()},this);b.addEventListener("message",a,!1);this.port1={};this.port2={postMessage:function(){b.postMessage(c,d)}}});if("undefined"!==typeof a&&!H("Trident")&&!H("MSIE")){var b=new a,c={},d=c;b.port1.onmessage=function(){if(n(c.next)){c=c.next;var a=c.qb;c.qb=null;a()}};return function(a){d.next={qb:a};d=d.next;b.port2.postMessage(0)}}return"undefined"!==typeof document&&"onreadystatechange"in document.createElement("SCRIPT")?function(a){var b=document.createElement("SCRIPT");
|
||||
b.onreadystatechange=function(){b.onreadystatechange=null;b.parentNode.removeChild(b);b=null;a();a=null};document.documentElement.appendChild(b)}:function(a){k.setTimeout(a,0)}};function Sb(a,b){Tb||Ub();Vb||(Tb(),Vb=!0);var c=Wb,d=vb.get();d.set(a,b);c.b?c.b.next=d:c.a=d;c.b=d}var Tb;function Ub(){if(k.Promise&&k.Promise.resolve){var a=k.Promise.resolve(void 0);Tb=function(){a.then(Xb)}}else Tb=function(){var a=Xb;!u(k.setImmediate)||k.Window&&k.Window.prototype&&!H("Edge")&&k.Window.prototype.setImmediate==k.setImmediate?(Qb||(Qb=Rb()),Qb(a)):k.setImmediate(a)}}var Vb=!1,Wb=new tb;
|
||||
function Xb(){for(var a=null;a=Wb.remove();){try{a.a.call(a.b)}catch(b){Pb(b)}ya(vb,a)}Vb=!1};function J(a,b){this.a=Yb;this.j=void 0;this.c=this.b=this.f=null;this.g=this.h=!1;if(a!=p)try{var c=this;a.call(b,function(a){Zb(c,$b,a)},function(a){try{if(a instanceof Error)throw a;throw Error("Promise rejected.");}catch(b){}Zb(c,K,a)})}catch(d){Zb(this,K,d)}}var Yb=0,$b=2,K=3;function ac(){this.next=this.context=this.b=this.c=this.a=null;this.f=!1}ac.prototype.reset=function(){this.context=this.b=this.c=this.a=null;this.f=!1};var bc=new xa(function(){return new ac},function(a){a.reset()},100);
|
||||
function cc(a,b,c){var d=bc.get();d.c=a;d.b=b;d.context=c;return d}J.prototype.then=function(a,b,c){return dc(this,u(a)?a:null,u(b)?b:null,c)};Wa(J);function ec(a,b){a.b||a.a!=$b&&a.a!=K||fc(a);a.c?a.c.next=b:a.b=b;a.c=b}function dc(a,b,c,d){var e=cc(null,null,null);e.a=new J(function(a,l){e.c=b?function(c){try{var e=b.call(d,c);a(e)}catch(I){l(I)}}:a;e.b=c?function(b){try{var e=c.call(d,b);a(e)}catch(I){l(I)}}:l});e.a.f=a;ec(a,e);return e.a}J.prototype.u=function(a){this.a=Yb;Zb(this,$b,a)};
|
||||
J.prototype.v=function(a){this.a=Yb;Zb(this,K,a)};function Zb(a,b,c){if(a.a==Yb){a==c&&(b=K,c=new TypeError("Promise cannot resolve to itself"));a.a=1;var d;a:{var e=c,g=a.u,l=a.v;if(e instanceof J)ec(e,cc(g||p,l||null,a)),d=!0;else if(Xa(e))e.then(g,l,a),d=!0;else{var m=typeof e;if("object"==m&&null!=e||"function"==m)try{var r=e.then;if(u(r)){gc(e,r,g,l,a);d=!0;break a}}catch(I){l.call(a,I);d=!0;break a}d=!1}}d||(a.j=c,a.a=b,a.f=null,fc(a),b!=K||hc(a,c))}}
|
||||
function gc(a,b,c,d,e){function g(a){m||(m=!0,d.call(e,a))}function l(a){m||(m=!0,c.call(e,a))}var m=!1;try{b.call(a,l,g)}catch(r){g(r)}}function fc(a){a.h||(a.h=!0,Sb(a.l,a))}function ic(a){var b=null;a.b&&(b=a.b,a.b=b.next,b.next=null);a.b||(a.c=null);return b}
|
||||
J.prototype.l=function(){for(var a=null;a=ic(this);){var b=this.a,c=this.j;if(b==K&&a.b&&!a.f)for(var d=void 0,d=this;d&&d.g;d=d.f)d.g=!1;if(a.a)a.a.f=null,jc(a,b,c);else try{a.f?a.c.call(a.context):jc(a,b,c)}catch(e){kc.call(null,e)}ya(bc,a)}this.h=!1};function jc(a,b,c){b==$b?a.c.call(a.context,c):a.b&&a.b.call(a.context,c)}function hc(a,b){a.g=!0;Sb(function(){a.g&&kc.call(null,b)})}var kc=Pb;function lc(a){Ba.call(this);this.h=1;this.f=[];this.c=0;this.a=[];this.b={};this.j=Boolean(a)}x(lc,Ba);function mc(a,b,c,d){if(b=a.b[b]){var e=a.a;if(b=nb(b,function(a){return e[a+1]==c&&e[a+2]==d}))return a.g(b)}return!1}lc.prototype.g=function(a){var b=this.a[a];if(b){var c=this.b[b];0!=this.c?(this.f.push(a),this.a[a+1]=p):(c&&ob(c,a),delete this.a[a],delete this.a[a+1],delete this.a[a+2])}return!!b};
|
||||
lc.prototype.l=function(a,b){var c=this.b[a];if(c){for(var d=Array(arguments.length-1),e=1,g=arguments.length;e<g;e++)d[e-1]=arguments[e];if(this.j)for(e=0;e<c.length;e++){var l=c[e];nc(this.a[l+1],this.a[l+2],d)}else{this.c++;try{for(e=0,g=c.length;e<g;e++)l=c[e],this.a[l+1].apply(this.a[l+2],d)}finally{if(this.c--,0<this.f.length&&0==this.c)for(;c=this.f.pop();)this.g(c)}}return 0!=e}return!1};function nc(a,b,c){Sb(function(){a.apply(b,c)})}
|
||||
lc.prototype.clear=function(a){if(a){var b=this.b[a];b&&(kb(b,this.g,this),delete this.b[a])}else this.a.length=0,this.b={}};var oc=H("Opera")||H("OPR"),L=H("Trident")||H("MSIE"),pc=H("Edge"),qc=H("Gecko")&&!(-1!=Mb.toLowerCase().indexOf("webkit")&&!H("Edge"))&&!(H("Trident")||H("MSIE"))&&!H("Edge"),rc=-1!=Mb.toLowerCase().indexOf("webkit")&&!H("Edge"),sc=rc&&H("Mobile");function tc(){var a=k.document;return a?a.documentMode:void 0}var uc;
|
||||
a:{var vc="",wc=function(){var a=Mb;if(qc)return/rv\:([^\);]+)(\)|;)/.exec(a);if(pc)return/Edge\/([\d\.]+)/.exec(a);if(L)return/\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/.exec(a);if(rc)return/WebKit\/(\S+)/.exec(a);if(oc)return/(?:Version)[ \/]?(\S+)/.exec(a)}();wc&&(vc=wc?wc[1]:"");if(L){var xc=tc();if(null!=xc&&xc>parseFloat(vc)){uc=String(xc);break a}}uc=vc}var yc={};
|
||||
function M(a){var b;if(!(b=yc[a])){b=0;for(var c=fb(String(uc)).split("."),d=fb(String(a)).split("."),e=Math.max(c.length,d.length),g=0;0==b&&g<e;g++){var l=c[g]||"",m=d[g]||"",r=RegExp("(\\d*)(\\D*)","g"),I=RegExp("(\\d*)(\\D*)","g");do{var oa=r.exec(l)||["","",""],pa=I.exec(m)||["","",""];if(0==oa[0].length&&0==pa[0].length)break;b=gb(0==oa[1].length?0:parseInt(oa[1],10),0==pa[1].length?0:parseInt(pa[1],10))||gb(0==oa[2].length,0==pa[2].length)||gb(oa[2],pa[2])}while(0==b)}b=yc[a]=0<=b}return b}
|
||||
var zc=k.document,Ac=zc&&L?tc()||("CSS1Compat"==zc.compatMode?parseInt(uc,10):5):void 0;y.b={};y.b.Cb=!1;y.b.jb=!1;y.b.Nb=y.b.Cb||y.b.jb;y.b.Ga=!1;y.b.Kb={Ab:"a"};
|
||||
y.b.ready=function(a){function b(){c||(c=!0,y.b.Ga=!0,a())}var c=!1;y.b.Ga&&a();if(document.addEventListener)document.addEventListener("DOMContentLoaded",function(){b()},!1);else if(document.attachEvent){if(document.documentElement.doScroll&&window==window.top){var d=function(){if(!c&&document.body)try{document.documentElement.doScroll("left"),b()}catch(a){setTimeout(d,0)}};d()}document.attachEvent("onreadystatechange",function(){"complete"===document.readyState&&b()})}window.addEventListener?window.addEventListener("load",
|
||||
b,!1):window.attachEvent&&window.attachEvent("onload",b)};y.b.ready(function(){y.b.Ga=!0});y.b.P=function(a){return t(a)?document.getElementById(a):a};y.b.getElementsByTagName=function(a){a=a.toUpperCase();return k.document.getElementsByTagName(a)};y.b.Ua=function(){var a=k.document.body,b=k.document.documentElement,a=lb([a.scrollHeight,b.scrollHeight,a.offsetHeight,b.offsetHeight,a.clientHeight,b.clientHeight],function(a){return a?!0:!1});return Math.max.apply(null,a)};
|
||||
y.b.tb=function(a){a=a||k;var b=a.document;if(rc&&!sc){n(a.innerHeight)||(a=k);var b=a.innerHeight,c=a.document.documentElement.scrollHeight;a==a.top&&c<b&&(b-=15);return new ra(a.innerWidth,b)}a=y.b.Zb(b)?b.documentElement:b.body;return new ra(a.clientWidth,a.clientHeight)};y.b.Zb=function(a){return y.b.Nb?y.b.jb:"CSS1Compat"==a.compatMode};function Bc(){this.a=[];k.setTimeout(v(function(){Cc(this)},this),0)}aa(Bc);function Cc(a){for(var b=y.b.getElementsByTagName(y.b.Kb.Ab),c=[],d=0,e=b.length;d<e;++d)c.push(b[d]);b=y.l.map(c,function(a){return a.href});a.a=y.l.xc(b)};function Dc(a){this.f=a;this.b=this.c=this.a=null}function Ec(a,b){this.name=a;this.value=b}Ec.prototype.toString=function(){return this.name};var Fc=new Ec("SEVERE",1E3),Gc=new Ec("CONFIG",700),Hc=new Ec("FINE",500);function Jc(a){if(a.c)return a.c;if(a.a)return Jc(a.a);jb("Root logger has no level set.");return null}
|
||||
Dc.prototype.log=function(a,b,c){if(a.value>=Jc(this).value)for(u(b)&&(b=b()),a=new za(a,String(b),this.f),c&&(a.a=c),c="log:"+a.b,k.console&&(k.console.timeStamp?k.console.timeStamp(c):k.console.markTimeline&&k.console.markTimeline(c)),k.msWriteProfilerMark&&k.msWriteProfilerMark(c),c=this;c;)c=c.a};var Kc={},Lc=null;
|
||||
function Mc(a){Lc||(Lc=new Dc(""),Kc[""]=Lc,Lc.c=Gc);var b;if(!(b=Kc[a])){b=new Dc(a);var c=a.lastIndexOf("."),d=a.substr(c+1),c=Mc(a.substr(0,c));c.b||(c.b={});c.b[d]=b;b.a=c;Kc[a]=b}return b};var Nc=!L||9<=Number(Ac),Oc=L&&!M("9");!rc||M("528");qc&&M("1.9b")||L&&M("8")||oc&&M("9.5")||rc&&M("528");qc&&!M("8")||L&&M("9");function Pc(a,b){Da.call(this,a?a.type:"");this.a=this.target=null;this.keyCode=this.button=this.screenY=this.screenX=0;this.metaKey=this.shiftKey=this.ctrlKey=!1;this.b=this.state=null;if(a){this.type=a.type;var c=a.changedTouches?a.changedTouches[0]:null;this.target=a.target||a.srcElement;this.a=b;var d=a.relatedTarget;if(d&&qc)try{db(d.nodeName)}catch(e){}null===c?(this.screenX=a.screenX||0,this.screenY=a.screenY||0):(this.screenX=c.screenX||0,this.screenY=c.screenY||0);this.button=a.button;this.keyCode=
|
||||
a.keyCode||0;this.ctrlKey=a.ctrlKey;this.shiftKey=a.shiftKey;this.metaKey=a.metaKey;this.state=a.state;this.b=a;a.defaultPrevented&&this.c()}}x(Pc,Da);Pc.prototype.c=function(){Pc.yc.c.call(this);var a=this.b;if(a.preventDefault)a.preventDefault();else if(a.returnValue=!1,Oc)try{if(a.ctrlKey||112<=a.keyCode&&123>=a.keyCode)a.keyCode=-1}catch(b){}};Pc.prototype.O=function(){return this.b};var Qc="closure_lm_"+(1E6*Math.random()|0),Rc={},Sc=0;
|
||||
function N(a,b,c,d,e){if(q(b))for(var g=0;g<b.length;g++)N(a,b[g],c,d,e);else if(c=Tc(c),a&&a[Ea])Uc(a,b,c,d,e);else{if(!b)throw Error("Invalid event type");var g=!!d,l=Vc(a);l||(a[Qc]=l=new wb(a));c=xb(l,b,c,d,e);if(!c.a){d=Wc();c.a=d;d.src=a;d.listener=c;if(a.addEventListener)a.addEventListener(b.toString(),d,g);else if(a.attachEvent)a.attachEvent(Xc(b.toString()),d);else throw Error("addEventListener and attachEvent are unavailable.");Sc++}}}
|
||||
function Wc(){var a=Yc,b=Nc?function(c){return a.call(b.src,b.listener,c)}:function(c){c=a.call(b.src,b.listener,c);if(!c)return c};return b}function Zc(a,b,c,d,e){if(q(b))for(var g=0;g<b.length;g++)Zc(a,b[g],c,d,e);else(c=Tc(c),a&&a[Ea])?a.pa.remove(String(b),c,d,e):a&&(a=Vc(a))&&(b=a.A[b.toString()],a=-1,b&&(a=yb(b,c,!!d,e)),(c=-1<a?b[a]:null)&&$c(c))}
|
||||
function $c(a){if("number"!=typeof a&&a&&!a.da){var b=a.src;if(b&&b[Ea])zb(b.pa,a);else{var c=a.type,d=a.a;b.removeEventListener?b.removeEventListener(c,d,a.$):b.detachEvent&&b.detachEvent(Xc(c),d);Sc--;(c=Vc(b))?(zb(c,a),0==c.a&&(c.src=null,b[Qc]=null)):Ha(a)}}}function Xc(a){return a in Rc?Rc[a]:Rc[a]="on"+a}function ad(a,b,c,d){var e=!0;if(a=Vc(a))if(b=a.A[b.toString()])for(b=b.concat(),a=0;a<b.length;a++){var g=b[a];g&&g.$==c&&!g.da&&(g=bd(g,d),e=e&&!1!==g)}return e}
|
||||
function bd(a,b){var c=a.listener,d=a.za||a.src;a.ua&&$c(a);return c.call(d,b)}
|
||||
function Yc(a,b){if(a.da)return!0;if(!Nc){var c;if(!(c=b))a:{c=["window","event"];for(var d=k,e;e=c.shift();)if(null!=d[e])d=d[e];else{c=null;break a}c=d}e=c;c=new Pc(e,this);d=!0;if(!(0>e.keyCode||void 0!=e.returnValue)){a:{var g=!1;if(0==e.keyCode)try{e.keyCode=-1;break a}catch(r){g=!0}if(g||void 0==e.returnValue)e.returnValue=!0}e=[];for(g=c.a;g;g=g.parentNode)e.push(g);for(var g=a.type,l=e.length-1;0<=l;l--){c.a=e[l];var m=ad(e[l],g,!0,c),d=d&&m}for(l=0;l<e.length;l++)c.a=e[l],m=ad(e[l],g,!1,
|
||||
c),d=d&&m}return d}return bd(a,new Pc(b,this))}function Vc(a){a=a[Qc];return a instanceof wb?a:null}var cd="__closure_events_fn_"+(1E9*Math.random()>>>0);function Tc(a){if(u(a))return a;a[cd]||(a[cd]=function(b){return a.handleEvent(b)});return a[cd]};y.f={};y.f.Bc={Jc:"scroll"};y.f.s=0;y.f.Za=!1;y.f.sa=[];y.f.La=300;y.f.la=48;y.f.Kc=function(a){if(!k.addEventListener)return!1;0===y.f.sa.length&&y.f.Na();y.f.sa.push(a);return!0};
|
||||
y.f.Na=function(){var a=void 0,b={},c={$:!0,vc:!0};k.document.addEventListener("touchstart",function(c){1===c.touches.length&&(a=w(),b=c.changedTouches.item(0))},y.f.Za?c:!0);k.document.addEventListener("touchend",function(c){if(1!==c.changedTouches.length)b={};else{var e=w(),g=c.changedTouches.item(0);if(g.identifier!==b.identifier)b={};else if(e-a>=y.f.La)b={};else{var e=b.radiusX||y.f.la,l=b.radiusY||y.f.la;if(Math.abs(g.pageX-b.pageX)>e||Math.abs(g.pageY-b.pageY)>l||Math.abs(g.screenX-b.screenX)>
|
||||
e||Math.abs(g.screenY-b.screenY)>l)b={};else{g=0;for(e=y.f.sa.length;g<e;++g)y.f.sa[g](c,y.f.s++);b={}}}}},y.f.Za?c:!0)};try{qa=Object.defineProperty&&Object.defineProperty({},"passive",{get:function(){y.f.Za=!0}}),k.addEventListener&&k.addEventListener("testPassiveEvents",null,qa)}catch(a){console.error(a)};var O={m:{}};O.m.keydown=void 0;O.addListener=function(a,b){switch(a){case "keydown":O.Pb();break;default:return}O.m[a]=b};O.Pb=function(){N(k.document,"keydown",O.gc,z())};O.gc=function(a){O.m.keydown(a)};var P={m:{}};P.m.click=void 0;P.m.mousedown=void 0;P.m.tap=void 0;P.m.touchstart=void 0;P.m.touchend=void 0;P.X={};P.X.mousedown=new A;P.X.click=new A;P.X.tap=new A;P.La=300;P.la=48;P.addListener=function(a,b){switch(a){case "click":P.Ob();break;case "tap":P.Na();break;case "mousedown":P.Qb();break;case "touchstart":P.Tb();break;default:return}P.m[a]=b};P.Ob=function(){N(k.document,"click",P.bc,z())};P.Qb=function(){N(k.document,"mousedown",P.hc,z())};
|
||||
P.Tb=function(){N(k.document,"touchstart",P.kc,z())};
|
||||
P.Na=function(){if(!k.addEventListener)return!1;var a=void 0,b={};k.document.addEventListener("touchstart",function(c){1===c.touches.length&&(a=w(),b=c.changedTouches.item(0))},z());k.document.addEventListener("touchend",function(c){if(1!==c.changedTouches.length)b={};else{var d=w(),e=c.changedTouches.item(0);if(e.identifier!==b.identifier)b={};else if(d-a>=P.La)b={};else{var d=b.radiusX||P.la,g=b.radiusY||P.la;Math.abs(e.pageX-b.pageX)>d||Math.abs(e.pageY-b.pageY)>g||Math.abs(e.screenX-b.screenX)>
|
||||
d||Math.abs(e.screenY-b.screenY)>g?b={}:(c.getBrowserEvent=c.O,P.Qa(c),b={})}}},z());return null};P.bc=function(a){a.getBrowserEvent=a.O;P.m.click(a)};P.hc=function(a){if(!P.ob("tap",a)){var b=P.X.mousedown;b.enqueue({target:a.target,yb:k.setTimeout(function(){b.na()},1E3)});a.getBrowserEvent=a.O;P.m.mousedown(a)}};P.kc=function(a){a.getBrowserEvent=a.O;P.m.touchstart(a)};
|
||||
P.Qa=function(a){if(!P.ob("mousedown",a)){var b=P.X.tap;b.enqueue({target:a.target,yb:k.setTimeout(function(){b.na()},1E3)});a.Oc=!0;a.getBrowserEvent=a.O;P.m.tap(a)}};P.ob=function(a,b){var c=P.X[a];if(c.D()||c.M().target!==b.target)return!1;k.clearTimeout(c.M().yb);c.na();return!0};var Q={m:{}};Q.m.scroll=void 0;Q.addListener=function(a,b){switch(a){case "scroll":Q.Sb();break;default:return}Q.m[a]=b};Q.Sb=function(){N(k.document,"scroll",Q.jc,z())};Q.jc=function(a){Q.m.scroll(a)};var R={m:{}};R.m.beforeunload=void 0;R.m.resize=void 0;R.addListener=function(a,b){switch(a){case "beforeunload":R.Ub();break;case "resize":R.Rb();break;default:return}R.m[a]=b};R.Ub=function(){N(k,"beforeunload",R.Ra,z())};R.Rb=function(){N(k,"resize",R.Pa,z())};R.Ra=function(a){R.m.beforeunload(a)};R.Pa=function(a){R.m.resize(a)};function S(){this.c=new lc;this.f={}}aa(S);S.prototype.a=function(a,b,c){var d=this.c,e=d.b[a];e||(e=d.b[a]=[]);var g=d.h;d.a[g]=a;d.a[g+1]=b;d.a[g+2]=c;d.h=g+3;e.push(g);return g};S.prototype.g=function(a,b,c){return mc(this.c,a,b,c)};S.prototype.b=function(a,b){return this.c.l.apply(this.c,arguments)};S.prototype.addListener=function(a,b,c){a=y.u.isArray(a)?a:[a];for(var d=0,e=a.length;d<e;++d)dd(this,a[d]).A.push({Z:b,context:c})};
|
||||
function dd(a,b){var c=a.f[b];c||(c=a.f[b]={A:[],Ya:void 0});c.Ya||(c.Ya=ed(b),c.Ya.addListener(b,fd(a,b)));return c}function ed(a){switch(a){case "click":case "mousedown":case "tap":case "touchstart":return P;case "beforeunload":case "resize":return R;case "keydown":return O;case "scroll":return Q;default:return null}}
|
||||
function fd(a,b){return v(function(){for(var a=dd(this,b).A,d=Array(arguments.length),e=0,g=arguments.length;e<g;e++)d[e]=arguments[e];e=0;for(g=a.length;e<g;++e)a[e].Z.apply(a[e].context,d)},a)}var T=S.prototype;T.subscribe=T.a;T.unsubscribe=T.g;T.publish=T.b;T.addListener=T.addListener;function gd(){this.c=S.B();this.a=0;w();this.b=!0;k.setTimeout(v(this.f,this),hd(this));var a=y.H.fb(this.g,this);this.c.addListener(id,a,this)}var jd=[0,10,30,60,120,180,240,300,360,420,480,540,600,720,840,960,1080,1200],id=["click","mousedown","keydown","scroll"];gd.prototype.g=function(){this.b=!0};function hd(a){return++a.a>=jd.length?12E4:1E3*(jd[a.a]-jd[a.a-1])}gd.prototype.f=function(){this.b&&(this.c.b("ping"),this.b=!1);k.setTimeout(v(this.f,this),hd(this))};function kd(){this.c=this.a=void 0;this.b=this.f="";this.g=void 0;var a;a:if("visibilityState"in document)this.f="visibilitychange",this.b="hidden",a=!0;else{a=void 0;for(var b=0;b<ld;++b)if(a=ld[b],a+"VisibilityState"in document){this.f=a+"visibilitychange";this.b=a+"Hidden";a=!0;break a}a=!1}if(this.c=a)this.g=S.B(),this.a=!k.document[this.b],N(k.document,this.f,this.h,!1,this)}var ld=["webkit","moz","ms","o"];kd.prototype.h=function(){this.a=!k.document[this.b];this.g.b("visibility")};function md(){Ba.call(this);this.pa=new wb(this);this.ra=this}x(md,Ba);md.prototype[Ea]=!0;md.prototype.removeEventListener=function(a,b,c,d){Zc(this,a,b,c,d)};function U(a,b){var c=a.ra,d=b,e=d.type||d;if(t(d))d=new Da(d,c);else if(d instanceof Da)d.target=d.target||c;else{var g=d,d=new Da(e,c);Ua(d,g)}c=d.a=c;nd(c,e,!0,d);nd(c,e,!1,d)}function Uc(a,b,c,d,e){xb(a.pa,String(b),c,d,e)}
|
||||
function nd(a,b,c,d){if(b=a.pa.A[String(b)]){b=b.concat();for(var e=!0,g=0;g<b.length;++g){var l=b[g];if(l&&!l.da&&l.$==c){var m=l.listener,r=l.za||l.src;l.ua&&zb(a.pa,l);e=!1!==m.call(r,d)&&e}}}};function od(){this.b=S.B();this.a=void 0;this.c=Bc.B();pd(this)}var qd=/^javascript\:/i,rd=/^_(self|parent|top)$/i;function pd(a){a.b.addListener("mousedown",function(a){var c=a.O().button;0!==c&&1!==c||sd(this,a)},a);a.b.addListener("keydown",function(a){13===a.O().keyCode&&sd(this,a)},a)}
|
||||
function sd(a,b){var c;for(c=b.target;c&&(!n(c.tagName)||"a"!==c.tagName.toLowerCase()||!c.href);)c=c.parentNode;var d=new D;if(c&&c.href){a.a=c.href;var e=a.a;-1!==e.indexOf(k.location.host)||e.match(qd)||(c.target&&c.target.match(rd),d.K("et","extln"),d.set("extln",a.a),y.l.includes(a.c.a,a.a)&&d.set("um_log","cl"),a.b.b("extLink",d))}};!qc&&!L||L&&9<=Number(Ac)||qc&&M("1.9.1");L&&M("9");function td(a,b){Pa(b,function(b,d){"style"==d?a.style.cssText=b:"class"==d?a.className=b:"for"==d?a.htmlFor=b:ud.hasOwnProperty(d)?a.setAttribute(ud[d],b):0==d.lastIndexOf("aria-",0)||0==d.lastIndexOf("data-",0)?a.setAttribute(d,b):a[d]=b})}var ud={cellpadding:"cellPadding",cellspacing:"cellSpacing",colspan:"colSpan",frameborder:"frameBorder",height:"height",maxlength:"maxLength",nonce:"nonce",role:"role",rowspan:"rowSpan",type:"type",usemap:"useMap",valign:"vAlign",width:"width"};
|
||||
function vd(a){a=a.document;a="CSS1Compat"==a.compatMode?a.documentElement:a.body;return new Va(a.clientWidth,a.clientHeight)}function wd(a){return a.parentWindow||a.defaultView}function xd(a){this.a=a||k.document||document}xd.prototype.P=function(a){return t(a)?this.a.getElementById(a):a};xd.prototype.tb=function(a){return vd(a||wd(this.a)||window)};
|
||||
xd.prototype.Ua=function(){var a;a:{var b=wd(this.a),c=b.document;a=0;if(c){a=c.body;var d=c.documentElement;if(!d||!a){a=0;break a}b=vd(b).a;if("CSS1Compat"==c.compatMode&&d.scrollHeight)a=d.scrollHeight!=b?d.scrollHeight:d.offsetHeight;else{var c=d.scrollHeight,e=d.offsetHeight;d.clientHeight!=e&&(c=a.scrollHeight,e=a.offsetHeight);a=c>b?c>e?c:e:c<e?c:e}}}return a};
|
||||
xd.prototype.contains=function(a,b){if(!a||!b)return!1;if(a.contains&&1==b.nodeType)return a==b||a.contains(b);if("undefined"!=typeof a.compareDocumentPosition)return a==b||Boolean(a.compareDocumentPosition(b)&16);for(;b&&a!=b;)b=b.parentNode;return b==a};function yd(){this.b=new D;this.a=void 0;var a=this.b;a.K("et","pv");a.set("bs",y.b.tb());a.set("ce",navigator.cookieEnabled?1:0);var b=k.document;b&&(a.set("rf",b.referrer||""),a.set("en",b.characterSet||b.charset||""),a.set("pt",b.title.substring(0,255)));if(b=k.screen)a.set("sr",b.width+"x"+b.height),a.set("cd",b.colorDepth+"-bit");if(b=k.navigator)a.set("la",b.language||b.browserLanguage||""),a.set("ja",b.javaEnabled()?1:0),a.set("acn",b.appCodeName),a.set("an",b.appName),a.set("pl",b.platform);
|
||||
a.set("tz",(new Date).getTimezoneOffset());a.set("fv",zd());a.set("sv",y.a.i.VERSION);a.set("lv",Ad(this))}function Bd(a,b,c,d){var e=a.b.clone(),g=b.hb&&a.Oa();d=d||b.cb||k.location.href.split("#")[0];e.set("pt",document.title.substring(0,255));var l;if(l=b.C){var m;a:{l=b.C;for(m in l){m=!1;break a}m=!0}l=!m}l&&(m=y.ga.zb(b.C),e.set("cv",m.toString()));q(b.ma)&&b.ma.length&&(a=a.c(b.ma),e.set("ch",Ja(a)));g&&e.set("hash",g);(c||0==c)&&e.set("le",c);d&&e.set("url",d);return e}
|
||||
function Ad(a){if(!a.a){a.a=B.get("last_visit");for(var b=["/",k.document.pathname],c=0,d=b.length;c<d;++c)B.remove("last_visit",b[c]);b=new Date;b=b.getTime()+6E4*b.getTimezoneOffset()+"::"+b.getTime();c="."+k.document.location.hostname.split("www.").pop();B.set("last_visit",b,864E5,"/",c)}return a.a||""}yd.prototype.c=function(a){for(var b=[],c=0,d=a.length;c<d;++c)b.push(a[c].substring(0,255));return b};
|
||||
function zd(){var a=Lb.match(/[\d]+/g);if(!a||!a.length)return"";a.length=3;return a[0]+"."+a[1]+" r"+a[2]}yd.prototype.c=function(a){for(var b=[],c=0,d=a.length;c<d;++c)b.push(a[c].substring(0,255));return b};yd.prototype.Oa=function(){var a=k.location.hash.split("#")[1];return y.b.P(a)?null:a};function Cd(){this.a=this.c=this.b=void 0;this.g=!1;k.setTimeout(v(this.f,this),0)}Cd.prototype.f=function(){this.a=y.b.Ua();this.b=vd(window).a;this.c=this.a/10;var a=y.g.Aa(this.a),b=y.g.Aa(this.b);a&&b?(this.g=!0,S.B().addListener("resize",y.H.fb(this.Pa,this),this)):k.setTimeout(v(this.f,this),1E3)};Cd.prototype.Pa=function(){this.b=vd(window).a};function V(a,b){a&&a.log(Hc,b,void 0)};function Dd(a,b,c){if(u(a))c&&(a=v(a,c));else if(a&&"function"==typeof a.handleEvent)a=v(a.handleEvent,a);else throw Error("Invalid listener argument");return 2147483647<Number(b)?-1:k.setTimeout(a,b||0)};function Ed(a){md.call(this);this.Ha=new Eb;this.G=a||null;this.b=!1;this.v=this.a=null;this.g=this.ga=this.j="";this.f=this.W=this.h=this.V=!1;this.c=0;this.l=null;this.ia=Fd;this.u=this.ja=!1}x(Ed,md);var Fd="",Gd=Ed.prototype,Hd=Mc("goog.net.XhrIo");Gd.F=Hd;var Id=/^https?$/i,Jd=["POST","PUT"];
|
||||
Ed.prototype.send=function(a,b,c,d){if(this.a)throw Error("[goog.net.XhrIo] Object is active with another request="+this.j+"; newUri="+a);b=b?b.toUpperCase():"GET";this.j=a;this.g="";this.ga=b;this.V=!1;this.b=!0;this.a=this.G?Db(this.G):Db(Bb);this.v=this.G?bb(this.G):bb(Bb);this.a.onreadystatechange=v(this.ha,this);try{V(this.F,W(this,"Opening Xhr")),this.W=!0,this.a.open(b,String(a),!0),this.W=!1}catch(g){V(this.F,W(this,"Error opening Xhr: "+g.message));Kd(this,g);return}a=c||"";var e=this.Ha.clone();
|
||||
d&&Hb(d,function(a,b){e.set(b,a)});d=nb(e.R(),Ld);c=k.FormData&&a instanceof k.FormData;!(0<=F(Jd,b))||d||c||e.set("Content-Type","application/x-www-form-urlencoded;charset=utf-8");e.forEach(function(a,b){this.a.setRequestHeader(b,a)},this);this.ia&&(this.a.responseType=this.ia);Sa(this.a)&&(this.a.withCredentials=this.ja);try{Md(this),0<this.c&&(this.u=Nd(this.a),V(this.F,W(this,"Will abort after "+this.c+"ms if incomplete, xhr2 "+this.u)),this.u?(this.a.timeout=this.c,this.a.ontimeout=v(this.Da,
|
||||
this)):this.l=Dd(this.Da,this.c,this)),V(this.F,W(this,"Sending request")),this.h=!0,this.a.send(a),this.h=!1}catch(g){V(this.F,W(this,"Send error: "+g.message)),Kd(this,g)}};function Nd(a){return L&&M(9)&&"number"==typeof a.timeout&&n(a.ontimeout)}function Ld(a){return"content-type"==a.toLowerCase()}
|
||||
Ed.prototype.Da=function(){"undefined"!=typeof h&&this.a&&(this.g="Timed out after "+this.c+"ms, aborting",V(this.F,W(this,this.g)),U(this,"timeout"),this.a&&this.b&&(V(this.F,W(this,"Aborting")),this.b=!1,this.f=!0,this.a.abort(),this.f=!1,U(this,"complete"),U(this,"abort"),Od(this)))};function Kd(a,b){a.b=!1;a.a&&(a.f=!0,a.a.abort(),a.f=!1);a.g=b;Pd(a);Od(a)}function Pd(a){a.V||(a.V=!0,U(a,"complete"),U(a,"error"))}Ed.prototype.ha=function(){this.H||(this.W||this.h||this.f?Qd(this):this.Ja())};
|
||||
Ed.prototype.Ja=function(){Qd(this)};
|
||||
function Qd(a){if(a.b&&"undefined"!=typeof h)if(a.v[1]&&4==Rd(a)&&2==Sd(a))V(a.F,W(a,"Local request error detected and ignored"));else if(a.h&&4==Rd(a))Dd(a.ha,0,a);else if(U(a,"readystatechange"),4==Rd(a)){V(a.F,W(a,"Request complete"));a.b=!1;try{var b=Sd(a),c;a:switch(b){case 200:case 201:case 202:case 204:case 206:case 304:case 1223:c=!0;break a;default:c=!1}var d;if(!(d=c)){var e;if(e=0===b){var g=String(a.j).match(Ib)[1]||null;if(!g&&k.self&&k.self.location)var l=k.self.location.protocol,g=
|
||||
l.substr(0,l.length-1);e=!Id.test(g?g.toLowerCase():"")}d=e}if(d)U(a,"complete"),U(a,"success");else{var m;try{m=2<Rd(a)?a.a.statusText:""}catch(r){V(a.F,"Can not get status: "+r.message),m=""}a.g=m+" ["+Sd(a)+"]";Pd(a)}}finally{Od(a)}}}function Od(a){if(a.a){Md(a);var b=a.a,c=a.v[0]?p:null;a.a=null;a.v=null;U(a,"ready");try{b.onreadystatechange=c}catch(d){(a=a.F)&&a.log(Fc,"Problem encountered resetting onreadystatechange: "+d.message,void 0)}}}
|
||||
function Md(a){a.a&&a.u&&(a.a.ontimeout=null);"number"==typeof a.l&&(k.clearTimeout(a.l),a.l=null)}function Rd(a){return a.a?a.a.readyState:0}function Sd(a){try{return 2<Rd(a)?a.a.status:-1}catch(b){return-1}}function W(a,b){return b+" ["+a.ga+" "+a.j+" "+Sd(a)+"]"};function Td(){this.a=void 0}Td.prototype.send=function(a,b,c){Ud(this,c);this.a.send(a,"POST",b)};function Ud(a,b){a.a=new Ed;a.a.ja=!0;a.a.c=Math.max(0,ka);Uc(a.a,"success",function(){b.eb()});Uc(a.a,"error",function(){b.error()})};function Vd(){this.a=new ja;this.c=new Td;this.b=new ia}aa(Vd);var ka=1E3,Wd="withCredentials"in new XMLHttpRequest,Xd=!!k.navigator.sendBeacon;Vd.prototype.send=function(a,b,c,d,e){a=e||a.ya();c===Yd?this.b.send(a,b.toString(),d):c===Zd?this.c.send(a,b.toString(),d):c===$d&&(b.setMeta("rn",y.g.Ba()),a+="?"+b.toString(),this.a.send(a,d))};function ae(){this.a=new sb;this.u=new Vd;this.h=!1;this.b=0;this.c=!1;this.f=0}aa(ae);var Yd="beacon",Zd="xhr",$d="image";ae.prototype.g=function(){if(this.a.D())this.h=!1;else{var a=this.a.M(),b=a.url;this.u.send(a.data[0][0],a.data[0][1],a.type,{eb:v(this.l,this),error:v(this.j,this)},b)}};ae.prototype.l=function(){this.c=!1;this.b=this.f=0;var a=this.a.M();a.data.shift();0===a.data.length&&(a=this.a.na(),a.Z&&a.Z());this.g()};
|
||||
ae.prototype.j=function(){if(5<=this.f++)this.c=!1,this.b=this.f=0;else{if(!this.c){this.c=!0;var a=this.a.M();a&&a.data&&a.data[0][1].set("retry",1)}this.b+=250;k.setTimeout(v(this.g,this),this.b)}};function be(){this.b=S.B();this.g=new kd;this.j=new Cd;this.h=new sa(v(this.v,this));this.f=!0;this.c=this.a=void 0;this.b.a("visibility",this.u,this);this.a={time:0,ea:qb(10)};Xd&&this.g.c?this.g.a&&this.h.start():new gd;var a=y.H.fb(this.l,this);this.b.addListener(ce,a,this);de(this)}var ce=["click","mousedown","keydown","scroll"];be.prototype.u=function(){var a=this.g.a;if(Xd){var b=this.h;a?b.start():(b.b=!1,va(b))}};
|
||||
be.prototype.v=function(){if(this.f){var a=this.j,b,c;c=(k||window).document;b=(c?new xd(9==c.nodeType?c:c.ownerDocument||c.document):Ia||(Ia=new xd)).a;c=b.scrollingElement?b.scrollingElement:rc||"CSS1Compat"!=b.compatMode?b.body||b.documentElement:b.documentElement;b=wd(b);var d=(L&&M("10")&&b.pageYOffset!=c.scrollTop?new Ab(c.scrollLeft,c.scrollTop):new Ab(b.pageXOffset||c.scrollLeft,b.pageYOffset||c.scrollTop)).J;a.a=y.b.Ua();b=Math.floor(d/a.c+.3);c=Math.floor((d+a.b)/a.c+.7)-1;a.a<d+a.b&&(c=
|
||||
y.g.trunc(c,10)-1);a=Math.ceil(a.a/a.c)-1;d=y.g.wb(b)&&y.g.Aa(c)&&y.g.Aa(a);if(this.j.g&&d)for(a+1>this.a.ea.length&&(this.a.ea=pb(this.a.ea,qb(a-this.a.ea.length+1))),a=b;a<=c;++a)this.a.ea[a]++;this.a.time++}};be.prototype.l=function(){this.f=!0;de(this)};function de(a){a.c&&k.clearTimeout(a.c);a.c=k.setTimeout(v(function(){this.f=!1},a),3E4)};
|
||||
function ee(a,b){this.f=[];this.H=b||null;this.a=this.b=!1;this.c=void 0;this.u=this.v=this.h=!1;this.g=0;this.j=null;this.G=0}ee.prototype.l=function(a,b){this.h=!1;fe(this,a,b)};function fe(a,b,c){a.b=!0;a.c=c;a.a=!b;ge(a)}function he(a){if(a.b){if(!a.u)throw new ie;a.u=!1}}ee.prototype.Z=function(a){he(this);fe(this,!0,a)};function je(a,b,c){a.f.push([b,c,void 0]);a.b&&ge(a)}
|
||||
ee.prototype.then=function(a,b,c){var d,e,g=new J(function(a,b){d=a;e=b});je(this,d,function(a){e(a)});return g.then(a,b,c)};Wa(ee);function ke(a){return mb(a.f,function(a){return u(a[1])})}
|
||||
function ge(a){if(a.g&&a.b&&ke(a)){var b=a.g,c=le[b];c&&(k.clearTimeout(c.a),delete le[b]);a.g=0}a.j&&(a.j.G--,delete a.j);for(var b=a.c,d=c=!1;a.f.length&&!a.h;){var e=a.f.shift(),g=e[0],l=e[1],e=e[2];if(g=a.a?l:g)try{var m=g.call(e||a.H,b);n(m)&&(a.a=a.a&&(m==b||m instanceof Error),a.c=b=m);if(Xa(b)||"function"===typeof k.Promise&&b instanceof k.Promise)d=!0,a.h=!0}catch(r){b=r,a.a=!0,ke(a)||(c=!0)}}a.c=b;d&&(m=v(a.l,a,!0),d=v(a.l,a,!1),b instanceof ee?(je(b,m,d),b.v=!0):b.then(m,d));c&&(b=new me(b),
|
||||
le[b.a]=b,a.g=b.a)}function ie(){C.call(this)}x(ie,C);ie.prototype.message="Deferred has already fired";ie.prototype.name="AlreadyCalledError";function me(a){this.a=k.setTimeout(v(this.c,this),0);this.b=a}me.prototype.c=function(){delete le[this.a];throw this.b;};var le={};function ne(a){var b={},c=b.document||document,d=document.createElement("SCRIPT"),e={Qc:d,Da:void 0},g=new ee(0,e),l=null,m=null!=b.timeout?b.timeout:5E3;0<m&&(l=window.setTimeout(function(){oe(d,!0);var b=new pe(qe,"Timeout reached for loading script "+a);he(g);fe(g,!1,b)},m),e.Da=l);d.onload=d.onreadystatechange=function(){d.readyState&&"loaded"!=d.readyState&&"complete"!=d.readyState||(oe(d,b.Mc||!1,l),g.Z(null))};d.onerror=function(){oe(d,!0,l);var b=new pe(re,"Error while loading script "+a);
|
||||
he(g);fe(g,!1,b)};e=b.attributes||{};Ua(e,{type:"text/javascript",charset:"UTF-8",src:a});td(d,e);se(c).appendChild(d)}function se(a){var b=a.getElementsByTagName("HEAD");return b&&0!=b.length?b[0]:a.documentElement}function oe(a,b,c){null!=c&&k.clearTimeout(c);a.onload=p;a.onerror=p;a.onreadystatechange=p;b&&window.setTimeout(function(){a&&a.parentNode&&a.parentNode.removeChild(a)},0)}var re=0,qe=1;function pe(a,b){var c="Jsloader error (code #"+a+")";b&&(c+=": "+b);C.call(this,c)}x(pe,C);function te(){this.b={};this.a={};this.c=S.B();for(var a in ue)this.a[ue[a].name]=[];this.c.a("module_init",this.f,this)}aa(te);var ve="//st.top100.ru/top100/1.8.0/",ue={Mb:{name:"usability",path:"usability.js"},Eb:{name:"ecommerce",path:"ecommerce.js"}};function we(a,b,c){a.b[b.name]||(ne(ve+b.path),a.a[b.name].push(c))}te.prototype.f=function(a,b){for(this.b[a]=b;this.a[a].length;)this.a[a].shift()(b)};function xe(){this.j=this.h=this.b=this.g=void 0;this.v=ae.B();this.u=te.B();this.a=[];this.f=[];this.l=!1;this.c=S.B();this.g=new yd;new od;this.h=Bc.B();this.c.a("extLink",this.fc,this);this.c.a("click",this.cc,this);this.c.a("tap",this.Qa,this);this.c.a("ecommerce",this.dc,this);this.j=new be;this.c.a("activity",this.ac,this);this.c.a("ping",this.ic,this);this.c.addListener("beforeunload",this.Ra,this)}aa(xe);
|
||||
function ye(a,b){var c=ze(a,b);if(!c.ca){for(var d=0,e=a.a.length;d<e;++d)a.a[d].id==c.id&&a.a.splice(d,1);c.w&&0<c.w.length&&we(a.u,ue.Mb,v(a.lc,a));c.L&&we(a.u,ue.Eb,v(a.ec,a));c.aa&&Ae(a,c.aa);a.a.push(c);c.ca||(c.element?(d=y.b.P(c.element))&&1===d.nodeType&&(d.innerHTML=a.ba(c.s,0)):a.U(c.s));c.s.o.Ea&&k.setTimeout(v(function(){var a=c.s,b;b=this.h;if(0===b.a.length)b=null;else{var d=new D;d.K("et","ll");d.set("ll",Ja(b.a));b=d}b&&(b=X(a,b),Y(this,[[a,b]],void 0,void 0,a.Wa()))},a),0)}}f=xe.prototype;
|
||||
f.U=function(a,b,c){b=Bd(this.g,a.o,b,c);b=X(a,b);Y(this,[[a,b]]);if(b=Be(this,a)){c=0;for(var d=b.w.length;c<d;++c)b.Ca[b.w[c]]=[];!a.o.Fa&&Ce(this,b)}};f.ba=function(a,b,c){b=Bd(this.g,a.o,b,c);b=X(a,b);b.K("rn",y.g.Ba());c=a.o.T;return'<a href="https://top100.rambler.ru'+(c?"/home?id="+c:"")+'" target="_blank"><img src="'+(a.ya()+"?"+b.toString())+'" title="Rambler\'s Top100" alt="Rambler\'s Top100" border="0" /></a>'};
|
||||
function Y(a,b,c,d,e){a=a.v;var g={};c=c||5;if(1===c)g.type=Yd;else{var l=b[0][1],m=void 0,r=l.get("et"),I=["bv","cl","ec","extln","ll"];0<=F(["extln","act"],r)&&Xd?m=Yd:0<=F(I,r)&&Wd?m=Zd:2E3>=l.toString().length?m=$d:Wd&&(m=Zd);g.type=m}g.type&&(g.data=b,g.Z=d,g.url=e,a.a.enqueue(c,g),a.h||(a.h=!0,a.g()))}f.cc=function(){for(var a=void 0,b=0,c=this.a.length;b<c;++b){var a=this.a[b],d=this.b.getClicks(a.w);d&&(d=X(a.s,d),Y(this,[[a.s,d]]))}this.b.eraseClicksData()};
|
||||
f.Qa=function(){for(var a=void 0,b=0,c=this.a.length;b<c;++b){var a=this.a[b],d=this.b.getClicks(a.w);d&&(d.set("clt","tap"),d=X(a.s,d),Y(this,[[a.s,d]]))}this.b.eraseClicksData()};f.ic=function(){var a=new D;a.set("et","ping");for(var b=void 0,c=[],d=0,e=this.a.length;d<e;++d)this.a[d].s.o.ca||(b=X(this.a[d].s,a.clone())),c.push([this.a[d].s,b]);0!==c.length&&Y(this,c)};
|
||||
f.dc=function(a){for(var b=[],c=0,d=this.a.length;c<d;++c)if(this.a[c].L){var e=X(this.a[c].s,a.clone());b.push([this.a[c].s,e])}0!==b.length&&Y(this,b)};f.fc=function(a,b){for(var c=[],d=0,e=this.a.length;d<e;++d)this.a[d].s.o.Ea||a.remove("um_log"),c.push([this.a[d].s,X(this.a[d].s,a.clone())]);0!==c.length&&Y(this,c,void 0,b)};f.ac=function(a,b){for(var c=[],d=b?1:5,e=0,g=this.a.length;e<g;++e)c.push([this.a[e].s,X(this.a[e].s,a.clone())]);0!==c.length&&Y(this,c,d)};
|
||||
function ze(a,b){var c={},d=b.o;c.id=b.wa();c.s=b;c.element=d.P();c.w=d.Sa;c.L=d.L;c.ca=d.ca;c.Pc=!1;c.Ca={};c.aa=d.Ta;if(c.aa.length)for(var d=0,e=c.aa.length;d<e;++d)0<=F(c.w,c.aa[d])||c.w.push(c.aa[d]);if(a.f.length)for(d=0,e=a.f.length;d<e;++d)0<=F(c.w,a.f[d])||c.w.push(a.f[d]);d=0;for(e=c.w.length;d<e;++d)c.Ca[c.w[d]]=[];return c}function Be(a,b){for(var c=b.wa(),d=0,e=a.a.length;d<e;++d)if(a.a[d].id===c)return a.a[d];return null}
|
||||
function Ae(a,b){for(var c=0,d=a.a.length;c<d;++c)for(var e=a.a[c],g=b,l=0,m=g.length;l<m;++l)0<=F(e.w,g[l])||(e.w.push(g[l]),e.Ca[g[l]]=[]);c=0;for(d=b.length;c<d;++c)0<=F(a.f,b[c])||a.f.push(b[c]);a.b&&a.b.addAttributes(b);a.Y()}function Ce(a,b){if(a.b){var c=a.b.getBlocks(b.w,b.Ca),d=void 0;if(c)for(var e=0,g=c.length;e<g;++e)d=c[e],d.isEmpty()||(d=X(b.s,d),Y(a,[[b.s,d]]))}}
|
||||
f.lc=function(a){this.b=a();a=0;for(var b=this.a.length;a<b;++a)this.b.addAttributes(this.a[a].w);this.Y();k.setTimeout(v(this.Y,this),1E3);k.setTimeout(v(this.Y,this),2E3);k.setTimeout(v(this.Y,this),4E3);k.setTimeout(v(this.Y,this),8E3)};f.Y=function(){for(var a=0,b=this.a.length;a<b;++a)!this.a[a].s.o.Fa&&Ce(this,this.a[a])};f.ec=function(a){for(var b=void 0,c=0,d=this.a.length;c<d;++c)if(this.a[c].L){b=this.a[c].L;break}a(b)};
|
||||
f.Ra=function(){if(!this.l){if(Xd){var a=this.j,b=new D,c=Ja({time:a.a.time,screens:a.a.ea});b.K("et","act");b.set("meta",c);a.b.b("activity",b,!0)}this.l=!0}};function De(a,b){this.a=this.b=void 0;Ee(this);this.version="1.8.0";if(a){if(this.T=a.project,this.Sa=a.attributes_dataset||[],this.Ta=a.common_attributes||[],this.fa=a.splits||[],this.ma=a.chapters||[],this.C=a.custom_vars||{},this.L=a.ecommerce||void 0,this.element=a.element||void 0,this.hb=a.trackHashes||!1,this.Ea=a.trackLinks||!1,this.cb=a.url||void 0,this.Fa=a.usabilityManualControl||!1,a.user_id||null===a.user_id?this.N=a.user_id:this.N=void 0,!0===a.useYmId&&(this.Ka=y.h.rc()),a.sync){var c=
|
||||
a.sync;this.C=this.C||{};this.C.__uid=c}}else this.T=ha.Ac,this.Sa=[],this.Ta=[],this.fa=[],this.ma=[],this.N=this.element=this.L=this.C=void 0,this.Ea=this.hb=!1,this.cb=void 0,this.Fa=!1;var c=this.T||"-1",d=a&&a.protocol;if(d){var e=void 0,g;for(g in Fe)if(e=Fe[g],d.split(":")[0]===e){":"!==e[e.length-1]&&(e=e+":");this.ka=e;break}ve=this.ka+ve}else this.ka=void 0;g=a.top100Id;this.gb=y.c.xa(c);if("string"===typeof g||"number"===typeof g)this.rb=g;c=void 0;this.ka?c=this.ka:c="https:"===k.location.protocol?
|
||||
"https:":"http:";this.b=c+"//kraken.rambler.ru/cnt/";this.a=c+"//kraken.rambler.ru/um_cnt/";this.ca=b||!1}var Fe={Dc:"http",Ec:"https"};f=De.prototype;f.version=void 0;f.gb="";f.Ka="";f.rb=void 0;f.T=void 0;f.$a=void 0;f.Sa=void 0;f.Ta=void 0;f.fa=void 0;f.ma=void 0;f.C=void 0;f.name=void 0;f.L=void 0;f.element=void 0;f.ka=void 0;f.ca=void 0;f.N=void 0;f.hb=void 0;f.Ea=void 0;f.cb=void 0;f.Fa=!1;f.ya=function(){return this.b};f.Wa=function(){return this.a};f.bb=function(a){this.name=a};f.P=function(){return this.element};
|
||||
function Ee(a){a.$a=(new Date/1E3).toString()+"-"+y.g.Ba().toString()};function Ge(a,b){this.o=new De(a,b);this.a=xe.B();ye(this.a,this)}f=Ge.prototype;f.ya=function(){return this.o.ya()};f.Wa=function(){return this.o.Wa()};f.bb=function(a){this.o.bb(a)};f.wa=function(){return this.o.T};f.ab=function(a){this.o.T=a};f.U=function(a){Ee(this.o);this.a.U(this,1,a)};f.ib=function(a,b){var c=y.b.P(a);c&&1===c.nodeType?c.innerHTML=this.a.ba(this,0,b):this.a.U(this,0,b)};f.sb=function(a,b){var c=y.b.P(a);c&&1===c.nodeType&&(c.innerHTML=this.a.ba(this,2,b))};f.pc=function(){return this.o.$a};
|
||||
f.ba=function(){return this.a.ba(this,0)};f.kb=function(){};f.nb=function(a){var b=this.o;a.splits&&(b.fa=a.splits);a.custom_vars&&(b.C=a.custom_vars)};f.mb=function(a,b){var c=this.o;c.C=c.C||{};c.C[a]=b};f.xb=function(a){this.b("__uid",a)};f.lb=function(a){var b=this.a;a=y.ha.Va(a);a=X(this,a);Y(b,[[this,a]])};f.Gb=function(){var a=this.a;Ce(a,Be(a,this))};f.Hb=function(a){var b=this.o;b.N||null===b.N?(this.o.N=a,a=this.a,b=y.ia.Va(),b=X(this,b),Y(a,[[this,b]])):y.W.wc()};
|
||||
function X(a,b){var c=a.o;b.setMeta("pid",c.T);b.setMeta("rid",c.$a);b.setMeta("tid",c.rb||c.gb);b.setMeta("v",c.version);q(c.fa)&&c.fa.length&&b.set("sp",Ja(c.fa));a.o.N&&b.setMeta("uid",c.N);c.Ka&&b.setMeta("yid",c.Ka);return b}f.xa=function(){return this.o.gb};var Z=Ge.prototype;Z.setAccount=Z.ab;Z.getAccount=Z.wa;Z.trackPageview=Z.U;Z.trackPageView=Z.U;Z.trackPageviewByLogo=Z.ib;Z.trackPageViewByLogo=Z.ib;Z.drawLogoTo=Z.sb;Z.setCustomVar=Z.mb;Z.getCustomVar=Z.kb;Z.sendCustomVars=Z.lb;
|
||||
Z.getWidgetHtml=Z.ba;Z.syncUserId=Z.Hb;Z.sync=Z.xb;Z.getRequestId=Z.pc;Z.sendBlocks=Z.Gb;Z.getTop100Id=Z.xa;Z.updateOptions=Z.nb;function y(a,b){a.checkInit&&k.setTimeout(function(){y.G.oc("initKraken"+a.project)},0);if(b)return new Ge(a,b);y.v[a.project]=new Ge(a,b);return y.v[a.project]}y.v={};y.Hc={};y.Ha=0;y.Ia=function(){return S.B()};y.Fc=function(){return S.B()};y.V=function(a,b){var c=void 0!==a?a:"~"+y.Ha++,d=new y({},!0);y.v[c]=d;d.bb(c);b&&d.ab(b);return d};y.Ja=function(a){return y.V(void 0,a)};y.ja=function(a){a=a||"";return y.v[a]||y.V(a)};y.loaded=!0;y.Fb=!0;
|
||||
y.ra=function(a){var b=k[a];b&&b.isTop100Namespace||(k[a]=y)};y.ra("Kraken");y.ra("top100");function He(){}He.prototype.push=function(){for(var a=arguments,b=0;b<a.length;b++)try{if("function"===typeof a[b])a[b]();else{var c="",d=a[b][0],e=d.lastIndexOf(".");0<e&&(c=d.substring(0,e),d=d.substring(e+1));var g=y.ja(c);g[d].apply(g,a[b].slice(1))}}catch(l){console.error(l)}};
|
||||
if(k._top100q&&q(k._top100q)){var Ie=new He;for(k._top100q=k._top100q.reverse();k._top100q.length;)Ie.push(k._top100q.pop());k._top100q=Ie}k._top100q||(k._top100q=new He);Z=Ge.prototype;Z.setAccount=Z.ab;Z.getAccount=Z.wa;Z.trackPageview=Z.U;Z.trackPageviewByLogo=Z.ib;Z.drawLogoTo=Z.sb;Z.setCustomVar=Z.mb;Z.getCustomVar=Z.kb;Z.sendCustomVars=Z.lb;Z.sync=Z.xb;Z.getTop100Id=Z.xa;Z.updateOptions=Z.nb;window._top100||(window._top100={},window._top100.createTracker=y.V,window._top100.getTrackerByName=y.ja,window._top100.getTracker=y.Ja,window._top100.getPubSub=y.Ia,window._top100.loaded=y.loaded,y.isTop100Namespace=y.Fb);})();
|
||||
|
After Width: | Height: | Size: 579 B |
113
F0:F030,F042,F072/Socket_fans/main.c
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* main.c
|
||||
*
|
||||
* Copyright 2017 Edward V. Emelianoff <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 "flash.h"
|
||||
#include "hardware.h"
|
||||
#include "monitor.h"
|
||||
#include "proto.h"
|
||||
#include "usb.h"
|
||||
#include "usb_lib.h"
|
||||
|
||||
volatile uint32_t Tms = 0;
|
||||
|
||||
volatile uint32_t Coolerspeed[2]; // RPM of cooler0/1
|
||||
|
||||
/* Called when systick fires */
|
||||
void sys_tick_handler(void){
|
||||
static uint32_t actr = 0;
|
||||
++Tms;
|
||||
if(++actr == 1000){ // RPM counter
|
||||
Coolerspeed[0] = TIM3->CNT/2;
|
||||
TIM3->CNT = 0;
|
||||
Coolerspeed[1] = Cooler1RPM/2;
|
||||
Cooler1RPM = 0;
|
||||
actr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#define USBBUF 63
|
||||
// usb getline
|
||||
static char *get_USB(){
|
||||
static char tmpbuf[USBBUF+1], *curptr = tmpbuf;
|
||||
static int rest = USBBUF;
|
||||
uint8_t x = USB_receive((uint8_t*)curptr);
|
||||
if(!x) return NULL;
|
||||
curptr[x] = 0;
|
||||
if(x == 1 && *curptr == 0x7f){ // backspace
|
||||
if(curptr > tmpbuf){
|
||||
--curptr;
|
||||
USND("\b \b");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
USB_sendstr(curptr); // echo
|
||||
if(curptr[x-1] == '\n'){ // || curptr[x-1] == '\r'){
|
||||
curptr = tmpbuf;
|
||||
rest = USBBUF;
|
||||
// omit empty lines
|
||||
if(tmpbuf[0] == '\n') return NULL;
|
||||
// and wrong empty lines
|
||||
if(tmpbuf[0] == '\r' && tmpbuf[1] == '\n') return NULL;
|
||||
return tmpbuf;
|
||||
}
|
||||
curptr += x; rest -= x;
|
||||
if(rest <= 0){ // buffer overflow
|
||||
curptr = tmpbuf;
|
||||
rest = USBBUF;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(void){
|
||||
uint32_t lastT = 0, lastTmon = 0;
|
||||
char *txt;
|
||||
sysreset();
|
||||
SysTick_Config(6000, 1);
|
||||
flashstorage_init();
|
||||
HW_setup();
|
||||
USB_setup();
|
||||
RCC->CSR |= RCC_CSR_RMVF; // remove reset flags
|
||||
iwdg_setup();
|
||||
|
||||
ON(COOLER0); // turn on power, manage only by PWM
|
||||
ON(COOLER1);
|
||||
|
||||
while (1){
|
||||
IWDG->KR = IWDG_REFRESH; // refresh watchdog
|
||||
if(Tms - lastT > MONITOR_PERIOD){
|
||||
process_monitor();
|
||||
lastT = Tms;
|
||||
}
|
||||
if(showMon && Tms - lastTmon > 4999){
|
||||
showState();
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
lastTmon = Tms;
|
||||
}
|
||||
usb_proc();
|
||||
if((txt = get_USB())){
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
cmd_parser(txt);
|
||||
}
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
buzzer_chk();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
203
F0:F030,F042,F072/Socket_fans/monitor.c
Normal file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* This file is part of the SockFans project.
|
||||
* Copyright 2020 Edward V. Emelianov <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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "adc.h"
|
||||
#include "flash.h"
|
||||
#include "monitor.h"
|
||||
#include "proto.h"
|
||||
|
||||
// when critical T reached wait for TturnOff ms and after that turn off system
|
||||
#define TturnOff the_conf.Tturnoff
|
||||
// don't mind when button 2 pressed again after t<5s
|
||||
#define TbtnPressed (5000)
|
||||
|
||||
// settings
|
||||
// T0 - CPU, T1 - HDD, T2 - inner T, T3 - power source
|
||||
#define Thysteresis (int16_t)the_conf.Thyst
|
||||
#define tmin the_conf.Tmin
|
||||
#define tmax the_conf.Tmax
|
||||
#define t3max the_conf.Tmax[TMAXNO-1]
|
||||
|
||||
static uint8_t dontprocess = 0; // don't process monitor
|
||||
static uint32_t TOff = 0; // time to turn off power
|
||||
|
||||
static void chkOffRelay(){
|
||||
static uint32_t scntr = 0;
|
||||
if(!TOff){ // warning cleared
|
||||
scntr = 0;
|
||||
return;
|
||||
}
|
||||
if(Tms > TOff){
|
||||
TOff = 0;
|
||||
OFF(RELAY);
|
||||
//TIM1->CCR1 = 0; TIM1->CCR2 = 0; TIM1->CCR3 = 0;
|
||||
//dontprocess = 1;
|
||||
SEND("POWEROFF");
|
||||
buzzer = BUZZER_OFF;
|
||||
scntr = 0;
|
||||
}else{
|
||||
SEND("TCRITSHUTDOWN");
|
||||
printu(++scntr);
|
||||
}
|
||||
NL();
|
||||
}
|
||||
static void startOff(){
|
||||
SEND("TCRITSHUTDOWN0"); NL();
|
||||
TOff = Tms + TturnOff;
|
||||
if(TOff == 0) TOff = 1;
|
||||
buzzer = BUZZER_ON;
|
||||
}
|
||||
|
||||
void SetDontProcess(uint8_t newstate){ // set dontprocess value
|
||||
dontprocess = newstate;
|
||||
}
|
||||
uint8_t GetDontProcess(){ // get dontprocess value
|
||||
return dontprocess;
|
||||
}
|
||||
|
||||
|
||||
// check buttons state
|
||||
static void chkButtons(){
|
||||
static uint32_t Tpressed = 0;
|
||||
if(CHK(BUTTON0) == 0){ // button 0 pressed - turn on power if was off
|
||||
if(CHK(RELAY) == 0){
|
||||
ON(RELAY);
|
||||
SEND("POWERON"); NL();
|
||||
}
|
||||
dontprocess = 0;
|
||||
}
|
||||
if(CHK(BUTTON1) == 0){ // button 1 - all OFF
|
||||
if(Tpressed){ // already pressed recently
|
||||
if(Tms - Tpressed < TbtnPressed) return;
|
||||
}
|
||||
Tpressed = Tms;
|
||||
if(Tpressed == 0) Tpressed = 1;
|
||||
buzzer = BUZZER_OFF;
|
||||
TIM1->CCR1 = 0; TIM1->CCR2 = 0; TIM1->CCR3 = 0;
|
||||
OFF(RELAY);
|
||||
dontprocess = 1;
|
||||
SEND("POWEROFF"); NL();
|
||||
}else Tpressed = 0;
|
||||
}
|
||||
|
||||
// maximum value of coolerproblem counter
|
||||
#define MAXCOOLERPROBLEM (10)
|
||||
|
||||
// monitor temperatures and do something
|
||||
void process_monitor(){
|
||||
chkButtons();
|
||||
if(dontprocess) return;
|
||||
int16_t T;
|
||||
static uint8_t coolerproblem[2] = {0,0}; // cooler don't run
|
||||
static uint8_t offreason[4] = {0}; // whos T was critical for turning power off
|
||||
// check all 4 temperatures
|
||||
// T0..1 - coolers
|
||||
for(int x = 0; x < 2; ++x){
|
||||
T = getNTC(x);
|
||||
volatile uint32_t *ccr = (x == 0) ? &TIM1->CCR1 : &TIM1->CCR2;
|
||||
uint32_t RPM = *ccr;
|
||||
uint32_t speed = Coolerspeed[x];
|
||||
if(T < tmin[x] - Thysteresis){ // turn off fan
|
||||
*ccr = 0;
|
||||
}else if(T > tmax[x] + Thysteresis){
|
||||
gett('0'+x); NL();
|
||||
if(!TOff){
|
||||
offreason[x] = 1;
|
||||
startOff();
|
||||
*ccr = 100;
|
||||
}
|
||||
}else{
|
||||
offreason[x] = 0;
|
||||
// check working fan
|
||||
int chk = (x==0) ? CHK(COOLER0) : CHK(COOLER1);
|
||||
if(chk){ // fan is working, check RPM
|
||||
if(RPM && (speed == 0)){
|
||||
if(coolerproblem[x] > MAXCOOLERPROBLEM){
|
||||
buzzer = BUZZER_SHORT;
|
||||
SEND("COOLER"); bufputchar('0'+x); SEND("DEAD");NL();
|
||||
}else ++coolerproblem[x];
|
||||
}else if(coolerproblem[x]){
|
||||
buzzer = BUZZER_OFF;
|
||||
coolerproblem[x] = 0;
|
||||
SEND("COOLER"); bufputchar('0'+x); SEND("OK");NL();
|
||||
}
|
||||
}else{ // turn on fan
|
||||
if(x==0) ON(COOLER0);
|
||||
else ON(COOLER1);
|
||||
}
|
||||
if(T > tmin[x] && T < tmax[x]){ // T between tmin and tmax
|
||||
int32_t tx = 80*(T - tmin[x]);
|
||||
tx /= (tmax[x] - tmin[x]);
|
||||
uint32_t pwm = 20 + tx;
|
||||
if(pwm < 20) pwm = 20;
|
||||
else if(pwm > 100) pwm = 100;
|
||||
*ccr = pwm;
|
||||
}
|
||||
}
|
||||
}
|
||||
// T2 - not controlled cooler
|
||||
T = getNTC(2);
|
||||
if(T < tmin[2] - Thysteresis){ // turn off fan
|
||||
TIM1->CCR3 = 0;
|
||||
}else if(T > tmax[2] + Thysteresis){
|
||||
gett('2'); NL();
|
||||
if(!TOff){
|
||||
offreason[2] = 1;
|
||||
startOff();
|
||||
TIM1->CCR3 = 100;
|
||||
}
|
||||
}else{ // T between tmin and tmax
|
||||
offreason[2] = 0;
|
||||
if(T > tmin[2] && T < tmax[2]){
|
||||
int32_t tx = 60*(T - tmin[2]);
|
||||
tx /= (tmax[2] - tmin[2]);
|
||||
uint32_t pwm = 40 + tx;
|
||||
if(pwm < 40) pwm = 40;
|
||||
else if(pwm > 100) pwm = 100;
|
||||
TIM1->CCR3 = pwm;
|
||||
}
|
||||
}
|
||||
// T3 - turn off power after TturnOff
|
||||
if(getNTC(3) > t3max){
|
||||
gett('3'); NL();
|
||||
// all coolers to max value
|
||||
TIM1->CCR1 = 100;
|
||||
TIM1->CCR2 = 100;
|
||||
TIM1->CCR3 = 100;
|
||||
ON(COOLER0); ON(COOLER1);
|
||||
if(!TOff){
|
||||
offreason[3] = 1;
|
||||
startOff();
|
||||
}
|
||||
}else offreason[3] = 0;
|
||||
// check offreason
|
||||
if(TOff){
|
||||
uint8_t stillbad = 0;
|
||||
for(int x = 0; x < 4; ++x)
|
||||
if(offreason[x]){
|
||||
stillbad = 1;
|
||||
break;
|
||||
}
|
||||
if(!stillbad){
|
||||
SEND("CLRPANIC");NL();
|
||||
TOff = 0;
|
||||
buzzer = BUZZER_OFF;
|
||||
}
|
||||
chkOffRelay();
|
||||
}
|
||||
}
|
||||
31
F0:F030,F042,F072/Socket_fans/monitor.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* This file is part of the SockFans project.
|
||||
* Copyright 2020 Edward V. Emelianov <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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef MONITOR_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// run monitor each 1s
|
||||
#define MONITOR_PERIOD (999)
|
||||
|
||||
void process_monitor();
|
||||
void SetDontProcess(uint8_t newstate);
|
||||
uint8_t GetDontProcess();
|
||||
#define MONITOR_H__
|
||||
#endif // MONITOR_H__
|
||||
587
F0:F030,F042,F072/Socket_fans/proto.c
Normal file
@@ -0,0 +1,587 @@
|
||||
/*
|
||||
* geany_encoding=koi8-r
|
||||
* proto.c
|
||||
*
|
||||
* Copyright 2018 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 "adc.h"
|
||||
#include "flash.h"
|
||||
#include "hardware.h"
|
||||
#include "monitor.h"
|
||||
#include "proto.h"
|
||||
#include "usb.h"
|
||||
|
||||
#include <string.h> // strlen
|
||||
|
||||
|
||||
uint8_t showMon = 0; // start monitoring @ each 5s
|
||||
|
||||
static char buff[BUFSZ+1], *bptr = buff;
|
||||
static uint8_t blen = 0;
|
||||
|
||||
void sendbuf(){
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
if(blen == 0) return;
|
||||
*bptr = 0;
|
||||
USB_sendstr(buff);
|
||||
bptr = buff;
|
||||
blen = 0;
|
||||
}
|
||||
|
||||
void bufputchar(char ch){
|
||||
if(blen > BUFSZ-1){
|
||||
sendbuf();
|
||||
}
|
||||
*bptr++ = ch;
|
||||
++blen;
|
||||
}
|
||||
|
||||
void addtobuf(const char *txt){
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
while(*txt) bufputchar(*txt++);
|
||||
}
|
||||
|
||||
char *omit_spaces(char *buf){
|
||||
while(*buf){
|
||||
if(*buf > ' ') break;
|
||||
++buf;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
// THERE'S NO OVERFLOW PROTECTION IN NUMBER READ PROCEDURES!
|
||||
// read decimal number
|
||||
static char *getdec(char *buf, uint32_t *N){
|
||||
uint32_t num = 0;
|
||||
while(*buf){
|
||||
char c = *buf;
|
||||
if(c < '0' || c > '9'){
|
||||
break;
|
||||
}
|
||||
num *= 10;
|
||||
num += c - '0';
|
||||
++buf;
|
||||
}
|
||||
*N = num;
|
||||
return buf;
|
||||
}
|
||||
// read hexadecimal number (without 0x prefix!)
|
||||
static char *gethex(char *buf, uint32_t *N){
|
||||
uint32_t num = 0;
|
||||
while(*buf){
|
||||
char c = *buf;
|
||||
uint8_t M = 0;
|
||||
if(c >= '0' && c <= '9'){
|
||||
M = '0';
|
||||
}else if(c >= 'A' && c <= 'F'){
|
||||
M = 'A' - 10;
|
||||
}else if(c >= 'a' && c <= 'f'){
|
||||
M = 'a' - 10;
|
||||
}
|
||||
if(M){
|
||||
num <<= 4;
|
||||
num += c - M;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
++buf;
|
||||
}
|
||||
*N = num;
|
||||
return buf;
|
||||
}
|
||||
// read binary number (without 0b prefix!)
|
||||
static char *getbin(char *buf, uint32_t *N){
|
||||
uint32_t num = 0;
|
||||
while(*buf){
|
||||
char c = *buf;
|
||||
if(c < '0' || c > '1'){
|
||||
break;
|
||||
}
|
||||
num <<= 1;
|
||||
if(c == '1') num |= 1;
|
||||
++buf;
|
||||
}
|
||||
*N = num;
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief getnum - read uint32_t from string (dec, hex or bin: 127, 0x7f, 0b1111111)
|
||||
* @param buf - buffer with number and so on
|
||||
* @param N - the number read
|
||||
* @return pointer to first non-number symbol in buf (if it is == buf, there's no number)
|
||||
*/
|
||||
char *getnum(char *txt, uint32_t *N){
|
||||
if(*txt == '0'){
|
||||
if(txt[1] == 'x' || txt[1] == 'X') return gethex(txt+2, N);
|
||||
if(txt[1] == 'b' || txt[1] == 'B') return getbin(txt+2, N);
|
||||
}
|
||||
return getdec(txt, N);
|
||||
}
|
||||
|
||||
// change pin state
|
||||
static void onoff(char state, GPIO_TypeDef *port, uint32_t pin, char *text){
|
||||
switch(state){
|
||||
case '0': // off
|
||||
pin_clear(port, pin);
|
||||
break;
|
||||
case '1': // on
|
||||
pin_set(port, pin);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SEND(text);
|
||||
bufputchar('=');
|
||||
bufputchar('0' + pin_read(port, pin));
|
||||
}
|
||||
|
||||
// get raw ADC value of channel chno + '0'
|
||||
static inline void ADCget(char chno){
|
||||
if(chno < '0' || chno > '7'){
|
||||
SEND("Channel number shoul be from 0 to 7");
|
||||
return;
|
||||
}
|
||||
int nch = chno - '0';
|
||||
SEND("ADCVAL");
|
||||
bufputchar(chno);
|
||||
bufputchar('=');
|
||||
printu(getADCval(nch));
|
||||
}
|
||||
|
||||
// get coolerx RPS
|
||||
static inline void coolerRPS(char n){
|
||||
if(n < '0' || n > '1'){
|
||||
SEND("Cooler number should be 0 or 1");
|
||||
return;
|
||||
}
|
||||
SEND("RPS");
|
||||
bufputchar(n);
|
||||
bufputchar('=');
|
||||
printu(Coolerspeed[n - '0']);
|
||||
}
|
||||
|
||||
static inline void getPWM(char n){
|
||||
if(n < '0' || n > '2'){
|
||||
SEND("Cooler number should be from 0 to 2");
|
||||
return;
|
||||
}
|
||||
SEND("PWM");
|
||||
bufputchar(n);
|
||||
bufputchar('=');
|
||||
uint32_t pwm;
|
||||
switch(n){
|
||||
case '0':
|
||||
pwm = TIM1->CCR1;
|
||||
break;
|
||||
case '1':
|
||||
pwm = TIM1->CCR2;
|
||||
break;
|
||||
default:
|
||||
pwm = TIM1->CCR3;
|
||||
}
|
||||
printu(pwm);
|
||||
}
|
||||
|
||||
// change Coolerx PWM
|
||||
static inline void changePWM(char *str){
|
||||
char channel = *str++;
|
||||
str = omit_spaces(str);
|
||||
uint32_t rpm;
|
||||
getnum(str, &rpm);
|
||||
if(rpm > 100){
|
||||
SEND("PWM should be from 0 to 100%");
|
||||
return;
|
||||
}
|
||||
switch(channel){
|
||||
case '0':
|
||||
TIM1->CCR1 = rpm;
|
||||
break;
|
||||
case '1':
|
||||
TIM1->CCR2 = rpm;
|
||||
break;
|
||||
case '2':
|
||||
TIM1->CCR3 = rpm;
|
||||
break;
|
||||
default:
|
||||
SEND("Cooler number should be from 0 to 2");
|
||||
}
|
||||
}
|
||||
|
||||
static inline void buzzercmd(char cmd){
|
||||
SEND("BUZZER=");
|
||||
switch(cmd){
|
||||
case '0':
|
||||
buzzer = BUZZER_OFF;
|
||||
SEND("OFF");
|
||||
break;
|
||||
case '1':
|
||||
buzzer = BUZZER_ON;
|
||||
SEND("ON");
|
||||
break;
|
||||
case 'l':
|
||||
buzzer = BUZZER_LONG;
|
||||
SEND("LONG");
|
||||
break;
|
||||
case 's':
|
||||
buzzer = BUZZER_SHORT;
|
||||
SEND("SHORT");
|
||||
break;
|
||||
default:
|
||||
SEND("BADSTATE");
|
||||
}
|
||||
}
|
||||
|
||||
void gett(char chno){
|
||||
if(chno < '0' || chno > '3'){
|
||||
SEND("Temperature channel should be 0..3");
|
||||
return;
|
||||
}
|
||||
bufputchar('T'); bufputchar(chno); bufputchar('=');
|
||||
printi(getNTC(chno - '0'));
|
||||
}
|
||||
|
||||
static inline void chkButtons(){
|
||||
SEND("BUTTON0=");
|
||||
bufputchar('1' - CHK(BUTTON0)); // buttons are inverted
|
||||
SEND("\nBUTTON1=");
|
||||
bufputchar('1' - CHK(BUTTON1));
|
||||
}
|
||||
|
||||
// show current device state: T, RPM, PWM, relay
|
||||
void showState(){
|
||||
SEND("TIME=");
|
||||
printu(Tms);
|
||||
newline();
|
||||
for(char x = '0'; x < '4'; ++x){
|
||||
gett(x);
|
||||
newline();
|
||||
}
|
||||
SEND("BUZZER=");
|
||||
switch(buzzer){
|
||||
case BUZZER_ON:
|
||||
SEND("ON");
|
||||
break;
|
||||
case BUZZER_OFF:
|
||||
SEND("OFF");
|
||||
break;
|
||||
case BUZZER_SHORT:
|
||||
SEND("SHORT");
|
||||
break;
|
||||
case BUZZER_LONG:
|
||||
SEND("LONG");
|
||||
break;
|
||||
}
|
||||
newline();
|
||||
chkButtons();
|
||||
newline();
|
||||
coolerRPS('0');
|
||||
newline();
|
||||
coolerRPS('1');
|
||||
newline();
|
||||
for(char x = '0'; x < '3'; ++x){
|
||||
getPWM(x);
|
||||
newline();
|
||||
}
|
||||
onoff('c', COOLER0_port, COOLER0_pin, "COOLER0");
|
||||
newline();
|
||||
onoff('c', COOLER1_port, COOLER1_pin, "COOLER1");
|
||||
newline();
|
||||
onoff('c', RELAY_port, RELAY_pin, "RELAY");
|
||||
NL();
|
||||
}
|
||||
|
||||
static uint8_t userconf_changed = 0; // ==1 if user_conf was changed
|
||||
static const char *nshould = "N should be from 0 to ";
|
||||
static const char *changed = "Changed OK\n";
|
||||
static const char *notchanged = "Not changed: the same value\n";
|
||||
static inline void setArrval(int16_t *arr, uint8_t maxelem, char *params){
|
||||
uint32_t N, val;
|
||||
int16_t sign = 1;
|
||||
char *next = getnum(params, &N);
|
||||
if(N > maxelem){
|
||||
SEND(nshould);
|
||||
printu(maxelem); newline();
|
||||
return;
|
||||
}
|
||||
next = omit_spaces(next);
|
||||
if(*next == '-'){
|
||||
next = omit_spaces(next+1);
|
||||
sign = -1;
|
||||
}
|
||||
char *rest = getnum(next, &val);
|
||||
if(*rest && *rest != '\n'){
|
||||
SEND("Arguments are: N T, where N is channel number, T - temperature\n");
|
||||
return;
|
||||
}
|
||||
sign *= (int16_t)val;
|
||||
if(arr[N] != sign){
|
||||
arr[N] = sign;
|
||||
userconf_changed = 1;
|
||||
SEND(changed);
|
||||
}else SEND(notchanged);
|
||||
}
|
||||
static inline void setval(uint32_t *var, char *params){
|
||||
uint32_t val;
|
||||
char *next = getnum(params, &val);
|
||||
if(*next && *next != '\n'){
|
||||
SEND("Argument is 32-bit number\n");
|
||||
return;
|
||||
}
|
||||
if(*var != val){
|
||||
*var = val;
|
||||
userconf_changed = 1;
|
||||
SEND(changed);
|
||||
}else SEND(notchanged);
|
||||
}
|
||||
static inline void showSettings(){
|
||||
int i;
|
||||
SEND("Tturnoff="); printu(the_conf.Tturnoff); newline();
|
||||
SEND("Thysteresis="); printu(the_conf.Thyst); newline();
|
||||
SEND("Tmin={");
|
||||
for(i = 0; i < TMINNO; ++i){
|
||||
if(i) SEND(", ");
|
||||
printu(the_conf.Tmin[i]);
|
||||
}
|
||||
SEND("}\n");
|
||||
SEND("Tmax={");
|
||||
for(i = 0; i < TMAXNO; ++i){
|
||||
if(i) SEND(", ");
|
||||
printu(the_conf.Tmax[i]);
|
||||
}
|
||||
SEND("}\n");
|
||||
}
|
||||
static inline void setters(char *txt){ // setters
|
||||
txt = omit_spaces(txt);
|
||||
if(!*txt){
|
||||
SEND("Setters need more arguments");
|
||||
return;
|
||||
}
|
||||
char *next = omit_spaces(txt+1);
|
||||
switch(*txt){
|
||||
case '<': // Tmin
|
||||
setArrval(the_conf.Tmin, TMINNO-1, next);
|
||||
break;
|
||||
case '>': // Tmax
|
||||
setArrval(the_conf.Tmax, TMAXNO-1, next);
|
||||
break;
|
||||
case 'H': // Thyst
|
||||
setval(&the_conf.Thyst, next);
|
||||
break;
|
||||
case 'O': // Tturnoff
|
||||
setval(&the_conf.Tturnoff, next);
|
||||
break;
|
||||
case 'S': // save settings
|
||||
if(userconf_changed){
|
||||
if(!store_userconf()){
|
||||
userconf_changed = 0;
|
||||
SEND("Stored!");
|
||||
}else SEND("Error when storing!");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
SEND("Setters:\n"
|
||||
"< N T - set nth (0..2) Tmin (T/10degrC)\n"
|
||||
"> N T - set Tmax\n"
|
||||
"H T - set temperature hysteresis (T/10degrC)\n"
|
||||
"O t - time to turn off after emergency (t in ms)\n"
|
||||
"S - save settings\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief cmd_parser - command parsing
|
||||
* @param txt - buffer with commands & data
|
||||
* @param isUSB - == 1 if data got from USB
|
||||
*/
|
||||
void cmd_parser(char *txt){
|
||||
char _1st = txt[0];
|
||||
/*
|
||||
* parse long commands here
|
||||
*/
|
||||
switch(_1st){
|
||||
case '0': // cooler0: set/clear/check
|
||||
onoff(txt[1], COOLER0_port, COOLER0_pin, "COOLER0");
|
||||
goto eof;
|
||||
break;
|
||||
case '1': // cooler1: set/clear/check
|
||||
onoff(txt[1], COOLER1_port, COOLER1_pin, "COOLER1");
|
||||
goto eof;
|
||||
break;
|
||||
case 'A': // ADC raw values
|
||||
ADCget(txt[1]);
|
||||
goto eof;
|
||||
break;
|
||||
case 'b': // buzzer
|
||||
buzzercmd(txt[1]);
|
||||
goto eof;
|
||||
break;
|
||||
case 'C': // Get real Cooler RPM
|
||||
coolerRPS(txt[1]);
|
||||
goto eof;
|
||||
break;
|
||||
case 'G': // get cooler PWM from settings
|
||||
getPWM(txt[1]);
|
||||
goto eof;
|
||||
break;
|
||||
case 'P': // set PWM
|
||||
changePWM(txt+1);
|
||||
goto eof;
|
||||
break;
|
||||
case 'r': // relay: set/clear/check
|
||||
onoff(txt[1], RELAY_port, RELAY_pin, "RELAY");
|
||||
goto eof;
|
||||
break;
|
||||
case 'S': // setters
|
||||
setters(&txt[1]);
|
||||
goto eof;
|
||||
case 't':
|
||||
gett(txt[1]);
|
||||
goto eof;
|
||||
break;
|
||||
}
|
||||
if(txt[1] != '\n') *txt = '?'; // help for wrong message length
|
||||
switch(_1st){
|
||||
case 'B':
|
||||
chkButtons();
|
||||
break;
|
||||
case 'D':
|
||||
SEND("Go into DFU mode\n");
|
||||
sendbuf();
|
||||
Jump2Boot();
|
||||
break;
|
||||
case 'E':
|
||||
showState();
|
||||
break;
|
||||
case 'M': // MCU temperature
|
||||
SEND("MCUTEMP=");
|
||||
printu(getMCUtemp());
|
||||
break;
|
||||
case 'm': // toggle monitoring
|
||||
showMon = !showMon;
|
||||
SEND("MONITORING=");
|
||||
if(showMon) SEND("on");
|
||||
else SEND("off");
|
||||
break;
|
||||
case 'R':
|
||||
SEND("Soft reset\n");
|
||||
sendbuf();
|
||||
pause_ms(5); // a little pause to transmit data
|
||||
NVIC_SystemReset();
|
||||
break;
|
||||
case 's':
|
||||
showSettings();
|
||||
break;
|
||||
case 'T':
|
||||
SEND("TIME=");
|
||||
printu(Tms);
|
||||
newline();
|
||||
break;
|
||||
case 'V':
|
||||
SEND("V3_3=");
|
||||
printu(getVdd());
|
||||
SEND("\nV5=");
|
||||
printu(getU5());
|
||||
SEND("\nV12=");
|
||||
printu(getU12());
|
||||
break;
|
||||
case 'Z':
|
||||
adc_setup();
|
||||
SEND("ADC restarted\n");
|
||||
break;
|
||||
case '!':
|
||||
SetDontProcess(!GetDontProcess());
|
||||
if(GetDontProcess()) SEND("\n\tManual");
|
||||
else SEND("\n\tAutomatic");
|
||||
SEND(" mode\n");
|
||||
break;
|
||||
default: // help
|
||||
SEND(
|
||||
"'0x' - turn cooler0 on/off (x=1/0) or get status (x - any other)\n"
|
||||
"'1x' - turn cooler1 on/off (x=1/0) or get status (x - any other)\n"
|
||||
"'Ax' - get ADC raw value (x=0..7)\n"
|
||||
"'B' - buttons' state\n"
|
||||
"'bx' - buzzer: x==0 - off, x==1 - on, x==l - long beeps, x==s - short beeps\n"
|
||||
"'Cx' - get cooler x (0/1) RPS\n"
|
||||
"'D' - activate DFU mode\n"
|
||||
"'E' - show current state\n"
|
||||
"'Gx' - get cooler x (0..3) PWM settings\n"
|
||||
"'M' - get MCU temperature\n"
|
||||
"'m' - toggle monitoring\n"
|
||||
"'Px y' - set coolerx PWM to y\n"
|
||||
"'R' - software reset\n"
|
||||
"'rx' - relay on/off (x=1/0) or get status\n"
|
||||
"'S' - setters\n"
|
||||
"'s' - show settings\n"
|
||||
"'T' - get time from start (ms)\n"
|
||||
"'tx' - get temperature x (0..3)\n"
|
||||
"'V' - get voltage\n"
|
||||
"'Z' - reinit ADC\n"
|
||||
"'!' - switch between manual and automatic modes\n"
|
||||
);
|
||||
break;
|
||||
}
|
||||
eof:
|
||||
newline();
|
||||
sendbuf();
|
||||
}
|
||||
|
||||
// print 32bit unsigned int
|
||||
void printu(uint32_t val){
|
||||
char buf[11], *bufptr = &buf[10];
|
||||
*bufptr = 0;
|
||||
if(!val){
|
||||
*(--bufptr) = '0';
|
||||
}else{
|
||||
while(val){
|
||||
*(--bufptr) = val % 10 + '0';
|
||||
val /= 10;
|
||||
}
|
||||
}
|
||||
addtobuf(bufptr);
|
||||
}
|
||||
|
||||
// print 32bit signed int
|
||||
void printi(int32_t val){
|
||||
if(val < 0){
|
||||
val = -val;
|
||||
bufputchar('-');
|
||||
}
|
||||
printu(val);
|
||||
}
|
||||
|
||||
// print 32bit unsigned int as hex
|
||||
void printuhex(uint32_t val){
|
||||
addtobuf("0x");
|
||||
uint8_t *ptr = (uint8_t*)&val + 3;
|
||||
int8_t i, j, z=1;
|
||||
for(i = 0; i < 4; ++i, --ptr){
|
||||
if(*ptr == 0){ // omit leading zeros
|
||||
if(i == 3) z = 0;
|
||||
if(z) continue;
|
||||
}
|
||||
else z = 0;
|
||||
for(j = 1; j > -1; --j){
|
||||
uint8_t half = (*ptr >> (4*j)) & 0x0f;
|
||||
if(half < 10) bufputchar(half + '0');
|
||||
else bufputchar(half - 10 + 'a');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
60
F0:F030,F042,F072/Socket_fans/proto.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* geany_encoding=koi8-r
|
||||
* proto.h
|
||||
*
|
||||
* Copyright 2018 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.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef __PROTO_H__
|
||||
#define __PROTO_H__
|
||||
|
||||
#include "stm32f0.h"
|
||||
#include "hardware.h"
|
||||
|
||||
#define BUFSZ (64)
|
||||
|
||||
// macro for static strings
|
||||
#define SEND(str) do{addtobuf(str);}while(0)
|
||||
|
||||
#ifdef EBUG
|
||||
#define MSG(str) do{addtobuf(__FILE__ " (L" STR(__LINE__) "): " str);}while(0)
|
||||
#else
|
||||
#define MSG(str)
|
||||
#endif
|
||||
|
||||
#define newline() do{bufputchar('\n');}while(0)
|
||||
// newline with buffer sending
|
||||
#define NL() do{bufputchar('\n'); sendbuf();}while(0)
|
||||
|
||||
extern uint8_t showMon;
|
||||
|
||||
void cmd_parser(char *buf);
|
||||
void addtobuf(const char *txt);
|
||||
void bufputchar(char ch);
|
||||
void gett(char chno);
|
||||
void printu(uint32_t val);
|
||||
void printi(int32_t val);
|
||||
void printuhex(uint32_t val);
|
||||
void sendbuf();
|
||||
void showState();
|
||||
|
||||
char *omit_spaces(char *buf);
|
||||
char *getnum(char *buf, uint32_t *N);
|
||||
|
||||
#endif // __PROTO_H__
|
||||
BIN
F0:F030,F042,F072/Socket_fans/sockfans.bin
Normal file
180
F0:F030,F042,F072/Socket_fans/usb.c
Normal file
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* geany_encoding=koi8-r
|
||||
* usb.c - base functions for different USB types
|
||||
*
|
||||
* Copyright 2018 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 "usb.h"
|
||||
#include "usb_lib.h"
|
||||
|
||||
static volatile uint8_t tx_succesfull = 1;
|
||||
static volatile uint8_t rxNE = 0;
|
||||
|
||||
// interrupt IN handler (never used?)
|
||||
static void EP1_Handler(){
|
||||
uint16_t epstatus = KEEP_DTOG(USB->EPnR[1]);
|
||||
if(RX_FLAG(epstatus)) epstatus = (epstatus & ~USB_EPnR_STAT_TX) ^ USB_EPnR_STAT_RX; // set valid RX
|
||||
else epstatus = epstatus & ~(USB_EPnR_STAT_TX|USB_EPnR_STAT_RX);
|
||||
// clear CTR
|
||||
epstatus = (epstatus & ~(USB_EPnR_CTR_RX|USB_EPnR_CTR_TX));
|
||||
USB->EPnR[1] = epstatus;
|
||||
}
|
||||
|
||||
// data IN/OUT handlers
|
||||
static void transmit_Handler(){ // EP3IN
|
||||
tx_succesfull = 1;
|
||||
uint16_t epstatus = KEEP_DTOG_STAT(USB->EPnR[3]);
|
||||
// clear CTR keep DTOGs & STATs
|
||||
USB->EPnR[3] = (epstatus & ~(USB_EPnR_CTR_TX)); // clear TX ctr
|
||||
}
|
||||
|
||||
static void receive_Handler(){ // EP2OUT
|
||||
rxNE = 1;
|
||||
uint16_t epstatus = KEEP_DTOG_STAT(USB->EPnR[2]);
|
||||
USB->EPnR[2] = (epstatus & ~(USB_EPnR_CTR_RX)); // clear RX ctr
|
||||
}
|
||||
|
||||
void USB_setup(){
|
||||
RCC->APB1ENR |= RCC_APB1ENR_CRSEN | RCC_APB1ENR_USBEN; // enable CRS (hsi48 sync) & USB
|
||||
RCC->CFGR3 &= ~RCC_CFGR3_USBSW; // reset USB
|
||||
RCC->CR2 |= RCC_CR2_HSI48ON; // turn ON HSI48
|
||||
uint32_t tmout = 16000000;
|
||||
while(!(RCC->CR2 & RCC_CR2_HSI48RDY)){if(--tmout == 0) break;}
|
||||
FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY;
|
||||
CRS->CFGR &= ~CRS_CFGR_SYNCSRC;
|
||||
CRS->CFGR |= CRS_CFGR_SYNCSRC_1; // USB SOF selected as sync source
|
||||
CRS->CR |= CRS_CR_AUTOTRIMEN; // enable auto trim
|
||||
CRS->CR |= CRS_CR_CEN; // enable freq counter & block CRS->CFGR as read-only
|
||||
RCC->CFGR |= RCC_CFGR_SW;
|
||||
// allow RESET and CTRM interrupts
|
||||
USB->CNTR = USB_CNTR_RESETM | USB_CNTR_WKUPM;
|
||||
// clear flags
|
||||
USB->ISTR = 0;
|
||||
// and activate pullup
|
||||
USB->BCDR |= USB_BCDR_DPPU;
|
||||
NVIC_EnableIRQ(USB_IRQn);
|
||||
}
|
||||
|
||||
|
||||
static int usbwr(const uint8_t *buf, uint16_t l){
|
||||
uint32_t ctra = 1000000;
|
||||
while(--ctra && tx_succesfull == 0){
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
}
|
||||
tx_succesfull = 0;
|
||||
EP_Write(3, buf, l);
|
||||
ctra = 1000000;
|
||||
while(--ctra && tx_succesfull == 0){
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
}
|
||||
if(tx_succesfull == 0){usbON = 0; return 1;} // usb is OFF?
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t usbbuff[USB_TXBUFSZ-1]; // temporary buffer (63 - to prevent need of ZLP)
|
||||
static uint8_t buflen = 0; // amount of symbols in usbbuff
|
||||
|
||||
// send next up to 63 bytes of data in usbbuff
|
||||
static void send_next(){
|
||||
if(!buflen || !tx_succesfull) return;
|
||||
tx_succesfull = 0;
|
||||
EP_Write(3, usbbuff, buflen);
|
||||
buflen = 0;
|
||||
}
|
||||
|
||||
// unblocking sending - just fill a buffer
|
||||
void USB_send(const uint8_t *buf, uint16_t len){
|
||||
if(!usbON || !len) return;
|
||||
if(len > USB_TXBUFSZ-1 - buflen){
|
||||
usbwr(usbbuff, buflen);
|
||||
buflen = 0;
|
||||
}
|
||||
if(len > USB_TXBUFSZ-1){
|
||||
USB_send_blk(buf, len);
|
||||
return;
|
||||
}
|
||||
while(len--) usbbuff[buflen++] = *buf++;
|
||||
}
|
||||
|
||||
// send zero-terminated string
|
||||
void USB_sendstr(const char *str){
|
||||
uint16_t l = 0;
|
||||
const char *ptr = str;
|
||||
while(*ptr++) ++l;
|
||||
USB_send((uint8_t*)str, l);
|
||||
}
|
||||
|
||||
// blocking sending
|
||||
void USB_send_blk(const uint8_t *buf, uint16_t len){
|
||||
if(!usbON || !len) return; // USB disconnected
|
||||
if(buflen){
|
||||
usbwr(usbbuff, buflen);
|
||||
buflen = 0;
|
||||
}
|
||||
int needzlp = 0;
|
||||
while(len){
|
||||
if(len == USB_TXBUFSZ) needzlp = 1;
|
||||
uint16_t s = (len > USB_TXBUFSZ) ? USB_TXBUFSZ : len;
|
||||
if(usbwr(buf, s)) return;
|
||||
len -= s;
|
||||
buf += s;
|
||||
}
|
||||
if(needzlp){
|
||||
usbwr(NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void usb_proc(){
|
||||
switch(USB_Dev.USB_Status){
|
||||
case USB_STATE_CONFIGURED:
|
||||
// make new BULK endpoint
|
||||
// Buffer have 1024 bytes, but last 256 we use for CAN bus (30.2 of RM: USB main features)
|
||||
EP_Init(1, EP_TYPE_INTERRUPT, USB_EP1BUFSZ, 0, EP1_Handler); // IN1 - transmit
|
||||
EP_Init(2, EP_TYPE_BULK, 0, USB_RXBUFSZ, receive_Handler); // OUT2 - receive data
|
||||
EP_Init(3, EP_TYPE_BULK, USB_TXBUFSZ, 0, transmit_Handler); // IN3 - transmit data
|
||||
USB_Dev.USB_Status = USB_STATE_CONNECTED;
|
||||
break;
|
||||
case USB_STATE_DEFAULT:
|
||||
case USB_STATE_ADDRESSED:
|
||||
if(usbON){
|
||||
usbON = 0;
|
||||
}
|
||||
break;
|
||||
default: // USB_STATE_CONNECTED - send next data portion
|
||||
if(!usbON) return;
|
||||
send_next();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USB_receive
|
||||
* @param buf (i) - buffer[64] for received data
|
||||
* @return amount of received bytes
|
||||
*/
|
||||
uint8_t USB_receive(uint8_t *buf){
|
||||
if(!usbON || !rxNE) return 0;
|
||||
uint8_t sz = EP_Read(2, buf);
|
||||
uint16_t epstatus = KEEP_DTOG(USB->EPnR[2]);
|
||||
// keep stat_tx & set ACK rx
|
||||
USB->EPnR[2] = (epstatus & ~(USB_EPnR_STAT_TX)) ^ USB_EPnR_STAT_RX;
|
||||
rxNE = 0;
|
||||
return sz;
|
||||
}
|
||||
|
||||
41
F0:F030,F042,F072/Socket_fans/usb.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* geany_encoding=koi8-r
|
||||
* usb.h
|
||||
*
|
||||
* Copyright 2018 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.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef __USB_H__
|
||||
#define __USB_H__
|
||||
|
||||
#include "hardware.h"
|
||||
|
||||
#define BUFFSIZE (64)
|
||||
|
||||
// send string with constant length
|
||||
#define USND(str) do{USB_send((uint8_t*)str, sizeof(str)-1);}while(0)
|
||||
|
||||
void USB_setup();
|
||||
void usb_proc();
|
||||
void USB_send(const uint8_t *buf, uint16_t len);
|
||||
void USB_sendstr(const char *str);
|
||||
void USB_send_blk(const uint8_t *buf, uint16_t len);
|
||||
uint8_t USB_receive(uint8_t *buf);
|
||||
|
||||
#endif // __USB_H__
|
||||
104
F0:F030,F042,F072/Socket_fans/usb_defs.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* geany_encoding=koi8-r
|
||||
* usb_defs.h
|
||||
*
|
||||
* Copyright 2018 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef __USB_DEFS_H__
|
||||
#define __USB_DEFS_H__
|
||||
|
||||
#include <stm32f0.h>
|
||||
|
||||
// max endpoints number
|
||||
#define STM32ENDPOINTS 8
|
||||
/**
|
||||
* Buffers size definition
|
||||
**/
|
||||
// !!! when working with CAN bus change USB_BTABLE_SIZE to 768 !!!
|
||||
#define USB_BTABLE_SIZE 768
|
||||
// for USB FS EP0 buffers are from 8 to 64 bytes long (64 for PL2303)
|
||||
#define USB_EP0_BUFSZ 64
|
||||
// USB transmit buffer size (64 for PL2303)
|
||||
#define USB_TXBUFSZ 64
|
||||
// USB receive buffer size (64 for PL2303)
|
||||
#define USB_RXBUFSZ 64
|
||||
// EP1 - interrupt - buffer size
|
||||
#define USB_EP1BUFSZ 8
|
||||
|
||||
#define USB_BTABLE_BASE 0x40006000
|
||||
|
||||
#ifdef USB_BTABLE
|
||||
#undef USB_BTABLE
|
||||
#endif
|
||||
#define USB_BTABLE ((USB_BtableDef *)(USB_BTABLE_BASE))
|
||||
#define USB_ISTR_EPID 0x0000000F
|
||||
#define USB_FNR_LSOF_0 0x00000800
|
||||
#define USB_FNR_lSOF_1 0x00001000
|
||||
#define USB_LPMCSR_BESL_0 0x00000010
|
||||
#define USB_LPMCSR_BESL_1 0x00000020
|
||||
#define USB_LPMCSR_BESL_2 0x00000040
|
||||
#define USB_LPMCSR_BESL_3 0x00000080
|
||||
#define USB_EPnR_CTR_RX 0x00008000
|
||||
#define USB_EPnR_DTOG_RX 0x00004000
|
||||
#define USB_EPnR_STAT_RX 0x00003000
|
||||
#define USB_EPnR_STAT_RX_0 0x00001000
|
||||
#define USB_EPnR_STAT_RX_1 0x00002000
|
||||
#define USB_EPnR_SETUP 0x00000800
|
||||
#define USB_EPnR_EP_TYPE 0x00000600
|
||||
#define USB_EPnR_EP_TYPE_0 0x00000200
|
||||
#define USB_EPnR_EP_TYPE_1 0x00000400
|
||||
#define USB_EPnR_EP_KIND 0x00000100
|
||||
#define USB_EPnR_CTR_TX 0x00000080
|
||||
#define USB_EPnR_DTOG_TX 0x00000040
|
||||
#define USB_EPnR_STAT_TX 0x00000030
|
||||
#define USB_EPnR_STAT_TX_0 0x00000010
|
||||
#define USB_EPnR_STAT_TX_1 0x00000020
|
||||
#define USB_EPnR_EA 0x0000000F
|
||||
#define USB_COUNTn_RX_BLSIZE 0x00008000
|
||||
#define USB_COUNTn_NUM_BLOCK 0x00007C00
|
||||
#define USB_COUNTn_RX 0x0000003F
|
||||
|
||||
#define USB_TypeDef USB_TypeDef_custom
|
||||
|
||||
typedef struct{
|
||||
__IO uint32_t EPnR[STM32ENDPOINTS];
|
||||
__IO uint32_t RESERVED[STM32ENDPOINTS];
|
||||
__IO uint32_t CNTR;
|
||||
__IO uint32_t ISTR;
|
||||
__IO uint32_t FNR;
|
||||
__IO uint32_t DADDR;
|
||||
__IO uint32_t BTABLE;
|
||||
__IO uint32_t LPMCSR;
|
||||
__IO uint32_t BCDR;
|
||||
} USB_TypeDef;
|
||||
|
||||
typedef struct{
|
||||
__IO uint16_t USB_ADDR_TX;
|
||||
__IO uint16_t USB_COUNT_TX;
|
||||
__IO uint16_t USB_ADDR_RX;
|
||||
__IO uint16_t USB_COUNT_RX;
|
||||
} USB_EPDATA_TypeDef;
|
||||
|
||||
typedef struct{
|
||||
__IO USB_EPDATA_TypeDef EP[STM32ENDPOINTS];
|
||||
} USB_BtableDef;
|
||||
|
||||
#endif // __USB_DEFS_H__
|
||||
473
F0:F030,F042,F072/Socket_fans/usb_lib.c
Normal file
@@ -0,0 +1,473 @@
|
||||
/*
|
||||
* geany_encoding=koi8-r
|
||||
* usb_lib.c
|
||||
*
|
||||
* Copyright 2018 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 <stdint.h>
|
||||
#include "usb_lib.h"
|
||||
|
||||
ep_t endpoints[STM32ENDPOINTS];
|
||||
|
||||
usb_dev_t USB_Dev;
|
||||
uint8_t usbON = 0;
|
||||
static usb_LineCoding lineCoding = {115200, 0, 0, 8};
|
||||
static config_pack_t setup_packet;
|
||||
static uint8_t ep0databuf[EP0DATABUF_SIZE];
|
||||
static uint8_t ep0dbuflen = 0;
|
||||
|
||||
usb_LineCoding getLineCoding(){return lineCoding;}
|
||||
|
||||
// definition of parts common for USB_DeviceDescriptor & USB_DeviceQualifierDescriptor
|
||||
#define bcdUSB_L 0x10
|
||||
#define bcdUSB_H 0x01
|
||||
#define bDeviceClass 0
|
||||
#define bDeviceSubClass 0
|
||||
#define bDeviceProtocol 0
|
||||
#define bNumConfigurations 1
|
||||
|
||||
static const uint8_t USB_DeviceDescriptor[] = {
|
||||
18, // bLength
|
||||
0x01, // bDescriptorType - Device descriptor
|
||||
bcdUSB_L, // bcdUSB_L - 1.10
|
||||
bcdUSB_H, // bcdUSB_H
|
||||
bDeviceClass, // bDeviceClass - USB_COMM
|
||||
bDeviceSubClass, // bDeviceSubClass
|
||||
bDeviceProtocol, // bDeviceProtocol
|
||||
USB_EP0_BUFSZ, // bMaxPacketSize
|
||||
0x7b, // idVendor_L PL2303: VID=0x067b, PID=0x2303
|
||||
0x06, // idVendor_H
|
||||
0x03, // idProduct_L
|
||||
0x23, // idProduct_H
|
||||
0x00, // bcdDevice_Ver_L
|
||||
0x03, // bcdDevice_Ver_H
|
||||
0x01, // iManufacturer
|
||||
0x02, // iProduct
|
||||
0x00, // iSerialNumber
|
||||
bNumConfigurations // bNumConfigurations
|
||||
};
|
||||
|
||||
static const uint8_t USB_DeviceQualifierDescriptor[] = {
|
||||
10, //bLength
|
||||
0x06, // bDescriptorType - Device qualifier
|
||||
bcdUSB_L, // bcdUSB_L
|
||||
bcdUSB_H, // bcdUSB_H
|
||||
bDeviceClass, // bDeviceClass
|
||||
bDeviceSubClass, // bDeviceSubClass
|
||||
bDeviceProtocol, // bDeviceProtocol
|
||||
USB_EP0_BUFSZ, // bMaxPacketSize0
|
||||
bNumConfigurations, // bNumConfigurations
|
||||
0x00 // Reserved
|
||||
};
|
||||
|
||||
static const uint8_t USB_ConfigDescriptor[] = {
|
||||
/*Configuration Descriptor*/
|
||||
0x09, /* bLength: Configuration Descriptor size */
|
||||
0x02, /* bDescriptorType: Configuration */
|
||||
39, /* wTotalLength:no of returned bytes */
|
||||
0x00,
|
||||
0x01, /* bNumInterfaces: 1 interface */
|
||||
0x01, /* bConfigurationValue: Configuration value */
|
||||
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
|
||||
0xa0, /* bmAttributes - Bus powered, Remote wakeup */
|
||||
0x32, /* MaxPower 100 mA */
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/*Interface Descriptor */
|
||||
0x09, /* bLength: Interface Descriptor size */
|
||||
0x04, /* bDescriptorType: Interface */
|
||||
0x00, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x03, /* bNumEndpoints: 3 endpoints used */
|
||||
0xff, /* bInterfaceClass */
|
||||
0x00, /* bInterfaceSubClass */
|
||||
0x00, /* bInterfaceProtocol */
|
||||
0x00, /* iInterface: */
|
||||
///////////////////////////////////////////////////
|
||||
/*Endpoint 1 Descriptor*/
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
0x05, /* bDescriptorType: Endpoint */
|
||||
0x81, /* bEndpointAddress IN1 */
|
||||
0x03, /* bmAttributes: Interrupt */
|
||||
0x0a, /* wMaxPacketSize LO: */
|
||||
0x00, /* wMaxPacketSize HI: */
|
||||
0x01, /* bInterval: */
|
||||
|
||||
/*Endpoint OUT2 Descriptor*/
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
0x05, /* bDescriptorType: Endpoint */
|
||||
0x02, /* bEndpointAddress: OUT2 */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
(USB_RXBUFSZ & 0xff), /* wMaxPacketSize: 64 */
|
||||
(USB_RXBUFSZ >> 8),
|
||||
0x00, /* bInterval: ignore for Bulk transfer */
|
||||
|
||||
/*Endpoint IN3 Descriptor*/
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
0x05, /* bDescriptorType: Endpoint */
|
||||
0x83, /* bEndpointAddress IN3 */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
(USB_TXBUFSZ & 0xff), /* wMaxPacketSize: 64 */
|
||||
(USB_TXBUFSZ >> 8),
|
||||
0x00, /* bInterval: ignore for Bulk transfer */
|
||||
};
|
||||
|
||||
_USB_LANG_ID_(USB_StringLangDescriptor, LANG_US);
|
||||
// these descriptors are not used in PL2303 emulator!
|
||||
_USB_STRING_(USB_StringSerialDescriptor, u"0");
|
||||
_USB_STRING_(USB_StringManufacturingDescriptor, u"Prolific Technology Inc.");
|
||||
_USB_STRING_(USB_StringProdDescriptor, u"USB-Serial Controller");
|
||||
|
||||
/*
|
||||
* default handlers
|
||||
*/
|
||||
// SET_LINE_CODING
|
||||
void WEAK linecoding_handler(usb_LineCoding __attribute__((unused)) *lc){
|
||||
}
|
||||
|
||||
// SET_CONTROL_LINE_STATE
|
||||
void WEAK clstate_handler(uint16_t __attribute__((unused)) val){
|
||||
}
|
||||
|
||||
// SEND_BREAK
|
||||
void WEAK break_handler(){
|
||||
}
|
||||
|
||||
// handler of vendor requests
|
||||
void WEAK vendor_handler(config_pack_t *packet){
|
||||
if(packet->bmRequestType & 0x80){ // read
|
||||
uint8_t c;
|
||||
switch(packet->wValue){
|
||||
case 0x8484:
|
||||
c = 2;
|
||||
break;
|
||||
case 0x0080:
|
||||
c = 1;
|
||||
break;
|
||||
case 0x8686:
|
||||
c = 0xaa;
|
||||
break;
|
||||
default:
|
||||
c = 0;
|
||||
}
|
||||
EP_WriteIRQ(0, &c, 1);
|
||||
}else{ // write ZLP
|
||||
EP_WriteIRQ(0, (uint8_t *)0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void wr0(const uint8_t *buf, uint16_t size){
|
||||
if(setup_packet.wLength < size) size = setup_packet.wLength; // shortened request
|
||||
if(size < endpoints[0].txbufsz){
|
||||
EP_WriteIRQ(0, buf, size);
|
||||
return;
|
||||
}
|
||||
while(size){
|
||||
uint16_t l = size;
|
||||
if(l > endpoints[0].txbufsz) l = endpoints[0].txbufsz;
|
||||
EP_WriteIRQ(0, buf, l);
|
||||
buf += l;
|
||||
size -= l;
|
||||
uint8_t needzlp = (l == endpoints[0].txbufsz) ? 1 : 0;
|
||||
if(size || needzlp){ // send last data buffer
|
||||
uint16_t status = KEEP_DTOG(USB->EPnR[0]);
|
||||
// keep DTOGs, clear CTR_RX,TX, set TX VALID, leave stat_Rx
|
||||
USB->EPnR[0] = (status & ~(USB_EPnR_CTR_RX|USB_EPnR_CTR_TX|USB_EPnR_STAT_RX))
|
||||
^ USB_EPnR_STAT_TX;
|
||||
uint32_t ctr = 1000000;
|
||||
while(--ctr && (USB->ISTR & USB_ISTR_CTR) == 0){IWDG->KR = IWDG_REFRESH;};
|
||||
if((USB->ISTR & USB_ISTR_CTR) == 0){
|
||||
return;
|
||||
}
|
||||
if(needzlp) EP_WriteIRQ(0, (uint8_t*)0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void get_descriptor(){
|
||||
switch(setup_packet.wValue){
|
||||
case DEVICE_DESCRIPTOR:
|
||||
wr0(USB_DeviceDescriptor, sizeof(USB_DeviceDescriptor));
|
||||
break;
|
||||
case CONFIGURATION_DESCRIPTOR:
|
||||
wr0(USB_ConfigDescriptor, sizeof(USB_ConfigDescriptor));
|
||||
break;
|
||||
case STRING_LANG_DESCRIPTOR:
|
||||
wr0((const uint8_t *)&USB_StringLangDescriptor, STRING_LANG_DESCRIPTOR_SIZE_BYTE);
|
||||
break;
|
||||
case STRING_MAN_DESCRIPTOR:
|
||||
wr0((const uint8_t *)&USB_StringManufacturingDescriptor, USB_StringManufacturingDescriptor.bLength);
|
||||
break;
|
||||
case STRING_PROD_DESCRIPTOR:
|
||||
wr0((const uint8_t *)&USB_StringProdDescriptor, USB_StringProdDescriptor.bLength);
|
||||
break;
|
||||
case STRING_SN_DESCRIPTOR:
|
||||
wr0((const uint8_t *)&USB_StringSerialDescriptor, USB_StringSerialDescriptor.bLength);
|
||||
break;
|
||||
case DEVICE_QUALIFIER_DESCRIPTOR:
|
||||
wr0(USB_DeviceQualifierDescriptor, USB_DeviceQualifierDescriptor[0]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t configuration = 0; // reply for GET_CONFIGURATION (==1 if configured)
|
||||
static inline void std_d2h_req(){
|
||||
uint16_t status = 0; // bus powered
|
||||
switch(setup_packet.bRequest){
|
||||
case GET_DESCRIPTOR:
|
||||
get_descriptor();
|
||||
break;
|
||||
case GET_STATUS:
|
||||
EP_WriteIRQ(0, (uint8_t *)&status, 2); // send status: Bus Powered
|
||||
break;
|
||||
case GET_CONFIGURATION:
|
||||
EP_WriteIRQ(0, &configuration, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void std_h2d_req(){
|
||||
switch(setup_packet.bRequest){
|
||||
case SET_ADDRESS:
|
||||
// new address will be assigned later - after acknowlegement or request to host
|
||||
USB_Dev.USB_Addr = setup_packet.wValue;
|
||||
break;
|
||||
case SET_CONFIGURATION:
|
||||
// Now device configured
|
||||
USB_Dev.USB_Status = USB_STATE_CONFIGURED;
|
||||
configuration = setup_packet.wValue;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
bmRequestType: 76543210
|
||||
7 direction: 0 - host->device, 1 - device->host
|
||||
65 type: 0 - standard, 1 - class, 2 - vendor
|
||||
4..0 getter: 0 - device, 1 - interface, 2 - endpoint, 3 - other
|
||||
*/
|
||||
/**
|
||||
* Endpoint0 (control) handler
|
||||
*/
|
||||
static void EP0_Handler(){
|
||||
uint16_t epstatus = USB->EPnR[0]; // EP0R on input -> return this value after modifications
|
||||
uint8_t reqtype = setup_packet.bmRequestType & 0x7f;
|
||||
uint8_t dev2host = (setup_packet.bmRequestType & 0x80) ? 1 : 0;
|
||||
int rxflag = RX_FLAG(epstatus);
|
||||
if(rxflag && SETUP_FLAG(epstatus)){
|
||||
switch(reqtype){
|
||||
case STANDARD_DEVICE_REQUEST_TYPE: // standard device request
|
||||
if(dev2host){
|
||||
std_d2h_req();
|
||||
}else{
|
||||
std_h2d_req();
|
||||
EP_WriteIRQ(0, (uint8_t *)0, 0);
|
||||
}
|
||||
break;
|
||||
case STANDARD_ENDPOINT_REQUEST_TYPE: // standard endpoint request
|
||||
if(setup_packet.bRequest == CLEAR_FEATURE){
|
||||
EP_WriteIRQ(0, (uint8_t *)0, 0);
|
||||
}
|
||||
break;
|
||||
case VENDOR_REQUEST_TYPE:
|
||||
vendor_handler(&setup_packet);
|
||||
break;
|
||||
case CONTROL_REQUEST_TYPE:
|
||||
switch(setup_packet.bRequest){
|
||||
case GET_LINE_CODING:
|
||||
EP_WriteIRQ(0, (uint8_t*)&lineCoding, sizeof(lineCoding));
|
||||
break;
|
||||
case SET_LINE_CODING: // omit this for next stage, when data will come
|
||||
break;
|
||||
case SET_CONTROL_LINE_STATE:
|
||||
usbON = 1;
|
||||
clstate_handler(setup_packet.wValue);
|
||||
break;
|
||||
case SEND_BREAK:
|
||||
usbON = 0;
|
||||
break_handler();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(setup_packet.bRequest != GET_LINE_CODING) EP_WriteIRQ(0, (uint8_t *)0, 0); // write acknowledgement
|
||||
break;
|
||||
default:
|
||||
EP_WriteIRQ(0, (uint8_t *)0, 0);
|
||||
}
|
||||
}else if(rxflag){ // got data over EP0 or host acknowlegement
|
||||
if(endpoints[0].rx_cnt){
|
||||
if(setup_packet.bRequest == SET_LINE_CODING){
|
||||
linecoding_handler((usb_LineCoding*)ep0databuf);
|
||||
}
|
||||
}
|
||||
} else if(TX_FLAG(epstatus)){ // package transmitted
|
||||
// now we can change address after enumeration
|
||||
if ((USB->DADDR & USB_DADDR_ADD) != USB_Dev.USB_Addr){
|
||||
USB->DADDR = USB_DADDR_EF | USB_Dev.USB_Addr;
|
||||
// change state to ADRESSED
|
||||
USB_Dev.USB_Status = USB_STATE_ADDRESSED;
|
||||
}
|
||||
}
|
||||
epstatus = KEEP_DTOG(USB->EPnR[0]);
|
||||
if(rxflag) epstatus ^= USB_EPnR_STAT_TX; // start ZLP/data transmission
|
||||
else epstatus &= ~USB_EPnR_STAT_TX; // or leave unchanged
|
||||
// keep DTOGs, clear CTR_RX,TX, set RX VALID
|
||||
USB->EPnR[0] = (epstatus & ~(USB_EPnR_CTR_RX|USB_EPnR_CTR_TX)) ^ USB_EPnR_STAT_RX;
|
||||
}
|
||||
|
||||
static uint16_t lastaddr = LASTADDR_DEFAULT;
|
||||
/**
|
||||
* Endpoint initialisation
|
||||
* !!! when working with CAN bus change USB_BTABLE_SIZE to 768 !!!
|
||||
* @param number - EP num (0...7)
|
||||
* @param type - EP type (EP_TYPE_BULK, EP_TYPE_CONTROL, EP_TYPE_ISO, EP_TYPE_INTERRUPT)
|
||||
* @param txsz - transmission buffer size @ USB/CAN buffer
|
||||
* @param rxsz - reception buffer size @ USB/CAN buffer
|
||||
* @param uint16_t (*func)(ep_t *ep) - EP handler function
|
||||
* @return 0 if all OK
|
||||
*/
|
||||
int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*func)()){
|
||||
if(number >= STM32ENDPOINTS) return 4; // out of configured amount
|
||||
if(txsz > USB_BTABLE_SIZE || rxsz > USB_BTABLE_SIZE) return 1; // buffer too large
|
||||
if(lastaddr + txsz + rxsz >= USB_BTABLE_SIZE) return 2; // out of btable
|
||||
USB->EPnR[number] = (type << 9) | (number & USB_EPnR_EA);
|
||||
USB->EPnR[number] ^= USB_EPnR_STAT_RX | USB_EPnR_STAT_TX_1;
|
||||
if(rxsz & 1 || rxsz > 512) return 3; // wrong rx buffer size
|
||||
uint16_t countrx = 0;
|
||||
if(rxsz < 64) countrx = rxsz / 2;
|
||||
else{
|
||||
if(rxsz & 0x1f) return 3; // should be multiple of 32
|
||||
countrx = 31 + rxsz / 32;
|
||||
}
|
||||
USB_BTABLE->EP[number].USB_ADDR_TX = lastaddr;
|
||||
endpoints[number].tx_buf = (uint16_t *)(USB_BTABLE_BASE + lastaddr);
|
||||
endpoints[number].txbufsz = txsz;
|
||||
lastaddr += txsz;
|
||||
USB_BTABLE->EP[number].USB_COUNT_TX = 0;
|
||||
USB_BTABLE->EP[number].USB_ADDR_RX = lastaddr;
|
||||
endpoints[number].rx_buf = (uint8_t *)(USB_BTABLE_BASE + lastaddr);
|
||||
lastaddr += rxsz;
|
||||
// buffer size: Table127 of RM
|
||||
USB_BTABLE->EP[number].USB_COUNT_RX = countrx << 10;
|
||||
endpoints[number].func = func;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// standard IRQ handler
|
||||
void usb_isr(){
|
||||
if (USB->ISTR & USB_ISTR_RESET){
|
||||
// Reinit registers
|
||||
USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM;
|
||||
USB->ISTR = 0;
|
||||
// Endpoint 0 - CONTROL
|
||||
// ON USB LS size of EP0 may be 8 bytes, but on FS it should be 64 bytes!
|
||||
lastaddr = LASTADDR_DEFAULT; // roll back to beginning of buffer
|
||||
EP_Init(0, EP_TYPE_CONTROL, USB_EP0_BUFSZ, USB_EP0_BUFSZ, EP0_Handler);
|
||||
// clear address, leave only enable bit
|
||||
USB->DADDR = USB_DADDR_EF;
|
||||
// state is default - wait for enumeration
|
||||
USB_Dev.USB_Status = USB_STATE_DEFAULT;
|
||||
}
|
||||
if(USB->ISTR & USB_ISTR_CTR){
|
||||
// EP number
|
||||
uint8_t n = USB->ISTR & USB_ISTR_EPID;
|
||||
// copy status register
|
||||
uint16_t epstatus = USB->EPnR[n];
|
||||
// copy received bytes amount
|
||||
endpoints[n].rx_cnt = USB_BTABLE->EP[n].USB_COUNT_RX & 0x3FF; // low 10 bits is counter
|
||||
// check direction
|
||||
if(USB->ISTR & USB_ISTR_DIR){ // OUT interrupt - receive data, CTR_RX==1 (if CTR_TX == 1 - two pending transactions: receive following by transmit)
|
||||
if(n == 0){ // control endpoint
|
||||
if(epstatus & USB_EPnR_SETUP){ // setup packet -> copy data to conf_pack
|
||||
EP_Read(0, (uint8_t*)&setup_packet);
|
||||
ep0dbuflen = 0;
|
||||
// interrupt handler will be called later
|
||||
}else if(epstatus & USB_EPnR_CTR_RX){ // data packet -> push received data to ep0databuf
|
||||
ep0dbuflen = endpoints[0].rx_cnt;
|
||||
EP_Read(0, (uint8_t*)&ep0databuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
// call EP handler
|
||||
if(endpoints[n].func) endpoints[n].func(endpoints[n]);
|
||||
}
|
||||
if(USB->ISTR & USB_ISTR_SUSP){ // suspend -> still no connection, may sleep
|
||||
usbON = 0;
|
||||
USB->CNTR |= USB_CNTR_FSUSP | USB_CNTR_LPMODE;
|
||||
USB->ISTR = ~USB_ISTR_SUSP;
|
||||
}
|
||||
if(USB->ISTR & USB_ISTR_WKUP){ // wakeup
|
||||
USB->CNTR &= ~(USB_CNTR_FSUSP | USB_CNTR_LPMODE); // clear suspend flags
|
||||
USB->ISTR = ~USB_ISTR_WKUP;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write data to EP buffer (called from IRQ handler)
|
||||
* @param number - EP number
|
||||
* @param *buf - array with data
|
||||
* @param size - its size
|
||||
*/
|
||||
void EP_WriteIRQ(uint8_t number, const uint8_t *buf, uint16_t size){
|
||||
uint8_t i;
|
||||
if(size > USB_TXBUFSZ) size = USB_TXBUFSZ;
|
||||
uint16_t N2 = (size + 1) >> 1;
|
||||
// the buffer is 16-bit, so we should copy data as it would be uint16_t
|
||||
uint16_t *buf16 = (uint16_t *)buf;
|
||||
for (i = 0; i < N2; i++){
|
||||
endpoints[number].tx_buf[i] = buf16[i];
|
||||
}
|
||||
USB_BTABLE->EP[number].USB_COUNT_TX = size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write data to EP buffer (called outside IRQ handler)
|
||||
* @param number - EP number
|
||||
* @param *buf - array with data
|
||||
* @param size - its size
|
||||
*/
|
||||
void EP_Write(uint8_t number, const uint8_t *buf, uint16_t size){
|
||||
EP_WriteIRQ(number, buf, size);
|
||||
uint16_t status = KEEP_DTOG(USB->EPnR[number]);
|
||||
// keep DTOGs, clear CTR_TX & set TX VALID to start transmission
|
||||
USB->EPnR[number] = (status & ~(USB_EPnR_CTR_TX)) ^ USB_EPnR_STAT_TX;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy data from EP buffer into user buffer area
|
||||
* @param *buf - user array for data
|
||||
* @return amount of data read
|
||||
*/
|
||||
int EP_Read(uint8_t number, uint8_t *buf){
|
||||
int n = endpoints[number].rx_cnt;
|
||||
if(n){
|
||||
for(int i = 0; i < n; ++i)
|
||||
buf[i] = endpoints[number].rx_buf[i];
|
||||
}
|
||||
return n;
|
||||
}
|
||||
189
F0:F030,F042,F072/Socket_fans/usb_lib.h
Normal file
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* geany_encoding=koi8-r
|
||||
* usb_lib.h
|
||||
*
|
||||
* Copyright 2018 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef __USB_LIB_H__
|
||||
#define __USB_LIB_H__
|
||||
|
||||
#include <wchar.h>
|
||||
#include "usb_defs.h"
|
||||
|
||||
#define EP0DATABUF_SIZE (64)
|
||||
#define LASTADDR_DEFAULT (STM32ENDPOINTS * 8)
|
||||
|
||||
// bmRequestType & 0x7f
|
||||
#define STANDARD_DEVICE_REQUEST_TYPE 0
|
||||
#define STANDARD_ENDPOINT_REQUEST_TYPE 2
|
||||
#define VENDOR_REQUEST_TYPE 0x40
|
||||
#define CONTROL_REQUEST_TYPE 0x21
|
||||
// bRequest, standard; for bmRequestType == 0x80
|
||||
#define GET_STATUS 0x00
|
||||
#define GET_DESCRIPTOR 0x06
|
||||
#define GET_CONFIGURATION 0x08
|
||||
// for bmRequestType == 0
|
||||
#define CLEAR_FEATURE 0x01
|
||||
#define SET_FEATURE 0x03 // unused
|
||||
#define SET_ADDRESS 0x05
|
||||
#define SET_DESCRIPTOR 0x07 // unused
|
||||
#define SET_CONFIGURATION 0x09
|
||||
// for bmRequestType == 0x81, 1 or 0xB2
|
||||
#define GET_INTERFACE 0x0A // unused
|
||||
#define SET_INTERFACE 0x0B // unused
|
||||
#define SYNC_FRAME 0x0C // unused
|
||||
#define VENDOR_REQUEST 0x01 // unused
|
||||
|
||||
// Class-Specific Control Requests
|
||||
#define SEND_ENCAPSULATED_COMMAND 0x00 // unused
|
||||
#define GET_ENCAPSULATED_RESPONSE 0x01 // unused
|
||||
#define SET_COMM_FEATURE 0x02 // unused
|
||||
#define GET_COMM_FEATURE 0x03 // unused
|
||||
#define CLEAR_COMM_FEATURE 0x04 // unused
|
||||
#define SET_LINE_CODING 0x20
|
||||
#define GET_LINE_CODING 0x21
|
||||
#define SET_CONTROL_LINE_STATE 0x22
|
||||
#define SEND_BREAK 0x23
|
||||
|
||||
// control line states
|
||||
#define CONTROL_DTR 0x01
|
||||
#define CONTROL_RTS 0x02
|
||||
|
||||
// wValue
|
||||
#define DEVICE_DESCRIPTOR 0x100
|
||||
#define CONFIGURATION_DESCRIPTOR 0x200
|
||||
#define STRING_LANG_DESCRIPTOR 0x300
|
||||
#define STRING_MAN_DESCRIPTOR 0x301
|
||||
#define STRING_PROD_DESCRIPTOR 0x302
|
||||
#define STRING_SN_DESCRIPTOR 0x303
|
||||
#define DEVICE_QUALIFIER_DESCRIPTOR 0x600
|
||||
|
||||
#define RX_FLAG(epstat) (epstat & USB_EPnR_CTR_RX)
|
||||
#define TX_FLAG(epstat) (epstat & USB_EPnR_CTR_TX)
|
||||
#define SETUP_FLAG(epstat) (epstat & USB_EPnR_SETUP)
|
||||
|
||||
// EPnR bits manipulation
|
||||
#define KEEP_DTOG_STAT(EPnR) (EPnR & ~(USB_EPnR_STAT_RX|USB_EPnR_STAT_TX|USB_EPnR_DTOG_RX|USB_EPnR_DTOG_TX))
|
||||
#define KEEP_DTOG(EPnR) (EPnR & ~(USB_EPnR_DTOG_RX|USB_EPnR_DTOG_TX))
|
||||
|
||||
// USB state: uninitialized, addressed, ready for use, client connected
|
||||
typedef enum{
|
||||
USB_STATE_DEFAULT,
|
||||
USB_STATE_ADDRESSED,
|
||||
USB_STATE_CONFIGURED,
|
||||
USB_STATE_CONNECTED
|
||||
} USB_state;
|
||||
|
||||
// EP types
|
||||
#define EP_TYPE_BULK 0x00
|
||||
#define EP_TYPE_CONTROL 0x01
|
||||
#define EP_TYPE_ISO 0x02
|
||||
#define EP_TYPE_INTERRUPT 0x03
|
||||
|
||||
#define LANG_US (uint16_t)0x0409
|
||||
|
||||
#define _USB_STRING_(name, str) \
|
||||
static const struct name \
|
||||
{ \
|
||||
uint8_t bLength; \
|
||||
uint8_t bDescriptorType; \
|
||||
uint16_t bString[(sizeof(str) - 2) / 2]; \
|
||||
\
|
||||
} \
|
||||
name = {sizeof(name), 0x03, str}
|
||||
|
||||
#define _USB_LANG_ID_(name, lng_id) \
|
||||
\
|
||||
static const struct name \
|
||||
{ \
|
||||
uint8_t bLength; \
|
||||
uint8_t bDescriptorType; \
|
||||
uint16_t bString; \
|
||||
\
|
||||
} \
|
||||
name = {0x04, 0x03, lng_id}
|
||||
#define STRING_LANG_DESCRIPTOR_SIZE_BYTE (4)
|
||||
|
||||
// EP0 configuration packet
|
||||
typedef struct {
|
||||
uint8_t bmRequestType;
|
||||
uint8_t bRequest;
|
||||
uint16_t wValue;
|
||||
uint16_t wIndex;
|
||||
uint16_t wLength;
|
||||
} config_pack_t;
|
||||
|
||||
// endpoints state
|
||||
typedef struct __ep_t{
|
||||
uint16_t *tx_buf; // transmission buffer address
|
||||
uint16_t txbufsz; // transmission buffer size
|
||||
uint8_t *rx_buf; // reception buffer address
|
||||
void (*func)(); // endpoint action function
|
||||
uint16_t rx_cnt; // received data counter
|
||||
} ep_t;
|
||||
|
||||
// USB status & its address
|
||||
typedef struct {
|
||||
uint8_t USB_Status;
|
||||
uint16_t USB_Addr;
|
||||
}usb_dev_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t dwDTERate;
|
||||
uint8_t bCharFormat;
|
||||
#define USB_CDC_1_STOP_BITS 0
|
||||
#define USB_CDC_1_5_STOP_BITS 1
|
||||
#define USB_CDC_2_STOP_BITS 2
|
||||
uint8_t bParityType;
|
||||
#define USB_CDC_NO_PARITY 0
|
||||
#define USB_CDC_ODD_PARITY 1
|
||||
#define USB_CDC_EVEN_PARITY 2
|
||||
#define USB_CDC_MARK_PARITY 3
|
||||
#define USB_CDC_SPACE_PARITY 4
|
||||
uint8_t bDataBits;
|
||||
} __attribute__ ((packed)) usb_LineCoding;
|
||||
|
||||
typedef struct {
|
||||
uint8_t bmRequestType;
|
||||
uint8_t bNotificationType;
|
||||
uint16_t wValue;
|
||||
uint16_t wIndex;
|
||||
uint16_t wLength;
|
||||
} __attribute__ ((packed)) usb_cdc_notification;
|
||||
|
||||
extern ep_t endpoints[];
|
||||
extern usb_dev_t USB_Dev;
|
||||
extern uint8_t usbON;
|
||||
|
||||
void USB_Init();
|
||||
uint8_t USB_GetState();
|
||||
int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*func)());
|
||||
void EP_WriteIRQ(uint8_t number, const uint8_t *buf, uint16_t size);
|
||||
void EP_Write(uint8_t number, const uint8_t *buf, uint16_t size);
|
||||
int EP_Read(uint8_t number, uint8_t *buf);
|
||||
usb_LineCoding getLineCoding();
|
||||
|
||||
void linecoding_handler(usb_LineCoding *lc);
|
||||
void clstate_handler(uint16_t val);
|
||||
void break_handler();
|
||||
void vendor_handler(config_pack_t *packet);
|
||||
|
||||
#endif // __USB_LIB_H__
|
||||