Merge pull request #2132 from hierophect/stm32-f412-tinyusb

STM32: Add USB support to F412 Discovery
This commit is contained in:
Dan Halbert 2019-09-09 17:41:21 -04:00 committed by GitHub
commit 53b0b35e34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 166 additions and 247 deletions

@ -1 +1 @@
Subproject commit 00c440cb26fbea7fd367623454d8b67855f1372f Subproject commit f8081536310e5ac7a1e8c8ba9295890429a2cb6f

View File

@ -1,71 +1,35 @@
/* /*
****************************************************************************** GNU linker script for STM32F412
**
** File : LinkerScript.ld
**
** Author : Auto-generated by Ac6 System Workbench
**
** Abstract : Linker script for STM32F412ZGTx series
** 1024Kbytes FLASH and 256Kbytes RAM
**
** Set heap size, stack size and stack location according
** to application requirements.
**
** Set memory bank area and size if external memory is used.
**
** Target : STMicroelectronics STM32
**
** Distribution: The file is distributed “as is,” without any warranty
** of any kind.
**
*****************************************************************************
** @attention
**
** <h2><center>&copy; COPYRIGHT(c) 2014 Ac6</center></h2>
**
** Redistribution and use in source and binary forms, with or without modification,
** are permitted provided that the following conditions are met:
** 1. Redistributions of source code must retain the above copyright notice,
** this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** 3. Neither the name of Ac6 nor the names of its contributors
** may be used to endorse or promote products derived from this software
** without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
*****************************************************************************
*/ */
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = 0x20040000; /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */
/* Specify the memory areas */ /* Specify the memory areas */
MEMORY MEMORY
{ {
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K /* entire flash */
FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */
FLASH_FS (rx) : ORIGIN = 0x08004000, LENGTH = 48K /* sectors 1,2,3 are 16K */
FLASH_TEXT (rx) : ORIGIN = 0x08010000, LENGTH = 960K /* sector 4 is 64K, sectors 5,6,7 are 128K */
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K
} }
/* Define output sections */ /* produce a link error if there is not this amount of RAM for these sections */
_minimum_stack_size = 2K;
_minimum_heap_size = 16K;
/* Define tho top end of the stack. The stack is full descending so begins just
above last byte of RAM. Note that EABI requires the stack to be 8-byte
aligned for a call. */
_estack = ORIGIN(RAM) + LENGTH(RAM);
/* RAM extents for the garbage collector */
_ram_start = ORIGIN(RAM);
_ram_end = ORIGIN(RAM) + LENGTH(RAM);
_heap_start = _ebss; /* heap starts just after statically allocated memory */
_heap_end = 0x20020000; /* tunable */
ENTRY(Reset_Handler)
/* define output sections */
SECTIONS SECTIONS
{ {
/* The startup code goes first into FLASH */ /* The startup code goes first into FLASH */
@ -73,117 +37,69 @@ SECTIONS
{ {
. = ALIGN(4); . = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */ KEEP(*(.isr_vector)) /* Startup code */
/* This first flash block is 16K annd the isr vectors only take up
about 400 bytes. Micropython pads this with files, but this didn't
work with the size of Circuitpython's ff object. */
. = ALIGN(4); . = ALIGN(4);
} >FLASH } >FLASH_ISR
/* The program code and other data goes into FLASH */ /* The program code and other data goes into FLASH */
.text : .text :
{ {
. = ALIGN(4); . = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */ *(.text*) /* .text* sections (code) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} >FLASH
/* Constant data goes into FLASH */
.rodata :
{
. = ALIGN(4);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4); . = ALIGN(4);
} >FLASH _etext = .; /* define a global symbol at end of code */
} >FLASH_TEXT
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
.ARM : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >FLASH
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH
/* used by the startup to initialize data */ /* used by the startup to initialize data */
_sidata = LOADADDR(.data); _sidata = LOADADDR(.data);
/* Initialized data sections goes into RAM, load LMA copy after code */ /* This is the initialized data section
The program executes knowing that the data is in the RAM
but the loader puts the initial values in the FLASH (inidata).
It is one task of the startup to copy the initial values from FLASH to RAM. */
.data : .data :
{ {
. = ALIGN(4); . = ALIGN(4);
_sdata = .; /* create a global symbol at data start */ _sdata = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */
*(.data) /* .data sections */
*(.data*) /* .data* sections */ *(.data*) /* .data* sections */
. = ALIGN(4); . = ALIGN(4);
_edata = .; /* define a global symbol at data end */ _edata = .; /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */
} >RAM AT> FLASH } >RAM AT> FLASH_TEXT
/* Uninitialized data section */ /* Uninitialized data section */
. = ALIGN(4);
.bss : .bss :
{ {
/* This is used by the startup in order to initialize the .bss secion */ . = ALIGN(4);
_sbss = .; /* define a global symbol at bss start */ _sbss = .; /* define a global symbol at bss start; used by startup code */
__bss_start__ = _sbss;
*(.bss)
*(.bss*) *(.bss*)
*(COMMON) *(COMMON)
. = ALIGN(4); . = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */ _ebss = .; /* define a global symbol at bss end; used by startup code and GC */
__bss_end__ = _ebss;
} >RAM } >RAM
/* User_heap_stack section, used to check that there is enough RAM left */ /* this is to define the start of the heap, and make sure we have a minimum size */
._user_heap_stack : .heap :
{ {
. = ALIGN(8); . = ALIGN(4);
PROVIDE ( end = . ); . = . + _minimum_heap_size;
PROVIDE ( _end = . ); . = ALIGN(4);
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM } >RAM
/* this just checks there is enough RAM for the stack */
.stack :
/* Remove information from the standard libraries */
/DISCARD/ :
{ {
libc.a ( * ) . = ALIGN(4);
libm.a ( * ) . = . + _minimum_stack_size;
libgcc.a ( * ) . = ALIGN(4);
} } >RAM
.ARM.attributes 0 : { *(.ARM.attributes) } .ARM.attributes 0 : { *(.ARM.attributes) }
} }

View File

@ -1,9 +1,10 @@
USB_VID = 0x483 USB_VID = 0x239A
USB_PID = 0x572B USB_PID = 0x8056
USB_PRODUCT = "STM32F412ZG Discovery Board - CPy" USB_PRODUCT = "STM32F412ZG Discovery Board - CPy"
USB_MANUFACTURER = "STMicroelectronics" USB_MANUFACTURER = "STMicroelectronics"
DISABLE_FILESYSTEM = 1 INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = NONE
MCU_SERIES = m4 MCU_SERIES = m4
MCU_VARIANT = stm32f4 MCU_VARIANT = stm32f4

View File

@ -28,48 +28,47 @@
void stm32f4_peripherals_clocks_init(void) { void stm32f4_peripherals_clocks_init(void) {
//System clock init //System clock init
RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
/** Configure the main internal regulator output voltage
*/ /* Enable Power Control clock */
__HAL_RCC_PWR_CLK_ENABLE(); __HAL_RCC_PWR_CLK_ENABLE();
/* The voltage scaling allows optimizing the power consumption when the
* device is clocked below the maximum system frequency, to update the
* voltage scaling value regarding system frequency refer to product
* datasheet. */
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the CPU, AHB and APB busses clocks
*/ /* Enable HSE Oscillator and activate PLL with HSE as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 4; RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 72; RCC_OscInitStruct.PLL.PLLN = 200;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 3; RCC_OscInitStruct.PLL.PLLQ = 7;
RCC_OscInitStruct.PLL.PLLR = 2; RCC_OscInitStruct.PLL.PLLR = 2;
HAL_RCC_OscConfig(&RCC_OscInitStruct); HAL_RCC_OscConfig(&RCC_OscInitStruct);
/** Initializes the CPU, AHB and APB busses clocks
*/ /* Select PLLSAI output as USB clock source */
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK PeriphClkInitStruct.PLLI2S.PLLI2SM = 8;
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; PeriphClkInitStruct.PLLI2S.PLLI2SQ = 4;
PeriphClkInitStruct.PLLI2S.PLLI2SN = 192;
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_CK48;
PeriphClkInitStruct.Clk48ClockSelection = RCC_CK48CLKSOURCE_PLLI2SQ;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
* clocks dividers */
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK |
RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2); HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3);
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2S_APB1|RCC_PERIPHCLK_SDIO
|RCC_PERIPHCLK_CLK48;
PeriphClkInitStruct.PLLI2S.PLLI2SN = 50;
PeriphClkInitStruct.PLLI2S.PLLI2SM = 4;
PeriphClkInitStruct.PLLI2S.PLLI2SR = 2;
PeriphClkInitStruct.PLLI2S.PLLI2SQ = 2;
PeriphClkInitStruct.Clk48ClockSelection = RCC_CLK48CLKSOURCE_PLLQ;
PeriphClkInitStruct.SdioClockSelection = RCC_SDIOCLKSOURCE_CLK48;
PeriphClkInitStruct.PLLI2SSelection = RCC_PLLI2SCLKSOURCE_PLLSRC;
PeriphClkInitStruct.I2sApb1ClockSelection = RCC_I2SAPB1CLKSOURCE_PLLI2S;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSI, RCC_MCODIV_1);
} }

View File

@ -34,12 +34,12 @@
#ifdef STM32F411xE #ifdef STM32F411xE
#define STM32_FLASH_SIZE 0x80000 //512KiB #define STM32_FLASH_SIZE 0x80000 //512KiB
#define INTERNAL_FLASH_FILESYSTEM_SIZE 0xC000 //112KiB #define INTERNAL_FLASH_FILESYSTEM_SIZE 0xC000 //48KiB
#endif #endif
#ifdef STM32F412Zx #ifdef STM32F412Zx
#define STM32_FLASH_SIZE 0x100000 //1MB #define STM32_FLASH_SIZE 0x100000 //1MB
#define INTERNAL_FLASH_FILESYSTEM_SIZE 0xC000 //112KiB #define INTERNAL_FLASH_FILESYSTEM_SIZE 0xC000 //48KiB
#endif #endif
#define STM32_FLASH_OFFSET 0x8000000 //All STM32 chips map to this flash location #define STM32_FLASH_OFFSET 0x8000000 //All STM32 chips map to this flash location

View File

@ -33,7 +33,8 @@
#include "stm32f4xx_hal.h" #include "stm32f4xx_hal.h"
void init_usb_hardware(void) { void init_usb_hardware(void) {
// HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_RESET); //LED 2 //TODO: if future chips overload this with options, move to peripherals management.
GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitTypeDef GPIO_InitStruct = {0};
/**USB_OTG_FS GPIO Configuration /**USB_OTG_FS GPIO Configuration
PA10 ------> USB_OTG_FS_ID PA10 ------> USB_OTG_FS_ID
@ -64,12 +65,14 @@ void init_usb_hardware(void) {
GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
#ifdef STM32F412Zx
/* Configure POWER_SWITCH IO pin (F412 ONLY)*/
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
#endif
/* Peripheral clock enable */ /* Peripheral clock enable */
__HAL_RCC_USB_OTG_FS_CLK_ENABLE(); __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
// /* Peripheral interrupt init */
// HAL_NVIC_SetPriority(OTG_FS_IRQn, 0, 0);
// HAL_NVIC_EnableIRQ(OTG_FS_IRQn);
//HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_RESET); //LED 3
} }