try to make 1-wire on timers

This commit is contained in:
eddyem 2014-10-30 11:17:48 +03:00
parent 6af145db1c
commit 7455c600b0
33 changed files with 1393 additions and 500 deletions

View File

@ -1,4 +1,3 @@
eeschema (2013-feb-26)-stable >> Creation date: Пн 21 июл 2014 08:49:29
#Cmp ( order = Reference )
| C4 2200u, 40V
| C5 10u

View File

@ -1,4 +1,4 @@
EESchema Schematic File Version 2 date Пн 29 сен 2014 14:40:29
EESchema Schematic File Version 2 date Вт 07 окт 2014 17:18:47
LIBS:power
LIBS:device
LIBS:transistors
@ -41,7 +41,7 @@ $Descr A3 16535 11693
encoding utf-8
Sheet 1 12
Title "IR-spectrometer Control System"
Date "29 sep 2014"
Date "7 oct 2014"
Rev ""
Comp "SAO RAS"
Comment1 ""

View File

@ -1,4 +1,4 @@
EESchema Schematic File Version 2 date Пн 29 сен 2014 14:40:29
EESchema Schematic File Version 2 date Вт 07 окт 2014 17:18:47
LIBS:power
LIBS:device
LIBS:transistors
@ -41,7 +41,7 @@ $Descr A3 16535 11693
encoding utf-8
Sheet 3 12
Title "MCU module on STM32F103"
Date "29 sep 2014"
Date "7 oct 2014"
Rev ""
Comp "SAO RAS"
Comment1 ""

View File

@ -1,4 +1,4 @@
EESchema Schematic File Version 2 date Пн 29 сен 2014 14:40:29
EESchema Schematic File Version 2 date Вт 07 окт 2014 17:18:47
LIBS:power
LIBS:device
LIBS:transistors
@ -41,7 +41,7 @@ $Descr A4 11693 8268
encoding utf-8
Sheet 5 12
Title "RS-232 level converter"
Date "29 sep 2014"
Date "7 oct 2014"
Rev ""
Comp "SAO RAS"
Comment1 ""

View File

@ -1,102 +1,102 @@
嬲嗡蒙衔撂匚吓 瘟谖赁盼膳 邢以献 蜕艘纤衔砸咸膛伊
Functional map of MCU pins
# 瘟谧廖膳 瘟谖赁盼膳
# name functionality
001 PE2 DIR_3 direction of steppers' rotation
002 PE3 DIR_4
003 PE4 DIR_5
004
005
006
007
008
009
010 VSS
011 VDD
012 OSC_IN
013 OSC_OUT
014 NRST RST
015 PC0 \
016 PC1 | ADG506 address
017 PC2 | selection
018 PC3 /
004 PE6 DG_FEEDBACK feedback from power switch POW_LOAD (+10..12V)
005 -
006 -
007 -
008 -
009 -
010 VSS GND
011 VDD +3.3V
012 OSC_IN 8MHz in
013 OSC_OUT 8MHz out
014 NRST Reset
015 PC0 SHTR Shutter on pulse
016 PC1 SHTR_FB Error signal from shutter H-bridge
017 PC2 POW0 Shutter polarity (open/close)
018 -
019 VSSA 0v analog
020 VREF- ref (0v)
021 VREF+ ref (+3.3v)
022 VDDA +3.3V analog
023
024 PA1 TIM2 timer for motors 4&5
025 PA2 UART_TX RS-232
026 PA3 UART_RX
027 VSS
028 VDD
029 PA4 7\
030 PA5 6 |
031 PA6 5 |
032 PA7 4 | ADC 12bit input channels (TRD)
033 PC4 3 |
034 PC5 2 |
035 PB0 1 |
036 PB1 0/
023 -
024 -
025 PA2 1WIRE_TX 1-wire interface
026 PA3 1WIRE_RX
027 VSS GND
028 VDD +3.3V
029 PA4 ADC7\
030 PA5 ADC6 |
031 PA6 ADC5 |
032 PA7 ADC4 | ADC 12bit input channels (TRD)
033 PC4 ADC3 |
034 PC5 ADC2 |
035 PB0 ADC1 |
036 PB1 ADC0/
037 BOOT1 BOOT 100k resistor to GND
038 PE7 EN1 \
039 PE8 EN2 |
040 PE9 EN3 | enable Xth stepper motor
041 PE10 EN4 |
042 PE11 EN5 /
043 PE12 POW0\
044 PE13 POW1 | Power load (12V, up to 17A on single channel)
045 PE14 POW2 |
046 PE15 POW3/
047 PB10 USART3_TX 1-wire data tx/rx
043 PE12 POW2\
044 PE13 POW1/ Power load (10..12V, pull-down)
045 -
046 -
047 PB10 USART3_TX RS-232 (master)
048 PB11 USART3_RX
049 VSS
050 VDD
051
049 VSS GND
050 VDD +3.3V
051 -
052 SPI2_SCK \
053 SPI2_MISO | External SPI connection
053 SPI2_MISO | External SPI connection (at edge of the board)
054 SPI2_MOSI /
055 PD8 \ Tur3[1..2] Upper filters turret Hall 1 & 2
056 PD9 /
057 PD10 \ LS1 Linear stage 1 (long) DOWN end-switch
058 PD11 / Linear stage 1 (long) UP end-switch
059 PD12 \ LS2 Linear stage 2 (short) DOWN end-switch
060 PD13 / Linear stage 2 (short) UP end-switch
061
062
055 -
056 -
057 PD10 EXT0\
058 PD11 EXT1 | ADG506 address selection
059 PD12 EXT2 | or custom external ports
060 PD13 EXT3/
061 -
062 PD15 TIM2 timer for motors 4&5
063 PC6 TIM1 timer for stepper motors 1..3
064 PC7 \
065 PC8 |
066 PC9 | EXT External ports +
067 PA8 |
068 PA9 | TX External UART (+ boot UART)
069 PA10 / RX
064 PC7 \ LS1 Linear stage 1 (long) DOWN end-switch
065 PC8 / Linear stage 1 (long) UP end-switch
066 PC9 \ LS2 Linear stage 2 (short) DOWN end-switch
067 PA8 / Linear stage 2 (short) UP end-switch
068 PA9 BOOT_TX \ UART1 (slave): boot + ext UART
069 PA10 BOOT_RX /
070 PA11 USB_DM USB data-
071 PA12 USB_DP USB data+
072
073
074 VSS
075 VDD
076
077
078
079 PC11 USB_DISC disconnect USB)
080
072 -
073 -
074 VSS GND
075 VDD +3.3V
076 -
077 -
078 PC10 USB_POWER +3V when USB connected
079 PC11 USB_DISC software USB disconnection (low lewel for bipolar VT1, high level for p-channel MOSFET)
080 -
081 PD0 \
082 PD1 | Tur1 Slits turret Hall sensors
083 PD2 |
084 PD3 /
085 PD4 \
086 PD5 | Tur2 Middle filters turret Hall sensors
087 PD6 / Upper filters turret Hall 0
088 PD7 Tur3_0
089 SPI1_SCK
090 SPI1_MISO
091 SPI1_MOSI/I2C_SMBAI
092
093
087 PD6 /
088 PD7 Tur3_0 Upper filters turret Hall 0
089 SPI1_SCK \
090 SPI1_MISO | SPI connection (near USB connector)
091 SPI1_MOSI/I2C_SMBAI/
092 PB6 Tur3_1 \ Upper filters turret Hall 1,2
093 PB7 Tur3_2 /
094 BOOT BOOT Button to boot from bootloader
095 I2C_SCL/CANRX
096 I2C_SDA/CANTX
095 I2C_SCL/CANRX \ External CAN connection (or I2S, etc)
096 I2C_SDA/CANTX /
097 PE0 DIR_1 direction of SM 1,2
098 PE1 DIR_2
099 VSS

View File

@ -1,4 +1,4 @@
EESchema Schematic File Version 2 date Пн 29 сен 2014 14:40:29
EESchema Schematic File Version 2 date Вт 07 окт 2014 17:18:47
LIBS:power
LIBS:device
LIBS:transistors
@ -41,7 +41,7 @@ $Descr A4 11693 8268
encoding utf-8
Sheet 12 12
Title "Power load module"
Date "29 sep 2014"
Date "7 oct 2014"
Rev ""
Comp "SAO RAS"
Comment1 ""

View File

@ -1,4 +1,4 @@
EESchema Schematic File Version 2 date Пн 29 сен 2014 14:40:29
EESchema Schematic File Version 2 date Вт 07 окт 2014 17:18:47
LIBS:power
LIBS:device
LIBS:transistors
@ -41,7 +41,7 @@ $Descr A4 11693 8268
encoding utf-8
Sheet 4 12
Title "USB input circuit"
Date "29 sep 2014"
Date "7 oct 2014"
Rev ""
Comp "SAO RAS"
Comment1 ""
@ -301,10 +301,20 @@ Wire Wire Line
Wire Wire Line
3900 2500 2500 2500
Connection ~ 2500 2500
Connection ~ 3900 2500
Wire Wire Line
5200 2000 3900 2000
Wire Wire Line
3900 2000 3900 3300
Connection ~ 3900 3100
Wire Wire Line
3900 3300 3900 2500
$Comp
L +3.3V #PWR?
U 1 1 5433F723
P 5200 1900
F 0 "#PWR?" H 5200 1860 30 0001 C CNN
F 1 "+3.3V" H 5200 2010 30 0000 C CNN
F 2 "" H 5200 1900 60 0000 C CNN
F 3 "" H 5200 1900 60 0000 C CNN
1 5200 1900
1 0 0 -1
$EndComp
Wire Wire Line
5200 1900 5200 2000
$EndSCHEMATC

View File

@ -1,4 +1,4 @@
EESchema Schematic File Version 2 date Пн 29 сен 2014 14:40:29
EESchema Schematic File Version 2 date Вт 07 окт 2014 17:18:47
LIBS:power
LIBS:device
LIBS:transistors
@ -41,7 +41,7 @@ $Descr A4 11693 8268
encoding utf-8
Sheet 2 12
Title "Stepper motor module"
Date "29 sep 2014"
Date "7 oct 2014"
Rev ""
Comp "SAO RAS"
Comment1 ""

View File

@ -1,4 +1,4 @@
EESchema Schematic File Version 2 date Пн 29 сен 2014 14:40:29
EESchema Schematic File Version 2 date Вт 07 окт 2014 17:18:47
LIBS:power
LIBS:device
LIBS:transistors
@ -41,7 +41,7 @@ $Descr A4 11693 8268
encoding utf-8
Sheet 11 12
Title "Power load module"
Date "29 sep 2014"
Date "7 oct 2014"
Rev ""
Comp "SAO RAS"
Comment1 ""

View File

@ -1,9 +1,11 @@
BINARY = ircontroller
BOOTPORT ?= /dev/ttyUSB0
BOOTSPEED ?= 115200
LDSCRIPT = stm32-h103.ld
# change this linking script depending on particular MCU model,
# for example, if you have STM32F103VBT6, you should write:
LDSCRIPT = ld/stm32f103xB.ld
LIBNAME = opencm3_stm32f1
DEFS = -DSTM32F1
DEFS = -DSTM32F1 -DEBUG
OBJDIR = mk
INDEPENDENT_HEADERS=
@ -11,7 +13,6 @@ INDEPENDENT_HEADERS=
FP_FLAGS ?= -msoft-float
ARCH_FLAGS = -mthumb -mcpu=cortex-m3 $(FP_FLAGS) -mfix-cortex-m3-ldrd
###############################################################################
# Executables
PREFIX ?= arm-none-eabi
@ -46,7 +47,7 @@ SCRIPT_DIR = $(OPENCM3_DIR)/scripts
###############################################################################
# C flags
CFLAGS += -Os -g
CFLAGS += -Wextra -Wshadow -Wimplicit-function-declaration
CFLAGS += -Wall -Wextra -Wshadow -Wimplicit-function-declaration
CFLAGS += -Wredundant-decls
# -Wmissing-prototypes -Wstrict-prototypes
CFLAGS += -fno-common -ffunction-sections -fdata-sections

1
with_opencm3/NVIC Normal file
View File

@ -0,0 +1 @@
don't forget to call nvic_enable_irq(irq) to allow interrupts

View File

@ -1,3 +1,11 @@
The work begins
First PCB have been prodused, so I need "only" to solder elements & finish the code
Pinout of MCI is in file schematics/STM32_PINS
-- OLD --
This is a sketch for futher work
I found that libopencm3 is more friendly than SPL. Also I have some new thoughts about modular system: for
flexibility.

View File

@ -292,20 +292,19 @@ usbd_device *USB_init(){
return current_usb;
}
uint8_t send_block = 0;
mutex_t send_block_mutex = MUTEX_UNLOCKED;
/**
* Put byte into USB buffer to send
* @param byte - a byte to put into a buffer
*/
void usb_send(uint8_t byte){
while(send_block); // wait for unlock
send_block = 1;
mutex_lock(&send_block_mutex);
USB_Tx_Buffer[USB_Tx_ptr++] = byte;
if(USB_Tx_ptr == USB_TX_DATA_SIZE){ // buffer can be overflowed - send it!
send_block = 0;
mutex_unlock(&send_block_mutex);
usb_send_buffer();
}
send_block = 0;
}else
mutex_unlock(&send_block_mutex);
}
/**
@ -313,8 +312,7 @@ void usb_send(uint8_t byte){
* this function runs when buffer is full or on SysTick
*/
void usb_send_buffer(){
if(send_block) return;
send_block = 1;
if(MUTEX_LOCKED == mutex_trylock(&send_block_mutex)) return;
if(USB_Tx_ptr){
if(current_usb && USB_connected){
// usbd_ep_write_packet return 0 if previous packet isn't transmit yet
@ -323,5 +321,5 @@ void usb_send_buffer(){
}
USB_Tx_ptr = 0;
}
send_block = 0;
mutex_unlock(&send_block_mutex);
}

View File

@ -31,14 +31,17 @@ function [Time T Tfxd] = get_T(filename, filter_treshold)
endfor
endif
plot(Time, R);
Leg = ['1'; '2'; '3'; '4'; '5'; '6'; '7'; '8'];
more_colors(plot(Time, R), 8);
Tit = sprintf("Resistance, \\Omega");
xlabel("Time, s"); ylabel("R, \\Omega"); title(Tit);
print -dpng -color resistance.png;
close
plot(Time, T);
more_colors(plot(Time, T), 8);
Tit = sprintf("Temperature, ^\\circ{}C");
xlabel("Time, s"); ylabel("T, ^\\circ{}C"); title(Tit);
legend(Leg);
print -dpng -color temperatures.png;
close
@ -46,12 +49,18 @@ function [Time T Tfxd] = get_T(filename, filter_treshold)
Tavr = mean(T, 2);
Tadd = mean(T - repmat(Tavr, [1 8]));
Tfxd = T - repmat(Tadd,[size(T,1) 1]);
plot(Time, Tfxd);
more_colors(plot(Time, Tfxd), 8);
Tit = sprintf("Temperature fixed to average value, ^\\circ{}C");
xlabel("Time, s"); ylabel("T, ^\\circ{}C"); title(Tit);
print -dpng -color temperatures_fixed.png;
legend(Leg);
close
printf("differences:\n"); printf("%g\n", -Tadd);
endfunction
function more_colors(h, N)
palette = jet (N);
for i = 1:N
set(h(i),"color",palette(i,:))
endfor
endfunction

View File

@ -19,24 +19,108 @@
* MA 02110-1301, USA.
*/
/*
* All hardware-dependent initialisation & definition should be placed here
* and in hardware_ini.h
*
*/
#include "main.h"
#include "hardware_ini.h"
volatile uint16_t ADC_value[8]; // ADC DMA value
/**
* GPIO initialisaion: clocking + ports setup
/*
* Configure SPI ports
*/
void GPIO_init(){
rcc_periph_clock_enable(RCC_GPIOC);
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO11|GPIO12); // LED + USB
// AD7794 addr + en
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, ADC_ADDR_MASK | GPIO10); // ADDRESS: PC6..9; EN: PC10
GPIO_BSRR(GPIOC) = (ADC_ADDR_MASK | GPIO10) << 16; // clear address & disable com
/*
* SPI1 remapped:
* SCK - PB3
* MISO - PB4
* MOSI - PB5
*/
void SPI1_init(){
// enable AFIO & other clocking
rcc_peripheral_enable_clock(&RCC_APB2ENR,
RCC_APB2ENR_SPI1EN | RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPBEN);
// remap SPI1 (change pins from PA5..7 to PB3..5); also turn off JTAG
gpio_primary_remap(AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_OFF, AFIO_MAPR_SPI1_REMAP);
// SCK, MOSI - push-pull output
gpio_set_mode(GPIO_BANK_SPI1_RE_SCK, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_SPI1_RE_SCK);
gpio_set_mode(GPIO_BANK_SPI1_RE_MOSI, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_SPI1_RE_MOSI);
// MISO - opendrain in
gpio_set_mode(GPIO_BANK_SPI1_RE_MISO, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO_SPI1_RE_MISO);
spi_reset(SPI1);
/* Set up SPI in Master mode with:
* Clock baud rate: 1/128 of peripheral clock frequency (APB2, 72MHz)
* Clock polarity: Idle High
* Clock phase: Data valid on 2nd clock pulse
* Data frame format: 8-bit
* Frame format: MSB First
*/
spi_init_master(SPI1, SPI_CR1_BAUDRATE_FPCLK_DIV_128, SPI_CR1_CPOL_CLK_TO_1_WHEN_IDLE,
SPI_CR1_CPHA_CLK_TRANSITION_2, SPI_CR1_DFF_8BIT, SPI_CR1_MSBFIRST);
nvic_enable_irq(NVIC_SPI1_IRQ); // enable SPI interrupt
}
/*
* SPI2:
* SCK - PB13
* MISO - PB14
* MOSI - PB15
*/
void SPI2_init(){
// turn on clocking
//rcc_periph_clock_enable(RCC_SPI2 | RCC_GPIOB);
rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_SPI2EN);
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPBEN);
// SCK, MOSI - push-pull output
gpio_set_mode(GPIO_BANK_SPI2_SCK, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_SPI2_SCK);
gpio_set_mode(GPIO_BANK_SPI2_MOSI, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_SPI2_MOSI);
// MISO - opendrain in
gpio_set_mode(GPIO_BANK_SPI2_MISO, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO_SPI2_MISO);
spi_reset(SPI2);
/* Set up SPI in Master mode with:
* Clock baud rate: 1/64 of peripheral clock frequency (APB1, 36MHz)
* Clock polarity: Idle High
* Clock phase: Data valid on 2nd clock pulse
* Data frame format: 8-bit
* Frame format: MSB First
*/
spi_init_master(SPI2, SPI_CR1_BAUDRATE_FPCLK_DIV_64, SPI_CR1_CPOL_CLK_TO_1_WHEN_IDLE,
SPI_CR1_CPHA_CLK_TRANSITION_2, SPI_CR1_DFF_8BIT, SPI_CR1_MSBFIRST);
nvic_enable_irq(NVIC_SPI2_IRQ); // enable SPI interrupt
}
/**
* GPIO initialisaion: clocking + pins setup
*/
void GPIO_init(){
/* rcc_periph_clock_enable(RCC_AFIO);
rcc_periph_clock_enable(RCC_SPI1);
rcc_periph_clock_enable(RCC_GPIOC);*/
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN |
RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN |
RCC_APB2ENR_IOPEEN);
// USB_DISC: push-pull
gpio_set_mode(USB_DISC_PORT, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, USB_DISC_PIN);
// USB_POWER: open drain, externall pull down with R7 (22k)
gpio_set_mode(USB_POWER_PORT, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_FLOAT, USB_POWER_PIN);
// AD7794 addr + en
gpio_set_mode(ADC_ADDR_PORT, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, ADC_ADDR_MASK | ADC_EN_PIN); // ADDRESS: PD10..12; EN: PD13
gpio_clear(ADC_ADDR_PORT, ADC_ADDR_MASK | ADC_EN_PIN); // clear address & turn switch off
}
/*
* SysTick used for system timer with period of 1ms
*/
void SysTick_init(){
systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8); // Systyck: 72/8=9MHz
systick_set_reload(8999); // 9000 pulses: 1kHz
@ -44,13 +128,31 @@ void SysTick_init(){
systick_counter_enable();
}
/*
* Due to inconvenient pins position on STM32F103VxT6 I had to make this strange location:
* my channel # -> ADC1/2 channel #
* 0 -> 9 PB1
* 1 -> 8 PB0
* 2 -> 15 PC5
* 3 -> 14 PC4
* 4 -> 7 PA7
* 5 -> 6 PA6
* 6 -> 5 PA5
* 7 -> 4 PA4
*/
uint8_t adc_channel_array[16] = {9,8,15,14,7,6,5,4};
#define ADC_CHANNELS_NUMBER 8
void ADC_init(){
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_ADC1EN); // enable clocking
rcc_periph_clock_enable(RCC_ADC1);
rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV4);
rcc_periph_clock_enable(RCC_GPIOB | RCC_GPIOC); // clocking for ADC ports
gpio_set_mode(GPIOB, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, 3); // ADC8 - PB0, ADC9 -PB1
gpio_set_mode(GPIOC, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, 63); // ADC10-15: PC0-PC5
rcc_periph_clock_enable(RCC_GPIOA | RCC_GPIOB | RCC_GPIOC); // clocking for ADC ports
// channels 4-7: PA7-PA4
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO4|GPIO5|GPIO6|GPIO7);
// channels 0,1: PB1, PB0
gpio_set_mode(GPIOB, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO0|GPIO1);
// channels 2,3: PC5, PC4
gpio_set_mode(GPIOC, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO4|GPIO5);
// Make sure the ADC doesn't run during config
adc_off(ADC1);
@ -60,7 +162,7 @@ void ADC_init(){
dma_channel_reset(DMA1, DMA_CHANNEL1); //DMA_DeInit(DMA1_Channel1);
dma_set_peripheral_address(DMA1, DMA_CHANNEL1, (uint32_t) &(ADC_DR(ADC1))); // DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
dma_set_memory_address(DMA1, DMA_CHANNEL1, (uint32_t) ADC_value); // DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_value;
dma_set_number_of_data(DMA1, DMA_CHANNEL1, 8); // DMA_InitStructure.DMA_BufferSize = 1;
dma_set_number_of_data(DMA1, DMA_CHANNEL1, ADC_CHANNELS_NUMBER); // DMA_InitStructure.DMA_BufferSize = 1;
dma_set_read_from_peripheral(DMA1, DMA_CHANNEL1); // DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL1); // DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL1); // DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
@ -76,8 +178,8 @@ void ADC_init(){
adc_set_continuous_conversion_mode(ADC1); // ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
adc_disable_external_trigger_regular(ADC1); // ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
adc_set_right_aligned(ADC1); // ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
//adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_239DOT5CYC); // ADC_SampleTime_239Cycles5
adc_set_sample_time(ADC1, ADC_CHANNEL8, ADC_SMPR_SMP_239DOT5CYC); // ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_239Cycles5);
adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_239DOT5CYC); // ADC_SampleTime_239Cycles5
//adc_set_sample_time(ADC1, ADC_CHANNEL8, ADC_SMPR_SMP_239DOT5CYC); // ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_239Cycles5);
adc_enable_dma(ADC1); // ADC_DMACmd(ADC1, ENABLE);
adc_power_on(ADC1); // ADC_Cmd(ADC1, ENABLE);
}
@ -87,13 +189,112 @@ void ADC_init(){
* First call ADC_init(), than wait a little and call this function
*/
void ADC_calibrate_and_start(){
uint8_t channel_array[16] = {8,9,10,11,12,13,14,15};
// adc_set_regular_sequence 1 channel -- 0 // ADC_InitStructure.ADC_NbrOfChannel = 1;
channel_array[0] = ADC_CHANNEL8;
adc_set_regular_sequence(ADC1, 8, channel_array);
adc_set_regular_sequence(ADC1, ADC_CHANNELS_NUMBER, adc_channel_array);
adc_reset_calibration(ADC1);
adc_calibration(ADC1);
adc_start_conversion_regular(ADC1); // ADC_SoftwareStartConvCmd(ADC1, ENABLE);
adc_start_conversion_direct(ADC1);
}
uint16_t tim2_buff[8] = {10,20,30,40,50,60,70,80};
uint16_t tim2_inbuff[8];
void init_dmatimer(){ // tim2_ch4 - PA3, no remap
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, GPIO3);
rcc_periph_clock_enable(RCC_TIM2);
timer_reset(TIM2);
// timers have frequency of 1MHz -- 1us for one step
// 36MHz of APB1
timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
// 72MHz div 72 = 1MHz
timer_set_prescaler(TIM2, 71); // prescaler is (div - 1)
timer_continuous_mode(TIM2); // automatically reload
timer_enable_preload(TIM2); // force changing period
timer_set_period(TIM2, 86); // period is 87us
timer_enable_update_event(TIM2);
timer_set_oc_mode(TIM2, TIM_OC4, TIM_OCM_PWM1); // edge-aligned mode
timer_enable_oc_preload(TIM2, TIM_OC4);
timer_enable_oc_output(TIM2, TIM_OC4);
timer_enable_irq(TIM2, TIM_DIER_UDE | TIM_DIER_CC4DE | TIM_DIER_CC3DE);
timer_set_oc_polarity_low(TIM2, TIM_OC4);
// TIM2_CH4 - DMA1, channel 7
rcc_periph_clock_enable(RCC_DMA1);
dma_channel_reset(DMA1, DMA_CHANNEL7);
dma_set_peripheral_address(DMA1, DMA_CHANNEL7, (uint32_t) &(TIM_CCR4(TIM2)));
dma_set_read_from_memory(DMA1, DMA_CHANNEL7);
dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL7);
dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL7);
dma_set_peripheral_size(DMA1, DMA_CHANNEL7, DMA_CCR_PSIZE_16BIT);
dma_set_memory_size(DMA1, DMA_CHANNEL7, DMA_CCR_MSIZE_16BIT);
dma_enable_transfer_error_interrupt(DMA1, DMA_CHANNEL7);
dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL7);
dma_set_memory_address(DMA1, DMA_CHANNEL7, (uint32_t)tim2_buff);
nvic_enable_irq(NVIC_DMA1_CHANNEL7_IRQ); // enable dma1_channel7_isr
// capture: TIM2_CH3
timer_ic_set_input(TIM2, TIM_IC3, TIM_IC_IN_TI4);
timer_set_oc_polarity_high(TIM2, TIM_OC3);
timer_ic_enable(TIM2, TIM_IC3);
timer_enable_oc_output(TIM2, TIM_OC3);
// configure DMA1 Channel1 (ADC1)
dma_channel_reset(DMA1, DMA_CHANNEL1);
dma_set_peripheral_address(DMA1, DMA_CHANNEL1, (uint32_t) &(TIM_CCR3(TIM2)));
dma_set_memory_address(DMA1, DMA_CHANNEL1, (uint32_t) tim2_inbuff);
dma_set_number_of_data(DMA1, DMA_CHANNEL1, 8);
dma_set_read_from_peripheral(DMA1, DMA_CHANNEL1);
dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL1);
dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL1);
dma_set_peripheral_size(DMA1, DMA_CHANNEL1, DMA_CCR_PSIZE_16BIT);
dma_set_memory_size(DMA1, DMA_CHANNEL1, DMA_CCR_MSIZE_16BIT);
nvic_enable_irq(NVIC_DMA1_CHANNEL1_IRQ);
dma_enable_transfer_error_interrupt(DMA1, DMA_CHANNEL1);
dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL1);
}
void run_dmatimer(){
int i;
DMA1_IFCR = DMA_ISR_TEIF7|DMA_ISR_HTIF7|DMA_ISR_TCIF7|DMA_ISR_GIF7 |
DMA_ISR_TEIF1|DMA_ISR_HTIF1|DMA_ISR_TCIF1|DMA_ISR_GIF1; // clear flags
dma_set_number_of_data(DMA1, DMA_CHANNEL7, 8);
timer_set_dma_on_compare_event(TIM2);
timer_enable_oc_output(TIM2, TIM_OC4);
dma_enable_channel(DMA1, DMA_CHANNEL7);
timer_enable_counter(TIM2);
for(i = 0; i < 8; i++) tim2_inbuff[i] = 0;
dma_set_number_of_data(DMA1, DMA_CHANNEL1, 8);
dma_enable_channel(DMA1, DMA_CHANNEL1);
}
void dma1_channel7_isr(){
if(DMA1_ISR & DMA_ISR_TCIF7) {
DMA1_IFCR = DMA_IFCR_CTCIF7;
dma_disable_channel(DMA1, DMA_CHANNEL7);
}else if(DMA1_ISR & DMA_ISR_TEIF7){
DMA1_IFCR = DMA_IFCR_CTEIF7;
MSG("out transfer error\n");
}
}
void dma1_channel1_isr(){
int i;
if(DMA1_ISR & DMA_ISR_TCIF1) {
DMA1_IFCR = DMA_IFCR_CTCIF1;
dma_disable_channel(DMA1, DMA_CHANNEL1);
timer_disable_counter(TIM2);
gpio_set(GPIOA, GPIO3);
for(i = 0; i < 8; i++){
print_int(tim2_inbuff[i], lastsendfun);
MSG(" ");
}
MSG("\n");
}else if(DMA1_ISR & DMA_ISR_TEIF1){
DMA1_IFCR = DMA_IFCR_CTEIF1;
MSG("in transfer error\n");
}
}

View File

@ -23,23 +23,72 @@
#ifndef __HARDWARE_INI_H__
#define __HARDWARE_INI_H__
extern volatile uint16_t ADC_value[]; // ADC DMA value
#define ADC_ADDR_MASK (GPIO6|GPIO7|GPIO8|GPIO9)
#define TRD_NO 8 // number of TRD devices
// bits used to address external SPI ADC - PD10..12
#define ADC_ADDR_MASK (GPIO10|GPIO11|GPIO12)
#define ADC_SET_ADDR(X) ((X << 10) & ADC_ADDR_MASK)
#define ADC_EN_PIN GPIO13
#define ADC_ADDR_PORT GPIOD
void SPI1_init();
void SPI2_init();
void GPIO_init();
void SysTick_init();
void ADC_init();
void ADC_calibrate_and_start();
/*
* USB interface
*/
// USB_DICS (disconnect) - PC11
#define USB_DISC_PIN GPIO11
#define USB_DISC_PORT GPIOC
// USB_POWER (high level when USB connected to PC)
#define USB_POWER_PIN GPIO10
#define USB_POWER_PORT GPIOC
// change signal level on USB diconnect pin
#define usb_disc_high() gpio_set(USB_DISC_PORT, USB_DISC_PIN)
#define usb_disc_low() gpio_clear(USB_DISC_PORT, USB_DISC_PIN)
// in case of pnp bipolar transistor on 1.5k pull-up disconnect means low level
// in case of p-channel FET on 1.5k pull-up change on/off disconnect means high level
#define usb_disconnect() usb_disc_low()
#define usb_connect() usb_disc_high()
/*
* Stepper motors
* motors' interface use timers 1 & 2, so even hardware-dependent functions are
* moved to stepper_motors.c
*/
// PE7..11 - EN
#define MOROT_EN_MASK (0x1f << 7)
#define MOTOR_EN_PORT (GPIOE)
// N == 1..5
#define MOTOR_EN_PIN(N) (GPIO6 << (N))
// PE0..PE5 - DIR
#define MOROT_DIR_MASK (0x1f)
#define MOTOR_DIR_PORT (GPIOE)
// N == 1..5
#define MOTOR_DIR_PIN(N) (GPIO0 << (N - 1))
// timers: TIM1 - PC6, TIM2 - PD15
#define MOTOR_TIM1_PORT (GPIOC)
#define MOTOR_TIM1_PIN (GPIO6)
#define MOTOR_TIM2_PORT (GPIOD)
#define MOTOR_TIM2_PIN (GPIO15)
/*
* One Wire interface
*/
// In case of using USART2 for 1-wire port, make corresponding change
// In case of using other USART for 1-wire port, make corresponding change
// and redefine pins in OW_Init
//#define OW_USART_X USART2
#define OW_USART_X USART3
#define OW_USART_X USART2
#define OW_RX_PORT GPIO_BANK_USART2_RX
#define OW_RX_PIN GPIO_USART2_RX
void init_dmatimer();
void run_dmatimer();
#endif // __HARDWARE_INI_H__

Binary file not shown.

View File

@ -24,6 +24,7 @@
#include "cdcacm.h"
#include "uart.h"
#include "spi.h"
#include "stepper_motors.h"
volatile uint32_t Timer = 0, tOVRFL = 0; // global timer (milliseconds), overflow counter
usbd_device *usbd_dev;
@ -55,10 +56,7 @@ void read_next_TRD(){
//P("Step 0: read_next_TRD, N=", uart1_send);
//print_int(N, uart1_send);
//newline(uart1_send);
GPIO_BSRR(GPIOC) = N << 6; // set address
GPIO_BSRR(GPIOC) = GPIO10; // enable com
N++; // and increment TRD counter
if(N == TRD_NO) N = 0;
gpio_set(ADC_ADDR_PORT, ADC_SET_ADDR(N) | ADC_EN_PIN); // set address & enable switch
val0 = val1 = 0;
step++;
break;
@ -102,17 +100,29 @@ void read_next_TRD(){
break;
default: // last step - turn off multiplexer
step = 0;
GPIO_BSRR(GPIOC) = (ADC_ADDR_MASK | GPIO10) << 16; // disable com & clear address bytes
gpio_clear(ADC_ADDR_PORT, ADC_ADDR_MASK | ADC_EN_PIN); // disable com & clear address bytes
N++; // and increment TRD counter
if(N == TRD_NO) N = 0;
}
}
//uint8_t curSPI = 1;
void AD7794_init(){
uint8_t i;
ad7794_on = 0;
i = reset_AD7794();
if(i != ADC_NO_ERROR){
if(i == ADC_ERR_NO_DEVICE){
MSG("ADC signal is absent! Check connection.\r\n");
// print_int(curSPI, lastsendfun);
MSG(": ADC signal is absent! Check connection.\r\n");
/* if(curSPI == 1){
curSPI = 2;
switch_SPI(SPI2);
}else{
curSPI = 1;
switch_SPI(SPI1);
}*/
}
}else{
if(!setup_AD7794(INTREFIN | REF_DETECTION | UNIPOLAR_CODING, IEXC_DIRECT | IEXC_1MA)
@ -133,11 +143,12 @@ int main(){
//rcc_clock_setup_in_hsi_out_48mhz();
// RCC clocking: 8MHz oscillator -> 72MHz system
rcc_clock_setup_in_hse_8mhz_out_72mhz();
// GPIO
GPIO_init();
gpio_set(GPIOC, GPIO11); // turn off USB
gpio_clear(GPIOC, GPIO12); // turn on LED
steppers_init();
usb_disconnect(); // turn off USB
// init USART1
UART_init(USART1);
@ -146,21 +157,26 @@ int main(){
usbd_dev = USB_init();
// init ADC
ADC_init();
// ADC_init();
// SysTick is a system timer with 1mc period
SysTick_init();
SPI1_init();
OW_Init();
// switch_SPI(SPI2); // init SPI2
// SPI_init();
switch_SPI(SPI1); // init SPI1
SPI_init();
//OW_Init();
// wait a little and then turn on USB pullup
for (i = 0; i < 0x800000; i++)
__asm__("nop");
gpio_clear(GPIOC, GPIO11);
ADC_calibrate_and_start();
usb_connect(); // turn on USB
//ADC_calibrate_and_start();
init_dmatimer();
while(1){
usbd_poll(usbd_dev);
if(usbdatalen){ // there's something in USB buffer
@ -174,10 +190,13 @@ int main(){
read_next_TRD();
}
}
process_stepper_motors(); // check flags of motors' timers
if(Timer - Old_timer > 999){ // one-second cycle
Old_timer += 1000;
gpio_toggle(GPIOC, GPIO12); // toggle LED
if(!ad7794_on) AD7794_init(); // try to init ADC if it doesn't work
//gpio_toggle(GPIOC, GPIO12); // toggle LED
//gpio_toggle(GPIO_BANK_SPI2_MOSI, GPIO_SPI2_MOSI);
//gpio_toggle(GPIO_BANK_SPI2_SCK, GPIO_SPI2_SCK);
// if(!ad7794_on) AD7794_init(); // try to init ADC if it doesn't work
//print_int(Timer/1000, usb_send);
}else if(Timer < Old_timer){ // Timer overflow
Old_timer = 0;

View File

@ -37,9 +37,12 @@
#include <libopencm3/stm32/dma.h>
#include <libopencm3/stm32/spi.h>
#include "sync.h" // mutexes
#include "user_proto.h"
#include "AD7794.h"
#include "onewire.h"
#include "stepper_motors.h"
#include "sensors.h"
#define _U_ __attribute__((__unused__))
#define U8(x) ((uint8_t) x)

View File

@ -24,8 +24,10 @@
#define OW_RST 0xf0
// In/Out buffer
uint8_t ow_buf[8];
uint8_t dev_amount = 0; // amount of 1-wire devices
uint8_t ID_buf[64] = {0}; // 1-wire devices ID buffer (8 bytes for every device)
uint8_t NUM_buf[8] = {0}; // numerical identificators for each sensor
/**
* this function sends bits of ow_byte (LSB first) to 1-wire line
* @param ow_byte - byte to convert
@ -46,22 +48,29 @@ void OW_SendBits(uint8_t ow_byte, uint8_t Nbits){
}
}
/*
* Inverce conversion - read data (not more than 8 b
*/
uint8_t OW_ReadByte(){
void OW_ClearBuff(){
UART_buff *curbuff = get_uart_buffer(OW_USART_X);
uint8_t ow_byte = 0, i, L, *buf;
if(!curbuff || !(L = curbuff->end)) return 0; // no data?
curbuff->end = 0;
}
/*
* Inverce conversion - read data (not more than 8 bits)
*/
uint8_t OW_ConvertByte(uint8_t *bits, uint8_t L){
uint8_t ow_byte = 0, i, *st = bits;
if(L > 8) L = 8; // forget all other data
buf = curbuff->buf;
for(i = 0; i < L; i++, buf++){
for(i = 0; i < L; i++, st++){
ow_byte = ow_byte >> 1; // prepare for next bit filling
if(*buf == OW_1){
if(*st == OW_1){
ow_byte |= 0x80; // MSB = 1
}
}
return ow_byte >> (8 - L); // shift to the end: L could be != 8 ???
ow_byte >>= (8 - L);
print_hex(bits, L, lastsendfun);
lastsendfun(' ');
print_hex(&ow_byte, 1, lastsendfun);
newline(lastsendfun);
return ow_byte; // shift to the end: L could be != 8 ???
}
@ -111,51 +120,60 @@ uint8_t OW_Reset() {
return 0;
}
/*
/**
* Procedure of 1-wire communications
* variables:
* sendReset - send RESET before transmission
* command - bytes sent to the bus (if we want to read, send OW_READ_SLOT)
* cLen - command buffer length (how many bytes to send)
* data - pointer for reading buffer (if reading needed)
* readStart - first byte to read (starts from 0) or OW_NO_READ (not read)
*
* return 1 if succeed, 0 if failure
* @param sendReset - send RESET before transmission
* @param command - bytes sent to the bus (if we want to read, send OW_READ_SLOT)
* @param cLen - command buffer length (how many bytes to send)
* @return 1 if succeed, 0 if failure
*/
uint8_t OW_Send(uint8_t sendReset, uint8_t *command, uint8_t cLen,
uint8_t *data, uint8_t dLen, uint8_t readStart) {
uint8_t OW_Send(uint8_t sendReset, uint8_t *command, uint8_t cLen){
// if reset needed - send RESET and check bus
if(sendReset){
if(OW_Reset() == 0){
return 0;
}
}
while(cLen > 0){
while(cLen-- > 0){
OW_SendBits(*command, 8);
command++;
cLen--;
// wait for EOT
while(!(USART_SR(OW_USART_X) & USART_SR_TC));
// put data from bus into user buffer
if(readStart == 0 && dLen > 0){
*data = OW_ReadByte();
data++;
dLen--;
}
return 1;
}
/**
* Check USART IN buffer for ready & fill user buffer with data on success
* @param buflen - expected buffer length
* @param data - pointer for reading buffer (if reading needed must be at least buflen-readStart bytes)
* @param readStart - first byte to read (starts from 0) or OW_NO_READ (not read)
* @return 0 if buffer not ready; 1 if OK
*/
uint8_t OW_Get(uint8_t buflen, uint8_t *data, uint8_t readStart){
UART_buff *curbuff = get_uart_buffer(OW_USART_X);
uint8_t *buff = curbuff->buf;
if(curbuff->end < buflen/8) return 0;
while(buflen-- > 0){
if(readStart == 0){
*data++ = OW_ConvertByte(buff, 8);
}else{
if(readStart != OW_NO_READ){
readStart--;
}
}
buff += 8;
}
curbuff->end = 0; // zero counter
return 1;
}
/*
* scan 1-wire bus
* WARNING! The procedure works in real-time, so it is VERY LONG
* num - max number of devices
* buf - array for devices' ID's (8*num bytes)
* return amount of founded devices
*/
*
uint8_t OW_Scan(uint8_t *buf, uint8_t num){
unsigned long path,next,pos;
uint8_t bit,chk;
@ -165,6 +183,8 @@ uint8_t OW_Scan(uint8_t *buf, uint8_t num) {
do{
//(issue the 'ROM search' command)
if( 0 == OW_WriteCmd(OW_SEARCH_ROM) ) return 0;
OW_Wait_TX();
OW_ClearBuff(); // clear RX buffer
next = 0; // next path to follow
pos = 1; // path bit pointer
for(cnt_byte = 0; cnt_byte != 8; cnt_byte++){
@ -172,10 +192,10 @@ uint8_t OW_Scan(uint8_t *buf, uint8_t num) {
for(cnt_bit = 0; cnt_bit != 8; cnt_bit++){
//(read two bits, 'bit' and 'chk', from the 1-wire bus)
OW_SendBits(OW_R, 2);
bit = OW_ReadByte();
OW_Wait_TX();
bit = -----OW_ReadByte();
chk = bit & 0x02; // bit 1
bit = bit & 0x01; // bit 0
//bit = (ow_buf[0] == OW_1); chk = (ow_buf[1] == OW_1);
if(bit && chk) return 0; // error
if(!bit && !chk){ // collision, both are zero
if (pos & path) bit = 1; // if we've been here before
@ -186,11 +206,54 @@ uint8_t OW_Scan(uint8_t *buf, uint8_t num) {
if (bit) buf[cnt_num*8 + cnt_byte]|=(1<<cnt_bit);
//(write 'bit' to the 1-wire bus)
OW_SendBits(bit, 1);
OW_Wait_TX();
}
}
//(output the just-completed ROM value)
path=next;
cnt_num++;
}while(path && cnt_num < num);
return cnt_num;
}*/
uint8_t OW_Scan(uint8_t *buf, uint8_t num){
uint8_t flg, b[11], i;
flg = OW_Send(1, (uint8_t*)"\xcc\x33\xff\xff\xff\xff\xff\xff\xff\xff\xff", 11);
if(!flg) return 0;
OW_Wait_TX();
if(!OW_Get(11, b, 0)) return 0;
num += 2;
for(i = 2; i < num; i++) *buf++ = b[i];
return 1;
}
//OW_USART_X
/*
void OW_getTemp(){
uint8_t buf[9], i;
void printTBuf(){
uint8_t j;
OW_Send(0, (uint8_t*)"\xbe\xff\xff\xff\xff\xff\xff\xff\xff\xff", 10, buf, 9, 1);
for(j = 0; j != 9; j++)
printInt(&buf[j], 1);
newline();
}
// send broadcast message to start measurement
if(!OW_Send(1, (uint8_t*)"\xcc\x44", 2)) return;
Delay(1000);
// read values
if(dev_amount == 1){
if(OW_WriteCmd(OW_SKIP_ROM)) printTBuf();
}else{
for(i = 0; i < dev_amount; i++){
MSG("Device ", "ow");
USB_Send_Data(i + '0');
MSG(": ", 0);
if(OW_WriteCmd(OW_MATCH_ROM)){
OW_SendOnly(0, &ID_buf[i*8], 8);
printTBuf();
}
}
}
}
*/

View File

@ -34,17 +34,20 @@
#define OW_READ_SLOT (uint8_t*)"0xff"
void OW_Init();
uint8_t OW_Send(uint8_t sendReset, uint8_t *command, uint8_t cLen,
uint8_t *data, uint8_t dLen, uint8_t readStart);
uint8_t OW_Send(uint8_t sendReset, uint8_t *command, uint8_t cLen);
uint8_t OW_Get(uint8_t buflen, uint8_t *data, uint8_t readStart);
uint8_t OW_Scan(uint8_t *buf, uint8_t num);
// shortcuts for functions
// only send message b wich length is c with RESET flag a
#define OW_SendOnly(a,b,c) OW_Send(a, b, c, (void*)0, 0, OW_NO_READ)
#define OW_SendOnly(a,b,c) OW_Send(a, b, c)
// send 1 command (with bus reset)
#define OW_WriteCmd(cmd) OW_Send(1, cmd, 1, (void*)0, 0, OW_NO_READ)
#define OW_WriteCmd(cmd) OW_Send(1, cmd, 1)
// send 1 function (without bus reset)
#define OW_WriteFn(cmd) OW_Send(0, cmd, 1, (void*)0, 0, OW_NO_READ)
#define OW_WriteFn(cmd) OW_Send(0, cmd, 1)
#define OW_Wait_TX() while(!(USART_SR(OW_USART_X) & USART_SR_TC))
void OW_getTemp();
/*
* thermometer identificator is: 8bits CRC, 48bits serial, 8bits device code (10h)

24
with_opencm3/sensors.c Normal file
View File

@ -0,0 +1,24 @@
/*
* sensors.c - funtions to work with end-switches & MOSFETs
*
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include "main.h"
#include "sensors.h"

29
with_opencm3/sensors.h Normal file
View File

@ -0,0 +1,29 @@
/*
* sensors.h
*
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#pragma once
#ifndef __SENSORS_H__
#define __SENSORS_H__
#include "hardware_ini.h"
#endif // __SENSORS_H__

View File

@ -21,6 +21,7 @@
#include "main.h"
#include "spi.h"
#include "hardware_ini.h"
// Rx/Tx buffer
volatile uint8_t SPI_TxBuffer[SPI_BUFFERSIZE];
@ -32,35 +33,31 @@ volatile uint8_t SPI_datalen = 0;
#endif
volatile uint8_t SPI_EOT_FLAG = 1; // end of transmission flag, set by interrupt
/*
* Configure SPI port
*/
void SPI1_init(){
rcc_periph_clock_enable(RCC_SPI1);
//rcc_periph_clock_enable(RCC_GPIOB); // PB3..5
rcc_periph_clock_enable(RCC_GPIOA); // PA5..7
// PA5 - SCK, PA6 - MISO, PA7 - MOSI
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO5 | GPIO7 );
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO6);
spi_reset(SPI1);
/* Set up SPI in Master mode with:
* Clock baud rate: 1/128 of peripheral clock frequency
* Clock polarity: Idle High
* Clock phase: Data valid on 2nd clock pulse
* Data frame format: 8-bit
* Frame format: MSB First
uint32_t Current_SPI = SPI1; // this is SPI interface which would b
/**
* Set current SPI to given value
*/
spi_init_master(SPI1, SPI_CR1_BAUDRATE_FPCLK_DIV_128, SPI_CR1_CPOL_CLK_TO_1_WHEN_IDLE,
SPI_CR1_CPHA_CLK_TRANSITION_2, SPI_CR1_DFF_8BIT, SPI_CR1_MSBFIRST);
nvic_enable_irq(NVIC_SPI1_IRQ); // enable SPI interrupt
void switch_SPI(uint32_t SPI){
Current_SPI = SPI;
}
void SPI_init(){
switch(Current_SPI){
case SPI1:
SPI1_init();
break;
case SPI2:
SPI2_init();
break;
default:
return; // error
}
}
//uint32_t read_end; // read timeout
/**
* Write data to SPI1
* Write data to current SPI
* @param data - buffer with data
* @param len - buffer length (<= DMA_BUFFERSIZE)
* @return 0 in case of error (or 1 in case of success)
@ -72,7 +69,7 @@ uint8_t write_SPI(uint8_t *data, uint8_t len){
//DBG("check\r\n");
while(!SPI_EOT_FLAG && Timer < tend); // wait for previous DMA interrupt
if(!SPI_EOT_FLAG){
//DBG("ERR!\r\n");
DBG("SPI error: no EOT flag!\r\n");
return 0; // error: there's no receiver???
}
if(len > SPI_BUFFERSIZE) len = SPI_BUFFERSIZE;
@ -88,9 +85,9 @@ uint8_t write_SPI(uint8_t *data, uint8_t len){
SPI_TxIndex = 0;
SPI_datalen = len; // set length of data to transmit
// start transmission - enable interrupts
SPI_CR2(SPI1) |= SPI_CR2_TXEIE | SPI_CR2_RXNEIE; //spi_enable_rx_buffer_not_empty_interrupt(SPI1); spi_enable_tx_buffer_empty_interrupt(SPI1);
SPI_CR2(Current_SPI) |= SPI_CR2_TXEIE | SPI_CR2_RXNEIE; //spi_enable_rx_buffer_not_empty_interrupt(SPI1); spi_enable_tx_buffer_empty_interrupt(SPI1);
// Enable the SPI peripheral
spi_enable(SPI1);
spi_enable(Current_SPI);
#endif // SPI_USE_DMA
return 1;
}
@ -108,7 +105,7 @@ uint8_t *read_SPI(uint8_t *data, uint8_t len){
//DBG("check\r\n");
while((!SPI_EOT_FLAG || len != SPI_RxIndex) && Timer < tend);
if(len != SPI_RxIndex){
//DBG("ERR\r\n");
//DBG("SPI error: bad data length\r\n");
return NULL;
}
//DBG("OK\r\n");

View File

@ -31,9 +31,11 @@ typedef enum{
SPI_READ_ERROR
} SPI_read_status;
void SPI1_init();
void SPI_init();
uint8_t write_SPI(uint8_t *data, uint8_t len);
SPI_read_status check_SPI();
uint8_t *read_SPI(uint8_t *data, uint8_t len);
void switch_SPI(uint32_t SPI);
#endif // __SPI_H__

View File

@ -0,0 +1,212 @@
/*
* stepper_motors.c - moving of stepper motors
*
* Copyright 2014 Edward V. Emelianoff <eddy@sao.ru>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include "main.h"
static uint8_t timers_activated[2] = {0, 0}; // flag of activated timers
uint16_t Motor_period[2] = {10000, 10000}; // near 100 steps per second
volatile uint8_t timer_flag[2] = {0,0};
// amount of steps for each motor
volatile uint32_t Motor_steps[5] = {0, 0, 0, 0, 0};
// flag of active motor
volatile uint8_t Motor_active[5] = {0, 0, 0, 0, 0};
/**
* Setup stepper motors' timer Tim
* N == 0 for TIM3, == 1 for TIM4
*/
static void setup_timer(uint8_t N){
uint32_t Tim;
switch (N){
case 0:
Tim = TIM3;
nvic_enable_irq(NVIC_TIM3_IRQ);
break;
case 1:
Tim = TIM4;
nvic_enable_irq(NVIC_TIM4_IRQ);
break;
default:
return;
}
timer_reset(Tim);
// timers have frequency of 2MHz, 2 pulse == 1 microstep
// 36MHz of APB1
timer_set_mode(Tim, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
// 72MHz div 36 = 2MHz
timer_set_prescaler(Tim, 35); // prescaler is (div - 1)
timer_continuous_mode(Tim); // automatically reload
timer_enable_preload(Tim); // force changing period
timer_set_period(Tim, Motor_period[N] - 1);
timer_enable_update_event(Tim);
timer_enable_irq(Tim, TIM_DIER_UIE); // update IRQ enable
timer_enable_counter(Tim);
timers_activated[N] = 1;
lastsendfun('3' + N);
MSG(" timer\n");
}
/**
* Set up motors pins & activate timers 3 & 4
* Timer3 gives ticks to motors 1..3 (turrets)
* Timer4 gives ticks to motors 4,5 (long & short stages)
*
* Timers are always work, stopping motors can be done by EN
* Timers simply works as counters, no PWM mode
*/
void steppers_init(){
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN |
RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | RCC_APB2ENR_IOPEEN);
rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_TIM3EN | RCC_APB1ENR_TIM4EN);
// timer pins
gpio_set_mode(MOTOR_TIM1_PORT, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, MOTOR_TIM1_PIN);
gpio_set_mode(MOTOR_TIM2_PORT, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, MOTOR_TIM2_PIN);
// EN pins
gpio_set_mode(MOTOR_EN_PORT, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, MOROT_EN_MASK);
// DIR pins
gpio_set_mode(MOTOR_DIR_PORT, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, MOROT_DIR_MASK);
setup_timer(0);
setup_timer(1);
}
/**
* Move motor Motor_number to User_value steps
*/
void move_motor(uint8_t num, int32_t steps){
if(steps == 0) return;
// check whether motor is moving
if(Motor_active[num]){
MSG("err: moving\r\n");
return;
}
if(steps < 0){
steps = -steps;
gpio_set(MOTOR_DIR_PORT, MOTOR_DIR_PIN(num)); // set DIR bit to rotate ccw
}else
gpio_clear(MOTOR_DIR_PORT, MOTOR_DIR_PIN(num)); // reset DIR bit
Motor_steps[num] = steps << 4; // multiply by 16 to get usteps count
Motor_active[num] = 1;
gpio_set(MOTOR_EN_PORT, MOTOR_EN_PIN(num)); // activate motor
}
void stop_motor(uint8_t num){
if(!Motor_active[num]) return;
MSG("stop motor ");
lastsendfun('0' + num);
MSG("\r\n");
gpio_clear(MOTOR_EN_PORT, MOTOR_EN_PIN(num));
Motor_active[num] = 0;
}
/**
* Check flags set by timers & do next:
* - decrease step counter if it isn't zero;
* - stop motor if counter is zero but motor still active
*/
void process_stepper_motors(){
int i, j;
const uint32_t ports[] = {MOTOR_TIM1_PORT, MOTOR_TIM2_PORT};
const uint32_t pins[] = {MOTOR_TIM1_PIN, MOTOR_TIM2_PIN};
const uint8_t startno[] = {0, 3};
const uint8_t stopno[] = {3, 5};
for(j = 0; j < 2; j++){
if(timer_flag[j]){
timer_flag[j] = 0;
gpio_toggle(ports[j], pins[j]); // change clock state
if(gpio_get(ports[j], pins[j])){ // positive pulse - next microstep
for(i = startno[j]; i < stopno[j]; i++){ // check motors
if(Motor_steps[i]) Motor_steps[i]--;
else if(Motor_active[i]){ // stop motor - all done
stop_motor(i);
}
}
}
}
}
}
/**
* Stop timers; turn off motor voltage
*
void stop_timer(){
// disable IRQs & stop timer
TIM_Cmd(SM_Timer, DISABLE);
TIM_ITConfig(SM_Timer, TIM_IT_Update, DISABLE);
// turn off power
SM_EN_GPIOx->BRR = SM_EN_PINS; // reset all EN bits
SM_PUL_GPIOx->BRR = SM_PUL_PIN; // reset signal on PUL
timers_activated = 0;
Motor_steps = 0;
}*/
/**
* Sets motor period to user value & refresh timer
* @param num - number of motor
* @param period - period of one STEP in microseconds
*/
void set_motor_period(uint8_t num, uint16_t period){
uint32_t Tim, N;
switch (num){
case 1:
case 2:
case 3:
Tim = TIM3;
N = 0;
break;
case 4:
case 5:
Tim = TIM4;
N = 1;
break;
default:
MSG("err: bad motor");
return;
}
period >>= 4; // divide by 4 to get 16usteps for one step
if(period == 0) Motor_period[N] = 1;
else Motor_period[N] = period;
if(!timers_activated[N]) setup_timer(N);
else timer_set_period(Tim, period);
}
/*
* Interrupts: just set flag
*/
void tim3_isr(){
if(timer_get_flag(TIM3, TIM_SR_UIF)){
// Clear compare interrupt flag
timer_clear_flag(TIM3, TIM_SR_UIF);
timer_flag[0] = 1;
}
}
void tim4_isr(){
if(timer_get_flag(TIM4, TIM_SR_UIF)){
// Clear compare interrupt flag
timer_clear_flag(TIM4, TIM_SR_UIF);
timer_flag[1] = 1;
}
}

View File

@ -0,0 +1,33 @@
/*
* stepper_motors.h
*
* Copyright 2014 Edward V. Emelianoff <eddy@sao.ru>
*
* 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 __STEPPER_MOTORS_H__
#define __STEPPER_MOTORS_H__
#include <libopencm3/stm32/timer.h>
void steppers_init();
void process_stepper_motors();
void move_motor(uint8_t num, int32_t steps);
void stop_motor(uint8_t num);
void set_motor_period(uint8_t num, uint16_t period);
#endif // __STEPPER_MOTORS_H__

88
with_opencm3/sync.c Normal file
View File

@ -0,0 +1,88 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2012 Fergus Noble <fergusnoble@gmail.com>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libopencm3/cm3/sync.h>
/* DMB is supported on CM0 */
void __dmb()
{
__asm__ volatile ("dmb");
}
/* Those are defined only on CM3 or CM4 */
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
uint32_t __ldrex(volatile uint32_t *addr)
{
uint32_t res;
__asm__ volatile ("ldrex %0, [%1]" : "=r" (res) : "r" (addr));
return res;
}
uint32_t __strex(uint32_t val, volatile uint32_t *addr)
{
uint32_t res;
__asm__ volatile ("strex %0, %2, [%1]"
: "=&r" (res) : "r" (addr), "r" (val));
return res;
}
void mutex_lock(mutex_t *m)
{
uint32_t status = 0;
do {
/* Wait until the mutex is unlocked. */
while (__ldrex(m) != MUTEX_UNLOCKED);
/* Try to acquire it. */
status = __strex(MUTEX_LOCKED, m);
/* Did we get it? If not then try again. */
} while (status != 0);
/* Execute the mysterious Data Memory Barrier instruction! */
__dmb();
}
void mutex_unlock(mutex_t *m)
{
/* Ensure accesses to protected resource are finished */
__dmb();
/* Free the lock. */
*m = MUTEX_UNLOCKED;
}
/*
* Try to lock mutex
* if it's already locked or there was error in STREX, return MUTEX_LOCKED
* else return MUTEX_UNLOCKED
*/
mutex_t mutex_trylock(mutex_t *m){
uint32_t status = 0;
mutex_t old_lock = __ldrex(m); // get mutex value
// set mutex
status = __strex(MUTEX_LOCKED, m);
if(status == 0) __dmb();
else old_lock = MUTEX_LOCKED;
return old_lock;
}
#endif

53
with_opencm3/sync.h Normal file
View File

@ -0,0 +1,53 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2012 Fergus Noble <fergusnoble@gmail.com>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef LIBOPENCM3_CM3_SYNC_H
#define LIBOPENCM3_CM3_SYNC_H
void __dmb(void);
/* Implements synchronisation primitives as discussed in the ARM document
* DHT0008A (ID081709) "ARM Synchronization Primitives" and the ARM v7-M
* Architecture Reference Manual.
*/
/* --- Exclusive load and store instructions ------------------------------- */
/* Those are defined only on CM3 or CM4 */
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
uint32_t __ldrex(volatile uint32_t *addr);
uint32_t __strex(uint32_t val, volatile uint32_t *addr);
/* --- Convenience functions ----------------------------------------------- */
/* Here we implement some simple synchronisation primitives. */
typedef uint32_t mutex_t;
#define MUTEX_UNLOCKED 0
#define MUTEX_LOCKED 1
void mutex_lock(mutex_t *m);
void mutex_unlock(mutex_t *m);
mutex_t mutex_trylock(mutex_t *m);
#endif
#endif

View File

@ -74,7 +74,7 @@ void UART_setspeed(uint32_t UART, struct usb_cdc_line_coding *lc){
void UART_init(uint32_t UART){
uint32_t irq, rcc, rccgpio, gpioport, gpiopin;
switch(UART){
case USART2:
case USART2: // 1-wire
irq = NVIC_USART2_IRQ; // interrupt for given USART
rcc = RCC_USART2; // RCC timing of USART
rccgpio = RCC_GPIOA; // RCC timing of GPIO pin (for output)
@ -84,7 +84,7 @@ void UART_init(uint32_t UART){
gpioport = GPIO_BANK_USART2_TX;
gpiopin = GPIO_USART2_TX;
break;
case USART3:
case USART3: // without remapping
irq = NVIC_USART3_IRQ;
rcc = RCC_USART3;
rccgpio = RCC_GPIOB;
@ -106,10 +106,19 @@ void UART_init(uint32_t UART){
// enable clocking
rcc_periph_clock_enable(RCC_AFIO); // alternate functions
rcc_periph_clock_enable(rcc); // USART
rcc_periph_clock_enable(rccgpio); // output pin
rcc_periph_clock_enable(rccgpio); // GPIO pins
// enable output pin
if(UART == OW_USART_X){ // one wire
// TX: open-drain output
gpio_set_mode(gpioport, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, gpiopin);
// RX: floating input
gpio_set_mode(OW_RX_PORT, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_FLOAT, OW_RX_PIN);
}else{
gpio_set_mode(gpioport, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, gpiopin);
}
// enable IRQ
nvic_enable_irq(irq);
UART_setspeed(UART, NULL);

View File

@ -24,7 +24,7 @@
#define __UART_H__
// Size of buffers
#define UART_TX_DATA_SIZE 64
#define UART_TX_DATA_SIZE 128
typedef struct {
uint8_t buf[UART_TX_DATA_SIZE];

View File

@ -26,6 +26,8 @@
// integer value given by user
static volatile int32_t User_value = 0;
// number of motor to process
static volatile uint8_t active_motor = 6;
// last active send function - to post "anonymous" replies
sendfun lastsendfun = usb_send; // make it usb_send by default (to prevent suspension)
// flag: !=0 when user value reading ends - for character terminals
@ -62,7 +64,8 @@ void print_ad_vals(sendfun s){
void parce_incoming_buf(char *buf, int len, sendfun s){
uint8_t command;
int i = 0, j;
uint8_t onewire_addr[8];
int i = 0, j, m;
lastsendfun = s;
if(Uval_ready == UVAL_START){ // we are in process of user's value reading
i += read_int(buf, len);
@ -78,11 +81,40 @@ void parce_incoming_buf(char *buf, int len, sendfun s){
for(; i < len; i++){
command = buf[i];
if(!command) continue; // omit zero
switch (command){
case '1': // single conversion
if(command >= '0' && command <= '4'){ // stepper motors
active_motor = command - '0';
I = stepper_proc;
READINT();
}else switch (command){
case 'P':
run_dmatimer();
break;
case 'x': // set period of TIM1 (motors 1..3)
active_motor = 1;
I = set_timr;
READINT();
break;
case 'X': // set period of TIM2 (motors 4,5)
active_motor = 4;
I = set_timr;
READINT();
break;
case 'B': // stop all motors
for(m = 0; m < 5; m++)
stop_motor(m);
break;
case 'W': // scan for one 1-wire device
if(1 == OW_Scan(onewire_addr, 1)){
P("found 1-wire: ", s);
print_hex(onewire_addr, 8, s);
}else
P("1-wire error",s );
P("\r\n", s);
break;
case 'S': // single conversion
doubleconv = 0;
break;
case '2': // double conversion
case 'D': // double conversion
doubleconv = 1;
break;
case 'A': // show ADC value
@ -94,19 +126,12 @@ void parce_incoming_buf(char *buf, int len, sendfun s){
}
newline(s);
break;
case 'b': // turn LED off
gpio_set(GPIOC, GPIO12);
break;
case 'B': // turn LED on
gpio_clear(GPIOC, GPIO12);
break;
case 'I': // read & print integer value
I = process_int;
READINT();
break;
case 'i': // init AD7794
AD7794_init();
break;
case 'I': // turn off flag AD7794
ad7794_on = 0;
break;
case '+': // user check number value & confirm it's right
if(Uval_ready == UVAL_PRINTED) Uval_ready = UVAL_CHECKED;
else WRONG_COMMAND();
@ -140,9 +165,9 @@ void parce_incoming_buf(char *buf, int len, sendfun s){
print_time(s);
newline(s);
break;
case 'U': // test: init USART1
/* case 'U': // test: init USART1
UART_init(USART1);
break;
break; */
case '\n': // show newline as is
break;
case '\r':
@ -210,6 +235,27 @@ int read_int(char *buf, int cnt){
return readed;
}
/**
* Print buff as hex values
* @param buf - buffer to print
* @param l - buf length
* @param s - function to send a byte
*/
void print_hex(uint8_t *buff, uint8_t l, sendfun s){
void putc(uint8_t c){
if(c < 10)
s(c + '0');
else
s(c + 'a' - 10);
}
s('0'); s('x'); // prefix 0x
while(l--){
putc(buff[l] >> 4);
putc(buff[l] & 0x0f);
}
}
/**
* Print decimal integer value
* @param N - value to print
@ -230,12 +276,14 @@ void print_int(int32_t N, sendfun s){
}else s('0');
}
/*
void process_int(int32_t v, sendfun s){
newline(s);
P("You have entered a value ", s);
print_int(v, s);
newline(s);
}
*/
void set_ADC_gain(int32_t v, sendfun s){
if(ad7794_on){
@ -246,3 +294,34 @@ void set_ADC_gain(int32_t v, sendfun s){
AD7794_calibration(0);
}
}
/**
* Process stepper
* @param v - user value
* @param s - active sendfunction
*/
void stepper_proc(int32_t v, sendfun s){
if(active_motor > 4){
P("wrong motor number\r\n", s);
return; // error
}
MSG("move ");
lastsendfun('0' + active_motor);
MSG(" to ");
print_int(v, lastsendfun);
MSG("\r\n");
move_motor(active_motor, v);
active_motor = 6;
}
void set_timr(int32_t v, sendfun s){
if(active_motor > 4){
P("wrong motor number\r\n", s);
return; // error
}
MSG("set period: ");
print_int(v, lastsendfun);
MSG("\r\n");
set_motor_period(active_motor, (uint16_t)v);
active_motor = 6;
}

View File

@ -50,8 +50,11 @@ void print_int(int32_t N, sendfun s);
void parce_incoming_buf(char *buf, int len, sendfun s);
void process_int(int32_t v, sendfun s);
// void process_int(int32_t v, sendfun s);
void set_ADC_gain(int32_t v, sendfun s);
void print_ad_vals(sendfun s);
void stepper_proc(int32_t v, sendfun s);
void set_timr(int32_t v, sendfun s);
void print_hex(uint8_t *buff, uint8_t l, sendfun s);
#endif // __USER_PROTO_H__