From: Keith Packard Date: Sat, 8 Aug 2020 03:12:22 +0000 (-0700) Subject: altos/stm32l0: Big update in functionality X-Git-Tag: 1.9.5~1^2~30 X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=commitdiff_plain;h=476fd2f2c23da427b6b2a68f7d285767a924041e altos/stm32l0: Big update in functionality Fix baud rate setting in LPUART Add code to turn everything off. Signed-off-by: Keith Packard --- diff --git a/src/stm32l0/ao_arch_funcs.h b/src/stm32l0/ao_arch_funcs.h index 65cf3f6f..297bd66c 100644 --- a/src/stm32l0/ao_arch_funcs.h +++ b/src/stm32l0/ao_arch_funcs.h @@ -386,6 +386,8 @@ struct ao_stm_usart { #endif }; +#include + void ao_debug_out(char c); @@ -591,4 +593,7 @@ ao_arch_wait_interrupt(void) { void start(void); +bool +ao_storage_device_is_erased(uint32_t pos); + #endif /* _AO_ARCH_FUNCS_H_ */ diff --git a/src/stm32l0/ao_exti_stm.c b/src/stm32l0/ao_exti_stm.c index daada01e..d808d1e9 100644 --- a/src/stm32l0/ao_exti_stm.c +++ b/src/stm32l0/ao_exti_stm.c @@ -50,7 +50,6 @@ void stm_exti15_4_isr(void) { ao_exti_range_isr(4, 15, 0xfff0); } void ao_exti_setup (struct stm_gpio *gpio, uint8_t pin, uint8_t mode, void (*callback)(void)) { uint32_t mask = 1 << pin; - uint32_t pupdr; uint8_t irq; uint8_t prio; @@ -59,7 +58,9 @@ ao_exti_setup (struct stm_gpio *gpio, uint8_t pin, uint8_t mode, void (*callback /* configure gpio to interrupt routing */ stm_exticr_set(gpio, pin); +#if 0 if (!(mode & AO_EXTI_PIN_NOCONFIGURE)) { + uint32_t pupdr; /* configure pin as input, setting selected pull-up/down mode */ stm_moder_set(gpio, pin, STM_MODER_INPUT); switch (mode & (AO_EXTI_MODE_PULL_UP|AO_EXTI_MODE_PULL_DOWN)) { @@ -76,6 +77,7 @@ ao_exti_setup (struct stm_gpio *gpio, uint8_t pin, uint8_t mode, void (*callback } stm_pupdr_set(gpio, pin, pupdr); } +#endif /* Set interrupt mask and rising/falling mode */ stm_exti.imr &= ~mask; diff --git a/src/stm32l0/ao_flash_stm32l0.c b/src/stm32l0/ao_flash_stm32l0.c index 68c21c82..ba327442 100644 --- a/src/stm32l0/ao_flash_stm32l0.c +++ b/src/stm32l0/ao_flash_stm32l0.c @@ -132,11 +132,6 @@ ao_flash_page(uint32_t *page, uint32_t *src) } #endif -void -ao_storage_setup(void) -{ -} - static ao_pos_t write_pos; static uint8_t write_pending; static union { @@ -210,23 +205,22 @@ ao_storage_device_write(ao_pos_t pos, void *buf, uint16_t len) return 1; } -/* Erase device from pos through pos + ao_storage_block */ -uint8_t -ao_storage_device_erase(uint32_t pos) +bool +ao_storage_device_is_erased(uint32_t pos) { - ao_flash_erase_page(__storage + pos); - return 1; -} + uint8_t *m = ((uint8_t *) __storage) + pos; + uint32_t i; -/* Initialize low-level device bits */ -void -ao_storage_device_init(void) -{ + for (i = 0; i < STM_FLASH_PAGE_SIZE; i++) + if (*m++ != AO_STORAGE_ERASED_BYTE) + return false; + return true; } -/* Print out information about flash chips */ -void -ao_storage_device_info(void) +/* Erase device from pos through pos + ao_storage_block */ +uint8_t +ao_storage_device_erase(uint32_t pos) { - printf("Detected chips 1 size %d\n", ao_storage_total); + ao_flash_erase_page(__storage + (pos >> 2)); + return 1; } diff --git a/src/stm32l0/ao_lpuart_stm.c b/src/stm32l0/ao_lpuart_stm.c index 8fdc09f4..c4a23f5b 100644 --- a/src/stm32l0/ao_lpuart_stm.c +++ b/src/stm32l0/ao_lpuart_stm.c @@ -182,7 +182,7 @@ ao_lpuart_set_speed(struct ao_stm_lpuart *lpuart, uint8_t speed) { if (speed > AO_SERIAL_SPEED_115200) return; - lpuart->reg->brr = AO_PCLK1 / ao_usart_speeds[speed]; + lpuart->reg->brr = 256 * AO_PCLK1 / ao_usart_speeds[speed]; } static void @@ -355,16 +355,16 @@ ao_lpuart1_enable(void) void ao_lpuart1_disable(void) { - /* Disable interrupts */ - stm_nvic_clear_enable(STM_ISR_LPUART1_AES_POS); - /* Stop LPUART */ ao_lpuart_disable(&ao_stm_lpuart1); + /* Disable interrupts */ + stm_nvic_clear_enable(STM_ISR_LPUART1_AES_POS); + /* Remap pins to GPIO use */ # if LPUART_1_PA0_PA1 - stm_afr_set(&stm_gpioa, 0, STM_AFR_NONE); - stm_afr_set(&stm_gpioa, 1, STM_AFR_NONE); + stm_moder_set(&stm_gpioa, 0, STM_MODER_INPUT); + stm_moder_set(&stm_gpioa, 1, STM_MODER_OUTPUT); # else # error "No LPUART_1 port configuration specified" # endif @@ -372,3 +372,4 @@ ao_lpuart1_disable(void) /* Disable LPUART */ stm_rcc.apb1enr &= ~(1 << STM_RCC_APB1ENR_LPUART1EN); } + diff --git a/src/stm32l0/ao_serial_stm.c b/src/stm32l0/ao_serial_stm.c index 8fead99e..ac745d97 100644 --- a/src/stm32l0/ao_serial_stm.c +++ b/src/stm32l0/ao_serial_stm.c @@ -380,10 +380,24 @@ ao_serial_set_sw_rts_cts(struct ao_stm_usart *usart, void ao_serial_shutdown(void) { +# if SERIAL_2_PA2_PA3 + stm_moder_set(&stm_gpioa, 2, STM_MODER_INPUT); + stm_moder_set(&stm_gpioa, 3, STM_MODER_INPUT); +# elif SERIAL_2_PA9_PA10 + stm_moder_set(&stm_gpioa, 9, STM_MODER_INPUT); + stm_moder_set(&stm_gpioa, 10, STM_MODER_INPUT); +# elif SERIAL_2_PA14_PA15 + stm_moder_set(&stm_gpioa, 14, STM_MODER_INPUT); + stm_moder_set(&stm_gpioa, 15, STM_MODER_INPUT); +# elif SERIAL_2_PB6_PB7 + stm_moder_set(&stm_gpiob, 6, STM_MODER_INPUT); + stm_moder_set(&stm_gpiob, 7, STM_MODER_INPUT); +#endif #if HAS_SERIAL_1 stm_rcc.apb2enr &= ~(1 << STM_RCC_APB2ENR_USART1EN); #endif #if HAS_SERIAL_2 + stm_nvic_set_disable(STM_ISR_USART2_POS); stm_rcc.apb1enr &= ~(1 << STM_RCC_APB1ENR_USART2EN); #endif } diff --git a/src/stm32l0/ao_timer_stm32l0.h b/src/stm32l0/ao_timer_stm32l0.h deleted file mode 100644 index d00deffa..00000000 --- a/src/stm32l0/ao_timer_stm32l0.h +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright © 2012 Keith Packard - * - * 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 2 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, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#include "ao.h" -#include -#if HAS_FAKE_FLIGHT -#include -#endif - -#ifndef HAS_TICK -#define HAS_TICK 1 -#endif - -#if HAS_TICK || defined(AO_TIMER_HOOK) - -#if HAS_TICK -volatile AO_TICK_TYPE ao_tick_count; - -AO_TICK_TYPE -ao_time(void) -{ - return ao_tick_count; -} - -uint64_t -ao_time_ns(void) -{ - AO_TICK_TYPE before, after; - uint32_t cvr; - - do { - before = ao_tick_count; - cvr = stm_systick.cvr; - after = ao_tick_count; - } while (before != after); - - return (uint64_t) after * (1000000000ULL / AO_HERTZ) + - (uint64_t) cvr * (1000000000ULL / AO_SYSTICK); -} - -#endif - -#if AO_DATA_ALL -volatile uint8_t ao_data_interval = 1; -volatile uint8_t ao_data_count; -#endif - -void stm_systick_isr(void) -{ - ao_validate_cur_stack(); - if (stm_systick.csr & (1 << STM_SYSTICK_CSR_COUNTFLAG)) { -#if HAS_TICK - ++ao_tick_count; -#endif -#if HAS_TASK_QUEUE - if (ao_task_alarm_tick && (int16_t) (ao_tick_count - ao_task_alarm_tick) >= 0) - ao_task_check_alarm((uint16_t) ao_tick_count); -#endif -#if AO_DATA_ALL - if (++ao_data_count == ao_data_interval) { - ao_data_count = 0; -#if HAS_FAKE_FLIGHT - if (ao_fake_flight_active) - ao_fake_flight_poll(); - else -#endif - ao_adc_poll(); -#if (AO_DATA_ALL & ~(AO_DATA_ADC)) - ao_wakeup((void *) &ao_data_count); -#endif - } -#endif -#ifdef AO_TIMER_HOOK - AO_TIMER_HOOK; -#endif - } -} - -#if HAS_ADC -void -ao_timer_set_adc_interval(uint8_t interval) -{ - ao_arch_critical( - ao_data_interval = interval; - ao_data_count = 0; - ); -} -#endif - -#define SYSTICK_RELOAD (AO_SYSTICK / 100 - 1) - -void -ao_timer_init(void) -{ - stm_systick.rvr = SYSTICK_RELOAD; - stm_systick.cvr = 0; - stm_systick.csr = ((1 << STM_SYSTICK_CSR_ENABLE) | - (1 << STM_SYSTICK_CSR_TICKINT) | - (STM_SYSTICK_CSR_CLKSOURCE_HCLK_8 << STM_SYSTICK_CSR_CLKSOURCE)); - stm_nvic.shpr15_12 |= AO_STM_NVIC_CLOCK_PRIORITY << 24; -} - -#endif - -void -ao_clock_init(void) -{ - uint32_t cfgr; - uint32_t cr; - - /* Switch to MSI while messing about */ - stm_rcc.cr |= (1 << STM_RCC_CR_MSION); - while (!(stm_rcc.cr & (1 << STM_RCC_CR_MSIRDY))) - ao_arch_nop(); - - stm_rcc.cfgr = (stm_rcc.cfgr & ~(STM_RCC_CFGR_SW_MASK << STM_RCC_CFGR_SW)) | - (STM_RCC_CFGR_SW_MSI << STM_RCC_CFGR_SW); - - /* wait for system to switch to MSI */ - while ((stm_rcc.cfgr & (STM_RCC_CFGR_SWS_MASK << STM_RCC_CFGR_SWS)) != - (STM_RCC_CFGR_SWS_MSI << STM_RCC_CFGR_SWS)) - ao_arch_nop(); - - /* reset SW, HPRE, PPRE1, PPRE2, MCOSEL and MCOPRE */ - stm_rcc.cfgr &= (uint32_t)0x88FFC00C; - - /* reset HSION, HSEON, CSSON and PLLON bits */ - stm_rcc.cr &= 0xeefefffe; - - /* reset PLLSRC, PLLMUL and PLLDIV bits */ - stm_rcc.cfgr &= 0xff02ffff; - - /* Disable all interrupts */ - stm_rcc.cir = 0; - -#if AO_HSE -#if AO_HSE_BYPASS - stm_rcc.cr |= (1 << STM_RCC_CR_HSEBYP); -#else - stm_rcc.cr &= ~(1 << STM_RCC_CR_HSEBYP); -#endif - /* Enable HSE clock */ - stm_rcc.cr |= (1 << STM_RCC_CR_HSEON); - while (!(stm_rcc.cr & (1 << STM_RCC_CR_HSERDY))) - asm("nop"); - -#define STM_RCC_CFGR_SWS_TARGET_CLOCK (STM_RCC_CFGR_SWS_HSE << STM_RCC_CFGR_SWS) -#define STM_RCC_CFGR_SW_TARGET_CLOCK (STM_RCC_CFGR_SW_HSE) -#define STM_PLLSRC AO_HSE -#define STM_RCC_CFGR_PLLSRC_TARGET_CLOCK (1 << STM_RCC_CFGR_PLLSRC) -#else -#define STM_HSI 16000000 -#define STM_RCC_CFGR_SWS_TARGET_CLOCK (STM_RCC_CFGR_SWS_HSI << STM_RCC_CFGR_SWS) -#define STM_RCC_CFGR_SW_TARGET_CLOCK (STM_RCC_CFGR_SW_HSI) -#define STM_PLLSRC STM_HSI -#define STM_RCC_CFGR_PLLSRC_TARGET_CLOCK (0 << STM_RCC_CFGR_PLLSRC) -#endif - -#if !AO_HSE || HAS_ADC || HAS_ADC_SINGLE - /* Enable HSI RC clock 16MHz */ - stm_rcc.cr |= (1 << STM_RCC_CR_HSION); - while (!(stm_rcc.cr & (1 << STM_RCC_CR_HSIRDY))) - asm("nop"); -#endif - - /* Set flash latency to tolerate 32MHz SYSCLK -> 1 wait state */ - - /* Enable 64-bit access and prefetch */ - stm_flash.acr |= (1 << STM_FLASH_ACR_ACC64); - stm_flash.acr |= (1 << STM_FLASH_ACR_PRFEN); - - /* Enable 1 wait state so the CPU can run at 32MHz */ - stm_flash.acr |= (1 << STM_FLASH_ACR_LATENCY); - - /* Enable power interface clock */ - stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_PWREN); - - /* Set voltage range to 1.8V */ - - /* poll VOSF bit in PWR_CSR. Wait until it is reset to 0 */ - while ((stm_pwr.csr & (1 << STM_PWR_CSR_VOSF)) != 0) - asm("nop"); - - /* Configure voltage scaling range */ - cr = stm_pwr.cr; - cr &= ~(STM_PWR_CR_VOS_MASK << STM_PWR_CR_VOS); - cr |= (STM_PWR_CR_VOS_1_8 << STM_PWR_CR_VOS); - stm_pwr.cr = cr; - - /* poll VOSF bit in PWR_CSR. Wait until it is reset to 0 */ - while ((stm_pwr.csr & (1 << STM_PWR_CSR_VOSF)) != 0) - asm("nop"); - - /* HCLK to 16MHz -> AHB prescaler = /1 */ - cfgr = stm_rcc.cfgr; - cfgr &= ~(STM_RCC_CFGR_HPRE_MASK << STM_RCC_CFGR_HPRE); - cfgr |= (AO_RCC_CFGR_HPRE_DIV << STM_RCC_CFGR_HPRE); - stm_rcc.cfgr = cfgr; - while ((stm_rcc.cfgr & (STM_RCC_CFGR_HPRE_MASK << STM_RCC_CFGR_HPRE)) != - (AO_RCC_CFGR_HPRE_DIV << STM_RCC_CFGR_HPRE)) - asm ("nop"); - - /* APB1 Prescaler = AO_APB1_PRESCALER */ - cfgr = stm_rcc.cfgr; - cfgr &= ~(STM_RCC_CFGR_PPRE1_MASK << STM_RCC_CFGR_PPRE1); - cfgr |= (AO_RCC_CFGR_PPRE1_DIV << STM_RCC_CFGR_PPRE1); - stm_rcc.cfgr = cfgr; - - /* APB2 Prescaler = AO_APB2_PRESCALER */ - cfgr = stm_rcc.cfgr; - cfgr &= ~(STM_RCC_CFGR_PPRE2_MASK << STM_RCC_CFGR_PPRE2); - cfgr |= (AO_RCC_CFGR_PPRE2_DIV << STM_RCC_CFGR_PPRE2); - stm_rcc.cfgr = cfgr; - - /* Disable the PLL */ - stm_rcc.cr &= ~(1 << STM_RCC_CR_PLLON); - while (stm_rcc.cr & (1 << STM_RCC_CR_PLLRDY)) - asm("nop"); - - /* PLLVCO to 96MHz (for USB) -> PLLMUL = 6, PLLDIV = 4 */ - cfgr = stm_rcc.cfgr; - cfgr &= ~(STM_RCC_CFGR_PLLMUL_MASK << STM_RCC_CFGR_PLLMUL); - cfgr &= ~(STM_RCC_CFGR_PLLDIV_MASK << STM_RCC_CFGR_PLLDIV); - - cfgr |= (AO_RCC_CFGR_PLLMUL << STM_RCC_CFGR_PLLMUL); - cfgr |= (AO_RCC_CFGR_PLLDIV << STM_RCC_CFGR_PLLDIV); - - /* PLL source */ - cfgr &= ~(1 << STM_RCC_CFGR_PLLSRC); - cfgr |= STM_RCC_CFGR_PLLSRC_TARGET_CLOCK; - - stm_rcc.cfgr = cfgr; - - /* Enable the PLL and wait for it */ - stm_rcc.cr |= (1 << STM_RCC_CR_PLLON); - while (!(stm_rcc.cr & (1 << STM_RCC_CR_PLLRDY))) - asm("nop"); - - /* Switch to the PLL for the system clock */ - - cfgr = stm_rcc.cfgr; - cfgr &= ~(STM_RCC_CFGR_SW_MASK << STM_RCC_CFGR_SW); - cfgr |= (STM_RCC_CFGR_SW_PLL << STM_RCC_CFGR_SW); - stm_rcc.cfgr = cfgr; - for (;;) { - uint32_t c, part, mask, val; - - c = stm_rcc.cfgr; - mask = (STM_RCC_CFGR_SWS_MASK << STM_RCC_CFGR_SWS); - val = (STM_RCC_CFGR_SWS_PLL << STM_RCC_CFGR_SWS); - part = c & mask; - if (part == val) - break; - } - -#if 0 - stm_rcc.apb2rstr = 0xffff; - stm_rcc.apb1rstr = 0xffff; - stm_rcc.ahbrstr = 0x3f; - stm_rcc.ahbenr = (1 << STM_RCC_AHBENR_FLITFEN); - stm_rcc.apb2enr = 0; - stm_rcc.apb1enr = 0; - stm_rcc.ahbrstr = 0; - stm_rcc.apb1rstr = 0; - stm_rcc.apb2rstr = 0; -#endif - - /* Clear reset flags */ - stm_rcc.csr |= (1 << STM_RCC_CSR_RMVF); - - -#if DEBUG_THE_CLOCK - /* Output SYSCLK on PA8 for measurments */ - - stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOAEN); - - stm_afr_set(&stm_gpioa, 8, STM_AFR_AF0); - stm_moder_set(&stm_gpioa, 8, STM_MODER_ALTERNATE); - stm_ospeedr_set(&stm_gpioa, 8, STM_OSPEEDR_40MHz); - - stm_rcc.cfgr |= (STM_RCC_CFGR_MCOPRE_DIV_1 << STM_RCC_CFGR_MCOPRE); - stm_rcc.cfgr |= (STM_RCC_CFGR_MCOSEL_HSE << STM_RCC_CFGR_MCOSEL); -#endif -} diff --git a/src/stm32l0/stm32l0.h b/src/stm32l0/stm32l0.h index a99d861e..90f070ce 100644 --- a/src/stm32l0/stm32l0.h +++ b/src/stm32l0/stm32l0.h @@ -160,7 +160,6 @@ stm_pupdr_get(struct stm_gpio *gpio, int pin) { #define STM_AFR_SHIFT(pin) ((pin) << 2) #define STM_AFR_MASK 0xf -#define STM_AFR_NONE 0 #define STM_AFR_AF0 0x0 #define STM_AFR_AF1 0x1 #define STM_AFR_AF2 0x2 @@ -397,6 +396,7 @@ struct stm_lpuart { vuint32_t rdr; vuint32_t tdr; }; +extern struct stm_lpuart stm_lpuart1; #define stm_lpuart1 (*((struct stm_lpuart *) 0x40004800)) @@ -1155,6 +1155,10 @@ extern struct stm_scb stm_scb; #define STM_SCB_AIRCR_VECTCLRACTIVE 1 #define STM_SCB_AIRCR_VECTRESET 0 +#define STM_SCB_SCR_SVONPEND 4 +#define STM_SCB_SCR_SLEEPDEEP 2 +#define STM_SCB_SCR_SLEEPONEXIT 1 + struct stm_mpu { vuint32_t typer; vuint32_t cr; @@ -1673,21 +1677,15 @@ extern struct stm_flash_size stm_flash_size_reg; extern uint32_t stm_flash_size(void); -struct stm_unique_id { - uint32_t u_id0; - uint32_t u_id1; - uint32_t u_id2; -}; - -extern struct stm_unique_id stm_unique_id; -#define stm_unique_id (*((struct stm_unique_id) 0x1ff80050)) - struct stm_device_id { - uint32_t device_id; + char lot_num_4_6[3]; + uint8_t waf_num; + char lot_num_0_3[4]; + uint8_t unique_id[4]; }; extern struct stm_device_id stm_device_id; -#define stm_device_id (*((struct stm_device_id) 0x40015800)) +#define stm_device_id (*((struct stm_device_id *) 0x1ff80050)) #define STM_NUM_I2C 2