9 Commits

Author SHA1 Message Date
Travis Geiselbrecht
f3e38e7050 WIP - stm32f7xx use hw timers to run tickless 2015-11-23 19:28:39 -08:00
Eric Holland
eb5f888ee2 GPIO definition and LED init 2015-11-23 13:43:25 -08:00
Travis Geiselbrecht
961a556813 [platform][stm32f7xx][uart] add support for more than one active uart
At the moment still only has hard coded bits for uart 1 and 3. Things
are declared in a wonky way to avoid allocating large structures unnecessarily.
2015-11-23 12:46:34 -08:00
Gurjant Kalsi
f3ee06a0d0 [dartuino][qspi][spiflash] Setup gpio pins for the dartuino 2015-11-23 12:00:47 -08:00
Eric Holland
08112cbfe9 added qspi init calls to init.c 2015-11-22 20:07:10 -08:00
Eric Holland
c1dd65de4f first cut at adding usb fs support from disco 2015-11-20 17:35:04 -08:00
Eric Holland
61e3dd51da Merge branch 'master' into dartuino-bringup 2015-11-20 15:05:57 -08:00
Eric Holland
d877ab5da8 catch up with master 2015-11-20 14:51:31 -08:00
Eric Holland
586da5f5f4 Dartuino bringup. New target. 2015-11-20 14:18:44 -08:00
17 changed files with 1071 additions and 113 deletions

View File

@@ -162,7 +162,7 @@ static inline void arm_cm_trigger_preempt(void)
}
/* systick */
void arm_cm_systick_init(uint32_t mhz);
void arm_cm_systick_init(uint32_t mhz, bool ext_clock_source);
/* extern void _systick(void); // override this */
/* interrupt glue */

View File

@@ -41,28 +41,48 @@
#define LOCAL_TRACE 0
static volatile uint64_t ticks;
static uint32_t tick_rate = 0;
static uint32_t tick_rate_mhz = 0;
#if !PLATFORM_IMPLEMENTS_TIME_BASE
static volatile uint64_t ticks;
static lk_time_t tick_interval_ms;
static lk_bigtime_t tick_interval_us;
#endif
static platform_timer_callback cb;
static void *cb_args;
static bool periodic;
static void arm_cm_systick_set_oneshot(lk_time_t period)
{
uint32_t ticks = tick_rate_mhz * 1000 * period;
if (ticks > 0x00ffffff)
ticks = 0x00ffffff;
LTRACEF("clk_freq %u, period %u, computed ticks %u\n", tick_rate, (uint)period, ticks);
periodic = false;
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;
SysTick->VAL = 0;
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
}
static void arm_cm_systick_set_periodic(lk_time_t period)
{
LTRACEF("clk_freq %u, period %u\n", tick_rate, (uint)period);
uint32_t ticks = tick_rate_mhz * 1000 * period;
if (ticks > 0x00ffffff)
ticks = 0x00ffffff;
uint32_t ticks = tick_rate / (1000 / period);
LTRACEF("ticks %d\n", ticks);
LTRACEF("clk_freq %u, period %u, computed ticks %u\n", tick_rate, (uint)period, ticks);
periodic = true;
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;
SysTick->VAL = 0;
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
}
static void arm_cm_systick_cancel_periodic(void)
static void arm_cm_systick_cancel(void)
{
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}
@@ -70,7 +90,13 @@ static void arm_cm_systick_cancel_periodic(void)
/* main systick irq handler */
void _systick(void)
{
#if !PLATFORM_IMPLEMENTS_TIME_BASE
ticks++;
#endif
/* oneshot, so cancel the timer */
if (!periodic)
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
arm_cm_irq_entry();
@@ -84,22 +110,40 @@ void _systick(void)
arm_cm_irq_exit(resched);
}
status_t platform_set_periodic_timer(platform_timer_callback callback, void *arg, lk_time_t interval)
status_t platform_set_oneshot_timer(platform_timer_callback callback, void *arg, lk_time_t interval)
{
LTRACEF("callback %p, arg %p, interval %u\n", callback, arg, interval);
DEBUG_ASSERT(tick_rate != 0 && tick_rate_mhz != 0);
cb = callback;
cb_args = arg;
arm_cm_systick_set_oneshot(interval);
return NO_ERROR;
}
status_t platform_set_periodic_timer(platform_timer_callback callback, void *arg, lk_time_t interval)
{
LTRACEF("callback %p, arg %p, interval %u\n", callback, arg, interval);
cb = callback;
cb_args = arg;
#if !PLATFORM_IMPLEMENTS_TIME_BASE
tick_interval_ms = interval;
tick_interval_us = interval * 1000;
#endif
arm_cm_systick_set_periodic(interval);
return NO_ERROR;
}
void platform_stop_timer(void)
{
arm_cm_systick_cancel();
}
#if !PLATFORM_HAS_TIME_BASE
lk_time_t current_time(void)
{
uint32_t reload = SysTick->LOAD & SysTick_LOAD_RELOAD_Msk;
@@ -137,9 +181,18 @@ lk_bigtime_t current_time_hires(void)
return res;
}
#endif
void arm_cm_systick_init(uint32_t mhz)
void arm_cm_systick_init(uint32_t mhz, bool ext_clock_source)
{
tick_rate = mhz;
tick_rate_mhz = mhz / 1000000;
if (tick_rate_mhz * 1000000 != tick_rate) {
TRACEF("WARNING: tick mhz not evenly divisible by 1000000 (%u)\n", mhz);
}
SysTick->CTRL = 0;
if (!ext_clock_source)
SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk;
}

View File

@@ -78,6 +78,8 @@
#define LAN8742A_PHY_ADDRESS 0x00
/* DP83848 PHY Address*/
#define DP83848_PHY_ADDRESS 0x01
/* KSZ8721 PHY Address*/
#define KSZ8721_PHY_ADDRESS 0x01
struct eth_status {
ETH_HandleTypeDef EthHandle;
@@ -116,13 +118,26 @@ status_t eth_init(const uint8_t *mac_addr, eth_phy_itf eth_phy)
eth.EthHandle.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
eth.EthHandle.Init.Speed = ETH_SPEED_100M;
eth.EthHandle.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
eth.EthHandle.Init.MediaInterface =
eth_phy == PHY_DP83848 ? ETH_MEDIA_INTERFACE_MII : ETH_MEDIA_INTERFACE_RMII;
switch (eth_phy) {
case PHY_DP83848:
eth.EthHandle.Init.MediaInterface = ETH_MEDIA_INTERFACE_MII;
eth.EthHandle.Init.PhyAddress = DP83848_PHY_ADDRESS;
break;
case PHY_LAN8742A:
eth.EthHandle.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
eth.EthHandle.Init.PhyAddress = LAN8742A_PHY_ADDRESS;
break;
case PHY_KSZ8721:
eth.EthHandle.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
eth.EthHandle.Init.PhyAddress = KSZ8721_PHY_ADDRESS;
break;
default:
return ERR_NOT_CONFIGURED;
}
eth.EthHandle.Init.RxMode = ETH_RXINTERRUPT_MODE;
//eth.EthHandle.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE; // XXX icmp checksums corrupted if stack stuff valid checksum
eth.EthHandle.Init.ChecksumMode = ETH_CHECKSUM_BY_SOFTWARE;
eth.EthHandle.Init.PhyAddress =
eth_phy == PHY_DP83848 ? DP83848_PHY_ADDRESS : LAN8742A_PHY_ADDRESS;
/* configure ethernet peripheral (GPIOs, clocks, MAC, DMA) */
if (HAL_ETH_Init(&eth.EthHandle) != HAL_OK)

View File

@@ -29,7 +29,7 @@
static GPIO_TypeDef *port_to_pointer(unsigned int port)
{
DEBUG_ASSERT(port <= GPIO_PORT_I);
DEBUG_ASSERT(port <= GPIO_PORT_K);
switch (port) {
default:
@@ -51,12 +51,16 @@ static GPIO_TypeDef *port_to_pointer(unsigned int port)
return GPIOH;
case GPIO_PORT_I:
return GPIOI;
case GPIO_PORT_J:
return GPIOJ;
case GPIO_PORT_K:
return GPIOK;
}
}
static void enable_port(unsigned int port)
{
DEBUG_ASSERT(port <= GPIO_PORT_I);
DEBUG_ASSERT(port <= GPIO_PORT_K);
switch (port) {
case GPIO_PORT_A:
@@ -86,6 +90,12 @@ static void enable_port(unsigned int port)
case GPIO_PORT_I:
__HAL_RCC_GPIOI_CLK_ENABLE();
break;
case GPIO_PORT_J:
__HAL_RCC_GPIOJ_CLK_ENABLE();
break;
case GPIO_PORT_K:
__HAL_RCC_GPIOK_CLK_ENABLE();
break;
}
}

View File

@@ -28,6 +28,7 @@
typedef enum {
PHY_LAN8742A, // Microchip.
PHY_DP83848, // Texas Instruments.
PHY_KSZ8721, // Micrel
} eth_phy_itf;
struct pktbuf;

View File

@@ -11,6 +11,8 @@
/* gpio port/pin is packed into a single unsigned int in 16x:8port:8pin format */
#define GPIO(port, pin) ((unsigned int)(((port) << 8) | (pin)))
#define GPIO_TO_PIN_MASK(gpio) ((unsigned int)( 1 << ((gpio) & 0x0f)))
#define GPIO_PORT(gpio) (((gpio) >> 8) & 0xff)
#define GPIO_PIN(gpio) ((gpio) & 0xff)
#define GPIO_AFNUM(gpio) (((gpio) >> 24) & 0xf)
@@ -24,6 +26,8 @@
#define GPIO_PORT_G 6
#define GPIO_PORT_H 7
#define GPIO_PORT_I 8
#define GPIO_PORT_J 9
#define GPIO_PORT_K 10
#endif

View File

@@ -279,7 +279,7 @@ void platform_early_init(void)
// Start the systick timer
uint32_t sysclk = HAL_RCC_GetSysClockFreq();
arm_cm_systick_init(sysclk);
arm_cm_systick_init(sysclk / 8, true);
stm32_timer_early_init();
stm32_gpio_early_init();

View File

@@ -19,6 +19,13 @@ GLOBAL_COMPILEFLAGS += -DSTM32F746xx
FOUND_CHIP := true
endif
ifeq ($(STM32_CHIP),stm32f756)
GLOBAL_DEFINES += STM32F746xx
# XXX workaround for uppercasing in GLOBAL_DEFINES
GLOBAL_COMPILEFLAGS += -DSTM32F746xx
FOUND_CHIP := true
endif
ifeq ($(FOUND_CHIP),)
$(error unknown STM32F7xx chip $(STM32_CHIP))
endif
@@ -26,6 +33,8 @@ endif
LK_HEAP_IMPLEMENTATION ?= miniheap
GLOBAL_DEFINES += \
PLATFORM_HAS_DYNAMIC_TIMER=1 \
PLATFORM_HAS_TIME_BASE=1 \
PLATFORM_SUPPORTS_PANIC_SHELL=1 \
NOVM_MAX_ARENAS=2

View File

@@ -32,47 +32,71 @@
#define LOCAL_TRACE 0
static void stm32_tim_irq(uint num)
/* terminal count of the timer, a nice even boundary that uses most of the 32bit counter */
#define WRAP_INTERVAL_US (4000000000)
static volatile lk_time_t ticks;
static TIM_HandleTypeDef timer2;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
TRACEF("tim irq %d\n", num);
PANIC_UNIMPLEMENTED;
LTRACEF("WRAP\n");
// wrapping the time base counter
ticks += WRAP_INTERVAL_US / 1000;
}
void stm32_TIM3_IRQ(void)
{
stm32_tim_irq(3);
}
void stm32_TIM4_IRQ(void)
{
stm32_tim_irq(4);
}
void stm32_TIM5_IRQ(void)
{
stm32_tim_irq(5);
}
void stm32_TIM6_IRQ(void)
{
stm32_tim_irq(6);
}
void stm32_TIM7_IRQ(void)
{
stm32_tim_irq(7);
}
/* time base */
void stm32_TIM2_IRQ(void)
{
stm32_tim_irq(2);
arm_cm_irq_entry();
HAL_TIM_IRQHandler(&timer2);
arm_cm_irq_exit(false);
}
void stm32_timer_early_init(void)
{
uint32_t pclk2 = HAL_RCC_GetPCLK2Freq();
/* timer 2 - timebase */
__HAL_RCC_TIM2_CLK_ENABLE();
timer2.Instance = TIM2;
timer2.Init.Prescaler = (pclk2 / 1000000) - 1;
timer2.Init.CounterMode = TIM_COUNTERMODE_UP;
timer2.Init.Period = WRAP_INTERVAL_US;
timer2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
timer2.Init.RepetitionCounter = 0;
HAL_TIM_Base_Init(&timer2);
HAL_TIM_Base_Start_IT(&timer2);
}
void stm32_timer_init(void)
{
HAL_NVIC_EnableIRQ(TIM2_IRQn);
}
lk_time_t current_time(void)
{
uint32_t t, delta;
do {
t = ticks;
delta = __HAL_TIM_GET_COUNTER(&timer2);
DMB;
} while (ticks != t);
return t + delta / 1000;
}
lk_bigtime_t current_time_hires(void)
{
uint32_t t, delta;
do {
t = ticks;
delta = __HAL_TIM_GET_COUNTER(&timer2);
DMB;
} while (ticks != t);
return (lk_bigtime_t)t * 1000 + delta;
}

View File

@@ -26,6 +26,7 @@
#include <debug.h>
#include <stdio.h>
#include <assert.h>
#include <err.h>
#include <lib/cbuf.h>
#include <kernel/thread.h>
#include <platform/debug.h>
@@ -35,165 +36,228 @@
#include <platform/stm32.h>
#include <arch/arm/cm.h>
#ifdef ENABLE_UART1
cbuf_t uart1_rx_buf;
#define DEFAULT_FLOWCONTROL UART_HWCONTROL_NONE
#define DEFAULT_BAUDRATE 115200
#define DEFAULT_RXBUF_SIZE 16
#define NUM_UARTS 8
struct uart_instance {
UART_HandleTypeDef handle;
cbuf_t rx_buf;
};
#if ENABLE_UART1
static struct uart_instance uart1;
#ifndef UART1_FLOWCONTROL
#define UART1_FLOWCONTROL USART_HardwareFlowControl_None
#define UART1_FLOWCONTROL DEFAULT_FLOWCONTROL
#endif
#ifndef UART1_BAUDRATE
#define UART1_BAUDRATE 115200
#define UART1_BAUDRATE DEFAULT_BAUDRATE
#endif
#ifndef UART1_RXBUF_SIZE
#define UART1_RXBUF_SIZE 16
#define UART1_RXBUF_SIZE DEFAULT_RXBUF_SIZE
#endif
#endif
static UART_HandleTypeDef handle;
#if ENABLE_UART3
static struct uart_instance uart3;
#ifndef UART3_FLOWCONTROL
#define UART3_FLOWCONTROL DEFAULT_FLOWCONTROL
#endif
#ifndef UART3_BAUDRATE
#define UART3_BAUDRATE DEFAULT_BAUDRATE
#endif
#ifndef UART3_RXBUF_SIZE
#define UART3_RXBUF_SIZE DEFAULT_RXBUF_SIZE
#endif
#endif
#if ENABLE_UART2 || ENABLE_UART4 || ENABLE_UART5 || ENABLE_UART6 || ENABLE_UART7 || ENABLE_UART8
#error add support for additional uarts
#endif
static struct uart_instance * const uart[NUM_UARTS + 1] = {
#if ENABLE_UART1
[1] = &uart1,
#endif
#if ENABLE_UART3
[3] = &uart3,
#endif
};
// This function is called by HAL_UART_Init().
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
if (huart != &handle) {
// !! harcoded only for USART1, like the rest of this file.
ITM_SendChar('!');
return;
}
RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit;
/*##-1- Enable Clocks #################################*/
/* Select SysClk as source of UART clocks */
switch ((uintptr_t)huart->Instance) {
case (uintptr_t)USART1:
RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
RCC_PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_SYSCLK;
HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit);
/* Select SysClk as source of USART1 clocks */
RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
RCC_PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_SYSCLK;
HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit);
__HAL_RCC_USART1_CLK_ENABLE();
break;
case (uintptr_t)USART3:
RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART3;
RCC_PeriphClkInit.Usart3ClockSelection = RCC_USART3CLKSOURCE_SYSCLK;
HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit);
/* Enable USARTx clock */
__HAL_RCC_USART1_CLK_ENABLE();
/*##-2- Make sure the irq handler is disabled for now */
/* NVIC for USARTx */
HAL_NVIC_DisableIRQ(USART1_IRQn);
__HAL_RCC_USART3_CLK_ENABLE();
break;
default:
panic("unimplemented clock set up for uart\n");
}
}
static void usart_init1_early(USART_TypeDef *usart, uint32_t baud, uint16_t flowcontrol, int irqn)
static void usart_init_early(struct uart_instance *u, USART_TypeDef *usart, uint32_t baud, uint16_t flowcontrol)
{
handle.Instance = usart;
handle.Init.BaudRate = baud;
handle.Init.WordLength = UART_WORDLENGTH_8B;
handle.Init.StopBits = UART_STOPBITS_1;
handle.Init.Parity = UART_PARITY_NONE;
handle.Init.Mode = UART_MODE_TX_RX;
handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
handle.Init.OverSampling = UART_OVERSAMPLING_8;
HAL_UART_Init(&handle);
u->handle.Instance = usart;
u->handle.Init.BaudRate = baud;
u->handle.Init.WordLength = UART_WORDLENGTH_8B;
u->handle.Init.StopBits = UART_STOPBITS_1;
u->handle.Init.Parity = UART_PARITY_NONE;
u->handle.Init.Mode = UART_MODE_TX_RX;
u->handle.Init.HwFlowCtl = flowcontrol;
u->handle.Init.OverSampling = UART_OVERSAMPLING_8;
HAL_UART_Init(&u->handle);
}
static void usart_init1(USART_TypeDef *usart, int irqn, cbuf_t *rxbuf, size_t rxsize)
static void usart_init(struct uart_instance *u, USART_TypeDef *usart, uint irqn, size_t rxsize)
{
cbuf_initialize(rxbuf, rxsize);
cbuf_initialize(&u->rx_buf, rxsize);
/* Enable the UART Parity Error Interrupt */
__HAL_UART_ENABLE_IT(&handle, UART_IT_PE);
__HAL_UART_ENABLE_IT(&u->handle, UART_IT_PE);
/* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
__HAL_UART_ENABLE_IT(&handle, UART_IT_ERR);
__HAL_UART_ENABLE_IT(&u->handle, UART_IT_ERR);
/* Enable the UART Data Register not empty Interrupt */
__HAL_UART_ENABLE_IT(&handle, UART_IT_RXNE);
__HAL_UART_ENABLE_IT(&u->handle, UART_IT_RXNE);
HAL_NVIC_EnableIRQ(USART1_IRQn);
HAL_NVIC_EnableIRQ(irqn);
}
void uart_init_early(void)
{
#if ENABLE_UART1
usart_init1_early(USART1, UART1_BAUDRATE, 0, USART1_IRQn);
usart_init_early(uart[1], USART1, UART1_BAUDRATE, UART1_FLOWCONTROL);
#endif
#if ENABLE_UART3
usart_init_early(uart[3], USART3, UART3_BAUDRATE, UART3_FLOWCONTROL);
#endif
}
void uart_init(void)
{
#ifdef ENABLE_UART1
usart_init1(USART1, USART1_IRQn, &uart1_rx_buf, UART1_RXBUF_SIZE);
usart_init(uart[1], USART1, USART1_IRQn, UART1_RXBUF_SIZE);
#endif
#ifdef ENABLE_UART3
usart_init(uart[3], USART3, USART3_IRQn, UART3_RXBUF_SIZE);
#endif
}
void stm32_USART1_IRQ(void)
static void stm32_usart_shared_irq(struct uart_instance *u)
{
bool resched = false;
arm_cm_irq_entry();
/* UART parity error interrupt occurred -------------------------------------*/
if ((__HAL_UART_GET_IT(&handle, UART_IT_PE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&handle, UART_IT_PE) != RESET)) {
__HAL_UART_CLEAR_PEFLAG(&handle);
if ((__HAL_UART_GET_IT(&u->handle, UART_IT_PE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&u->handle, UART_IT_PE) != RESET)) {
__HAL_UART_CLEAR_PEFLAG(&u->handle);
printf("UART PARITY ERROR\n");
}
/* UART frame error interrupt occurred --------------------------------------*/
if ((__HAL_UART_GET_IT(&handle, UART_IT_FE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&handle, UART_IT_ERR) != RESET)) {
__HAL_UART_CLEAR_FEFLAG(&handle);
if ((__HAL_UART_GET_IT(&u->handle, UART_IT_FE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&u->handle, UART_IT_ERR) != RESET)) {
__HAL_UART_CLEAR_FEFLAG(&u->handle);
printf("UART FRAME ERROR\n");
}
/* UART noise error interrupt occurred --------------------------------------*/
if ((__HAL_UART_GET_IT(&handle, UART_IT_NE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&handle, UART_IT_ERR) != RESET)) {
__HAL_UART_CLEAR_NEFLAG(&handle);
if ((__HAL_UART_GET_IT(&u->handle, UART_IT_NE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&u->handle, UART_IT_ERR) != RESET)) {
__HAL_UART_CLEAR_NEFLAG(&u->handle);
printf("UART NOISE ERROR\n");
}
/* UART Over-Run interrupt occurred -----------------------------------------*/
if ((__HAL_UART_GET_IT(&handle, UART_IT_ORE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&handle, UART_IT_ERR) != RESET)) {
__HAL_UART_CLEAR_OREFLAG(&handle);
if ((__HAL_UART_GET_IT(&u->handle, UART_IT_ORE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&u->handle, UART_IT_ERR) != RESET)) {
__HAL_UART_CLEAR_OREFLAG(&u->handle);
printf("UART OVERRUN ERROR\n");
}
/* UART in mode Receiver ---------------------------------------------------*/
if ((__HAL_UART_GET_IT(&handle, UART_IT_RXNE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&handle, UART_IT_RXNE) != RESET)) {
if ((__HAL_UART_GET_IT(&u->handle, UART_IT_RXNE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&u->handle, UART_IT_RXNE) != RESET)) {
/* we got a character */
uint8_t c = (uint8_t)(handle.Instance->RDR & 0xff);
if (cbuf_write_char(&uart1_rx_buf, c, false) != 1) {
uint8_t c = (uint8_t)(u->handle.Instance->RDR & 0xff);
if (cbuf_write_char(&u->rx_buf, c, false) != 1) {
printf("WARNING: uart cbuf overrun!\n");
}
resched = true;
/* Clear RXNE interrupt flag */
__HAL_UART_SEND_REQ(&handle, UART_RXDATA_FLUSH_REQUEST);
__HAL_UART_SEND_REQ(&u->handle, UART_RXDATA_FLUSH_REQUEST);
}
/* UART in mode Transmitter ------------------------------------------------*/
if ((__HAL_UART_GET_IT(&handle, UART_IT_TXE) != RESET) &&(__HAL_UART_GET_IT_SOURCE(&handle, UART_IT_TXE) != RESET)) {
if ((__HAL_UART_GET_IT(&u->handle, UART_IT_TXE) != RESET) &&(__HAL_UART_GET_IT_SOURCE(&u->handle, UART_IT_TXE) != RESET)) {
;
}
/* UART in mode Transmitter (transmission end) -----------------------------*/
if ((__HAL_UART_GET_IT(&handle, UART_IT_TC) != RESET) &&(__HAL_UART_GET_IT_SOURCE(&handle, UART_IT_TC) != RESET)) {
if ((__HAL_UART_GET_IT(&u->handle, UART_IT_TC) != RESET) &&(__HAL_UART_GET_IT_SOURCE(&u->handle, UART_IT_TC) != RESET)) {
;
}
arm_cm_irq_exit(resched);
}
#if ENABLE_UART1
void stm32_USART1_IRQ(void)
{
stm32_usart_shared_irq(uart[1]);
}
#endif
#if ENABLE_UART3
void stm32_USART3_IRQ(void)
{
stm32_usart_shared_irq(uart[3]);
}
#endif
int uart_putc(int port, char c)
{
while (__HAL_UART_GET_FLAG(&handle, UART_FLAG_TXE) == RESET)
struct uart_instance *u = uart[port];
if (port < 0 || port > NUM_UARTS || !u)
return ERR_BAD_HANDLE;
while (__HAL_UART_GET_FLAG(&u->handle, UART_FLAG_TXE) == RESET)
;
handle.Instance->TDR = (c & (uint8_t)0xFF);
u->handle.Instance->TDR = (c & (uint8_t)0xFF);
return 1;
}
int uart_getc(int port, bool wait)
{
struct uart_instance *u = uart[port];
if (port < 0 || port > NUM_UARTS || !u)
return ERR_BAD_HANDLE;
char c;
if (cbuf_read_char(&uart1_rx_buf, &c, wait) == 0)
return -1;
if (cbuf_read_char(&u->rx_buf, &c, wait) == 0)
return ERR_IO;
return c;
}
@@ -204,11 +268,15 @@ int uart_pputc(int port, char c)
int uart_pgetc(int port)
{
if ((__HAL_UART_GET_IT(&handle, UART_IT_RXNE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&handle, UART_IT_RXNE) != RESET)) {
uint8_t c = (uint8_t)(handle.Instance->RDR & 0xff);
return c;
}
return -1;
struct uart_instance *u = uart[port];
if (port < 0 || port > NUM_UARTS || !u)
return ERR_BAD_HANDLE;
if ((__HAL_UART_GET_IT(&u->handle, UART_IT_RXNE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&u->handle, UART_IT_RXNE) != RESET)) {
uint8_t c = (uint8_t)(u->handle.Instance->RDR & 0xff);
return c;
}
return ERR_IO;
}
void uart_flush_tx(int port) {}

View File

@@ -0,0 +1,5 @@
include project/target/dartuinoP0.mk
include project/virtual/test.mk
include project/virtual/minip.mk
# Console serial port is on pins PA9(TX) and PB7(RX)

View File

@@ -0,0 +1,3 @@
LOCAL_DIR := $(GET_LOCAL_DIR)
TARGET := dartuinoP0

View File

@@ -0,0 +1,28 @@
/*
* Copyright (c) 2012 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __TARGET_DEBUGCONFIG_H
#define __TARGET_DEBUGCONFIG_H
#define DEBUG_UART 3
#endif

View File

@@ -0,0 +1,71 @@
/*
* Copyright (c) 2012 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __TARGET_GPIOCONFIG_H
#define __TARGET_GPIOCONFIG_H
#include <platform/gpio.h>
#define GPIO_LED_ON GPIO_PIN_RESET
#define GPIO_LED_OFF GPIO_PIN_SET
#define GPIO_USART3_TX GPIO(GPIO_PORT_B, 10)
#define GPIO_USART3_RX GPIO(GPIO_PORT_B, 11)
#define GPIO_LED108 GPIO(GPIO_PORT_E, 3)
#define GPIO_LED109 GPIO(GPIO_PORT_E, 4)
#define GPIO_LED110 GPIO(GPIO_PORT_E, 5)
#define GPIO_LED111 GPIO(GPIO_PORT_E, 6)
#define GPIO_LED112 GPIO(GPIO_PORT_D, 6)
#define GPIO_LED113 GPIO(GPIO_PORT_D, 7)
#define GPIO_LED114 GPIO(GPIO_PORT_J, 10)
#define GPIO_LED115 GPIO(GPIO_PORT_J, 11)
#define GPIO_SHIELD_D0 GPIO(GPIO_PORT_B, 11)
#define GPIO_SHIELD_D1 GPIO(GPIO_PORT_B, 10)
#define GPIO_SHIELD_D2 GPIO(GPIO_PORT_E, 3)
#define GPIO_SHIELD_D3 GPIO(GPIO_PORT_E, 4)
#define GPIO_SHIELD_D4 GPIO(GPIO_PORT_E, 5)
#define GPIO_SHIELD_D5 GPIO(GPIO_PORT_E, 6)
#define GPIO_SHIELD_D6 GPIO(GPIO_PORT_D, 6)
#define GPIO_SHIELD_D7 GPIO(GPIO_PORT_D, 7)
#define GPIO_SHIELD_D8 GPIO(GPIO_PORT_J, 10)
#define GPIO_SHIELD_D9 GPIO(GPIO_PORT_J, 11)
#define GPIO_SHIELD_D10 GPIO(GPIO_PORT_J, 12)
#define GPIO_SHIELD_D11 GPIO(GPIO_PORT_J, 13)
#define GPIO_SHIELD_D12 GPIO(GPIO_PORT_J, 14)
#define GPIO_SHIELD_D13 GPIO(GPIO_PORT_J, 15)
#define GPIO_SHIELD_ADC0 GPIO(GPIO_PORT_F, 6)
#define GPIO_SHIELD_ADC1 GPIO(GPIO_PORT_F, 10)
#define GPIO_SHIELD_ADC2 GPIO(GPIO_PORT_A, 3)
#define GPIO_SHIELD_ADC3 GPIO(GPIO_PORT_A, 5)
#define GPIO_SHIELD_ADC4 GPIO(GPIO_PORT_A, 6)
#define GPIO_SHIELD_ADC5 GPIO(GPIO_PORT_B, 0)
#define GPIO_SW100 GPIO(GPIO_PORT_J, 12)
#define GPIO_SW101 GPIO(GPIO_PORT_J, 13)
#define GPIO_SW102 GPIO(GPIO_PORT_J, 14)
#define GPIO_SW103 GPIO(GPIO_PORT_J, 15)
#endif

413
target/dartuinoP0/init.c Normal file
View File

@@ -0,0 +1,413 @@
/*
* Copyright (c) 2015 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <err.h>
#include <stdlib.h>
#include <debug.h>
#include <trace.h>
#include <target.h>
#include <compiler.h>
#include <dev/gpio.h>
#include <dev/usb.h>
#include <platform/stm32.h>
#include <platform/sdram.h>
#include <platform/gpio.h>
#include <platform/eth.h>
#include <platform/qspi.h>
#include <platform/n25q128a.h>
#include <target/debugconfig.h>
#include <target/gpioconfig.h>
#include <reg.h>
#if WITH_LIB_MINIP
#include <lib/minip.h>
#endif
extern void target_usb_setup(void);
const sdram_config_t target_sdram_config = {
.bus_width = SDRAM_BUS_WIDTH_16,
.cas_latency = SDRAM_CAS_LATENCY_2,
.col_bits_num = SDRAM_COLUMN_BITS_8
};
void target_early_init(void)
{
GPIO_InitTypeDef gpio_init_structure;
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOJ_CLK_ENABLE();
#if DEBUG_UART == 3
/* configure usart 3 pins */
gpio_config(GPIO_USART3_TX, GPIO_STM32_AF | GPIO_STM32_AFn(GPIO_AF7_USART3) | GPIO_PULLUP);
gpio_config(GPIO_USART3_RX, GPIO_STM32_AF | GPIO_STM32_AFn(GPIO_AF7_USART3) | GPIO_PULLUP);
#else
#error need to configure gpio pins for debug uart
#endif
gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP;
gpio_init_structure.Pull = GPIO_NOPULL;
gpio_init_structure.Speed = GPIO_SPEED_LOW;
gpio_init_structure.Pin = GPIO_TO_PIN_MASK(GPIO_LED108) | GPIO_TO_PIN_MASK(GPIO_LED109) |\
GPIO_TO_PIN_MASK(GPIO_LED110) | GPIO_TO_PIN_MASK(GPIO_LED111);
HAL_GPIO_Init(GPIOE, &gpio_init_structure);
gpio_init_structure.Pin = GPIO_TO_PIN_MASK(GPIO_LED112) | GPIO_TO_PIN_MASK(GPIO_LED113);
HAL_GPIO_Init(GPIOD, &gpio_init_structure);
gpio_init_structure.Pin = GPIO_TO_PIN_MASK(GPIO_LED114) | GPIO_TO_PIN_MASK(GPIO_LED115);
HAL_GPIO_Init(GPIOJ, &gpio_init_structure);
// Initialize to a pattern just so we know we have something
gpio_set(GPIO_LED108, GPIO_LED_ON);
gpio_set(GPIO_LED109, GPIO_LED_ON);
gpio_set(GPIO_LED110, GPIO_LED_ON);
gpio_set(GPIO_LED111, GPIO_LED_ON);
gpio_set(GPIO_LED112, GPIO_LED_ON);
gpio_set(GPIO_LED113, GPIO_LED_ON);
gpio_set(GPIO_LED114, GPIO_LED_ON);
gpio_set(GPIO_LED115, GPIO_LED_ON);
/* now that the uart gpios are configured, enable the debug uart */
stm32_debug_early_init();
/* The lcd framebuffer starts at the base of SDRAM */
}
static uint8_t* gen_mac_address(void) {
static uint8_t mac_addr[6];
for (size_t i = 0; i < sizeof(mac_addr); i++) {
mac_addr[i] = rand() & 0xff;
}
mac_addr[5] += 1;
/* unicast and locally administered */
mac_addr[0] &= ~(1<<0);
mac_addr[0] |= (1<<1);
return mac_addr;
}
void target_init(void)
{
stm32_debug_init();
qspi_flash_init(N25Q128A_FLASH_SIZE);
#if WITH_LIB_MINIP
uint8_t mac_addr[6];
gen_random_mac_address(mac_addr);
eth_init(mac_addr, PHY_LAN8742A);
/* start minip */
minip_set_macaddr(mac_addr);
uint32_t ip_addr = IPV4(192, 168, 0, 98);
uint32_t ip_mask = IPV4(255, 255, 255, 0);
uint32_t ip_gateway = IPV4_NONE;
minip_init(stm32_eth_send_minip_pkt, NULL, ip_addr, ip_mask, ip_gateway);
#endif
// start usb
target_usb_setup();
}
/*
void target_init(void)
{
uint8_t* mac_addr = gen_mac_address();
stm32_debug_init();
eth_init(mac_addr, PHY_KSZ8721);
#if WITH_LIB_MINIP
minip_set_macaddr(mac_addr);
uint32_t ip_addr = IPV4(192, 168, 0, 98);
uint32_t ip_mask = IPV4(255, 255, 255, 0);
uint32_t ip_gateway = IPV4_NONE;
minip_init(stm32_eth_send_minip_pkt, NULL, ip_addr, ip_mask, ip_gateway);
#endif
// start usb
target_usb_setup();
}
*/
/**
* @brief Initializes SDRAM GPIO.
* called back from stm32_sdram_init
*/
void stm_sdram_GPIO_init(void)
{
GPIO_InitTypeDef gpio_init_structure;
/* Enable GPIOs clock */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
/* Common GPIO configuration */
gpio_init_structure.Mode = GPIO_MODE_AF_PP;
gpio_init_structure.Pull = GPIO_PULLUP;
gpio_init_structure.Speed = GPIO_SPEED_FAST;
gpio_init_structure.Alternate = GPIO_AF12_FMC;
/* GPIOC configuration */
gpio_init_structure.Pin = GPIO_PIN_3;
HAL_GPIO_Init(GPIOC, &gpio_init_structure);
/* GPIOD configuration */
gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_3 | GPIO_PIN_8| GPIO_PIN_9 | GPIO_PIN_10 |\
GPIO_PIN_14 | GPIO_PIN_15;
HAL_GPIO_Init(GPIOD, &gpio_init_structure);
/* GPIOE configuration */
gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_7| GPIO_PIN_8 | GPIO_PIN_9 |\
GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 |\
GPIO_PIN_15;
HAL_GPIO_Init(GPIOE, &gpio_init_structure);
/* GPIOF configuration */
gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2| GPIO_PIN_3 | GPIO_PIN_4 |\
GPIO_PIN_5 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 |\
GPIO_PIN_15;
HAL_GPIO_Init(GPIOF, &gpio_init_structure);
/* GPIOG configuration */
gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4| GPIO_PIN_5 | GPIO_PIN_8 |\
GPIO_PIN_15;
HAL_GPIO_Init(GPIOG, &gpio_init_structure);
/* GPIOH configuration */
gpio_init_structure.Pin = GPIO_PIN_3 | GPIO_PIN_5;
HAL_GPIO_Init(GPIOH, &gpio_init_structure);
}
/**
* @brief Initializes the ETH MSP.
* @param heth: ETH handle
* @retval None
*/
/* called back from the HAL_ETH_Init routine */
void HAL_ETH_MspInit(ETH_HandleTypeDef *heth)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable GPIOs clocks */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
/* Ethernet pins configuration ************************************************/
/*
RMII_REF_CLK ----------------------> PA1
RMII_MDIO -------------------------> PA2
RMII_MDC --------------------------> PC1
RMII_MII_CRS_DV -------------------> PA7
RMII_MII_RXD0 ---------------------> PC4
RMII_MII_RXD1 ---------------------> PC5
RMII_MII_TX_EN --------------------> PG11
RMII_MII_TXD0 ---------------------> PG13
RMII_MII_TXD1 ---------------------> PG14
*/
/* Configure PA1, PA2 and PA7 */
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Alternate = GPIO_AF11_ETH;
GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7;
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure PC1, PC4 and PC5 */
GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5;
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Configure PG2, PG11, PG13 and PG14 */
GPIO_InitStructure.Pin = GPIO_PIN_2 | GPIO_PIN_11 | GPIO_PIN_13 | GPIO_PIN_14;
HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);
}
void HAL_QSPI_MspInit(QSPI_HandleTypeDef *hqspi)
{
GPIO_InitTypeDef GPIO_InitStruct;
/*##-1- Enable peripherals and GPIO Clocks #################################*/
/* Enable GPIO clocks */
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
/*##-2- Configure peripheral GPIO ##########################################*/
/* QSPI CS GPIO pin configuration */
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* QSPI CLK GPIO pin configuration */
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* QSPI D0 GPIO pin configuration */
GPIO_InitStruct.Pin = GPIO_PIN_11;
GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* QSPI D1 GPIO pin configuration */
GPIO_InitStruct.Pin = GPIO_PIN_12;
GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* QSPI D2 GPIO pin configuration */
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
/* QSPI D3 GPIO pin configuration */
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
}
/**
* @brief Initializes the PCD MSP.
* @param hpcd: PCD handle
* @retval None
*/
void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
{
GPIO_InitTypeDef GPIO_InitStruct;
if (hpcd->Instance == USB_OTG_FS) {
/* Configure USB FS GPIOs */
__HAL_RCC_GPIOA_CLK_ENABLE();
/* Configure DM DP Pins */
GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12);
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Enable USB FS Clock */
__HAL_RCC_USB_OTG_FS_CLK_ENABLE();
/* Set USBFS Interrupt priority */
HAL_NVIC_SetPriority(OTG_FS_IRQn, 5, 0);
/* Enable USBFS Interrupt */
HAL_NVIC_EnableIRQ(OTG_FS_IRQn);
if (hpcd->Init.low_power_enable == 1) {
/* Enable EXTI Line 18 for USB wakeup*/
__HAL_USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG();
__HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_RISING_EDGE();
__HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_IT();
/* Set EXTI Wakeup Interrupt priority*/
HAL_NVIC_SetPriority(OTG_FS_WKUP_IRQn, 0, 0);
/* Enable EXTI Interrupt */
HAL_NVIC_EnableIRQ(OTG_FS_WKUP_IRQn);
}
} else if (hpcd->Instance == USB_OTG_HS) {
/* Configure USB FS GPIOs */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
/* CLK */
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* D0 */
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* D1 D2 D3 D4 D5 D6 D7 */
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_5 |\
GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* STP */
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* NXT */
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
/* DIR */
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
__HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE();
/* Enable USB HS Clocks */
__HAL_RCC_USB_OTG_HS_CLK_ENABLE();
/* Set USBHS Interrupt to the lowest priority */
HAL_NVIC_SetPriority(OTG_HS_IRQn, 5, 0);
/* Enable USBHS Interrupt */
HAL_NVIC_EnableIRQ(OTG_HS_IRQn);
}
}

View File

@@ -0,0 +1,35 @@
LOCAL_DIR := $(GET_LOCAL_DIR)
MODULE := $(LOCAL_DIR)
STM32_CHIP := stm32f756
PLATFORM := stm32f7xx
SDRAM_SIZE := 0x00800000
SDRAM_BASE := 0xc0000000
GLOBAL_DEFINES += \
ENABLE_UART3=1 \
ENABLE_SDRAM=1 \
USE_HSE_XTAL=1 \
SDRAM_BASE=$(SDRAM_BASE) \
SDRAM_SIZE=$(SDRAM_SIZE) \
PLL_M_VALUE=8 \
PLL_N_VALUE=336 \
PLL_P_VALUE=2 \
\
PKTBUF_POOL_SIZE=16
GLOBAL_INCLUDES += $(LOCAL_DIR)/include
MODULE_SRCS += \
$(LOCAL_DIR)/init.c \
$(LOCAL_DIR)/usb.c \
MODULE_DEPS += \
include make/module.mk

219
target/dartuinoP0/usb.c Normal file
View File

@@ -0,0 +1,219 @@
/*
* Copyright (c) 2013-2015 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <err.h>
#include <debug.h>
#include <stdio.h>
#include <trace.h>
#include <target.h>
#include <compiler.h>
#include <dev/usb.h>
#include <dev/usbc.h>
#include <hw/usb.h>
#include <lk/init.h>
#define LOCAL_TRACE 0
#define W(w) (w & 0xff), (w >> 8)
#define W3(w) (w & 0xff), ((w >> 8) & 0xff), ((w >> 16) & 0xff)
/* top level device descriptor */
static const uint8_t dev_descr[] = {
0x12, /* descriptor length */
DEVICE, /* Device Descriptor type */
W(0x0200), /* USB Version */
0xff, /* class */
0xff, /* subclass */
0xff, /* protocol */
64, /* max packet size, ept0 */
W(0x9999), /* vendor */
W(0x9999), /* product */
W(0x9999), /* release */
0x2, /* manufacturer string */
0x1, /* product string */
0x0, /* serialno string */
0x1, /* num configs */
};
/* high/low speed device qualifier */
static const uint8_t devqual_descr[] = {
0x0a, /* len */
DEVICE_QUALIFIER, /* Device Qualifier type */
W(0x0200), /* USB version */
0x00, /* class */
0x00, /* subclass */
0x00, /* protocol */
64, /* max packet size, ept0 */
0x01, /* num configs */
0x00 /* reserved */
};
static const uint8_t cfg_descr[] = {
0x09, /* Length of Cfg Descr */
CONFIGURATION, /* Type of Cfg Descr */
W(0x09), /* Total Length (incl ifc, ept) */
0x00, /* # Interfaces */
0x01, /* Cfg Value */
0x00, /* Cfg String */
0xc0, /* Attributes -- self powered */
250, /* Power Consumption - 500mA */
};
static const uchar langid[] = { 0x04, 0x03, 0x09, 0x04 };
static const uint8_t if_descriptor_lowspeed[] = {
0x09, /* length */
INTERFACE, /* type */
0x01, /* interface num */
0x00, /* alternates */
0x02, /* endpoint count */
0xff, /* interface class */
0xff, /* interface subclass */
0x00, /* interface protocol */
0x00, /* string index */
/* endpoint 1 IN */
0x07, /* length */
ENDPOINT, /* type */
0x81, /* address: 1 IN */
0x02, /* type: bulk */
W(64), /* max packet size: 64 */
00, /* interval */
/* endpoint 1 OUT */
0x07, /* length */
ENDPOINT, /* type */
0x01, /* address: 1 OUT */
0x02, /* type: bulk */
W(64), /* max packet size: 64 */
00, /* interval */
};
usb_config config = {
.lowspeed = {
.device = USB_DESC_STATIC(dev_descr),
.device_qual = USB_DESC_STATIC(devqual_descr),
.config = USB_DESC_STATIC(cfg_descr),
},
.highspeed = {
.device = USB_DESC_STATIC(dev_descr),
.device_qual = USB_DESC_STATIC(devqual_descr),
.config = USB_DESC_STATIC(cfg_descr),
},
.langid = USB_DESC_STATIC(langid),
};
static status_t ep_cb_rx(ep_t endpoint, usbc_transfer_t *t);
static status_t ep_cb_tx(ep_t endpoint, usbc_transfer_t *t);
static void queue_rx(void)
{
static usbc_transfer_t transfer;
static uint8_t buf[512];
transfer.callback = &ep_cb_rx;
transfer.result = 0;
transfer.buf = &buf;
transfer.buflen = sizeof(buf);
transfer.bufpos = 0;
transfer.extra = 0;
usbc_queue_rx(1, &transfer);
}
static void queue_tx(void)
{
static usbc_transfer_t transfer;
static uint8_t buf[512];
for (uint i = 0; i < sizeof(buf); i++) {
buf[i] = ~i;
}
transfer.callback = &ep_cb_tx;
transfer.result = 0;
transfer.buf = &buf;
transfer.buflen = sizeof(buf);
transfer.bufpos = 0;
transfer.extra = 0;
usbc_queue_tx(1, &transfer);
}
static status_t ep_cb_rx(ep_t endpoint, usbc_transfer_t *t)
{
#if LOCAL_TRACE
LTRACEF("ep %u transfer %p\n", endpoint, t);
usbc_dump_transfer(t);
if (t->result >= 0) {
hexdump8(t->buf, t->bufpos);
}
#endif
if (t->result >= 0)
queue_rx();
return NO_ERROR;
}
static status_t ep_cb_tx(ep_t endpoint, usbc_transfer_t *t)
{
#if LOCAL_TRACE
LTRACEF("ep %u transfer %p\n", endpoint, t);
usbc_dump_transfer(t);
#endif
if (t->result >= 0)
queue_tx();
return NO_ERROR;
}
static status_t usb_cb(void *cookie, usb_callback_op_t op, const union usb_callback_args *args)
{
LTRACEF("cookie %p, op %u, args %p\n", cookie, op, args);
if (op == USB_CB_ONLINE) {
usbc_setup_endpoint(1, USB_IN, 0x40);
usbc_setup_endpoint(1, USB_OUT, 0x40);
queue_rx();
queue_tx();
}
return NO_ERROR;
}
void target_usb_setup(void)
{
usb_setup(&config);
printf("appending interfaces\n");
usb_append_interface_lowspeed(if_descriptor_lowspeed, sizeof(if_descriptor_lowspeed));
usb_append_interface_highspeed(if_descriptor_lowspeed, sizeof(if_descriptor_lowspeed));
usb_add_string("LK", 1);
usb_add_string("LK Industries", 2);
usb_register_callback(&usb_cb, NULL);
usb_start();
}