210 lines
5.7 KiB
C
210 lines
5.7 KiB
C
|
/* Copyright 2014 The Chromium OS Authors. All rights reserved.
|
||
|
* Use of this source code is governed by a BSD-style license that can be
|
||
|
* found in the LICENSE file.
|
||
|
*/
|
||
|
/* STM32F072-discovery board configuration */
|
||
|
|
||
|
#include "common.h"
|
||
|
#include "ec_version.h"
|
||
|
#include "gpio.h"
|
||
|
#include "hooks.h"
|
||
|
#include "queue_policies.h"
|
||
|
#include "registers.h"
|
||
|
#include "spi.h"
|
||
|
#include "task.h"
|
||
|
#include "usart-stm32f0.h"
|
||
|
#include "usart_tx_dma.h"
|
||
|
#include "usart_rx_dma.h"
|
||
|
#include "usb_gpio.h"
|
||
|
#include "usb_spi.h"
|
||
|
#include "usb-stream.h"
|
||
|
#include "util.h"
|
||
|
|
||
|
/******************************************************************************
|
||
|
* Build GPIO tables and expose a subset of the GPIOs over USB.
|
||
|
*/
|
||
|
void button_event(enum gpio_signal signal);
|
||
|
|
||
|
#include "gpio_list.h"
|
||
|
|
||
|
static enum gpio_signal const usb_gpio_list[] = {
|
||
|
GPIO_USER_BUTTON,
|
||
|
GPIO_LED_U,
|
||
|
GPIO_LED_D,
|
||
|
GPIO_LED_L,
|
||
|
GPIO_LED_R,
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
* This instantiates struct usb_gpio_config const usb_gpio, plus several other
|
||
|
* variables, all named something beginning with usb_gpio_
|
||
|
*/
|
||
|
USB_GPIO_CONFIG(usb_gpio,
|
||
|
usb_gpio_list,
|
||
|
USB_IFACE_GPIO,
|
||
|
USB_EP_GPIO);
|
||
|
|
||
|
/******************************************************************************
|
||
|
* Setup USART1 as a loopback device, it just echo's back anything sent to it.
|
||
|
*/
|
||
|
static struct usart_config const loopback_usart;
|
||
|
|
||
|
static struct queue const loopback_queue =
|
||
|
QUEUE_DIRECT(64, uint8_t,
|
||
|
loopback_usart.producer,
|
||
|
loopback_usart.consumer);
|
||
|
|
||
|
static struct usart_rx_dma const loopback_rx_dma =
|
||
|
USART_RX_DMA(STM32_DMAC_CH3, 8);
|
||
|
|
||
|
static struct usart_tx_dma const loopback_tx_dma =
|
||
|
USART_TX_DMA(STM32_DMAC_CH2, 16);
|
||
|
|
||
|
static struct usart_config const loopback_usart =
|
||
|
USART_CONFIG(usart1_hw,
|
||
|
loopback_rx_dma.usart_rx,
|
||
|
loopback_tx_dma.usart_tx,
|
||
|
115200,
|
||
|
0,
|
||
|
loopback_queue,
|
||
|
loopback_queue);
|
||
|
|
||
|
/******************************************************************************
|
||
|
* Forward USART4 as a simple USB serial interface.
|
||
|
*/
|
||
|
static struct usart_config const forward_usart;
|
||
|
struct usb_stream_config const forward_usb;
|
||
|
|
||
|
static struct queue const usart_to_usb = QUEUE_DIRECT(64, uint8_t,
|
||
|
forward_usart.producer,
|
||
|
forward_usb.consumer);
|
||
|
static struct queue const usb_to_usart = QUEUE_DIRECT(64, uint8_t,
|
||
|
forward_usb.producer,
|
||
|
forward_usart.consumer);
|
||
|
|
||
|
static struct usart_tx_dma const forward_tx_dma =
|
||
|
USART_TX_DMA(STM32_DMAC_CH7, 16);
|
||
|
|
||
|
static struct usart_config const forward_usart =
|
||
|
USART_CONFIG(usart4_hw,
|
||
|
usart_rx_interrupt,
|
||
|
forward_tx_dma.usart_tx,
|
||
|
115200,
|
||
|
0,
|
||
|
usart_to_usb,
|
||
|
usb_to_usart);
|
||
|
|
||
|
#define USB_STREAM_RX_SIZE 16
|
||
|
#define USB_STREAM_TX_SIZE 16
|
||
|
|
||
|
USB_STREAM_CONFIG(forward_usb,
|
||
|
USB_IFACE_STREAM,
|
||
|
USB_STR_STREAM_NAME,
|
||
|
USB_EP_STREAM,
|
||
|
USB_STREAM_RX_SIZE,
|
||
|
USB_STREAM_TX_SIZE,
|
||
|
usb_to_usart,
|
||
|
usart_to_usb)
|
||
|
|
||
|
/******************************************************************************
|
||
|
* Handle button presses by cycling the LEDs on the board. Also run a tick
|
||
|
* handler to cycle them when they are not actively under USB control.
|
||
|
*/
|
||
|
void button_event(enum gpio_signal signal)
|
||
|
{
|
||
|
static int count;
|
||
|
|
||
|
gpio_set_level(GPIO_LED_U, (count & 0x03) == 0);
|
||
|
gpio_set_level(GPIO_LED_R, (count & 0x03) == 1);
|
||
|
gpio_set_level(GPIO_LED_D, (count & 0x03) == 2);
|
||
|
gpio_set_level(GPIO_LED_L, (count & 0x03) == 3);
|
||
|
|
||
|
count++;
|
||
|
}
|
||
|
|
||
|
void usb_gpio_tick(void)
|
||
|
{
|
||
|
if (usb_gpio.state->set_mask || usb_gpio.state->clear_mask)
|
||
|
return;
|
||
|
|
||
|
button_event(0);
|
||
|
}
|
||
|
DECLARE_HOOK(HOOK_TICK, usb_gpio_tick, HOOK_PRIO_DEFAULT);
|
||
|
|
||
|
/******************************************************************************
|
||
|
* Define the strings used in our USB descriptors.
|
||
|
*/
|
||
|
const void *const usb_strings[] = {
|
||
|
[USB_STR_DESC] = usb_string_desc,
|
||
|
[USB_STR_VENDOR] = USB_STRING_DESC("Google Inc."),
|
||
|
[USB_STR_PRODUCT] = USB_STRING_DESC("discovery-stm32f072"),
|
||
|
[USB_STR_VERSION] = USB_STRING_DESC(CROS_EC_VERSION32),
|
||
|
[USB_STR_STREAM_NAME] = USB_STRING_DESC("Forward"),
|
||
|
[USB_STR_CONSOLE_NAME] = USB_STRING_DESC("Shell"),
|
||
|
};
|
||
|
|
||
|
BUILD_ASSERT(ARRAY_SIZE(usb_strings) == USB_STR_COUNT);
|
||
|
|
||
|
|
||
|
/******************************************************************************
|
||
|
* Support SPI bridging over USB, this requires usb_spi_board_enable and
|
||
|
* usb_spi_board_disable to be defined to enable and disable the SPI bridge.
|
||
|
*/
|
||
|
|
||
|
/* SPI devices */
|
||
|
const struct spi_device_t spi_devices[] = {
|
||
|
{ CONFIG_SPI_FLASH_PORT, 0, GPIO_SPI_CS},
|
||
|
};
|
||
|
const unsigned int spi_devices_used = ARRAY_SIZE(spi_devices);
|
||
|
|
||
|
void usb_spi_board_enable(struct usb_spi_config const *config)
|
||
|
{
|
||
|
/* Remap SPI2 to DMA channels 6 and 7 */
|
||
|
STM32_SYSCFG_CFGR1 |= BIT(24);
|
||
|
|
||
|
/* Configure SPI GPIOs */
|
||
|
gpio_config_module(MODULE_SPI_FLASH, 1);
|
||
|
|
||
|
/* Set all four SPI pins to high speed */
|
||
|
STM32_GPIO_OSPEEDR(GPIO_B) |= 0xff000000;
|
||
|
|
||
|
/* Enable clocks to SPI2 module */
|
||
|
STM32_RCC_APB1ENR |= STM32_RCC_PB1_SPI2;
|
||
|
|
||
|
/* Reset SPI2 */
|
||
|
STM32_RCC_APB1RSTR |= STM32_RCC_PB1_SPI2;
|
||
|
STM32_RCC_APB1RSTR &= ~STM32_RCC_PB1_SPI2;
|
||
|
|
||
|
spi_enable(CONFIG_SPI_FLASH_PORT, 1);
|
||
|
}
|
||
|
|
||
|
void usb_spi_board_disable(struct usb_spi_config const *config)
|
||
|
{
|
||
|
spi_enable(CONFIG_SPI_FLASH_PORT, 0);
|
||
|
|
||
|
/* Disable clocks to SPI2 module */
|
||
|
STM32_RCC_APB1ENR &= ~STM32_RCC_PB1_SPI2;
|
||
|
|
||
|
/* Release SPI GPIOs */
|
||
|
gpio_config_module(MODULE_SPI_FLASH, 0);
|
||
|
}
|
||
|
|
||
|
USB_SPI_CONFIG(usb_spi, USB_IFACE_SPI, USB_EP_SPI);
|
||
|
|
||
|
/******************************************************************************
|
||
|
* Initialize board.
|
||
|
*/
|
||
|
static void board_init(void)
|
||
|
{
|
||
|
gpio_enable_interrupt(GPIO_USER_BUTTON);
|
||
|
|
||
|
queue_init(&loopback_queue);
|
||
|
queue_init(&usart_to_usb);
|
||
|
queue_init(&usb_to_usart);
|
||
|
usart_init(&loopback_usart);
|
||
|
usart_init(&forward_usart);
|
||
|
|
||
|
usb_spi_enable(&usb_spi, 1);
|
||
|
}
|
||
|
DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT);
|