Testing USB on STM32L4.
This commit is contained in:
@@ -55,6 +55,16 @@ clock_init (void)
|
||||
RCC->CFGR |= 0x03;
|
||||
while ((RCC->CFGR & 0x0C) != 0x0C)
|
||||
;
|
||||
|
||||
/* Peripheral clock selection */
|
||||
RCC->CCIPR = ( (0x00 << 26) | /* HSI48 for USB */
|
||||
(0x00 << 2) | /* PCLK for USART2 */
|
||||
(0x00 << 0) ); /* PCLK for USART1 */
|
||||
|
||||
/* Enable HSI48 clock */
|
||||
RCC->CRRCR |= 1;
|
||||
while ((RCC->CRRCR & 0x02) == 0)
|
||||
;
|
||||
}
|
||||
|
||||
static struct GPIO *const GPIO_LED = (struct GPIO *)GPIO_LED_BASE;
|
||||
|
||||
23
mcu/stm32l.h
23
mcu/stm32l.h
@@ -109,17 +109,10 @@ struct GPIO {
|
||||
};
|
||||
|
||||
#define GPIOA_BASE (AHB2PERIPH_BASE)
|
||||
#define GPIOA ((struct GPIO *) GPIOA_BASE)
|
||||
static struct GPIO *const GPIOA = (struct GPIO *)GPIOA_BASE;
|
||||
#define GPIOB_BASE (AHB2PERIPH_BASE + 0x0400)
|
||||
#define GPIOB ((struct GPIO *) GPIOB_BASE)
|
||||
#define GPIOC_BASE (AHB2PERIPH_BASE + 0x0800)
|
||||
#define GPIOC ((struct GPIO *) GPIOC_BASE)
|
||||
#define GPIOD_BASE (AHB2PERIPH_BASE + 0x0C00)
|
||||
#define GPIOD ((struct GPIO *) GPIOD_BASE)
|
||||
#define GPIOE_BASE (AHB2PERIPH_BASE + 0x1000)
|
||||
#define GPIOE ((struct GPIO *) GPIOE_BASE)
|
||||
#define GPIOH_BASE (AHB2PERIPH_BASE + 0x1C00)
|
||||
#define GPIOH ((struct GPIO *) GPIOH_BASE)
|
||||
static struct GPIO *const GPIOB = (struct GPIO *)GPIOB_BASE;
|
||||
|
||||
|
||||
struct FLASH {
|
||||
volatile uint32_t ACR;
|
||||
@@ -139,3 +132,13 @@ struct FLASH {
|
||||
|
||||
#define FLASH_R_BASE (AHB1PERIPH_BASE + 0x2000)
|
||||
static struct FLASH *const FLASH = (struct FLASH *)FLASH_R_BASE;
|
||||
|
||||
struct USB_STM32L4 {
|
||||
volatile uint16_t LPMCSR;
|
||||
volatile uint16_t reserved0;
|
||||
volatile uint16_t BCDR;
|
||||
volatile uint16_t reserved1;
|
||||
};
|
||||
|
||||
#define USB_STM32L4_BASE (0x40006854UL)
|
||||
static struct USB_STM32L4 *const USB_STM32L4 = (struct USB_STM32L4 *)USB_STM32L4_BASE;
|
||||
|
||||
@@ -47,16 +47,25 @@ static void wait (int count)
|
||||
void
|
||||
usb_lld_sys_shutdown (void)
|
||||
{
|
||||
USB_STM32L4->BCDR &= 0x7fff; /* DP disable */
|
||||
RCC->APB1ENR1 &= ~(RCC_APB1_1_USB | RCC_APB1_1_CRS);
|
||||
RCC->APB1RSTR1 |= (RCC_APB1_1_USB | RCC_APB1_1_CRS);
|
||||
}
|
||||
|
||||
struct CRS
|
||||
{
|
||||
volatile uint32_t CR;
|
||||
volatile uint32_t CFGR;
|
||||
volatile uint32_t ISR;
|
||||
volatile uint32_t ICR;
|
||||
};
|
||||
static struct CRS *const CRS = ((struct CRS *)(APB1PERIPH_BASE + 0x6000));
|
||||
|
||||
|
||||
void
|
||||
usb_lld_sys_init (void)
|
||||
{
|
||||
/* XXX: should configure CRS (clock recovery system) and HSI48 clock */
|
||||
|
||||
if ((RCC->APB1ENR1 & RCC_APB1_1_USB)
|
||||
if ((RCC->APB1ENR1 & RCC_APB1_1_USB)
|
||||
&& (RCC->APB1RSTR1 & RCC_APB1_1_USB) == 0)
|
||||
/* Make sure the device is disconnected, even after core reset. */
|
||||
{
|
||||
@@ -65,10 +74,46 @@ usb_lld_sys_init (void)
|
||||
wait (5*MHZ);
|
||||
}
|
||||
|
||||
/* Enable USB clock and CRC clock */
|
||||
RCC->APB1ENR1 |= (RCC_APB1_1_USB | RCC_APB1_1_CRS);
|
||||
RCC->APB1RSTR1 = (RCC_APB1_1_USB | RCC_APB1_1_CRS);
|
||||
RCC->APB1RSTR1 = 0;
|
||||
|
||||
USB_STM32L4->BCDR |= 0x8000; /* DP enable */
|
||||
|
||||
/* Configure CRS (clock recovery system) for HSI48 clock */
|
||||
CRS->CFGR = ( (0x00 << 31) | /* Polarity rising */
|
||||
(0x02 << 28) | /* USB SOF for Sync */
|
||||
(0x00 << 24) | /* divider = 1 */
|
||||
(0x22 << 16) | /* Frequency error limit */
|
||||
0xBB7F ); /* Reload value */
|
||||
|
||||
CRS->CR |= ( (1 << 6) | /* Automatic trimming enable */
|
||||
(1 << 5) ); /* Frequency error counter enable */
|
||||
}
|
||||
|
||||
void
|
||||
nvic_system_reset (void)
|
||||
{
|
||||
SCB->AIRCR = (0x05FA0000 | (SCB->AIRCR & 0x70) | SCB_AIRCR_SYSRESETREQ);
|
||||
asm volatile ("dsb");
|
||||
for (;;);
|
||||
}
|
||||
|
||||
const uint8_t sys_version[8] __attribute__((section(".sys.version"))) = {
|
||||
3*2+2, /* bLength */
|
||||
0x03, /* bDescriptorType = USB_STRING_DESCRIPTOR_TYPE */
|
||||
/* sys version: "3.0" */
|
||||
'3', 0, '.', 0, '0', 0,
|
||||
};
|
||||
|
||||
#if defined(USE_SYS3) || defined(USE_SYS_BOARD_ID)
|
||||
const uint32_t __attribute__((section(".sys.board_id")))
|
||||
sys_board_id = BOARD_ID;
|
||||
|
||||
const uint8_t __attribute__((section(".sys.board_name")))
|
||||
sys_board_name[] = BOARD_NAME;
|
||||
#endif
|
||||
|
||||
/* Not yet implemented, API should be reconsidered */
|
||||
|
||||
@@ -133,26 +178,3 @@ flash_erase_all_and_exec (void (*entry)(void))
|
||||
{
|
||||
(void)entry;
|
||||
}
|
||||
|
||||
void
|
||||
nvic_system_reset (void)
|
||||
{
|
||||
SCB->AIRCR = (0x05FA0000 | (SCB->AIRCR & 0x70) | SCB_AIRCR_SYSRESETREQ);
|
||||
asm volatile ("dsb");
|
||||
for (;;);
|
||||
}
|
||||
|
||||
const uint8_t sys_version[8] __attribute__((section(".sys.version"))) = {
|
||||
3*2+2, /* bLength */
|
||||
0x03, /* bDescriptorType = USB_STRING_DESCRIPTOR_TYPE */
|
||||
/* sys version: "3.0" */
|
||||
'3', 0, '.', 0, '0', 0,
|
||||
};
|
||||
|
||||
#if defined(USE_SYS3) || defined(USE_SYS_BOARD_ID)
|
||||
const uint32_t __attribute__((section(".sys.board_id")))
|
||||
sys_board_id = BOARD_ID;
|
||||
|
||||
const uint8_t __attribute__((section(".sys.board_name")))
|
||||
sys_board_name[] = BOARD_NAME;
|
||||
#endif
|
||||
|
||||
@@ -41,7 +41,7 @@ struct USB {
|
||||
volatile uint16_t reserved4;
|
||||
};
|
||||
|
||||
struct USB *const USB = (struct USB *)REG_BASE;
|
||||
static struct USB *const USB = (struct USB *)REG_BASE;
|
||||
|
||||
#define ISTR_CTR (0x8000) /* Correct TRansfer (read-only bit) */
|
||||
#define ISTR_OVR (0x4000) /* OVeR/underrun (clear-only bit) */
|
||||
|
||||
@@ -119,7 +119,7 @@ handle_setup0 (struct usb_dev *dev)
|
||||
uint8_t req_no;
|
||||
HANDLER handler;
|
||||
|
||||
pw = (uint16_t *)(PMA_ADDR + (uint8_t *)(epbuf_get_rx_addr (ENDP0) * 2));
|
||||
pw = (uint16_t *)(PMA_ADDR + (epbuf_get_rx_addr (ENDP0) * 2));
|
||||
w = *pw++;
|
||||
|
||||
dev->dev_req.type = (w & 0xff);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* usb-stm32l.c - USB driver for STM32L
|
||||
* usb-stm32l4.c - USB driver for STM32L4
|
||||
*
|
||||
* Copyright (C) 2019 Flying Stone Technology
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
@@ -29,7 +29,7 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "sys-stm32l.h"
|
||||
#include "sys-stm32l4.h"
|
||||
#include "usb_lld.h"
|
||||
#include "usb_lld_driver.h"
|
||||
|
||||
@@ -119,7 +119,7 @@ handle_setup0 (struct usb_dev *dev)
|
||||
uint8_t req_no;
|
||||
HANDLER handler;
|
||||
|
||||
pw = (uint16_t *)(PMA_ADDR + (uint8_t *)(epbuf_get_rx_addr (ENDP0)));
|
||||
pw = (uint16_t *)(PMA_ADDR + epbuf_get_rx_addr (ENDP0));
|
||||
w = *pw++;
|
||||
|
||||
dev->dev_req.type = (w & 0xff);
|
||||
@@ -174,22 +174,20 @@ usb_lld_to_pmabuf (const void *src, uint16_t addr, size_t n)
|
||||
|
||||
if ((addr & 1))
|
||||
{
|
||||
p = (uint16_t *)(PMA_ADDR + (addr - 1) * 2);
|
||||
p = (uint16_t *)(PMA_ADDR + (addr - 1));
|
||||
w = *p;
|
||||
w = (w & 0xff) | (*s++) << 8;
|
||||
*p = w;
|
||||
p += 2;
|
||||
*p++ = w;
|
||||
n--;
|
||||
}
|
||||
else
|
||||
p = (uint16_t *)(PMA_ADDR + addr * 2);
|
||||
p = (uint16_t *)(PMA_ADDR + addr);
|
||||
|
||||
while (n >= 2)
|
||||
{
|
||||
w = *s++;
|
||||
w |= (*s++) << 8;
|
||||
*p = w;
|
||||
p += 2;
|
||||
*p++ = w;
|
||||
n -= 2;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user