ADC working
This commit is contained in:
parent
468fe59d97
commit
62389e00fe
15 changed files with 1897 additions and 45 deletions
12
common/.gitignore
vendored
Normal file
12
common/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
*.elf
|
||||
*.o
|
||||
*.expand
|
||||
*.hex
|
||||
*.lst
|
||||
*.map
|
||||
*.bin
|
||||
sources.c
|
||||
sources.tar.xz
|
||||
sources.tar.xz.zip
|
||||
8b10b_test_decode
|
||||
8b10b_test_encode
|
||||
|
|
@ -4,6 +4,9 @@
|
|||
|
||||
#include "8b10b.h"
|
||||
|
||||
/* Ignore warnings about some of the following arrays being unused. They will be removed by the linker. I want to keep
|
||||
* them here for future reference. */
|
||||
#pragma GCC diagnostic ignored "-Wunused-const-variable=0"
|
||||
static const struct entry map_5b6b[32] = {
|
||||
{0b100111, 0b011000, 2}, /* D.00 */
|
||||
{0b011101, 0b100010, 2}, /* D.01 */
|
||||
|
|
@ -212,7 +215,7 @@ int xfr_8b10b_encode(struct state_8b10b_enc *st, int data) {
|
|||
int x5b = (st->rd == -1) ? map_5b6b[p5b].rd_neg : map_5b6b[p5b].rd_pos;
|
||||
st->rd -= map_5b6b[p5b].disp * st->rd;
|
||||
//fprintf(stderr, "\nnow: rd %d data %x p5b %d p3b %d\n", st->rd, data, p5b, p3b);
|
||||
assert(st->rd == -1 || st->rd == 1);
|
||||
//assert(st->rd == -1 || st->rd == 1);
|
||||
|
||||
int x3b = (st->rd == -1) ? map_3b4b_d[p3b].rd_neg : map_3b4b_d[p3b].rd_pos;
|
||||
if (p3b == 7) {
|
||||
|
|
@ -223,7 +226,7 @@ int xfr_8b10b_encode(struct state_8b10b_enc *st, int data) {
|
|||
}
|
||||
}
|
||||
st->rd -= map_3b4b_d[p3b].disp * st->rd; /* D.x.A7 and D.x.P7 both have parity 2 */
|
||||
assert(st->rd == -1 || st->rd == 1);
|
||||
//assert(st->rd == -1 || st->rd == 1);
|
||||
|
||||
return x5b<<4 | x3b;
|
||||
}
|
||||
|
|
@ -15,7 +15,8 @@ enum k_code {
|
|||
enum decoder_return_codes {
|
||||
_K_CODES_LAST = K_CODES_LAST,
|
||||
DECODING_ERROR,
|
||||
DECODING_IN_PROGRESS
|
||||
DECODING_IN_PROGRESS,
|
||||
DECODER_RETURN_CODE_LAST
|
||||
};
|
||||
|
||||
struct entry {
|
||||
1549
common/8b10b.pp
Normal file
1549
common/8b10b.pp
Normal file
File diff suppressed because it is too large
Load diff
27
common/Makefile
Normal file
27
common/Makefile
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# Megumin LED display firmware
|
||||
# Copyright (C) 2018 Sebastian Götte <code@jaseg.net>
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
all: 8b10b_test_encode 8b10b_test_decode
|
||||
|
||||
8b10b_test_encode: 8b10b_test_encode.c 8b10b.c
|
||||
gcc -o $@ $^
|
||||
|
||||
8b10b_test_decode: 8b10b_test_decode.c 8b10b.c
|
||||
gcc -o $@ $^
|
||||
|
||||
clean:
|
||||
rm -f 8b10b_test_encode 8b10b_test_decode
|
||||
|
||||
|
|
@ -9,7 +9,7 @@ OBJCOPY := arm-none-eabi-objcopy
|
|||
OBJDUMP := arm-none-eabi-objdump
|
||||
SIZE := arm-none-eabi-size
|
||||
|
||||
CFLAGS = -g -Wall -std=gnu11 -O1 -fdump-rtl-expand
|
||||
CFLAGS = -g -Wall -std=gnu11 -O1 -fdump-rtl-expand -Wno-discarded-qualifiers
|
||||
CFLAGS += -mlittle-endian -mcpu=cortex-m3 -mthumb
|
||||
#CFLAGS += -ffunction-sections -fdata-sections
|
||||
LDFLAGS = -nostartfiles
|
||||
|
|
@ -22,7 +22,7 @@ LIBS = -lgcc
|
|||
CFLAGS += -DSTM32F103xB -DHSE_VALUE=8000000
|
||||
|
||||
LDFLAGS += -Tstm32_flash.ld
|
||||
CFLAGS += -I$(CMSIS_DEV_PATH)/Include -I$(CMSIS_PATH)/Include -I$(HAL_PATH)/Inc -Iconfig
|
||||
CFLAGS += -I$(CMSIS_DEV_PATH)/Include -I$(CMSIS_PATH)/Include -I$(HAL_PATH)/Inc -Iconfig -I../common
|
||||
#LDFLAGS += -L$(CMSIS_PATH)/Lib/GCC -larm_cortexM0l_math
|
||||
|
||||
###################################################
|
||||
|
|
@ -45,7 +45,7 @@ cmsis_exports.c: $(CMSIS_DEV_PATH)/Include/stm32f103xb.h $(CMSIS_PATH)/Include/c
|
|||
%.dot: %.elf
|
||||
r2 -a arm -qc 'aa;agC' $< 2>/dev/null >$@
|
||||
|
||||
main.elf: main.o startup_stm32f103xb.o system_stm32f1xx.o $(HAL_PATH)/Src/stm32f1xx_ll_utils.o cmsis_exports.o
|
||||
main.elf: main.o startup_stm32f103xb.o system_stm32f1xx.o $(HAL_PATH)/Src/stm32f1xx_ll_utils.o cmsis_exports.o ../common/8b10b.o
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
$(OBJCOPY) -O ihex $@ $(@:.elf=.hex)
|
||||
$(OBJCOPY) -O binary $@ $(@:.elf=.bin)
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <8b10b.h>
|
||||
|
||||
/* Part number: STM32F030F4C6 */
|
||||
|
||||
static volatile unsigned int sys_time;
|
||||
|
|
@ -20,14 +22,23 @@ uint32_t get_tick() {
|
|||
return SysTick->VAL;
|
||||
}
|
||||
|
||||
static volatile struct {
|
||||
int current_symbol, next_symbol;
|
||||
struct state_8b10b_enc st;
|
||||
} txstate;
|
||||
|
||||
#define NO_SYMBOL (DECODER_RETURN_CODE_LAST + 1)
|
||||
|
||||
int main(void) {
|
||||
/* External crystal: 8MHz */
|
||||
RCC->CR |= RCC_CR_HSEON;
|
||||
while (!(RCC->CR&RCC_CR_HSERDY));
|
||||
|
||||
/* Sysclk = HCLK = 48MHz */
|
||||
RCC->CFGR = (RCC->CFGR & (~RCC_CFGR_PLLMULL_Msk & ~RCC_CFGR_SW_Msk & ~RCC_CFGR_PPRE1_Msk & ~RCC_CFGR_PPRE2_Msk & ~RCC_CFGR_HPRE_Msk))
|
||||
| (10<<RCC_CFGR_PLLMULL_Pos) | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | (4<<RCC_CFGR_PPRE1_Pos) | (4<<RCC_CFGR_PPRE2_Pos);
|
||||
RCC->CFGR = (RCC->CFGR & (~RCC_CFGR_PLLMULL_Msk & ~RCC_CFGR_SW_Msk & ~RCC_CFGR_PPRE1_Msk & ~RCC_CFGR_PPRE2_Msk &
|
||||
~RCC_CFGR_HPRE_Msk))
|
||||
| (10<<RCC_CFGR_PLLMULL_Pos) | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | (4<<RCC_CFGR_PPRE1_Pos) |
|
||||
(4<<RCC_CFGR_PPRE2_Pos);
|
||||
|
||||
RCC->CR |= RCC_CR_PLLON;
|
||||
while (!(RCC->CR&RCC_CR_PLLRDY));
|
||||
|
|
@ -38,43 +49,70 @@ int main(void) {
|
|||
// | (4<<RCC_CFGR_PPRE1_Pos) | (4<<RCC_CFGR_PPRE2_Pos);
|
||||
SystemCoreClockUpdate();
|
||||
|
||||
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN;
|
||||
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_TIM1EN;
|
||||
|
||||
GPIOA->CRL =
|
||||
(0<<GPIO_CRL_CNF6_Pos) | (1<<GPIO_CRL_MODE6_Pos) /* PA6 - Channel 1 low side */
|
||||
| (0<<GPIO_CRL_CNF7_Pos) | (1<<GPIO_CRL_MODE7_Pos); /* PA7 - Channel 2 low side */
|
||||
GPIOA->CRH =
|
||||
(2<<GPIO_CRH_CNF8_Pos) | (1<<GPIO_CRH_MODE8_Pos); /* PA8 - low side */
|
||||
|
||||
GPIOB->CRL =
|
||||
(0<<GPIO_CRL_CNF0_Pos) | (1<<GPIO_CRL_MODE0_Pos) /* PB0 - Channel 1 high side */
|
||||
| (0<<GPIO_CRL_CNF1_Pos) | (1<<GPIO_CRL_MODE1_Pos); /* PB1 - Channel 2 high side */
|
||||
GPIOB->CRH =
|
||||
(2<<GPIO_CRH_CNF13_Pos) | (1<<GPIO_CRH_MODE13_Pos); /* PB13 - high side */
|
||||
|
||||
GPIOC->CRH =
|
||||
(0<<GPIO_CRH_CNF13_Pos) | (1<<GPIO_CRH_MODE13_Pos); /* PC13 - LED */
|
||||
|
||||
/* Turn all outputs off */
|
||||
GPIOA->BRR |= 1<<6 | 1<<7;
|
||||
GPIOB->BRR |= 1<<0 | 1<<1;
|
||||
/* TIM1 running off 24MHz APB2 clk, T=41.667ns */
|
||||
TIM1->CR1 = 0; /* Disable ARR preload (double-buffering) */
|
||||
TIM1->PSC = 24-1; /* Prescaler 24 -> f=1MHz/T=1us */
|
||||
TIM1->DIER = TIM_DIER_UIE; /* Enable update (overflow) interrupt */
|
||||
TIM1->CCMR1 = 6<<TIM_CCMR1_OC1M_Pos | TIM_CCMR1_OC1PE; /* Configure output compare unit 1 to PWM mode 1, enable CCR1
|
||||
preload */
|
||||
TIM1->CCER = TIM_CCER_CC1NE | TIM_CCER_CC1E; /* Confiugre CH1 to complementary outputs */
|
||||
TIM1->BDTR = TIM_BDTR_MOE | 100<<TIM_BDTR_DTG_Pos; /* Enable MOE on next update event, i.e. on initial timer load.
|
||||
Set dead-time to 100us. */
|
||||
TIM1->CR1 |= TIM_CR1_CEN;
|
||||
TIM1->ARR = 1000-1; /* Set f=1.0kHz/T=1.0ms */
|
||||
|
||||
xfr_8b10b_encode_reset(&txstate.st);
|
||||
txstate.current_symbol = txstate.next_symbol = xfr_8b10b_encode(&txstate.st, K28_1) | 1<<10;
|
||||
TIM1->EGR |= TIM_EGR_UG;
|
||||
|
||||
NVIC_EnableIRQ(TIM1_UP_IRQn);
|
||||
NVIC_SetPriority(TIM1_UP_IRQn, 3<<4);
|
||||
|
||||
uint8_t txbuf[128];
|
||||
int txpos = -1;
|
||||
/* FIXME test code */
|
||||
for (int i=0; i<sizeof(txbuf); i++)
|
||||
txbuf[i] = i;
|
||||
/* FIXME end test code */
|
||||
while (42) {
|
||||
#define FOO 100000
|
||||
for (int i=0; i<FOO; i++) ;
|
||||
GPIOA->BRR |= 1<<6 | 1<<7;
|
||||
GPIOB->BRR |= 1<<0 | 1<<1;
|
||||
if (txstate.next_symbol == -NO_SYMBOL) {
|
||||
if (txpos == -1)
|
||||
txstate.next_symbol = xfr_8b10b_encode(&txstate.st, K28_1);
|
||||
else
|
||||
txstate.next_symbol = xfr_8b10b_encode(&txstate.st, txbuf[txpos]);
|
||||
|
||||
GPIOA->BSRR |= 1<<6;
|
||||
GPIOB->BSRR |= 1<<1;
|
||||
|
||||
for (int i=0; i<FOO; i++) ;
|
||||
GPIOA->BRR |= 1<<6 | 1<<7;
|
||||
GPIOB->BRR |= 1<<0 | 1<<1;
|
||||
|
||||
GPIOA->BSRR |= 1<<7;
|
||||
GPIOB->BSRR |= 1<<0;
|
||||
|
||||
GPIOC->ODR ^= 1<<13;
|
||||
txpos++;
|
||||
if (txpos == sizeof(txbuf))
|
||||
txpos = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TIM1_UP_IRQHandler() {
|
||||
TIM1->SR &= ~TIM_SR_UIF;
|
||||
int sym = txstate.current_symbol;
|
||||
int bit = sym&1;
|
||||
sym >>= 1;
|
||||
if (sym == 1) { /* last bit shifted out */
|
||||
sym = txstate.next_symbol | 1<<10;
|
||||
txstate.next_symbol = -NO_SYMBOL;
|
||||
}
|
||||
txstate.current_symbol = sym;
|
||||
|
||||
TIM1->CCR1 = bit ? 0xffff : 0x0000;
|
||||
}
|
||||
|
||||
void NMI_Handler(void) {
|
||||
}
|
||||
|
||||
|
|
@ -104,5 +142,5 @@ void MemManage_Handler() {
|
|||
|
||||
void BusFault_Handler(void) __attribute__((naked));
|
||||
void BusFault_Handler() {
|
||||
asm volatile ("bkpt");
|
||||
asm volatile ("bkpt");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ LIBS = -lgcc
|
|||
CFLAGS += -DSTM32F030x6 -DHSE_VALUE=8000000
|
||||
|
||||
LDFLAGS += -Tstm32_flash.ld
|
||||
CFLAGS += -I$(CMSIS_DEV_PATH)/Include -I$(CMSIS_PATH)/Include -I$(HAL_PATH)/Inc -Iconfig -Wno-unused
|
||||
CFLAGS += -I$(CMSIS_DEV_PATH)/Include -I$(CMSIS_PATH)/Include -I$(HAL_PATH)/Inc -Iconfig -Wno-unused -I../common
|
||||
LDFLAGS += -L$(CMSIS_PATH)/Lib/GCC -larm_cortexM0l_math
|
||||
|
||||
###################################################
|
||||
|
|
@ -66,7 +66,7 @@ cmsis_exports.c: $(CMSIS_DEV_PATH)/Include/stm32f030x6.h $(CMSIS_PATH)/Include/c
|
|||
%.dot: %.elf
|
||||
r2 -a arm -qc 'aa;agC' $< 2>/dev/null >$@
|
||||
|
||||
sources.tar.xz: main.c Makefile
|
||||
sources.tar.xz: main.c adc.c ../common/8b10b.c Makefile
|
||||
tar -caf $@ $^
|
||||
|
||||
# don't ask...
|
||||
|
|
@ -76,7 +76,7 @@ sources.tar.xz.zip: sources.tar.xz
|
|||
sources.c: sources.tar.xz.zip
|
||||
xxd -i $< | head -n -1 | sed 's/=/__attribute__((section(".source_tarball"))) =/' > $@
|
||||
|
||||
main.elf: main.o startup_stm32f030x6.o system_stm32f0xx.o $(HAL_PATH)/Src/stm32f0xx_ll_utils.o base.o cmsis_exports.o 8b10b.o sources.o
|
||||
main.elf: main.o startup_stm32f030x6.o system_stm32f0xx.o $(HAL_PATH)/Src/stm32f0xx_ll_utils.o base.o cmsis_exports.o ../common/8b10b.o adc.o
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
$(OBJCOPY) -O ihex $@ $(@:.elf=.hex)
|
||||
$(OBJCOPY) -O binary $@ $(@:.elf=.bin)
|
||||
|
|
|
|||
118
fw/adc.c
Normal file
118
fw/adc.c
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
/* Megumin LED display firmware
|
||||
* Copyright (C) 2018 Sebastian Götte <code@jaseg.net>
|
||||
*
|
||||
* 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"
|
||||
|
||||
volatile struct adc_measurements adc_data = {0};
|
||||
|
||||
enum adc_channels {
|
||||
VREF_CH,
|
||||
VMEAS_A,
|
||||
VMEAS_B,
|
||||
TEMP_CH,
|
||||
NCH
|
||||
};
|
||||
static volatile uint16_t adc_buf[NCH];
|
||||
|
||||
void adc_init(void) {
|
||||
/* The ADC is used for temperature measurement. To compute the temperature from an ADC reading of the internal
|
||||
* temperature sensor, the supply voltage must also be measured. Thus we are using two channels.
|
||||
*
|
||||
* The ADC is triggered by compare channel 4 of timer 1. The trigger is set to falling edge to trigger on compare
|
||||
* match, not overflow.
|
||||
*/
|
||||
ADC1->CFGR1 = ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG | (2<<ADC_CFGR1_EXTEN_Pos) | (1<<ADC_CFGR1_EXTSEL_Pos);
|
||||
/* Clock from PCLK/4 instead of the internal exclusive high-speed RC oscillator. */
|
||||
ADC1->CFGR2 = (2<<ADC_CFGR2_CKMODE_Pos); /* Use PCLK/4=12MHz */
|
||||
/* Sampling time 13.5 ADC clock cycles -> total conversion time 2.17us*/
|
||||
ADC1->SMPR = (2<<ADC_SMPR_SMP_Pos);
|
||||
/* Internal VCC and temperature sensor channels */
|
||||
ADC1->CHSELR = ADC_CHSELR_CHSEL0 | ADC_CHSELR_CHSEL1 | ADC_CHSELR_CHSEL16 | ADC_CHSELR_CHSEL17;
|
||||
/* Enable internal voltage reference and temperature sensor */
|
||||
ADC->CCR = ADC_CCR_TSEN | ADC_CCR_VREFEN;
|
||||
/* Perform ADC calibration */
|
||||
ADC1->CR |= ADC_CR_ADCAL;
|
||||
while (ADC1->CR & ADC_CR_ADCAL)
|
||||
;
|
||||
/* Enable ADC */
|
||||
ADC1->CR |= ADC_CR_ADEN;
|
||||
ADC1->CR |= ADC_CR_ADSTART;
|
||||
|
||||
/* Configure DMA 1 Channel 1 to get rid of all the data */
|
||||
DMA1_Channel1->CPAR = (unsigned int)&ADC1->DR;
|
||||
DMA1_Channel1->CMAR = (unsigned int)&adc_buf;
|
||||
DMA1_Channel1->CNDTR = NCH;
|
||||
DMA1_Channel1->CCR = (0<<DMA_CCR_PL_Pos);
|
||||
DMA1_Channel1->CCR |=
|
||||
DMA_CCR_CIRC /* circular mode so we can leave it running indefinitely */
|
||||
| (1<<DMA_CCR_MSIZE_Pos) /* 16 bit */
|
||||
| (1<<DMA_CCR_PSIZE_Pos) /* 16 bit */
|
||||
| DMA_CCR_MINC
|
||||
| DMA_CCR_TCIE; /* Enable transfer complete interrupt. */
|
||||
DMA1_Channel1->CCR |= DMA_CCR_EN; /* Enable channel */
|
||||
|
||||
/* triggered on transfer completion. We use this to process the ADC data */
|
||||
NVIC_EnableIRQ(DMA1_Channel1_IRQn);
|
||||
NVIC_SetPriority(DMA1_Channel1_IRQn, 3<<5);
|
||||
}
|
||||
|
||||
uint16_t buf_a[256];
|
||||
uint16_t buf_b[256];
|
||||
int bufp = 0;
|
||||
|
||||
void DMA1_Channel1_IRQHandler(void) {
|
||||
/* This interrupt takes either 1.2us or 13us. It can be pre-empted by the more timing-critical UART and LED timer
|
||||
* interrupts. */
|
||||
static int count = 0; /* oversampling accumulator sample count */
|
||||
static uint32_t adc_aggregate[NCH] = {0}; /* oversampling accumulator */
|
||||
|
||||
/* Clear the interrupt flag */
|
||||
DMA1->IFCR |= DMA_IFCR_CGIF1;
|
||||
|
||||
for (int i=0; i<NCH; i++)
|
||||
adc_aggregate[i] += adc_buf[i];
|
||||
|
||||
if (++count == (1<<ADC_OVERSAMPLING)) {
|
||||
for (int i=0; i<NCH; i++)
|
||||
adc_aggregate[i] >>= ADC_OVERSAMPLING;
|
||||
/* This has been copied from the code examples to section 12.9 ADC>"Temperature sensor and internal reference
|
||||
* voltage" in the reference manual with the extension that we actually measure the supply voltage instead of
|
||||
* hardcoding it. This is not strictly necessary since we're running off a bored little LDO but it's free and
|
||||
* the current supply voltage is a nice health value.
|
||||
*/
|
||||
adc_data.adc_vcc_mv = (3300 * VREFINT_CAL)/(adc_aggregate[VREF_CH]);
|
||||
|
||||
int64_t read = adc_aggregate[TEMP_CH] * 10 * 10000;
|
||||
int64_t vcc = adc_data.adc_vcc_mv;
|
||||
int64_t cal = TS_CAL1 * 10 * 10000;
|
||||
adc_data.adc_temp_celsius_tenths = 300 + ((read/4096 * vcc) - (cal/4096 * 3300))/43000;
|
||||
|
||||
adc_data.adc_vmeas_a_mv = (adc_aggregate[VMEAS_A]*13300L)/4096 * vcc / 3300;
|
||||
adc_data.adc_vmeas_b_mv = (adc_aggregate[VMEAS_B]*13300L)/4096 * vcc / 3300;
|
||||
|
||||
buf_a[bufp] = adc_data.adc_vmeas_a_mv;
|
||||
buf_b[bufp] = adc_data.adc_vmeas_b_mv;
|
||||
if (++bufp >= sizeof(buf_a)/sizeof(buf_a[0])) {
|
||||
bufp = 0;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
for (int i=0; i<NCH; i++)
|
||||
adc_aggregate[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
36
fw/adc.h
Normal file
36
fw/adc.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/* Megumin LED display firmware
|
||||
* Copyright (C) 2018 Sebastian Götte <code@jaseg.net>
|
||||
*
|
||||
* 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 "global.h"
|
||||
|
||||
#define ADC_OVERSAMPLING 0
|
||||
|
||||
struct adc_measurements {
|
||||
int16_t adc_vcc_mv;
|
||||
int16_t adc_temp_celsius_tenths;
|
||||
int16_t adc_vmeas_a_mv;
|
||||
int16_t adc_vmeas_b_mv;
|
||||
};
|
||||
|
||||
extern volatile struct adc_measurements adc_data;
|
||||
|
||||
void adc_init(void);
|
||||
|
||||
#endif/*__ADC_H__*/
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
#ifndef __GENERATED_CMSIS_HEADER_EXPORTS__
|
||||
#define __GENERATED_CMSIS_HEADER_EXPORTS__
|
||||
|
||||
#include <stm32f030x6.h>
|
||||
|
||||
/* stm32f030x6.h */
|
||||
TIM_TypeDef *tim3 = TIM3;
|
||||
TIM_TypeDef *tim14 = TIM14;
|
||||
RTC_TypeDef *rtc = RTC;
|
||||
WWDG_TypeDef *wwdg = WWDG;
|
||||
IWDG_TypeDef *iwdg = IWDG;
|
||||
I2C_TypeDef *i2c1 = I2C1;
|
||||
PWR_TypeDef *pwr = PWR;
|
||||
SYSCFG_TypeDef *syscfg = SYSCFG;
|
||||
EXTI_TypeDef *exti = EXTI;
|
||||
ADC_TypeDef *adc1 = ADC1;
|
||||
ADC_Common_TypeDef *adc1_common = ADC1_COMMON;
|
||||
ADC_Common_TypeDef *adc = ADC;
|
||||
TIM_TypeDef *tim1 = TIM1;
|
||||
SPI_TypeDef *spi1 = SPI1;
|
||||
USART_TypeDef *usart1 = USART1;
|
||||
TIM_TypeDef *tim16 = TIM16;
|
||||
TIM_TypeDef *tim17 = TIM17;
|
||||
DBGMCU_TypeDef *dbgmcu = DBGMCU;
|
||||
DMA_TypeDef *dma1 = DMA1;
|
||||
DMA_Channel_TypeDef *dma1_channel1 = DMA1_Channel1;
|
||||
DMA_Channel_TypeDef *dma1_channel2 = DMA1_Channel2;
|
||||
DMA_Channel_TypeDef *dma1_channel3 = DMA1_Channel3;
|
||||
DMA_Channel_TypeDef *dma1_channel4 = DMA1_Channel4;
|
||||
DMA_Channel_TypeDef *dma1_channel5 = DMA1_Channel5;
|
||||
FLASH_TypeDef *flash = FLASH;
|
||||
OB_TypeDef *ob = OB;
|
||||
RCC_TypeDef *rcc = RCC;
|
||||
CRC_TypeDef *crc = CRC;
|
||||
GPIO_TypeDef *gpioa = GPIOA;
|
||||
GPIO_TypeDef *gpiob = GPIOB;
|
||||
GPIO_TypeDef *gpioc = GPIOC;
|
||||
GPIO_TypeDef *gpiod = GPIOD;
|
||||
GPIO_TypeDef *gpiof = GPIOF;
|
||||
|
||||
#include <core_cm0.h>
|
||||
|
||||
/* core_cm0.h */
|
||||
SCB_Type *scb = SCB;
|
||||
SysTick_Type *systick = SysTick;
|
||||
NVIC_Type *nvic = NVIC;
|
||||
|
||||
#endif//__GENERATED_CMSIS_HEADER_EXPORTS__
|
||||
36
fw/main.c
36
fw/main.c
|
|
@ -17,29 +17,34 @@
|
|||
|
||||
#include "global.h"
|
||||
|
||||
#include "adc.h"
|
||||
|
||||
volatile unsigned int sys_time = 0;
|
||||
volatile unsigned int sys_time_seconds = 0;
|
||||
|
||||
void TIM1_BRK_UP_TRG_COM_Handler() {
|
||||
TIM1->SR &= ~TIM_SR_UIF_Msk;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
RCC->CR |= RCC_CR_HSEON;
|
||||
while (!(RCC->CR&RCC_CR_HSERDY));
|
||||
RCC->CFGR &= ~RCC_CFGR_PLLMUL_Msk & ~RCC_CFGR_SW_Msk & ~RCC_CFGR_PPRE_Msk & ~RCC_CFGR_HPRE_Msk;
|
||||
RCC->CFGR |= (2<<RCC_CFGR_PLLMUL_Pos) | RCC_CFGR_PLLSRC_HSE_PREDIV; /* PLL x4 -> 32.0MHz */
|
||||
RCC->CFGR2 &= ~RCC_CFGR2_PREDIV_Msk;
|
||||
RCC->CFGR2 |= RCC_CFGR2_PREDIV_DIV2; /* prediv :2 -> 4.0MHz */
|
||||
RCC->CFGR |= ((6-2)<<RCC_CFGR_PLLMUL_Pos) | RCC_CFGR_PLLSRC_HSE_PREDIV; /* PLL x6 -> 48.0MHz */
|
||||
RCC->CR |= RCC_CR_PLLON;
|
||||
while (!(RCC->CR&RCC_CR_PLLRDY));
|
||||
RCC->CFGR |= (2<<RCC_CFGR_SW_Pos);
|
||||
SystemCoreClockUpdate();
|
||||
SysTick_Config(SystemCoreClock/1000); /* 1ms interval */
|
||||
|
||||
/* Turn on lots of neat things */
|
||||
RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_FLITFEN;
|
||||
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN | RCC_APB2ENR_DBGMCUEN | RCC_APB2ENR_TIM1EN;
|
||||
RCC->AHBENR |= RCC_AHBENR_DMAEN | RCC_AHBENR_GPIOAEN | RCC_AHBENR_FLITFEN;
|
||||
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN | RCC_APB2ENR_ADCEN| RCC_APB2ENR_DBGMCUEN | RCC_APB2ENR_TIM1EN | RCC_APB2ENR_TIM1EN;;
|
||||
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
|
||||
|
||||
GPIOA->MODER |=
|
||||
(0<<GPIO_MODER_MODER0_Pos) /* PA0 - Vmeas_A */
|
||||
| (0<<GPIO_MODER_MODER1_Pos) /* PA1 - Vmeas_B */
|
||||
(3<<GPIO_MODER_MODER0_Pos) /* PA0 - Vmeas_A to ADC */
|
||||
| (3<<GPIO_MODER_MODER1_Pos) /* PA1 - Vmeas_B to ADC */
|
||||
| (1<<GPIO_MODER_MODER2_Pos) /* PA2 - LOAD */
|
||||
| (1<<GPIO_MODER_MODER3_Pos) /* PA3 - CH0 */
|
||||
| (1<<GPIO_MODER_MODER4_Pos) /* PA4 - CH3 */
|
||||
|
|
@ -57,7 +62,20 @@ int main(void) {
|
|||
| (2<<GPIO_OSPEEDR_OSPEEDR6_Pos) /* CH2 */
|
||||
| (2<<GPIO_OSPEEDR_OSPEEDR7_Pos); /* CH1 */
|
||||
|
||||
SysTick_Config(SystemCoreClock/1000); /* 1ms interval */
|
||||
/* Setup CC1 and CC2. CC2 generates the LED drivers' STROBE, CC1 triggers the IRQ handler */
|
||||
TIM1->BDTR = TIM_BDTR_MOE;
|
||||
TIM1->CCMR2 = (6<<TIM_CCMR2_OC4M_Pos); /* PWM Mode 1 */
|
||||
TIM1->CCER = TIM_CCER_CC4E;
|
||||
TIM1->CCR4 = 1;
|
||||
TIM1->DIER = TIM_DIER_UIE;
|
||||
|
||||
TIM1->PSC = SystemCoreClock/1000000 - 1; /* 1.0us/tick */
|
||||
TIM1->ARR = 20-1; /* 20us */
|
||||
/* Preload all values */
|
||||
TIM1->EGR |= TIM_EGR_UG;
|
||||
TIM1->CR1 = TIM_CR1_ARPE;
|
||||
/* And... go! */
|
||||
TIM1->CR1 |= TIM_CR1_CEN;
|
||||
|
||||
void set_outputs(uint8_t val) {
|
||||
int a=!!(val&1), b=!!(val&2), c=!!(val&4), d=!!(val&8);
|
||||
|
|
@ -66,6 +84,8 @@ int main(void) {
|
|||
}
|
||||
set_outputs(0);
|
||||
|
||||
adc_init();
|
||||
|
||||
uint8_t out_state = 0x01;
|
||||
#define DEBOUNCE 100
|
||||
int debounce_ctr = 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue