diff options
| author | Keith Packard <keithp@keithp.com> | 2015-01-26 22:14:57 -0800 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2015-01-26 22:14:57 -0800 | 
| commit | 729bb7a405460db8d44c9ff6ee903b28c7499a02 (patch) | |
| tree | f2184151a3f2dd2f7fef76f016a340c7a79f37d1 /src/stmf0 | |
| parent | a01effc2f64c757c907e0f4937b4d3710b97bde0 (diff) | |
altos/stmf0: Add ADC and DMA APIs
The ADC api is what USBtrng wants; a way to repeatedly read a single
ADC input as fast as possible.
Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'src/stmf0')
| -rw-r--r-- | src/stmf0/ao_adc_fast.c | 188 | ||||
| -rw-r--r-- | src/stmf0/ao_adc_fast.h | 27 | ||||
| -rw-r--r-- | src/stmf0/ao_dma_stm.c | 141 | ||||
| -rw-r--r-- | src/stmf0/ao_interrupt.c | 11 | ||||
| -rw-r--r-- | src/stmf0/stm32f0.h | 314 | 
5 files changed, 522 insertions, 159 deletions
diff --git a/src/stmf0/ao_adc_fast.c b/src/stmf0/ao_adc_fast.c new file mode 100644 index 00000000..5885ae4f --- /dev/null +++ b/src/stmf0/ao_adc_fast.c @@ -0,0 +1,188 @@ +/* + * Copyright © 2015 Keith Packard <keithp@keithp.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; version 2 of the License. + * + * 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., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include <ao.h> +#include <ao_adc_fast.h> + +static uint8_t			ao_adc_done; + +/* + * Callback from DMA ISR + * + * Mark time in ring, shut down DMA engine + */ +static void ao_adc_dma_done(int index) +{ +	(void) index; +	ao_adc_done = 1; +	ao_wakeup(&ao_adc_done); +} + +/* + * Start the ADC sequence using the DMA engine + */ +void +ao_adc_read(uint16_t *dest, int len) +{ +	ao_adc_done = 0; +	stm_adc.isr = 0; +	ao_dma_set_transfer(STM_DMA_INDEX(STM_DMA_CHANNEL_ADC_1), +			    &stm_adc.dr, +			    dest, +			    len, +			    (0 << STM_DMA_CCR_MEM2MEM) | +			    (STM_DMA_CCR_PL_HIGH << STM_DMA_CCR_PL) | +			    (STM_DMA_CCR_MSIZE_16 << STM_DMA_CCR_MSIZE) | +			    (STM_DMA_CCR_PSIZE_16 << STM_DMA_CCR_PSIZE) | +			    (1 << STM_DMA_CCR_MINC) | +			    (0 << STM_DMA_CCR_PINC) | +			    (0 << STM_DMA_CCR_CIRC) | +			    (STM_DMA_CCR_DIR_PER_TO_MEM << STM_DMA_CCR_DIR)); +	ao_dma_set_isr(STM_DMA_INDEX(STM_DMA_CHANNEL_ADC_1), ao_adc_dma_done); +	ao_dma_start(STM_DMA_INDEX(STM_DMA_CHANNEL_ADC_1)); + +	stm_adc.cr |= (1 << STM_ADC_CR_ADSTART); +	ao_arch_block_interrupts(); +	while (!ao_adc_done) +		ao_sleep(&ao_adc_done); +	ao_arch_release_interrupts(); + +	ao_dma_done_transfer(STM_DMA_INDEX(STM_DMA_CHANNEL_ADC_1)); + +	stm_adc.cr |= (1 << STM_ADC_CR_ADSTP); +	while ((stm_adc.cr & (1 << STM_ADC_CR_ADSTP)) != 0) +		; +} + +void +ao_adc_init(void) +{ +	uint32_t	chselr; +	int		i; + +	/* Reset ADC */ +	stm_rcc.apb2rstr |= (1 << STM_RCC_APB2RSTR_ADCRST); +	stm_rcc.apb2rstr &= ~(1 << STM_RCC_APB2RSTR_ADCRST); + +	/* Turn on ADC pins */ +	stm_rcc.ahbenr |= AO_ADC_RCC_AHBENR; + +#ifdef AO_ADC_PIN0_PORT +	stm_moder_set(AO_ADC_PIN0_PORT, AO_ADC_PIN0_PIN, STM_MODER_ANALOG); +#endif +#ifdef AO_ADC_PIN1_PORT +	stm_moder_set(AO_ADC_PIN1_PORT, AO_ADC_PIN1_PIN, STM_MODER_ANALOG); +#endif +#ifdef AO_ADC_PIN2_PORT +	stm_moder_set(AO_ADC_PIN2_PORT, AO_ADC_PIN2_PIN, STM_MODER_ANALOG); +#endif +#ifdef AO_ADC_PIN3_PORT +	stm_moder_set(AO_ADC_PIN3_PORT, AO_ADC_PIN3_PIN, STM_MODER_ANALOG); +#endif +#ifdef AO_ADC_PIN4_PORT +	stm_moder_set(AO_ADC_PIN4_PORT, AO_ADC_PIN4_PIN, STM_MODER_ANALOG); +#endif +#ifdef AO_ADC_PIN5_PORT +	stm_moder_set(AO_ADC_PIN5_PORT, AO_ADC_PIN5_PIN, STM_MODER_ANALOG); +#endif +#ifdef AO_ADC_PIN6_PORT +	stm_moder_set(AO_ADC_PIN6_PORT, AO_ADC_PIN6_PIN, STM_MODER_ANALOG); +#endif +#ifdef AO_ADC_PIN7_PORT +	stm_moder_set(AO_ADC_PIN7_PORT, AO_ADC_PIN7_PIN, STM_MODER_ANALOG); +#endif +#ifdef AO_ADC_PIN24_PORT +	#error "Too many ADC ports" +#endif + +	stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_ADCEN); + +	chselr = 0; +#if AO_NUM_ADC > 0 +	chselr |= (1 << AO_ADC_PIN0_CH); +#endif +#if AO_NUM_ADC > 1 +	chselr |= (1 << AO_ADC_PIN1_CH); +#endif +#if AO_NUM_ADC > 2 +	chselr |= (1 << AO_ADC_PIN2_CH); +#endif +#if AO_NUM_ADC > 3 +	chselr |= (1 << AO_ADC_PIN3_CH); +#endif +#if AO_NUM_ADC > 4 +	chselr |= (1 << AO_ADC_PIN4_CH); +#endif +#if AO_NUM_ADC > 5 +	chselr |= (1 << AO_ADC_PIN5_CH); +#endif +#if AO_NUM_ADC > 6 +	chselr |= (1 << AO_ADC_PIN6_CH); +#endif +#if AO_NUM_ADC > 7 +	chselr |= (1 << AO_ADC_PIN7_CH); +#endif +#if AO_NUM_ADC > 8 +#error Need more ADC defines +#endif +	stm_adc.chselr = chselr; + +	/* Set the clock */ +	stm_adc.cfgr2 = STM_ADC_CFGR2_CKMODE_PCLK_2 << STM_ADC_CFGR2_CKMODE; + +	/* Shortest sample time */ +	stm_adc.smpr = STM_ADC_SMPR_SMP_1_5 << STM_ADC_SMPR_SMP; + +	/* Calibrate */ +	stm_adc.cr |= (1 << STM_ADC_CR_ADCAL); +	for (i = 0; i < 0xf000; i++) { +		if ((stm_adc.cr & (1 << STM_ADC_CR_ADCAL)) == 0) +			break; +	} + +	/* Enable */ +	stm_adc.cr |= (1 << STM_ADC_CR_ADEN); +	while ((stm_adc.isr & (1 << STM_ADC_ISR_ADRDY)) == 0) +		; + +	stm_adc.cfgr1 = ((0 << STM_ADC_CFGR1_AWDCH) | +			 (0 << STM_ADC_CFGR1_AWDEN) | +			 (0 << STM_ADC_CFGR1_AWDSGL) | +			 (0 << STM_ADC_CFGR1_DISCEN) | +			 (0 << STM_ADC_CFGR1_AUTOOFF) | +			 (1 << STM_ADC_CFGR1_WAIT) | +			 (1 << STM_ADC_CFGR1_CONT) | +			 (0 << STM_ADC_CFGR1_OVRMOD) | +			 (STM_ADC_CFGR1_EXTEN_DISABLE << STM_ADC_CFGR1_EXTEN) | +			 (0 << STM_ADC_CFGR1_ALIGN) | +			 (STM_ADC_CFGR1_RES_12 << STM_ADC_CFGR1_RES) | +			 (STM_ADC_CFGR1_SCANDIR_UP << STM_ADC_CFGR1_SCANDIR) | +			 (STM_ADC_CFGR1_DMACFG_ONESHOT << STM_ADC_CFGR1_DMACFG) | +			 (1 << STM_ADC_CFGR1_DMAEN)); +	stm_adc.ccr = 0; + +	/* Clear any stale status bits */ +	stm_adc.isr = 0; + +	/* Turn on syscfg */ +	stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_SYSCFGCOMPEN); + +	/* Set ADC to use DMA channel 1 (option 1) */ +	stm_syscfg.cfgr1 &= ~(1 << STM_SYSCFG_CFGR1_ADC_DMA_RMP); + +	ao_dma_alloc(STM_DMA_INDEX(STM_DMA_CHANNEL_ADC_1)); +} diff --git a/src/stmf0/ao_adc_fast.h b/src/stmf0/ao_adc_fast.h new file mode 100644 index 00000000..a2408d14 --- /dev/null +++ b/src/stmf0/ao_adc_fast.h @@ -0,0 +1,27 @@ +/* + * Copyright © 2015 Keith Packard <keithp@keithp.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; version 2 of the License. + * + * 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., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_ADC_FAST_H_ +#define _AO_ADC_FAST_H_ + +void +ao_adc_read(uint16_t *dest, int len); + +void +ao_adc_init(void); + +#endif /* _AO_ADC_FAST_H_ */ diff --git a/src/stmf0/ao_dma_stm.c b/src/stmf0/ao_dma_stm.c new file mode 100644 index 00000000..78fabe18 --- /dev/null +++ b/src/stmf0/ao_dma_stm.c @@ -0,0 +1,141 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.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; version 2 of the License. + * + * 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., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include "ao.h" + +struct ao_dma_config { +	void		(*isr)(int index); +}; + +uint8_t ao_dma_done[STM_NUM_DMA]; + +static struct ao_dma_config ao_dma_config[STM_NUM_DMA]; +static uint8_t ao_dma_allocated[STM_NUM_DMA]; +static uint8_t ao_dma_mutex[STM_NUM_DMA]; +static uint8_t ao_dma_active; + +#define id(ch)		STM_DMA_INDEX(ch) +#define id_mask(id)	(STM_DMA_ISR_MASK << (id)) +#define ch_mask(ch)	id_mask(id(ch)) + +static void +ao_dma_isr(uint8_t low_index, uint8_t high_index, uint32_t mask) { +	/* Get channel interrupt bits */ +	uint32_t	isr = stm_dma.isr & mask; +	uint8_t		index; + +	/* Ack them */ +	stm_dma.ifcr = isr; +	for (index = low_index; index <= high_index; index++) { +		if (isr & id_mask(index)) { +			if (ao_dma_config[index].isr) +				(*ao_dma_config[index].isr)(index); +			else { +				ao_dma_done[index] = 1; +				ao_wakeup(&ao_dma_done[index]); +			} +		} +	} +} + +void stm_dma_ch1_isr(void) { ao_dma_isr(id(1), id(1), ch_mask(1)); } +void stm_dma_ch2_3_isr(void) { ao_dma_isr(id(2), id(3), ch_mask(2) | ch_mask(3)); } +void stm_dma1_ch4_5_6_isr(void) { ao_dma_isr(id(4), id(6), ch_mask(4) | ch_mask(5) | ch_mask(6)); } + +void +ao_dma_set_transfer(uint8_t 		index, +		    volatile void	*peripheral, +		    void		*memory, +		    uint16_t		count, +		    uint32_t		ccr) +{ +	if (ao_dma_allocated[index]) { +		if (ao_dma_mutex[index]) +			ao_panic(AO_PANIC_DMA); +		ao_dma_mutex[index] = 1; +	} else +		ao_mutex_get(&ao_dma_mutex[index]); +	ao_arch_critical( +		if (ao_dma_active++ == 0) +			stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_DMAEN); +		); +	stm_dma.channel[index].ccr = ccr | (1 << STM_DMA_CCR_TCIE); +	stm_dma.channel[index].cndtr = count; +	stm_dma.channel[index].cpar = peripheral; +	stm_dma.channel[index].cmar = memory; +	ao_dma_config[index].isr = NULL; +} + +void +ao_dma_set_isr(uint8_t index, void (*isr)(int)) +{ +	ao_dma_config[index].isr = isr; +} + +void +ao_dma_start(uint8_t index) +{ +	ao_dma_done[index] = 0; +	stm_dma.channel[index].ccr |= (1 << STM_DMA_CCR_EN); +} + +void +ao_dma_done_transfer(uint8_t index) +{ +	stm_dma.channel[index].ccr &= ~(1 << STM_DMA_CCR_EN); +	ao_arch_critical( +		if (--ao_dma_active == 0) +			stm_rcc.ahbenr &= ~(1 << STM_RCC_AHBENR_DMAEN); +		); +	if (ao_dma_allocated[index]) +		ao_dma_mutex[index] = 0; +	else +		ao_mutex_put(&ao_dma_mutex[index]); +} + +void +ao_dma_abort(uint8_t index) +{ +	stm_dma.channel[index].ccr &= ~(1 << STM_DMA_CCR_EN); +	ao_wakeup(&ao_dma_done[index]); +} + +void +ao_dma_alloc(uint8_t index) +{ +	if (ao_dma_allocated[index]) +		ao_panic(AO_PANIC_DMA); +	ao_dma_allocated[index] = 1; +} + +#define STM_NUM_DMA_ISR	3 + +void +ao_dma_init(void) +{ +	int	isr_id; +	int	index; + +	for (isr_id = 0; isr_id < STM_NUM_DMA_ISR; isr_id++) { +		stm_nvic_set_enable(STM_ISR_DMA_CH1_POS + isr_id); +		stm_nvic_set_priority(STM_ISR_DMA_CH1_POS + isr_id, 4); +	} +	for (index = 0; index < STM_NUM_DMA; index++) { +		ao_dma_allocated[index] = 0; +		ao_dma_mutex[index] = 0; +	} +} diff --git a/src/stmf0/ao_interrupt.c b/src/stmf0/ao_interrupt.c index b6a3147f..c6d8ef34 100644 --- a/src/stmf0/ao_interrupt.c +++ b/src/stmf0/ao_interrupt.c @@ -74,6 +74,9 @@ void start(void)  	}  #endif  #if RELOCATE_INTERRUPT +	/* Turn on syscfg */ +	stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_SYSCFGCOMPEN); +  	memcpy(&__interrupt_start__, &__interrupt_rom__, &__interrupt_end__ - &__interrupt_start__);  	stm_syscfg.cfgr1 = (stm_syscfg.cfgr1 & ~(STM_SYSCFG_CFGR1_MEM_MODE_MASK << STM_SYSCFG_CFGR1_MEM_MODE)) |  		(STM_SYSCFG_CFGR1_MEM_MODE_SRAM << STM_SYSCFG_CFGR1_MEM_MODE); @@ -112,8 +115,8 @@ isr(exti2_3)  isr(exti4_15)  isr(tsc)  isr(dma_ch1) -isr(dma_ch2_3_dma2_ch1_2) -isr(dma_ch4_5_6_7_dma2_ch3_4_5) +isr(dma_ch2_3) +isr(dma_ch4_5_6)  isr(adc_comp)  isr(tim1_brk_up_trg_com)  isr(tim1_cc) @@ -157,8 +160,8 @@ const void *stm_interrupt_vector[] = {  	i(0x5c, exti4_15),  	i(0x60, tsc),  	i(0x64, dma_ch1), -	i(0x68, dma_ch2_3_dma2_ch1_2), -	i(0x6c, dma_ch4_5_6_7_dma2_ch3_4_5), +	i(0x68, dma_ch2_3), +	i(0x6c, dma_ch4_5_6),  	i(0x70, adc_comp),  	i(0x74, tim1_brk_up_trg_com),  	i(0x78, tim1_cc), diff --git a/src/stmf0/stm32f0.h b/src/stmf0/stm32f0.h index 504db433..456f7631 100644 --- a/src/stmf0/stm32f0.h +++ b/src/stmf0/stm32f0.h @@ -587,6 +587,19 @@ extern struct stm_rcc stm_rcc;  #define  STM_RCC_CFGR_SW_HSI48		3  #define  STM_RCC_CFGR_SW_MASK		3 +#define STM_RCC_APB2RSTR_DBGMCURST	22 +#define STM_RCC_APB2RSTR_TIM17RST	18 +#define STM_RCC_APB2RSTR_TIM16RST	17 +#define STM_RCC_APB2RSTR_TIM15RST	16 +#define STM_RCC_APB2RSTR_USART1RST	14 +#define STM_RCC_APB2RSTR_SPI1RST	12 +#define STM_RCC_APB2RSTR_TIM1RST	11 +#define STM_RCC_APB2RSTR_ADCRST		9 +#define STM_RCC_APB2RSTR_USART8RST	7 +#define STM_RCC_APB2RSTR_USART7RST	6 +#define STM_RCC_APB2RSTR_USART6RST	5 +#define STM_RCC_APB2RSTR_SYSCFGRST	1 +  #define STM_RCC_APB1RSTR_CECRST		30  #define STM_RCC_APB1RSTR_DACRST		29  #define STM_RCC_APB1RSTR_PWRRST		28 @@ -618,7 +631,7 @@ extern struct stm_rcc stm_rcc;  #define STM_RCC_AHBENR_FLITFEN	4  #define STM_RCC_AHBENR_SRAMEN	2  #define STM_RCC_AHBENR_DMA2EN	1 -#define STM_RCC_AHBENR_DMAEM	0 +#define STM_RCC_AHBENR_DMAEN	0  #define STM_RCC_APB2ENR_DBGMCUEN	22  #define STM_RCC_APB2ENR_TIM17EN		18 @@ -1262,7 +1275,7 @@ struct stm_dma_channel {  	vuint32_t	reserved;  }; -#define STM_NUM_DMA	7 +#define STM_NUM_DMA	6  struct stm_dma {  	vuint32_t		isr; @@ -1272,7 +1285,7 @@ struct stm_dma {  extern struct stm_dma stm_dma; -/* DMA channels go from 1 to 7, instead of 0 to 6 (sigh) +/* DMA channels go from 1 to 6, instead of 0 to 5 (sigh)   */  #define STM_DMA_INDEX(channel)		((channel) - 1) @@ -1323,39 +1336,70 @@ extern struct stm_dma stm_dma;  #define STM_DMA_CCR_TCIE		(1)  #define STM_DMA_CCR_EN			(0) -#define STM_DMA_CHANNEL_ADC1		1 +/* DMA channel assignments. When a peripheral has multiple channels + * (indicated with _<number>), then it can be configured to either + * channel using syscfg.cfgr1 + */ + +#define STM_DMA_CHANNEL_ADC_1		1 +#define STM_DMA_CHANNEL_ADC_2		2 +  #define STM_DMA_CHANNEL_SPI1_RX		2  #define STM_DMA_CHANNEL_SPI1_TX		3 +  #define STM_DMA_CHANNEL_SPI2_RX		4  #define STM_DMA_CHANNEL_SPI2_TX		5 -#define STM_DMA_CHANNEL_USART3_TX	2 -#define STM_DMA_CHANNEL_USART3_RX	3 -#define STM_DMA_CHANNEL_USART1_TX	4 -#define STM_DMA_CHANNEL_USART1_RX	5 -#define STM_DMA_CHANNEL_USART2_RX	6 -#define STM_DMA_CHANNEL_USART2_TX	7 + +#define STM_DMA_CHANNEL_USART1_TX_1	2 +#define STM_DMA_CHANNEL_USART1_RX_1	3 +#define STM_DMA_CHANNEL_USART1_TX_2	4 +#define STM_DMA_CHANNEL_USART1_RX_2	5 + +#define STM_DMA_CHANNEL_USART2_RX	4 +#define STM_DMA_CHANNEL_USART2_TX	5 + +#define STM_DMA_CHANNEL_I2C1_TX		2 +#define STM_DMA_CHANNEL_I2C1_RX		3 +  #define STM_DMA_CHANNEL_I2C2_TX		4  #define STM_DMA_CHANNEL_I2C2_RX		5 -#define STM_DMA_CHANNEL_I2C1_TX		6 -#define STM_DMA_CHANNEL_I2C1_RX		7 + +#define STM_DMA_CHANNEL_TIM1_CH1	2 +#define STM_DMA_CHANNEL_TIM1_CH2	3 +#define STM_DMA_CHANNEL_TIM1_CH4	4 +#define STM_DMA_CHANNEL_TIM1_TRIG	4 +#define STM_DMA_CHANNEL_TIM1_COM	4 +#define STM_DMA_CHANNEL_TIM1_CH3	5 +#define STM_DMA_CHANNEL_TIM1_UP		5 +  #define STM_DMA_CHANNEL_TIM2_CH3	1  #define STM_DMA_CHANNEL_TIM2_UP		2 +#define STM_DMA_CHANNEL_TIM2_CH2	3 +#define STM_DMA_CHANNEL_TIM2_CH4	4  #define STM_DMA_CHANNEL_TIM2_CH1	5 -#define STM_DMA_CHANNEL_TIM2_CH2	7 -#define STM_DMA_CHANNEL_TIM2_CH4	7 +  #define STM_DMA_CHANNEL_TIM3_CH3	2  #define STM_DMA_CHANNEL_TIM3_CH4	3  #define STM_DMA_CHANNEL_TIM3_UP		3 -#define STM_DMA_CHANNEL_TIM3_CH1	6 -#define STM_DMA_CHANNEL_TIM3_TRIG	6 -#define STM_DMA_CHANNEL_TIM4_CH1	1 -#define STM_DMA_CHANNEL_TIM4_CH2	4 -#define STM_DMA_CHANNEL_TIM4_CH3	5 -#define STM_DMA_CHANNEL_TIM4_UP		7 -#define STM_DMA_CHANNEL_TIM6_UP_DA	2 -#define STM_DMA_CHANNEL_C_CHANNEL1	2 -#define STM_DMA_CHANNEL_TIM7_UP_DA	3 -#define STM_DMA_CHANNEL_C_CHANNEL2	3 +#define STM_DMA_CHANNEL_TIM3_CH1	4 +#define STM_DMA_CHANNEL_TIM3_TRIG	4 + +#define STM_DMA_CHANNEL_TIM6_UP_DAC	2 + +#define STM_DMA_CHANNEL_TIM15_CH1	5 +#define STM_DMA_CHANNEL_TIM15_UP	5 +#define STM_DMA_CHANNEL_TIM15_TRIG	5 +#define STM_DMA_CHANNEL_TIM15_COM	5 + +#define STM_DMA_CHANNEL_TIM16_CH1_1	3 +#define STM_DMA_CHANNEL_TIM16_UP_1	3 +#define STM_DMA_CHANNEL_TIM16_CH1_2	4 +#define STM_DMA_CHANNEL_TIM16_UP_2	4 + +#define STM_DMA_CHANNEL_TIM17_CH1_1	1 +#define STM_DMA_CHANNEL_TIM17_UP_1	1 +#define STM_DMA_CHANNEL_TIM17_CH1_2	2 +#define STM_DMA_CHANNEL_TIM17_UP_2	2  /*   * Only spi channel 1 and 2 can use DMA @@ -1419,143 +1463,103 @@ extern struct stm_spi stm_spi1, stm_spi2, stm_spi3;  #define STM_SPI_SR_RXNE		0  struct stm_adc { -	vuint32_t	sr; -	vuint32_t	cr1; -	vuint32_t	cr2; -	vuint32_t	smpr1; -	vuint32_t	smpr2; -	vuint32_t	smpr3; -	vuint32_t	jofr1; -	vuint32_t	jofr2; -	vuint32_t	jofr3; -	vuint32_t	jofr4; -	vuint32_t	htr; -	vuint32_t	ltr; -	vuint32_t	sqr1; -	vuint32_t	sqr2; -	vuint32_t	sqr3; -	vuint32_t	sqr4; -	vuint32_t	sqr5; -	vuint32_t	jsqr; -	vuint32_t	jdr1; -	vuint32_t	jdr2; -	vuint32_t	jdr3; -	vuint32_t	jdr4; +	vuint32_t	isr; +	vuint32_t	ier; +	vuint32_t	cr; +	vuint32_t	cfgr1; + +	vuint32_t	cfgr2; +	vuint32_t	smpr; +	vuint32_t	r_18; +	vuint32_t	r_1c; + +	vuint32_t	tr; +	vuint32_t	r_24; +	vuint32_t	chselr; +	vuint32_t	r_2c; + +	vuint32_t	r_30[4]; +  	vuint32_t	dr; -	uint8_t		reserved[0x300 - 0x5c]; -	vuint32_t	csr; + +	uint8_t		r_44[0x308 - 0x44];  	vuint32_t	ccr;  };  extern struct stm_adc stm_adc; -#define STM_ADC_SR_JCNR		9 -#define STM_ADC_SR_RCNR		8 -#define STM_ADC_SR_ADONS	6 -#define STM_ADC_SR_OVR		5 -#define STM_ADC_SR_STRT		4 -#define STM_ADC_SR_JSTRT	3 -#define STM_ADC_SR_JEOC		2 -#define STM_ADC_SR_EOC		1 -#define STM_ADC_SR_AWD		0 - -#define STM_ADC_CR1_OVRIE	26 -#define STM_ADC_CR1_RES		24 -#define  STM_ADC_CR1_RES_12		0 -#define  STM_ADC_CR1_RES_10		1 -#define  STM_ADC_CR1_RES_8		2 -#define  STM_ADC_CR1_RES_6		3 -#define  STM_ADC_CR1_RES_MASK		3 -#define STM_ADC_CR1_AWDEN       23 -#define STM_ADC_CR1_JAWDEN	22 -#define STM_ADC_CR1_PDI		17 -#define STM_ADC_CR1_PDD		16 -#define STM_ADC_CR1_DISCNUM	13 -#define  STM_ADC_CR1_DISCNUM_1		0 -#define  STM_ADC_CR1_DISCNUM_2		1 -#define  STM_ADC_CR1_DISCNUM_3		2 -#define  STM_ADC_CR1_DISCNUM_4		3 -#define  STM_ADC_CR1_DISCNUM_5		4 -#define  STM_ADC_CR1_DISCNUM_6		5 -#define  STM_ADC_CR1_DISCNUM_7		6 -#define  STM_ADC_CR1_DISCNUM_8		7 -#define  STM_ADC_CR1_DISCNUM_MASK	7 -#define STM_ADC_CR1_JDISCEN	12 -#define STM_ADC_CR1_DISCEN	11 -#define STM_ADC_CR1_JAUTO	10 -#define STM_ADC_CR1_AWDSGL	9 -#define STM_ADC_CR1_SCAN	8 -#define STM_ADC_CR1_JEOCIE	7 -#define STM_ADC_CR1_AWDIE	6 -#define STM_ADC_CR1_EOCIE	5 -#define STM_ADC_CR1_AWDCH	0 -#define  STM_ADC_CR1_AWDCH_MASK		0x1f - -#define STM_ADC_CR2_SWSTART	30 -#define STM_ADC_CR2_EXTEN	28 -#define  STM_ADC_CR2_EXTEN_DISABLE	0 -#define  STM_ADC_CR2_EXTEN_RISING	1 -#define  STM_ADC_CR2_EXTEN_FALLING	2 -#define  STM_ADC_CR2_EXTEN_BOTH		3 -#define  STM_ADC_CR2_EXTEN_MASK		3 -#define STM_ADC_CR2_EXTSEL	24 -#define  STM_ADC_CR2_EXTSEL_TIM9_CC2	0 -#define  STM_ADC_CR2_EXTSEL_TIM9_TRGO	1 -#define  STM_ADC_CR2_EXTSEL_TIM2_CC3	2 -#define  STM_ADC_CR2_EXTSEL_TIM2_CC2	3 -#define  STM_ADC_CR2_EXTSEL_TIM3_TRGO	4 -#define  STM_ADC_CR2_EXTSEL_TIM4_CC4	5 -#define  STM_ADC_CR2_EXTSEL_TIM2_TRGO	6 -#define  STM_ADC_CR2_EXTSEL_TIM3_CC1	7 -#define  STM_ADC_CR2_EXTSEL_TIM3_CC3	8 -#define  STM_ADC_CR2_EXTSEL_TIM4_TRGO	9 -#define  STM_ADC_CR2_EXTSEL_TIM6_TRGO	10 -#define  STM_ADC_CR2_EXTSEL_EXTI_11	15 -#define  STM_ADC_CR2_EXTSEL_MASK	15 -#define STM_ADC_CR2_JWSTART	22 -#define STM_ADC_CR2_JEXTEN	20 -#define  STM_ADC_CR2_JEXTEN_DISABLE	0 -#define  STM_ADC_CR2_JEXTEN_RISING	1 -#define  STM_ADC_CR2_JEXTEN_FALLING	2 -#define  STM_ADC_CR2_JEXTEN_BOTH	3 -#define  STM_ADC_CR2_JEXTEN_MASK	3 -#define STM_ADC_CR2_JEXTSEL	16 -#define  STM_ADC_CR2_JEXTSEL_TIM9_CC1	0 -#define  STM_ADC_CR2_JEXTSEL_TIM9_TRGO	1 -#define  STM_ADC_CR2_JEXTSEL_TIM2_TRGO	2 -#define  STM_ADC_CR2_JEXTSEL_TIM2_CC1	3 -#define  STM_ADC_CR2_JEXTSEL_TIM3_CC4	4 -#define  STM_ADC_CR2_JEXTSEL_TIM4_TRGO	5 -#define  STM_ADC_CR2_JEXTSEL_TIM4_CC1	6 -#define  STM_ADC_CR2_JEXTSEL_TIM4_CC2	7 -#define  STM_ADC_CR2_JEXTSEL_TIM4_CC3	8 -#define  STM_ADC_CR2_JEXTSEL_TIM10_CC1	9 -#define  STM_ADC_CR2_JEXTSEL_TIM7_TRGO	10 -#define  STM_ADC_CR2_JEXTSEL_EXTI_15	15 -#define  STM_ADC_CR2_JEXTSEL_MASK	15 -#define STM_ADC_CR2_ALIGN	11 -#define STM_ADC_CR2_EOCS	10 -#define STM_ADC_CR2_DDS		9 -#define STM_ADC_CR2_DMA		8 -#define STM_ADC_CR2_DELS	4 -#define  STM_ADC_CR2_DELS_NONE		0 -#define  STM_ADC_CR2_DELS_UNTIL_READ	1 -#define  STM_ADC_CR2_DELS_7		2 -#define  STM_ADC_CR2_DELS_15		3 -#define  STM_ADC_CR2_DELS_31		4 -#define  STM_ADC_CR2_DELS_63		5 -#define  STM_ADC_CR2_DELS_127		6 -#define  STM_ADC_CR2_DELS_255		7 -#define  STM_ADC_CR2_DELS_MASK		7 -#define STM_ADC_CR2_CONT	1 -#define STM_ADC_CR2_ADON	0 - -#define STM_ADC_CCR_TSVREFE	23 -#define STM_ADC_CCR_ADCPRE	16 -#define  STM_ADC_CCR_ADCPRE_HSI_1	0 -#define  STM_ADC_CCR_ADCPRE_HSI_2	1 -#define  STM_ADC_CCR_ADCPRE_HSI_4	2 -#define  STM_ADC_CCR_ADCPRE_MASK	3 +#define STM_ADC_ISR_AWD		7 +#define STM_ADC_ISR_OVR		4 +#define STM_ADC_ISR_EOSEQ	3 +#define STM_ADC_ISR_EOC		2 +#define STM_ADC_ISR_EOSMP	1 +#define STM_ADC_ISR_ADRDY	0 + +#define STM_ADC_IER_AWDIE	7 +#define STM_ADC_IER_OVRIE	4 +#define STM_ADC_IER_EOSEQIE	3 +#define STM_ADC_IER_EOCIE	2 +#define STM_ADC_IER_EOSMPIE	1 +#define STM_ADC_IER_ADRDYIE	0 + +#define STM_ADC_CR_ADCAL	31 +#define STM_ADC_CR_ADSTP	4 +#define STM_ADC_CR_ADSTART	2 +#define STM_ADC_CR_ADDIS	1 +#define STM_ADC_CR_ADEN		0 + +#define STM_ADC_CFGR1_AWDCH	26 +#define STM_ADC_CFGR1_AWDEN	23 +#define STM_ADC_CFGR1_AWDSGL	22 +#define STM_ADC_CFGR1_DISCEN	16 +#define STM_ADC_CFGR1_AUTOOFF	15 +#define STM_ADC_CFGR1_WAIT	14 +#define STM_ADC_CFGR1_CONT	13 +#define STM_ADC_CFGR1_OVRMOD	12 +#define STM_ADC_CFGR1_EXTEN	10 +#define  STM_ADC_CFGR1_EXTEN_DISABLE	0 +#define  STM_ADC_CFGR1_EXTEN_RISING	1 +#define  STM_ADC_CFGR1_EXTEN_FALLING	2 +#define  STM_ADC_CFGR1_EXTEN_BOTH	3 +#define  STM_ADC_CFGR1_EXTEN_MASK	3 + +#define STM_ADC_CFGR1_EXTSEL	6 +#define STM_ADC_CFGR1_ALIGN	5 +#define STM_ADC_CFGR1_RES	3 +#define  STM_ADC_CFGR1_RES_12		0 +#define  STM_ADC_CFGR1_RES_10		1 +#define  STM_ADC_CFGR1_RES_8		2 +#define  STM_ADC_CFGR1_RES_6		3 +#define  STM_ADC_CFGR1_RES_MASK		3 +#define STM_ADC_CFGR1_SCANDIR	2 +#define  STM_ADC_CFGR1_SCANDIR_UP	0 +#define  STM_ADC_CFGR1_SCANDIR_DOWN	1 +#define STM_ADC_CFGR1_DMACFG	1 +#define  STM_ADC_CFGR1_DMACFG_ONESHOT	0 +#define  STM_ADC_CFGR1_DMACFG_CIRCULAR	1 +#define STM_ADC_CFGR1_DMAEN	0 + +#define STM_ADC_CFGR2_CKMODE	30 +#define  STM_ADC_CFGR2_CKMODE_ADCCLK	0 +#define  STM_ADC_CFGR2_CKMODE_PCLK_2	1 +#define  STM_ADC_CFGR2_CKMODE_PCLK_4	2 + +#define STM_ADC_SMPR_SMP	0 +#define  STM_ADC_SMPR_SMP_1_5		0 +#define  STM_ADC_SMPR_SMP_7_5		1 +#define  STM_ADC_SMPR_SMP_13_5		2 +#define  STM_ADC_SMPR_SMP_28_5		3 +#define  STM_ADC_SMPR_SMP_41_5		4 +#define  STM_ADC_SMPR_SMP_55_5		5 +#define  STM_ADC_SMPR_SMP_71_5		6 +#define  STM_ADC_SMPR_SMP_239_5		7 + +#define STM_ADC_TR_HT		16 +#define STM_ADC_TR_LT		0 + +#define STM_ADC_CCR_VBATEN	24 +#define STM_ADC_CCR_TSEN	23 +#define STM_ADC_CCR_VREFEN	22  struct stm_cal {  	uint16_t	ts_cal_cold;	/* 30°C */  | 
