Skip to content
Snippets Groups Projects
Commit 21f20e12 authored by Werner Sembach's avatar Werner Sembach
Browse files

Initial Commit

parents
No related branches found
No related tags found
No related merge requests found
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
void adc_init();
uint16_t adc_get(uint8_t channel);
#ifdef __cplusplus
}
#endif
#pragma once
#include <stdint.h>
#define DC_LEFT 0
#define DC_RIGHT 1
#ifdef __cplusplus
extern "C" {
#endif
void dc_init();
void dc_set(uint8_t direction, uint8_t speed);
#ifdef __cplusplus
}
#endif
#pragma once
#include <stdint.h>
#define BUTTON_PUSHED 1
#define BUTTON_RELEASED 0
#ifdef __cplusplus
extern "C" {
#endif
void button_init();
int button_get();
#ifdef __cplusplus
}
#endif
#pragma once
#include <stdint.h>
#define SERVO_0 0
#define SERVO_1 1
#define SERVO_2 2
#define SERVO_3 3
#ifdef __cplusplus
extern "C" {
#endif
void servo_init();
void servo_set(uint8_t servo, uint8_t position);
#ifdef __cplusplus
}
#endif
#include "ADC.h"
#include <libopencm3/stm32/adc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/rcc.h>
extern "C" void adc_init() {
rcc_clock_setup_hse_3v3(&rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_168MHZ]);
rcc_periph_clock_enable(RCC_ADC1);
gpio_mode_setup(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO1);
adc_power_off(ADC1);
adc_disable_scan_mode(ADC1);
adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_3CYC);
adc_power_on(ADC1);
}
extern "C" uint16_t adc_get(uint8_t channel) {
uint8_t channel_array[16];
channel_array[0] = channel;
adc_set_regular_sequence(ADC1, 1, channel_array);
adc_start_conversion_regular(ADC1);
while (!adc_eoc(ADC1));
uint16_t reg16 = adc_read_regular(ADC1);
return reg16;
}
#include "DCMotor.h"
#include <cyg/hal/hal_arch.h>
#include <libopencm3/cm3/common.h>
#include <libopencm3/stm32/timer.h>
#include <libopencm3/stm32/f4/rcc.h>
#include <libopencm3/stm32/f4/gpio.h>
#define GPIO_B0 CYGHWR_HAL_STM32_PIN_ALTFN_OUT(B, 0, 2, PUSHPULL, NONE, LOW)
#define GPIO_B1 CYGHWR_HAL_STM32_PIN_ALTFN_OUT(B, 1, 2, PUSHPULL, NONE, LOW)
// The timer ticks per microsecond. Can be adjusted by measuring PWM on an oscilloscope.
#define PWM_TIMER_TICKS_PER_MICROSECOND 86.0
// PWM Frequency, default is 62 kHz
#define PWM_FREQUENCY_kHz 8
// PWM Period, set automatically by the options above
#define PWM_PERIOD ((1.0/PWM_FREQUENCY_kHz) * 1000.0 * PWM_TIMER_TICKS_PER_MICROSECOND / 2)
#define GPIO_C4 CYGHWR_HAL_STM32_PIN_OUT(C, 4, PUSHPULL, NONE, LOW)
#define GPIO_C5 CYGHWR_HAL_STM32_PIN_OUT(C, 5, PUSHPULL, NONE, LOW)
static void pwm_init(uint32_t timer, uint8_t channel, uint32_t period) {
// Function stolen from somewhere on stackoverflow
// Convert channel number to internal rep
enum tim_oc_id chan;
switch (channel) {
case 1:
chan = TIM_OC1;
break;
case 2:
chan = TIM_OC2;
break;
case 3:
chan = TIM_OC3;
break;
case 4:
chan = TIM_OC4;
break;
default:
chan = TIM_OC4;
break;
}
// Timer Base Configuration
// timer_reset(timer);
// clock division, Center-aligned mode selection, TIMx_CR1 DIR: Direction
timer_set_mode(timer, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
timer_continuous_mode(timer); // Disables TIM_CR1_OPM (One pulse mode)
timer_set_period(timer, period); // Sets TIMx_ARR
timer_set_prescaler(timer, 1); // Adjusts speed of timer
timer_set_clock_division(timer, 0); // Adjusts speed of timer
timer_set_master_mode(timer, TIM_CR2_MMS_UPDATE); // Master Mode Selection
timer_enable_preload(timer); // Set ARPE bit in TIMx_CR1
// Channel-specific settings
timer_set_oc_value(timer, chan, 0); // sets TIMx_CCRx
timer_set_oc_mode(timer, chan, TIM_OCM_PWM1); // Sets PWM Mode 1
timer_enable_oc_preload(timer, chan); // Sets OCxPE in TIMx_CCMRx
timer_set_oc_polarity_high(timer, chan); // set desired polarity in TIMx_CCER
timer_enable_oc_output(timer, chan); // set CCxE bit in TIMx_CCER (enable output)
// Initialize all counters in the register
switch (timer) {
case TIM1:
TIM1_EGR |= TIM_EGR_UG;
break;
case TIM2:
TIM2_EGR |= TIM_EGR_UG;
break;
case TIM3:
TIM3_EGR |= TIM_EGR_UG;
break;
case TIM4:
TIM4_EGR |= TIM_EGR_UG;
break;
case TIM5:
TIM5_EGR |= TIM_EGR_UG;
break;
case TIM6:
TIM6_EGR |= TIM_EGR_UG;
break;
case TIM7:
TIM7_EGR |= TIM_EGR_UG;
break;
case TIM8:
TIM8_EGR |= TIM_EGR_UG;
break;
default:
break;
}
}
static void pwm_setup(void) {
rcc_periph_clock_enable(RCC_TIM3);
pwm_init(TIM3, 1, PWM_PERIOD);
pwm_init(TIM3, 2, PWM_PERIOD);
pwm_init(TIM3, 3, PWM_PERIOD);
pwm_init(TIM3, 4, PWM_PERIOD);
// PWM channels = PB0, PB1
// AHB1-bus ? _ gpIO Port D ENable
rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPBEN);
// AF = alternate function
gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO0 | GPIO1);
// AF2 = TIM3_CH1..4
gpio_set_af(GPIOB, GPIO_AF2, GPIO0 | GPIO1);
timer_enable_counter(TIM3);
}
void dc_init() {
CYGHWR_HAL_STM32_GPIO_SET(GPIO_C4);
CYGHWR_HAL_STM32_GPIO_SET(GPIO_C5);
CYGHWR_HAL_STM32_GPIO_OUT(GPIO_C4, 1);
CYGHWR_HAL_STM32_GPIO_OUT(GPIO_C5, 1);
pwm_setup();
CYGHWR_HAL_STM32_GPIO_SET(GPIO_B0);
CYGHWR_HAL_STM32_GPIO_SET(GPIO_B1);
}
void dc_set(uint8_t direction, uint8_t speed){
if (direction == DC_RIGHT) {
timer_set_oc_value(TIM3, TIM_OC4, 0);
timer_set_oc_value(TIM3, TIM_OC3, speed * PWM_PERIOD / 255);
}
else if (direction == DC_LEFT) {
timer_set_oc_value(TIM3, TIM_OC3, 0);
timer_set_oc_value(TIM3, TIM_OC4, speed * PWM_PERIOD / 255);
}
}
#include "ExternButton.h"
#include <cyg/hal/hal_arch.h>
extern "C" void button_init() {
CYGHWR_HAL_STM32_GPIO_SET(CYGHWR_HAL_STM32_PIN_IN(D, 11, PULLUP));
}
extern "C" int button_get() {
int button;
CYGHWR_HAL_STM32_GPIO_IN(CYGHWR_HAL_STM32_PIN_IN(D, 11, PULLUP), &button);
return !button;
}
#include "ServoMotor.h"
#include <cyg/hal/hal_arch.h>
#include <libopencm3/cm3/common.h>
#include <libopencm3/stm32/timer.h>
#include <libopencm3/stm32/f4/rcc.h>
#include <libopencm3/stm32/f4/gpio.h>
#define GPIO_D12 CYGHWR_HAL_STM32_PIN_ALTFN_OUT(D,12, 2, PUSHPULL,NONE,LOW)
#define GPIO_D13 CYGHWR_HAL_STM32_PIN_ALTFN_OUT(D,13, 2, PUSHPULL,NONE,LOW)
#define GPIO_D14 CYGHWR_HAL_STM32_PIN_ALTFN_OUT(D,14, 2, PUSHPULL,NONE,LOW)
#define GPIO_D15 CYGHWR_HAL_STM32_PIN_ALTFN_OUT(D,15, 2, PUSHPULL,NONE,LOW)
// The timer ticks per microsecond. Can be adjusted by measuring PWM on an oscilloscope.
#define PWM_TIMER_TICKS_PER_MICROSECOND 86
// PWM Period. Must be more then maximum high time.
#define PWM_PERIOD (3000 * PWM_TIMER_TICKS_PER_MICROSECOND)
static void pwm_init(uint32_t timer, uint8_t channel, uint32_t period) {
// Function stolen from somewhere on stackoverflow
// Convert channel number to internal rep
enum tim_oc_id chan;
switch (channel) {
case 1:
chan = TIM_OC1;
break;
case 2:
chan = TIM_OC2;
break;
case 3:
chan = TIM_OC3;
break;
case 4:
chan = TIM_OC4;
break;
default:
chan = TIM_OC4;
break;
}
// Timer Base Configuration
// timer_reset(timer);
// clock division, Center-aligned mode selection, TIMx_CR1 DIR: Direction
timer_set_mode(timer, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
timer_continuous_mode(timer); // Disables TIM_CR1_OPM (One pulse mode)
timer_set_period(timer, period); // Sets TIMx_ARR
timer_set_prescaler(timer, 1); // Adjusts speed of timer
timer_set_clock_division(timer, 0); // Adjusts speed of timer
timer_set_master_mode(timer, TIM_CR2_MMS_UPDATE); // Master Mode Selection
timer_enable_preload(timer); // Set ARPE bit in TIMx_CR1
// Channel-specific settings
timer_set_oc_value(timer, chan, 0); // sets TIMx_CCRx
timer_set_oc_mode(timer, chan, TIM_OCM_PWM1); // Sets PWM Mode 1
timer_enable_oc_preload(timer, chan); // Sets OCxPE in TIMx_CCMRx
timer_set_oc_polarity_high(timer, chan); // set desired polarity in TIMx_CCER
timer_enable_oc_output(timer, chan); // set CCxE bit in TIMx_CCER (enable output)
// Initialize all counters in the register
switch (timer) {
case TIM1:
TIM1_EGR |= TIM_EGR_UG;
break;
case TIM2:
TIM2_EGR |= TIM_EGR_UG;
break;
case TIM3:
TIM3_EGR |= TIM_EGR_UG;
break;
case TIM4:
TIM4_EGR |= TIM_EGR_UG;
break;
case TIM5:
TIM5_EGR |= TIM_EGR_UG;
break;
case TIM6:
TIM6_EGR |= TIM_EGR_UG;
break;
case TIM7:
TIM7_EGR |= TIM_EGR_UG;
break;
case TIM8:
TIM8_EGR |= TIM_EGR_UG;
break;
}
}
static void pwm_setup(void) {
rcc_periph_clock_enable(RCC_TIM4);
pwm_init(TIM4, 1, PWM_PERIOD);
pwm_init(TIM4, 2, PWM_PERIOD);
pwm_init(TIM4, 3, PWM_PERIOD);
pwm_init(TIM4, 4, PWM_PERIOD);
// LED channels = PD12..15
// AHB1-bus ? _ gpIO Port D ENable
rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPDEN);
// AF = alternate function
gpio_mode_setup(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO12 | GPIO13 | GPIO14 | GPIO15);
// AF2 = TIM4_CH1..4
gpio_set_af(GPIOD, GPIO_AF2, GPIO12 | GPIO13 | GPIO14 | GPIO15);
timer_enable_counter(TIM4);
}
extern "C" void servo_init() {
pwm_setup();
CYGHWR_HAL_STM32_GPIO_SET(GPIO_D12);
CYGHWR_HAL_STM32_GPIO_SET(GPIO_D13);
CYGHWR_HAL_STM32_GPIO_SET(GPIO_D14);
CYGHWR_HAL_STM32_GPIO_SET(GPIO_D15);
}
extern "C" void servo_set(uint8_t servo, uint8_t position) {
switch (servo) {
case SERVO_0:
timer_set_oc_value(TIM4, TIM_OC1, 150 * PWM_TIMER_TICKS_PER_MICROSECOND + (position * 325 * PWM_TIMER_TICKS_PER_MICROSECOND / 255));
break;
case SERVO_1:
timer_set_oc_value(TIM4, TIM_OC2, 150 * PWM_TIMER_TICKS_PER_MICROSECOND + (position * 325 * PWM_TIMER_TICKS_PER_MICROSECOND / 255));
break;
case SERVO_2:
timer_set_oc_value(TIM4, TIM_OC3, 150 * PWM_TIMER_TICKS_PER_MICROSECOND + (position * 325 * PWM_TIMER_TICKS_PER_MICROSECOND / 255));
break;
case SERVO_3:
timer_set_oc_value(TIM4, TIM_OC4, 150 * PWM_TIMER_TICKS_PER_MICROSECOND + (position * 325 * PWM_TIMER_TICKS_PER_MICROSECOND / 255));
break;
default:
break;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment