-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
+ Brushed mode + Drag brake at 75% by default + DSHOT command 40 (select timing) + DSHOT command 41 (select PWM frequency) Support for GD32F350 New targets: LUMENIER1 Drop WWDG for predictable flash programming Minor bug fixes
- Loading branch information
Showing
14 changed files
with
375 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
/* | ||
** Copyright (C) 2022-2023 Arseny Vakhrushev <[email protected]> | ||
** | ||
** This firmware 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 firmware 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 firmware. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#include <libopencm3/cm3/common.h> | ||
#include <libopencm3/stm32/f1/adc.h> | ||
#include "common.h" | ||
|
||
#define ADC1_BASE ADC_BASE | ||
#define COMP_CSR MMIO32(SYSCFG_COMP_BASE + 0x1c) | ||
|
||
static char len, ain; | ||
static uint16_t buf[5]; | ||
|
||
void init(void) { | ||
RCC_CFGR &= ~RCC_CFGR_SW_PLL; | ||
while (RCC_CFGR & RCC_CFGR_SWS_PLL); | ||
RCC_CR &= ~RCC_CR_PLLON; | ||
RCC_CFGR = 0x8240000; // PLLMUL=11001 (x26) | ||
RCC_CR |= RCC_CR_PLLON; | ||
while (!(RCC_CR & RCC_CR_PLLRDY)); | ||
RCC_CFGR |= RCC_CFGR_SW_PLL; | ||
|
||
RCC_APB2RSTR = -1; | ||
RCC_APB1RSTR = -1; | ||
RCC_APB2RSTR = 0; | ||
RCC_APB1RSTR = 0; | ||
RCC_AHBENR = RCC_AHBENR_DMAEN | RCC_AHBENR_SRAMEN | RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN; | ||
RCC_APB2ENR = RCC_APB2ENR_SYSCFGCOMPEN | RCC_APB2ENR_ADCEN | RCC_APB2ENR_TIM1EN | RCC_APB2ENR_USART1EN | RCC_APB2ENR_TIM17EN; | ||
RCC_APB1ENR = RCC_APB1ENR_TIM2EN | RCC_APB1ENR_TIM14EN | RCC_APB1ENR_WWDGEN; | ||
SCB_VTOR = (uint32_t)_rom; // Set vector table address | ||
|
||
// Default GPIO state - analog input | ||
GPIOA_AFRL = 0x20000000; // A7 (TIM1_CH1N) | ||
GPIOA_AFRH = 0x00000222; // A8 (TIM1_CH1), A9 (TIM1_CH2), A10 (TIM1_CH3) | ||
GPIOB_AFRL = 0x00000022; // B0 (TIM1_CH2N), B1 (TIM1_CH3N) | ||
GPIOB_AFRH = 0x00000000; | ||
GPIOA_PUPDR = 0x24000000; | ||
GPIOB_PUPDR = 0x00001000; // B6 (pull-up) | ||
GPIOA_MODER = 0xebeabfff; // A7 (TIM1_CH1N), A8 (TIM1_CH1), A9 (TIM1_CH2), A10 (TIM1_CH3) | ||
GPIOB_MODER = 0xffffeffa; // B0 (TIM1_CH2N), B1 (TIM1_CH3N), B6 (USART1_TX) | ||
#ifndef ANALOG | ||
#ifdef IO_PA2 | ||
RCC_APB2ENR |= RCC_APB2ENR_TIM15EN; | ||
GPIOA_PUPDR |= 0x10; // A2 (pull-up) | ||
GPIOA_MODER &= ~0x10; // A2 (TIM15_CH1) | ||
#else | ||
RCC_APB1ENR |= RCC_APB1ENR_TIM3EN; | ||
GPIOB_AFRL |= 0x10000; // B4 (TIM3_CH1) | ||
GPIOB_PUPDR |= 0x100; // B4 (pull-up) | ||
GPIOB_MODER &= ~0x100; // B4 (TIM3_CH1) | ||
#endif | ||
#endif | ||
|
||
nvic_set_priority(NVIC_TIM3_IRQ, 0x40); | ||
nvic_set_priority(NVIC_TIM15_IRQ, 0x40); | ||
nvic_set_priority(NVIC_USART1_IRQ, 0x80); | ||
nvic_set_priority(NVIC_USART2_IRQ, 0x40); | ||
nvic_set_priority(NVIC_DMA1_CHANNEL1_IRQ, 0x80); // ADC | ||
nvic_set_priority(NVIC_DMA1_CHANNEL2_3_DMA2_CHANNEL1_2_IRQ, 0x80); // USART1 | ||
nvic_set_priority(NVIC_DMA1_CHANNEL4_7_DMA2_CHANNEL3_5_IRQ, 0x40); // TIM3 or TIM15 or USART2 | ||
|
||
nvic_enable_irq(NVIC_TIM1_BRK_UP_TRG_COM_IRQ); | ||
nvic_enable_irq(NVIC_TIM1_CC_IRQ); | ||
nvic_enable_irq(NVIC_TIM2_IRQ); | ||
nvic_enable_irq(NVIC_TIM3_IRQ); | ||
nvic_enable_irq(NVIC_TIM15_IRQ); | ||
nvic_enable_irq(NVIC_USART1_IRQ); | ||
nvic_enable_irq(NVIC_USART2_IRQ); | ||
nvic_enable_irq(NVIC_DMA1_CHANNEL1_IRQ); | ||
nvic_enable_irq(NVIC_DMA1_CHANNEL2_3_DMA2_CHANNEL1_2_IRQ); | ||
nvic_enable_irq(NVIC_DMA1_CHANNEL4_7_DMA2_CHANNEL3_5_IRQ); | ||
|
||
RCC_CR2 |= RCC_CR2_HSI14ON; // Enable IRC28M | ||
while (!(RCC_CR2 & RCC_CR2_HSI14RDY)); | ||
ADC1_CR2 = ADC_CR2_ADON | ADC_CR2_TSVREFE; | ||
TIM17_ARR = CLK_MHZ - 1; | ||
TIM17_CR1 = TIM_CR1_CEN | TIM_CR1_OPM; | ||
while (TIM17_CR1 & TIM_CR1_CEN); // Wait for 1us (RM 11.4.1) | ||
ADC1_CR2 |= ADC_CR2_CAL; | ||
while (ADC1_CR2 & ADC_CR2_CAL); | ||
ADC1_CR1 = ADC_CR1_SCAN; | ||
ADC1_SMPR1 = -1; // Sampling time ~17us @ IRC28M/2=14Mhz | ||
ADC1_SMPR2 = -1; | ||
ADC1_SQR3 = SENS_CHAN; | ||
len = SENS_CNT; | ||
if (IO_ANALOG) { | ||
ADC1_SQR3 |= THROT_CHAN << (len++ * 5); | ||
ain = 1; | ||
} | ||
ADC1_SQR3 |= 0x230 << (len * 5); // CH16 (temp), CH17 (vref) | ||
len += 2; | ||
ADC1_SQR1 = (len - 1) << ADC_SQR1_L_LSB; | ||
DMA1_CPAR(1) = (uint32_t)&ADC1_DR; | ||
DMA1_CMAR(1) = (uint32_t)buf; | ||
|
||
TIM1_DIER = TIM_DIER_UIE | TIM_DIER_CC1IE | TIM_DIER_CC4IE; // Software comparator blanking, ADC trigger | ||
TIM1_SMCR = TIM_SMCR_TS_ITR1; // TRGI=TIM2 | ||
TIM2_CR2 = TIM_CR2_MMS_COMPARE_OC1REF; // TRGO=OC1REF | ||
TIM2_CCMR1 = TIM_CCMR1_OC1PE | TIM_CCMR1_OC1M_PWM2; // Inverted PWM on OC1 | ||
TIM2_CCMR2 = TIM_CCMR2_CC4S_IN_TI4 | TIM_CCMR2_IC4F_DTF_DIV_16_N_8; | ||
TIM2_CCER = TIM_CCER_CC4E; // IC4 on rising edge on TI4 (COMP1_OUT) | ||
} | ||
|
||
void compctl(int x) { | ||
int cr = 0; | ||
switch (x & 3) { | ||
case COMP_IN1: | ||
cr = 0x61; // A1>A0 | ||
break; | ||
case COMP_IN2: | ||
cr = 0x41; // A1>A4 | ||
break; | ||
case COMP_IN3: | ||
cr = 0x51; // A1>A5 | ||
break; | ||
} | ||
if (x & 4) cr |= 0x800; // Change polarity | ||
COMP_CSR = cr; | ||
} | ||
|
||
void io_serial(void) { | ||
TIM15_DIER = 0; | ||
nvic_clear_pending_irq(NVIC_TIM15_IRQ); | ||
RCC_APB2ENR &= ~RCC_APB2ENR_TIM15EN; | ||
RCC_APB1ENR |= RCC_APB1ENR_USART2EN; | ||
GPIOA_AFRL |= 0x100; // A2 (USART2_TX) | ||
} | ||
|
||
void io_analog(void) { | ||
TIM15_DIER = 0; | ||
nvic_clear_pending_irq(NVIC_TIM15_IRQ); | ||
RCC_APB2ENR &= ~RCC_APB2ENR_TIM15EN; | ||
GPIOA_PUPDR &= ~0x30; // A2 (no pull-up/pull-down) | ||
GPIOA_MODER |= 0x30; // A2 (analog) | ||
} | ||
|
||
void adc_trig(void) { | ||
if (DMA1_CCR(1) & DMA_CCR_EN) return; | ||
DMA1_CNDTR(1) = len; | ||
DMA1_CCR(1) = DMA_CCR_EN | DMA_CCR_TCIE | DMA_CCR_MINC | DMA_CCR_PSIZE_16BIT | DMA_CCR_MSIZE_16BIT; | ||
ADC1_CR2 = ADC_CR2_ADON | ADC_CR2_TSVREFE | ADC_CR2_DMA | ADC_CR2_EXTTRIG | ADC_CR2_EXTSEL_SWSTART; | ||
} | ||
|
||
void tim1_brk_up_trg_com_isr(void) { | ||
int sr = TIM1_SR; | ||
if (sr & TIM_SR_UIF) { | ||
TIM1_SR = ~TIM_SR_UIF; | ||
if (TIM1_CCR4) COMP_CSR &= ~0x700; // COMP_OUT off | ||
} | ||
if (sr & TIM_SR_COMIF) tim1_com_isr(); | ||
} | ||
|
||
void tim1_cc_isr(void) { | ||
int sr = TIM1_SR; | ||
if (sr & TIM_SR_CC4IF) { | ||
TIM1_SR = ~TIM_SR_CC4IF; | ||
COMP_CSR |= 0x400; // COMP1_OUT=TIM2_IC4 | ||
} | ||
if (!(sr & TIM_SR_CC1IF)) return; | ||
TIM1_SR = ~TIM_SR_CC1IF; | ||
if (!(ADC1_CR2 & ADC_CR2_DMA)) return; | ||
ADC1_CR2 = ADC_CR2_ADON | ADC_CR2_TSVREFE | ADC_CR2_DMA | ADC_CR2_EXTTRIG | ADC_CR2_EXTSEL_SWSTART | ADC_CR2_SWSTART; | ||
} | ||
|
||
void dma1_channel1_isr(void) { | ||
DMA1_IFCR = DMA_IFCR_CTCIF(1); | ||
DMA1_CCR(1) = 0; | ||
ADC1_CR2 = ADC_CR2_ADON | ADC_CR2_TSVREFE; | ||
int i = 0, v = 0, c = 0, x = 0; | ||
#if SENS_CNT == 2 | ||
c = buf[i++]; | ||
#endif | ||
#if SENS_CNT >= 1 | ||
v = buf[i++]; | ||
#endif | ||
if (ain) x = buf[i++]; | ||
int r = 4914000 / buf[i + 1]; | ||
int t = (1450 - (buf[i] * r >> 12)) * 10 / 43 + 25; | ||
adc_data(t, v * r >> 12, c * r >> 12, x); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
set(opts -mcpu=cortex-m4 -mthumb) | ||
set(libs opencm3_stm32f0) | ||
set(defs STM32F0) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
/* | ||
** Copyright (C) 2022-2023 Arseny Vakhrushev <[email protected]> | ||
** | ||
** This firmware 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 firmware 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 firmware. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#if SENS_MAP == 0xA3 // A3 (volt) | ||
#define SENS_CNT 1 | ||
#define SENS_CHAN 0x3 | ||
#endif | ||
|
||
#ifndef THROT_CHAN | ||
#define THROT_CHAN 2 // A2 | ||
#endif | ||
|
||
#define CLK 104000000 | ||
|
||
#define IFTIM TIM2 | ||
#define IFTIM_ICF 128 | ||
#define IFTIM_ICE TIM_DIER_CC4IE | ||
#define IFTIM_ICR TIM2_CCR4 | ||
#define IFTIM_OCR TIM2_CCR1 | ||
#define iftim_isr tim2_isr | ||
|
||
#ifdef IO_PA2 | ||
#define IO_TYPE 0 | ||
#define IOTIM TIM15 | ||
#define IOTIM_IDR (GPIOA_IDR & 0x4) // A2 | ||
#define IOTIM_DMA 5 | ||
#define iotim_isr tim15_isr | ||
#else | ||
#define IO_TYPE 2 | ||
#define IOTIM TIM3 | ||
#define IOTIM_IDR (GPIOB_IDR & 0x10) // B4 | ||
#define IOTIM_DMA 4 | ||
#define iotim_isr tim3_isr | ||
#endif | ||
#define iodma_isr dma1_channel4_7_dma2_channel3_5_isr | ||
|
||
#define USART1_TX_DMA 2 | ||
#define USART1_RX_DMA 3 | ||
#define usart1_dma_isr dma1_channel2_3_dma2_channel1_2_isr | ||
|
||
#define USART2_RX_DMA 5 | ||
|
||
void tim1_com_isr(void); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
MEMORY { | ||
boot (rx) : ORIGIN = 0x8000000, LENGTH = 4K | ||
cfg (rx) : ORIGIN = ORIGIN(boot) + LENGTH(boot), LENGTH = 1K | ||
rom (rx) : ORIGIN = ORIGIN(cfg) + LENGTH(cfg), LENGTH = 32K - LENGTH(boot) - LENGTH(cfg) | ||
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 8K | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/* | ||
** Copyright (C) 2022-2023 Arseny Vakhrushev <[email protected]> | ||
** | ||
** This firmware 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 firmware 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 firmware. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#include "common.h" | ||
|
||
const uint16_t sinedata[] = { | ||
346, 352, 358, 364, 370, 376, 382, 388, 394, 400, 406, 412, 418, 424, 430, 436, 441, 447, 453, 459, 464, 470, 476, 481, 487, 492, 498, 503, 508, 514, | ||
519, 524, 529, 534, 539, 544, 549, 554, 559, 564, 568, 573, 578, 582, 586, 591, 595, 599, 603, 607, 611, 615, 619, 622, 626, 629, 633, 636, 639, 643, | ||
646, 649, 651, 654, 657, 660, 662, 664, 667, 669, 671, 673, 675, 677, 679, 680, 682, 683, 684, 686, 687, 688, 689, 689, 690, 691, 691, 692, 692, 692, | ||
692, 692, 692, 692, 691, 691, 690, 689, 689, 688, 687, 686, 684, 683, 682, 680, 679, 677, 675, 673, 671, 669, 667, 664, 662, 660, 657, 654, 651, 649, | ||
646, 643, 639, 636, 633, 629, 626, 622, 619, 615, 611, 607, 603, 599, 595, 591, 586, 582, 578, 573, 568, 564, 559, 554, 549, 544, 539, 534, 529, 524, | ||
519, 514, 508, 503, 498, 492, 487, 481, 476, 470, 464, 459, 453, 447, 441, 436, 430, 424, 418, 412, 406, 400, 394, 388, 382, 376, 370, 364, 358, 352, | ||
346, 340, 334, 328, 322, 316, 310, 304, 298, 292, 286, 280, 274, 268, 262, 256, 251, 245, 239, 233, 228, 222, 216, 211, 205, 200, 194, 189, 184, 178, | ||
173, 168, 163, 158, 153, 148, 143, 138, 133, 128, 124, 119, 114, 110, 106, 101, 97, 93, 89, 85, 81, 77, 73, 70, 66, 63, 59, 56, 53, 49, | ||
46, 43, 41, 38, 35, 32, 30, 28, 25, 23, 21, 19, 17, 15, 13, 12, 10, 9, 8, 6, 5, 4, 3, 3, 2, 1, 1, 0, 0, 0, | ||
0, 0, 0, 0, 1, 1, 2, 3, 3, 4, 5, 6, 8, 9, 10, 12, 13, 15, 17, 19, 21, 23, 25, 28, 30, 32, 35, 38, 41, 43, | ||
46, 49, 53, 56, 59, 63, 66, 70, 73, 77, 81, 85, 89, 93, 97, 101, 106, 110, 114, 119, 124, 128, 133, 138, 143, 148, 153, 158, 163, 168, | ||
173, 178, 184, 189, 194, 200, 205, 211, 216, 222, 228, 233, 239, 245, 251, 256, 262, 268, 274, 280, 286, 292, 298, 304, 310, 316, 322, 328, 334, 340, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -86,6 +86,7 @@ typedef struct { | |
char volume; | ||
char beacon; | ||
char led; | ||
char brushed; | ||
} Cfg; | ||
|
||
typedef struct { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.