diff options
-rw-r--r-- | chip/stm32/adc-stm32f.c | 307 | ||||
-rw-r--r--[l---------] | chip/stm32/adc-stm32f3.c | 308 | ||||
-rw-r--r-- | chip/stm32/build.mk | 1 | ||||
-rw-r--r-- | chip/stm32/clock-stm32f.c | 304 | ||||
-rw-r--r-- | chip/stm32/config-stm32f100.h | 24 | ||||
-rw-r--r-- | chip/stm32/config-stm32f10x.h | 20 | ||||
-rw-r--r-- | chip/stm32/config_chip.h | 6 | ||||
-rw-r--r-- | chip/stm32/flash-stm32f.c | 130 | ||||
-rw-r--r--[l---------] | chip/stm32/flash-stm32f3.c | 131 | ||||
-rw-r--r-- | chip/stm32/gpio-stm32f.c | 149 | ||||
-rw-r--r-- | chip/stm32/gpio.c | 11 | ||||
-rw-r--r-- | chip/stm32/hwtimer.c | 2 | ||||
-rw-r--r-- | chip/stm32/hwtimer32.c | 2 | ||||
-rw-r--r-- | chip/stm32/i2c-stm32f.c | 769 | ||||
-rw-r--r-- | chip/stm32/jtag-stm32f.c | 14 | ||||
-rw-r--r-- | chip/stm32/pwm.c | 23 | ||||
-rw-r--r-- | chip/stm32/registers.h | 163 | ||||
-rw-r--r-- | chip/stm32/system.c | 3 | ||||
-rw-r--r-- | chip/stm32/usart-stm32f.c | 115 | ||||
-rw-r--r-- | chip/stm32/usart-stm32f.h | 20 | ||||
-rw-r--r-- | common/i2c.c | 11 |
21 files changed, 478 insertions, 2035 deletions
diff --git a/chip/stm32/adc-stm32f.c b/chip/stm32/adc-stm32f.c deleted file mode 100644 index 072c71b9df..0000000000 --- a/chip/stm32/adc-stm32f.c +++ /dev/null @@ -1,307 +0,0 @@ -/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "adc.h" -#include "adc_chip.h" -#include "common.h" -#include "console.h" -#include "dma.h" -#include "hooks.h" -#include "registers.h" -#include "task.h" -#include "timer.h" -#include "util.h" - -#define ADC_SINGLE_READ_TIMEOUT 3000 /* 3 ms */ - -#define SMPR1_EXPAND(v) ((v) | ((v) << 3) | ((v) << 6) | ((v) << 9) | \ - ((v) << 12) | ((v) << 15) | ((v) << 18) | \ - ((v) << 21)) -#define SMPR2_EXPAND(v) (SMPR1_EXPAND(v) | ((v) << 24) | ((v) << 27)) - -/* Default ADC sample time = 13.5 cycles */ -#ifndef CONFIG_ADC_SAMPLE_TIME -#define CONFIG_ADC_SAMPLE_TIME 2 -#endif - -struct mutex adc_lock; - -static int watchdog_ain_id; - -static const struct dma_option dma_adc_option = { - STM32_DMAC_ADC, (void *)&STM32_ADC_DR, - STM32_DMA_CCR_MSIZE_16_BIT | STM32_DMA_CCR_PSIZE_16_BIT, -}; - -static inline void adc_set_channel(int sample_id, int channel) -{ - uint32_t mask, val; - volatile uint32_t *sqr_reg; - - if (sample_id < 6) { - mask = 0x1f << (sample_id * 5); - val = channel << (sample_id * 5); - sqr_reg = &STM32_ADC_SQR3; - } else if (sample_id < 12) { - mask = 0x1f << ((sample_id - 6) * 5); - val = channel << ((sample_id - 6) * 5); - sqr_reg = &STM32_ADC_SQR2; - } else { - mask = 0x1f << ((sample_id - 12) * 5); - val = channel << ((sample_id - 12) * 5); - sqr_reg = &STM32_ADC_SQR1; - } - - *sqr_reg = (*sqr_reg & ~mask) | val; -} - -static void adc_configure(int ain_id) -{ - /* Set ADC channel */ - adc_set_channel(0, ain_id); - - /* Disable DMA */ - STM32_ADC_CR2 &= ~(1 << 8); - - /* Disable scan mode */ - STM32_ADC_CR1 &= ~(1 << 8); -} - -static void __attribute__((unused)) adc_configure_all(void) -{ - int i; - - /* Set ADC channels */ - STM32_ADC_SQR1 = (ADC_CH_COUNT - 1) << 20; - for (i = 0; i < ADC_CH_COUNT; ++i) - adc_set_channel(i, adc_channels[i].channel); - - /* Enable DMA */ - STM32_ADC_CR2 |= (1 << 8); - - /* Enable scan mode */ - STM32_ADC_CR1 |= (1 << 8); -} - -static inline int adc_powered(void) -{ - return STM32_ADC_CR2 & (1 << 0); -} - -static inline int adc_conversion_ended(void) -{ - return STM32_ADC_SR & (1 << 1); -} - -static int adc_watchdog_enabled(void) -{ - return STM32_ADC_CR1 & (1 << 23); -} - -static int adc_enable_watchdog_no_lock(void) -{ - /* Fail if watchdog already enabled */ - if (adc_watchdog_enabled()) - return EC_ERROR_UNKNOWN; - - /* Set channel */ - STM32_ADC_SQR3 = watchdog_ain_id; - STM32_ADC_SQR1 = 0; - STM32_ADC_CR1 = (STM32_ADC_CR1 & ~0x1f) | watchdog_ain_id; - - /* Clear interrupt bit */ - STM32_ADC_SR &= ~0x1; - - /* AWDSGL=1, SCAN=1, AWDIE=1, AWDEN=1 */ - STM32_ADC_CR1 |= (1 << 9) | (1 << 8) | (1 << 6) | (1 << 23); - - /* Disable DMA */ - STM32_ADC_CR2 &= ~(1 << 8); - - /* CONT=1 */ - STM32_ADC_CR2 |= (1 << 1); - - /* Start conversion */ - STM32_ADC_CR2 |= (1 << 0); - - return EC_SUCCESS; -} - -int adc_enable_watchdog(int ain_id, int high, int low) -{ - int ret; - - if (!adc_powered()) - return EC_ERROR_UNKNOWN; - - mutex_lock(&adc_lock); - - watchdog_ain_id = ain_id; - - /* Set thresholds */ - STM32_ADC_HTR = high & 0xfff; - STM32_ADC_LTR = low & 0xfff; - - ret = adc_enable_watchdog_no_lock(); - mutex_unlock(&adc_lock); - return ret; -} - -static int adc_disable_watchdog_no_lock(void) -{ - /* Fail if watchdog not running */ - if (!adc_watchdog_enabled()) - return EC_ERROR_UNKNOWN; - - /* AWDEN=0, AWDIE=0 */ - STM32_ADC_CR1 &= ~(1 << 23) & ~(1 << 6); - - /* CONT=0 */ - STM32_ADC_CR2 &= ~(1 << 1); - - return EC_SUCCESS; -} - -int adc_disable_watchdog(void) -{ - int ret; - - if (!adc_powered()) - return EC_ERROR_UNKNOWN; - - mutex_lock(&adc_lock); - ret = adc_disable_watchdog_no_lock(); - mutex_unlock(&adc_lock); - return ret; -} - -int adc_read_channel(enum adc_channel ch) -{ - const struct adc_t *adc = adc_channels + ch; - int value; - int restore_watchdog = 0; - timestamp_t deadline; - - if (!adc_powered()) - return EC_ERROR_UNKNOWN; - - mutex_lock(&adc_lock); - - if (adc_watchdog_enabled()) { - restore_watchdog = 1; - adc_disable_watchdog_no_lock(); - } - - adc_configure(adc->channel); - - /* Clear EOC bit */ - STM32_ADC_SR &= ~(1 << 1); - - /* Start conversion */ - STM32_ADC_CR2 |= (1 << 0); /* ADON */ - - /* Wait for EOC bit set */ - deadline.val = get_time().val + ADC_SINGLE_READ_TIMEOUT; - value = ADC_READ_ERROR; - do { - if (adc_conversion_ended()) { - value = STM32_ADC_DR & ADC_READ_MAX; - break; - } - } while (!timestamp_expired(deadline, NULL)); - - if (restore_watchdog) - adc_enable_watchdog_no_lock(); - - mutex_unlock(&adc_lock); - return (value == ADC_READ_ERROR) ? ADC_READ_ERROR : - value * adc->factor_mul / adc->factor_div + adc->shift; -} - -int adc_read_all_channels(int *data) -{ - int i; - int16_t raw_data[ADC_CH_COUNT]; - const struct adc_t *adc; - int restore_watchdog = 0; - int ret = EC_SUCCESS; - - if (!adc_powered()) - return EC_ERROR_UNKNOWN; - - mutex_lock(&adc_lock); - - if (adc_watchdog_enabled()) { - restore_watchdog = 1; - adc_disable_watchdog_no_lock(); - } - - adc_configure_all(); - - dma_clear_isr(STM32_DMAC_ADC); - dma_start_rx(&dma_adc_option, ADC_CH_COUNT, raw_data); - - /* Start conversion */ - STM32_ADC_CR2 |= (1 << 0); /* ADON */ - - if (dma_wait(STM32_DMAC_ADC)) { - ret = EC_ERROR_UNKNOWN; - goto exit_all_channels; - } - - for (i = 0; i < ADC_CH_COUNT; ++i) { - adc = adc_channels + i; - data[i] = raw_data[i] * adc->factor_mul / adc->factor_div + - adc->shift; - } - -exit_all_channels: - dma_disable(STM32_DMAC_ADC); - - if (restore_watchdog) - adc_enable_watchdog_no_lock(); - - mutex_unlock(&adc_lock); - return ret; -} - -static void adc_init(void) -{ - /* - * Enable ADC clock. - * APB2 clock is 16MHz. ADC clock prescaler is /2. - * So the ADC clock is 8MHz. - */ - STM32_RCC_APB2ENR |= (1 << 9); - - /* - * ADC clock is divided with respect to AHB, so no delay needed - * here. If ADC clock is the same as AHB, a dummy read on ADC - * register is needed here. - */ - - if (!adc_powered()) { - /* Power on ADC module */ - STM32_ADC_CR2 |= (1 << 0); /* ADON */ - - /* Reset calibration */ - STM32_ADC_CR2 |= (1 << 3); /* RSTCAL */ - while (STM32_ADC_CR2 & (1 << 3)) - ; - - /* A/D Calibrate */ - STM32_ADC_CR2 |= (1 << 2); /* CAL */ - while (STM32_ADC_CR2 & (1 << 2)) - ; - } - - /* Set right alignment */ - STM32_ADC_CR2 &= ~(1 << 11); - - /* Set sample time of all channels */ - STM32_ADC_SMPR1 = SMPR1_EXPAND(CONFIG_ADC_SAMPLE_TIME); - STM32_ADC_SMPR2 = SMPR2_EXPAND(CONFIG_ADC_SAMPLE_TIME); -} -DECLARE_HOOK(HOOK_INIT, adc_init, HOOK_PRIO_DEFAULT); diff --git a/chip/stm32/adc-stm32f3.c b/chip/stm32/adc-stm32f3.c index 65ace77ef4..072c71b9df 120000..100644 --- a/chip/stm32/adc-stm32f3.c +++ b/chip/stm32/adc-stm32f3.c @@ -1 +1,307 @@ -adc-stm32f.c
\ No newline at end of file +/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "adc.h" +#include "adc_chip.h" +#include "common.h" +#include "console.h" +#include "dma.h" +#include "hooks.h" +#include "registers.h" +#include "task.h" +#include "timer.h" +#include "util.h" + +#define ADC_SINGLE_READ_TIMEOUT 3000 /* 3 ms */ + +#define SMPR1_EXPAND(v) ((v) | ((v) << 3) | ((v) << 6) | ((v) << 9) | \ + ((v) << 12) | ((v) << 15) | ((v) << 18) | \ + ((v) << 21)) +#define SMPR2_EXPAND(v) (SMPR1_EXPAND(v) | ((v) << 24) | ((v) << 27)) + +/* Default ADC sample time = 13.5 cycles */ +#ifndef CONFIG_ADC_SAMPLE_TIME +#define CONFIG_ADC_SAMPLE_TIME 2 +#endif + +struct mutex adc_lock; + +static int watchdog_ain_id; + +static const struct dma_option dma_adc_option = { + STM32_DMAC_ADC, (void *)&STM32_ADC_DR, + STM32_DMA_CCR_MSIZE_16_BIT | STM32_DMA_CCR_PSIZE_16_BIT, +}; + +static inline void adc_set_channel(int sample_id, int channel) +{ + uint32_t mask, val; + volatile uint32_t *sqr_reg; + + if (sample_id < 6) { + mask = 0x1f << (sample_id * 5); + val = channel << (sample_id * 5); + sqr_reg = &STM32_ADC_SQR3; + } else if (sample_id < 12) { + mask = 0x1f << ((sample_id - 6) * 5); + val = channel << ((sample_id - 6) * 5); + sqr_reg = &STM32_ADC_SQR2; + } else { + mask = 0x1f << ((sample_id - 12) * 5); + val = channel << ((sample_id - 12) * 5); + sqr_reg = &STM32_ADC_SQR1; + } + + *sqr_reg = (*sqr_reg & ~mask) | val; +} + +static void adc_configure(int ain_id) +{ + /* Set ADC channel */ + adc_set_channel(0, ain_id); + + /* Disable DMA */ + STM32_ADC_CR2 &= ~(1 << 8); + + /* Disable scan mode */ + STM32_ADC_CR1 &= ~(1 << 8); +} + +static void __attribute__((unused)) adc_configure_all(void) +{ + int i; + + /* Set ADC channels */ + STM32_ADC_SQR1 = (ADC_CH_COUNT - 1) << 20; + for (i = 0; i < ADC_CH_COUNT; ++i) + adc_set_channel(i, adc_channels[i].channel); + + /* Enable DMA */ + STM32_ADC_CR2 |= (1 << 8); + + /* Enable scan mode */ + STM32_ADC_CR1 |= (1 << 8); +} + +static inline int adc_powered(void) +{ + return STM32_ADC_CR2 & (1 << 0); +} + +static inline int adc_conversion_ended(void) +{ + return STM32_ADC_SR & (1 << 1); +} + +static int adc_watchdog_enabled(void) +{ + return STM32_ADC_CR1 & (1 << 23); +} + +static int adc_enable_watchdog_no_lock(void) +{ + /* Fail if watchdog already enabled */ + if (adc_watchdog_enabled()) + return EC_ERROR_UNKNOWN; + + /* Set channel */ + STM32_ADC_SQR3 = watchdog_ain_id; + STM32_ADC_SQR1 = 0; + STM32_ADC_CR1 = (STM32_ADC_CR1 & ~0x1f) | watchdog_ain_id; + + /* Clear interrupt bit */ + STM32_ADC_SR &= ~0x1; + + /* AWDSGL=1, SCAN=1, AWDIE=1, AWDEN=1 */ + STM32_ADC_CR1 |= (1 << 9) | (1 << 8) | (1 << 6) | (1 << 23); + + /* Disable DMA */ + STM32_ADC_CR2 &= ~(1 << 8); + + /* CONT=1 */ + STM32_ADC_CR2 |= (1 << 1); + + /* Start conversion */ + STM32_ADC_CR2 |= (1 << 0); + + return EC_SUCCESS; +} + +int adc_enable_watchdog(int ain_id, int high, int low) +{ + int ret; + + if (!adc_powered()) + return EC_ERROR_UNKNOWN; + + mutex_lock(&adc_lock); + + watchdog_ain_id = ain_id; + + /* Set thresholds */ + STM32_ADC_HTR = high & 0xfff; + STM32_ADC_LTR = low & 0xfff; + + ret = adc_enable_watchdog_no_lock(); + mutex_unlock(&adc_lock); + return ret; +} + +static int adc_disable_watchdog_no_lock(void) +{ + /* Fail if watchdog not running */ + if (!adc_watchdog_enabled()) + return EC_ERROR_UNKNOWN; + + /* AWDEN=0, AWDIE=0 */ + STM32_ADC_CR1 &= ~(1 << 23) & ~(1 << 6); + + /* CONT=0 */ + STM32_ADC_CR2 &= ~(1 << 1); + + return EC_SUCCESS; +} + +int adc_disable_watchdog(void) +{ + int ret; + + if (!adc_powered()) + return EC_ERROR_UNKNOWN; + + mutex_lock(&adc_lock); + ret = adc_disable_watchdog_no_lock(); + mutex_unlock(&adc_lock); + return ret; +} + +int adc_read_channel(enum adc_channel ch) +{ + const struct adc_t *adc = adc_channels + ch; + int value; + int restore_watchdog = 0; + timestamp_t deadline; + + if (!adc_powered()) + return EC_ERROR_UNKNOWN; + + mutex_lock(&adc_lock); + + if (adc_watchdog_enabled()) { + restore_watchdog = 1; + adc_disable_watchdog_no_lock(); + } + + adc_configure(adc->channel); + + /* Clear EOC bit */ + STM32_ADC_SR &= ~(1 << 1); + + /* Start conversion */ + STM32_ADC_CR2 |= (1 << 0); /* ADON */ + + /* Wait for EOC bit set */ + deadline.val = get_time().val + ADC_SINGLE_READ_TIMEOUT; + value = ADC_READ_ERROR; + do { + if (adc_conversion_ended()) { + value = STM32_ADC_DR & ADC_READ_MAX; + break; + } + } while (!timestamp_expired(deadline, NULL)); + + if (restore_watchdog) + adc_enable_watchdog_no_lock(); + + mutex_unlock(&adc_lock); + return (value == ADC_READ_ERROR) ? ADC_READ_ERROR : + value * adc->factor_mul / adc->factor_div + adc->shift; +} + +int adc_read_all_channels(int *data) +{ + int i; + int16_t raw_data[ADC_CH_COUNT]; + const struct adc_t *adc; + int restore_watchdog = 0; + int ret = EC_SUCCESS; + + if (!adc_powered()) + return EC_ERROR_UNKNOWN; + + mutex_lock(&adc_lock); + + if (adc_watchdog_enabled()) { + restore_watchdog = 1; + adc_disable_watchdog_no_lock(); + } + + adc_configure_all(); + + dma_clear_isr(STM32_DMAC_ADC); + dma_start_rx(&dma_adc_option, ADC_CH_COUNT, raw_data); + + /* Start conversion */ + STM32_ADC_CR2 |= (1 << 0); /* ADON */ + + if (dma_wait(STM32_DMAC_ADC)) { + ret = EC_ERROR_UNKNOWN; + goto exit_all_channels; + } + + for (i = 0; i < ADC_CH_COUNT; ++i) { + adc = adc_channels + i; + data[i] = raw_data[i] * adc->factor_mul / adc->factor_div + + adc->shift; + } + +exit_all_channels: + dma_disable(STM32_DMAC_ADC); + + if (restore_watchdog) + adc_enable_watchdog_no_lock(); + + mutex_unlock(&adc_lock); + return ret; +} + +static void adc_init(void) +{ + /* + * Enable ADC clock. + * APB2 clock is 16MHz. ADC clock prescaler is /2. + * So the ADC clock is 8MHz. + */ + STM32_RCC_APB2ENR |= (1 << 9); + + /* + * ADC clock is divided with respect to AHB, so no delay needed + * here. If ADC clock is the same as AHB, a dummy read on ADC + * register is needed here. + */ + + if (!adc_powered()) { + /* Power on ADC module */ + STM32_ADC_CR2 |= (1 << 0); /* ADON */ + + /* Reset calibration */ + STM32_ADC_CR2 |= (1 << 3); /* RSTCAL */ + while (STM32_ADC_CR2 & (1 << 3)) + ; + + /* A/D Calibrate */ + STM32_ADC_CR2 |= (1 << 2); /* CAL */ + while (STM32_ADC_CR2 & (1 << 2)) + ; + } + + /* Set right alignment */ + STM32_ADC_CR2 &= ~(1 << 11); + + /* Set sample time of all channels */ + STM32_ADC_SMPR1 = SMPR1_EXPAND(CONFIG_ADC_SAMPLE_TIME); + STM32_ADC_SMPR2 = SMPR2_EXPAND(CONFIG_ADC_SAMPLE_TIME); +} +DECLARE_HOOK(HOOK_INIT, adc_init, HOOK_PRIO_DEFAULT); diff --git a/chip/stm32/build.mk b/chip/stm32/build.mk index 19460eacde..1e0d6a60df 100644 --- a/chip/stm32/build.mk +++ b/chip/stm32/build.mk @@ -42,7 +42,6 @@ chip-$(HAS_TASK_KEYSCAN)+=keyboard_raw.o chip-$(HAS_TASK_POWERLED)+=power_led.o chip-$(CONFIG_FLASH)+=flash-$(CHIP_FAMILY).o ifdef CONFIG_FLASH -chip-$(CHIP_FAMILY_STM32F)+=flash-f.o chip-$(CHIP_FAMILY_STM32F0)+=flash-f.o chip-$(CHIP_FAMILY_STM32F3)+=flash-f.o endif diff --git a/chip/stm32/clock-stm32f.c b/chip/stm32/clock-stm32f.c deleted file mode 100644 index ed2c3abd2c..0000000000 --- a/chip/stm32/clock-stm32f.c +++ /dev/null @@ -1,304 +0,0 @@ -/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* Clocks and power management settings */ - -#include "atomic.h" -#include "clock.h" -#include "common.h" -#include "console.h" -#include "cpu.h" -#include "hwtimer.h" -#include "registers.h" -#include "system.h" -#include "task.h" -#include "timer.h" -#include "util.h" - -/* Allow serial console to wake up the EC from STOP mode */ -/* #define CONFIG_FORCE_CONSOLE_RESUME */ - -/* - * minimum delay to enter stop mode - * STOP mode wakeup time with regulator in low power mode is 5 us. - * PLL locking time is 200us. - */ -#define STOP_MODE_LATENCY 300 /* us */ - -/* - * RTC clock frequency (connected to LSI clock) - * - * TODO(crosbug.com/p/12281): Calibrate LSI frequency on a per-chip basis. The - * LSI on any given chip can be between 30 kHz to 60 kHz. Without calibration, - * LSI frequency may be off by as much as 50%. Fortunately, we don't do any - * high-precision delays based solely on LSI. - */ -#define RTC_FREQ 40000 /* Hz */ -#define US_PER_RTC_TICK (1000000 / RTC_FREQ) - -static void wait_rtc_ready(void) -{ - /* wait for Registers Synchronized Flag */ - while (!(STM32_RTC_CRL & (1 << 3))) - ; -} - -static void prepare_rtc_write(void) -{ - /* wait for RTOFF */ - while (!(STM32_RTC_CRL & (1 << 5))) - ; - /* set CNF bit */ - STM32_RTC_CRL |= (1 << 4); -} - -static void finalize_rtc_write(void) -{ - /* reset CNF bit */ - STM32_RTC_CRL &= ~(1 << 4); - /* wait for RTOFF */ - while (!(STM32_RTC_CRL & (1 << 5))) - ; -} - -uint32_t set_rtc_alarm(unsigned delay_s, unsigned delay_us) -{ - unsigned rtc_t0, rtc_t1; - - rtc_t0 = ((uint32_t)STM32_RTC_CNTH << 16) | STM32_RTC_CNTL; - rtc_t1 = rtc_t0 + delay_us / US_PER_RTC_TICK + delay_s * RTC_FREQ; - - prepare_rtc_write(); - /* set RTC alarm timestamp (using the 40kHz counter ) */ - STM32_RTC_ALRH = rtc_t1 >> 16; - STM32_RTC_ALRL = rtc_t1 & 0xffff; - /* clear RTC alarm */ - STM32_RTC_CRL &= ~2; - /* enable RTC alarm interrupt */ - STM32_RTC_CRL |= 2; - finalize_rtc_write(); - /* remove synchro flag */ - STM32_RTC_CRL &= ~(1 << 3); - - return rtc_t0; -} - -uint32_t reset_rtc_alarm(void) -{ - uint32_t rtc_stamp; - - wait_rtc_ready(); - - prepare_rtc_write(); - /* clear RTC alarm */ - STM32_RTC_CRL &= ~2; - finalize_rtc_write(); - STM32_EXTI_PR = (1 << 17); - - rtc_stamp = ((uint32_t)STM32_RTC_CNTH << 16) | STM32_RTC_CNTL; - return rtc_stamp; -} - -void __rtc_wakeup_irq(void) -{ - reset_rtc_alarm(); -} -DECLARE_IRQ(STM32_IRQ_RTC_WAKEUP, __rtc_wakeup_irq, 1); - -void __rtc_alarm_irq(void) -{ - reset_rtc_alarm(); -} -DECLARE_IRQ(STM32_IRQ_RTC_ALARM, __rtc_alarm_irq, 1); - -/* - * These were the clock settings we used for the STM32F103 reference, but - * they'll need updating for use on some other board. - * - * HSI = 8MHz, no prescaler, no MCO - * PLLSRC = HSI/2, PLLMUL = x12 => PLLCLK = 48MHz - * USB clock = PLLCLK - */ -#define DESIRED_CPU_CLOCK 48000000 -#define RCC_CFGR 0x00680000 -#error "Need board-specific clock settings" - -BUILD_ASSERT(CPU_CLOCK == DESIRED_CPU_CLOCK); - -static void config_hispeed_clock(void) -{ - /* Ensure that HSI is ON */ - if (!(STM32_RCC_CR & (1 << 1))) { - /* Enable HSI */ - STM32_RCC_CR |= 1 << 0; - /* Wait for HSI to be ready */ - while (!(STM32_RCC_CR & (1 << 1))) - ; - } - - STM32_RCC_CFGR = RCC_CFGR; - /* Enable the PLL */ - STM32_RCC_CR |= 1 << 24; - /* Wait for the PLL to lock */ - while (!(STM32_RCC_CR & (1 << 25))) - ; - /* switch to SYSCLK to the PLL */ - STM32_RCC_CFGR = RCC_CFGR | 0x02; - - /* wait until the PLL is the clock source */ - while ((STM32_RCC_CFGR & 0xc) != 0x8) - ; -} - -#ifdef CONFIG_HIBERNATE -void __enter_hibernate(uint32_t seconds, uint32_t microseconds) -{ - if (seconds || microseconds) - set_rtc_alarm(seconds, microseconds); - - /* interrupts off now */ - asm volatile("cpsid i"); - - /* enable the wake up pin */ - STM32_PWR_CSR |= STM32_PWR_CSR_EWUP; - STM32_PWR_CR |= 0xe; - CPU_SCB_SYSCTRL |= 0x4; - /* go to Standby mode */ - asm("wfi"); - - /* we should never reach that point */ - while (1) - ; -} -#endif - -#ifdef CONFIG_LOW_POWER_IDLE - -void clock_refresh_console_in_use(void) -{ -} - -#ifdef CONFIG_FORCE_CONSOLE_RESUME -static void enable_serial_wakeup(int enable) -{ - static uint32_t save_exticr; - - if (enable) { - /** - * allow to wake up from serial port (RX on pin PA10) - * by setting it as a GPIO with an external interrupt. - */ - save_exticr = STM32_AFIO_EXTICR(10 / 4); - STM32_AFIO_EXTICR(10 / 4) = (save_exticr & ~(0xf << 8)); - } else { - /* serial port wake up : don't go back to sleep */ - if (STM32_EXTI_PR & (1 << 10)) - disable_sleep(SLEEP_MASK_FORCE_NO_DSLEEP); - /* restore keyboard external IT on PC10 */ - STM32_AFIO_EXTICR(10 / 4) = save_exticr; - } -} -#else -static void enable_serial_wakeup(int enable) -{ -} -#endif - -/* Idle task. Executed when no tasks are ready to be scheduled. */ -void __idle(void) -{ - timestamp_t t0, t1; - int next_delay; - uint32_t rtc_t0, rtc_t1; - - while (1) { - asm volatile("cpsid i"); - - t0 = get_time(); - next_delay = __hw_clock_event_get() - t0.le.lo; - - if (DEEP_SLEEP_ALLOWED && (next_delay > STOP_MODE_LATENCY)) { - /* deep-sleep in STOP mode */ - - enable_serial_wakeup(1); - - /* set deep sleep bit */ - CPU_SCB_SYSCTRL |= 0x4; - - rtc_t0 = set_rtc_alarm(0, - next_delay - STOP_MODE_LATENCY); - asm("wfi"); - - CPU_SCB_SYSCTRL &= ~0x4; - - enable_serial_wakeup(0); - - /* re-lock the PLL */ - config_hispeed_clock(); - - /* fast forward timer according to RTC counter */ - rtc_t1 = reset_rtc_alarm(); - t1.val = t0.val + (rtc_t1 - rtc_t0) * US_PER_RTC_TICK; - force_time(t1); - } else { - /* normal idle : only CPU clock stopped */ - asm("wfi"); - } - asm volatile("cpsie i"); - } -} -#endif /* CONFIG_LOW_POWER_IDLE */ - -int clock_get_freq(void) -{ - return CPU_CLOCK; -} - -void clock_wait_bus_cycles(enum bus_type bus, uint32_t cycles) -{ - volatile uint32_t dummy __attribute__((unused)); - - if (bus == BUS_AHB) { - while (cycles--) - dummy = STM32_DMA1_REGS->isr; - } else { /* APB */ - while (cycles--) - dummy = STM32_USART_BRR(STM32_USART1_BASE); - } -} - -void clock_init(void) -{ - /* - * The initial state : - * SYSCLK from HSI (=8MHz), no divider on AHB, APB1, APB2 - * PLL unlocked, RTC enabled on LSE - */ - - config_hispeed_clock(); - - /* configure RTC clock */ - wait_rtc_ready(); - prepare_rtc_write(); - /* set RTC divider to /1 */ - STM32_RTC_PRLH = 0; - STM32_RTC_PRLL = 0; - finalize_rtc_write(); - /* setup RTC EXTINT17 to wake up us from STOP mode */ - STM32_EXTI_IMR |= (1 << 17); - STM32_EXTI_RTSR |= (1 << 17); - - /* - * Our deep sleep mode is STOP mode. - * clear PDDS (stop mode) , set LDDS (regulator in low power mode) - */ - STM32_PWR_CR = (STM32_PWR_CR & ~2) | 1; - - /* Enable RTC interrupts */ - task_enable_irq(STM32_IRQ_RTC_WAKEUP); - task_enable_irq(STM32_IRQ_RTC_ALARM); -} - - diff --git a/chip/stm32/config-stm32f100.h b/chip/stm32/config-stm32f100.h deleted file mode 100644 index 09a638c28f..0000000000 --- a/chip/stm32/config-stm32f100.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* Memory mapping */ -#define CONFIG_FLASH_BASE 0x08000000 -#define CONFIG_FLASH_PHYSICAL_SIZE 0x00020000 -#define CONFIG_FLASH_BANK_SIZE 0x1000 -#define CONFIG_FLASH_ERASE_SIZE 0x0400 /* erase bank size */ -#define CONFIG_FLASH_WRITE_SIZE 0x0002 /* minimum write size */ - -/* No page mode on STM32F, so no benefit to larger write sizes */ -#define CONFIG_FLASH_WRITE_IDEAL_SIZE 0x0002 - -#define CONFIG_RAM_BASE 0x20000000 -#define CONFIG_RAM_SIZE 0x00002000 - -/* Number of IRQ vectors on the NVIC */ -#define CONFIG_IRQ_COUNT 61 - -/* Reduced history because of limited RAM */ -#undef CONFIG_CONSOLE_HISTORY -#define CONFIG_CONSOLE_HISTORY 3 diff --git a/chip/stm32/config-stm32f10x.h b/chip/stm32/config-stm32f10x.h deleted file mode 100644 index e568d7ea87..0000000000 --- a/chip/stm32/config-stm32f10x.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* Memory mapping */ -#define CONFIG_FLASH_BASE 0x08000000 -#define CONFIG_FLASH_PHYSICAL_SIZE 0x00020000 -#define CONFIG_FLASH_BANK_SIZE 0x1000 -#define CONFIG_FLASH_ERASE_SIZE 0x0400 /* erase bank size */ -#define CONFIG_FLASH_WRITE_SIZE 0x0002 /* minimum write size */ - -/* No page mode on STM32F, so no benefit to larger write sizes */ -#define CONFIG_FLASH_WRITE_IDEAL_SIZE 0x0002 - -#define CONFIG_RAM_BASE 0x20000000 -#define CONFIG_RAM_SIZE (10 * 1024) - -/* Number of IRQ vectors on the NVIC */ -#define CONFIG_IRQ_COUNT 68 diff --git a/chip/stm32/config_chip.h b/chip/stm32/config_chip.h index 976e929b6e..614e61513f 100644 --- a/chip/stm32/config_chip.h +++ b/chip/stm32/config_chip.h @@ -24,12 +24,6 @@ #include "config-stm32l100.h" #elif defined(CHIP_VARIANT_STM32F373) #include "config-stm32f373.h" -#elif defined(CHIP_VARIANT_STM32F100) -/* STM32F100xx is currently the only outlier in the STM32F series */ -#include "config-stm32f100.h" -#elif defined(CHIP_VARIANT_STM32F10X) -/* STM32F101xx, STM32F102xx, STM32F103xx, STM32F105xx, and STM32F107xx */ -#include "config-stm32f10x.h" #elif defined(CHIP_VARIANT_STM32F09X) /* STM32F09xx */ #include "config-stm32f09x.h" diff --git a/chip/stm32/flash-stm32f.c b/chip/stm32/flash-stm32f.c deleted file mode 100644 index 299d40d5c1..0000000000 --- a/chip/stm32/flash-stm32f.c +++ /dev/null @@ -1,130 +0,0 @@ -/* Copyright 2014 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* Flash memory module for Chrome EC */ - -#include "common.h" -#include "flash.h" -#include "hooks.h" -#include "registers.h" -#include "system.h" -#include "panic.h" - -/* Flag indicating whether we have locked down entire flash */ -static int entire_flash_locked; - -#define FLASH_SYSJUMP_TAG 0x5750 /* "WP" - Write Protect */ -#define FLASH_HOOK_VERSION 1 -/* The previous write protect state before sys jump */ -/* - * TODO(crosbug.com/p/23798): check if STM32L code works here too - that is, - * check if entire flash is locked by attempting to lock it rather than keeping - * a global variable. - */ -struct flash_wp_state { - int entire_flash_locked; -}; - -/*****************************************************************************/ -/* Physical layer APIs */ - -int flash_physical_get_protect(int block) -{ - return entire_flash_locked || !(STM32_FLASH_WRPR & (1 << block)); -} - -uint32_t flash_physical_get_protect_flags(void) -{ - uint32_t flags = 0; - - /* Read all-protected state from our shadow copy */ - if (entire_flash_locked) - flags |= EC_FLASH_PROTECT_ALL_NOW; - - return flags; -} - -int flash_physical_protect_now(int all) -{ - if (all) { - /* - * Lock by writing a wrong key to FLASH_KEYR. This triggers a - * bus fault, so we need to disable bus fault handler while - * doing this. - */ - ignore_bus_fault(1); - STM32_FLASH_KEYR = 0xffffffff; - ignore_bus_fault(0); - - entire_flash_locked = 1; - - return EC_SUCCESS; - } else { - /* No way to protect just the RO flash until next boot */ - return EC_ERROR_INVAL; - } -} - -uint32_t flash_physical_get_valid_flags(void) -{ - return EC_FLASH_PROTECT_RO_AT_BOOT | - EC_FLASH_PROTECT_RO_NOW | - EC_FLASH_PROTECT_ALL_NOW; -} - -uint32_t flash_physical_get_writable_flags(uint32_t cur_flags) -{ - uint32_t ret = 0; - - /* If RO protection isn't enabled, its at-boot state can be changed. */ - if (!(cur_flags & EC_FLASH_PROTECT_RO_NOW)) - ret |= EC_FLASH_PROTECT_RO_AT_BOOT; - - /* - * If entire flash isn't protected at this boot, it can be enabled if - * the WP GPIO is asserted. - */ - if (!(cur_flags & EC_FLASH_PROTECT_ALL_NOW) && - (cur_flags & EC_FLASH_PROTECT_GPIO_ASSERTED)) - ret |= EC_FLASH_PROTECT_ALL_NOW; - - return ret; -} - -int flash_physical_restore_state(void) -{ - uint32_t reset_flags = system_get_reset_flags(); - int version, size; - const struct flash_wp_state *prev; - - /* - * If we have already jumped between images, an earlier image could - * have applied write protection. Nothing additional needs to be done. - */ - if (reset_flags & RESET_FLAG_SYSJUMP) { - prev = (const struct flash_wp_state *)system_get_jump_tag( - FLASH_SYSJUMP_TAG, &version, &size); - if (prev && version == FLASH_HOOK_VERSION && - size == sizeof(*prev)) - entire_flash_locked = prev->entire_flash_locked; - return 1; - } - - return 0; -} - -/*****************************************************************************/ -/* Hooks */ - -static void flash_preserve_state(void) -{ - struct flash_wp_state state; - - state.entire_flash_locked = entire_flash_locked; - - system_add_jump_tag(FLASH_SYSJUMP_TAG, FLASH_HOOK_VERSION, - sizeof(state), &state); -} -DECLARE_HOOK(HOOK_SYSJUMP, flash_preserve_state, HOOK_PRIO_DEFAULT); diff --git a/chip/stm32/flash-stm32f3.c b/chip/stm32/flash-stm32f3.c index 13dc8d8e47..299d40d5c1 120000..100644 --- a/chip/stm32/flash-stm32f3.c +++ b/chip/stm32/flash-stm32f3.c @@ -1 +1,130 @@ -flash-stm32f.c
\ No newline at end of file +/* Copyright 2014 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Flash memory module for Chrome EC */ + +#include "common.h" +#include "flash.h" +#include "hooks.h" +#include "registers.h" +#include "system.h" +#include "panic.h" + +/* Flag indicating whether we have locked down entire flash */ +static int entire_flash_locked; + +#define FLASH_SYSJUMP_TAG 0x5750 /* "WP" - Write Protect */ +#define FLASH_HOOK_VERSION 1 +/* The previous write protect state before sys jump */ +/* + * TODO(crosbug.com/p/23798): check if STM32L code works here too - that is, + * check if entire flash is locked by attempting to lock it rather than keeping + * a global variable. + */ +struct flash_wp_state { + int entire_flash_locked; +}; + +/*****************************************************************************/ +/* Physical layer APIs */ + +int flash_physical_get_protect(int block) +{ + return entire_flash_locked || !(STM32_FLASH_WRPR & (1 << block)); +} + +uint32_t flash_physical_get_protect_flags(void) +{ + uint32_t flags = 0; + + /* Read all-protected state from our shadow copy */ + if (entire_flash_locked) + flags |= EC_FLASH_PROTECT_ALL_NOW; + + return flags; +} + +int flash_physical_protect_now(int all) +{ + if (all) { + /* + * Lock by writing a wrong key to FLASH_KEYR. This triggers a + * bus fault, so we need to disable bus fault handler while + * doing this. + */ + ignore_bus_fault(1); + STM32_FLASH_KEYR = 0xffffffff; + ignore_bus_fault(0); + + entire_flash_locked = 1; + + return EC_SUCCESS; + } else { + /* No way to protect just the RO flash until next boot */ + return EC_ERROR_INVAL; + } +} + +uint32_t flash_physical_get_valid_flags(void) +{ + return EC_FLASH_PROTECT_RO_AT_BOOT | + EC_FLASH_PROTECT_RO_NOW | + EC_FLASH_PROTECT_ALL_NOW; +} + +uint32_t flash_physical_get_writable_flags(uint32_t cur_flags) +{ + uint32_t ret = 0; + + /* If RO protection isn't enabled, its at-boot state can be changed. */ + if (!(cur_flags & EC_FLASH_PROTECT_RO_NOW)) + ret |= EC_FLASH_PROTECT_RO_AT_BOOT; + + /* + * If entire flash isn't protected at this boot, it can be enabled if + * the WP GPIO is asserted. + */ + if (!(cur_flags & EC_FLASH_PROTECT_ALL_NOW) && + (cur_flags & EC_FLASH_PROTECT_GPIO_ASSERTED)) + ret |= EC_FLASH_PROTECT_ALL_NOW; + + return ret; +} + +int flash_physical_restore_state(void) +{ + uint32_t reset_flags = system_get_reset_flags(); + int version, size; + const struct flash_wp_state *prev; + + /* + * If we have already jumped between images, an earlier image could + * have applied write protection. Nothing additional needs to be done. + */ + if (reset_flags & RESET_FLAG_SYSJUMP) { + prev = (const struct flash_wp_state *)system_get_jump_tag( + FLASH_SYSJUMP_TAG, &version, &size); + if (prev && version == FLASH_HOOK_VERSION && + size == sizeof(*prev)) + entire_flash_locked = prev->entire_flash_locked; + return 1; + } + + return 0; +} + +/*****************************************************************************/ +/* Hooks */ + +static void flash_preserve_state(void) +{ + struct flash_wp_state state; + + state.entire_flash_locked = entire_flash_locked; + + system_add_jump_tag(FLASH_SYSJUMP_TAG, FLASH_HOOK_VERSION, + sizeof(state), &state); +} +DECLARE_HOOK(HOOK_SYSJUMP, flash_preserve_state, HOOK_PRIO_DEFAULT); diff --git a/chip/stm32/gpio-stm32f.c b/chip/stm32/gpio-stm32f.c deleted file mode 100644 index 9a381edfee..0000000000 --- a/chip/stm32/gpio-stm32f.c +++ /dev/null @@ -1,149 +0,0 @@ -/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* GPIO module for Chrome EC */ - -#include "clock.h" -#include "common.h" -#include "gpio.h" -#include "hooks.h" -#include "registers.h" -#include "task.h" -#include "util.h" - -/** - * Helper function for generating bitmasks for STM32 GPIO config registers - */ -static void gpio_config_info(uint32_t port, uint32_t mask, uint32_t *addr, - uint32_t *mode, uint32_t *cnf) { - /* - * 2-bit config followed by 2-bit mode for each pin, each - * successive pin raises the exponent for the lowest bit - * set by an order of 4, e.g. 2^0, 2^4, 2^8, etc. - */ - if (mask & 0xff) { - *addr = port; /* GPIOx_CRL */ - *mode = mask; - } else { - *addr = port + 0x04; /* GPIOx_CRH */ - *mode = mask >> 8; - } - *mode = *mode * *mode * *mode * *mode; - *mode |= *mode << 1; - *cnf = *mode << 2; -} - -void gpio_set_flags_by_mask(uint32_t port, uint32_t pmask, uint32_t flags) -{ - uint32_t addr, cnf, mode, mask; - - gpio_config_info(port, pmask, &addr, &mode, &cnf); - mask = REG32(addr) & ~(cnf | mode); - - /* - * For STM32, the port configuration field changes meaning - * depending on whether the port is an input, analog input, - * output, or alternate function. - */ - if (flags & GPIO_OUTPUT) { - /* - * This sets output max speed to 10MHz. That should be - * sufficient for most GPIO needs; the only thing that needs to - * go faster is SPI, which overrides the port speed on its own. - */ - mask |= 0x11111111 & mode; - if (flags & GPIO_OPEN_DRAIN) - mask |= 0x44444444 & cnf; - - } else { - /* - * GPIOx_ODR determines which resistor to activate in - * input mode, see Table 16 (datasheet rm0041) - */ - if (flags & GPIO_ANALOG) { - /* Analog input, MODE=00 CNF=00 */ - /* the 4 bits in mask are already reset above */ - } else if (flags & GPIO_PULL_UP) { - mask |= 0x88888888 & cnf; - STM32_GPIO_BSRR(port) = pmask; - } else if (flags & GPIO_PULL_DOWN) { - mask |= 0x88888888 & cnf; - STM32_GPIO_BSRR(port) = pmask << 16; - } else { - mask |= 0x44444444 & cnf; - } - } - - REG32(addr) = mask; - - if (flags & GPIO_OUTPUT) { - /* - * Set pin level after port has been set up as to avoid - * potential damage, e.g. driving an open-drain output high - * before it has been configured as such. - */ - if (flags & GPIO_HIGH) - STM32_GPIO_BSRR(port) = pmask; - else if (flags & GPIO_LOW) - STM32_GPIO_BSRR(port) = pmask << 16; - } - - /* Set up interrupts if necessary */ - ASSERT(!(flags & (GPIO_INT_F_LOW | GPIO_INT_F_HIGH))); - if (flags & GPIO_INT_F_RISING) - STM32_EXTI_RTSR |= pmask; - if (flags & GPIO_INT_F_FALLING) - STM32_EXTI_FTSR |= pmask; - /* Interrupt is enabled by gpio_enable_interrupt() */ -} - -int gpio_is_reboot_warm(void) -{ - return (STM32_RCC_APB1ENR & 1); -} - -void gpio_enable_clocks(void) -{ - /* - * Enable all GPIOs clocks - * - * TODO(crosbug.com/p/23770): only enable the banks we need to, - * and support disabling some of them in low-power idle. - */ -#ifdef CHIP_VARIANT_STM32TS60 - STM32_RCC_APB2ENR |= 0x7fd; -#else - STM32_RCC_APB2ENR |= 0x1fd; -#endif - - /* Delay 1 APB clock cycle after the clock is enabled */ - clock_wait_bus_cycles(BUS_APB, 1); -} - -void gpio_set_alternate_function(uint32_t port, uint32_t mask, int func) -{ - /* TODO(crosbug.com/p/21618): implement me! */ -} - -static void gpio_init(void) -{ - /* Enable IRQs now that pins are set up */ - task_enable_irq(STM32_IRQ_EXTI0); - task_enable_irq(STM32_IRQ_EXTI1); - task_enable_irq(STM32_IRQ_EXTI2); - task_enable_irq(STM32_IRQ_EXTI3); - task_enable_irq(STM32_IRQ_EXTI4); - task_enable_irq(STM32_IRQ_EXTI9_5); - task_enable_irq(STM32_IRQ_EXTI15_10); -} -DECLARE_HOOK(HOOK_INIT, gpio_init, HOOK_PRIO_DEFAULT); - -DECLARE_IRQ(STM32_IRQ_EXTI0, gpio_interrupt, 1); -DECLARE_IRQ(STM32_IRQ_EXTI1, gpio_interrupt, 1); -DECLARE_IRQ(STM32_IRQ_EXTI2, gpio_interrupt, 1); -DECLARE_IRQ(STM32_IRQ_EXTI3, gpio_interrupt, 1); -DECLARE_IRQ(STM32_IRQ_EXTI4, gpio_interrupt, 1); -DECLARE_IRQ(STM32_IRQ_EXTI9_5, gpio_interrupt, 1); -DECLARE_IRQ(STM32_IRQ_EXTI15_10, gpio_interrupt, 1); diff --git a/chip/stm32/gpio.c b/chip/stm32/gpio.c index 683303688f..8e8e25085d 100644 --- a/chip/stm32/gpio.c +++ b/chip/stm32/gpio.c @@ -96,17 +96,8 @@ int gpio_enable_interrupt(enum gpio_signal signal) shift = (bit % 4) * 4; bank = (g->port - STM32_GPIOA_BASE) / 0x400; -#if defined(CHIP_FAMILY_STM32F) - STM32_AFIO_EXTICR(group) = (STM32_AFIO_EXTICR(group) & - ~(0xF << shift)) | (bank << shift); -#elif defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32L) || \ - defined(CHIP_FAMILY_STM32F3) STM32_SYSCFG_EXTICR(group) = (STM32_SYSCFG_EXTICR(group) & - ~(0xF << shift)) | (bank << shift); -#else -#error "Unsupported chip family" -#endif - + ~(0xF << shift)) | (bank << shift); STM32_EXTI_IMR |= g->mask; return EC_SUCCESS; diff --git a/chip/stm32/hwtimer.c b/chip/stm32/hwtimer.c index 2658cf5734..27f363f731 100644 --- a/chip/stm32/hwtimer.c +++ b/chip/stm32/hwtimer.c @@ -238,7 +238,7 @@ void __hw_timer_enable_clock(int n, int enable) * Mapping of timers to reg/mask is split into a few different ranges, * some specific to individual chips. */ -#if defined(CHIP_FAMILY_STM32F) || defined(CHIP_FAMILY_STM32F0) +#if defined(CHIP_FAMILY_STM32F0) if (n == 1) { reg = &STM32_RCC_APB2ENR; mask = STM32_RCC_PB2_TIM1; diff --git a/chip/stm32/hwtimer32.c b/chip/stm32/hwtimer32.c index ef6e9321c4..1b47015bdb 100644 --- a/chip/stm32/hwtimer32.c +++ b/chip/stm32/hwtimer32.c @@ -72,7 +72,7 @@ void __hw_timer_enable_clock(int n, int enable) * Mapping of timers to reg/mask is split into a few different ranges, * some specific to individual chips. */ -#if defined(CHIP_FAMILY_STM32F) || defined(CHIP_FAMILY_STM32F0) +#if defined(CHIP_FAMILY_STM32F0) if (n == 1) { reg = &STM32_RCC_APB2ENR; mask = STM32_RCC_PB2_TIM1; diff --git a/chip/stm32/i2c-stm32f.c b/chip/stm32/i2c-stm32f.c deleted file mode 100644 index 1fab9c3b7c..0000000000 --- a/chip/stm32/i2c-stm32f.c +++ /dev/null @@ -1,769 +0,0 @@ -/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "chipset.h" -#include "clock.h" -#include "common.h" -#include "console.h" -#include "dma.h" -#include "gpio.h" -#include "hooks.h" -#include "host_command.h" -#include "i2c.h" -#include "i2c_arbitration.h" -#include "registers.h" -#include "task.h" -#include "timer.h" -#include "util.h" - -/* Console output macros */ -#define CPUTS(outstr) cputs(CC_I2C, outstr) -#define CPRINTF(format, args...) cprintf(CC_I2C, format, ## args) -#define CPRINTS(format, args...) cprints(CC_I2C, format, ## args) - -/* 8-bit I2C slave address */ -#define I2C_ADDRESS 0x3c - -/* I2C bus frequency */ -#define I2C_FREQ 100000 /* Hz */ - -/* I2C bit period in microseconds */ -#define I2C_PERIOD_US (SECOND / I2C_FREQ) - -/* Clock divider for I2C controller */ -#define I2C_CCR (CPU_CLOCK / (2 * I2C_FREQ)) - -/* - * Transmit timeout in microseconds - * - * In theory we shouldn't have a timeout here (at least when we're in slave - * mode). The slave is supposed to wait forever for the master to read bytes. - * ...but we're going to keep the timeout to make sure we're robust. It may in - * fact be needed if the host resets itself mid-read. - * - * NOTE: One case where this timeout is useful is when the battery - * flips out. The battery may flip out and hold lines low for up to - * 25ms. If we just wait it will eventually let them go. - */ -#define I2C_TX_TIMEOUT_SLAVE (100 * MSEC) -#define I2C_TX_TIMEOUT_MASTER (30 * MSEC) - -/* - * We delay 5us in bitbang mode. That gives us 5us low and 5us high or - * a frequency of 100kHz. - * - * Note that the code takes a little time to run so we don't actually get - * 100kHz, but that's OK. - */ -#define I2C_BITBANG_DELAY_US 5 - -#define I2C1 STM32_I2C1_PORT -#define I2C2 STM32_I2C2_PORT - -/* Select the DMA channels matching the board configuration */ -#define DMAC_SLAVE_TX \ - ((I2C_PORT_SLAVE) ? STM32_DMAC_I2C2_TX : STM32_DMAC_I2C1_TX) -#define DMAC_SLAVE_RX \ - ((I2C_PORT_SLAVE) ? STM32_DMAC_I2C2_RX : STM32_DMAC_I2C1_RX) -#define DMAC_MASTER_TX \ - ((I2C_PORT_MASTER) ? STM32_DMAC_I2C2_TX : STM32_DMAC_I2C1_TX) -#define DMAC_MASTER_RX \ - ((I2C_PORT_MASTER) ? STM32_DMAC_I2C2_RX : STM32_DMAC_I2C1_RX) - -enum { - /* - * A stop condition should take 2 clocks, but the process may need more - * time to notice if it is preempted, so we poll repeatedly for 8 - * clocks, before backing off and only check once every - * STOP_SENT_RETRY_US for up to TIMEOUT_STOP_SENT clocks before giving - * up. - */ - SLOW_STOP_SENT_US = I2C_PERIOD_US * 8, - TIMEOUT_STOP_SENT_US = I2C_PERIOD_US * 200, - STOP_SENT_RETRY_US = 150, -}; - -static const struct dma_option dma_tx_option[I2C_PORT_COUNT] = { - {STM32_DMAC_I2C1_TX, (void *)&STM32_I2C_DR(I2C1), - STM32_DMA_CCR_MSIZE_8_BIT | STM32_DMA_CCR_PSIZE_16_BIT}, - {STM32_DMAC_I2C2_TX, (void *)&STM32_I2C_DR(I2C2), - STM32_DMA_CCR_MSIZE_8_BIT | STM32_DMA_CCR_PSIZE_16_BIT}, -}; - -static const struct dma_option dma_rx_option[I2C_PORT_COUNT] = { - {STM32_DMAC_I2C1_RX, (void *)&STM32_I2C_DR(I2C1), - STM32_DMA_CCR_MSIZE_8_BIT | STM32_DMA_CCR_PSIZE_16_BIT}, - {STM32_DMAC_I2C2_RX, (void *)&STM32_I2C_DR(I2C2), - STM32_DMA_CCR_MSIZE_8_BIT | STM32_DMA_CCR_PSIZE_16_BIT}, -}; - -static uint16_t i2c_sr1[I2C_PORT_COUNT]; - -/* Buffer for host commands (including version, error code and checksum) */ -static uint8_t host_buffer[EC_PROTO2_MAX_REQUEST_SIZE]; -static struct host_cmd_handler_args host_cmd_args; -static uint8_t i2c_old_response; /* Send an old-style response */ - -/* Flag indicating if a command is currently in the buffer */ -static uint8_t rx_pending; - -static inline void disable_i2c_interrupt(int port) -{ - STM32_I2C_CR2(port) &= ~(3 << 8); -} - -static inline void enable_i2c_interrupt(int port) -{ - STM32_I2C_CR2(port) |= 3 << 8; -} - -static inline void enable_ack(int port) -{ - STM32_I2C_CR1(port) |= (1 << 10); -} - -static inline void disable_ack(int port) -{ - STM32_I2C_CR1(port) &= ~(1 << 10); -} - -static void i2c_init_port(unsigned int port); - -static int i2c_write_raw_slave(int port, void *buf, int len) -{ - stm32_dma_chan_t *chan; - int rv; - - /* we don't want to race with TxE interrupt event */ - disable_i2c_interrupt(port); - - /* Configuring DMA1 channel DMAC_SLAVE_TX */ - enable_ack(port); - chan = dma_get_channel(DMAC_SLAVE_TX); - dma_prepare_tx(dma_tx_option + port, len, buf); - - /* Start the DMA */ - dma_go(chan); - - /* Configuring i2c to use DMA */ - STM32_I2C_CR2(port) |= (1 << 11); - - if (in_interrupt_context()) { - /* Poll for the transmission complete flag */ - dma_wait(DMAC_SLAVE_TX); - dma_clear_isr(DMAC_SLAVE_TX); - } else { - /* Wait for the transmission complete Interrupt */ - dma_enable_tc_interrupt(DMAC_SLAVE_TX); - rv = task_wait_event(DMA_TRANSFER_TIMEOUT_US); - dma_disable_tc_interrupt(DMAC_SLAVE_TX); - - if (!(rv & TASK_EVENT_WAKE)) { - CPRINTS("Slave timeout, resetting i2c"); - i2c_init_port(port); - } - } - - dma_disable(DMAC_SLAVE_TX); - STM32_I2C_CR2(port) &= ~(1 << 11); - - enable_i2c_interrupt(port); - - return len; -} - -static void i2c_send_response(struct host_cmd_handler_args *args) -{ - const uint8_t *data = args->response; - int size = args->response_size; - uint8_t *out = host_buffer; - int sum = 0, i; - - *out++ = args->result; - if (!i2c_old_response) { - *out++ = size; - sum = args->result + size; - } - for (i = 0; i < size; i++, data++, out++) { - if (data != out) - *out = *data; - sum += *data; - } - *out++ = sum & 0xff; - - /* send the answer to the AP */ - i2c_write_raw_slave(I2C2, host_buffer, out - host_buffer); -} - -/* Process the command in the i2c host buffer */ -static void i2c_process_command(void) -{ - struct host_cmd_handler_args *args = &host_cmd_args; - char *buff = host_buffer; - - args->command = *buff; - args->result = EC_RES_SUCCESS; - if (args->command >= EC_CMD_VERSION0) { - int csum, i; - - /* Read version and data size */ - args->version = args->command - EC_CMD_VERSION0; - args->command = buff[1]; - args->params_size = buff[2]; - - /* Verify checksum */ - for (csum = i = 0; i < args->params_size + 3; i++) - csum += buff[i]; - if ((uint8_t)csum != buff[i]) - args->result = EC_RES_INVALID_CHECKSUM; - - buff += 3; - i2c_old_response = 0; - } else { - /* - * Old style (version 1) command. - * - * TODO(crosbug.com/p/23765): Nothing sends these anymore, - * since this was superseded by version 2 before snow launched. - * This code should be safe to remove. - */ - args->version = 0; - args->params_size = EC_PROTO2_MAX_PARAM_SIZE; /* unknown */ - buff++; - i2c_old_response = 1; - } - - /* we have an available command : execute it */ - args->send_response = i2c_send_response; - args->params = buff; - /* skip room for error code, arglen */ - args->response = host_buffer + 2; - args->response_max = EC_PROTO2_MAX_PARAM_SIZE; - args->response_size = 0; - - host_command_received(args); -} - -static void i2c_event_handler(int port) -{ - /* save and clear status */ - i2c_sr1[port] = STM32_I2C_SR1(port); - STM32_I2C_SR1(port) = 0; - - /* Confirm that you are not in master mode */ - if (STM32_I2C_SR2(port) & (1 << 0)) { - CPRINTS("slave ISR triggered in master mode, ignoring"); - return; - } - - /* transfer matched our slave address */ - if (i2c_sr1[port] & (1 << 1)) { - /* If it's a receiver slave */ - if (!(STM32_I2C_SR2(port) & (1 << 2))) { - dma_start_rx(dma_rx_option + port, sizeof(host_buffer), - host_buffer); - - STM32_I2C_CR2(port) |= (1 << 11); - rx_pending = 1; - } - - /* cleared by reading SR1 followed by reading SR2 */ - STM32_I2C_SR1(port); - STM32_I2C_SR2(port); - } else if (i2c_sr1[port] & (1 << 4)) { - /* If it's a receiver slave */ - if (!(STM32_I2C_SR2(port) & (1 << 2))) { - /* Disable, and clear the DMA transfer complete flag */ - dma_disable(DMAC_SLAVE_RX); - dma_clear_isr(DMAC_SLAVE_RX); - - /* Turn off i2c's DMA flag */ - STM32_I2C_CR2(port) &= ~(1 << 11); - } - /* clear STOPF bit by reading SR1 and then writing CR1 */ - STM32_I2C_SR1(port); - STM32_I2C_CR1(port) = STM32_I2C_CR1(port); - } - - /* TxE event */ - if (i2c_sr1[port] & (1 << 7)) { - if (port == I2C2) { /* AP is waiting for EC response */ - if (rx_pending) { - i2c_process_command(); - /* reset host buffer after end of transfer */ - rx_pending = 0; - } else { - /* spurious read : return dummy value */ - STM32_I2C_DR(port) = 0xec; - } - } - } -} -void i2c2_event_interrupt(void) { i2c_event_handler(I2C2); } -DECLARE_IRQ(STM32_IRQ_I2C2_EV, i2c2_event_interrupt, 3); - -static void i2c_error_handler(int port) -{ - i2c_sr1[port] = STM32_I2C_SR1(port); - - if (i2c_sr1[port] & 1 << 10) { - /* ACK failed (NACK); expected when AP reads final byte. - * Software must clear AF bit. */ - } else { - CPRINTS("%s: I2C_SR1(%d): 0x%04x", - __func__, port, i2c_sr1[port]); - CPRINTS("%s: I2C_SR2(%d): 0x%04x", - __func__, port, STM32_I2C_SR2(port)); - } - - STM32_I2C_SR1(port) &= ~0xdf00; -} -void i2c2_error_interrupt(void) { i2c_error_handler(I2C2); } -DECLARE_IRQ(STM32_IRQ_I2C2_ER, i2c2_error_interrupt, 2); - -/* board-specific setup for post-I2C module init */ -void __board_i2c_post_init(int port) -{ -} - -void board_i2c_post_init(int port) - __attribute__((weak, alias("__board_i2c_post_init"))); - -static void i2c_init_port(unsigned int port) -{ - const int i2c_clock_bit[] = {21, 22}; - - if (!(STM32_RCC_APB1ENR & (1 << i2c_clock_bit[port]))) { - /* Only unwedge the bus if the clock is off */ - if (i2c_claim(port) == EC_SUCCESS) { - i2c_release(port); - } - - /* enable I2C2 clock */ - STM32_RCC_APB1ENR |= 1 << i2c_clock_bit[port]; - - /* Delay 1 APB clock cycle after the clock is enabled */ - clock_wait_bus_cycles(BUS_APB, 1); - } - - /* force reset of the i2c peripheral */ - STM32_I2C_CR1(port) = 0x8000; - STM32_I2C_CR1(port) = 0x0000; - - /* set clock configuration : standard mode (100kHz) */ - STM32_I2C_CCR(port) = I2C_CCR; - - /* set slave address */ - if (port == I2C2) - STM32_I2C_OAR1(port) = I2C_ADDRESS; - - /* configuration : I2C mode / Periphal enabled, ACK enabled */ - STM32_I2C_CR1(port) = (1 << 10) | (1 << 0); - /* error and event interrupts enabled / input clock is 16Mhz */ - STM32_I2C_CR2(port) = (1 << 9) | (1 << 8) | 0x10; - - /* clear status */ - STM32_I2C_SR1(port) = 0; - - board_i2c_post_init(port); -} - -static void i2c_init(void) -{ - /* - * TODO(crosbug.com/p/23763): Add config options to determine which - * channels to init. - */ - i2c_init_port(I2C1); - i2c_init_port(I2C2); - - /* Enable event and error interrupts */ - task_enable_irq(STM32_IRQ_I2C2_EV); - task_enable_irq(STM32_IRQ_I2C2_ER); -} -DECLARE_HOOK(HOOK_INIT, i2c_init, HOOK_PRIO_INIT_I2C); - -/*****************************************************************************/ -/* STM32 Host I2C */ - -#define SR1_SB (1 << 0) /* Start bit sent */ -#define SR1_ADDR (1 << 1) /* Address sent */ -#define SR1_BTF (1 << 2) /* Byte transfered */ -#define SR1_ADD10 (1 << 3) /* 10bit address sent */ -#define SR1_STOPF (1 << 4) /* Stop detected */ -#define SR1_RxNE (1 << 6) /* Data reg not empty */ -#define SR1_TxE (1 << 7) /* Data reg empty */ -#define SR1_BERR (1 << 8) /* Buss error */ -#define SR1_ARLO (1 << 9) /* Arbitration lost */ -#define SR1_AF (1 << 10) /* Ack failure */ -#define SR1_OVR (1 << 11) /* Overrun/underrun */ -#define SR1_PECERR (1 << 12) /* PEC err in reception */ -#define SR1_TIMEOUT (1 << 14) /* Timeout : 25ms */ -#define CR2_DMAEN (1 << 11) /* DMA enable */ -#define CR2_LAST (1 << 12) /* Next EOT is last EOT */ - -static inline void dump_i2c_reg(int port) -{ -#ifdef CONFIG_I2C_DEBUG - CPRINTF("CR1 : %016b\n", STM32_I2C_CR1(port)); - CPRINTF("CR2 : %016b\n", STM32_I2C_CR2(port)); - CPRINTF("SR2 : %016b\n", STM32_I2C_SR2(port)); - CPRINTF("SR1 : %016b\n", STM32_I2C_SR1(port)); - CPRINTF("OAR1 : %016b\n", STM32_I2C_OAR1(port)); - CPRINTF("OAR2 : %016b\n", STM32_I2C_OAR2(port)); - CPRINTF("DR : %016b\n", STM32_I2C_DR(port)); - CPRINTF("CCR : %016b\n", STM32_I2C_CCR(port)); - CPRINTF("TRISE: %016b\n", STM32_I2C_TRISE(port)); -#endif /* CONFIG_I2C_DEBUG */ -} - -enum wait_t { - WAIT_NONE, - WAIT_MASTER_START, - WAIT_ADDR_READY, - WAIT_XMIT_TXE, - WAIT_XMIT_FINAL_TXE, - WAIT_XMIT_BTF, - WAIT_XMIT_STOP, - WAIT_RX_NE, - WAIT_RX_NE_FINAL, - WAIT_RX_NE_STOP, - WAIT_RX_NE_STOP_SIZE2, -}; - -/** - * Wait for a specific i2c event - * - * This function waits until the bit(s) corresponding to mask in - * the specified port's I2C SR1 register is/are set. It may - * return a timeout or success. - * - * @param port Port to wait on - * @param mask A mask specifying which bits in SR1 to wait to be set - * @param wait A wait code to be returned with the timeout error code if that - * occurs, to help with debugging. - * @return EC_SUCCESS, or EC_ERROR_TIMEOUT with the wait code OR'd onto the - * bits 8-16 to indicate what it timed out waiting for. - */ -static int wait_status(int port, uint32_t mask, enum wait_t wait) -{ - uint32_t r; - timestamp_t t1, t2; - - t1 = t2 = get_time(); - r = STM32_I2C_SR1(port); - while (mask ? ((r & mask) != mask) : r) { - t2 = get_time(); - - if (t2.val - t1.val > I2C_TX_TIMEOUT_MASTER) - return EC_ERROR_TIMEOUT | (wait << 8); - else if (t2.val - t1.val > 150) - usleep(100); - - r = STM32_I2C_SR1(port); - } - - return EC_SUCCESS; -} - -static inline uint32_t read_clear_status(int port) -{ - uint32_t sr1, sr2; - - sr1 = STM32_I2C_SR1(port); - sr2 = STM32_I2C_SR2(port); - return (sr2 << 16) | (sr1 & 0xffff); -} - -static int master_start(int port, int slave_addr) -{ - int rv; - - /* Change to master send mode, reset stop bit, send start bit */ - STM32_I2C_CR1(port) = (STM32_I2C_CR1(port) & ~(1 << 9)) | (1 << 8); - /* Wait for start bit sent event */ - rv = wait_status(port, SR1_SB, WAIT_MASTER_START); - if (rv) - return rv; - - /* Send address */ - STM32_I2C_DR(port) = slave_addr; - /* Wait for addr ready */ - rv = wait_status(port, SR1_ADDR, WAIT_ADDR_READY); - if (rv) - return rv; - - read_clear_status(port); - - return EC_SUCCESS; -} - -static void master_stop(int port) -{ - STM32_I2C_CR1(port) |= (1 << 9); -} - -static int wait_until_stop_sent(int port) -{ - timestamp_t deadline; - timestamp_t slow_cutoff; - uint8_t is_slow; - - deadline = slow_cutoff = get_time(); - deadline.val += TIMEOUT_STOP_SENT_US; - slow_cutoff.val += SLOW_STOP_SENT_US; - - while (STM32_I2C_CR1(port) & (1 << 9)) { - if (timestamp_expired(deadline, NULL)) { - ccprintf("Stop event deadline passed:\ttask=%d" - "\tCR1=%016b\n", - (int)task_get_current(), STM32_I2C_CR1(port)); - return EC_ERROR_TIMEOUT; - } - - if (is_slow) { - /* If we haven't gotten a fast response, sleep */ - usleep(STOP_SENT_RETRY_US); - } else { - /* Check to see if this request is taking a while */ - if (timestamp_expired(slow_cutoff, NULL)) { - ccprintf("Stop event taking a while: task=%d", - (int)task_get_current()); - is_slow = 1; - } - } - } - - return EC_SUCCESS; -} - -static void handle_i2c_error(int port, int rv) -{ - timestamp_t t1, t2; - uint32_t r; - - /* We have not used the bus, just exit */ - if (rv == EC_ERROR_BUSY) - return; - - /* EC_ERROR_TIMEOUT may have a code specifying where the timeout was */ - if ((rv & 0xff) == EC_ERROR_TIMEOUT) { -#ifdef CONFIG_I2C_DEBUG - CPRINTS("Wait_status() timeout type: %d", (rv >> 8)); -#endif - rv = EC_ERROR_TIMEOUT; - } - if (rv) - dump_i2c_reg(port); - - /* Clear rc_w0 bits */ - STM32_I2C_SR1(port) = 0; - /* Clear seq read status bits */ - r = STM32_I2C_SR1(port); - r = STM32_I2C_SR2(port); - /* Clear busy state */ - t1 = get_time(); - - if (rv == EC_ERROR_TIMEOUT && (STM32_I2C_CR1(port) & (1 << 8))) { - /* - * If it failed while just trying to send the start bit then - * something is wrong with the internal state of the i2c, - * (Probably a stray pulse on the line got it out of sync with - * the actual bytes) so reset it. - */ - CPRINTS("Unable to send START, resetting i2c"); - i2c_init_port(port); - goto cr_cleanup; - } else if (rv == EC_ERROR_TIMEOUT && !(r & 2)) { - /* - * If the BUSY bit is faulty, send a stop bit just to be sure. - * It seems that this can be happen very briefly while sending - * a 1. We've not actually seen this, but just to be safe. - */ - CPRINTS("Bad BUSY bit detected"); - master_stop(port); - } - - /* Try to send stop bits until the bus becomes idle */ - while (r & 2) { - t2 = get_time(); - if (t2.val - t1.val > I2C_TX_TIMEOUT_MASTER) { - dump_i2c_reg(port); - /* Reset the i2c periph to get it back to slave mode */ - i2c_init_port(port); - goto cr_cleanup; - } - /* Send stop */ - master_stop(port); - usleep(1000); - r = STM32_I2C_SR2(port); - } - -cr_cleanup: - /* - * Reset control register to the default state : - * I2C mode / Periphal enabled, ACK enabled - */ - STM32_I2C_CR1(port) = (1 << 10) | (1 << 0); -} - -static int i2c_master_transmit(int port, int slave_addr, const uint8_t *data, - int size, int stop) -{ - int rv, rv_start; - - disable_ack(port); - - /* Configure DMA channel for TX to host */ - dma_prepare_tx(dma_tx_option + port, size, data); - dma_enable_tc_interrupt(DMAC_MASTER_TX); - - /* Start the DMA */ - dma_go(dma_get_channel(DMAC_MASTER_TX)); - - /* Configuring i2c2 to use DMA */ - STM32_I2C_CR2(port) |= CR2_DMAEN; - - /* Initialise i2c communication by sending START and ADDR */ - rv_start = master_start(port, slave_addr); - - /* If it started, wait for the transmission complete Interrupt */ - if (!rv_start) - rv = task_wait_event(DMA_TRANSFER_TIMEOUT_US); - - dma_disable(DMAC_MASTER_TX); - dma_disable_tc_interrupt(DMAC_MASTER_TX); - STM32_I2C_CR2(port) &= ~CR2_DMAEN; - - if (rv_start) - return rv_start; - if (!(rv & TASK_EVENT_WAKE)) - return EC_ERROR_TIMEOUT; - - rv = wait_status(port, SR1_BTF, WAIT_XMIT_BTF); - if (rv) - return rv; - - if (stop) { - master_stop(port); - return wait_status(port, 0, WAIT_XMIT_STOP); - } - - return EC_SUCCESS; -} - -static int i2c_master_receive(int port, int slave_addr, uint8_t *data, - int size) -{ - int rv, rv_start; - - if (data == NULL || size < 1) - return EC_ERROR_INVAL; - - /* Master receive only supports DMA for payloads > 1 byte */ - if (size > 1) { - enable_ack(port); - dma_start_rx(dma_rx_option + port, size, data); - - dma_enable_tc_interrupt(DMAC_MASTER_RX); - - STM32_I2C_CR2(port) |= CR2_DMAEN; - STM32_I2C_CR2(port) |= CR2_LAST; - - rv_start = master_start(port, slave_addr | 1); - if (!rv_start) - rv = task_wait_event(DMA_TRANSFER_TIMEOUT_US); - - dma_disable(DMAC_MASTER_RX); - dma_disable_tc_interrupt(DMAC_MASTER_RX); - STM32_I2C_CR2(port) &= ~CR2_DMAEN; - disable_ack(port); - - if (rv_start) - return rv_start; - if (!(rv & TASK_EVENT_WAKE)) - return EC_ERROR_TIMEOUT; - - master_stop(port); - } else { - disable_ack(port); - - rv = master_start(port, slave_addr | 1); - if (rv) - return rv; - master_stop(port); - rv = wait_status(port, SR1_RxNE, WAIT_RX_NE_STOP_SIZE2); - if (rv) - return rv; - data[0] = STM32_I2C_DR(port); - } - - return wait_until_stop_sent(port); -} - -int chip_i2c_xfer(int port, int slave_addr, const uint8_t *out, int out_bytes, - uint8_t *in, int in_bytes, int flags) -{ - int rv; - - /* TODO(crosbug.com/p/23569): support start/stop flags */ - - ASSERT(out || !out_bytes); - ASSERT(in || !in_bytes); - - if (i2c_claim(port)) - return EC_ERROR_BUSY; - - /* If the port appears to be wedged, then try to unwedge it. */ - if (!i2c_raw_get_scl(port) || !i2c_raw_get_sda(port)) { - i2c_unwedge(port); - - /* Reset the i2c port. */ - i2c_init_port(port); - } - - disable_i2c_interrupt(port); - - rv = i2c_master_transmit(port, slave_addr, out, out_bytes, - in_bytes ? 0 : 1); - if (!rv && in_bytes) - rv = i2c_master_receive(port, slave_addr, in, in_bytes); - handle_i2c_error(port, rv); - - enable_i2c_interrupt(port); - - i2c_release(port); - - return rv; -} - -int i2c_raw_get_scl(int port) -{ - enum gpio_signal g; - - if (get_scl_from_i2c_port(port, &g) == EC_SUCCESS) - return gpio_get_level(g); - - /* If no SCL pin defined for this port, then return 1 to appear idle. */ - return 1; -} - -int i2c_raw_get_sda(int port) -{ - enum gpio_signal g; - - if (get_sda_from_i2c_port(port, &g) == EC_SUCCESS) - return gpio_get_level(g); - - /* If no SDA pin defined for this port, then return 1 to appear idle. */ - return 1; -} - -int i2c_get_line_levels(int port) -{ - return (i2c_raw_get_sda(port) ? I2C_LINE_SDA_HIGH : 0) | - (i2c_raw_get_scl(port) ? I2C_LINE_SCL_HIGH : 0); -} - diff --git a/chip/stm32/jtag-stm32f.c b/chip/stm32/jtag-stm32f.c deleted file mode 100644 index 9d55fdb906..0000000000 --- a/chip/stm32/jtag-stm32f.c +++ /dev/null @@ -1,14 +0,0 @@ -/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -/* Settings to enable JTAG debugging */ - -#include "jtag.h" -#include "registers.h" - -void jtag_pre_init(void) -{ - /* stop TIM1-4 and watchdogs when the JTAG stops the CPU */ - STM32_DBGMCU_CR |= 0x00003f00; -} diff --git a/chip/stm32/pwm.c b/chip/stm32/pwm.c index 42e6716db5..c25dd2330e 100644 --- a/chip/stm32/pwm.c +++ b/chip/stm32/pwm.c @@ -38,32 +38,11 @@ static void pwm_configure(enum pwm_channel ch) const struct gpio_info *gpio = gpio_list + pwm->pin; timer_ctlr_t *tim = (timer_ctlr_t *)(pwm->tim.base); volatile unsigned *ccmr = NULL; -#ifdef CHIP_FAMILY_STM32F - int mask = gpio->mask; - volatile uint32_t *gpio_cr = NULL; - uint32_t val; -#endif if (using_pwm[ch]) return; -#if defined(CHIP_FAMILY_STM32F) - if (mask < 0x100) { - gpio_cr = &STM32_GPIO_CRL(gpio->port); - } else { - gpio_cr = &STM32_GPIO_CRH(gpio->port); - mask >>= 8; - } - - /* Expand mask from 8-bit to 32-bit */ - mask = mask * mask; - mask = mask * mask; - - /* Set alternate function */ - val = *gpio_cr & ~(mask * 0xf); - val |= mask * 0x9; - *gpio_cr = val; -#elif defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) +#if defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) gpio_set_alternate_function(gpio->port, gpio->mask, pwm->gpio_alt_func); #else /* stm32l */ gpio_set_alternate_function(gpio->port, gpio->mask, diff --git a/chip/stm32/registers.h b/chip/stm32/registers.h index 749da6ed78..d008ee0167 100644 --- a/chip/stm32/registers.h +++ b/chip/stm32/registers.h @@ -72,8 +72,6 @@ #ifdef CHIP_VARIANT_STM32TS60 #define STM32_IRQ_ADC_1 21 -#else -#define STM32_IRQ_ADC_1 18 /* ADC1 and ADC2 interrupt on STM32F10x */ #endif #ifdef CHIP_VARIANT_STM32F373 @@ -84,10 +82,10 @@ #define STM32_IRQ_USB_LP 20 #endif -#define STM32_IRQ_CAN_TX 19 /* STM32F10x/373 only */ -#define STM32_IRQ_USB_LP_CAN_RX 20 /* STM32F10x/373 only */ +#define STM32_IRQ_CAN_TX 19 /* STM32F373 only */ +#define STM32_IRQ_USB_LP_CAN_RX 20 /* STM32F373 only */ #define STM32_IRQ_DAC 21 -#define STM32_IRQ_CAN_RX1 21 /* STM32F10x/373 only */ +#define STM32_IRQ_CAN_RX1 21 /* STM32F373 only */ #ifdef CHIP_VARIANT_STM32F373 #define STM32_IRQ_COMP 64 @@ -95,23 +93,18 @@ #define STM32_IRQ_COMP 22 #endif -#define STM32_IRQ_CAN_SCE 22 /* STM32F10x/373 only */ +#define STM32_IRQ_CAN_SCE 22 /* STM32F373 only */ #define STM32_IRQ_ADC_2 22 /* STM32TS60 only */ #define STM32_IRQ_EXTI9_5 23 #define STM32_IRQ_LCD 24 /* STM32L15X only */ -#define STM32_IRQ_TIM1_BRK_TIM15 24 /* TIM15 interrupt on STM32F100 only */ #define STM32_IRQ_PMAD 24 /* STM32TS60 only */ #define STM32_IRQ_TIM15 24 /* STM32F373 only */ #define STM32_IRQ_TIM9 25 /* STM32L15X only */ -#define STM32_IRQ_TIM1_UP_TIM16 25 /* TIM16 interrupt on STM32F100 only */ #define STM32_IRQ_PMSE 25 /* STM32TS60 only */ #define STM32_IRQ_TIM16 25 /* STM32F373 only */ #define STM32_IRQ_TIM10 26 /* STM32L15X only */ -#define STM32_IRQ_TIM1_TRG_TIM17 26 /* STM32F100 only */ -#define STM32_IRQ_TIM1_TRG_COM 26 /* STM32F10x only */ #define STM32_IRQ_TIM17 26 /* STM32F373 only */ #define STM32_IRQ_TIM11 27 /* STM32L15X only */ -#define STM32_IRQ_TIM1_CC 27 /* STM32F100 and STM32F10x */ #define STM32_IRQ_TIM18_DAC2 27 /* STM32F373 only */ #define STM32_IRQ_TIM2 28 #define STM32_IRQ_TIM3 29 @@ -127,34 +120,23 @@ #define STM32_IRQ_USART3 39 #define STM32_IRQ_EXTI15_10 40 #define STM32_IRQ_RTC_ALARM 41 -#define STM32_IRQ_USB_FS_WAKEUP 42 /* STM32L15X and STM32F10x */ -#define STM32_IRQ_CEC 42 /* STM32F100/373 only */ +#define STM32_IRQ_USB_FS_WAKEUP 42 /* STM32L15X */ +#define STM32_IRQ_CEC 42 /* STM32F373 only */ #define STM32_IRQ_TIM6_BASIC 43 /* STM32L15X only */ -#define STM32_IRQ_TIM12 43 /* STM32F100/373 only */ -#define STM32_IRQ_TIM8_BRK 43 /* STM32F10x only */ +#define STM32_IRQ_TIM12 43 /* STM32F373 only */ #define STM32_IRQ_TIM7_BASIC 44 /* STM32L15X only */ -#define STM32_IRQ_TIM13 44 /* STM32F100/373 only */ -#define STM32_IRQ_TIM8_UP 44 /* STM32F10x only */ -#define STM32_IRQ_TIM14 45 /* STM32F100/373 only */ -#define STM32_IRQ_TIM8_TRG_COM 45 /* STM32F10x only */ -#define STM32_IRQ_TIM8_CC 46 /* STM32F10x only */ -#define STM32_IRQ_ADC3 47 /* STM32F10x only */ -#define STM32_IRQ_FSMC 48 /* STM32F100 and STM32F10x */ -#define STM32_IRQ_SDIO 49 /* STM32F10x only */ -#define STM32_IRQ_TIM5 50 /* STM32F100, STM32F10x, and STM32F373 */ -#define STM32_IRQ_SPI3 51 /* STM32F100, STM32F10x, and STM32F373 */ -#define STM32_IRQ_UART4 52 /* STM32F100 and STM32F10x */ -#define STM32_IRQ_UART5 53 /* STM32F100 and STM32F10x */ -#define STM32_IRQ_TIM6_DAC 54 /* STM32F100 and STM32F373 */ -#define STM32_IRQ_TIM6 54 /* STM32F10x only */ -#define STM32_IRQ_TIM7 55 /* STM32F100, STM32F10x, and STM32F373 */ -#define STM32_IRQ_DMA2_CHANNEL1 56 /* STM32F100, STM32F10x, and STM32F373 */ -#define STM32_IRQ_DMA2_CHANNEL2 57 /* STM32F100, STM32F10x, and STM32F373 */ -#define STM32_IRQ_DMA2_CHANNEL3 58 /* STM32F100, STM32F10x, and STM32F373 */ -#define STM32_IRQ_DMA2_CHANNEL4_5 59 /* STM32F100 and STM32F10x */ +#define STM32_IRQ_TIM13 44 /* STM32F373 only */ +#define STM32_IRQ_TIM14 45 /* STM32F373 only */ +#define STM32_IRQ_TIM5 50 /* STM32F373 */ +#define STM32_IRQ_SPI3 51 /* STM32F373 */ +#define STM32_IRQ_TIM6_DAC 54 /* STM32F373 */ +#define STM32_IRQ_TIM7 55 /* STM32F373 */ +#define STM32_IRQ_DMA2_CHANNEL1 56 /* STM32F373 */ +#define STM32_IRQ_DMA2_CHANNEL2 57 /* STM32F373 */ +#define STM32_IRQ_DMA2_CHANNEL3 58 /* STM32F373 */ #define STM32_IRQ_DMA2_CHANNEL4 59 /* STM32F373 only */ /* if MISC_REMAP bits are set */ -#define STM32_IRQ_DMA2_CHANNEL5 60 /* STM32F100 and STM32F373 */ +#define STM32_IRQ_DMA2_CHANNEL5 60 /* STM32F373 */ #define STM32_IRQ_SDADC1 61 /* STM32F373 only */ #define STM32_IRQ_SDADC2 62 /* STM32F373 only */ #define STM32_IRQ_SDADC3 63 /* STM32F373 only */ @@ -239,29 +221,24 @@ #define STM32_IRQ_USART(n) CONCAT2(STM32_IRQ_USART, n) /* --- TIMERS --- */ -#define STM32_TIM1_BASE 0x40012c00 /* STM32F100 and STM32F10x */ +#define STM32_TIM1_BASE 0x40012c00 /* STM32F373 */ #define STM32_TIM2_BASE 0x40000000 #define STM32_TIM3_BASE 0x40000400 #define STM32_TIM4_BASE 0x40000800 -#define STM32_TIM5_BASE 0x40000c00 /* STM32F1xx and STM32F373 */ +#define STM32_TIM5_BASE 0x40000c00 /* STM32F373 */ #define STM32_TIM6_BASE 0x40001000 #define STM32_TIM7_BASE 0x40001400 -#define STM32_TIM8_BASE 0x40013400 /* STM32F10x only */ #if defined(CHIP_FAMILY_STM32L) #define STM32_TIM9_BASE 0x40010800 /* STM32L15X only */ #define STM32_TIM10_BASE 0x40010C00 /* STM32L15X only */ #define STM32_TIM11_BASE 0x40011000 /* STM32L15X only */ -#elif defined(CHIP_VARIANT_STM32F10X) -#define STM32_TIM9_BASE 0x40014C00 /* STM32F10x only */ -#define STM32_TIM10_BASE 0x40015000 /* STM32F10x only */ -#define STM32_TIM11_BASE 0x40015400 /* STM32F10x only */ #endif /* TIM9-11 */ -#define STM32_TIM12_BASE 0x40001800 /* STM32F1xx and STM32F373 */ -#define STM32_TIM13_BASE 0x40001c00 /* STM32F1xx and STM32F373 */ -#define STM32_TIM14_BASE 0x40002000 /* STM32F1xx and STM32F373 */ -#define STM32_TIM15_BASE 0x40014000 /* STM32F100 only */ -#define STM32_TIM16_BASE 0x40014400 /* STM32F100 only */ -#define STM32_TIM17_BASE 0x40014800 /* STM32F100 only */ +#define STM32_TIM12_BASE 0x40001800 /* STM32F373 */ +#define STM32_TIM13_BASE 0x40001c00 /* STM32F373 */ +#define STM32_TIM14_BASE 0x40002000 /* STM32F373 */ +#define STM32_TIM15_BASE 0x40014000 +#define STM32_TIM16_BASE 0x40014400 +#define STM32_TIM17_BASE 0x40014800 #define STM32_TIM18_BASE 0x40009c00 /* STM32F373 only */ #define STM32_TIM19_BASE 0x40015c00 /* STM32F373 only */ @@ -403,31 +380,6 @@ typedef volatile struct timer_ctlr timer_ctlr_t; #define GPIO_ALT_F4 0x4 #define GPIO_ALT_F5 0x5 -#elif defined(CHIP_FAMILY_STM32F) -#define STM32_GPIOA_BASE 0x40010800 -#define STM32_GPIOB_BASE 0x40010c00 -#define STM32_GPIOC_BASE 0x40011000 -#define STM32_GPIOD_BASE 0x40011400 -#define STM32_GPIOE_BASE 0x40011800 -#define STM32_GPIOF_BASE 0x4001c000 -#define STM32_GPIOG_BASE 0x40012000 -#define STM32_GPIOH_BASE 0x40012400 /* STM32TS only */ -#define STM32_GPIOI_BASE 0x40012800 /* STM32TS only */ - -#define STM32_GPIO_CRL(b) REG32((b) + 0x00) -#define STM32_GPIO_CRH(b) REG32((b) + 0x04) -#define STM32_GPIO_IDR(b) REG16((b) + 0x08) -#define STM32_GPIO_ODR(b) REG16((b) + 0x0c) -#define STM32_GPIO_BSRR(b) REG32((b) + 0x10) -#define STM32_GPIO_BRR(b) REG32((b) + 0x14) -#define STM32_GPIO_LCKR(b) REG32((b) + 0x18) - -#define STM32_AFIO_BASE 0x40010000 -#define STM32_AFIO_EXTICR(n) REG32(STM32_AFIO_BASE + 8 + 4 * (n)) -#define STM32_GPIO_AFIO_EVCR REG32(STM32_AFIO_BASE + 0x00) -#define STM32_GPIO_AFIO_MAPR REG32(STM32_AFIO_BASE + 0x04) -#define STM32_GPIO_AFIO_MAPR2 REG32(STM32_AFIO_BASE + 0x1c) - #else #error Unsupported chip variant #endif @@ -531,9 +483,7 @@ typedef volatile struct timer_ctlr timer_ctlr_t; #define STM32_PWR_CR REG32(STM32_PWR_BASE + 0x00) #define STM32_PWR_CR_LPSDSR (1 << 0) #define STM32_PWR_CSR REG32(STM32_PWR_BASE + 0x04) -#if defined(CHIP_FAMILY_STM32F) -#define STM32_PWR_CSR_EWUP (1 << 8) -#elif defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) +#if defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) #define STM32_PWR_CSR_EWUP1 (1 << 8) #define STM32_PWR_CSR_EWUP2 (1 << 9) #define STM32_PWR_CSR_EWUP3 (1 << 10) @@ -594,8 +544,7 @@ typedef volatile struct timer_ctlr timer_ctlr_t; #define STM32_SYSCFG_PMC REG32(STM32_SYSCFG_BASE + 0x04) #define STM32_SYSCFG_EXTICR(n) REG32(STM32_SYSCFG_BASE + 8 + 4 * (n)) -#elif defined(CHIP_FAMILY_STM32F) || defined(CHIP_FAMILY_STM32F0) || \ - defined(CHIP_FAMILY_STM32F3) +#elif defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) #define STM32_RCC_BASE 0x40021000 #define STM32_RCC_CR REG32(STM32_RCC_BASE + 0x00) @@ -608,7 +557,7 @@ typedef volatile struct timer_ctlr timer_ctlr_t; #define STM32_RCC_APB1ENR REG32(STM32_RCC_BASE + 0x1c) #define STM32_RCC_BDCR REG32(STM32_RCC_BASE + 0x20) #define STM32_RCC_CSR REG32(STM32_RCC_BASE + 0x24) -/* STM32F100 and STM32F373 */ +/* STM32F373 */ #define STM32_RCC_CFGR2 REG32(STM32_RCC_BASE + 0x2c) /* STM32F0XX and STM32F373 */ #define STM32_RCC_CFGR3 REG32(STM32_RCC_BASE + 0x30) @@ -716,36 +665,6 @@ typedef volatile struct timer_ctlr timer_ctlr_t; #define STM32_BKP_ENTRIES 20 #endif -#elif defined(CHIP_FAMILY_STM32F) -#define STM32_RTC_CRH REG32(STM32_RTC_BASE + 0x00) -#define STM32_RTC_CRL REG32(STM32_RTC_BASE + 0x04) -#define STM32_RTC_PRLH REG32(STM32_RTC_BASE + 0x08) -#define STM32_RTC_PRLL REG16(STM32_RTC_BASE + 0x0c) -#define STM32_RTC_DIVH REG16(STM32_RTC_BASE + 0x10) -#define STM32_RTC_DIVL REG16(STM32_RTC_BASE + 0x14) -#define STM32_RTC_CNTH REG16(STM32_RTC_BASE + 0x18) -#define STM32_RTC_CNTL REG16(STM32_RTC_BASE + 0x1c) -#define STM32_RTC_ALRH REG16(STM32_RTC_BASE + 0x20) -#define STM32_RTC_ALRL REG16(STM32_RTC_BASE + 0x24) - -/* --- Backup Registers --- */ -#define STM32_BKP_BASE 0x40006c00 - -#if defined(CHIP_VARIANT_STM32F10X) -#define STM32_BKP_ENTRIES 42 -#define STM32_BKP_DATA(n) \ - REG16(STM32_BKP_BASE + (n < 11 ? 0x4 : 0x40) + 4 * (n)) -#else -#define STM32_BKP_ENTRIES 10 -#define STM32_BKP_DATA(n) REG16(STM32_BKP_BASE + 0x4 + 4 * (n)) -#endif - -#define STM32_BKP_RTCCR REG16(STM32_BKP_BASE + 0x2c) -#define STM32_BKP_CR REG16(STM32_BKP_BASE + 0x30) -#define STM32_BKP_CSR REG16(STM32_BKP_BASE + 0x34) - -#define STM32_RTC_BACKUP(n) STM32_BKP_DATA(n) - #else #error Unsupported chip variant #endif @@ -753,7 +672,7 @@ typedef volatile struct timer_ctlr timer_ctlr_t; /* --- SPI --- */ #define STM32_SPI1_BASE 0x40013000 #define STM32_SPI2_BASE 0x40003800 -#define STM32_SPI3_BASE 0x40003c00 /* STM32F100 and STM32F373 */ +#define STM32_SPI3_BASE 0x40003c00 /* STM32F373 */ #define STM32_SPI1_PORT 0 #define STM32_SPI2_PORT 1 @@ -771,8 +690,8 @@ struct stm32_spi_regs { unsigned crcpr; unsigned rxcrcr; unsigned txcrcr; - unsigned i2scfgr; /* STM32F10x and STM32L only */ - unsigned i2spr; /* STM32F10x and STM32L only */ + unsigned i2scfgr; /* STM32L only */ + unsigned i2spr; /* STM32L only */ }; /* Must be volatile, or compiler optimizes out repeated accesses */ typedef volatile struct stm32_spi_regs stm32_spi_regs_t; @@ -861,8 +780,7 @@ typedef volatile struct stm32_spi_regs stm32_spi_regs_t; #define STM32_OPTB_WRP3L 0x18 #define STM32_OPTB_WRP3H 0x1c -#elif defined(CHIP_FAMILY_STM32F) || defined(CHIP_FAMILY_STM32F0) || \ - defined(CHIP_FAMILY_STM32F3) +#elif defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) #define STM32_FLASH_REGS_BASE 0x40022000 #define STM32_FLASH_ACR REG32(STM32_FLASH_REGS_BASE + 0x00) @@ -915,11 +833,9 @@ typedef volatile struct stm32_spi_regs stm32_spi_regs_t; #else /* !CHIP_VARIANT_STM32TS60 */ #define STM32_ADC1_BASE 0x40012400 #define STM32_ADC_BASE 0x40012700 /* STM32L15X only */ -#define STM32_ADC2_BASE 0x40012800 /* STM32F10x only */ -#define STM32_ADC3_BASE 0x40013C00 /* STM32F10x only */ #endif -#if defined(CHIP_VARIANT_STM32F100) || defined(CHIP_VARIANT_STM32F373) +#if defined(CHIP_VARIANT_STM32F373) #define STM32_ADC_SR REG32(STM32_ADC1_BASE + 0x00) #define STM32_ADC_CR1 REG32(STM32_ADC1_BASE + 0x04) #define STM32_ADC_CR2 REG32(STM32_ADC1_BASE + 0x08) @@ -1183,8 +1099,7 @@ typedef volatile struct stm32_spi_regs stm32_spi_regs_t; #if defined(CHIP_FAMILY_STM32L) #define STM32_DMA1_BASE 0x40026000 -#elif defined(CHIP_FAMILY_STM32F) || defined(CHIP_FAMILY_STM32F0) || \ - defined(CHIP_FAMILY_STM32F3) +#elif defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) #define STM32_DMA1_BASE 0x40020000 #else #error Unsupported chip variant @@ -1236,7 +1151,7 @@ enum dma_channel { STM32_DMAC_SPI2_TX = STM32_DMAC_CH7, #endif - /* Only DMA1 (with 7 channels) is present on STM32F100 and STM32L151x */ + /* Only DMA1 (with 7 channels) is present on STM32L151x */ STM32_DMAC_COUNT = 7, #else /* stm32f03x and stm32f05x have only 5 channels */ @@ -1386,14 +1301,8 @@ typedef volatile struct stm32_dma_regs stm32_dma_regs_t; /* --- MISC --- */ #define STM32_UNIQUE_ID 0x1ffff7ac -#define STM32_CEC_BASE 0x40007800 /* STM32F100 and STM32F373 */ +#define STM32_CEC_BASE 0x40007800 /* STM32F373 */ #define STM32_LCD_BASE 0x40002400 -#define STM32_FSMC_BASE 0xA0000000 /* STM32F10x only */ -#define STM32_USB_OTG_FS_BASE 0x50000000 /* STM32F10x only */ -#define STM32_ETHERNET_BASE 0x40028000 /* STM32F10x only */ -#define STM32_SDIO_BASE 0x40018000 /* STM32F10x only */ -#define STM32_BXCAN1_BASE 0x40006400 /* STM32F10x only */ -#define STM32_BXCAN2_BASE 0x40006800 /* STM32F10x only */ #endif /* !__ASSEMBLER__ */ diff --git a/chip/stm32/system.c b/chip/stm32/system.c index 0030e1a305..88cde274fd 100644 --- a/chip/stm32/system.c +++ b/chip/stm32/system.c @@ -195,8 +195,7 @@ void system_pre_init(void) /* Enable RTC and use LSI as clock source */ STM32_RCC_CSR = (STM32_RCC_CSR & ~0x00C30000) | 0x00420000; } -#elif defined(CHIP_FAMILY_STM32F) || defined(CHIP_FAMILY_STM32F0) || \ - defined(CHIP_FAMILY_STM32F3) +#elif defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) if ((STM32_RCC_BDCR & 0x00018300) != 0x00008200) { /* the RTC settings are bad, we need to reset it */ STM32_RCC_BDCR |= 0x00010000; diff --git a/chip/stm32/usart-stm32f.c b/chip/stm32/usart-stm32f.c deleted file mode 100644 index 276e1d7193..0000000000 --- a/chip/stm32/usart-stm32f.c +++ /dev/null @@ -1,115 +0,0 @@ -/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -#include "usart-stm32f.h" - -#include "clock.h" -#include "common.h" -#include "hooks.h" -#include "registers.h" -#include "task.h" -#include "util.h" - -/* - * This configs array stores the currently active usart_config structure for - * each USART, an entry will be NULL if no USART driver is initialized for the - * corresponding hardware instance. - */ -static struct usart_config const *configs[STM32_USARTS_MAX]; - -static void usart_variant_enable(struct usart_config const *config) -{ - /* - * Make sure we register this config before enabling the HW. - * If we did it the other way around the FREQ_CHANGE hook could be - * called before we update the configs array and we would miss the - * clock frequency change event, leaving our baud rate divisor wrong. - */ - configs[config->hw->index] = config; - - usart_set_baud_f(config, clock_get_freq()); - - task_enable_irq(config->hw->irq); -} - -static void usart_variant_disable(struct usart_config const *config) -{ - task_disable_irq(config->hw->irq); - - configs[config->hw->index] = NULL; -} - -static usart_hw_ops const struct usart_variant_hw_ops = { - .enable = usart_variant_enable, - .disable = usart_variant_disable, -}; - -static void freq_change(void) -{ - size_t i; - - for (i = 0; i < ARRAY_SIZE(configs); ++i) - if (configs[i]) - usart_set_baud_f(configs[i], clock_get_freq()); -} - -DECLARE_HOOK(HOOK_FREQ_CHANGE, freq_change, HOOK_PRIO_DEFAULT); - -/* - * USART interrupt bindings. These functions can not be defined as static or - * they will be removed by the linker because of the way that DECLARE_IRQ works. - */ -#if defined(CONFIG_STREAM_USART1) -struct usart_hw_config const usart1_hw = { - .index = 0, - .base = STM32_USART1_BASE, - .irq = STM32_IRQ_USART1, - .clock_register = &STM32_RCC_APB2ENR, - .clock_enable = STM32_RCC_PB2_USART1, - .ops = &usart_variant_hw_ops, -}; - -void usart1_interrupt(void) -{ - usart_interrupt(configs[0]); -} - -DECLARE_IRQ(STM32_IRQ_USART1, usart1_interrupt, 2); -#endif - -#if defined(CONFIG_STREAM_USART2) -struct usart_hw_config const usart2_hw = { - .index = 1, - .base = STM32_USART2_BASE, - .irq = STM32_IRQ_USART2, - .clock_register = &STM32_RCC_APB1ENR, - .clock_enable = STM32_RCC_PB1_USART2, - .ops = &usart_variant_hw_ops, -}; - -void usart2_interrupt(void) -{ - usart_interrupt(configs[1]); -} - -DECLARE_IRQ(STM32_IRQ_USART2, usart2_interrupt, 2); -#endif - -#if defined(CONFIG_STREAM_USART3) -struct usart_hw_config const usart3_hw = { - .index = 2, - .base = STM32_USART3_BASE, - .irq = STM32_IRQ_USART3_4, - .clock_register = &STM32_RCC_APB1ENR, - .clock_enable = STM32_RCC_PB1_USART3, - .ops = &usart_variant_hw_ops, -}; - -void usart3_interrupt(void) -{ - usart_interrupt(configs[2]); -} - -DECLARE_IRQ(STM32_IRQ_USART3, usart3_interrupt, 2); -#endif diff --git a/chip/stm32/usart-stm32f.h b/chip/stm32/usart-stm32f.h deleted file mode 100644 index 5b0abe0a01..0000000000 --- a/chip/stm32/usart-stm32f.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -#ifndef __CROS_EC_USART_STM32F_H -#define __CROS_EC_USART_STM32F_H - -#include "usart.h" - -#define STM32_USARTS_MAX 3 - -/* - * The STM32F series can have as many as three UARTS. These are the HW configs - * for those UARTS. They can be used to initialize STM32 generic UART configs. - */ -extern struct usart_hw_config const usart1_hw; -extern struct usart_hw_config const usart2_hw; -extern struct usart_hw_config const usart3_hw; - -#endif /* __CROS_EC_USART_STM32F_H */ diff --git a/common/i2c.c b/common/i2c.c index 518bca0647..af1184a4e7 100644 --- a/common/i2c.c +++ b/common/i2c.c @@ -711,19 +711,8 @@ static void scan_bus(int port, const char *desc) watchdog_reload(); /* Otherwise a full scan trips watchdog */ ccputs("."); -#ifdef CHIP_FAMILY_STM32F - /* - * TODO(crosbug.com/p/23569): The i2c_xfer() implementation on - * STM32F can't read a byte without writing one first. So - * write a byte and hope nothing bad happens. Remove this - * workaround when STM32F is fixed. - */ - tmp = 0; - if (!i2c_xfer(port, a, &tmp, 1, &tmp, 1, I2C_XFER_SINGLE)) -#else /* Do a single read */ if (!i2c_xfer(port, a, NULL, 0, &tmp, 1, I2C_XFER_SINGLE)) -#endif ccprintf("\n 0x%02x", a); } |