mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-27 18:25:05 +00:00
stm32f446e-eval: add support for stm32f446
This adds basic support for the stm32f446. This consists of: * New DMA model for stm32f4 * New clock domain support. * MCO oscillator gpio export support. * Flash support for irregular blocks. BUG=chromium:608039 TEST=boots w/ correct clock, stm32f0 also boots. BRANCH=None Change-Id: I1c5cf6ddca09009c9dac60da8a3d0c5ceedfcf4d Signed-off-by: Nick Sanders <nsanders@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/363992 Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
This commit is contained in:
58
board/stm32f446e-eval/board.c
Normal file
58
board/stm32f446e-eval/board.c
Normal file
@@ -0,0 +1,58 @@
|
||||
/* Copyright 2016 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 "common.h"
|
||||
#include "dma.h"
|
||||
#include "ec_version.h"
|
||||
#include "gpio.h"
|
||||
#include "gpio_list.h"
|
||||
#include "hooks.h"
|
||||
#include "registers.h"
|
||||
#include "stm32-dma.h"
|
||||
|
||||
#define GPIO_SET_HS(bank, number) \
|
||||
(STM32_GPIO_OSPEEDR(GPIO_##bank) |= (0x3 << (number * 2)))
|
||||
|
||||
void board_config_post_gpio_init(void)
|
||||
{
|
||||
/* We use MCO2 clock passthrough to provide a clock to USB HS */
|
||||
gpio_config_module(MODULE_MCO, 1);
|
||||
/* GPIO PC9 to high speed */
|
||||
GPIO_SET_HS(C, 9);
|
||||
|
||||
/* Set USB GPIO to high speed */
|
||||
GPIO_SET_HS(A, 11);
|
||||
GPIO_SET_HS(A, 12);
|
||||
|
||||
GPIO_SET_HS(C, 3);
|
||||
GPIO_SET_HS(C, 2);
|
||||
GPIO_SET_HS(C, 0);
|
||||
GPIO_SET_HS(A, 5);
|
||||
|
||||
GPIO_SET_HS(B, 5);
|
||||
GPIO_SET_HS(B, 13);
|
||||
GPIO_SET_HS(B, 12);
|
||||
GPIO_SET_HS(B, 2);
|
||||
GPIO_SET_HS(B, 10);
|
||||
GPIO_SET_HS(B, 1);
|
||||
GPIO_SET_HS(B, 0);
|
||||
GPIO_SET_HS(A, 3);
|
||||
|
||||
/* Set I2C GPIO to HS */
|
||||
GPIO_SET_HS(B, 6);
|
||||
GPIO_SET_HS(B, 7);
|
||||
GPIO_SET_HS(F, 1);
|
||||
GPIO_SET_HS(F, 0);
|
||||
GPIO_SET_HS(A, 8);
|
||||
GPIO_SET_HS(B, 4);
|
||||
GPIO_SET_HS(C, 6);
|
||||
GPIO_SET_HS(C, 7);
|
||||
}
|
||||
|
||||
static void board_init(void)
|
||||
{
|
||||
}
|
||||
DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT);
|
||||
|
||||
54
board/stm32f446e-eval/board.h
Normal file
54
board/stm32f446e-eval/board.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/* Copyright 2016 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.
|
||||
*/
|
||||
|
||||
/* STM32F446E-Eval board configuration */
|
||||
|
||||
#ifndef __CROS_EC_BOARD_H
|
||||
#define __CROS_EC_BOARD_H
|
||||
|
||||
/* Use external clock */
|
||||
#define CONFIG_STM32_CLOCK_HSE_HZ 8000000
|
||||
|
||||
/* Optional features */
|
||||
#undef CONFIG_WATCHDOG_HELP
|
||||
#undef CONFIG_LID_SWITCH
|
||||
#define CONFIG_BOARD_POST_GPIO_INIT
|
||||
|
||||
/* Enable console recasting of GPIO type. */
|
||||
#define CONFIG_CMD_GPIO_EXTENDED
|
||||
|
||||
/* The UART console is on USART1 (PA9/PA10) */
|
||||
#undef CONFIG_UART_CONSOLE
|
||||
#define CONFIG_UART_CONSOLE 1
|
||||
#undef CONFIG_UART_TX_BUF_SIZE
|
||||
#define CONFIG_UART_TX_BUF_SIZE 4096
|
||||
#define CONFIG_UART_TX_REQ_CH 4
|
||||
#define CONFIG_UART_RX_REQ_CH 4
|
||||
|
||||
/* This is not actually an EC so disable some features. */
|
||||
#undef CONFIG_WATCHDOG_HELP
|
||||
#undef CONFIG_LID_SWITCH
|
||||
#undef CONFIG_WATCHDOG
|
||||
|
||||
/* Optional features */
|
||||
#define CONFIG_STM_HWTIMER32
|
||||
#define CONFIG_DMA_HELP
|
||||
|
||||
/*
|
||||
* Allow dangerous commands all the time, since we don't have a write protect
|
||||
* switch.
|
||||
*/
|
||||
#define CONFIG_SYSTEM_UNLOCKED
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
#undef CONFIG_FLASH
|
||||
|
||||
/* Timer selection */
|
||||
#define TIM_CLOCK32 5
|
||||
|
||||
#include "gpio_signal.h"
|
||||
|
||||
#endif /* !__ASSEMBLER__ */
|
||||
#endif /* __CROS_EC_BOARD_H */
|
||||
12
board/stm32f446e-eval/build.mk
Normal file
12
board/stm32f446e-eval/build.mk
Normal file
@@ -0,0 +1,12 @@
|
||||
# -*- makefile -*-
|
||||
# Copyright 2016 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.
|
||||
#
|
||||
# Board specific files build
|
||||
|
||||
CHIP:=stm32
|
||||
CHIP_FAMILY:=stm32f4
|
||||
CHIP_VARIANT:=stm32f446
|
||||
|
||||
board-y=board.o
|
||||
21
board/stm32f446e-eval/ec.tasklist
Normal file
21
board/stm32f446e-eval/ec.tasklist
Normal file
@@ -0,0 +1,21 @@
|
||||
/* Copyright 2016 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* List of enabled tasks in the priority order
|
||||
*
|
||||
* The first one has the lowest priority.
|
||||
*
|
||||
* For each task, use the macro TASK_ALWAYS(n, r, d, s) for base tasks and
|
||||
* TASK_NOTEST(n, r, d, s) for tasks that can be excluded in test binaries,
|
||||
* where :
|
||||
* 'n' in the name of the task
|
||||
* 'r' in the main routine of the task
|
||||
* 'd' in an opaque parameter passed to the routine at startup
|
||||
* 's' is the stack size in bytes; must be a multiple of 8
|
||||
*/
|
||||
#define CONFIG_TASK_LIST \
|
||||
TASK_ALWAYS(HOOKS, hook_task, NULL, TASK_STACK_SIZE) \
|
||||
TASK_ALWAYS(CONSOLE, console_task, NULL, VENTI_TASK_STACK_SIZE)
|
||||
62
board/stm32f446e-eval/gpio.inc
Normal file
62
board/stm32f446e-eval/gpio.inc
Normal file
@@ -0,0 +1,62 @@
|
||||
/* -*- mode:c -*-
|
||||
*
|
||||
* Copyright 2016 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.
|
||||
*/
|
||||
|
||||
/* Declare symbolic names for all the GPIOs that we care about.
|
||||
* Note: Those with interrupt handlers must be declared first. */
|
||||
|
||||
/* Outputs */
|
||||
GPIO(PD11, PIN(D, 11), GPIO_OUT_HIGH)
|
||||
|
||||
GPIO(I2C1_SCL, PIN(B, 8), GPIO_INPUT)
|
||||
GPIO(I2C1_SDA, PIN(B, 9), GPIO_INPUT)
|
||||
GPIO(FMPI2C_SCL, PIN(C, 6), GPIO_INPUT)
|
||||
GPIO(FMPI2C_SDA, PIN(C, 7), GPIO_INPUT)
|
||||
|
||||
/* USART3 TX/RX */
|
||||
GPIO(MCU_UART1_TX, PIN(A, 9), GPIO_INPUT)
|
||||
GPIO(MCU_UART1_RX, PIN(A, 10), GPIO_INPUT)
|
||||
GPIO(MCU_UART3_TX, PIN(C, 10), GPIO_INPUT)
|
||||
GPIO(MCU_UART3_RX, PIN(C, 11), GPIO_INPUT)
|
||||
|
||||
GPIO(USB_FS_DM, PIN(A, 11), GPIO_INPUT)
|
||||
GPIO(USB_FS_DP, PIN(A, 12), GPIO_INPUT)
|
||||
|
||||
|
||||
GPIO(USB_HS_ULPI_NXT, PIN(C, 3), GPIO_INPUT)
|
||||
GPIO(USB_HS_ULPI_DIR, PIN(C, 2), GPIO_INPUT)
|
||||
GPIO(USB_HS_ULPI_STP, PIN(C, 0), GPIO_INPUT)
|
||||
GPIO(USB_HS_ULPI_CK, PIN(A, 5), GPIO_INPUT)
|
||||
|
||||
GPIO(USB_HS_ULPI_D7, PIN(B, 5), GPIO_INPUT)
|
||||
GPIO(USB_HS_ULPI_D6, PIN(B,13), GPIO_INPUT)
|
||||
GPIO(USB_HS_ULPI_D5, PIN(B,12), GPIO_INPUT)
|
||||
GPIO(USB_HS_ULPI_D4, PIN(B, 2), GPIO_INPUT)
|
||||
GPIO(USB_HS_ULPI_D3, PIN(B,10), GPIO_INPUT)
|
||||
GPIO(USB_HS_ULPI_D2, PIN(B, 1), GPIO_INPUT)
|
||||
GPIO(USB_HS_ULPI_D1, PIN(B, 0), GPIO_INPUT)
|
||||
GPIO(USB_HS_ULPI_D0, PIN(A, 3), GPIO_INPUT)
|
||||
|
||||
|
||||
|
||||
/* Unimplemented signals since this is a dev board */
|
||||
UNIMPLEMENTED(ENTERING_RW)
|
||||
UNIMPLEMENTED(WP_L)
|
||||
|
||||
ALTERNATE(PIN_MASK(A, 0x0600), 7, MODULE_UART, 0) /* USART1: PA9/PA10 - Console */
|
||||
ALTERNATE(PIN_MASK(C, 0x0C00), 7, MODULE_USART, 0) /* USART3: PC10/PC11 - NOT Console */
|
||||
ALTERNATE(PIN_MASK(A, 0x0100), 0, MODULE_MCO, 0) /* MCO1: PA8 */
|
||||
ALTERNATE(PIN_MASK(C, 0x0200), 0, MODULE_MCO, 0) /* MCO2: PC9 */
|
||||
|
||||
ALTERNATE(PIN_MASK(B, 0x0300), 4, MODULE_I2C, GPIO_ODR_HIGH | GPIO_PULL_UP) /* I2C1: PB8-9 */
|
||||
ALTERNATE(PIN_MASK(C, 0x00c0), 4, MODULE_I2C, GPIO_ODR_HIGH | GPIO_PULL_UP) /* FMPI2C MASTER:PC6/7 */
|
||||
|
||||
ALTERNATE(PIN_MASK(A, 0x1800), 10, MODULE_USB, 0) /* DWC USB OTG: PA11/12 */
|
||||
|
||||
/* OTG HS */
|
||||
ALTERNATE(PIN_MASK(A, 0x0028), 10, MODULE_USB, 0) /* DWC USB OTG HS */
|
||||
ALTERNATE(PIN_MASK(B, 0x3427), 10, MODULE_USB, 0) /* DWC USB OTG HS */
|
||||
ALTERNATE(PIN_MASK(C, 0x000d), 10, MODULE_USB, 0) /* DWC USB OTG HS */
|
||||
@@ -28,8 +28,6 @@
|
||||
|
||||
/* PECI Time-out */
|
||||
#define PECI_DONE_TIMEOUT_US (10*MSEC)
|
||||
/* Task Event for PECI */
|
||||
#define TASK_EVENT_PECI_DONE TASK_EVENT_CUSTOM(1<<26)
|
||||
|
||||
#define NULL_PENDING_TASK_ID 0xFFFFFFFF
|
||||
#define PECI_MAX_FIFO_SIZE 16
|
||||
|
||||
@@ -11,7 +11,7 @@ ifeq ($(CHIP_FAMILY),stm32f0)
|
||||
CORE:=cortex-m0
|
||||
# Force ARMv6-M ISA used by the Cortex-M0
|
||||
CFLAGS_CPU+=-march=armv6-m -mcpu=cortex-m0
|
||||
else ifeq ($(CHIP_FAMILY),$(filter $(CHIP_FAMILY),stm32f3 stm32l4))
|
||||
else ifeq ($(CHIP_FAMILY),$(filter $(CHIP_FAMILY),stm32f3 stm32l4 stm32f4))
|
||||
# STM32F3xx and STM32L4xx sub-family has a Cortex-M4 ARM core
|
||||
CORE:=cortex-m
|
||||
# Allow the full Cortex-M4 instruction set
|
||||
@@ -25,10 +25,14 @@ endif
|
||||
|
||||
# Select between 16-bit and 32-bit timer for clock source
|
||||
TIMER_TYPE=$(if $(CONFIG_STM_HWTIMER32),32,)
|
||||
DMA_TYPE=$(if $(CHIP_FAMILY_STM32F4),-stm32f4,)
|
||||
|
||||
chip-y=dma.o
|
||||
chip-$(CONFIG_DMA)+=dma$(DMA_TYPE).o
|
||||
chip-$(CONFIG_COMMON_RUNTIME)+=system.o
|
||||
chip-y+=jtag-$(CHIP_FAMILY).o clock-$(CHIP_FAMILY).o
|
||||
ifeq ($(CHIP_FAMILY),$(filter $(CHIP_FAMILY),stm32f0 stm32f3 stm32f4))
|
||||
chip-y+=clock-f.o
|
||||
endif
|
||||
chip-$(CONFIG_SPI)+=spi.o
|
||||
chip-$(CONFIG_SPI_MASTER)+=spi_master.o
|
||||
chip-$(CONFIG_COMMON_GPIO)+=gpio.o gpio-$(CHIP_FAMILY).o
|
||||
|
||||
209
chip/stm32/clock-f.c
Normal file
209
chip/stm32/clock-f.c
Normal file
@@ -0,0 +1,209 @@
|
||||
/* Copyright 2016 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 "chipset.h"
|
||||
#include "clock.h"
|
||||
#include "clock-f.h"
|
||||
#include "common.h"
|
||||
#include "console.h"
|
||||
#include "cpu.h"
|
||||
#include "hooks.h"
|
||||
#include "hwtimer.h"
|
||||
#include "registers.h"
|
||||
#include "system.h"
|
||||
#include "task.h"
|
||||
#include "timer.h"
|
||||
#include "util.h"
|
||||
|
||||
/* Console output macros */
|
||||
#define CPUTS(outstr) cputs(CC_CLOCK, outstr)
|
||||
#define CPRINTS(format, args...) cprints(CC_CLOCK, format, ## args)
|
||||
|
||||
|
||||
/* Convert between RTC regs in BCD and seconds */
|
||||
uint32_t rtc_to_sec(uint32_t rtc)
|
||||
{
|
||||
uint32_t sec;
|
||||
|
||||
/* convert the hours field */
|
||||
sec = (((rtc & 0x300000) >> 20) * 10 + ((rtc & 0xf0000) >> 16)) * 3600;
|
||||
/* convert the minutes field */
|
||||
sec += (((rtc & 0x7000) >> 12) * 10 + ((rtc & 0xf00) >> 8)) * 60;
|
||||
/* convert the seconds field */
|
||||
sec += ((rtc & 0x70) >> 4) * 10 + (rtc & 0xf);
|
||||
|
||||
return sec;
|
||||
}
|
||||
uint32_t sec_to_rtc(uint32_t sec)
|
||||
{
|
||||
uint32_t rtc;
|
||||
|
||||
/* convert the hours field */
|
||||
rtc = ((sec / 36000) << 20) | (((sec / 3600) % 10) << 16);
|
||||
/* convert the minutes field */
|
||||
rtc |= (((sec % 3600) / 600) << 12) | (((sec % 600) / 60) << 8);
|
||||
/* convert the seconds field */
|
||||
rtc |= (((sec % 60) / 10) << 4) | (sec % 10);
|
||||
|
||||
return rtc;
|
||||
}
|
||||
|
||||
/* Return time diff between two rtc readings */
|
||||
int32_t get_rtc_diff(uint32_t rtc0, uint32_t rtc0ss,
|
||||
uint32_t rtc1, uint32_t rtc1ss)
|
||||
{
|
||||
int32_t diff;
|
||||
|
||||
/* Note: this only looks at the diff mod 10 seconds */
|
||||
diff = ((rtc1 & 0xf) * SECOND +
|
||||
rtcss_to_us(rtc1ss)) -
|
||||
((rtc0 & 0xf) * SECOND +
|
||||
rtcss_to_us(rtc0ss));
|
||||
|
||||
return (diff < 0) ? (diff + 10*SECOND) : diff;
|
||||
}
|
||||
|
||||
void rtc_read(uint32_t *rtc, uint32_t *rtcss)
|
||||
{
|
||||
/* Read current time synchronously */
|
||||
do {
|
||||
*rtc = STM32_RTC_TR;
|
||||
/*
|
||||
* RTC_SSR must be read twice with identical values because
|
||||
* glitches may occur for reads close to the RTCCLK edge.
|
||||
*/
|
||||
do {
|
||||
*rtcss = STM32_RTC_SSR;
|
||||
} while (*rtcss != STM32_RTC_SSR);
|
||||
} while (*rtc != STM32_RTC_TR);
|
||||
}
|
||||
|
||||
void set_rtc_alarm(uint32_t delay_s, uint32_t delay_us,
|
||||
uint32_t *rtc, uint32_t *rtcss)
|
||||
{
|
||||
uint32_t alarm_sec, alarm_us;
|
||||
|
||||
/* Alarm must be within 1 day (86400 seconds) */
|
||||
ASSERT((delay_s + delay_us / SECOND) < 86400);
|
||||
|
||||
rtc_unlock_regs();
|
||||
|
||||
/* Make sure alarm is disabled */
|
||||
STM32_RTC_CR &= ~STM32_RTC_CR_ALRAE;
|
||||
while (!(STM32_RTC_ISR & STM32_RTC_ISR_ALRAWF))
|
||||
;
|
||||
STM32_RTC_ISR &= ~STM32_RTC_ISR_ALRAF;
|
||||
|
||||
rtc_read(rtc, rtcss);
|
||||
|
||||
/* Calculate alarm time */
|
||||
alarm_sec = rtc_to_sec(*rtc) + delay_s;
|
||||
alarm_us = rtcss_to_us(*rtcss) + delay_us;
|
||||
alarm_sec = alarm_sec + alarm_us / SECOND;
|
||||
alarm_us = alarm_us % 1000000;
|
||||
/*
|
||||
* If seconds is greater than 1 day, subtract by 1 day to deal with
|
||||
* 24-hour rollover.
|
||||
*/
|
||||
if (alarm_sec >= 86400)
|
||||
alarm_sec -= 86400;
|
||||
|
||||
/* Set alarm time */
|
||||
STM32_RTC_ALRMAR = sec_to_rtc(alarm_sec);
|
||||
STM32_RTC_ALRMASSR = us_to_rtcss(alarm_us);
|
||||
/* Check for match on hours, minutes, seconds, and subsecond */
|
||||
STM32_RTC_ALRMAR |= 0xc0000000;
|
||||
STM32_RTC_ALRMASSR |= 0x0f000000;
|
||||
|
||||
/* Enable alarm and alarm interrupt */
|
||||
STM32_EXTI_PR = EXTI_RTC_ALR_EVENT;
|
||||
STM32_EXTI_IMR |= EXTI_RTC_ALR_EVENT;
|
||||
STM32_RTC_CR |= STM32_RTC_CR_ALRAE;
|
||||
|
||||
rtc_lock_regs();
|
||||
}
|
||||
|
||||
void reset_rtc_alarm(uint32_t *rtc, uint32_t *rtcss)
|
||||
{
|
||||
rtc_unlock_regs();
|
||||
|
||||
/* Disable alarm */
|
||||
STM32_RTC_CR &= ~STM32_RTC_CR_ALRAE;
|
||||
STM32_RTC_ISR &= ~STM32_RTC_ISR_ALRAF;
|
||||
|
||||
/* Disable RTC alarm interrupt */
|
||||
STM32_EXTI_IMR &= ~EXTI_RTC_ALR_EVENT;
|
||||
STM32_EXTI_PR = EXTI_RTC_ALR_EVENT;
|
||||
|
||||
/* Read current time */
|
||||
rtc_read(rtc, rtcss);
|
||||
|
||||
rtc_lock_regs();
|
||||
}
|
||||
|
||||
void __rtc_alarm_irq(void)
|
||||
{
|
||||
uint32_t rtc, rtcss;
|
||||
|
||||
reset_rtc_alarm(&rtc, &rtcss);
|
||||
}
|
||||
DECLARE_IRQ(STM32_IRQ_RTC_ALARM, __rtc_alarm_irq, 1);
|
||||
|
||||
void clock_init(void)
|
||||
{
|
||||
/*
|
||||
* The initial state :
|
||||
* SYSCLK from HSI (=8MHz), no divider on AHB, APB1, APB2
|
||||
* PLL unlocked, RTC enabled on LSE
|
||||
*/
|
||||
|
||||
/*
|
||||
* put 1 Wait-State for flash access to ensure proper reads at 48Mhz
|
||||
* and enable prefetch buffer.
|
||||
*/
|
||||
/* Enable data and instruction cache. */
|
||||
STM32_FLASH_ACR = STM32_FLASH_ACR_LATENCY | STM32_FLASH_ACR_PRFTEN;
|
||||
|
||||
config_hispeed_clock();
|
||||
|
||||
rtc_init();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Console commands */
|
||||
|
||||
#ifdef CONFIG_CMD_RTC_ALARM
|
||||
static int command_rtc_alarm_test(int argc, char **argv)
|
||||
{
|
||||
int s = 1, us = 0;
|
||||
uint32_t rtc, rtcss;
|
||||
char *e;
|
||||
|
||||
ccprintf("Setting RTC alarm\n");
|
||||
|
||||
if (argc > 1) {
|
||||
s = strtoi(argv[1], &e, 10);
|
||||
if (*e)
|
||||
return EC_ERROR_PARAM1;
|
||||
|
||||
}
|
||||
if (argc > 2) {
|
||||
us = strtoi(argv[2], &e, 10);
|
||||
if (*e)
|
||||
return EC_ERROR_PARAM2;
|
||||
|
||||
}
|
||||
|
||||
set_rtc_alarm(s, us, &rtc, &rtcss);
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
DECLARE_CONSOLE_COMMAND(rtc_alarm, command_rtc_alarm_test,
|
||||
"[seconds [microseconds]]",
|
||||
"Test alarm",
|
||||
NULL);
|
||||
#endif /* CONFIG_CMD_RTC_ALARM */
|
||||
|
||||
70
chip/stm32/clock-f.h
Normal file
70
chip/stm32/clock-f.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/* Copyright 2016 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 */
|
||||
|
||||
#ifndef __CROS_EC_CLOCK_F_H
|
||||
#define __CROS_EC_CLOCK_F_H
|
||||
|
||||
#include "chipset.h"
|
||||
#include "clock.h"
|
||||
#include "common.h"
|
||||
#include "console.h"
|
||||
#include "cpu.h"
|
||||
#include "hooks.h"
|
||||
#include "hwtimer.h"
|
||||
#include "registers.h"
|
||||
#include "system.h"
|
||||
#include "task.h"
|
||||
#include "timer.h"
|
||||
#include "util.h"
|
||||
|
||||
/* Lock and unlock RTC write access */
|
||||
static inline void rtc_lock_regs(void)
|
||||
{
|
||||
STM32_RTC_WPR = 0xff;
|
||||
}
|
||||
static inline void rtc_unlock_regs(void)
|
||||
{
|
||||
STM32_RTC_WPR = 0xca;
|
||||
STM32_RTC_WPR = 0x53;
|
||||
}
|
||||
|
||||
/* Convert between RTC regs in BCD and seconds */
|
||||
uint32_t rtc_to_sec(uint32_t rtc);
|
||||
|
||||
/* Convert between seconds and RTC regs */
|
||||
uint32_t sec_to_rtc(uint32_t sec);
|
||||
|
||||
/* Calculate microseconds from rtc clocks. */
|
||||
int32_t rtcss_to_us(uint32_t rtcss);
|
||||
|
||||
/* Calculate rtc clocks from microseconds. */
|
||||
uint32_t us_to_rtcss(int32_t us);
|
||||
|
||||
/* Return time diff between two rtc readings */
|
||||
int32_t get_rtc_diff(uint32_t rtc0, uint32_t rtc0ss,
|
||||
uint32_t rtc1, uint32_t rtc1ss);
|
||||
|
||||
/* Read RTC values */
|
||||
void rtc_read(uint32_t *rtc, uint32_t *rtcss);
|
||||
|
||||
/* Set RTC wakeup */
|
||||
void set_rtc_alarm(uint32_t delay_s, uint32_t delay_us,
|
||||
uint32_t *rtc, uint32_t *rtcss);
|
||||
|
||||
/* Clear RTC wakeup */
|
||||
void reset_rtc_alarm(uint32_t *rtc, uint32_t *rtcss);
|
||||
|
||||
/* RTC init */
|
||||
void rtc_init(void);
|
||||
|
||||
/* Init clock blocks and finctionality */
|
||||
void clock_init(void);
|
||||
|
||||
/* Init high speed clock config */
|
||||
void config_hispeed_clock(void);
|
||||
|
||||
#endif /* __CROS_EC_CLOCK_F_H */
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "chipset.h"
|
||||
#include "clock.h"
|
||||
#include "clock-f.h"
|
||||
#include "common.h"
|
||||
#include "console.h"
|
||||
#include "cpu.h"
|
||||
@@ -74,147 +75,19 @@ static int dsleep_recovery_margin_us = 1000000;
|
||||
#define RTC_PREDIV_A 1
|
||||
#define US_PER_RTC_TICK (1000000 / RTC_FREQ)
|
||||
|
||||
/* Lock and unlock RTC write access */
|
||||
static inline void rtc_lock_regs(void)
|
||||
|
||||
int32_t rtcss_to_us(uint32_t rtcss)
|
||||
{
|
||||
STM32_RTC_WPR = 0xff;
|
||||
}
|
||||
static inline void rtc_unlock_regs(void)
|
||||
{
|
||||
STM32_RTC_WPR = 0xca;
|
||||
STM32_RTC_WPR = 0x53;
|
||||
return ((RTC_PREDIV_S - rtcss) * US_PER_RTC_TICK);
|
||||
}
|
||||
|
||||
/* Convert between RTC regs in BCD and seconds */
|
||||
static inline uint32_t rtc_to_sec(uint32_t rtc)
|
||||
uint32_t us_to_rtcss(int32_t us)
|
||||
{
|
||||
uint32_t sec;
|
||||
|
||||
/* convert the hours field */
|
||||
sec = (((rtc & 0x300000) >> 20) * 10 + ((rtc & 0xf0000) >> 16)) * 3600;
|
||||
/* convert the minutes field */
|
||||
sec += (((rtc & 0x7000) >> 12) * 10 + ((rtc & 0xf00) >> 8)) * 60;
|
||||
/* convert the seconds field */
|
||||
sec += ((rtc & 0x70) >> 4) * 10 + (rtc & 0xf);
|
||||
|
||||
return sec;
|
||||
}
|
||||
static inline uint32_t sec_to_rtc(uint32_t sec)
|
||||
{
|
||||
uint32_t rtc;
|
||||
|
||||
/* convert the hours field */
|
||||
rtc = ((sec / 36000) << 20) | (((sec / 3600) % 10) << 16);
|
||||
/* convert the minutes field */
|
||||
rtc |= (((sec % 3600) / 600) << 12) | (((sec % 600) / 60) << 8);
|
||||
/* convert the seconds field */
|
||||
rtc |= (((sec % 60) / 10) << 4) | (sec % 10);
|
||||
|
||||
return rtc;
|
||||
return (RTC_PREDIV_S - (us / US_PER_RTC_TICK));
|
||||
}
|
||||
|
||||
/* Return time diff between two rtc readings */
|
||||
int32_t get_rtc_diff(uint32_t rtc0, uint32_t rtc0ss,
|
||||
uint32_t rtc1, uint32_t rtc1ss)
|
||||
{
|
||||
int32_t diff;
|
||||
|
||||
/* Note: this only looks at the diff mod 10 seconds */
|
||||
diff = ((rtc1 & 0xf) * SECOND +
|
||||
(RTC_PREDIV_S - rtc1ss) * US_PER_RTC_TICK) -
|
||||
((rtc0 & 0xf) * SECOND +
|
||||
(RTC_PREDIV_S - rtc0ss) * US_PER_RTC_TICK);
|
||||
|
||||
return (diff < 0) ? (diff + 10*SECOND) : diff;
|
||||
}
|
||||
|
||||
static inline void rtc_read(uint32_t *rtc, uint32_t *rtcss)
|
||||
{
|
||||
/* Read current time synchronously */
|
||||
do {
|
||||
*rtc = STM32_RTC_TR;
|
||||
/*
|
||||
* RTC_SSR must be read twice with identical values because
|
||||
* glitches may occur for reads close to the RTCCLK edge.
|
||||
*/
|
||||
do {
|
||||
*rtcss = STM32_RTC_SSR;
|
||||
} while (*rtcss != STM32_RTC_SSR);
|
||||
} while (*rtc != STM32_RTC_TR);
|
||||
}
|
||||
|
||||
void set_rtc_alarm(uint32_t delay_s, uint32_t delay_us,
|
||||
uint32_t *rtc, uint32_t *rtcss)
|
||||
{
|
||||
uint32_t alarm_sec, alarm_us;
|
||||
|
||||
/* Alarm must be within 1 day (86400 seconds) */
|
||||
ASSERT((delay_s + delay_us / SECOND) < 86400);
|
||||
|
||||
rtc_unlock_regs();
|
||||
|
||||
/* Make sure alarm is disabled */
|
||||
STM32_RTC_CR &= ~STM32_RTC_CR_ALRAE;
|
||||
while (!(STM32_RTC_ISR & STM32_RTC_ISR_ALRAWF))
|
||||
;
|
||||
STM32_RTC_ISR &= ~STM32_RTC_ISR_ALRAF;
|
||||
|
||||
rtc_read(rtc, rtcss);
|
||||
|
||||
/* Calculate alarm time */
|
||||
alarm_sec = rtc_to_sec(*rtc) + delay_s;
|
||||
alarm_us = (RTC_PREDIV_S - *rtcss) * US_PER_RTC_TICK + delay_us;
|
||||
alarm_sec = alarm_sec + alarm_us / SECOND;
|
||||
alarm_us = alarm_us % 1000000;
|
||||
/*
|
||||
* If seconds is greater than 1 day, subtract by 1 day to deal with
|
||||
* 24-hour rollover.
|
||||
*/
|
||||
if (alarm_sec >= 86400)
|
||||
alarm_sec -= 86400;
|
||||
|
||||
/* Set alarm time */
|
||||
STM32_RTC_ALRMAR = sec_to_rtc(alarm_sec);
|
||||
STM32_RTC_ALRMASSR = RTC_PREDIV_S - (alarm_us / US_PER_RTC_TICK);
|
||||
/* Check for match on hours, minutes, seconds, and subsecond */
|
||||
STM32_RTC_ALRMAR |= 0xc0000000;
|
||||
STM32_RTC_ALRMASSR |= 0x0f000000;
|
||||
|
||||
/* Enable alarm and alarm interrupt */
|
||||
STM32_EXTI_PR = EXTI_RTC_ALR_EVENT;
|
||||
STM32_EXTI_IMR |= EXTI_RTC_ALR_EVENT;
|
||||
STM32_RTC_CR |= STM32_RTC_CR_ALRAE;
|
||||
|
||||
rtc_lock_regs();
|
||||
}
|
||||
|
||||
void reset_rtc_alarm(uint32_t *rtc, uint32_t *rtcss)
|
||||
{
|
||||
rtc_unlock_regs();
|
||||
|
||||
/* Disable alarm */
|
||||
STM32_RTC_CR &= ~STM32_RTC_CR_ALRAE;
|
||||
STM32_RTC_ISR &= ~STM32_RTC_ISR_ALRAF;
|
||||
|
||||
/* Disable RTC alarm interrupt */
|
||||
STM32_EXTI_IMR &= ~EXTI_RTC_ALR_EVENT;
|
||||
STM32_EXTI_PR = EXTI_RTC_ALR_EVENT;
|
||||
|
||||
/* Read current time */
|
||||
rtc_read(rtc, rtcss);
|
||||
|
||||
rtc_lock_regs();
|
||||
}
|
||||
|
||||
void __rtc_alarm_irq(void)
|
||||
{
|
||||
uint32_t rtc, rtcss;
|
||||
|
||||
reset_rtc_alarm(&rtc, &rtcss);
|
||||
}
|
||||
DECLARE_IRQ(STM32_IRQ_RTC_ALARM, __rtc_alarm_irq, 1);
|
||||
|
||||
static void config_hispeed_clock(void)
|
||||
void config_hispeed_clock(void)
|
||||
{
|
||||
#ifdef CHIP_FAMILY_STM32F3
|
||||
/* Ensure that HSE is ON */
|
||||
@@ -517,58 +390,6 @@ void rtc_init(void)
|
||||
rtc_lock_regs();
|
||||
}
|
||||
|
||||
void clock_init(void)
|
||||
{
|
||||
/*
|
||||
* The initial state :
|
||||
* SYSCLK from HSI (=8MHz), no divider on AHB, APB1, APB2
|
||||
* PLL unlocked, RTC enabled on LSE
|
||||
*/
|
||||
|
||||
/*
|
||||
* put 1 Wait-State for flash access to ensure proper reads at 48Mhz
|
||||
* and enable prefetch buffer.
|
||||
*/
|
||||
STM32_FLASH_ACR = STM32_FLASH_ACR_LATENCY | STM32_FLASH_ACR_PRFTEN;
|
||||
|
||||
config_hispeed_clock();
|
||||
|
||||
rtc_init();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Console commands */
|
||||
|
||||
#ifdef CONFIG_CMD_RTC_ALARM
|
||||
static int command_rtc_alarm_test(int argc, char **argv)
|
||||
{
|
||||
int s = 1, us = 0;
|
||||
uint32_t rtc, rtcss;
|
||||
char *e;
|
||||
|
||||
ccprintf("Setting RTC alarm\n");
|
||||
|
||||
if (argc > 1) {
|
||||
s = strtoi(argv[1], &e, 10);
|
||||
if (*e)
|
||||
return EC_ERROR_PARAM1;
|
||||
|
||||
}
|
||||
if (argc > 2) {
|
||||
us = strtoi(argv[2], &e, 10);
|
||||
if (*e)
|
||||
return EC_ERROR_PARAM2;
|
||||
|
||||
}
|
||||
|
||||
set_rtc_alarm(s, us, &rtc, &rtcss);
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
DECLARE_CONSOLE_COMMAND(rtc_alarm, command_rtc_alarm_test,
|
||||
"[seconds [microseconds]]",
|
||||
"Test alarm",
|
||||
NULL);
|
||||
#endif /* CONFIG_CMD_RTC_ALARM */
|
||||
|
||||
#if defined(CONFIG_LOW_POWER_IDLE) && defined(CONFIG_COMMON_RUNTIME)
|
||||
#ifdef CONFIG_CMD_IDLE_STATS
|
||||
@@ -595,4 +416,3 @@ DECLARE_CONSOLE_COMMAND(idlestats, command_idle_stats,
|
||||
NULL);
|
||||
#endif /* CONFIG_CMD_IDLE_STATS */
|
||||
#endif
|
||||
|
||||
|
||||
254
chip/stm32/clock-stm32f4.c
Normal file
254
chip/stm32/clock-stm32f4.c
Normal file
@@ -0,0 +1,254 @@
|
||||
/* Copyright 2016 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 "chipset.h"
|
||||
#include "clock.h"
|
||||
#include "clock-f.h"
|
||||
#include "common.h"
|
||||
#include "console.h"
|
||||
#include "cpu.h"
|
||||
#include "hooks.h"
|
||||
#include "hwtimer.h"
|
||||
#include "registers.h"
|
||||
#include "system.h"
|
||||
#include "task.h"
|
||||
#include "timer.h"
|
||||
#include "util.h"
|
||||
|
||||
/* Console output macros */
|
||||
#define CPUTS(outstr) cputs(CC_CLOCK, outstr)
|
||||
#define CPRINTS(format, args...) cprints(CC_CLOCK, format, ## args)
|
||||
|
||||
#ifdef CONFIG_STM32_CLOCK_HSE_HZ
|
||||
#define RTC_PREDIV_A 39
|
||||
#define RTC_FREQ ((STM32F4_RTC_REQ) / (RTC_PREDIV_A + 1)) /* Hz */
|
||||
#else
|
||||
/* LSI clock is 40kHz-ish */
|
||||
#define RTC_PREDIV_A 1
|
||||
#define RTC_FREQ (40000 / (RTC_PREDIV_A + 1)) /* Hz */
|
||||
#endif
|
||||
#define RTC_PREDIV_S (RTC_FREQ - 1)
|
||||
#define US_PER_RTC_TICK (1000000 / RTC_FREQ)
|
||||
|
||||
int32_t rtcss_to_us(uint32_t rtcss)
|
||||
{
|
||||
return ((RTC_PREDIV_S - rtcss) * US_PER_RTC_TICK);
|
||||
}
|
||||
|
||||
uint32_t us_to_rtcss(int32_t us)
|
||||
{
|
||||
return (RTC_PREDIV_S - (us / US_PER_RTC_TICK));
|
||||
}
|
||||
|
||||
static void wait_for_ready(volatile uint32_t *cr_reg,
|
||||
uint32_t enable, uint32_t ready)
|
||||
{
|
||||
/* Ensure that clock source is ON */
|
||||
if (!(*cr_reg & ready)) {
|
||||
/* Enable clock */
|
||||
*cr_reg |= enable;
|
||||
/* Wait for ready */
|
||||
while (!(*cr_reg & ready))
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
void config_hispeed_clock(void)
|
||||
{
|
||||
#ifdef CONFIG_STM32_CLOCK_HSE_HZ
|
||||
int srcclock = CONFIG_STM32_CLOCK_HSE_HZ;
|
||||
int clk_check_mask = STM32_RCC_CR_HSERDY;
|
||||
int clk_enable_mask = STM32_RCC_CR_HSEON;
|
||||
#else
|
||||
int srcclock = STM32F4_HSI_CLOCK;
|
||||
int clk_check_mask = STM32_RCC_CR_HSIRDY;
|
||||
int clk_enable_mask = STM32_RCC_CR_HSION;
|
||||
#endif
|
||||
int plldiv, pllinputclock;
|
||||
int pllmult, vcoclock;
|
||||
int systemdivq, systemclock;
|
||||
int usbdiv;
|
||||
int i2sdiv;
|
||||
|
||||
int ahbpre, apb1pre, apb2pre;
|
||||
int rtcdiv = 0;
|
||||
|
||||
/* If PLL is the clock source, PLL has already been set up. */
|
||||
if ((STM32_RCC_CFGR & STM32_RCC_CFGR_SWS_MASK) ==
|
||||
STM32_RCC_CFGR_SWS_PLL)
|
||||
return;
|
||||
|
||||
/* Ensure that HSE/HSI is ON */
|
||||
wait_for_ready(&(STM32_RCC_CR), clk_enable_mask, clk_check_mask);
|
||||
|
||||
/* PLL input must be between 1-2MHz, near 2 */
|
||||
/* Valid values 2-63 */
|
||||
plldiv = (srcclock + STM32F4_PLL_REQ - 1) / STM32F4_PLL_REQ;
|
||||
pllinputclock = srcclock / plldiv;
|
||||
|
||||
/* PLL output clock: Must be 100-432MHz */
|
||||
/* Valid values 50-432, we'll get 336MHz */
|
||||
pllmult = (STM32F4_VCO_CLOCK + (pllinputclock / 2)) / pllinputclock;
|
||||
vcoclock = pllinputclock * pllmult;
|
||||
|
||||
/* CPU/System clock: Below 180MHz */
|
||||
/* We'll do 84MHz */
|
||||
systemclock = vcoclock / 4;
|
||||
systemdivq = 1;
|
||||
/* USB clock = 48MHz exactly */
|
||||
usbdiv = (vcoclock + (STM32F4_USB_REQ / 2)) / STM32F4_USB_REQ;
|
||||
/* SYSTEM/I2S: same system clock */
|
||||
i2sdiv = (vcoclock + (systemclock / 2)) / systemclock;
|
||||
|
||||
/* All IO clocks at 42MHz */
|
||||
/* AHB Prescalar */
|
||||
ahbpre = 0x8; /* AHB = system clock / 2*/
|
||||
/* NOTE: If apbXpre is not 0, timers are x2 clocked. RM0390 Fig. 13 */
|
||||
apb1pre = 0; /* APB1 = AHB */
|
||||
apb2pre = 0; /* APB2 = AHB */
|
||||
|
||||
#ifdef CONFIG_STM32_CLOCK_HSE_HZ
|
||||
/* RTC clock = 1MHz */
|
||||
rtcdiv = (CONFIG_STM32_CLOCK_HSE_HZ + (STM32F4_RTC_REQ / 2))
|
||||
/ STM32F4_RTC_REQ;
|
||||
#endif
|
||||
/* Switch SYSCLK to PLL, setup prescalars.
|
||||
* EC codebase doesn't understand multiple clock domains
|
||||
* so we enforce a clock config that keeps AHB = APB1 = APB2
|
||||
* allowing ec codebase assumptions about consistent clock
|
||||
* rates to remain true.
|
||||
*
|
||||
* NOTE: Sweetberry requires MCO2 <- HSE @ 24MHz
|
||||
* MCO outputs are selected here but are not changeable later.
|
||||
* A CONFIG may be needed if other boards have different MCO
|
||||
* requirements.
|
||||
*/
|
||||
STM32_RCC_CFGR =
|
||||
(2 << 30) | /* MCO2 <- HSE */
|
||||
(0 << 27) | /* MCO2 div / 4 */
|
||||
(6 << 24) | /* MCO1 div / 4 */
|
||||
(3 << 21) | /* MCO1 <- PLL */
|
||||
CFGR_RTCPRE(rtcdiv) |
|
||||
CFGR_PPRE2(apb2pre) |
|
||||
CFGR_PPRE1(apb1pre) |
|
||||
CFGR_HPRE(ahbpre) |
|
||||
STM32_RCC_CFGR_SW_PLL;
|
||||
|
||||
/* Set up PLL */
|
||||
STM32_RCC_PLLCFGR =
|
||||
PLLCFGR_PLLM(plldiv) |
|
||||
PLLCFGR_PLLN(pllmult) |
|
||||
PLLCFGR_PLLP(systemdivq) |
|
||||
#if defined(CONFIG_STM32_CLOCK_HSE_HZ)
|
||||
PLLCFGR_PLLSRC_HSE |
|
||||
#else
|
||||
PLLCFGR_PLLSRC_HSI |
|
||||
#endif
|
||||
PLLCFGR_PLLQ(usbdiv) |
|
||||
PLLCFGR_PLLR(i2sdiv);
|
||||
|
||||
wait_for_ready(&(STM32_RCC_CR),
|
||||
STM32_RCC_CR_PLLON, STM32_RCC_CR_PLLRDY);
|
||||
|
||||
/* Wait until the PLL is the clock source */
|
||||
if ((STM32_RCC_CFGR & STM32_RCC_CFGR_SWS_MASK) ==
|
||||
STM32_RCC_CFGR_SWS_PLL)
|
||||
;
|
||||
|
||||
/* Setup RTC Clock input */
|
||||
STM32_RCC_BDCR |= STM32_RCC_BDCR_BDRST;
|
||||
#ifdef CONFIG_STM32_CLOCK_HSE_HZ
|
||||
STM32_RCC_BDCR = STM32_RCC_BDCR_RTCEN | BCDR_RTCSEL(BDCR_SRC_HSE);
|
||||
#else
|
||||
/* Ensure that LSI is ON */
|
||||
wait_for_ready(&(STM32_RCC_CSR),
|
||||
STM32_RCC_CSR_LSION, STM32_RCC_CSR_LSIRDY);
|
||||
|
||||
STM32_RCC_BDCR = STM32_RCC_BDCR_RTCEN | BCDR_RTCSEL(BDCR_SRC_LSI);
|
||||
#endif
|
||||
}
|
||||
|
||||
int clock_get_freq(void)
|
||||
{
|
||||
return STM32F4_IO_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_DMA_GET_ISR(0);
|
||||
} else { /* APB */
|
||||
while (cycles--)
|
||||
dummy = STM32_USART_BRR(STM32_USART1_BASE);
|
||||
}
|
||||
}
|
||||
|
||||
void clock_enable_module(enum module_id module, int enable)
|
||||
{
|
||||
if (module == MODULE_USB) {
|
||||
if (enable) {
|
||||
STM32_RCC_AHB2ENR |= STM32_RCC_AHB2ENR_OTGFSEN;
|
||||
STM32_RCC_AHB1ENR |= STM32_RCC_AHB1ENR_OTGHSEN |
|
||||
STM32_RCC_AHB1ENR_OTGHSULPIEN;
|
||||
} else {
|
||||
STM32_RCC_AHB2ENR &= ~STM32_RCC_AHB2ENR_OTGFSEN;
|
||||
STM32_RCC_AHB1ENR &= ~STM32_RCC_AHB1ENR_OTGHSEN &
|
||||
~STM32_RCC_AHB1ENR_OTGHSULPIEN;
|
||||
}
|
||||
return;
|
||||
} else if (module == MODULE_I2C) {
|
||||
if (enable) {
|
||||
/* Enable clocks to I2C modules if necessary */
|
||||
STM32_RCC_APB1ENR |=
|
||||
STM32_RCC_I2C1EN | STM32_RCC_I2C2EN
|
||||
| STM32_RCC_I2C3EN | STM32_RCC_FMPI2C4EN;
|
||||
STM32_RCC_DCKCFGR2 =
|
||||
(STM32_RCC_DCKCFGR2 & ~DCKCFGR2_FMPI2C1SEL_MASK)
|
||||
| DCKCFGR2_FMPI2C1SEL(FMPI2C1SEL_APB);
|
||||
} else {
|
||||
STM32_RCC_APB1ENR &=
|
||||
~(STM32_RCC_I2C1EN | STM32_RCC_I2C2EN |
|
||||
STM32_RCC_I2C3EN | STM32_RCC_FMPI2C4EN);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
CPRINTS("Module %d is not supported for clock %s\n",
|
||||
module, enable ? "enable" : "disable");
|
||||
}
|
||||
|
||||
void rtc_init(void)
|
||||
{
|
||||
rtc_unlock_regs();
|
||||
|
||||
/* Enter RTC initialize mode */
|
||||
STM32_RTC_ISR |= STM32_RTC_ISR_INIT;
|
||||
while (!(STM32_RTC_ISR & STM32_RTC_ISR_INITF))
|
||||
;
|
||||
|
||||
/* Set clock prescalars: Needs two separate writes. */
|
||||
STM32_RTC_PRER =
|
||||
(STM32_RTC_PRER & ~STM32_RTC_PRER_S_MASK) | RTC_PREDIV_S;
|
||||
STM32_RTC_PRER =
|
||||
(STM32_RTC_PRER & ~STM32_RTC_PRER_A_MASK)
|
||||
| (RTC_PREDIV_A << 16);
|
||||
|
||||
/* Start RTC timer */
|
||||
STM32_RTC_ISR &= ~STM32_RTC_ISR_INIT;
|
||||
while (STM32_RTC_ISR & STM32_RTC_ISR_INITF)
|
||||
;
|
||||
|
||||
/* Enable RTC alarm interrupt */
|
||||
STM32_RTC_CR |= STM32_RTC_CR_ALRAIE | STM32_RTC_CR_BYPSHAD;
|
||||
STM32_EXTI_RTSR |= EXTI_RTC_ALR_EVENT;
|
||||
task_enable_irq(STM32_IRQ_RTC_ALARM);
|
||||
|
||||
rtc_lock_regs();
|
||||
}
|
||||
63
chip/stm32/config-stm32f446.h
Normal file
63
chip/stm32/config-stm32f446.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/* Copyright 2016 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 */
|
||||
/* Flash physical size is: (512 * 1024)
|
||||
* We are limiting the ec.bin size to 128k to reduce flashing time.
|
||||
*/
|
||||
#define CONFIG_FLASH_SIZE (128 * 1024)
|
||||
#define CONFIG_FLASH_BANK_SIZE (16 * 1024)
|
||||
|
||||
/*
|
||||
* 8 "erase" sectors : 16KB/16KB/16KB/16KB/64KB/128KB/128KB/128KB
|
||||
* We won't use CONFIG_FLASH_ERASE_SIZE, it will be programmatically
|
||||
* set in flash-stm32f4.c. However it must be set or the common flash
|
||||
* code won't build. So we'll set it here.
|
||||
*/
|
||||
#define CONFIG_FLASH_ERASE_SIZE (16 * 1024)
|
||||
|
||||
/* minimum write size for 3.3V. 1 for 1.8V */
|
||||
#define FLASH_WRITE_SIZE_1800 0x0001
|
||||
#define FLASH_WS_DIV_1800 16000000
|
||||
#define FLASH_WRITE_SIZE_3300 0x0004
|
||||
#define FLASH_WS_DIV_3300 30000000
|
||||
#define FLASH_WRITE_SIZE 0x0004
|
||||
|
||||
#define CONFIG_FLASH_WRITE_SIZE FLASH_WRITE_SIZE
|
||||
|
||||
/* No page mode on STM32F, so no benefit to larger write sizes */
|
||||
#define CONFIG_FLASH_WRITE_IDEAL_SIZE FLASH_WRITE_SIZE
|
||||
|
||||
#define CONFIG_RAM_BASE 0x20000000
|
||||
#define CONFIG_RAM_SIZE 0x00020000
|
||||
|
||||
#define CONFIG_RO_MEM_OFF 0
|
||||
#define CONFIG_RO_SIZE (48 * 1024)
|
||||
#define CONFIG_RW_MEM_OFF (64 * 1024)
|
||||
#define CONFIG_RW_SIZE (64 * 1024)
|
||||
|
||||
#define CONFIG_RO_STORAGE_OFF 0
|
||||
#define CONFIG_RW_STORAGE_OFF 0
|
||||
|
||||
#define CONFIG_EC_PROTECTED_STORAGE_OFF 0
|
||||
#define CONFIG_EC_PROTECTED_STORAGE_SIZE CONFIG_RW_MEM_OFF
|
||||
#define CONFIG_EC_WRITABLE_STORAGE_OFF CONFIG_RW_MEM_OFF
|
||||
#define CONFIG_EC_WRITABLE_STORAGE_SIZE \
|
||||
(CONFIG_FLASH_SIZE - CONFIG_EC_WRITABLE_STORAGE_OFF)
|
||||
|
||||
#define CONFIG_WP_STORAGE_OFF CONFIG_EC_PROTECTED_STORAGE_OFF
|
||||
#define CONFIG_WP_STORAGE_SIZE CONFIG_EC_PROTECTED_STORAGE_SIZE
|
||||
|
||||
/* PSTATE lives in one of the smaller blocks. */
|
||||
#define CONFIG_FLASH_PSTATE
|
||||
#define CONFIG_FW_PSTATE_SIZE (16 * 1024)
|
||||
#define CONFIG_FW_PSTATE_OFF (CONFIG_RO_SIZE)
|
||||
|
||||
#undef I2C_PORT_COUNT
|
||||
#define I2C_PORT_COUNT 4
|
||||
|
||||
|
||||
/* Number of IRQ vectors on the NVIC */
|
||||
#define CONFIG_IRQ_COUNT 97
|
||||
@@ -23,12 +23,17 @@
|
||||
#define CHIP_VARIANT_STM32F03X
|
||||
#endif
|
||||
|
||||
/* Number of I2C ports, can be overridden in variant */
|
||||
#define I2C_PORT_COUNT 2
|
||||
|
||||
#if defined(CHIP_VARIANT_STM32L476)
|
||||
#include "config-stm32l476.h"
|
||||
#elif defined(CHIP_VARIANT_STM32L15X)
|
||||
#include "config-stm32l15x.h"
|
||||
#elif defined(CHIP_VARIANT_STM32L100)
|
||||
#include "config-stm32l100.h"
|
||||
#elif defined(CHIP_VARIANT_STM32F446)
|
||||
#include "config-stm32f446.h"
|
||||
#elif defined(CHIP_VARIANT_STM32F373)
|
||||
#include "config-stm32f373.h"
|
||||
#elif defined(CHIP_VARIANT_STM32F09X)
|
||||
@@ -56,8 +61,10 @@
|
||||
/* Program is run directly from storage */
|
||||
#define CONFIG_MAPPED_STORAGE_BASE CONFIG_PROGRAM_MEMORY_BASE
|
||||
|
||||
#if !defined(CHIP_VARIANT_STM32F446)
|
||||
/* Compute the rest of the flash params from these */
|
||||
#include "config_std_internal_flash.h"
|
||||
#endif
|
||||
|
||||
/* System stack size */
|
||||
#if defined(CHIP_VARIANT_STM32F05X)
|
||||
@@ -85,9 +92,6 @@
|
||||
#define HOOK_TICK_INTERVAL_MS 500
|
||||
#define HOOK_TICK_INTERVAL (HOOK_TICK_INTERVAL_MS * MSEC)
|
||||
|
||||
/* Number of I2C ports */
|
||||
#define I2C_PORT_COUNT 2
|
||||
|
||||
/*
|
||||
* Use a timer to print a watchdog warning event before the actual watchdog
|
||||
* timer fires. This is needed on STM32, where the independent watchdog has no
|
||||
|
||||
308
chip/stm32/dma-stm32f4.c
Normal file
308
chip/stm32/dma-stm32f4.c
Normal file
@@ -0,0 +1,308 @@
|
||||
/* Copyright 2016 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 "common.h"
|
||||
#include "console.h"
|
||||
#include "dma.h"
|
||||
#include "hooks.h"
|
||||
#include "registers.h"
|
||||
#include "task.h"
|
||||
#include "timer.h"
|
||||
#include "util.h"
|
||||
|
||||
/* Console output macros */
|
||||
#define CPUTS(outstr) cputs(CC_DMA, outstr)
|
||||
#define CPRINTF(format, args...) cprintf(CC_DMA, format, ## args)
|
||||
|
||||
stm32_dma_regs_t *STM32_DMA_REGS[] = { STM32_DMA1_REGS, STM32_DMA2_REGS };
|
||||
|
||||
/* Callback data to use when IRQ fires */
|
||||
static struct {
|
||||
void (*cb)(void *); /* Callback function to call */
|
||||
void *cb_data; /* Callback data for callback function */
|
||||
} dma_irq[STM32_DMAS_TOTAL_COUNT];
|
||||
|
||||
/**
|
||||
* Return the IRQ for the DMA stream
|
||||
*
|
||||
* @param stream stream number
|
||||
* @return IRQ for the stream
|
||||
*/
|
||||
static int dma_get_irq(enum dma_channel stream)
|
||||
{
|
||||
if (stream < STM32_DMA1_STREAM6)
|
||||
return STM32_IRQ_DMA1_STREAM0 + stream;
|
||||
if (stream == STM32_DMA1_STREAM7)
|
||||
return STM32_IRQ_DMA1_STREAM7;
|
||||
if (stream < STM32_DMA2_STREAM5)
|
||||
return STM32_IRQ_DMA2_STREAM0 + stream - STM32_DMA2_STREAM0;
|
||||
else
|
||||
return STM32_IRQ_DMA2_STREAM5 + stream - STM32_DMA2_STREAM5;
|
||||
}
|
||||
|
||||
stm32_dma_regs_t *dma_get_ctrl(enum dma_channel stream)
|
||||
{
|
||||
return STM32_DMA_REGS[stream / STM32_DMAS_COUNT];
|
||||
}
|
||||
|
||||
stm32_dma_stream_t *dma_get_channel(enum dma_channel stream)
|
||||
{
|
||||
stm32_dma_regs_t *dma = dma_get_ctrl(stream);
|
||||
|
||||
return &dma->stream[stream % STM32_DMAS_COUNT];
|
||||
}
|
||||
|
||||
void dma_disable(enum dma_channel ch)
|
||||
{
|
||||
stm32_dma_stream_t *stream = dma_get_channel(ch);
|
||||
|
||||
if (stream->scr & STM32_DMA_CCR_EN) {
|
||||
stream->scr &= ~STM32_DMA_CCR_EN;
|
||||
while (stream->scr & STM32_DMA_CCR_EN)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
void dma_disable_all(void)
|
||||
{
|
||||
int ch;
|
||||
|
||||
for (ch = 0; ch < STM32_DMAS_TOTAL_COUNT; ch++)
|
||||
dma_disable(ch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare a stream for use and start it
|
||||
*
|
||||
* @param stream stream to read
|
||||
* @param count Number of bytes to transfer
|
||||
* @param periph Pointer to peripheral data register
|
||||
* @param memory Pointer to memory address for receive/transmit
|
||||
* @param flags DMA flags for the control register.
|
||||
*/
|
||||
static void prepare_stream(enum dma_channel stream, unsigned count,
|
||||
void *periph, void *memory, unsigned flags)
|
||||
{
|
||||
stm32_dma_stream_t *dma_stream = dma_get_channel(stream);
|
||||
uint32_t ccr = STM32_DMA_CCR_PL_VERY_HIGH;
|
||||
|
||||
dma_disable(stream);
|
||||
dma_clear_isr(stream);
|
||||
|
||||
/* Following the order in DocID026448 Rev 1 (RM0383) p181 */
|
||||
dma_stream->spar = (uint32_t)periph;
|
||||
dma_stream->sm0ar = (uint32_t)memory;
|
||||
dma_stream->sndtr = count;
|
||||
dma_stream->scr = ccr;
|
||||
ccr |= flags & STM32_DMA_CCR_CHANNEL_MASK;
|
||||
dma_stream->scr = ccr;
|
||||
dma_stream->sfcr &= ~STM32_DMA_SFCR_DMDIS;
|
||||
ccr |= flags;
|
||||
dma_stream->scr = ccr;
|
||||
}
|
||||
|
||||
void dma_go(stm32_dma_stream_t *stream)
|
||||
{
|
||||
/* Flush data in write buffer so that DMA can get the lastest data */
|
||||
asm volatile("dsb;");
|
||||
|
||||
/* Fire it up */
|
||||
stream->scr |= STM32_DMA_CCR_EN;
|
||||
}
|
||||
|
||||
void dma_prepare_tx(const struct dma_option *option, unsigned count,
|
||||
const void *memory)
|
||||
{
|
||||
/*
|
||||
* Cast away const for memory pointer; this is ok because we know
|
||||
* we're preparing the stream for transmit.
|
||||
*/
|
||||
prepare_stream(option->channel, count, option->periph, (void *)memory,
|
||||
STM32_DMA_CCR_MINC | STM32_DMA_CCR_DIR_M2P |
|
||||
option->flags);
|
||||
}
|
||||
|
||||
void dma_start_rx(const struct dma_option *option, unsigned count,
|
||||
void *memory)
|
||||
{
|
||||
stm32_dma_stream_t *stream = dma_get_channel(option->channel);
|
||||
|
||||
prepare_stream(option->channel, count, option->periph, memory,
|
||||
STM32_DMA_CCR_MINC | STM32_DMA_CCR_DIR_P2M |
|
||||
option->flags);
|
||||
dma_go(stream);
|
||||
}
|
||||
|
||||
int dma_bytes_done(stm32_dma_stream_t *stream, int orig_count)
|
||||
{
|
||||
if (!(stream->scr & STM32_DMA_CCR_EN))
|
||||
return 0;
|
||||
return orig_count - stream->sndtr;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DMA_HELP
|
||||
void dma_dump(enum dma_channel stream)
|
||||
{
|
||||
stm32_dma_stream_t *dma_stream = dma_get_channel(stream);
|
||||
|
||||
CPRINTF("scr=%x, sndtr=%x, spar=%x, sm0ar=%x, sfcr=%x\n",
|
||||
dma_stream->scr, dma_stream->sndtr, dma_stream->spar,
|
||||
dma_stream->sm0ar, dma_stream->sfcr);
|
||||
CPRINTF("stream %d, isr=%x, ifcr=%x\n",
|
||||
stream,
|
||||
STM32_DMA_GET_ISR(stream),
|
||||
STM32_DMA_GET_IFCR(stream));
|
||||
}
|
||||
|
||||
void dma_check(enum dma_channel stream, char *buf)
|
||||
{
|
||||
stm32_dma_stream_t *dma_stream = dma_get_channel(stream);
|
||||
int count;
|
||||
int i;
|
||||
|
||||
count = dma_stream->sndtr;
|
||||
CPRINTF("c=%d\n", count);
|
||||
udelay(100 * MSEC);
|
||||
CPRINTF("c=%d\n", dma_stream->sndtr);
|
||||
for (i = 0; i < count; i++)
|
||||
CPRINTF("%02x ", buf[i]);
|
||||
udelay(100 * MSEC);
|
||||
CPRINTF("c=%d\n", dma_stream->sndtr);
|
||||
for (i = 0; i < count; i++)
|
||||
CPRINTF("%02x ", buf[i]);
|
||||
}
|
||||
|
||||
/* Run a check of memory-to-memory DMA */
|
||||
void dma_test(enum dma_channel stream)
|
||||
{
|
||||
stm32_dma_stream_t *dma_stream = dma_get_channel(stream);
|
||||
uint32_t ctrl;
|
||||
char periph[32], memory[32];
|
||||
unsigned count = sizeof(periph);
|
||||
int i;
|
||||
|
||||
memset(memory, '\0', sizeof(memory));
|
||||
for (i = 0; i < count; i++)
|
||||
periph[i] = 10 + i;
|
||||
|
||||
dma_clear_isr(stream);
|
||||
/* Following the order in Doc ID 15965 Rev 5 p194 */
|
||||
dma_stream->spar = (uint32_t)periph;
|
||||
dma_stream->sm0ar = (uint32_t)memory;
|
||||
dma_stream->sndtr = count;
|
||||
dma_stream->sfcr &= ~STM32_DMA_SFCR_DMDIS;
|
||||
ctrl = STM32_DMA_CCR_PL_MEDIUM;
|
||||
dma_stream->scr = ctrl;
|
||||
|
||||
ctrl |= STM32_DMA_CCR_MINC;
|
||||
ctrl |= STM32_DMA_CCR_DIR_M2M;
|
||||
ctrl |= STM32_DMA_CCR_PINC;
|
||||
|
||||
dma_stream->scr = ctrl;
|
||||
dma_dump(stream);
|
||||
dma_stream->scr = ctrl | STM32_DMA_CCR_EN;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
CPRINTF("%d/%d ", periph[i], memory[i]);
|
||||
CPRINTF("\ncount=%d\n", dma_stream->sndtr);
|
||||
dma_dump(stream);
|
||||
}
|
||||
#endif /* CONFIG_DMA_HELP */
|
||||
|
||||
void dma_init(void)
|
||||
{
|
||||
STM32_RCC_AHB1ENR |= STM32_RCC_HB1_DMA1 | STM32_RCC_HB1_DMA2;
|
||||
}
|
||||
|
||||
int dma_wait(enum dma_channel stream)
|
||||
{
|
||||
timestamp_t deadline;
|
||||
|
||||
deadline.val = get_time().val + DMA_TRANSFER_TIMEOUT_US;
|
||||
while ((STM32_DMA_GET_ISR(stream) & STM32_DMA_TCIF) == 0) {
|
||||
if (deadline.val <= get_time().val)
|
||||
return EC_ERROR_TIMEOUT;
|
||||
|
||||
udelay(DMA_POLLING_INTERVAL_US);
|
||||
}
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
static inline void _dma_wake_callback(void *cb_data)
|
||||
{
|
||||
task_id_t id = (task_id_t)(int)cb_data;
|
||||
|
||||
if (id != TASK_ID_INVALID)
|
||||
task_set_event(id, TASK_EVENT_DMA_TC, 0);
|
||||
}
|
||||
|
||||
void dma_enable_tc_interrupt(enum dma_channel stream)
|
||||
{
|
||||
dma_enable_tc_interrupt_callback(stream, _dma_wake_callback,
|
||||
(void *)(int)task_get_current());
|
||||
}
|
||||
|
||||
void dma_enable_tc_interrupt_callback(enum dma_channel stream,
|
||||
void (*callback)(void *),
|
||||
void *callback_data)
|
||||
{
|
||||
stm32_dma_stream_t *dma_stream = dma_get_channel(stream);
|
||||
|
||||
dma_irq[stream].cb = callback;
|
||||
dma_irq[stream].cb_data = callback_data;
|
||||
|
||||
dma_stream->scr |= STM32_DMA_CCR_TCIE;
|
||||
task_enable_irq(dma_get_irq(stream));
|
||||
}
|
||||
|
||||
void dma_disable_tc_interrupt(enum dma_channel stream)
|
||||
{
|
||||
stm32_dma_stream_t *dma_stream = dma_get_channel(stream);
|
||||
|
||||
dma_stream->scr &= ~STM32_DMA_CCR_TCIE;
|
||||
task_disable_irq(dma_get_irq(stream));
|
||||
|
||||
dma_irq[stream].cb = NULL;
|
||||
dma_irq[stream].cb_data = NULL;
|
||||
}
|
||||
|
||||
void dma_clear_isr(enum dma_channel stream)
|
||||
{
|
||||
STM32_DMA_SET_IFCR(stream, STM32_DMA_ALL);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DMA_DEFAULT_HANDLERS
|
||||
#define STM32_DMA_IDX(dma, x) CONCAT4(STM32_DMA, dma, _STREAM, x)
|
||||
#define STM32_DMA_FCT(dma, x) CONCAT4(dma_, dma, _event_interrupt_stream_, x)
|
||||
#define DECLARE_DMA_IRQ(dma, x) \
|
||||
void STM32_DMA_FCT(dma, x)(void) \
|
||||
{ \
|
||||
dma_clear_isr(STM32_DMA_IDX(dma, x)); \
|
||||
if (dma_irq[STM32_DMA_IDX(dma, x)].cb != NULL) \
|
||||
(*dma_irq[STM32_DMA_IDX(dma, x)].cb) \
|
||||
(dma_irq[STM32_DMA_IDX(dma, x)].cb_data); \
|
||||
} \
|
||||
DECLARE_IRQ(CONCAT4(STM32_IRQ_DMA, dma, _STREAM, x), \
|
||||
STM32_DMA_FCT(dma, x), 1);
|
||||
|
||||
DECLARE_DMA_IRQ(1, 0);
|
||||
DECLARE_DMA_IRQ(1, 1);
|
||||
DECLARE_DMA_IRQ(1, 2);
|
||||
DECLARE_DMA_IRQ(1, 3);
|
||||
DECLARE_DMA_IRQ(1, 4);
|
||||
DECLARE_DMA_IRQ(1, 5);
|
||||
DECLARE_DMA_IRQ(1, 6);
|
||||
DECLARE_DMA_IRQ(1, 7);
|
||||
DECLARE_DMA_IRQ(2, 0);
|
||||
DECLARE_DMA_IRQ(2, 1);
|
||||
DECLARE_DMA_IRQ(2, 2);
|
||||
DECLARE_DMA_IRQ(2, 3);
|
||||
DECLARE_DMA_IRQ(2, 4);
|
||||
DECLARE_DMA_IRQ(2, 5);
|
||||
DECLARE_DMA_IRQ(2, 6);
|
||||
DECLARE_DMA_IRQ(2, 7);
|
||||
|
||||
#endif /* CONFIG_DMA_DEFAULT_HANDLERS */
|
||||
|
||||
@@ -73,6 +73,20 @@ void dma_select_channel(enum dma_channel channel, unsigned char stream)
|
||||
val = STM32_DMA_CSELR(channel) & ~(mask << ch * shift);
|
||||
STM32_DMA_CSELR(channel) = val | (stream << ch * shift);
|
||||
}
|
||||
#elif defined(CHIP_FAMILY_STM32F4)
|
||||
void dma_select_channel(enum dma_channel channel, unsigned char stream)
|
||||
{
|
||||
stm32_dma_chan_t *chan = dma_get_channel(channel);
|
||||
uint32_t val;
|
||||
|
||||
ASSERT(channel < STM32_DMAC_COUNT);
|
||||
ASSERT(stream < STM32_DMA_MAX_STREAMS);
|
||||
|
||||
/* Set stream input for channel */
|
||||
val = chan->ccr &
|
||||
~(STM32_DMA_CCR_CHMASK << STM32_DMA_CCR_CHOFF);
|
||||
chan->ccr = val | (stream << STM32_DMA_CCR_CHOFF);
|
||||
}
|
||||
#endif
|
||||
|
||||
void dma_disable(enum dma_channel channel)
|
||||
@@ -230,7 +244,7 @@ void dma_test(enum dma_channel channel)
|
||||
|
||||
void dma_init(void)
|
||||
{
|
||||
#ifdef CHIP_FAMILY_STM32L4
|
||||
#if defined(CHIP_FAMILY_STM32L4) || defined(CHIP_FAMILY_STM32F4)
|
||||
STM32_RCC_AHB1ENR |= STM32_RCC_AHB1ENR_DMA1EN|STM32_RCC_AHB1ENR_DMA2EN;
|
||||
#else
|
||||
STM32_RCC_AHBENR |= STM32_RCC_HB_DMA1;
|
||||
@@ -244,6 +258,19 @@ void dma_init(void)
|
||||
|
||||
int dma_wait(enum dma_channel channel)
|
||||
{
|
||||
#if defined(CHIP_FAMILY_STM32F4)
|
||||
timestamp_t deadline;
|
||||
|
||||
deadline.val = get_time().val + DMA_TRANSFER_TIMEOUT_US;
|
||||
|
||||
/* Wait for TCIF completion */
|
||||
while ((STM32_DMA_GET_ISR(channel) & STM32_DMA_TCIF) == 0) {
|
||||
if (deadline.val <= get_time().val)
|
||||
return EC_ERROR_TIMEOUT;
|
||||
|
||||
udelay(DMA_POLLING_INTERVAL_US);
|
||||
}
|
||||
#else
|
||||
stm32_dma_regs_t *dma = STM32_DMA_REGS(channel);
|
||||
const uint32_t mask = STM32_DMA_ISR_TCIF(channel);
|
||||
timestamp_t deadline;
|
||||
@@ -255,6 +282,7 @@ int dma_wait(enum dma_channel channel)
|
||||
|
||||
udelay(DMA_POLLING_INTERVAL_US);
|
||||
}
|
||||
#endif
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -297,9 +325,13 @@ void dma_disable_tc_interrupt(enum dma_channel channel)
|
||||
|
||||
void dma_clear_isr(enum dma_channel channel)
|
||||
{
|
||||
#if defined(CHIP_FAMILY_STM32F4)
|
||||
STM32_DMA_SET_IFCR(channel, STM32_DMA_ALL);
|
||||
#else
|
||||
stm32_dma_regs_t *dma = STM32_DMA_REGS(channel);
|
||||
|
||||
dma->ifcr |= STM32_DMA_ISR_ALL(channel);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DMA_DEFAULT_HANDLERS
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "battery.h"
|
||||
#include "console.h"
|
||||
#include "clock.h"
|
||||
#include "flash.h"
|
||||
#include "hooks.h"
|
||||
#include "registers.h"
|
||||
@@ -25,8 +26,6 @@
|
||||
|
||||
/* Flash page programming timeout. This is 2x the datasheet max. */
|
||||
#define FLASH_TIMEOUT_US 16000
|
||||
#define FLASH_TIMEOUT_LOOP \
|
||||
(FLASH_TIMEOUT_US * (CPU_CLOCK / SECOND) / CYCLE_PER_FLASH_LOOP)
|
||||
|
||||
/* Flash unlocking keys */
|
||||
#define KEY1 0x45670123
|
||||
@@ -44,9 +43,15 @@
|
||||
|
||||
static int write_optb(int byte, uint8_t value);
|
||||
|
||||
static inline int calculate_flash_timeout(void)
|
||||
{
|
||||
return (FLASH_TIMEOUT_US *
|
||||
(clock_get_freq() / SECOND) / CYCLE_PER_FLASH_LOOP);
|
||||
}
|
||||
|
||||
static int wait_busy(void)
|
||||
{
|
||||
int timeout = FLASH_TIMEOUT_LOOP;
|
||||
int timeout = calculate_flash_timeout();
|
||||
while (STM32_FLASH_SR & (1 << 0) && timeout-- > 0)
|
||||
udelay(CYCLE_PER_FLASH_LOOP);
|
||||
return (timeout > 0) ? EC_SUCCESS : EC_ERROR_TIMEOUT;
|
||||
@@ -207,6 +212,7 @@ int flash_physical_write(int offset, int size, const char *data)
|
||||
{
|
||||
uint16_t *address = (uint16_t *)(CONFIG_PROGRAM_MEMORY_BASE + offset);
|
||||
int res = EC_SUCCESS;
|
||||
int timeout = calculate_flash_timeout();
|
||||
int i;
|
||||
|
||||
if (unlock(PRG_LOCK) != EC_SUCCESS) {
|
||||
@@ -228,7 +234,7 @@ int flash_physical_write(int offset, int size, const char *data)
|
||||
watchdog_reload();
|
||||
|
||||
/* wait to be ready */
|
||||
for (i = 0; (STM32_FLASH_SR & 1) && (i < FLASH_TIMEOUT_LOOP);
|
||||
for (i = 0; (STM32_FLASH_SR & 1) && (i < timeout);
|
||||
i++)
|
||||
;
|
||||
|
||||
@@ -237,7 +243,7 @@ int flash_physical_write(int offset, int size, const char *data)
|
||||
data += 2;
|
||||
|
||||
/* Wait for writes to complete */
|
||||
for (i = 0; (STM32_FLASH_SR & 1) && (i < FLASH_TIMEOUT_LOOP);
|
||||
for (i = 0; (STM32_FLASH_SR & 1) && (i < timeout);
|
||||
i++)
|
||||
;
|
||||
|
||||
|
||||
384
chip/stm32/flash-stm32f4.c
Normal file
384
chip/stm32/flash-stm32f4.c
Normal file
@@ -0,0 +1,384 @@
|
||||
/* Copyright 2016 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 stm32f4 */
|
||||
|
||||
#include "clock.h"
|
||||
#include "compile_time_macros.h"
|
||||
#include "console.h"
|
||||
#include "common.h"
|
||||
#include "flash.h"
|
||||
#include "hooks.h"
|
||||
#include "registers.h"
|
||||
#include "system.h"
|
||||
#include "panic.h"
|
||||
#include "watchdog.h"
|
||||
|
||||
|
||||
#define CPRINTS(format, args...) cprints(CC_CLOCK, format, ## args)
|
||||
|
||||
/*
|
||||
* Approximate number of CPU cycles per iteration of the loop when polling
|
||||
* the flash status
|
||||
*/
|
||||
#define CYCLE_PER_FLASH_LOOP 10
|
||||
|
||||
/* Flash page programming timeout. This is 2x the datasheet max. */
|
||||
#define FLASH_TIMEOUT_US 16000
|
||||
|
||||
static inline int calculate_flash_timeout(void)
|
||||
{
|
||||
return (FLASH_TIMEOUT_US *
|
||||
(clock_get_freq() / SECOND) / CYCLE_PER_FLASH_LOOP);
|
||||
}
|
||||
|
||||
|
||||
/* 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 */
|
||||
struct flash_wp_state {
|
||||
int entire_flash_locked;
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Physical layer APIs */
|
||||
|
||||
/* Flash unlocking keys */
|
||||
#define PRG_LOCK 0
|
||||
#define KEY1 0x45670123
|
||||
#define KEY2 0xCDEF89AB
|
||||
|
||||
static int unlock(void)
|
||||
{
|
||||
/*
|
||||
* We may have already locked the flash module and get a bus fault
|
||||
* in the attempt to unlock. Need to disable bus fault handler now.
|
||||
*/
|
||||
ignore_bus_fault(1);
|
||||
|
||||
/* unlock CR if needed */
|
||||
if (STM32_FLASH_CR & FLASH_CR_LOCK) {
|
||||
STM32_FLASH_KEYR = KEY1;
|
||||
STM32_FLASH_KEYR = KEY2;
|
||||
}
|
||||
|
||||
/* Re-enable bus fault handler */
|
||||
ignore_bus_fault(0);
|
||||
|
||||
return (STM32_FLASH_CR & FLASH_CR_LOCK) ?
|
||||
EC_ERROR_UNKNOWN : EC_SUCCESS;
|
||||
}
|
||||
|
||||
static void lock(void)
|
||||
{
|
||||
STM32_FLASH_CR = FLASH_CR_LOCK;
|
||||
}
|
||||
|
||||
|
||||
int flash_physical_get_protect(int block)
|
||||
{
|
||||
/* TODO: not sure if write protect can be implemented like this. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t flash_physical_get_protect_flags(void)
|
||||
{
|
||||
return entire_flash_locked ? EC_FLASH_PROTECT_ALL_NOW : 0;
|
||||
}
|
||||
|
||||
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.
|
||||
*
|
||||
* This incorrect key fault causes the flash to become
|
||||
* permanenlty locked until reset, a correct keyring write
|
||||
* will not unlock it. In this way we can implement system
|
||||
* write protect.
|
||||
*/
|
||||
ignore_bus_fault(1);
|
||||
STM32_FLASH_KEYR = 0xffffffff;
|
||||
ignore_bus_fault(0);
|
||||
|
||||
entire_flash_locked = 1;
|
||||
|
||||
/* Check if lock happened */
|
||||
if (STM32_FLASH_CR & FLASH_CR_LOCK)
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
static int flash_idle(void)
|
||||
{
|
||||
timestamp_t deadline;
|
||||
|
||||
deadline.val = get_time().val + FLASH_TIMEOUT_US;
|
||||
/* Wait for flash op to complete.
|
||||
* This function is used for both reads and writes, so
|
||||
* we need a long timeout, but a relatively short poll interval.
|
||||
*/
|
||||
while ((STM32_FLASH_SR & FLASH_SR_BUSY) &&
|
||||
(get_time().val < deadline.val)) {
|
||||
usleep(1);
|
||||
}
|
||||
|
||||
if (STM32_FLASH_SR & FLASH_SR_BUSY)
|
||||
return EC_ERROR_TIMEOUT;
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
static void clear_flash_errors(void)
|
||||
{
|
||||
/* Clear previous error status */
|
||||
STM32_FLASH_SR = FLASH_SR_ERR_MASK;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Physical layer APIs */
|
||||
|
||||
int flash_physical_protect_at_boot(enum flash_wp_range range)
|
||||
{
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
int flash_physical_write(int offset, int size, const char *data)
|
||||
{
|
||||
uint32_t *address = (uint32_t *)(CONFIG_MAPPED_STORAGE_BASE + offset);
|
||||
int res = EC_SUCCESS;
|
||||
|
||||
if (unlock() != EC_SUCCESS) {
|
||||
res = EC_ERROR_UNKNOWN;
|
||||
goto exit_wr;
|
||||
}
|
||||
|
||||
/* Wait for busy to clear */
|
||||
res = flash_idle();
|
||||
if (res)
|
||||
goto exit_wr;
|
||||
clear_flash_errors();
|
||||
|
||||
/* set PG bit */
|
||||
STM32_FLASH_CR &= ~FLASH_CR_PSIZE_MASK;
|
||||
STM32_FLASH_CR |= FLASH_CR_PSIZE(FLASH_CR_PSIZE_32);
|
||||
STM32_FLASH_CR |= FLASH_CR_PG;
|
||||
|
||||
for (; size > 0; size -= sizeof(uint32_t)) {
|
||||
/*
|
||||
* Reload the watchdog timer to avoid watchdog reset when doing
|
||||
* long writing with interrupt disabled.
|
||||
*/
|
||||
watchdog_reload();
|
||||
|
||||
res = flash_idle();
|
||||
if (res)
|
||||
goto exit_wr;
|
||||
|
||||
/* write the word */
|
||||
*address = data[0] + (data[1] << 8) +
|
||||
(data[2] << 16) + (data[3] << 24);
|
||||
|
||||
address++;
|
||||
data += sizeof(uint32_t);
|
||||
|
||||
res = flash_idle();
|
||||
if (res)
|
||||
goto exit_wr;
|
||||
|
||||
if (STM32_FLASH_SR & FLASH_SR_BUSY) {
|
||||
res = EC_ERROR_TIMEOUT;
|
||||
goto exit_wr;
|
||||
}
|
||||
|
||||
/* Check for error conditions - erase failed, voltage error,
|
||||
* protection error.
|
||||
*/
|
||||
if (STM32_FLASH_SR & FLASH_SR_ERR_MASK) {
|
||||
res = EC_ERROR_UNKNOWN;
|
||||
goto exit_wr;
|
||||
}
|
||||
}
|
||||
|
||||
exit_wr:
|
||||
/* Disable PG bit */
|
||||
STM32_FLASH_CR &= ~FLASH_CR_PG;
|
||||
|
||||
lock();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* "@Internal Flash /0x08000000/04*016Kg,01*064Kg,03*128Kg" */
|
||||
struct flash_sector {
|
||||
int base;
|
||||
int size;
|
||||
};
|
||||
static const struct flash_sector sectors[] = {
|
||||
{(0 * 1024), (16 * 1024)},
|
||||
{(16 * 1024), (16 * 1024)},
|
||||
{(32 * 1024), (16 * 1024)},
|
||||
{(48 * 1024), (16 * 1024)},
|
||||
{(64 * 1024), (64 * 1024)},
|
||||
{(128 * 1024), (128 * 1024)},
|
||||
{(256 * 1024), (128 * 1024)},
|
||||
{(384 * 1024), (128 * 1024)}
|
||||
};
|
||||
static const int num_sectors = ARRAY_SIZE(sectors);
|
||||
|
||||
int flash_physical_erase(int offset, int size)
|
||||
{
|
||||
int res = EC_SUCCESS;
|
||||
int start_sector;
|
||||
int end_sector;
|
||||
|
||||
/* Check that offset/size align with sectors. */
|
||||
for (start_sector = 0; start_sector < num_sectors; start_sector++)
|
||||
if (offset == sectors[start_sector].base)
|
||||
break;
|
||||
for (end_sector = start_sector; end_sector < num_sectors; end_sector++)
|
||||
if ((offset + size) ==
|
||||
(sectors[end_sector].base + sectors[end_sector].size))
|
||||
break;
|
||||
|
||||
/* We can only erase on sector boundaries. */
|
||||
if ((start_sector >= num_sectors) || (end_sector >= num_sectors))
|
||||
return EC_ERROR_PARAM1;
|
||||
|
||||
if (unlock() != EC_SUCCESS)
|
||||
return EC_ERROR_UNKNOWN;
|
||||
|
||||
res = flash_idle();
|
||||
if (res)
|
||||
goto exit_er;
|
||||
|
||||
clear_flash_errors();
|
||||
|
||||
for (; start_sector <= end_sector; start_sector++) {
|
||||
/* Do nothing if already erased */
|
||||
if (flash_is_erased(sectors[start_sector].base,
|
||||
sectors[start_sector].size))
|
||||
continue;
|
||||
|
||||
res = flash_idle();
|
||||
if (res)
|
||||
goto exit_er;
|
||||
|
||||
/* set Sector Erase bit and select sector */
|
||||
STM32_FLASH_CR = (STM32_FLASH_CR & ~FLASH_CR_SNB_MASK) |
|
||||
FLASH_CR_SER | FLASH_CR_SNB(start_sector);
|
||||
|
||||
/* set STRT bit : start erase */
|
||||
STM32_FLASH_CR |= FLASH_CR_STRT;
|
||||
|
||||
/*
|
||||
* Reload the watchdog timer to avoid watchdog reset during a
|
||||
* long erase operation.
|
||||
*/
|
||||
watchdog_reload();
|
||||
|
||||
/* Wait for erase to complete, this will be awhile */
|
||||
res = flash_idle();
|
||||
if (res)
|
||||
goto exit_er;
|
||||
/*
|
||||
* Check for error conditions - erase failed, voltage error,
|
||||
* protection error
|
||||
*/
|
||||
if (STM32_FLASH_SR & FLASH_SR_ERR_MASK) {
|
||||
res = EC_ERROR_UNKNOWN;
|
||||
goto exit_er;
|
||||
}
|
||||
}
|
||||
|
||||
exit_er:
|
||||
/* reset PER bit */
|
||||
STM32_FLASH_CR &= ~FLASH_CR_SER;
|
||||
|
||||
lock();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* High-level APIs */
|
||||
|
||||
int flash_pre_init(void)
|
||||
{
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* 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);
|
||||
|
||||
26
chip/stm32/gpio-stm32f4.c
Normal file
26
chip/stm32/gpio-stm32f4.c
Normal file
@@ -0,0 +1,26 @@
|
||||
/* Copyright 2016 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 "registers.h"
|
||||
|
||||
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.
|
||||
*/
|
||||
STM32_RCC_AHB1ENR |= STM32_RCC_AHB1ENR_GPIOMASK;
|
||||
|
||||
/* Delay 1 AHB clock cycle after the clock is enabled */
|
||||
clock_wait_bus_cycles(BUS_AHB, 1);
|
||||
}
|
||||
|
||||
#include "gpio-f0-l.c"
|
||||
@@ -27,7 +27,7 @@ void gpio_pre_init(void)
|
||||
int i;
|
||||
|
||||
/* Required to configure external IRQ lines (SYSCFG_EXTICRn) */
|
||||
STM32_RCC_APB2ENR |= 1 << 0;
|
||||
STM32_RCC_APB2ENR |= STM32_RCC_SYSCFGEN;
|
||||
|
||||
/* Delay 1 APB clock cycle after the clock is enabled */
|
||||
clock_wait_bus_cycles(BUS_APB, 1);
|
||||
|
||||
17
chip/stm32/jtag-stm32f4.c
Normal file
17
chip/stm32/jtag-stm32f4.c
Normal file
@@ -0,0 +1,17 @@
|
||||
/* Copyright 2016 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 all timers we might use (TIM1-8) and watchdogs when
|
||||
* the JTAG stops the CPU.
|
||||
*/
|
||||
/* TODO(nsanders): Implement this if someone needs jtag. */
|
||||
}
|
||||
@@ -121,6 +121,8 @@
|
||||
#define STM32_IRQ_TIM14 45 /* STM32F373 only */
|
||||
#define STM32_IRQ_TIM5 50 /* STM32F373 */
|
||||
#define STM32_IRQ_SPI3 51 /* STM32F373 */
|
||||
#define STM32_IRQ_USART4 52 /* STM32F446 only */
|
||||
#define STM32_IRQ_USART5 53 /* STM32F446 only */
|
||||
#define STM32_IRQ_TIM6_DAC 54 /* STM32F373 */
|
||||
#define STM32_IRQ_TIM7 55 /* STM32F373 */
|
||||
#define STM32_IRQ_DMA2_CHANNEL1 56 /* STM32F373 */
|
||||
@@ -136,6 +138,9 @@
|
||||
#define STM32_IRQ_DMA2_CHANNEL7 69 /* STM32L4 only */
|
||||
#define STM32_IRQ_LPUART 70 /* STM32L4 only */
|
||||
#define STM32_IRQ_USART9 70 /* STM32L4 only */
|
||||
#define STM32_IRQ_USART6 71 /* STM32F446 only */
|
||||
#define STM32_IRQ_I2C3_EV 72 /* STM32F446 only */
|
||||
#define STM32_IRQ_I2C3_ER 73 /* STM32F446 only */
|
||||
#define STM32_IRQ_USB_WAKEUP 76 /* STM32F373 only */
|
||||
#define STM32_IRQ_TIM19 78 /* STM32F373 only */
|
||||
#define STM32_IRQ_FPU 81 /* STM32F373 only */
|
||||
@@ -149,16 +154,57 @@
|
||||
/* aliases for easier code sharing */
|
||||
#define STM32_IRQ_I2C1 STM32_IRQ_I2C1_EV
|
||||
#define STM32_IRQ_I2C2 STM32_IRQ_I2C2_EV
|
||||
#define STM32_IRQ_I2C3 STM32_IRQ_I2C3_EV
|
||||
#endif /* !CHIP_FAMILY_STM32F0 */
|
||||
|
||||
#ifdef CHIP_FAMILY_STM32F4
|
||||
/*
|
||||
* STM32F4 introduces a concept of DMA stream to allow
|
||||
* fine allocation of a stream to a channel.
|
||||
*/
|
||||
#define STM32_IRQ_DMA1_STREAM0 11
|
||||
#define STM32_IRQ_DMA1_STREAM1 12
|
||||
#define STM32_IRQ_DMA1_STREAM2 13
|
||||
#define STM32_IRQ_DMA1_STREAM3 14
|
||||
#define STM32_IRQ_DMA1_STREAM4 15
|
||||
#define STM32_IRQ_DMA1_STREAM5 16
|
||||
#define STM32_IRQ_DMA1_STREAM6 17
|
||||
#define STM32_IRQ_DMA1_STREAM7 47
|
||||
#define STM32_IRQ_DMA2_STREAM0 56
|
||||
#define STM32_IRQ_DMA2_STREAM1 57
|
||||
#define STM32_IRQ_DMA2_STREAM2 58
|
||||
#define STM32_IRQ_DMA2_STREAM3 59
|
||||
#define STM32_IRQ_DMA2_STREAM4 60
|
||||
#define STM32_IRQ_DMA2_STREAM5 68
|
||||
#define STM32_IRQ_DMA2_STREAM6 69
|
||||
#define STM32_IRQ_DMA2_STREAM7 70
|
||||
|
||||
#define STM32_IRQ_OTG_HS_WKUP 76
|
||||
#define STM32_IRQ_OTG_HS_EP1_IN 75
|
||||
#define STM32_IRQ_OTG_HS_EP1_OUT 74
|
||||
#define STM32_IRQ_OTG_HS 77
|
||||
#define STM32_IRQ_OTG_FS 67
|
||||
#define STM32_IRQ_OTG_FS_WKUP 42
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
/* --- USART --- */
|
||||
#if defined(CHIP_FAMILY_STM32F4)
|
||||
#define STM32_USART1_BASE 0x40011000
|
||||
#define STM32_USART2_BASE 0x40004400
|
||||
#define STM32_USART3_BASE 0x40004800
|
||||
#define STM32_USART4_BASE 0x40004c00
|
||||
#define STM32_USART5_BASE 0x40005000
|
||||
#define STM32_USART6_BASE 0x40011400
|
||||
#else
|
||||
#define STM32_USART1_BASE 0x40013800
|
||||
#define STM32_USART2_BASE 0x40004400
|
||||
#define STM32_USART3_BASE 0x40004800
|
||||
#define STM32_USART4_BASE 0x40004c00
|
||||
#define STM32_USART9_BASE 0x40008000 /* LPUART */
|
||||
#endif
|
||||
|
||||
#define STM32_USART_BASE(n) CONCAT3(STM32_USART, n, _BASE)
|
||||
#define STM32_USART_REG(base, offset) REG32((base) + (offset))
|
||||
@@ -218,6 +264,7 @@
|
||||
#define STM32_USART_CR1_OVER8 (1 << 15) /* STM32L only */
|
||||
#define STM32_USART_CR2(base) STM32_USART_REG(base, 0x10)
|
||||
#define STM32_USART_CR3(base) STM32_USART_REG(base, 0x14)
|
||||
#define STM32_USART_CR3_EIE (1 << 0)
|
||||
#define STM32_USART_CR3_DMAR (1 << 6)
|
||||
#define STM32_USART_CR3_DMAT (1 << 7)
|
||||
#define STM32_USART_CR3_ONEBIT (1 << 11) /* STM32L only */
|
||||
@@ -403,6 +450,28 @@ typedef volatile struct timer_ctlr timer_ctlr_t;
|
||||
#define GPIO_ALT_FE 0xE
|
||||
#define GPIO_ALT_FF 0xF
|
||||
|
||||
#elif defined(CHIP_FAMILY_STM32F4)
|
||||
|
||||
#define STM32_GPIOA_BASE 0x40020000
|
||||
#define STM32_GPIOB_BASE 0x40020400
|
||||
#define STM32_GPIOC_BASE 0x40020800
|
||||
#define STM32_GPIOD_BASE 0x40020C00
|
||||
#define STM32_GPIOE_BASE 0x40021000
|
||||
#define STM32_GPIOF_BASE 0x40021400
|
||||
#define STM32_GPIOG_BASE 0x40021800
|
||||
#define STM32_GPIOH_BASE 0x40021C00
|
||||
|
||||
#define STM32_GPIO_MODER(b) REG32((b) + 0x00)
|
||||
#define STM32_GPIO_OTYPER(b) REG16((b) + 0x04)
|
||||
#define STM32_GPIO_OSPEEDR(b) REG32((b) + 0x08)
|
||||
#define STM32_GPIO_PUPDR(b) REG32((b) + 0x0C)
|
||||
#define STM32_GPIO_IDR(b) REG16((b) + 0x10)
|
||||
#define STM32_GPIO_ODR(b) REG16((b) + 0x14)
|
||||
#define STM32_GPIO_BSRR(b) REG32((b) + 0x18)
|
||||
#define STM32_GPIO_LCKR(b) REG32((b) + 0x1C)
|
||||
#define STM32_GPIO_AFRL(b) REG32((b) + 0x20)
|
||||
#define STM32_GPIO_AFRH(b) REG32((b) + 0x24)
|
||||
|
||||
#else
|
||||
#error Unsupported chip variant
|
||||
#endif
|
||||
@@ -410,9 +479,13 @@ typedef volatile struct timer_ctlr timer_ctlr_t;
|
||||
/* --- I2C --- */
|
||||
#define STM32_I2C1_BASE 0x40005400
|
||||
#define STM32_I2C2_BASE 0x40005800
|
||||
#define STM32_I2C3_BASE 0x40005C00
|
||||
#define STM32_I2C4_BASE 0x40006000
|
||||
|
||||
#define STM32_I2C1_PORT 0
|
||||
#define STM32_I2C2_PORT 1
|
||||
#define STM32_I2C3_PORT 2
|
||||
#define STM32_FMPI2C4_PORT 3
|
||||
|
||||
#define stm32_i2c_reg(port, offset) \
|
||||
((uint16_t *)((STM32_I2C1_BASE + ((port) * 0x400)) + (offset)))
|
||||
@@ -477,6 +550,8 @@ typedef volatile struct timer_ctlr timer_ctlr_t;
|
||||
#define STM32_I2C_CR1_POS (1 << 11)
|
||||
#define STM32_I2C_CR1_SWRST (1 << 15)
|
||||
#define STM32_I2C_CR2(n) REG16(stm32_i2c_reg(n, 0x04))
|
||||
#define STM32_I2C_CR2_LAST (1 << 12)
|
||||
#define STM32_I2C_CR2_DMAEN (1 << 11)
|
||||
#define STM32_I2C_OAR1(n) REG16(stm32_i2c_reg(n, 0x08))
|
||||
#define STM32_I2C_OAR2(n) REG16(stm32_i2c_reg(n, 0x0C))
|
||||
#define STM32_I2C_DR(n) REG16(stm32_i2c_reg(n, 0x10))
|
||||
@@ -494,9 +569,58 @@ typedef volatile struct timer_ctlr timer_ctlr_t;
|
||||
#define STM32_I2C_SR2_BUSY (1 << 1)
|
||||
|
||||
#define STM32_I2C_CCR(n) REG16(stm32_i2c_reg(n, 0x1C))
|
||||
#define STM32_I2C_CCR_DUTY (1 << 14)
|
||||
#define STM32_I2C_CCR_FM (1 << 15)
|
||||
#define STM32_I2C_TRISE(n) REG16(stm32_i2c_reg(n, 0x20))
|
||||
#endif /* !CHIP_FAMILY_STM32F0 && !CHIP_FAMILY_STM32F3 */
|
||||
|
||||
|
||||
#if defined(CHIP_FAMILY_STM32F4)
|
||||
#define STM32_FMPI2C_CR1(n) REG32(stm32_i2c_reg(n, 0x00))
|
||||
#define FMPI2C_CR1_PE (1 << 0)
|
||||
#define FMPI2C_CR1_TXDMAEN (1 << 14)
|
||||
#define FMPI2C_CR1_RXDMAEN (1 << 15)
|
||||
#define STM32_FMPI2C_CR2(n) REG32(stm32_i2c_reg(n, 0x04))
|
||||
#define FMPI2C_CR2_RD_WRN (1 << 10)
|
||||
#define FMPI2C_READ 1
|
||||
#define FMPI2C_WRITE 0
|
||||
#define FMPI2C_CR2_START (1 << 13)
|
||||
#define FMPI2C_CR2_STOP (1 << 14)
|
||||
#define FMPI2C_CR2_NACK (1 << 15)
|
||||
#define FMPI2C_CR2_RELOAD (1 << 24)
|
||||
#define FMPI2C_CR2_AUTOEND (1 << 25)
|
||||
#define FMPI2C_CR2_SADD(addr) ((addr) & 0x3ff)
|
||||
#define FMPI2C_CR2_SADD_MASK FMPI2C_CR2_SADD(0x3ff)
|
||||
#define FMPI2C_CR2_SIZE(size) (((size) & 0xff) << 16)
|
||||
#define FMPI2C_CR2_SIZE_MASK FMPI2C_CR2_SIZE(0xf)
|
||||
#define STM32_FMPI2C_OAR1(n) REG32(stm32_i2c_reg(n, 0x08))
|
||||
#define STM32_FMPI2C_OAR2(n) REG32(stm32_i2c_reg(n, 0x0C))
|
||||
#define STM32_FMPI2C_TIMINGR(n) REG32(stm32_i2c_reg(n, 0x10))
|
||||
#define TIMINGR_THE_RIGHT_VALUE 0xC0000E12
|
||||
#define FMPI2C_TIMINGR_PRESC(val) (((val) & 0xf) << 28)
|
||||
#define FMPI2C_TIMINGR_SCLDEL(val) (((val) & 0xf) << 20)
|
||||
#define FMPI2C_TIMINGR_SDADEL(val) (((val) & 0xf) << 16)
|
||||
#define FMPI2C_TIMINGR_SCLH(val) (((val) & 0xff) << 8)
|
||||
#define FMPI2C_TIMINGR_SCLL(val) (((val) & 0xff) << 0)
|
||||
#define STM32_FMPI2C_TIMEOUTR(n) REG32(stm32_i2c_reg(n, 0x14))
|
||||
|
||||
#define STM32_FMPI2C_ISR(n) REG32(stm32_i2c_reg(n, 0x18))
|
||||
#define FMPI2C_ISR_TXE (1 << 0)
|
||||
#define FMPI2C_ISR_TXIS (1 << 1)
|
||||
#define FMPI2C_ISR_RXNE (1 << 2)
|
||||
#define FMPI2C_ISR_ADDR (1 << 3)
|
||||
#define FMPI2C_ISR_NACKF (1 << 4)
|
||||
#define FMPI2C_ISR_STOPF (1 << 5)
|
||||
#define FMPI2C_ISR_BERR (1 << 8)
|
||||
#define FMPI2C_ISR_ARLO (1 << 9)
|
||||
#define FMPI2C_ISR_BUSY (1 << 15)
|
||||
#define STM32_FMPI2C_ICR(n) REG32(stm32_i2c_reg(n, 0x1C))
|
||||
|
||||
#define STM32_FMPI2C_PECR(n) REG32(stm32_i2c_reg(n, 0x20))
|
||||
#define STM32_FMPI2C_RXDR(n) REG32(stm32_i2c_reg(n, 0x24))
|
||||
#define STM32_FMPI2C_TXDR(n) REG32(stm32_i2c_reg(n, 0x28))
|
||||
#endif
|
||||
|
||||
/* --- Power / Reset / Clocks --- */
|
||||
#define STM32_PWR_BASE 0x40007000
|
||||
|
||||
@@ -551,7 +675,11 @@ typedef volatile struct timer_ctlr timer_ctlr_t;
|
||||
#define STM32_RCC_APB1RSTR REG32(STM32_RCC_BASE + 0x18)
|
||||
#define STM32_RCC_AHBENR REG32(STM32_RCC_BASE + 0x1C)
|
||||
#define STM32_RCC_APB2ENR REG32(STM32_RCC_BASE + 0x20)
|
||||
#define STM32_RCC_SYSCFGEN (1 << 0)
|
||||
|
||||
#define STM32_RCC_APB1ENR REG32(STM32_RCC_BASE + 0x24)
|
||||
#define STM32_RCC_PWREN (1 << 28)
|
||||
|
||||
#define STM32_RCC_AHBLPENR REG32(STM32_RCC_BASE + 0x28)
|
||||
#define STM32_RCC_APB2LPENR REG32(STM32_RCC_BASE + 0x2C)
|
||||
#define STM32_RCC_APB1LPENR REG32(STM32_RCC_BASE + 0x30)
|
||||
@@ -624,10 +752,13 @@ typedef volatile struct timer_ctlr timer_ctlr_t;
|
||||
#define STM32_RCC_AHB2ENR_GPIOMASK (0xff << 0)
|
||||
|
||||
#define STM32_RCC_APB1ENR REG32(STM32_RCC_BASE + 0x58)
|
||||
#define STM32_RCC_PWREN (1 << 28)
|
||||
|
||||
#define STM32_RCC_APB1ENR2 REG32(STM32_RCC_BASE + 0x5C)
|
||||
#define STM32_RCC_APB1ENR2_LPUART1EN (1 << 0)
|
||||
|
||||
#define STM32_RCC_APB2ENR REG32(STM32_RCC_BASE + 0x60)
|
||||
#define STM32_RCC_SYSCFGEN (1 << 0)
|
||||
|
||||
#define STM32_RCC_CCIPR REG32(STM32_RCC_BASE + 0x88)
|
||||
#define STM32_RCC_CCIPR_PCLK 0
|
||||
@@ -659,7 +790,11 @@ typedef volatile struct timer_ctlr timer_ctlr_t;
|
||||
#define STM32_RCC_APB1RSTR REG32(STM32_RCC_BASE + 0x10)
|
||||
#define STM32_RCC_AHBENR REG32(STM32_RCC_BASE + 0x14)
|
||||
#define STM32_RCC_APB2ENR REG32(STM32_RCC_BASE + 0x18)
|
||||
#define STM32_RCC_SYSCFGEN (1 << 0)
|
||||
|
||||
#define STM32_RCC_APB1ENR REG32(STM32_RCC_BASE + 0x1c)
|
||||
#define STM32_RCC_PWREN (1 << 28)
|
||||
|
||||
#define STM32_RCC_BDCR REG32(STM32_RCC_BASE + 0x20)
|
||||
#define STM32_RCC_CSR REG32(STM32_RCC_BASE + 0x24)
|
||||
/* STM32F373 */
|
||||
@@ -690,6 +825,142 @@ typedef volatile struct timer_ctlr timer_ctlr_t;
|
||||
#define STM32_SYSCFG_EXTICR(n) REG32(STM32_SYSCFG_BASE + 8 + 4 * (n))
|
||||
#define STM32_SYSCFG_CFGR2 REG32(STM32_SYSCFG_BASE + 0x18)
|
||||
|
||||
#elif defined(CHIP_FAMILY_STM32F4)
|
||||
#define STM32_RCC_BASE 0x40023800
|
||||
|
||||
#define STM32_RCC_CR REG32(STM32_RCC_BASE + 0x00)
|
||||
#define STM32_RCC_CR_HSION (1 << 0)
|
||||
#define STM32_RCC_CR_HSIRDY (1 << 1)
|
||||
#define STM32_RCC_CR_HSEON (1 << 16)
|
||||
#define STM32_RCC_CR_HSERDY (1 << 17)
|
||||
#define STM32_RCC_CR_PLLON (1 << 24)
|
||||
#define STM32_RCC_CR_PLLRDY (1 << 25)
|
||||
|
||||
/* Required or recommended clocks for stm32f446 */
|
||||
#define STM32F4_PLL_REQ 2000000
|
||||
#define STM32F4_RTC_REQ 1000000
|
||||
#define STM32F4_IO_CLOCK 42000000
|
||||
#define STM32F4_USB_REQ 48000000
|
||||
#define STM32F4_VCO_CLOCK 336000000
|
||||
#define STM32F4_HSI_CLOCK 16000000
|
||||
#define STM32F4_LSI_CLOCK 32000
|
||||
|
||||
#define STM32_RCC_PLLCFGR REG32(STM32_RCC_BASE + 0x04)
|
||||
/* PLL Division factor */
|
||||
#define PLLCFGR_PLLM_OFF 0
|
||||
#define PLLCFGR_PLLM(val) (((val) & 0x1f) << PLLCFGR_PLLM_OFF)
|
||||
/* PLL Multiplication factor */
|
||||
#define PLLCFGR_PLLN_OFF 6
|
||||
#define PLLCFGR_PLLN(val) (((val) & 0x1ff) << PLLCFGR_PLLN_OFF)
|
||||
/* Main CPU Clock */
|
||||
#define PLLCFGR_PLLP_OFF 16
|
||||
#define PLLCFGR_PLLP(val) (((val) & 0x3) << PLLCFGR_PLLP_OFF)
|
||||
|
||||
#define PLLCFGR_PLLSRC_HSI (0 << 22)
|
||||
#define PLLCFGR_PLLSRC_HSE (1 << 22)
|
||||
/* USB OTG FS: Must equal 48MHz */
|
||||
#define PLLCFGR_PLLQ_OFF 24
|
||||
#define PLLCFGR_PLLQ(val) (((val) & 0xf) << PLLCFGR_PLLQ_OFF)
|
||||
/* SYSTEM */
|
||||
#define PLLCFGR_PLLR_OFF 28
|
||||
#define PLLCFGR_PLLR(val) (((val) & 0x7) << PLLCFGR_PLLR_OFF)
|
||||
|
||||
#define STM32_RCC_CFGR REG32(STM32_RCC_BASE + 0x08)
|
||||
#define STM32_RCC_CFGR_SW_HSI (0 << 0)
|
||||
#define STM32_RCC_CFGR_SW_HSE (1 << 0)
|
||||
#define STM32_RCC_CFGR_SW_PLL (2 << 0)
|
||||
#define STM32_RCC_CFGR_SW_PLL_R (3 << 0)
|
||||
#define STM32_RCC_CFGR_SW_MASK (3 << 0)
|
||||
#define STM32_RCC_CFGR_SWS_HSI (0 << 2)
|
||||
#define STM32_RCC_CFGR_SWS_HSE (1 << 2)
|
||||
#define STM32_RCC_CFGR_SWS_PLL (2 << 2)
|
||||
#define STM32_RCC_CFGR_SWS_PLL_R (3 << 2)
|
||||
#define STM32_RCC_CFGR_SWS_MASK (3 << 2)
|
||||
/* AHB Prescalar: nonlinear values, look up in RM0390 */
|
||||
#define CFGR_HPRE_OFF 4
|
||||
#define CFGR_HPRE(val) (((val) & 0xf) << CFGR_HPRE_OFF)
|
||||
/* APB1 Low Speed Prescalar < 45MHz */
|
||||
#define CFGR_PPRE1_OFF 10
|
||||
#define CFGR_PPRE1(val) (((val) & 0x7) << CFGR_PPRE1_OFF)
|
||||
/* APB2 High Speed Prescalar < 90MHz */
|
||||
#define CFGR_PPRE2_OFF 13
|
||||
#define CFGR_PPRE2(val) (((val) & 0x7) << CFGR_PPRE2_OFF)
|
||||
/* RTC CLock: Must equal 1MHz */
|
||||
#define CFGR_RTCPRE_OFF 16
|
||||
#define CFGR_RTCPRE(val) (((val) & 0x1f) << CFGR_RTCPRE_OFF)
|
||||
|
||||
#define STM32_RCC_CIR REG32(STM32_RCC_BASE + 0x0C)
|
||||
#define STM32_RCC_AHB1RSTR REG32(STM32_RCC_BASE + 0x10)
|
||||
#define RCC_AHB1RSTR_OTGHSRST (1 << 29)
|
||||
|
||||
#define STM32_RCC_AHB2RSTR REG32(STM32_RCC_BASE + 0x14)
|
||||
#define STM32_RCC_AHB3RSTR REG32(STM32_RCC_BASE + 0x18)
|
||||
|
||||
#define STM32_RCC_APB1RSTR REG32(STM32_RCC_BASE + 0x20)
|
||||
#define STM32_RCC_APB2RSTR REG32(STM32_RCC_BASE + 0x24)
|
||||
|
||||
#define STM32_RCC_AHB1ENR REG32(STM32_RCC_BASE + 0x30)
|
||||
#define STM32_RCC_AHB1ENR_GPIOMASK (0xff << 0)
|
||||
#define STM32_RCC_AHB1ENR_BKPSRAMEN (1 << 18)
|
||||
#define STM32_RCC_AHB1ENR_DMA1EN (1 << 21)
|
||||
#define STM32_RCC_AHB1ENR_DMA2EN (1 << 22)
|
||||
/* TODO(nsanders): normalize naming.*/
|
||||
#define STM32_RCC_HB1_DMA1 (1 << 21)
|
||||
#define STM32_RCC_HB1_DMA2 (1 << 22)
|
||||
#define STM32_RCC_AHB1ENR_OTGHSEN (1 << 29)
|
||||
#define STM32_RCC_AHB1ENR_OTGHSULPIEN (1 << 30)
|
||||
|
||||
#define STM32_RCC_AHB2ENR REG32(STM32_RCC_BASE + 0x34)
|
||||
#define STM32_RCC_AHB2ENR_OTGFSEN (1 << 7)
|
||||
#define STM32_RCC_AHB3ENR REG32(STM32_RCC_BASE + 0x38)
|
||||
|
||||
#define STM32_RCC_APB1ENR REG32(STM32_RCC_BASE + 0x40)
|
||||
#define STM32_RCC_PWREN (1 << 28)
|
||||
#define STM32_RCC_I2C1EN (1 << 21)
|
||||
#define STM32_RCC_I2C2EN (1 << 22)
|
||||
#define STM32_RCC_I2C3EN (1 << 23)
|
||||
#define STM32_RCC_FMPI2C4EN (1 << 24)
|
||||
|
||||
#define STM32_RCC_APB2ENR REG32(STM32_RCC_BASE + 0x44)
|
||||
|
||||
#define STM32_RCC_PB2_USART6 (1 << 5)
|
||||
#define STM32_RCC_SYSCFGEN (1 << 14)
|
||||
|
||||
#define STM32_RCC_AHB1LPENR REG32(STM32_RCC_BASE + 0x50)
|
||||
#define STM32_RCC_AHB2LPENR REG32(STM32_RCC_BASE + 0x54)
|
||||
#define STM32_RCC_AHB3LPENR REG32(STM32_RCC_BASE + 0x58)
|
||||
#define STM32_RCC_APB1LPENR REG32(STM32_RCC_BASE + 0x60)
|
||||
#define STM32_RCC_APB2LPENR REG32(STM32_RCC_BASE + 0x64)
|
||||
|
||||
#define STM32_RCC_BDCR REG32(STM32_RCC_BASE + 0x70)
|
||||
#define STM32_RCC_BDCR_BDRST (1 << 16)
|
||||
#define STM32_RCC_BDCR_RTCEN (1 << 15)
|
||||
#define BCDR_RTCSEL(source) (((source) & 0x3) << 8)
|
||||
#define BDCR_SRC_HSE 0x3
|
||||
#define BDCR_SRC_LSI 0x2
|
||||
#define STM32_RCC_CSR REG32(STM32_RCC_BASE + 0x74)
|
||||
#define STM32_RCC_CSR_LSION (1 << 0)
|
||||
#define STM32_RCC_CSR_LSIRDY (1 << 1)
|
||||
|
||||
#define STM32_RCC_HB_DMA1 (1 << 24)
|
||||
#define STM32_RCC_PB2_TIM9 (1 << 2)
|
||||
#define STM32_RCC_PB2_TIM10 (1 << 3)
|
||||
#define STM32_RCC_PB2_TIM11 (1 << 4)
|
||||
#define STM32_RCC_PB1_USB (1 << 23)
|
||||
|
||||
#define STM32_RCC_DCKCFGR2 REG32(STM32_RCC_BASE + 0x94)
|
||||
#define DCKCFGR2_FMPI2C1SEL(val) (((val) & 0x3) << 22)
|
||||
#define DCKCFGR2_FMPI2C1SEL_MASK (0x3 << 22)
|
||||
#define FMPI2C1SEL_APB 0x0
|
||||
|
||||
#define STM32_SYSCFG_BASE 0x40013800
|
||||
|
||||
#define STM32_SYSCFG_MEMRMP REG32(STM32_SYSCFG_BASE + 0x00)
|
||||
#define STM32_SYSCFG_PMC REG32(STM32_SYSCFG_BASE + 0x04)
|
||||
#define STM32_SYSCFG_EXTICR(n) REG32(STM32_SYSCFG_BASE + 8 + 4 * (n))
|
||||
#define STM32_SYSCFG_CMPCR REG32(STM32_SYSCFG_BASE + 0x20)
|
||||
#define STM32_SYSCFG_CFGR REG32(STM32_SYSCFG_BASE + 0x2C)
|
||||
|
||||
#else
|
||||
#error Unsupported chip variant
|
||||
#endif
|
||||
@@ -711,7 +982,11 @@ typedef volatile struct timer_ctlr timer_ctlr_t;
|
||||
#define STM32_RCC_PB1_USART4 (1 << 19)
|
||||
#define STM32_RCC_PB1_USART5 (1 << 20)
|
||||
#define STM32_RCC_PB2_SPI1 (1 << 12)
|
||||
#if defined(CHIP_FAMILY_STM32F4)
|
||||
#define STM32_RCC_PB2_USART1 (1 << 4)
|
||||
#else
|
||||
#define STM32_RCC_PB2_USART1 (1 << 14)
|
||||
#endif
|
||||
|
||||
/* --- Watchdogs --- */
|
||||
|
||||
@@ -740,7 +1015,8 @@ typedef volatile struct timer_ctlr timer_ctlr_t;
|
||||
#define STM32_RTC_BASE 0x40002800
|
||||
|
||||
#if defined(CHIP_FAMILY_STM32L) || defined(CHIP_FAMILY_STM32F0) || \
|
||||
defined(CHIP_FAMILY_STM32F3) || defined(CHIP_FAMILY_STM32L4)
|
||||
defined(CHIP_FAMILY_STM32F3) || defined(CHIP_FAMILY_STM32L4) || \
|
||||
defined(CHIP_FAMILY_STM32F4)
|
||||
#define STM32_RTC_TR REG32(STM32_RTC_BASE + 0x00)
|
||||
#define STM32_RTC_DR REG32(STM32_RTC_BASE + 0x04)
|
||||
#define STM32_RTC_CR REG32(STM32_RTC_BASE + 0x08)
|
||||
@@ -754,6 +1030,8 @@ typedef volatile struct timer_ctlr timer_ctlr_t;
|
||||
#define STM32_RTC_ISR_INIT (1 << 7)
|
||||
#define STM32_RTC_ISR_ALRAF (1 << 8)
|
||||
#define STM32_RTC_PRER REG32(STM32_RTC_BASE + 0x10)
|
||||
#define STM32_RTC_PRER_A_MASK (0x7f << 16)
|
||||
#define STM32_RTC_PRER_S_MASK (0x7fff << 0)
|
||||
#define STM32_RTC_WUTR REG32(STM32_RTC_BASE + 0x14)
|
||||
#define STM32_RTC_CALIBR REG32(STM32_RTC_BASE + 0x18)
|
||||
#define STM32_RTC_ALRMAR REG32(STM32_RTC_BASE + 0x1C)
|
||||
@@ -915,12 +1193,53 @@ typedef volatile struct stm32_spi_regs stm32_spi_regs_t;
|
||||
|
||||
#define STM32_OPTB_COMPL_SHIFT 8
|
||||
|
||||
#elif defined(CHIP_FAMILY_STM32F4)
|
||||
#define STM32_FLASH_REGS_BASE 0x40023c00
|
||||
|
||||
#define STM32_FLASH_ACR REG32(STM32_FLASH_REGS_BASE + 0x00)
|
||||
#define STM32_FLASH_ACR_LATENCY (1 << 0)
|
||||
#define STM32_FLASH_ACR_PRFTEN (1 << 8)
|
||||
#define STM32_FLASH_ACR_ICEN (1 << 9)
|
||||
#define STM32_FLASH_ACR_DCEN (1 << 10)
|
||||
#define STM32_FLASH_KEYR REG32(STM32_FLASH_REGS_BASE + 0x04)
|
||||
#define STM32_FLASH_OPTKEYR REG32(STM32_FLASH_REGS_BASE + 0x08)
|
||||
#define STM32_FLASH_SR REG32(STM32_FLASH_REGS_BASE + 0x0c)
|
||||
#define FLASH_SR_BUSY (1 << 16)
|
||||
#define FLASH_SR_ERR_MASK (0x1f3)
|
||||
#define STM32_FLASH_CR REG32(STM32_FLASH_REGS_BASE + 0x10)
|
||||
#define FLASH_CR_PG (1 << 0)
|
||||
#define FLASH_CR_SER (1 << 1)
|
||||
#define FLASH_CR_STRT (1 << 16)
|
||||
#define FLASH_CR_LOCK (1 << 31)
|
||||
#define FLASH_CR_PSIZE(size) (((size) & 0x3) << 8)
|
||||
#define FLASH_CR_PSIZE_16 (1)
|
||||
#define FLASH_CR_PSIZE_32 (2)
|
||||
#define FLASH_CR_PSIZE_MASK FLASH_CR_PSIZE(0x3)
|
||||
#define FLASH_CR_SNB(sec) (((sec) & 0xf) << 3)
|
||||
#define FLASH_CR_SNB_MASK FLASH_CR_SNB(0xf)
|
||||
|
||||
#define STM32_FLASH_OPTCR REG32(STM32_FLASH_REGS_BASE + 0x14)
|
||||
|
||||
#define STM32_OPTB_BASE 0x1FFFC000
|
||||
|
||||
#define STM32_OPTB_RDP_OFF 0x00
|
||||
#define STM32_OPTB_USER_OFF 0x02
|
||||
#define STM32_OPTB_WRP_OFF(n) (0x08 + (n&3) * 2)
|
||||
#define STM32_OPTB_WRP01 0x08
|
||||
#define STM32_OPTB_WRP23 0x0c
|
||||
|
||||
#define STM32_OPTB_COMPL_SHIFT 8
|
||||
|
||||
#else
|
||||
#error Unsupported chip variant
|
||||
#endif
|
||||
|
||||
/* --- External Interrupts --- */
|
||||
#if defined(CHIP_FAMILY_STM32F4)
|
||||
#define STM32_EXTI_BASE 0x40013C00
|
||||
#else
|
||||
#define STM32_EXTI_BASE 0x40010400
|
||||
#endif
|
||||
|
||||
#define STM32_EXTI_IMR REG32(STM32_EXTI_BASE + 0x00)
|
||||
#define STM32_EXTI_EMR REG32(STM32_EXTI_BASE + 0x04)
|
||||
@@ -929,15 +1248,21 @@ typedef volatile struct stm32_spi_regs stm32_spi_regs_t;
|
||||
#define STM32_EXTI_SWIER REG32(STM32_EXTI_BASE + 0x10)
|
||||
#define STM32_EXTI_PR REG32(STM32_EXTI_BASE + 0x14)
|
||||
|
||||
#if defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3)
|
||||
#if defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) || \
|
||||
defined(CHIP_FAMILY_STM32F4)
|
||||
#define EXTI_RTC_ALR_EVENT (1 << 17)
|
||||
#endif
|
||||
|
||||
/* --- ADC --- */
|
||||
#if defined(CHIP_FAMILY_STM32F4)
|
||||
#define STM32_ADC1_BASE 0x40012000
|
||||
#define STM32_ADC_BASE 0x40012300
|
||||
#else
|
||||
#define STM32_ADC1_BASE 0x40012400
|
||||
#define STM32_ADC_BASE 0x40012700 /* STM32L15X only */
|
||||
#endif
|
||||
|
||||
#if defined(CHIP_VARIANT_STM32F373)
|
||||
#if defined(CHIP_VARIANT_STM32F373) || defined(CHIP_FAMILY_STM32F4)
|
||||
#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)
|
||||
@@ -1241,10 +1566,107 @@ typedef volatile struct stm32_spi_regs stm32_spi_regs_t;
|
||||
defined(CHIP_FAMILY_STM32L4)
|
||||
#define STM32_DMA1_BASE 0x40020000
|
||||
#define STM32_DMA2_BASE 0x40020400
|
||||
#elif defined(CHIP_FAMILY_STM32F4)
|
||||
#define STM32_DMA1_BASE 0x40026000
|
||||
#define STM32_DMA2_BASE 0x40026400
|
||||
#else
|
||||
#error Unsupported chip variant
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(CHIP_FAMILY_STM32F4)
|
||||
|
||||
/*
|
||||
* Available DMA streams, numbered from 0.
|
||||
*
|
||||
* Named channel to respect older interface, but a stream can serve
|
||||
* any channels, as long as they are in the same DMA controller.
|
||||
*
|
||||
* Stream 0 - 7 are managed by controller DMA1, 8 - 15 DMA2.
|
||||
*/
|
||||
enum dma_channel {
|
||||
/* Channel numbers */
|
||||
STM32_DMA1_STREAM0 = 0,
|
||||
STM32_DMA1_STREAM1 = 1,
|
||||
STM32_DMA1_STREAM2 = 2,
|
||||
STM32_DMA1_STREAM3 = 3,
|
||||
STM32_DMA1_STREAM4 = 4,
|
||||
STM32_DMA1_STREAM5 = 5,
|
||||
STM32_DMA1_STREAM6 = 6,
|
||||
STM32_DMA1_STREAM7 = 7,
|
||||
STM32_DMAS_COUNT = 8,
|
||||
STM32_DMA2_STREAM0 = 8,
|
||||
STM32_DMA2_STREAM1 = 9,
|
||||
STM32_DMA2_STREAM2 = 10,
|
||||
STM32_DMA2_STREAM3 = 11,
|
||||
STM32_DMA2_STREAM4 = 12,
|
||||
STM32_DMA2_STREAM5 = 13,
|
||||
STM32_DMA2_STREAM6 = 14,
|
||||
STM32_DMA2_STREAM7 = 15,
|
||||
|
||||
STM32_DMAS_USART1_TX = STM32_DMA2_STREAM7,
|
||||
STM32_DMAS_USART1_RX = STM32_DMA2_STREAM5,
|
||||
/* Legacy naming for uart.c */
|
||||
STM32_DMAC_USART1_TX = STM32_DMAS_USART1_TX,
|
||||
STM32_DMAC_USART1_RX = STM32_DMAS_USART1_RX,
|
||||
|
||||
STM32_DMAC_I2C1_TX = STM32_DMA1_STREAM6,
|
||||
STM32_DMAC_I2C1_RX = STM32_DMA1_STREAM0,
|
||||
|
||||
STM32_DMAC_I2C2_TX = STM32_DMA1_STREAM7,
|
||||
STM32_DMAC_I2C2_RX = STM32_DMA1_STREAM3,
|
||||
|
||||
STM32_DMAC_I2C3_TX = STM32_DMA1_STREAM4,
|
||||
STM32_DMAC_I2C3_RX = STM32_DMA1_STREAM1,
|
||||
|
||||
STM32_DMAC_FMPI2C4_TX = STM32_DMA1_STREAM5,
|
||||
STM32_DMAC_FMPI2C4_RX = STM32_DMA1_STREAM2,
|
||||
|
||||
};
|
||||
|
||||
#define STM32_REQ_USART1_TX 4
|
||||
#define STM32_REQ_USART1_RX 4
|
||||
|
||||
#define STM32_REQ_USART2_TX 4
|
||||
#define STM32_REQ_USART2_RX 4
|
||||
|
||||
#define STM32_I2C1_TX_REQ_CH 1
|
||||
#define STM32_I2C1_RX_REQ_CH 1
|
||||
|
||||
#define STM32_I2C2_TX_REQ_CH 7
|
||||
#define STM32_I2C2_RX_REQ_CH 7
|
||||
|
||||
#define STM32_I2C3_TX_REQ_CH 3
|
||||
#define STM32_I2C3_RX_REQ_CH 1
|
||||
|
||||
#define STM32_FMPI2C4_TX_REQ_CH 2
|
||||
#define STM32_FMPI2C4_RX_REQ_CH 2
|
||||
|
||||
#define STM32_DMAS_TOTAL_COUNT 16
|
||||
|
||||
/* Registers for a single stream of a DMA controller */
|
||||
struct stm32_dma_stream {
|
||||
uint32_t scr; /* Control */
|
||||
uint32_t sndtr; /* Number of data to transfer */
|
||||
uint32_t spar; /* Peripheral address */
|
||||
uint32_t sm0ar; /* Memory address 0 */
|
||||
uint32_t sm1ar; /* address 1 for double buffer */
|
||||
uint32_t sfcr; /* FIFO control */
|
||||
};
|
||||
|
||||
/* Always use stm32_dma_stream_t so volatile keyword is included! */
|
||||
typedef volatile struct stm32_dma_stream stm32_dma_stream_t;
|
||||
|
||||
/* Common code and header file must use this */
|
||||
typedef stm32_dma_stream_t dma_chan_t;
|
||||
struct stm32_dma_regs {
|
||||
uint32_t isr[2];
|
||||
uint32_t ifcr[2];
|
||||
stm32_dma_stream_t stream[STM32_DMAS_COUNT];
|
||||
};
|
||||
|
||||
#else /* CHIP_FAMILY_STM32F4 */
|
||||
|
||||
/*
|
||||
* Available DMA channels, numbered from 0.
|
||||
*
|
||||
@@ -1338,12 +1760,93 @@ struct stm32_dma_regs {
|
||||
uint32_t ifcr;
|
||||
stm32_dma_chan_t chan[STM32_DMAC_COUNT];
|
||||
};
|
||||
#endif /* CHIP_FAMILY_STM32F4 */
|
||||
|
||||
/* Always use stm32_dma_regs_t so volatile keyword is included! */
|
||||
typedef volatile struct stm32_dma_regs stm32_dma_regs_t;
|
||||
|
||||
#define STM32_DMA1_REGS ((stm32_dma_regs_t *)STM32_DMA1_BASE)
|
||||
|
||||
|
||||
|
||||
#if defined(CHIP_FAMILY_STM32F4)
|
||||
#define STM32_DMA2_REGS ((stm32_dma_regs_t *)STM32_DMA2_BASE)
|
||||
|
||||
#define STM32_DMA_REGS(channel) \
|
||||
((channel) < STM32_DMAS_COUNT ? STM32_DMA1_REGS : STM32_DMA2_REGS)
|
||||
|
||||
#define STM32_DMA_CCR_EN (1 << 0)
|
||||
#define STM32_DMA_CCR_DMEIE (1 << 1)
|
||||
#define STM32_DMA_CCR_TEIE (1 << 2)
|
||||
#define STM32_DMA_CCR_HTIE (1 << 3)
|
||||
#define STM32_DMA_CCR_TCIE (1 << 4)
|
||||
#define STM32_DMA_CCR_PFCTRL (1 << 5)
|
||||
#define STM32_DMA_CCR_DIR_P2M (0 << 6)
|
||||
#define STM32_DMA_CCR_DIR_M2P (1 << 6)
|
||||
#define STM32_DMA_CCR_DIR_M2M (2 << 6)
|
||||
#define STM32_DMA_CCR_CIRC (1 << 8)
|
||||
#define STM32_DMA_CCR_PINC (1 << 9)
|
||||
#define STM32_DMA_CCR_MINC (1 << 10)
|
||||
#define STM32_DMA_CCR_PSIZE_8_BIT (0 << 11)
|
||||
#define STM32_DMA_CCR_PSIZE_16_BIT (1 << 11)
|
||||
#define STM32_DMA_CCR_PSIZE_32_BIT (2 << 11)
|
||||
#define STM32_DMA_CCR_MSIZE_8_BIT (0 << 13)
|
||||
#define STM32_DMA_CCR_MSIZE_16_BIT (1 << 13)
|
||||
#define STM32_DMA_CCR_MSIZE_32_BIT (2 << 13)
|
||||
#define STM32_DMA_CCR_PINCOS (1 << 15)
|
||||
#define STM32_DMA_CCR_PL_LOW (0 << 16)
|
||||
#define STM32_DMA_CCR_PL_MEDIUM (1 << 16)
|
||||
#define STM32_DMA_CCR_PL_HIGH (2 << 16)
|
||||
#define STM32_DMA_CCR_PL_VERY_HIGH (3 << 16)
|
||||
#define STM32_DMA_CCR_DBM (1 << 18)
|
||||
#define STM32_DMA_CCR_CT (1 << 19)
|
||||
#define STM32_DMA_CCR_PBURST(b_len) ((((b_len) - 4) / 4) << 21)
|
||||
#define STM32_DMA_CCR_MBURST(b_len) ((((b_len) - 4) / 4) << 21)
|
||||
#define STM32_DMA_CCR_CHANNEL_MASK (0x7 << 25)
|
||||
#define STM32_DMA_CCR_CHANNEL(channel) ((channel) << 25)
|
||||
#define STM32_DMA_CCR_RSVD_MASK (0xF0100000)
|
||||
|
||||
|
||||
#define STM32_DMA_SFCR_DMDIS (1 << 2)
|
||||
#define STM32_DMA_SFCR_FTH(level) (((level) - 1) << 0)
|
||||
|
||||
|
||||
#define STM32_DMA_CH_LOCAL(channel) ((channel) % STM32_DMAS_COUNT)
|
||||
#define STM32_DMA_CH_LH(channel) \
|
||||
((STM32_DMA_CH_LOCAL(channel) < 4) ? 0 : 1)
|
||||
#define STM32_DMA_CH_OFFSET(channel) \
|
||||
(((STM32_DMA_CH_LOCAL(channel) % 4) * 6) + \
|
||||
(((STM32_DMA_CH_LOCAL(channel) % 4) >= 2) ? 4 : 0))
|
||||
#define STM32_DMA_CH_GETBITS(channel, val) \
|
||||
(((val) >> STM32_DMA_CH_OFFSET(channel)) & 0x3f)
|
||||
#define STM32_DMA_GET_IFCR(channel) \
|
||||
(STM32_DMA_CH_GETBITS(channel, \
|
||||
STM32_DMA_REGS(channel)->ifcr[STM32_DMA_CH_LH(channel)]))
|
||||
#define STM32_DMA_GET_ISR(channel) \
|
||||
(STM32_DMA_CH_GETBITS(channel, \
|
||||
STM32_DMA_REGS(channel)->ifcr[STM32_DMA_CH_LH(channel)]))
|
||||
|
||||
#define STM32_DMA_SET_IFCR(channel, val) \
|
||||
(STM32_DMA_REGS(channel)->ifcr[STM32_DMA_CH_LH(channel)] = \
|
||||
(STM32_DMA_REGS(channel)->ifcr[STM32_DMA_CH_LH(channel)] & \
|
||||
~(0x3f << STM32_DMA_CH_OFFSET(channel))) | \
|
||||
(((val) & 0x3f) << STM32_DMA_CH_OFFSET(channel)))
|
||||
#define STM32_DMA_SET_ISR(channel, val) \
|
||||
(STM32_DMA_REGS(channel)->isr[STM32_DMA_CH_LH(channel)] = \
|
||||
(STM32_DMA_REGS(channel)->isr[STM32_DMA_CH_LH(channel)] & \
|
||||
~(0x3f << STM32_DMA_CH_OFFSET(channel))) | \
|
||||
(((val) & 0x3f) << STM32_DMA_CH_OFFSET(channel)))
|
||||
|
||||
#define STM32_DMA_FEIF (1 << 0)
|
||||
#define STM32_DMA_DMEIF (1 << 2)
|
||||
#define STM32_DMA_TEIF (1 << 3)
|
||||
#define STM32_DMA_HTIF (1 << 4)
|
||||
#define STM32_DMA_TCIF (1 << 5)
|
||||
#define STM32_DMA_ALL 0x3d
|
||||
|
||||
#else /* !CHIP_FAMILY_STM32F4 */
|
||||
#define STM32_DMA_CCR_CHANNEL(channel) (0)
|
||||
|
||||
#if defined(CHIP_FAMILY_STM32F3) || defined(CHIP_FAMILY_STM32L4)
|
||||
#define STM32_DMA2_REGS ((stm32_dma_regs_t *)STM32_DMA2_BASE)
|
||||
#define STM32_DMA_REGS(channel) \
|
||||
@@ -1356,14 +1859,39 @@ typedef volatile struct stm32_dma_regs stm32_dma_regs_t;
|
||||
#endif
|
||||
|
||||
/* Bits for DMA controller regs (isr and ifcr) */
|
||||
#define STM32_DMA_CH_OFFSET(channel) (4 * ((channel) % STM32_DMAC_PER_CTLR))
|
||||
#define STM32_DMA_ISR_MASK(channel, mask) \
|
||||
((mask) << (4 * ((channel) % STM32_DMAC_PER_CTLR)))
|
||||
((mask) << STM32_DMA_CH_OFFSET(channel))
|
||||
#define STM32_DMA_ISR_GIF(channel) STM32_DMA_ISR_MASK(channel, 1 << 0)
|
||||
#define STM32_DMA_ISR_TCIF(channel) STM32_DMA_ISR_MASK(channel, 1 << 1)
|
||||
#define STM32_DMA_ISR_HTIF(channel) STM32_DMA_ISR_MASK(channel, 1 << 2)
|
||||
#define STM32_DMA_ISR_TEIF(channel) STM32_DMA_ISR_MASK(channel, 1 << 3)
|
||||
#define STM32_DMA_ISR_ALL(channel) STM32_DMA_ISR_MASK(channel, 0x0f)
|
||||
|
||||
#define STM32_DMA_GIF (1 << 0)
|
||||
#define STM32_DMA_TCIF (1 << 1)
|
||||
#define STM32_DMA_HTIF (1 << 2)
|
||||
#define STM32_DMA_TEIF (1 << 3)
|
||||
#define STM32_DMA_ALL 0xf
|
||||
|
||||
#define STM32_DMA_GET_ISR(channel) \
|
||||
((STM32_DMA_REGS(channel)->isr >> STM32_DMA_CH_OFFSET(channel)) \
|
||||
& STM32_DMA_ALL)
|
||||
#define STM32_DMA_SET_ISR(channel, val) \
|
||||
(STM32_DMA_REGS(channel)->isr = \
|
||||
((STM32_DMA_REGS(channel)->isr & \
|
||||
~(STM32_DMA_ALL << STM32_DMA_CH_OFFSET(channel))) | \
|
||||
(((val) & STM32_DMA_ALL) << STM32_DMA_CH_OFFSET(channel))))
|
||||
#define STM32_DMA_GET_IFCR(channel) \
|
||||
((STM32_DMA_REGS(channel)->ifcr >> STM32_DMA_CH_OFFSET(channel)) \
|
||||
& STM32_DMA_ALL)
|
||||
#define STM32_DMA_SET_IFCR(channel, val) \
|
||||
(STM32_DMA_REGS(channel)->ifcr = \
|
||||
((STM32_DMA_REGS(channel)->ifcr & \
|
||||
~(STM32_DMA_ALL << STM32_DMA_CH_OFFSET(channel))) | \
|
||||
(((val) & STM32_DMA_ALL) << STM32_DMA_CH_OFFSET(channel))))
|
||||
|
||||
|
||||
/* Bits for DMA channel regs */
|
||||
#define STM32_DMA_CCR_EN (1 << 0)
|
||||
#define STM32_DMA_CCR_TCIE (1 << 1)
|
||||
@@ -1384,6 +1912,7 @@ typedef volatile struct stm32_dma_regs stm32_dma_regs_t;
|
||||
#define STM32_DMA_CCR_PL_HIGH (2 << 12)
|
||||
#define STM32_DMA_CCR_PL_VERY_HIGH (3 << 12)
|
||||
#define STM32_DMA_CCR_MEM2MEM (1 << 14)
|
||||
#endif /* !CHIP_FAMILY_STM32F4 */
|
||||
|
||||
/* --- CRC --- */
|
||||
#define STM32_CRC_BASE 0x40023000
|
||||
|
||||
@@ -186,9 +186,14 @@ void system_pre_init(void)
|
||||
#endif
|
||||
|
||||
/* enable clock on Power module */
|
||||
STM32_RCC_APB1ENR |= 1 << 28;
|
||||
STM32_RCC_APB1ENR |= STM32_RCC_PWREN;
|
||||
#if defined(CHIP_FAMILY_STM32F4)
|
||||
/* enable backup registers */
|
||||
STM32_RCC_AHB1ENR |= STM32_RCC_AHB1ENR_BKPSRAMEN;
|
||||
#else
|
||||
/* enable backup registers */
|
||||
STM32_RCC_APB1ENR |= 1 << 27;
|
||||
#endif
|
||||
/* Delay 1 APB clock cycle after the clock is enabled */
|
||||
clock_wait_bus_cycles(BUS_APB, 1);
|
||||
/* Enable access to RCC CSR register and RTC backup registers */
|
||||
@@ -212,7 +217,7 @@ void system_pre_init(void)
|
||||
STM32_RCC_CSR = (STM32_RCC_CSR & ~0x00C30000) | 0x00420000;
|
||||
}
|
||||
#elif defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) || \
|
||||
defined(CHIP_FAMILY_STM32L4)
|
||||
defined(CHIP_FAMILY_STM32L4) || defined(CHIP_FAMILY_STM32F4)
|
||||
if ((STM32_RCC_BDCR & 0x00018300) != 0x00008200) {
|
||||
/* the RTC settings are bad, we need to reset it */
|
||||
STM32_RCC_BDCR |= 0x00010000;
|
||||
@@ -404,5 +409,8 @@ int system_is_reboot_warm(void)
|
||||
#elif defined(CHIP_FAMILY_STM32L4)
|
||||
return ((STM32_RCC_AHB2ENR & STM32_RCC_AHB2ENR_GPIOMASK)
|
||||
== STM32_RCC_AHB2ENR_GPIOMASK);
|
||||
#elif defined(CHIP_FAMILY_STM32F4)
|
||||
return ((STM32_RCC_AHB1ENR & STM32_RCC_AHB1ENR_GPIOMASK)
|
||||
== STM32_RCC_AHB1ENR_GPIOMASK);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -32,6 +32,9 @@
|
||||
static const struct dma_option dma_tx_option = {
|
||||
CONFIG_UART_TX_DMA_CH, (void *)&STM32_USART_TDR(UARTN_BASE),
|
||||
STM32_DMA_CCR_MSIZE_8_BIT | STM32_DMA_CCR_PSIZE_8_BIT
|
||||
#ifdef CHIP_FAMILY_STM32F4
|
||||
| STM32_DMA_CCR_CHANNEL(CONFIG_UART_TX_REQ_CH)
|
||||
#endif
|
||||
};
|
||||
|
||||
#else
|
||||
@@ -47,6 +50,9 @@ static const struct dma_option dma_tx_option = {
|
||||
static const struct dma_option dma_rx_option = {
|
||||
CONFIG_UART_RX_DMA_CH, (void *)&STM32_USART_RDR(UARTN_BASE),
|
||||
STM32_DMA_CCR_MSIZE_8_BIT | STM32_DMA_CCR_PSIZE_8_BIT |
|
||||
#ifdef CHIP_FAMILY_STM32F4
|
||||
STM32_DMA_CCR_CHANNEL(CONFIG_UART_RX_REQ_CH) |
|
||||
#endif
|
||||
STM32_DMA_CCR_CIRC
|
||||
};
|
||||
|
||||
@@ -167,7 +173,11 @@ void uart_interrupt(void)
|
||||
STM32_USART_CR1(UARTN_BASE) &= ~STM32_USART_CR1_TCIE;
|
||||
enable_sleep(SLEEP_MASK_UART);
|
||||
}
|
||||
#if defined(CHIP_FAMILY_STM32F4)
|
||||
STM32_USART_SR(UARTN_BASE) &= ~STM32_USART_SR_TC;
|
||||
#else
|
||||
STM32_USART_ICR(UARTN_BASE) |= STM32_USART_SR_TC;
|
||||
#endif
|
||||
if (!(STM32_USART_SR(UARTN_BASE) & ~STM32_USART_SR_TC))
|
||||
return;
|
||||
}
|
||||
@@ -234,7 +244,8 @@ static void uart_freq_change(void)
|
||||
#endif
|
||||
|
||||
#if defined(CHIP_FAMILY_STM32L) || defined(CHIP_FAMILY_STM32F0) || \
|
||||
defined(CHIP_FAMILY_STM32F3) || defined(CHIP_FAMILY_STM32L4)
|
||||
defined(CHIP_FAMILY_STM32F3) || defined(CHIP_FAMILY_STM32L4) || \
|
||||
defined(CHIP_FAMILY_STM32F4)
|
||||
if (div / 16 > 0) {
|
||||
/*
|
||||
* CPU clock is high enough to support x16 oversampling.
|
||||
@@ -279,6 +290,8 @@ void uart_init(void)
|
||||
/* Enable USART clock */
|
||||
#if (UARTN == 1)
|
||||
STM32_RCC_APB2ENR |= STM32_RCC_PB2_USART1;
|
||||
#elif (UARTN == 6)
|
||||
STM32_RCC_APB2ENR |= STM32_RCC_PB2_USART6;
|
||||
#elif (UARTN == 9)
|
||||
STM32_RCC_APB1ENR2 |= STM32_RCC_APB1ENR2_LPUART1EN;
|
||||
#else
|
||||
@@ -340,7 +353,7 @@ void uart_init(void)
|
||||
STM32_USART_CR1(UARTN_BASE) |= STM32_USART_CR1_RXNEIE;
|
||||
#endif
|
||||
|
||||
#ifdef CHIP_FAMILY_STM32L
|
||||
#if defined(CHIP_FAMILY_STM32L) || defined(CHIP_FAMILY_STM32F4)
|
||||
/* Use single-bit sampling */
|
||||
STM32_USART_CR3(UARTN_BASE) |= STM32_USART_CR3_ONEBIT;
|
||||
#endif
|
||||
|
||||
@@ -524,6 +524,9 @@
|
||||
*/
|
||||
#undef CONFIG_CLOCK_CRYSTAL
|
||||
|
||||
/* Indicate if a clock source is connected to stm32f4's "HSE" specific input */
|
||||
#undef CONFIG_STM32_CLOCK_HSE_HZ
|
||||
|
||||
/*****************************************************************************/
|
||||
/* PMIC config */
|
||||
|
||||
@@ -1870,6 +1873,11 @@
|
||||
/* The DMA peripheral request signal for UART TX. STM32 only. */
|
||||
#undef CONFIG_UART_TX_DMA_PH
|
||||
|
||||
/* The DMA channel mapping config for stm32f4. */
|
||||
#undef CONFIG_UART_TX_REQ_CH
|
||||
#undef CONFIG_UART_RX_REQ_CH
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* USB PD config */
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ enum module_id {
|
||||
MODULE_USB_PORT_POWER, /* 35 */
|
||||
MODULE_USB_SWITCH,
|
||||
MODULE_VBOOT,
|
||||
MODULE_MCO,
|
||||
|
||||
/* Module count; not an actual module */
|
||||
MODULE_COUNT
|
||||
|
||||
@@ -13,13 +13,26 @@
|
||||
|
||||
/* Task event bitmasks */
|
||||
/* Tasks may use the bits in TASK_EVENT_CUSTOM for their own events */
|
||||
#define TASK_EVENT_CUSTOM(x) (x & 0x03ffffff)
|
||||
#define TASK_EVENT_CUSTOM(x) (x & 0x0007ffff)
|
||||
|
||||
/* npcx peci event */
|
||||
#define TASK_EVENT_PECI_DONE (1 << 19)
|
||||
|
||||
/* I2C tx/rx interrupt handler completion event. */
|
||||
#define TASK_EVENT_I2C_COMPLETION(port) \
|
||||
(1 << ((port) + 20))
|
||||
#define TASK_EVENT_I2C_IDLE (TASK_EVENT_I2C_COMPLETION(0))
|
||||
#define TASK_EVENT_MAX_I2C 6
|
||||
#ifdef I2C_PORT_COUNT
|
||||
#if (I2C_PORT_COUNT > TASK_EVENT_MAX_I2C)
|
||||
#error "Too many i2c ports for i2c events"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* DMA transmit complete event */
|
||||
#define TASK_EVENT_DMA_TC (1 << 26)
|
||||
/* ADC interrupt handler event */
|
||||
#define TASK_EVENT_ADC_DONE (1 << 27)
|
||||
/* I2C interrupt handler event */
|
||||
#define TASK_EVENT_I2C_IDLE (1 << 28)
|
||||
/* task_wake() called on task */
|
||||
#define TASK_EVENT_WAKE (1 << 29)
|
||||
/* Mutex unlocking */
|
||||
|
||||
@@ -88,6 +88,7 @@ BOARDS_STM32_DFU=(
|
||||
discovery
|
||||
servo_v4
|
||||
servo_micro
|
||||
stm32f446e-eval
|
||||
)
|
||||
|
||||
BOARDS_NPCX_5M5G_JTAG=(
|
||||
|
||||
Reference in New Issue
Block a user