blob: 589fa12d5a976c12003c482b8ceb62618e5d3ef2 [file] [log] [blame]
/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/* Hardware initialization and common functions */
#include "common.h"
#include "cpu.h"
#include "registers.h"
#include "task.h"
#include "timer.h"
#include "touch_scan.h"
#include "util.h"
void hardware_clock_init(void)
{
/* Turn on HSE */
if (!(STM32_RCC_CR & (1 << 17))) {
/* Enable HSE */
STM32_RCC_CR |= (1 << 18) | (1 << 16);
/* Wait for HSE to be ready */
while (!(STM32_RCC_CR & (1 << 17)))
;
}
/* PLLSRC = HSE/2 = 8MHz, PLLMUL = x6 = 48MHz */
STM32_RCC_CFGR = 0x00534000;
/* Enable PLL */
STM32_RCC_CR |= 1 << 24;
/* Wait for PLL to be ready */
while (!(STM32_RCC_CR & (1 << 25)))
;
/* switch SYSCLK to PLL */
STM32_RCC_CFGR = 0x00534002;
/* wait until the PLL is the clock source */
while ((STM32_RCC_CFGR & 0xc) != 0x8)
;
}
static void power_init(void)
{
/* enable ADC1, ADC2, PMSE, SPI1, GPA-GPI, AFIO */
STM32_RCC_APB2ENR = 0x0000f7fd;
/* enable TIM2, TIM3, PWR */
STM32_RCC_APB1ENR = 0x10000003;
/* enable DMA, SRAM */
STM32_RCC_AHBENR = 0x000005;
}
/* GPIO setting helpers */
#define OUT(n) (0x1 << ((n & 0x7) * 4))
#define OUT50(n) (0x3 << ((n & 0x7) * 4))
#define ANALOG(n) (0x0)
#define FLOAT(n) (0x4 << ((n & 0x7) * 4))
#define GP_OD(n) (0x5 << ((n & 0x7) * 4))
#define AF_PP(n) (0x9 << ((n & 0x7) * 4))
#define AF_OD(n) (0xd << ((n & 0x7) * 4))
#define LOW(n) (1 << (n + 16))
#define HIGH(n) (1 << n)
#define INT(n) (1 << n)
static void pins_init(void)
{
/*
* Disable JTAG and SWD. We want JTDI for UART Tx and SWD pins for
* touch scan.
*/
STM32_GPIO_AFIO_MAPR = (STM32_GPIO_AFIO_MAPR & ~(0x7 << 24))
| (4 << 24);
/*
* Initial pin usage:
* PA0: SPI_NSS - INPUT/INT_FALLING
* PA1: N_CHG - INPUT
* PA3: SPI_CLK - INPUT
* PA4: SPI_MISO - INPUT
* PA6: CS1 - OUTPUT/HIGH
* PA7: SPI_MOSI - INPUT
* PA9: USB_PU - OUTPUT/LOW
* PA15: UART TX - OUTPUT/HIGH
* PI1: SYNC1 - OUTPUT/LOW
* PI2: SYNC2 - OUTPUT/LOW
*/
STM32_GPIO_CRL(GPIO_A) = FLOAT(0) | FLOAT(1) | FLOAT(3) | FLOAT(4) |
OUT(6) | FLOAT(7);
STM32_GPIO_CRH(GPIO_A) = OUT(9) | OUT(15);
STM32_GPIO_BSRR(GPIO_A) = LOW(1) | HIGH(6) | LOW(9) | HIGH(15);
STM32_EXTI_FTSR |= INT(0);
STM32_GPIO_CRL(GPIO_I) = OUT(1) | OUT(2);
STM32_GPIO_BSRR(GPIO_I) = LOW(1) | LOW(2);
}
static void adc_init(void)
{
int id;
for (id = 0; id < 2; ++id) {
/* Enable ADC clock */
STM32_RCC_APB2ENR |= (1 << (14 + id));
/* Power on ADC if it's off */
if (!(STM32_ADC_CR2(id) & (1 << 0))) {
/* Power on ADC module */
STM32_ADC_CR2(id) |= (1 << 0); /* ADON */
/* Reset calibration */
STM32_ADC_CR2(id) |= (1 << 3); /* RSTCAL */
while (STM32_ADC_CR2(id) & (1 << 3))
;
/* A/D Calibrate */
STM32_ADC_CR2(id) |= (1 << 2); /* CAL */
while (STM32_ADC_CR2(id) & (1 << 2))
;
}
/* Set right alignment */
STM32_ADC_CR2(id) &= ~(1 << 11);
/* Set sampling time */
STM32_ADC_SMPR2(id) = ADC_SMPR_VAL;
/* Select AIN0 */
STM32_ADC_SQR3(id) &= ~0x1f;
/* Disable DMA */
STM32_ADC_CR2(id) &= ~(1 << 8);
/* Disable scan mode */
STM32_ADC_CR1(id) &= ~(1 << 8);
}
}
static void timers_init(void)
{
STM32_TIM_CR1(3) = 0x0004; /* MSB */
STM32_TIM_CR1(2) = 0x0004; /* LSB */
STM32_TIM_CR2(3) = 0x0000;
STM32_TIM_CR2(2) = 0x0020;
STM32_TIM_SMCR(3) = 0x0007 | (1 << 4);
STM32_TIM_SMCR(2) = 0x0000;
STM32_TIM_ARR(3) = 0xffff;
STM32_TIM_ARR(2) = 0xffff;
STM32_TIM_PSC(3) = 0;
STM32_TIM_PSC(2) = CPU_CLOCK / 1000000 - 1;
STM32_TIM_EGR(3) = 0x0001;
STM32_TIM_EGR(2) = 0x0001;
STM32_TIM_DIER(3) = 0x0001;
STM32_TIM_DIER(2) = 0x0000;
STM32_TIM_CR1(3) |= 1;
STM32_TIM_CR1(2) |= 1;
STM32_TIM_CNT(3) = 0;
STM32_TIM_CNT(2) = 0;
task_enable_irq(STM32_IRQ_TIM3);
task_enable_irq(STM32_IRQ_TIM2);
}
static void irq_init(void)
{
/* clear all pending interrupts */
CPU_NVIC_UNPEND(0) = 0xffffffff;
/* enable global interrupts */
asm("cpsie i");
}
static void pmse_init(void)
{
/* Use 10K-ohm pull down */
STM32_PMSE_CR |= (1 << 13);
}
void hardware_init(void)
{
power_init();
hardware_clock_init();
pins_init();
timers_init();
adc_init();
irq_init();
pmse_init();
}