diff --git a/Makefile b/Makefile index 9d4b473..69c7429 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,6 @@ OBJS += utils/nvic.o OBJS += utils/str_utils.o OBJS += init.o OBJS += blink.o -OBJS += capture.o OBJS += lib/common.o ################################################################ diff --git a/README.md b/README.md new file mode 100644 index 0000000..86373df --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +This is a bootstrap project for programming STM32L100 without any external libs (with just libc). + +It uses `arm-none-eabi-gcc` and is written for STM32L100C-DISCOVERY. diff --git a/capture.c b/capture.c deleted file mode 100644 index 1b78fee..0000000 --- a/capture.c +++ /dev/null @@ -1,77 +0,0 @@ -#include "capture.h" -#include "utils/timebase.h" -#include - -uint16_t adc_measure(uint8_t channel) -{ - ADC1_SQR5 = channel; // select n-th channel - ADC1_SQR1 = 0; // sets length to 1 (0000) - - ADC1_CR2 |= ADC_CR2_SWSTART; // start conversion - - // wait for end of conversion - while (!(ADC1_SR & ADC_SR_EOC)); - return ADC1_DR; -} - - -float measure_angle(void) -{ - uint16_t d = adc_measure(18); - return -135 + 270 * (d / 4095.0f); -} - - -float measure_exposure(void) -{ - uint16_t d = adc_measure(8); - float alpha = d / 4095.0f; - return alpha * 100; // % -} - - -float measure_resistance(void) -{ - uint16_t d = adc_measure(9); - - float alpha = d / 4095.0f; - float ref_r = 330; - - return (ref_r * alpha) / (1 - alpha); -} - - -float measure_temp(void) -{ - uint16_t ts_data = adc_measure(ADC_CH_TEMP); - - // temperature calibration constants for L100 are undocumented, - // probably because the sensor is broken. - - // Temperature sensor is unstable and unreliable. - - uint16_t ts_cal1 = MMIO16(0x1FF800FA); - uint16_t ts_cal2 = MMIO16(0x1FF800FE); - - return ((80.0f / (ts_cal2 - ts_cal1)) * (ts_data - ts_cal1) + 30.0f); -} - - -void pwm2_set_frequency(float hz) -{ - float core_clk = 16000000 / 2.0f; // prescaller - - float cnt = core_clk / hz; - - uint32_t div = (uint32_t)cnt; - - if (hz < 150) { - div /= 8; - TIM2_PSC = 15; - } else { - TIM2_PSC = 1; - } - - TIM2_ARR = div; // sets frequency - TIM2_CCR2 = TIM2_ARR/2; // duty cycle -} diff --git a/capture.h b/capture.h deleted file mode 100644 index 0c6c8c1..0000000 --- a/capture.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include - -uint16_t adc_measure(uint8_t channel); -float measure_temp(void); -float measure_angle(void); -float measure_resistance(void); -float measure_exposure(void); - -void pwm2_set_frequency(float hz); diff --git a/doc/controls.txt b/doc/controls.txt deleted file mode 100644 index fc41a49..0000000 --- a/doc/controls.txt +++ /dev/null @@ -1,3 +0,0 @@ -b,d - změna střídy PWM, krok 50 (rozsah 0-1000) -m,n - změna hodnoty DAC, krok 117 (rozsah 0-4095) -g - nulovat počítadlo závory diff --git a/doc/output.txt b/doc/output.txt deleted file mode 100644 index a596df0..0000000 --- a/doc/output.txt +++ /dev/null @@ -1 +0,0 @@ -T -179.6°C | An -6.6° | R 589.2 | L 1.8% | G 0, #0 | DA 4095 | PWM 1000 diff --git a/init.c b/init.c index ed0d5e6..15a4200 100644 --- a/init.c +++ b/init.c @@ -4,17 +4,15 @@ #include "utils/usart.h" #include "utils/nvic.h" +// This file contains examples of initializing some peripherals + void init_gpios(void) { - gpio_enable(GPIOA); - gpio_enable(GPIOB); gpio_enable(GPIOC); // LEDs gpio_set_mode(GPIOC, BIT8 | BIT9, MODER_OUTPUT); - - gpio_set_mode(GPIOC, BIT11, MODER_INPUT); } @@ -42,7 +40,7 @@ void init_usart(void) { gpio_set_af(GPIOA, BIT2 | BIT3, AF7); - // USART at A2 (tx), A3 (rx) + // USART2 at A2 (tx), A3 (rx) RCC_APB1ENR |= RCC_APB1ENR_USART2EN; // RATE 9600Bd 104.1875 (see datasheet for reference) @@ -61,24 +59,18 @@ void init_usart(void) void init_systick(void) { - //SysTick_CSR = (SysTick_CSR & ~SysTick_CSR_CLKSOURCE) | (1 << __CTZ(SysTick_CSR_CLKSOURCE)); - patch_register(SysTick_CSR, SysTick_CSR_CLKSOURCE, 1); // 1 - core, 0 - div 8 SysTick_RELOAD = 16000; // 1ms interrupt @ 16MHz core clock SysTick_CSR |= SysTick_CSR_TICKINT | SysTick_CSR_ENABLE; } +// ---- + void init_adc(void) { - // B1 ... AN9 Vcc o--[330R]--(B1)--[?R]--| GND - // B0 ... AN8 fototransistor - // B12 .. AN18 "angle" potentiometer - // C5 ... AN15 - - gpio_set_mode(GPIOB, BIT1 | BIT0 | BIT12, MODER_ANALOG); - //gpio_set_mode(GPIOC, BIT5, MODER_ANALOG); + gpio_set_mode(GPIOB, BIT1 | BIT0 | BIT12, MODER_ANALOG); // configure pins you want to use // enable clock for ADC RCC_APB2ENR |= RCC_APB2ENR_ADC1EN; @@ -98,6 +90,22 @@ void init_adc(void) while (!(ADC1_SR & ADC_SR_ADONS)); } +// EXAMPLE to measure an ADC channel +uint16_t adc_measure(uint8_t channel) +{ + ADC1_SQR5 = channel; // select n-th channel + ADC1_SQR1 = 0; // sets length to 1 (0000) + + ADC1_CR2 |= ADC_CR2_SWSTART; // start conversion + + // wait for end of conversion + while (!(ADC1_SR & ADC_SR_EOC)); + return ADC1_DR; +} + + +// ---- + void init_dac(void) { @@ -117,7 +125,7 @@ void init_pwm1(void) RCC_APB1ENR |= RCC_APB1ENR_TIM3EN; // using timer 3, channel 1 - gpio_set_af(GPIOA, BIT6, AF2); + gpio_set_af(GPIOA, BIT6, AF2); // A6 PWM output patch_register(TIM3_CCMR1, TIM_CCMR1_OC1M, TIM_OCM_PWM1); // set PWM1 mode @@ -139,51 +147,3 @@ void init_pwm1(void) TIM3_CR1 |= TIM_CR1_CEN; // enable timer. } - - -// pwm with variable frequency -void init_pwm2(void) -{ - // enable clock for the timer - RCC_APB1ENR |= RCC_APB1ENR_TIM2EN; - - // using timer 2, channel 2 - PA1 - gpio_set_af(GPIOA, BIT1, AF1); - - patch_register(TIM2_CCMR1, TIM_CCMR1_OC2M, TIM_OCM_PWM1); // set PWM1 mode - - TIM2_CCMR1 |= TIM_CCMR1_OC2PE; // preload enable - TIM2_CR1 |= TIM_CR1_ARPE; // auto reload is buffered - TIM2_CCER |= TIM_CCER_CC2E; // enable output compare (PWM output) - - patch_register(TIM2_CR1, TIM_CR1_CMS, TIM_CMS_EDGE); // centering mode - patch_register(TIM2_CR1, TIM_CR1_DIR, 0); // count upwards only - - // frequency set to 16 kHz - - /* - TIM2_PSC = 32; // prescaller - TIM2_ARR = 1000; // sets frequency - TIM2_CCR2 = 500; // duty cycle - */ - - TIM2_PSC = 1; // prescaller - TIM2_ARR = 1600; // sets frequency - TIM2_CCR2 = 500; // duty cycle - - // generate update event to latch the value registers - TIM2_EGR |= TIM_EGR_UG; - - TIM2_CR1 |= TIM_CR1_CEN; // enable timer. -} - - - - - - - - - - - diff --git a/init.h b/init.h index afc1b3e..a8d62f6 100644 --- a/init.h +++ b/init.h @@ -8,4 +8,3 @@ void init_systick(void); void init_adc(void); void init_dac(void); void init_pwm1(void); -void init_pwm2(void); diff --git a/main.c b/main.c index 1d211ba..698b1d3 100644 --- a/main.c +++ b/main.c @@ -9,16 +9,6 @@ #include "init.h" #include "blink.h" -#include "capture.h" - -// Gate state -static bool gate_closed = false; -static uint32_t gate_cnt = 0; - -static float exposure_out, exposure_accum; -static uint32_t exposure_cnt; - -static uint32_t pwm2_f = 50; /** IRQ */ void USART2_IRQHandler(void) @@ -33,81 +23,15 @@ void USART2_IRQHandler(void) // handle incoming char. char c = usart_rx_char(USART2); - - uint32_t pwm2_f_old = pwm2_f; - - switch (c) { - case 'g': // nulovat pocitadlo preruseni - gate_cnt = 0; - break; - - case 'm': // zvysit DAC hodnotu - if (DAC_DHR12R1 < 4095) DAC_DHR12R1 += 117; - break; - - case 'n': // snizit DAC hodnotu - if (DAC_DHR12R1 > 0) DAC_DHR12R1 -= 117; - break; - - case 'b': // zvysit PWM stridu - if (TIM3_CCR1 < 1000) TIM3_CCR1 += 50; - break; - - case 'd': // snizit PWM stridu - if (TIM3_CCR1 > 0) TIM3_CCR1 -= 50; - break; - - case 'f': // zvysit PWM stridu - if (pwm2_f < 20000) pwm2_f += 10; - break; - - case 's': // snizit PWM stridu - if (pwm2_f > 20) pwm2_f -= 10; - break; - - case 'F': // zvysit PWM stridu - if (pwm2_f < 20000-100) pwm2_f += 100; - break; - - case 'S': // snizit PWM stridu - if (pwm2_f > 100) { - pwm2_f -= 100; - } else { - pwm2_f = 20; - } - - if (pwm2_f < 20) pwm2_f = 20; - - break; - - default: - break; - } - - if (pwm2_f_old != pwm2_f) { - pwm2_set_frequency(pwm2_f); - } + + // echo + usart_tx_char(USART2, c); USART2_SR ^= USART_SR_RXNE; } } - -// Gate close handler -void gate_close(void) -{ - gate_closed = 1; - gate_cnt++; -} - -// Gate open handler -void gate_open(void) -{ - gate_closed = 0; -} - - /** Init peripherals; Called by startup script, before main() */ void SystemInit(void) { @@ -118,82 +42,15 @@ void SystemInit(void) init_adc(); init_dac(); init_pwm1(); - init_pwm2(); - - pwm2_set_frequency(50); - - register_periodic_task(green_toggle, 1000); // indicate running state - - register_debounced_pin(GPIOB, 11, gate_close, gate_open); // gate handler } - int main(void) { - char buf[200]; - - usart_tx_string(USART2, "DAQ system started.\n"); - delay_ms(100); + usart_tx_string(USART2, "Hello.\n"); - bool first = true; while (1) { - float cels = measure_temp(); - float angle = measure_angle(); - float resis = measure_resistance(); - float expos = measure_exposure(); - - // --- exposure averaging - exposure_accum += expos; - exposure_cnt++; - - if (exposure_cnt >= 5) { - exposure_out = exposure_accum / exposure_cnt; - exposure_accum = 0; - exposure_cnt = 0; - } - - if (first) { - exposure_out = expos; // pretend it's averaged - } - // --- - - - buf_reset(buf); - buf_append_str(buf, "T "); - buf_append_flt(buf, cels, 1); - buf_append_str(buf, "°C | "); - - buf_append_str(buf, "An "); - buf_append_flt(buf, angle, 1); - buf_append_str(buf, "° | "); - - buf_append_str(buf, "R "); - buf_append_flt(buf, resis, 1); - buf_append_str(buf, " | "); - - buf_append_str(buf, "L "); - buf_append_flt(buf, exposure_out, 1); - buf_append_str(buf, "% | "); - - buf_append_str(buf, "G "); - buf_append_str(buf, gate_closed ? "1" : "0"); - buf_append_str(buf, ", #"); - buf_append_int(buf, gate_cnt); - buf_append_str(buf, " | "); - - buf_append_str(buf, "DA "); - buf_append_int(buf, DAC_DHR12R1); - buf_append_str(buf, " | "); - - buf_append_str(buf, "PWM "); - buf_append_int(buf, TIM3_CCR1); - - buf_append_str(buf, "\n"); - - usart_tx_string(USART2, buf); - - delay_ms(100); - first = false; + delay_ms(500); + green_toggle(); } }