Added Azure RTOS components.

This commit is contained in:
imi415 2022-02-08 20:51:00 +08:00
parent d507b87178
commit 12e177d375
Signed by: imi415
GPG Key ID: 17F01E106F9F5E0A
61 changed files with 6891 additions and 119 deletions

12
.gitmodules vendored Normal file
View File

@ -0,0 +1,12 @@
[submodule "Middlewares/Third_Party/azrtos/threadx"]
path = Middlewares/Third_Party/azrtos/threadx
url = https://github.com/azure-rtos/threadx.git
[submodule "Middlewares/Third_Party/azrtos/usbx"]
path = Middlewares/Third_Party/azrtos/usbx
url = https://github.com/azure-rtos/usbx.git
[submodule "Middlewares/Third_Party/azrtos/netxduo"]
path = Middlewares/Third_Party/azrtos/netxduo
url = https://github.com/azure-rtos/netxduo.git
[submodule "Middlewares/Third_Party/azrtos/filex"]
path = Middlewares/Third_Party/azrtos/filex
url = https://github.com/azure-rtos/filex.git

View File

@ -16,9 +16,26 @@ set(TARGET_LDSCRIPT_RAM "${CMAKE_SOURCE_DIR}/STM32H750VBTx_RAM.ld")
# Copy them from Makefile
set(TARGET_C_SOURCES
"Core/Src/audio/audio_clocksel.c"
"Core/Src/audio/audio_amp.c"
"Core/Src/audio/impl/tpa6130a2_impl.c"
"Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_callback.c"
"Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_endpoint_create.c"
"Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_endpoint_destroy.c"
"Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_endpoint_reset.c"
"Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_endpoint_stall.c"
"Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_endpoint_status.c"
"Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_frame_number_get.c"
"Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_function.c"
"Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_initialize_complete.c"
"Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_initialize.c"
"Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_interrupt_handler.c"
"Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_transfer_request.c"
"Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_uninitialize.c"
"Core/Src/main.c"
"Core/Src/stm32h7xx_it.c"
"Core/Src/stm32h7xx_hal_msp.c"
"Core/Src/stm32h7xx_hal_timebase_tim.c"
"Core/Src/system_stm32h7xx.c"
"Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal.c"
"Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cortex.c"
@ -78,6 +95,7 @@ set(TARGET_C_DEFINES_RAM
# Copy them from Makefile
set(TARGET_C_INCLUDES
"Core/Inc"
"Core/Inc/azrtos/usbx_dcd"
"Drivers/STM32H7xx_HAL_Driver/Inc"
"Drivers/STM32H7xx_HAL_Driver/Inc/Legacy"
"Drivers/CMSIS/Device/ST/STM32H7xx/Include"
@ -86,6 +104,11 @@ set(TARGET_C_INCLUDES
# Shared libraries linked with application
set(TARGET_LIBS
"tpa6130"
"threadx"
"filex"
"netxduo"
"usbx"
)
# Shared library and linker script search paths
@ -114,6 +137,17 @@ set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} ${CMAKE_C_FLAGS} -x assembler-wit
set(CMAKE_EXE_LINKER_FLAGS "-specs=nano.specs -Wl,--gc-sections -lc -lm -lnosys ${TARGET_LDFLAGS_EXTRA}")
# Include sub directories here
add_subdirectory(lib/tpa6130a2)
set(THREADX_ARCH "cortex_m7")
set(THREADX_TOOLCHAIN "gnu")
set(THREADX_CUSTOM_PORT "${CMAKE_CURRENT_SOURCE_DIR}/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu" )
set(TX_USER_FILE "${CMAKE_CURRENT_SOURCE_DIR}/Core/Inc/azrtos/tx_user.h")
add_subdirectory(Middlewares/Third_Party/azrtos/threadx)
add_subdirectory(Middlewares/Third_Party/azrtos/filex)
add_subdirectory(Middlewares/Third_Party/azrtos/netxduo)
add_subdirectory(Middlewares/Third_Party/azrtos/usbx)
# Shared sources, includes and definitions
add_compile_definitions(${TARGET_C_DEFINES})

View File

@ -0,0 +1,7 @@
#ifndef AUDIO_AMP_H
#define AUDIO_AMP_H
uint8_t audio_amp_is_connected(void);
uint8_t audio_amp_power(uint8_t up);
uint8_t audio_amp_set_volume(uint8_t volume);
#endif

View File

@ -0,0 +1,13 @@
#ifndef AUDIO_CLKSEL_H
#define AUDIO_CLKSEL_H
#include <stdint.h>
typedef enum {
AUDIO_CLKIN_22M = 0,
AUDIO_CLKIN_24M = 1,
} audio_clock_t;
uint8_t audio_clock_select(audio_clock_t clock);
#endif

View File

302
Core/Inc/azrtos/tx_user.h Normal file
View File

@ -0,0 +1,302 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** User Specific */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_user.h PORTABLE C */
/* 6.1.9 */
/* */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file contains user defines for configuring ThreadX in specific */
/* ways. This file will have an effect only if the application and */
/* ThreadX library are built with TX_INCLUDE_USER_DEFINE_FILE defined. */
/* Note that all the defines in this file may also be made on the */
/* command line when building ThreadX library and application objects. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
/* resulting in version 6.1 */
/* 03-02-2021 Scott Larson Modified comment(s), */
/* added option to remove */
/* FileX pointer, */
/* resulting in version 6.1.5 */
/* 06-02-2021 Scott Larson Added options for multiple */
/* block pool search & delay, */
/* resulting in version 6.1.7 */
/* 10-15-2021 Yuxin Zhou Modified comment(s), added */
/* user-configurable symbol */
/* TX_TIMER_TICKS_PER_SECOND */
/* resulting in version 6.1.9 */
/* */
/**************************************************************************/
#ifndef TX_USER_H
#define TX_USER_H
/* Define various build options for the ThreadX port. The application should either make changes
here by commenting or un-commenting the conditional compilation defined OR supply the defines
though the compiler's equivalent of the -D option.
For maximum speed, the following should be defined:
TX_MAX_PRIORITIES 32
TX_DISABLE_PREEMPTION_THRESHOLD
TX_DISABLE_REDUNDANT_CLEARING
TX_DISABLE_NOTIFY_CALLBACKS
TX_NOT_INTERRUPTABLE
TX_TIMER_PROCESS_IN_ISR
TX_REACTIVATE_INLINE
TX_DISABLE_STACK_FILLING
TX_INLINE_THREAD_RESUME_SUSPEND
For minimum size, the following should be defined:
TX_MAX_PRIORITIES 32
TX_DISABLE_PREEMPTION_THRESHOLD
TX_DISABLE_REDUNDANT_CLEARING
TX_DISABLE_NOTIFY_CALLBACKS
TX_NO_FILEX_POINTER
TX_NOT_INTERRUPTABLE
TX_TIMER_PROCESS_IN_ISR
Of course, many of these defines reduce functionality and/or change the behavior of the
system in ways that may not be worth the trade-off. For example, the TX_TIMER_PROCESS_IN_ISR
results in faster and smaller code, however, it increases the amount of processing in the ISR.
In addition, some services that are available in timers are not available from ISRs and will
therefore return an error if this option is used. This may or may not be desirable for a
given application. */
/* Override various options with default values already assigned in tx_port.h. Please also refer
to tx_port.h for descriptions on each of these options. */
/*
#define TX_MAX_PRIORITIES 32
#define TX_MINIMUM_STACK ????
#define TX_THREAD_USER_EXTENSION ????
#define TX_TIMER_THREAD_STACK_SIZE ????
#define TX_TIMER_THREAD_PRIORITY ????
*/
/* Define the common timer tick reference for use by other middleware components. The default
value is 10ms (i.e. 100 ticks, defined in tx_api.h), but may be replaced by a port-specific
version in tx_port.h or here.
Note: the actual hardware timer value may need to be changed (usually in tx_initialize_low_level). */
/*
#define TX_TIMER_TICKS_PER_SECOND ((ULONG) 100)
*/
/* Determine if there is a FileX pointer in the thread control block.
By default, the pointer is there for legacy/backwards compatibility.
The pointer must also be there for applications using FileX.
Define this to save space in the thread control block.
*/
/*
#define TX_NO_FILEX_POINTER
*/
/* Determine if timer expirations (application timers, timeouts, and tx_thread_sleep calls
should be processed within the a system timer thread or directly in the timer ISR.
By default, the timer thread is used. When the following is defined, the timer expiration
processing is done directly from the timer ISR, thereby eliminating the timer thread control
block, stack, and context switching to activate it. */
/*
#define TX_TIMER_PROCESS_IN_ISR
*/
/* Determine if in-line timer reactivation should be used within the timer expiration processing.
By default, this is disabled and a function call is used. When the following is defined,
reactivating is performed in-line resulting in faster timer processing but slightly larger
code size. */
/*
#define TX_REACTIVATE_INLINE
*/
/* Determine is stack filling is enabled. By default, ThreadX stack filling is enabled,
which places an 0xEF pattern in each byte of each thread's stack. This is used by
debuggers with ThreadX-awareness and by the ThreadX run-time stack checking feature. */
/*
#define TX_DISABLE_STACK_FILLING
*/
/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is
disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack
checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING
define is negated, thereby forcing the stack fill which is necessary for the stack checking
logic. */
/*
#define TX_ENABLE_STACK_CHECKING
*/
/* Determine if preemption-threshold should be disabled. By default, preemption-threshold is
enabled. If the application does not use preemption-threshold, it may be disabled to reduce
code size and improve performance. */
/*
#define TX_DISABLE_PREEMPTION_THRESHOLD
*/
/* Determine if global ThreadX variables should be cleared. If the compiler startup code clears
the .bss section prior to ThreadX running, the define can be used to eliminate unnecessary
clearing of ThreadX global variables. */
/*
#define TX_DISABLE_REDUNDANT_CLEARING
*/
/* Determine if no timer processing is required. This option will help eliminate the timer
processing when not needed. The user will also have to comment out the call to
tx_timer_interrupt, which is typically made from assembly language in
tx_initialize_low_level. Note: if TX_NO_TIMER is used, the define TX_TIMER_PROCESS_IN_ISR
must also be used and tx_timer_initialize must be removed from ThreadX library. */
/*
#define TX_NO_TIMER
#ifndef TX_TIMER_PROCESS_IN_ISR
#define TX_TIMER_PROCESS_IN_ISR
#endif
*/
/* Determine if the notify callback option should be disabled. By default, notify callbacks are
enabled. If the application does not use notify callbacks, they may be disabled to reduce
code size and improve performance. */
/*
#define TX_DISABLE_NOTIFY_CALLBACKS
*/
/* Determine if the tx_thread_resume and tx_thread_suspend services should have their internal
code in-line. This results in a larger image, but improves the performance of the thread
resume and suspend services. */
/*
#define TX_INLINE_THREAD_RESUME_SUSPEND
*/
/* Determine if the internal ThreadX code is non-interruptable. This results in smaller code
size and less processing overhead, but increases the interrupt lockout time. */
/*
#define TX_NOT_INTERRUPTABLE
*/
/* Determine if the trace event logging code should be enabled. This causes slight increases in
code size and overhead, but provides the ability to generate system trace information which
is available for viewing in TraceX. */
/*
#define TX_ENABLE_EVENT_TRACE
*/
/* Determine if block pool performance gathering is required by the application. When the following is
defined, ThreadX gathers various block pool performance information. */
/*
#define TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
*/
/* Determine if byte pool performance gathering is required by the application. When the following is
defined, ThreadX gathers various byte pool performance information. */
/*
#define TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
*/
/* Determine if event flags performance gathering is required by the application. When the following is
defined, ThreadX gathers various event flags performance information. */
/*
#define TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
*/
/* Determine if mutex performance gathering is required by the application. When the following is
defined, ThreadX gathers various mutex performance information. */
/*
#define TX_MUTEX_ENABLE_PERFORMANCE_INFO
*/
/* Determine if queue performance gathering is required by the application. When the following is
defined, ThreadX gathers various queue performance information. */
/*
#define TX_QUEUE_ENABLE_PERFORMANCE_INFO
*/
/* Determine if semaphore performance gathering is required by the application. When the following is
defined, ThreadX gathers various semaphore performance information. */
/*
#define TX_SEMAPHORE_ENABLE_PERFORMANCE_INFO
*/
/* Determine if thread performance gathering is required by the application. When the following is
defined, ThreadX gathers various thread performance information. */
/*
#define TX_THREAD_ENABLE_PERFORMANCE_INFO
*/
/* Determine if timer performance gathering is required by the application. When the following is
defined, ThreadX gathers various timer performance information. */
/*
#define TX_TIMER_ENABLE_PERFORMANCE_INFO
*/
/* Override options for byte pool searches of multiple blocks. */
/*
#define TX_BYTE_POOL_MULTIPLE_BLOCK_SEARCH 20
*/
/* Override options for byte pool search delay to avoid thrashing. */
/*
#define TX_BYTE_POOL_DELAY_VALUE 3
*/
#endif

View File

@ -0,0 +1,140 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** USBX Component */
/** */
/** STM32 Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* COMPONENT DEFINITION RELEASE */
/* */
/* ux_dcd_stm32.h PORTABLE C */
/* 6.1 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file defines the USB OTG device equivalences for the STM32 */
/* controller. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* 09-30-2020 Chaoqiong Xiao Modified comment(s), used ST */
/* HAL library to drive the */
/* controller, */
/* resulting in version 6.1 */
/* */
/**************************************************************************/
#ifndef UX_DCD_STM32_H
#define UX_DCD_STM32_H
#include "ux_stm32_config.h"
/* Define STM32 generic equivalences. */
#define UX_DCD_STM32_SLAVE_CONTROLLER 0x80
#ifndef UX_DCD_STM32_MAX_ED
#define UX_DCD_STM32_MAX_ED 4
#endif /* UX_DCD_STM32_MAX_ED */
#define UX_DCD_STM32_IN_FIFO 3
#define UX_DCD_STM32_FLUSH_RX_FIFO 0x00000010
#define UX_DCD_STM32_FLUSH_TX_FIFO 0x00000020
#define UX_DCD_STM32_FLUSH_FIFO_ALL 0x00000010
#define UX_DCD_STM32_ENDPOINT_SPACE_SIZE 0x00000020
#define UX_DCD_STM32_ENDPOINT_CHANNEL_SIZE 0x00000020
/* Define USB STM32 physical endpoint status definition. */
#define UX_DCD_STM32_ED_STATUS_UNUSED 0
#define UX_DCD_STM32_ED_STATUS_USED 1
#define UX_DCD_STM32_ED_STATUS_TRANSFER 2
#define UX_DCD_STM32_ED_STATUS_STALLED 4
/* Define USB STM32 physical endpoint state machine definition. */
#define UX_DCD_STM32_ED_STATE_IDLE 0
#define UX_DCD_STM32_ED_STATE_DATA_TX 1
#define UX_DCD_STM32_ED_STATE_DATA_RX 2
#define UX_DCD_STM32_ED_STATE_STATUS_TX 3
#define UX_DCD_STM32_ED_STATE_STATUS_RX 4
/* Define USB STM32 endpoint transfer status definition. */
#define UX_DCD_STM32_ED_TRANSFER_STATUS_IDLE 0
#define UX_DCD_STM32_ED_TRANSFER_STATUS_SETUP 1
#define UX_DCD_STM32_ED_TRANSFER_STATUS_IN_COMPLETION 2
#define UX_DCD_STM32_ED_TRANSFER_STATUS_OUT_COMPLETION 3
/* Define USB STM32 physical endpoint structure. */
typedef struct UX_DCD_STM32_ED_STRUCT
{
UCHAR ux_dcd_stm32_ed_status;
UCHAR ux_dcd_stm32_ed_state;
UCHAR ux_dcd_stm32_ed_index;
UCHAR ux_dcd_stm32_ed_direction;
struct UX_SLAVE_ENDPOINT_STRUCT
*ux_dcd_stm32_ed_endpoint;
} UX_DCD_STM32_ED;
/* Define USB STM32 DCD structure definition. */
typedef struct UX_DCD_STM32_STRUCT
{
struct UX_SLAVE_DCD_STRUCT
*ux_dcd_stm32_dcd_owner;
struct UX_DCD_STM32_ED_STRUCT
ux_dcd_stm32_ed[UX_DCD_STM32_MAX_ED];
PCD_HandleTypeDef *pcd_handle;
} UX_DCD_STM32;
/* Define USB STM32 DCD prototypes. */
UINT _ux_dcd_stm32_endpoint_create(UX_DCD_STM32 *dcd_stm32, UX_SLAVE_ENDPOINT *endpoint);
UINT _ux_dcd_stm32_endpoint_destroy(UX_DCD_STM32 *dcd_stm32, UX_SLAVE_ENDPOINT *endpoint);
UINT _ux_dcd_stm32_endpoint_reset(UX_DCD_STM32 *dcd_stm32, UX_SLAVE_ENDPOINT *endpoint);
UINT _ux_dcd_stm32_endpoint_stall(UX_DCD_STM32 *dcd_stm32, UX_SLAVE_ENDPOINT *endpoint);
UINT _ux_dcd_stm32_endpoint_status(UX_DCD_STM32 *dcd_stm32, ULONG endpoint_index);
UINT _ux_dcd_stm32_frame_number_get(UX_DCD_STM32 *dcd_stm32, ULONG *frame_number);
UINT _ux_dcd_stm32_function(UX_SLAVE_DCD *dcd, UINT function, VOID *parameter);
UINT _ux_dcd_stm32_initialize_complete(VOID);
VOID _ux_dcd_stm32_interrupt_handler(VOID);
UINT _ux_dcd_stm32_transfer_request(UX_DCD_STM32 *dcd_stm32, UX_SLAVE_TRANSFER *transfer_request);
UINT _ux_dcd_stm32_initialize(ULONG dcd_io, ULONG parameter);
UINT _ux_dcd_stm32_uninitialize(ULONG dcd_io, ULONG parameter);
#define ux_dcd_stm32_initialize _ux_dcd_stm32_initialize
#define ux_dcd_stm32_interrupt_handler _ux_dcd_stm32_interrupt_handler
#endif

View File

@ -0,0 +1,50 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file ux_stm32_config.h
* @author MCD Application Team
* @brief USBX STM32 config header file
******************************************************************************
* @attention
*
* Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __UX_STM32_CONFIG_H__
#define __UX_STM32_CONFIG_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32h7xx_hal.h"
/* USER CODE BEGIN Private Includes */
/* USER CODE BEGIN Private Includes */
/* Private defines -----------------------------------------------------------*/
#define UX_DCD_STM32_MAX_ED 6
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
#ifdef __cplusplus
}
#endif
#endif /* __UX_STM32_CONFIG_H__ */

View File

@ -65,12 +65,16 @@ void Error_Handler(void);
#define LED_SR_48_GPIO_Port GPIOD
#define LED_SR_96_Pin GPIO_PIN_10
#define LED_SR_96_GPIO_Port GPIOD
#define MCU_OSC22EN_Pin GPIO_PIN_14
#define MCU_OSC22EN_GPIO_Port GPIOD
#define LED_BIT_16_Pin GPIO_PIN_6
#define LED_BIT_16_GPIO_Port GPIOC
#define LED_BIT_24_Pin GPIO_PIN_7
#define LED_BIT_24_GPIO_Port GPIOC
#define MCU_OSC_SEL_Pin GPIO_PIN_8
#define MCU_OSC_SEL_GPIO_Port GPIOC
#define MCU_OSC24EN_Pin GPIO_PIN_8
#define MCU_OSC24EN_GPIO_Port GPIOA
#define A_AMP_UP_Pin GPIO_PIN_4
#define A_AMP_UP_GPIO_Port GPIOB
/* USER CODE BEGIN Private defines */

View File

@ -74,7 +74,7 @@
/* #define HAL_SPDIFRX_MODULE_ENABLED */
/* #define HAL_SPI_MODULE_ENABLED */
/* #define HAL_SWPMI_MODULE_ENABLED */
/* #define HAL_TIM_MODULE_ENABLED */
#define HAL_TIM_MODULE_ENABLED
#define HAL_UART_MODULE_ENABLED
/* #define HAL_USART_MODULE_ENABLED */
/* #define HAL_IRDA_MODULE_ENABLED */

View File

@ -60,6 +60,7 @@ void FLASH_IRQHandler(void);
void RCC_IRQHandler(void);
void DMA1_Stream0_IRQHandler(void);
void USART1_IRQHandler(void);
void TIM7_IRQHandler(void);
void FPU_IRQHandler(void);
void QUADSPI_IRQHandler(void);
void I2C4_EV_IRQHandler(void);

174
Core/Inc/usbd_descriptors.h Normal file
View File

@ -0,0 +1,174 @@
#ifndef USBD_DESCRIPTORS_H
#define USBD_DESCRIPTORS_H
UCHAR device_framework_fs[] = {
/* Device descriptor */
0x12, // bLength
0x01, // bDescriptorType
0x00, 0x02, // bcdUSB
0xEF, // bDeviceClass !! DESCRIBED IN IAD
0x02, // bDeviceSubClass !! -^
0x01, // bDeviceProtocol !! -^
0x08, // bMaxPacketSize0
0x81, 0x07, // idVendor
0x00, 0x00, // idProduct
0x00, 0x00, // bcdDevice
0x01, // iManufacturer
0x02, // iProduct
0x03, // iSerialNumber
0x01, // bNumConfigurations
/* Configuration descriptor */
0x09, // bLength
0x02, // bDescriptorType
0x20, 0x00, // wTotalLength
0x01, // bNumInterfaces
0x01, // bConfigurationValue
0x00, // iConfiguration
0xC0, // bmAttributes
0x32, // bMaxPower
/* Interface Association descriptor <ECN> */
0x08, // bLength
0x0B, // bDescriptorType !! IAD, See ECN
0x00, // bFirstInterface
0x01, // bInterfaceCount
0x01, // bFunctionClass !! AUDIO_FUNCTION
0x00, // bFunctionSubClass !! FUNCTION_SUBCLASS_UNDEFINED
0x20, // bFunctionProtocol !! AF_VERSION_02_00
0x00, // iFunction
/* Audio Control Interface descriptor */
0x09, // bLength
0x00, // bDescriptorType
0x00, // bInterfaceNumber
};
UCHAR device_framework_hs[] = {
/* Device descriptor */
0x12,
0x01,
0x00,
0x02,
0x00,
0x00,
0x00,
0x40,
0x81,
0x07,
0x00,
0x00,
0x01,
0x00,
0x01,
0x02,
0x03,
0x01,
/* Device qualifier descriptor */
0x0a,
0x06,
0x00,
0x02,
0x00,
0x00,
0x00,
0x40,
0x01,
0x00,
/* Configuration descriptor */
0x09,
0x02,
0x20,
0x00,
0x01,
0x01,
0x00,
0xc0,
0x32,
/* Interface descriptor */
0x09,
0x04,
0x00,
0x00,
0x02,
0x08,
0x06,
0x50,
0x00,
/* Endpoint descriptor (Bulk In) */
0x07,
0x05,
0x81,
0x02,
0x00,
0x02,
0x00,
/* Endpoint descriptor (Bulk Out) */
0x07,
0x05,
0x02,
0x02,
0x00,
0x02,
0x00,
};
UCHAR string_device_framework[] = {
/* Manufacturer string descriptor : Index 1 */
0x09,
0x04,
0x01,
0x0c,
0x45,
0x78,
0x70,
0x72,
0x65,
0x73,
0x20,
0x4c,
0x6f,
0x67,
0x69,
0x63,
/* Product string descriptor : Index 2 */
0x09,
0x04,
0x02,
0x0a,
0x46,
0x6c,
0x61,
0x73,
0x68,
0x20,
0x44,
0x69,
0x73,
0x6b,
/* Serial Number string descriptor : Index 3 */
0x09,
0x04,
0x03,
0x04,
0x30,
0x30,
0x30,
0x31,
};
UCHAR language_id_framework[] = {
/* English. */
0x09,
0x04,
};
#endif

View File

@ -0,0 +1,81 @@
#include "main.h"
#include "tpa6130a2.h"
tpa6130_ret_t tpa_impl_read_reg(void *handle, uint8_t addr, uint8_t reg, uint8_t *value);
tpa6130_ret_t tpa_impl_write_reg(void *handle, uint8_t addr, uint8_t reg, uint8_t value);
extern I2C_HandleTypeDef hi2c4;
static tpa6130_t s_tpa = {
.cb =
{
.write_reg_cb = tpa_impl_write_reg,
.read_reg_cb = tpa_impl_read_reg,
},
.user_data = &hi2c4,
};
/**
* @brief Bring the amplifier out of shutdown mode,
* In shutdown mode, the AMP's registers will be resetted.
*
* @param up 0 - power down, everything else - power up
* @return uint8_t 0 - ERROR, everything else - OK
*/
uint8_t audio_amp_power(uint8_t up) {
if (up) {
HAL_GPIO_WritePin(A_AMP_UP_GPIO_Port, A_AMP_UP_Pin, GPIO_PIN_SET);
} else {
HAL_GPIO_WritePin(A_AMP_UP_GPIO_Port, A_AMP_UP_Pin, GPIO_PIN_RESET);
}
return 1;
}
/**
* @brief Check if amplifier is ready
*
* @return uint8_t 0 - disconnected, 1 - connected
*/
uint8_t audio_amp_is_connected(void) {
uint8_t rev = 0;
if (tpa6130a2_revision(&s_tpa, &rev) == TPA6130_OK) {
if (rev == 2) return 1; /* TPA6130A2's rev is 0b0010(2) */
}
return 0;
}
/**
* @brief Enable amplifiers and set volume.
*
* @param volume volume to be set (1 - 100)
* @return uint8_t 0 - ERROR, everything else - OK
*/
uint8_t audio_amp_set_volume(uint8_t volume) {
uint8_t converted_vol = 0;
if(volume > 0) {
converted_vol = (volume - 1) * 64 / 100;
}
if (tpa6130a2_enable_channel(&s_tpa, TPA6130_CH_L | TPA6130_CH_R) != TPA6130_OK) {
return 0;
}
tpa6130_ch_t mute_ch = TPA6130_CH_NONE;
if (volume == 0) {
mute_ch = TPA6130_CH_L | TPA6130_CH_R;
}
if (tpa6130a2_set_mute(&s_tpa, mute_ch) != TPA6130_OK) {
return 0;
}
if (tpa6130a2_set_volume(&s_tpa, converted_vol) != TPA6130_OK) {
return 0;
}
return 1;
}

View File

@ -0,0 +1,28 @@
#include "audio/audio_clocksel.h"
#include "main.h"
#include "stm32h7xx_hal.h"
static void audio_clock_en(audio_clock_t clock) {
if(clock == AUDIO_CLKIN_22M) {
HAL_GPIO_WritePin(MCU_OSC22EN_GPIO_Port, MCU_OSC22EN_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(MCU_OSC24EN_GPIO_Port, MCU_OSC24EN_Pin, GPIO_PIN_RESET);
} else if(clock == AUDIO_CLKIN_24M) {
HAL_GPIO_WritePin(MCU_OSC24EN_GPIO_Port, MCU_OSC24EN_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(MCU_OSC22EN_GPIO_Port, MCU_OSC22EN_Pin, GPIO_PIN_RESET);
}
}
uint8_t audio_clock_select(audio_clock_t clock) {
audio_clock_en(clock);
if (clock == AUDIO_CLKIN_22M) {
HAL_GPIO_WritePin(MCU_OSC_SEL_GPIO_Port, MCU_OSC_SEL_Pin, GPIO_PIN_RESET);
} else if (clock == AUDIO_CLKIN_24M) {
HAL_GPIO_WritePin(MCU_OSC_SEL_GPIO_Port, MCU_OSC_SEL_Pin, GPIO_PIN_SET);
} else {
return 1;
}
return 0;
}

View File

View File

@ -0,0 +1,29 @@
#include "stm32h7xx_hal.h"
#include "tpa6130a2.h"
#define AMP_TXN_TIMEOUT 1000
tpa6130_ret_t tpa_impl_read_reg(void *handle, uint8_t addr, uint8_t reg, uint8_t *value) {
I2C_HandleTypeDef *hi2c = handle;
if (HAL_I2C_Master_Transmit(hi2c, addr << 1U, &reg, 0x01, AMP_TXN_TIMEOUT) != HAL_OK) {
return TPA6130_FAIL;
}
if (HAL_I2C_Master_Receive(hi2c, addr << 1U, value, 0x01, AMP_TXN_TIMEOUT) != HAL_OK) {
return TPA6130_FAIL;
}
return TPA6130_OK;
}
tpa6130_ret_t tpa_impl_write_reg(void *handle, uint8_t addr, uint8_t reg, uint8_t value) {
I2C_HandleTypeDef *hi2c = handle;
uint8_t tx_buf[2] = {reg, value};
if (HAL_I2C_Master_Transmit(hi2c, addr << 1U, tx_buf, 0x02, AMP_TXN_TIMEOUT) != HAL_OK) {
return TPA6130_FAIL;
}
return TPA6130_OK;
}

View File

@ -0,0 +1,32 @@
/**
******************************************************************************
* @file readme.txt
* @author MCD Application Team
* @brief This file lists the main changes done by STMicroelectronics on
* USBX device controller driver
******************************************************************************
*/
### V1.0.1 / 21-June-2021 ###
=================================
Main changes
-------------
- Stop device when disconnected from the host
- Fix compile warnings
Dependencies:
-------------
- Azure RTOS USBX V6.1.7
- STM32Cube PCD HAL drivers
### V1.0.0 / 25-February-2021 ###
=================================
Main changes
-------------
- First official release of Azure RTOS USBX device controller driver for STM32 MCU series
Dependencies:
-------------
- Azure RTOS LevelX V6.1.3
- STM32Cube PCD HAL drivers

View File

@ -0,0 +1,634 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** USBX Component */
/** */
/** STM32 Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
#define UX_DCD_STM32_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_dcd_stm32.h"
#include "ux_device_stack.h"
#include "ux_utility.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* HAL_PCD_SetupStageCallback PORTABLE C */
/* 6.1 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function handles callback from HAL driver. */
/* */
/* INPUT */
/* */
/* hpcd Pointer to PCD handle */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _ux_device_stack_control_request_process */
/* Process control request */
/* HAL_PCD_EP_Transmit Transmit data */
/* HAL_PCD_EP_Receive Receive data */
/* */
/* CALLED BY */
/* */
/* STM32 HAL Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Chaoqiong Xiao Initial Version 6.1 */
/* */
/**************************************************************************/
void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
{
UX_SLAVE_DCD *dcd;
UX_DCD_STM32 *dcd_stm32;
UX_DCD_STM32_ED *ed;
UX_SLAVE_TRANSFER *transfer_request;
UX_SLAVE_ENDPOINT *endpoint;
/* Get the pointer to the DCD. */
dcd = &_ux_system_slave -> ux_system_slave_dcd;
/* Get the pointer to the STM32 DCD. */
dcd_stm32 = (UX_DCD_STM32 *) dcd -> ux_slave_dcd_controller_hardware;
/* Fetch the address of the physical endpoint. */
ed = &dcd_stm32 -> ux_dcd_stm32_ed[0];
/* Get the pointer to the transfer request. */
transfer_request = &ed -> ux_dcd_stm32_ed_endpoint -> ux_slave_endpoint_transfer_request;
/* Copy setup data to transfer request. */
_ux_utility_memory_copy(transfer_request->ux_slave_transfer_request_setup, hpcd -> Setup, UX_SETUP_SIZE);
/* Clear the length of the data received. */
transfer_request -> ux_slave_transfer_request_actual_length = 0;
/* Mark the phase as SETUP. */
transfer_request -> ux_slave_transfer_request_type = UX_TRANSFER_PHASE_SETUP;
/* Mark the transfer as successful. */
transfer_request -> ux_slave_transfer_request_completion_code = UX_SUCCESS;
/* Set the status of the endpoint to not stalled. */
ed -> ux_dcd_stm32_ed_status &= ~UX_DCD_STM32_ED_STATUS_STALLED;
/* Check if the transaction is IN. */
if (*transfer_request -> ux_slave_transfer_request_setup & UX_REQUEST_IN)
{
/* The endpoint is IN. This is important to memorize the direction for the control endpoint
in case of a STALL. */
ed -> ux_dcd_stm32_ed_direction = UX_ENDPOINT_IN;
/* Call the Control Transfer dispatcher. */
_ux_device_stack_control_request_process(transfer_request);
/* Set the state to TX. */
ed -> ux_dcd_stm32_ed_state = UX_DCD_STM32_ED_STATE_DATA_TX;
}
else
{
/* The endpoint is OUT. This is important to memorize the direction for the control endpoint
in case of a STALL. */
ed -> ux_dcd_stm32_ed_direction = UX_ENDPOINT_OUT;
/* We are in a OUT transaction. Check if there is a data payload. If so, wait for the payload
to be delivered. */
if (*(transfer_request -> ux_slave_transfer_request_setup + 6) == 0 &&
*(transfer_request -> ux_slave_transfer_request_setup + 7) == 0)
{
/* The endpoint is IN. This is important to memorize the direction for the control endpoint
in case of a STALL. */
ed -> ux_dcd_stm32_ed_direction = UX_ENDPOINT_IN;
/* Call the Control Transfer dispatcher. */
if (_ux_device_stack_control_request_process(transfer_request) == UX_SUCCESS)
{
/* Set the state to STATUS RX. */
ed -> ux_dcd_stm32_ed_state = UX_DCD_STM32_ED_STATE_STATUS_RX;
HAL_PCD_EP_Transmit(hpcd, 0x00U, UX_NULL, 0U);
}
}
else
{
/* Get the pointer to the logical endpoint from the transfer request. */
endpoint = transfer_request -> ux_slave_transfer_request_endpoint;
/* Get the length we expect from the SETUP packet. */
transfer_request -> ux_slave_transfer_request_requested_length = _ux_utility_short_get(transfer_request -> ux_slave_transfer_request_setup + 6);
/* Check if we have enough space for the request. */
if (transfer_request -> ux_slave_transfer_request_requested_length > UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH)
{
/* No space available, stall the endpoint. */
_ux_dcd_stm32_endpoint_stall(dcd_stm32, endpoint);
/* Next phase is a SETUP. */
ed -> ux_dcd_stm32_ed_state = UX_DCD_STM32_ED_STATE_IDLE;
/* We are done. */
return;
}
else
{
/* Reset what we have received so far. */
transfer_request -> ux_slave_transfer_request_actual_length = 0;
/* And reprogram the current buffer address to the beginning of the buffer. */
transfer_request -> ux_slave_transfer_request_current_data_pointer = transfer_request -> ux_slave_transfer_request_data_pointer;
/* Receive data. */
HAL_PCD_EP_Receive(hpcd,
endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress,
transfer_request -> ux_slave_transfer_request_current_data_pointer,
transfer_request -> ux_slave_transfer_request_requested_length);
/* Set the state to RX. */
ed -> ux_dcd_stm32_ed_state = UX_DCD_STM32_ED_STATE_DATA_RX;
}
}
}
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* HAL_PCD_DataInStageCallback PORTABLE C */
/* 6.1 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function handles callback from HAL driver. */
/* */
/* INPUT */
/* */
/* hpcd Pointer to PCD handle */
/* epnum Endpoint number */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _ux_utility_semaphore_put Put semaphore */
/* HAL_PCD_EP_Transmit Transmit data */
/* HAL_PCD_EP_Receive Receive data */
/* */
/* CALLED BY */
/* */
/* STM32 HAL Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Chaoqiong Xiao Initial Version 6.1 */
/* */
/**************************************************************************/
void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
{
UX_SLAVE_DCD *dcd;
UX_DCD_STM32 *dcd_stm32;
UX_DCD_STM32_ED *ed;
UX_SLAVE_TRANSFER *transfer_request;
ULONG transfer_length;
UX_SLAVE_ENDPOINT *endpoint;
/* Get the pointer to the DCD. */
dcd = &_ux_system_slave -> ux_system_slave_dcd;
/* Get the pointer to the STM32 DCD. */
dcd_stm32 = (UX_DCD_STM32 *) dcd -> ux_slave_dcd_controller_hardware;
/* Fetch the address of the physical endpoint. */
ed = &dcd_stm32 -> ux_dcd_stm32_ed[epnum & 0xF];
/* Get the pointer to the transfer request. */
transfer_request = &(ed -> ux_dcd_stm32_ed_endpoint -> ux_slave_endpoint_transfer_request);
/* Endpoint 0 is different. */
if (epnum == 0U)
{
/* Get the pointer to the logical endpoint from the transfer request. */
endpoint = transfer_request -> ux_slave_transfer_request_endpoint;
/* Check if we need to send data again on control endpoint. */
if (ed -> ux_dcd_stm32_ed_state == UX_DCD_STM32_ED_STATE_DATA_TX)
{
/* Arm Status transfer. */
HAL_PCD_EP_Receive(hpcd, 0, 0, 0);
/* Are we done with this transfer ? */
if (transfer_request -> ux_slave_transfer_request_in_transfer_length <= endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize)
{
/* There is no data to send but we may need to send a Zero Length Packet. */
if (transfer_request -> ux_slave_transfer_request_force_zlp == UX_TRUE)
{
/* Arm a ZLP packet on IN. */
HAL_PCD_EP_Transmit(hpcd,
endpoint->ux_slave_endpoint_descriptor.bEndpointAddress, 0, 0);
/* Reset the ZLP condition. */
transfer_request -> ux_slave_transfer_request_force_zlp = UX_FALSE;
}
else
{
/* Set the completion code to no error. */
transfer_request -> ux_slave_transfer_request_completion_code = UX_SUCCESS;
/* The transfer is completed. */
transfer_request -> ux_slave_transfer_request_status = UX_TRANSFER_STATUS_COMPLETED;
/* We are using a Control endpoint, if there is a callback, invoke it. We are still under ISR. */
if (transfer_request -> ux_slave_transfer_request_completion_function)
transfer_request -> ux_slave_transfer_request_completion_function (transfer_request) ;
/* State is now STATUS RX. */
ed -> ux_dcd_stm32_ed_state = UX_DCD_STM32_ED_STATE_STATUS_RX;
}
}
else
{
/* Get the size of the transfer. */
transfer_length = transfer_request -> ux_slave_transfer_request_in_transfer_length - endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize;
/* Check if the endpoint size is bigger that data requested. */
if (transfer_length > endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize)
{
/* Adjust the transfer size. */
transfer_length = endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize;
}
/* Adjust the data pointer. */
transfer_request -> ux_slave_transfer_request_current_data_pointer += endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize;
/* Adjust the transfer length remaining. */
transfer_request -> ux_slave_transfer_request_in_transfer_length -= transfer_length;
/* Transmit data. */
HAL_PCD_EP_Transmit(hpcd,
endpoint->ux_slave_endpoint_descriptor.bEndpointAddress,
transfer_request->ux_slave_transfer_request_current_data_pointer,
transfer_length);
}
}
}
else
{
/* Set the completion code to no error. */
transfer_request -> ux_slave_transfer_request_completion_code = UX_SUCCESS;
/* The transfer is completed. */
transfer_request -> ux_slave_transfer_request_status = UX_TRANSFER_STATUS_COMPLETED;
/* Non control endpoint operation, use semaphore. */
_ux_utility_semaphore_put(&transfer_request -> ux_slave_transfer_request_semaphore);
}
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* HAL_PCD_DataOutStageCallback PORTABLE C */
/* 6.1 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function handles callback from HAL driver. */
/* */
/* INPUT */
/* */
/* hpcd Pointer to PCD handle */
/* epnum Endpoint number */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _ux_device_stack_control_request_process */
/* Process control request */
/* _ux_utility_semaphore_put Put semaphore */
/* HAL_PCD_EP_Transmit Transmit data */
/* HAL_PCD_EP_Receive Receive data */
/* */
/* CALLED BY */
/* */
/* STM32 HAL Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Chaoqiong Xiao Initial Version 6.1 */
/* */
/**************************************************************************/
void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
{
UX_SLAVE_DCD *dcd;
UX_DCD_STM32 *dcd_stm32;
UX_DCD_STM32_ED *ed;
UX_SLAVE_TRANSFER *transfer_request;
ULONG transfer_length;
UX_SLAVE_ENDPOINT *endpoint;
/* Get the pointer to the DCD. */
dcd = &_ux_system_slave -> ux_system_slave_dcd;
/* Get the pointer to the STM32 DCD. */
dcd_stm32 = (UX_DCD_STM32 *) dcd -> ux_slave_dcd_controller_hardware;
/* Fetch the address of the physical endpoint. */
ed = &dcd_stm32 -> ux_dcd_stm32_ed[epnum & 0xF];
/* Get the pointer to the transfer request. */
transfer_request = &(ed -> ux_dcd_stm32_ed_endpoint -> ux_slave_endpoint_transfer_request);
/* Endpoint 0 is different. */
if (epnum == 0U)
{
/* Check if we have received something on endpoint 0 during data phase . */
if (ed -> ux_dcd_stm32_ed_state == UX_DCD_STM32_ED_STATE_DATA_RX)
{
/* Get the pointer to the logical endpoint from the transfer request. */
endpoint = transfer_request -> ux_slave_transfer_request_endpoint;
/* Read the received data length for the Control endpoint. */
transfer_length = HAL_PCD_EP_GetRxCount(hpcd, epnum);
/* Update the length of the data received. */
transfer_request -> ux_slave_transfer_request_actual_length += transfer_length;
/* Can we accept this much? */
if (transfer_request -> ux_slave_transfer_request_actual_length <=
transfer_request -> ux_slave_transfer_request_requested_length)
{
/* Are we done with this transfer ? */
if ((transfer_request -> ux_slave_transfer_request_actual_length ==
transfer_request -> ux_slave_transfer_request_requested_length) ||
(transfer_length != endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize))
{
/* Set the completion code to no error. */
transfer_request -> ux_slave_transfer_request_completion_code = UX_SUCCESS;
/* The endpoint is IN. This is important to memorize the direction for the control endpoint
in case of a STALL. */
ed -> ux_dcd_stm32_ed_direction = UX_ENDPOINT_IN;
/* We are using a Control endpoint on a OUT transaction and there was a payload. */
if (_ux_device_stack_control_request_process(transfer_request) == UX_SUCCESS)
{
/* Set the state to STATUS phase TX. */
ed -> ux_dcd_stm32_ed_state = UX_DCD_STM32_ED_STATE_STATUS_TX;
/* Arm the status transfer. */
HAL_PCD_EP_Transmit(hpcd, 0x00U, UX_NULL, 0U);
}
}
else
{
/* Rearm the OUT control endpoint for one packet. */
transfer_request -> ux_slave_transfer_request_current_data_pointer += endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize;
HAL_PCD_EP_Receive(hpcd,
endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress,
transfer_request -> ux_slave_transfer_request_current_data_pointer,
endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize);
}
}
else
{
/* We have an overflow situation. Set the completion code to overflow. */
transfer_request -> ux_slave_transfer_request_completion_code = UX_TRANSFER_BUFFER_OVERFLOW;
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_TRANSFER_BUFFER_OVERFLOW, transfer_request, 0, 0, UX_TRACE_ERRORS, 0, 0)
/* We are using a Control endpoint, if there is a callback, invoke it. We are still under ISR. */
if (transfer_request -> ux_slave_transfer_request_completion_function)
transfer_request -> ux_slave_transfer_request_completion_function (transfer_request) ;
}
}
}
else
{
/* Update the length of the data sent in previous transaction. */
transfer_request -> ux_slave_transfer_request_actual_length = HAL_PCD_EP_GetRxCount(hpcd, epnum);
/* Set the completion code to no error. */
transfer_request -> ux_slave_transfer_request_completion_code = UX_SUCCESS;
/* The transfer is completed. */
transfer_request -> ux_slave_transfer_request_status = UX_TRANSFER_STATUS_COMPLETED;
/* Non control endpoint operation, use semaphore. */
_ux_utility_semaphore_put(&transfer_request -> ux_slave_transfer_request_semaphore);
}
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* HAL_PCD_ResetCallback PORTABLE C */
/* 6.1 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function handles callback from HAL driver. */
/* */
/* INPUT */
/* */
/* hpcd Pointer to PCD handle */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _ux_device_stack_disconnect Disconnect device */
/* _ux_dcd_stm32_initialize_complete Complete initialization */
/* */
/* CALLED BY */
/* */
/* STM32 HAL Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Chaoqiong Xiao Initial Version 6.1 */
/* */
/**************************************************************************/
void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
{
/* If the device is attached or configured, we need to disconnect it. */
if (_ux_system_slave -> ux_system_slave_device.ux_slave_device_state != UX_DEVICE_RESET)
{
/* Disconnect the device. */
_ux_device_stack_disconnect();
}
/* Set USB Current Speed */
switch(hpcd -> Init.speed)
{
#ifdef PCD_SPEED_HIGH
case PCD_SPEED_HIGH:
/* We are connected at high speed. */
_ux_system_slave -> ux_system_slave_speed = UX_HIGH_SPEED_DEVICE;
break;
#endif
case PCD_SPEED_FULL:
/* We are connected at full speed. */
_ux_system_slave -> ux_system_slave_speed = UX_FULL_SPEED_DEVICE;
break;
default:
/* We are connected at full speed. */
_ux_system_slave -> ux_system_slave_speed = UX_FULL_SPEED_DEVICE;
break;
}
/* Complete the device initialization. */
_ux_dcd_stm32_initialize_complete();
/* Mark the device as attached now. */
_ux_system_slave -> ux_system_slave_device.ux_slave_device_state = UX_DEVICE_ATTACHED;
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* HAL_PCD_ResetCallback PORTABLE C */
/* 6.1 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function handles callback from HAL driver. */
/* */
/* INPUT */
/* */
/* hpcd Pointer to PCD handle */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _ux_device_stack_disconnect Disconnect device */
/* */
/* CALLED BY */
/* */
/* STM32 HAL Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Chaoqiong Xiao Initial Version 6.1 */
/* */
/**************************************************************************/
void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
{
/* Check if the device is attached or configured. */
if (_ux_system_slave -> ux_system_slave_device.ux_slave_device_state != UX_DEVICE_RESET)
{
/* Disconnect the device. */
_ux_device_stack_disconnect();
}
}

View File

@ -0,0 +1,125 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** USBX Component */
/** */
/** STM32 Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
#define UX_DCD_STM32_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_dcd_stm32.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_dcd_stm32_endpoint_create PORTABLE C */
/* 6.1 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function will create a physical endpoint. */
/* */
/* INPUT */
/* */
/* dcd_stm32 Pointer to device controller */
/* endpoint Pointer to endpoint container */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* HAL_PCD_EP_Open Open endpoint */
/* */
/* CALLED BY */
/* */
/* STM32 Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* 09-30-2020 Chaoqiong Xiao Modified comment(s), used ST */
/* HAL library to drive the */
/* controller, */
/* resulting in version 6.1 */
/* */
/**************************************************************************/
UINT _ux_dcd_stm32_endpoint_create(UX_DCD_STM32 *dcd_stm32, UX_SLAVE_ENDPOINT *endpoint)
{
UX_DCD_STM32_ED *ed;
ULONG stm32_endpoint_index;
/* The endpoint index in the array of the STM32 must match the endpoint number. */
stm32_endpoint_index = endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & ~UX_ENDPOINT_DIRECTION;
/* Fetch the address of the physical endpoint. */
ed = &dcd_stm32 -> ux_dcd_stm32_ed[stm32_endpoint_index];
/* Check the index range and endpoint status, if it is free, reserve it. If not reject this endpoint. */
if ((stm32_endpoint_index < UX_DCD_STM32_MAX_ED) && ((ed -> ux_dcd_stm32_ed_status & UX_DCD_STM32_ED_STATUS_USED) == 0))
{
/* We can use this endpoint. */
ed -> ux_dcd_stm32_ed_status |= UX_DCD_STM32_ED_STATUS_USED;
/* Keep the physical endpoint address in the endpoint container. */
endpoint -> ux_slave_endpoint_ed = (VOID *) ed;
/* Save the endpoint pointer. */
ed -> ux_dcd_stm32_ed_endpoint = endpoint;
/* And its index. */
ed -> ux_dcd_stm32_ed_index = stm32_endpoint_index;
/* And its direction. */
ed -> ux_dcd_stm32_ed_direction = endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION;
/* Check if it is non-control endpoint. */
if (stm32_endpoint_index != 0)
{
/* Open the endpoint. */
HAL_PCD_EP_Open(dcd_stm32 -> pcd_handle, endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress,
endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize,
endpoint -> ux_slave_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE);
}
/* Return successful completion. */
return(UX_SUCCESS);
}
/* Return an error. */
return(UX_NO_ED_AVAILABLE);
}

View File

@ -0,0 +1,94 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** USBX Component */
/** */
/** STM32 Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
#define UX_DCD_STM32_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_dcd_stm32.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_dcd_stm32_endpoint_destroy PORTABLE C */
/* 6.1 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function will destroy a physical endpoint. */
/* */
/* INPUT */
/* */
/* dcd_stm32 Pointer to device controller */
/* endpoint Pointer to endpoint container */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* HAL_PCD_EP_Close Deactivate endpoint */
/* */
/* CALLED BY */
/* */
/* STM32 Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* 09-30-2020 Chaoqiong Xiao Modified comment(s), used ST */
/* HAL library to drive the */
/* controller, */
/* resulting in version 6.1 */
/* */
/**************************************************************************/
UINT _ux_dcd_stm32_endpoint_destroy(UX_DCD_STM32 *dcd_stm32, UX_SLAVE_ENDPOINT *endpoint)
{
UX_DCD_STM32_ED *ed;
/* Keep the physical endpoint address in the endpoint container. */
ed = (UX_DCD_STM32_ED *) endpoint -> ux_slave_endpoint_ed;
/* We can free this endpoint. */
ed -> ux_dcd_stm32_ed_status = UX_DCD_STM32_ED_STATUS_UNUSED;
/* Deactivate the endpoint. */
HAL_PCD_EP_Close(dcd_stm32 -> pcd_handle, endpoint->ux_slave_endpoint_descriptor.bEndpointAddress);
/* This function never fails. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,98 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** USBX Component */
/** */
/** STM32 Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
#define UX_DCD_STM32_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_dcd_stm32.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_dcd_stm32_endpoint_reset PORTABLE C */
/* 6.1 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function will reset a physical endpoint. */
/* */
/* INPUT */
/* */
/* dcd_stm32 Pointer to device controller */
/* endpoint Pointer to endpoint container */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* HAL_PCD_EP_ClrStall Clear STALL */
/* */
/* CALLED BY */
/* */
/* STM32 Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* 09-30-2020 Chaoqiong Xiao Modified comment(s), used ST */
/* HAL library to drive the */
/* controller, */
/* resulting in version 6.1 */
/* */
/**************************************************************************/
UINT _ux_dcd_stm32_endpoint_reset(UX_DCD_STM32 *dcd_stm32, UX_SLAVE_ENDPOINT *endpoint)
{
UX_DCD_STM32_ED *ed;
/* Get the physical endpoint address in the endpoint container. */
ed = (UX_DCD_STM32_ED *) endpoint -> ux_slave_endpoint_ed;
/* Set the status of the endpoint to not stalled. */
ed -> ux_dcd_stm32_ed_status &= ~UX_DCD_STM32_ED_STATUS_STALLED;
/* Set the state of the endpoint to IDLE. */
ed -> ux_dcd_stm32_ed_state = UX_DCD_STM32_ED_STATE_IDLE;
/* Clear STALL condition. */
HAL_PCD_EP_ClrStall(dcd_stm32 -> pcd_handle, endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress);
/* This function never fails. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,94 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** USBX Component */
/** */
/** STM32 Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
#define UX_DCD_STM32_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_dcd_stm32.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_dcd_stm32_endpoint_stall PORTABLE C */
/* 6.1 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function will stall a physical endpoint. */
/* */
/* INPUT */
/* */
/* dcd_stm32 Pointer to device controller */
/* endpoint Pointer to endpoint container */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* HAL_PCD_EP_SetStall Set STALL condition */
/* */
/* CALLED BY */
/* */
/* STM32 Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* 09-30-2020 Chaoqiong Xiao Modified comment(s), used ST */
/* HAL library to drive the */
/* controller, */
/* resulting in version 6.1 */
/* */
/**************************************************************************/
UINT _ux_dcd_stm32_endpoint_stall(UX_DCD_STM32 *dcd_stm32, UX_SLAVE_ENDPOINT *endpoint)
{
UX_DCD_STM32_ED *ed;
/* Get the physical endpoint address in the endpoint container. */
ed = (UX_DCD_STM32_ED *) endpoint -> ux_slave_endpoint_ed;
/* Set the endpoint to stall. */
ed -> ux_dcd_stm32_ed_status |= UX_DCD_STM32_ED_STATUS_STALLED;
/* Stall the endpoint. */
HAL_PCD_EP_SetStall(dcd_stm32 -> pcd_handle, endpoint->ux_slave_endpoint_descriptor.bEndpointAddress | ed -> ux_dcd_stm32_ed_direction);
/* This function never fails. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,95 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** USBX Component */
/** */
/** STM32 Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
#define UX_DCD_STM32_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_dcd_stm32.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_dcd_stm32_endpoint_status PORTABLE C */
/* 6.1 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function will retrieve the status of the endpoint. */
/* */
/* INPUT */
/* */
/* dcd_stm32 Pointer to device controller */
/* endpoint_index Endpoint index */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* STM32 Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* 09-30-2020 Chaoqiong Xiao Modified comment(s), used ST */
/* HAL library to drive the */
/* controller, */
/* resulting in version 6.1 */
/* */
/**************************************************************************/
UINT _ux_dcd_stm32_endpoint_status(UX_DCD_STM32 *dcd_stm32, ULONG endpoint_index)
{
UX_DCD_STM32_ED *ed;
/* Fetch the address of the physical endpoint. */
ed = &dcd_stm32 -> ux_dcd_stm32_ed[endpoint_index];
/* Check the endpoint status, if it is free, we have a illegal endpoint. */
if ((ed -> ux_dcd_stm32_ed_status & UX_DCD_STM32_ED_STATUS_USED) == 0)
return(UX_ERROR);
/* Check if the endpoint is stalled. */
if ((ed -> ux_dcd_stm32_ed_status & UX_DCD_STM32_ED_STATUS_STALLED) == 0)
return(UX_FALSE);
else
return(UX_TRUE);
}

View File

@ -0,0 +1,83 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** USBX Component */
/** */
/** STM32 Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
#define UX_DCD_STM32_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_dcd_stm32.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_dcd_stm32_frame_number_get PORTABLE C */
/* 6.1 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function will return the frame number currently used by the */
/* controller. This function is mostly used for isochronous purposes. */
/* */
/* INPUT */
/* */
/* dcd_stm32 Pointer to device controller */
/* frame_number Destination for frame number */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_dcd_stm32_register_read Read register */
/* */
/* CALLED BY */
/* */
/* STM32 Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* 09-30-2020 Chaoqiong Xiao Modified comment(s), used ST */
/* HAL library to drive the */
/* controller, */
/* resulting in version 6.1 */
/* */
/**************************************************************************/
UINT _ux_dcd_stm32_frame_number_get(UX_DCD_STM32 *dcd_stm32, ULONG *frame_number)
{
/* This function never fails. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,175 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** USBX Component */
/** */
/** STM32 Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
#define UX_DCD_STM32_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_dcd_stm32.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_dcd_stm32_function PORTABLE C */
/* 6.1 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function dispatches the DCD function internally to the STM32 */
/* controller. */
/* */
/* INPUT */
/* */
/* dcd Pointer to device controller */
/* function Function requested */
/* parameter Pointer to function parameters*/
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_dcd_stm32_endpoint_create Create endpoint */
/* _ux_dcd_stm32_endpoint_destroy Destroy endpoint */
/* _ux_dcd_stm32_endpoint_reset Reset endpoint */
/* _ux_dcd_stm32_endpoint_stall Stall endpoint */
/* _ux_dcd_stm32_endpoint_status Get endpoint status */
/* _ux_dcd_stm32_frame_number_get Get frame number */
/* _ux_dcd_stm32_transfer_request Request data transfer */
/* */
/* CALLED BY */
/* */
/* USBX Device Stack */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* 09-30-2020 Chaoqiong Xiao Modified comment(s), used ST */
/* HAL library to drive the */
/* controller, */
/* resulting in version 6.1 */
/* */
/**************************************************************************/
UINT _ux_dcd_stm32_function(UX_SLAVE_DCD *dcd, UINT function, VOID *parameter)
{
UINT status = 0U;
UX_DCD_STM32 *dcd_stm32;
/* Check the status of the controller. */
if (dcd -> ux_slave_dcd_status == UX_UNUSED)
{
/* Error trap. */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_DCD, UX_CONTROLLER_UNKNOWN);
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_CONTROLLER_UNKNOWN, 0, 0, 0, UX_TRACE_ERRORS, 0, 0)
return(UX_CONTROLLER_UNKNOWN);
}
/* Get the pointer to the STM32 DCD. */
dcd_stm32 = (UX_DCD_STM32 *) dcd -> ux_slave_dcd_controller_hardware;
/* Look at the function and route it. */
switch(function)
{
case UX_DCD_GET_FRAME_NUMBER:
status = _ux_dcd_stm32_frame_number_get(dcd_stm32, (ULONG *) parameter);
break;
case UX_DCD_TRANSFER_REQUEST:
status = _ux_dcd_stm32_transfer_request(dcd_stm32, (UX_SLAVE_TRANSFER *) parameter);
break;
case UX_DCD_CREATE_ENDPOINT:
status = _ux_dcd_stm32_endpoint_create(dcd_stm32, parameter);
break;
case UX_DCD_DESTROY_ENDPOINT:
status = _ux_dcd_stm32_endpoint_destroy(dcd_stm32, parameter);
break;
case UX_DCD_RESET_ENDPOINT:
status = _ux_dcd_stm32_endpoint_reset(dcd_stm32, parameter);
break;
case UX_DCD_STALL_ENDPOINT:
status = _ux_dcd_stm32_endpoint_stall(dcd_stm32, parameter);
break;
case UX_DCD_SET_DEVICE_ADDRESS:
status = HAL_PCD_SetAddress(dcd_stm32 -> pcd_handle, (uint8_t)(ULONG) parameter);
break;
case UX_DCD_CHANGE_STATE:
if ((ULONG) parameter == UX_DEVICE_FORCE_DISCONNECT)
{
/* Disconnect the USB device */
status = HAL_PCD_Stop(dcd_stm32 -> pcd_handle);
}
break;
case UX_DCD_ENDPOINT_STATUS:
status = _ux_dcd_stm32_endpoint_status(dcd_stm32, (ULONG) parameter);
break;
default:
/* Error trap. */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_DCD, UX_FUNCTION_NOT_SUPPORTED);
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_FUNCTION_NOT_SUPPORTED, 0, 0, 0, UX_TRACE_ERRORS, 0, 0)
status = UX_FUNCTION_NOT_SUPPORTED;
break;
}
/* Return completion status. */
return(status);
}

View File

@ -0,0 +1,122 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** USBX Component */
/** */
/** STM32 Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
#define UX_DCD_STM32_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_dcd_stm32.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_dcd_stm32_initialize PORTABLE C */
/* 6.1 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function initializes the USB device controller of the STM32 */
/* microcontroller from ST. */
/* */
/* Note: only software structures that are necessary for STM32 HAL to */
/* work is initialized, STM32 HAL APIs should be used to initialize */
/* controller hardware AFTER the function is invoked. */
/* */
/* INPUT */
/* */
/* dcd Address of DCD, not used */
/* parameter Parameter, STM32 HAL PCD */
/* pointer is expected */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* HAL_PCD_Init Initialize LL driver */
/* _ux_utility_memory_allocate Allocate memory */
/* */
/* CALLED BY */
/* */
/* USBX Device Stack */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* 09-30-2020 Chaoqiong Xiao Modified comment(s), used ST */
/* HAL library to drive the */
/* controller, */
/* resulting in version 6.1 */
/* */
/**************************************************************************/
UINT _ux_dcd_stm32_initialize(ULONG dcd_io, ULONG parameter)
{
UX_SLAVE_DCD *dcd;
UX_DCD_STM32 *dcd_stm32;
UX_PARAMETER_NOT_USED(dcd_io);
/* Get the pointer to the DCD. */
dcd = &_ux_system_slave -> ux_system_slave_dcd;
/* The controller initialized here is of STM32 type. */
dcd -> ux_slave_dcd_controller_type = UX_DCD_STM32_SLAVE_CONTROLLER;
/* Allocate memory for this STM32 DCD instance. */
dcd_stm32 = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_DCD_STM32));
/* Check if memory was properly allocated. */
if(dcd_stm32 == UX_NULL)
return(UX_MEMORY_INSUFFICIENT);
/* Set the pointer to the STM32 DCD. */
dcd -> ux_slave_dcd_controller_hardware = (VOID *) dcd_stm32;
/* Set the generic DCD owner for the STM32 DCD. */
dcd_stm32 -> ux_dcd_stm32_dcd_owner = dcd;
/* Initialize the function collector for this DCD. */
dcd -> ux_slave_dcd_function = _ux_dcd_stm32_function;
dcd_stm32 -> pcd_handle = (PCD_HandleTypeDef *)parameter;
/* Set the state of the controller to OPERATIONAL now. */
dcd -> ux_slave_dcd_status = UX_DCD_STATUS_OPERATIONAL;
/* Return successful completion. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,213 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** USBX Component */
/** */
/** STM32 Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
#define UX_DCD_STM32_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_system.h"
#include "ux_utility.h"
#include "ux_dcd_stm32.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_dcd_stm32_initialize_complete PORTABLE C */
/* 6.1 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function completes the initialization of the USB slave */
/* controller for the STM32 chip. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* (ux_slave_dcd_function) Process the DCD function */
/* _ux_utility_descriptor_parse Parse descriptor */
/* _ux_utility_memory_allocate Allocate memory */
/* */
/* CALLED BY */
/* */
/* STM32 Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
/* prefixed UX to MS_TO_TICK, */
/* used ST HAL library to */
/* drive the controller, */
/* resulting in version 6.1 */
/* */
/**************************************************************************/
UINT _ux_dcd_stm32_initialize_complete(VOID)
{
UX_SLAVE_DCD *dcd;
UX_DCD_STM32 *dcd_stm32;
UX_SLAVE_DEVICE *device;
UCHAR *device_framework;
UX_SLAVE_TRANSFER *transfer_request;
/* Get the pointer to the DCD. */
dcd = &_ux_system_slave -> ux_system_slave_dcd;
/* Get the pointer to the STM32 DCD. */
dcd_stm32 = (UX_DCD_STM32 *) dcd -> ux_slave_dcd_controller_hardware;
/* Get the pointer to the device. */
device = &_ux_system_slave -> ux_system_slave_device;
/* Are we in DFU mode ? If so, check if we are in a Reset mode. */
if (_ux_system_slave -> ux_system_slave_device_dfu_state_machine == UX_SYSTEM_DFU_STATE_APP_DETACH)
{
/* The device is now in DFU reset mode. Switch to the DFU device framework. */
_ux_system_slave -> ux_system_slave_device_framework = _ux_system_slave -> ux_system_slave_dfu_framework;
_ux_system_slave -> ux_system_slave_device_framework_length = _ux_system_slave -> ux_system_slave_dfu_framework_length;
}
else
{
/* Set State to App Idle. */
_ux_system_slave -> ux_system_slave_device_dfu_state_machine = UX_SYSTEM_DFU_STATE_APP_IDLE;
/* Check the speed and set the correct descriptor. */
if (_ux_system_slave -> ux_system_slave_speed == UX_FULL_SPEED_DEVICE)
{
/* The device is operating at full speed. */
_ux_system_slave -> ux_system_slave_device_framework = _ux_system_slave -> ux_system_slave_device_framework_full_speed;
_ux_system_slave -> ux_system_slave_device_framework_length = _ux_system_slave -> ux_system_slave_device_framework_length_full_speed;
}
else
{
/* The device is operating at high speed. */
_ux_system_slave -> ux_system_slave_device_framework = _ux_system_slave -> ux_system_slave_device_framework_high_speed;
_ux_system_slave -> ux_system_slave_device_framework_length = _ux_system_slave -> ux_system_slave_device_framework_length_high_speed;
}
}
/* Get the device framework pointer. */
device_framework = _ux_system_slave -> ux_system_slave_device_framework;
/* And create the decompressed device descriptor structure. */
_ux_utility_descriptor_parse(device_framework,
_ux_system_device_descriptor_structure,
UX_DEVICE_DESCRIPTOR_ENTRIES,
(UCHAR *) &device -> ux_slave_device_descriptor);
/* Now we create a transfer request to accept the first SETUP packet
and get the ball running. First get the address of the endpoint
transfer request container. */
transfer_request = &device -> ux_slave_device_control_endpoint.ux_slave_endpoint_transfer_request;
/* Set the timeout to be for Control Endpoint. */
transfer_request -> ux_slave_transfer_request_timeout = UX_MS_TO_TICK(UX_CONTROL_TRANSFER_TIMEOUT);
/* Adjust the current data pointer as well. */
transfer_request -> ux_slave_transfer_request_current_data_pointer =
transfer_request -> ux_slave_transfer_request_data_pointer;
/* Update the transfer request endpoint pointer with the default endpoint. */
transfer_request -> ux_slave_transfer_request_endpoint = &device -> ux_slave_device_control_endpoint;
/* The control endpoint max packet size needs to be filled manually in its descriptor. */
transfer_request -> ux_slave_transfer_request_endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize =
device -> ux_slave_device_descriptor.bMaxPacketSize0;
/* On the control endpoint, always expect the maximum. */
transfer_request -> ux_slave_transfer_request_requested_length =
device -> ux_slave_device_descriptor.bMaxPacketSize0;
/* Attach the control endpoint to the transfer request. */
transfer_request -> ux_slave_transfer_request_endpoint = &device -> ux_slave_device_control_endpoint;
/* Create the default control endpoint attached to the device.
Once this endpoint is enabled, the host can then send a setup packet
The device controller will receive it and will call the setup function
module. */
dcd -> ux_slave_dcd_function(dcd, UX_DCD_CREATE_ENDPOINT,
(VOID *) &device -> ux_slave_device_control_endpoint);
/* Open Control OUT endpoint. */
HAL_PCD_EP_Open(dcd_stm32 -> pcd_handle, 0x00U, device -> ux_slave_device_descriptor.bMaxPacketSize0, UX_CONTROL_ENDPOINT);
/* Open Control IN endpoint. */
HAL_PCD_EP_Open(dcd_stm32 -> pcd_handle, 0x80U, device -> ux_slave_device_descriptor.bMaxPacketSize0, UX_CONTROL_ENDPOINT);
/* Ensure the control endpoint is properly reset. */
device -> ux_slave_device_control_endpoint.ux_slave_endpoint_state = UX_ENDPOINT_RESET;
/* Mark the phase as SETUP. */
transfer_request -> ux_slave_transfer_request_type = UX_TRANSFER_PHASE_SETUP;
/* Mark this transfer request as pending. */
transfer_request -> ux_slave_transfer_request_status = UX_TRANSFER_STATUS_PENDING;
/* Ask for 8 bytes of the SETUP packet. */
transfer_request -> ux_slave_transfer_request_requested_length = UX_SETUP_SIZE;
transfer_request -> ux_slave_transfer_request_in_transfer_length = UX_SETUP_SIZE;
/* Reset the number of bytes sent/received. */
transfer_request -> ux_slave_transfer_request_actual_length = 0;
/* Check the status change callback. */
if(_ux_system_slave -> ux_system_slave_change_function != UX_NULL)
{
/* Inform the application if a callback function was programmed. */
_ux_system_slave -> ux_system_slave_change_function(UX_DEVICE_ATTACHED);
}
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_CONNECT, 0, 0, 0, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0)
/* If trace is enabled, register this object. */
UX_TRACE_OBJECT_REGISTER(UX_TRACE_DEVICE_OBJECT_TYPE_DEVICE, device, 0, 0, 0)
/* We are now ready for the USB device to accept the first packet when connected. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,95 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** USBX Component */
/** */
/** STM32 Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
#define UX_DCD_STM32_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_dcd_stm32.h"
#include "ux_device_stack.h"
#include "ux_system.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_dcd_stm32_interrupt_handler PORTABLE C */
/* 6.1 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is the interrupt handler for the STM32 controller. */
/* The controller will trigger an interrupt when something happens on */
/* an endpoint whose mask has been set in the interrupt enable */
/* register, or when a bus reset is detected. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* HAL_PCD_IRQHandler HAL IRQ handler */
/* */
/* CALLED BY */
/* */
/* USBX Device Stack */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* 09-30-2020 Chaoqiong Xiao Modified comment(s), used ST */
/* HAL library to drive the */
/* controller, */
/* resulting in version 6.1 */
/* */
/**************************************************************************/
VOID _ux_dcd_stm32_interrupt_handler(VOID)
{
UX_SLAVE_DCD *dcd;
UX_DCD_STM32 *dcd_stm32;
/* Get the pointer to the DCD. */
dcd = &_ux_system_slave -> ux_system_slave_dcd;
/* Get the pointer to the STM32 DCD. */
dcd_stm32 = (UX_DCD_STM32 *) dcd -> ux_slave_dcd_controller_hardware;
/* Call the actual interrupt handler function. */
HAL_PCD_IRQHandler(dcd_stm32 -> pcd_handle);
}

View File

@ -0,0 +1,162 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** USBX Component */
/** */
/** STM32 Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
#define UX_DCD_STM32_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_dcd_stm32.h"
#include "ux_utility.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_dcd_stm32_transfer_request PORTABLE C */
/* 6.1 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function will initiate a transfer to a specific endpoint. */
/* If the endpoint is IN, the endpoint register will be set to accept */
/* the request. */
/* */
/* If the endpoint is IN, the endpoint FIFO will be filled with the */
/* buffer and the endpoint register set. */
/* */
/* INPUT */
/* */
/* dcd_stm32 Pointer to device controller */
/* transfer_request Pointer to transfer request */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* */
/* CALLS */
/* */
/* HAL_PCD_EP_Transmit Transmit data */
/* HAL_PCD_EP_Receive Receive data */
/* _ux_utility_semaphore_get Get semaphore */
/* */
/* CALLED BY */
/* */
/* STM32 Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* 09-30-2020 Chaoqiong Xiao Modified comment(s), used ST */
/* HAL library to drive the */
/* controller, */
/* resulting in version 6.1 */
/* */
/**************************************************************************/
UINT _ux_dcd_stm32_transfer_request(UX_DCD_STM32 *dcd_stm32, UX_SLAVE_TRANSFER *transfer_request)
{
UX_SLAVE_ENDPOINT *endpoint;
UINT status;
/* Get the pointer to the logical endpoint from the transfer request. */
endpoint = transfer_request -> ux_slave_transfer_request_endpoint;
/* Check for transfer direction. Is this a IN endpoint ? */
if (transfer_request -> ux_slave_transfer_request_phase == UX_TRANSFER_PHASE_DATA_OUT)
{
/* Transmit data. */
HAL_PCD_EP_Transmit(dcd_stm32 -> pcd_handle,
endpoint->ux_slave_endpoint_descriptor.bEndpointAddress,
transfer_request->ux_slave_transfer_request_data_pointer,
transfer_request->ux_slave_transfer_request_requested_length);
/* If the endpoint is a Control endpoint, all this is happening under Interrupt and there is no
thread to suspend. */
if ((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & (UINT)~UX_ENDPOINT_DIRECTION) != 0)
{
/* We should wait for the semaphore to wake us up. */
status = _ux_utility_semaphore_get(&transfer_request -> ux_slave_transfer_request_semaphore, UX_WAIT_FOREVER);
/* Check the completion code. */
if (status != UX_SUCCESS)
return(status);
transfer_request -> ux_slave_transfer_request_actual_length = transfer_request->ux_slave_transfer_request_requested_length;
/* Check the transfer request completion code. We may have had a BUS reset or
a device disconnection. */
if (transfer_request -> ux_slave_transfer_request_completion_code != UX_SUCCESS)
return(transfer_request -> ux_slave_transfer_request_completion_code);
/* Return to caller with success. */
return(UX_SUCCESS);
}
}
else
{
/* We have a request for a SETUP or OUT Endpoint. */
/* Receive data. */
HAL_PCD_EP_Receive(dcd_stm32 -> pcd_handle,
endpoint->ux_slave_endpoint_descriptor.bEndpointAddress,
transfer_request->ux_slave_transfer_request_data_pointer,
transfer_request->ux_slave_transfer_request_requested_length);
/* If the endpoint is a Control endpoint, all this is happening under Interrupt and there is no
thread to suspend. */
if ((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & (UINT)~UX_ENDPOINT_DIRECTION) != 0)
{
/* We should wait for the semaphore to wake us up. */
status = _ux_utility_semaphore_get(&transfer_request -> ux_slave_transfer_request_semaphore, UX_WAIT_FOREVER);
/* Check the completion code. */
if (status != UX_SUCCESS)
return(status);
/* Check the transfer request completion code. We may have had a BUS reset or
a device disconnection. */
if (transfer_request -> ux_slave_transfer_request_completion_code != UX_SUCCESS)
return(transfer_request -> ux_slave_transfer_request_completion_code);
/* Return to caller with success. */
return(UX_SUCCESS);
}
}
/* Return to caller with success. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,105 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** USBX Component */
/** */
/** STM32 Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
#define UX_DCD_STM32_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_dcd_stm32.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_dcd_stm32_uninitialize PORTABLE C */
/* 6.1 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function uninitializes the USB device controller of the STM32 */
/* microcontroller from ST. */
/* */
/* Note: only software structures are uninitialized. STM32 HAL APIs */
/* must be used to uninitialize controller hardware BEFORE the */
/* function is invoked. */
/* */
/* INPUT */
/* */
/* dcd Address of DCD, not used */
/* parameter Parameter, STM32 HAL PCD */
/* pointer is expected */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* */
/* CALLED BY */
/* */
/* USBX Device Stack */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Chaoqiong Xiao Initial Version 6.1 */
/* */
/**************************************************************************/
UINT _ux_dcd_stm32_uninitialize(ULONG dcd_io, ULONG parameter)
{
UX_SLAVE_DCD *dcd;
UX_DCD_STM32 *dcd_stm32;
UX_PARAMETER_NOT_USED(dcd_io);
/* Get the pointer to the DCD. */
dcd = &_ux_system_slave -> ux_system_slave_dcd;
/* Set the state of the controller to HALTED now. */
dcd -> ux_slave_dcd_status = UX_DCD_STATUS_HALTED;
/* Get controller driver. */
dcd_stm32 = (UX_DCD_STM32 *)dcd -> ux_slave_dcd_controller_hardware;
/* Check parameter. */
if ((ULONG)dcd_stm32 -> pcd_handle == parameter)
{
_ux_utility_memory_free(dcd_stm32);
dcd -> ux_slave_dcd_controller_hardware = UX_NULL;
return(UX_SUCCESS);
}
/* Parameter not correct. */
return(UX_ERROR);
}

View File

@ -23,6 +23,18 @@
/* USER CODE BEGIN Includes */
#include <string.h>
#include <math.h>
#include "audio/audio_amp.h"
#include "audio/audio_clocksel.h"
#include "tx_api.h"
#include "ux_api.h"
#include "ux_system.h"
#include "ux_utility.h"
#include "ux_dcd_stm32.h"
#include "ux_device_class_audio.h"
#include "ux_device_class_audio20.h"
#include "ux_device_stack.h"
/* USER CODE END Includes */
@ -66,7 +78,6 @@ PCD_HandleTypeDef hpcd_USB_OTG_FS;
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MPU_Config(void);
static void MX_GPIO_Init(void);
static void MX_RAMECC_Init(void);
static void MX_QUADSPI_Init(void);
@ -82,18 +93,85 @@ static void MX_USB_OTG_FS_PCD_Init(void);
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint8_t __ALIGNED(4) da_data[1024];
extern void *_tx_initialize_unused_memory;
static uint8_t tx_block_memory[65536];
void sai_error_cb(SAI_HandleTypeDef *hsai) {
for(;;) {
TX_THREAD led_thread;
UX_DEVICE_CLASS_AUDIO_PARAMETER audio_param;
#include "usbd_descriptors.h"
static void usb_init(void) {
HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x120);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x80);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x174);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 3, 0x20);
HAL_PCD_Start(&hpcd_USB_OTG_FS);
}
static void led_thread_entry(ULONG thread_input) {
_ux_dcd_stm32_initialize(0, (ULONG)&hpcd_USB_OTG_FS);
usb_init();
while(1) {
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
tx_thread_sleep(500);
}
}
void sai_cplt_cb(SAI_HandleTypeDef *hsai) {
HAL_GPIO_WritePin(LED_SR_44_GPIO_Port, LED_SR_44_Pin, GPIO_PIN_RESET);
/**
* @brief Define threads.
*
* @param first_unused_memory
*/
void tx_application_define(void *first_unused_memory) {
CHAR *memory_ptr = first_unused_memory;
ux_system_initialize(memory_ptr, (32*1024), UX_NULL, 0);
memory_ptr += 32 * 1024;
_ux_device_stack_initialize(device_framework_hs, sizeof(device_framework_hs),
device_framework_fs, sizeof(device_framework_fs),
string_device_framework, sizeof(string_device_framework),
language_id_framework, sizeof(language_id_framework),
UX_NULL);
//_ux_device_stack_class_register(_ux_system_slave_class_audio_name, _ux_device_class_audio_entry, 1, 0, UX_NULL);
tx_thread_create(&led_thread, "LED Thread", led_thread_entry, 0, memory_ptr, 2048, 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START);
}
/**
* @brief Low level init,
* Set up block memory and timer interrupts.
* As CubeMX project has to generate IRQ handlers,
* a custom port is required to rename the IRQ handlers
* and call them from stm32h7xx_it.c
* Handlers to be renamed:
* SysTick_IRQHandler (for SysTick)
* PendSV_IRQHandler (for task scheduler)
*
*/
void _tx_initialize_low_level(void) {
// Like Heap_4, we define our own memory block here.
_tx_initialize_unused_memory = tx_block_memory;
SysTick_Config(SystemCoreClock / 1000);
/* From low_level ASM file.
* It is different from FreeRTOS, that
* SysTick IRQ priority must be higher than
* PendSV IRQ.
*/
HAL_NVIC_SetPriority(SysTick_IRQn, 4, 0);
HAL_NVIC_EnableIRQ(SysTick_IRQn);
}
/* USER CODE END 0 */
/**
@ -106,15 +184,6 @@ int main(void)
/* USER CODE END 1 */
/* MPU Configuration--------------------------------------------------------*/
MPU_Config();
/* Enable I-Cache---------------------------------------------------------*/
SCB_EnableICache();
/* Enable D-Cache---------------------------------------------------------*/
SCB_EnableDCache();
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
@ -129,6 +198,8 @@ int main(void)
/* USER CODE BEGIN SysInit */
/* FBI CRITICAL: DMA must be initialized BEFORE SAI. */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
@ -142,19 +213,7 @@ int main(void)
MX_USB_OTG_FS_PCD_Init();
/* USER CODE BEGIN 2 */
HAL_GPIO_WritePin(MCU_OSC_SEL_GPIO_Port, MCU_OSC_SEL_Pin, GPIO_PIN_RESET);
memset(da_data, 0xAA, sizeof(da_data));
HAL_SAI_RegisterCallback(&hsai_BlockA3, HAL_SAI_ERROR_CB_ID, sai_error_cb);
HAL_SAI_RegisterCallback(&hsai_BlockA3, HAL_SAI_TX_COMPLETE_CB_ID, sai_cplt_cb);
if(HAL_SAI_Transmit_DMA(&hsai_BlockA3, da_data, sizeof(da_data)) != HAL_OK) {
for(;;) {
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
HAL_Delay(100);
}
}
tx_kernel_enter();
/* USER CODE END 2 */
@ -394,7 +453,7 @@ static void MX_SAI3_Init(void)
hsai_BlockA3.Init.Synchro = SAI_ASYNCHRONOUS;
hsai_BlockA3.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE;
hsai_BlockA3.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
hsai_BlockA3.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_3QF;
hsai_BlockA3.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF;
hsai_BlockA3.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_48K;
hsai_BlockA3.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
hsai_BlockA3.Init.MonoStereoMode = SAI_STEREOMODE;
@ -404,14 +463,14 @@ static void MX_SAI3_Init(void)
hsai_BlockA3.Init.PdmInit.MicPairsNbr = 1;
hsai_BlockA3.Init.PdmInit.ClockEnable = SAI_PDM_CLOCK1_ENABLE;
hsai_BlockA3.FrameInit.FrameLength = 32;
hsai_BlockA3.FrameInit.ActiveFrameLength = 1;
hsai_BlockA3.FrameInit.FSDefinition = SAI_FS_STARTFRAME;
hsai_BlockA3.FrameInit.ActiveFrameLength = 16;
hsai_BlockA3.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
hsai_BlockA3.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
hsai_BlockA3.FrameInit.FSOffset = SAI_FS_FIRSTBIT;
hsai_BlockA3.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
hsai_BlockA3.SlotInit.FirstBitOffset = 0;
hsai_BlockA3.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
hsai_BlockA3.SlotInit.SlotSize = SAI_SLOTSIZE_16B;
hsai_BlockA3.SlotInit.SlotNumber = 2;
hsai_BlockA3.SlotInit.SlotActive = 0x0000FFFF;
hsai_BlockA3.SlotInit.SlotActive = 0x00000003;
if (HAL_SAI_Init(&hsai_BlockA3) != HAL_OK)
{
Error_Handler();
@ -545,12 +604,18 @@ static void MX_GPIO_Init(void)
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOD, LED_SR_44_Pin|LED_SR_48_Pin|LED_SR_96_Pin, GPIO_PIN_SET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(MCU_OSC22EN_GPIO_Port, MCU_OSC22EN_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, LED_BIT_16_Pin|LED_BIT_24_Pin, GPIO_PIN_SET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(MCU_OSC_SEL_GPIO_Port, MCU_OSC_SEL_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(MCU_OSC24EN_GPIO_Port, MCU_OSC24EN_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(A_AMP_UP_GPIO_Port, A_AMP_UP_Pin, GPIO_PIN_RESET);
@ -568,6 +633,13 @@ static void MX_GPIO_Init(void)
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/*Configure GPIO pin : MCU_OSC22EN_Pin */
GPIO_InitStruct.Pin = MCU_OSC22EN_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(MCU_OSC22EN_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : LED_BIT_16_Pin LED_BIT_24_Pin */
GPIO_InitStruct.Pin = LED_BIT_16_Pin|LED_BIT_24_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
@ -590,6 +662,13 @@ static void MX_GPIO_Init(void)
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pin : MCU_OSC24EN_Pin */
GPIO_InitStruct.Pin = MCU_OSC24EN_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(MCU_OSC24EN_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : A_AMP_UP_Pin */
GPIO_InitStruct.Pin = A_AMP_UP_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
@ -603,32 +682,25 @@ static void MX_GPIO_Init(void)
/* USER CODE END 4 */
/* MPU Configuration */
void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct = {0};
/* Disables the MPU */
HAL_MPU_Disable();
/** Initializes and configures the Region and the memory to be protected
/**
* @brief Period elapsed callback in non blocking mode
* @note This function is called when TIM7 interrupt took place, inside
* HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
* a global variable "uwTick" used as application time base.
* @param htim : TIM handle
* @retval None
*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.BaseAddress = 0x0;
MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
MPU_InitStruct.SubRegionDisable = 0x0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
/* USER CODE BEGIN Callback 0 */
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enables the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
/* USER CODE END Callback 0 */
if (htim->Instance == TIM7) {
HAL_IncTick();
}
/* USER CODE BEGIN Callback 1 */
/* USER CODE END Callback 1 */
}
/**

View File

@ -69,6 +69,10 @@ void HAL_MspInit(void)
__HAL_RCC_SYSCFG_CLK_ENABLE();
/* System interrupt init*/
/* SVCall_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SVCall_IRQn, 15, 0);
/* PendSV_IRQn interrupt configuration */
HAL_NVIC_SetPriority(PendSV_IRQn, 15, 0);
/* Peripheral interrupt init */
/* PVD_AVD_IRQn interrupt configuration */
@ -413,11 +417,11 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef* hpcd)
/* Peripheral clock enable */
__HAL_RCC_USB_OTG_FS_CLK_ENABLE();
/* USB_OTG_FS interrupt Init */
HAL_NVIC_SetPriority(OTG_FS_EP1_OUT_IRQn, 0, 0);
HAL_NVIC_SetPriority(OTG_FS_EP1_OUT_IRQn, 4, 0);
HAL_NVIC_EnableIRQ(OTG_FS_EP1_OUT_IRQn);
HAL_NVIC_SetPriority(OTG_FS_EP1_IN_IRQn, 0, 0);
HAL_NVIC_SetPriority(OTG_FS_EP1_IN_IRQn, 4, 0);
HAL_NVIC_EnableIRQ(OTG_FS_EP1_IN_IRQn);
HAL_NVIC_SetPriority(OTG_FS_IRQn, 0, 0);
HAL_NVIC_SetPriority(OTG_FS_IRQn, 4, 0);
HAL_NVIC_EnableIRQ(OTG_FS_IRQn);
/* USER CODE BEGIN USB_OTG_FS_MspInit 1 */
@ -513,8 +517,8 @@ void HAL_SAI_MspInit(SAI_HandleTypeDef* hsai)
hdma_sai3_a.Init.MemInc = DMA_MINC_ENABLE;
hdma_sai3_a.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_sai3_a.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_sai3_a.Init.Mode = DMA_NORMAL;
hdma_sai3_a.Init.Priority = DMA_PRIORITY_LOW;
hdma_sai3_a.Init.Mode = DMA_CIRCULAR;
hdma_sai3_a.Init.Priority = DMA_PRIORITY_MEDIUM;
hdma_sai3_a.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_sai3_a) != HAL_OK)
{

View File

@ -0,0 +1,130 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32h7xx_hal_timebase_TIM.c
* @brief HAL time base based on the hardware TIM.
******************************************************************************
* @attention
*
* Copyright (c) 2022 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "stm32h7xx_hal.h"
#include "stm32h7xx_hal_tim.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim7;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/**
* @brief This function configures the TIM7 as a time base source.
* The time source is configured to have 1ms time base with a dedicated
* Tick interrupt priority.
* @note This function is called automatically at the beginning of program after
* reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig().
* @param TickPriority: Tick interrupt priority.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
RCC_ClkInitTypeDef clkconfig;
uint32_t uwTimclock, uwAPB1Prescaler;
uint32_t uwPrescalerValue;
uint32_t pFLatency;
/*Configure the TIM7 IRQ priority */
if (TickPriority < (1UL << __NVIC_PRIO_BITS))
{
HAL_NVIC_SetPriority(TIM7_IRQn, TickPriority ,0U);
/* Enable the TIM7 global Interrupt */
HAL_NVIC_EnableIRQ(TIM7_IRQn);
uwTickPrio = TickPriority;
}
else
{
return HAL_ERROR;
}
/* Enable TIM7 clock */
__HAL_RCC_TIM7_CLK_ENABLE();
/* Get clock configuration */
HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);
/* Get APB1 prescaler */
uwAPB1Prescaler = clkconfig.APB1CLKDivider;
/* Compute TIM7 clock */
if (uwAPB1Prescaler == RCC_HCLK_DIV1)
{
uwTimclock = HAL_RCC_GetPCLK1Freq();
}
else
{
uwTimclock = 2UL * HAL_RCC_GetPCLK1Freq();
}
/* Compute the prescaler value to have TIM7 counter clock equal to 1MHz */
uwPrescalerValue = (uint32_t) ((uwTimclock / 1000000U) - 1U);
/* Initialize TIM7 */
htim7.Instance = TIM7;
/* Initialize TIMx peripheral as follow:
+ Period = [(TIM7CLK/1000) - 1]. to have a (1/1000) s time base.
+ Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock.
+ ClockDivision = 0
+ Counter direction = Up
*/
htim7.Init.Period = (1000000U / 1000U) - 1U;
htim7.Init.Prescaler = uwPrescalerValue;
htim7.Init.ClockDivision = 0;
htim7.Init.CounterMode = TIM_COUNTERMODE_UP;
if(HAL_TIM_Base_Init(&htim7) == HAL_OK)
{
/* Start the TIM time Base generation in interrupt mode */
return HAL_TIM_Base_Start_IT(&htim7);
}
/* Return function status */
return HAL_ERROR;
}
/**
* @brief Suspend Tick increment.
* @note Disable the tick increment by disabling TIM7 update interrupt.
* @param None
* @retval None
*/
void HAL_SuspendTick(void)
{
/* Disable TIM7 update Interrupt */
__HAL_TIM_DISABLE_IT(&htim7, TIM_IT_UPDATE);
}
/**
* @brief Resume Tick increment.
* @note Enable the tick increment by Enabling TIM7 update interrupt.
* @param None
* @retval None
*/
void HAL_ResumeTick(void)
{
/* Enable TIM7 Update interrupt */
__HAL_TIM_ENABLE_IT(&htim7, TIM_IT_UPDATE);
}

View File

@ -47,6 +47,9 @@
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
void _tx_timer_interrupt(void);
void TX_PendSV_Handler(void);
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
@ -61,6 +64,8 @@ extern DMA_HandleTypeDef hdma_sai3_a;
extern SAI_HandleTypeDef hsai_BlockA3;
extern UART_HandleTypeDef huart1;
extern PCD_HandleTypeDef hpcd_USB_OTG_FS;
extern TIM_HandleTypeDef htim7;
/* USER CODE BEGIN EV */
/* USER CODE END EV */
@ -176,6 +181,8 @@ void PendSV_Handler(void)
{
/* USER CODE BEGIN PendSV_IRQn 0 */
TX_PendSV_Handler();
/* USER CODE END PendSV_IRQn 0 */
/* USER CODE BEGIN PendSV_IRQn 1 */
@ -189,8 +196,10 @@ void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
_tx_timer_interrupt();
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
/* USER CODE BEGIN SysTick_IRQn 1 */
/* USER CODE END SysTick_IRQn 1 */
@ -272,6 +281,20 @@ void USART1_IRQHandler(void)
/* USER CODE END USART1_IRQn 1 */
}
/**
* @brief This function handles TIM7 global interrupt.
*/
void TIM7_IRQHandler(void)
{
/* USER CODE BEGIN TIM7_IRQn 0 */
/* USER CODE END TIM7_IRQn 0 */
HAL_TIM_IRQHandler(&htim7);
/* USER CODE BEGIN TIM7_IRQn 1 */
/* USER CODE END TIM7_IRQn 1 */
}
/**
* @brief This function handles FPU global interrupt.
*/

View File

@ -0,0 +1,16 @@
target_sources(${PROJECT_NAME} PRIVATE
# {{BEGIN_TARGET_SOURCES}}
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_context_restore.S
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_context_save.S
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_interrupt_control.S
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_schedule.S
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_stack_build.S
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_system_return.S
${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_interrupt.S
# {{END_TARGET_SOURCES}}
)
target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_LIST_DIR}/inc
)

View File

@ -0,0 +1,229 @@
del tx.a
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb tx_initialize_low_level.S
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb ../src/tx_thread_stack_build.S
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb ../src/tx_thread_schedule.S
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb ../src/tx_thread_system_return.S
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb ../src/tx_thread_context_save.S
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb ../src/tx_thread_context_restore.S
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb ../src/tx_thread_interrupt_control.S
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb ../src/tx_timer_interrupt.S
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb ../src/tx_thread_interrupt_control.S
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_block_allocate.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_cleanup.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_create.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_delete.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_initialize.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_performance_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_performance_system_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_prioritize.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_block_release.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_allocate.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_cleanup.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_create.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_delete.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_initialize.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_performance_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_performance_system_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_prioritize.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_search.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_release.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_cleanup.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_create.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_delete.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_initialize.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_performance_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_performance_system_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_set.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_set_notify.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_initialize_high_level.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_initialize_kernel_enter.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_initialize_kernel_setup.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_cleanup.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_create.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_delete.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_initialize.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_performance_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_performance_system_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_prioritize.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_priority_change.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_put.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_cleanup.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_create.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_delete.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_flush.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_front_send.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_initialize.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_performance_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_performance_system_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_prioritize.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_receive.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_send.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_send_notify.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_ceiling_put.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_cleanup.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_create.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_delete.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_initialize.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_performance_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_performance_system_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_prioritize.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_put.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_put_notify.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_create.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_delete.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_entry_exit_notify.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_identify.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_initialize.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_performance_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_performance_system_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_preemption_change.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_priority_change.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_relinquish.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_reset.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_resume.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_shell_entry.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_sleep.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_stack_analyze.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_stack_error_handler.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_stack_error_notify.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_suspend.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_system_preempt_check.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_system_resume.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_system_suspend.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_terminate.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_time_slice.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_time_slice_change.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_timeout.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_wait_abort.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_time_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_time_set.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_activate.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_change.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_create.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_deactivate.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_delete.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_expiration_process.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_initialize.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_performance_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_performance_system_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_system_activate.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_system_deactivate.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_thread_entry.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_buffer_full_notify.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_enable.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_event_filter.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_event_unfilter.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_disable.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_initialize.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_interrupt_control.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_isr_enter_insert.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_isr_exit_insert.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_object_register.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_object_unregister.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_user_event_insert.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_block_allocate.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_create.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_delete.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_prioritize.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_block_release.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_allocate.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_create.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_delete.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_prioritize.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_release.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_create.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_delete.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_set.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_set_notify.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_create.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_delete.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_prioritize.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_put.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_create.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_delete.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_flush.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_front_send.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_prioritize.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_receive.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_send.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_send_notify.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_ceiling_put.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_create.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_delete.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_prioritize.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_put.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_put_notify.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_create.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_delete.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_entry_exit_notify.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_info_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_preemption_change.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_priority_change.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_relinquish.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_reset.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_resume.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_suspend.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_terminate.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_time_slice_change.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_wait_abort.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_activate.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_change.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_create.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_deactivate.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_delete.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_info_get.c
arm-none-eabi-ar -r tx.a tx_thread_stack_build.o tx_thread_schedule.o tx_thread_system_return.o tx_thread_context_save.o tx_thread_context_restore.o tx_timer_interrupt.o tx_thread_interrupt_control.o
arm-none-eabi-ar -r tx.a tx_thread_interrupt_control.o tx_initialize_low_level.o
arm-none-eabi-ar -r tx.a tx_block_allocate.o tx_block_pool_cleanup.o tx_block_pool_create.o tx_block_pool_delete.o tx_block_pool_info_get.o
arm-none-eabi-ar -r tx.a tx_block_pool_initialize.o tx_block_pool_performance_info_get.o tx_block_pool_performance_system_info_get.o tx_block_pool_prioritize.o
arm-none-eabi-ar -r tx.a tx_block_release.o tx_byte_allocate.o tx_byte_pool_cleanup.o tx_byte_pool_create.o tx_byte_pool_delete.o tx_byte_pool_info_get.o
arm-none-eabi-ar -r tx.a tx_byte_pool_initialize.o tx_byte_pool_performance_info_get.o tx_byte_pool_performance_system_info_get.o tx_byte_pool_prioritize.o
arm-none-eabi-ar -r tx.a tx_byte_pool_search.o tx_byte_release.o tx_event_flags_cleanup.o tx_event_flags_create.o tx_event_flags_delete.o tx_event_flags_get.o
arm-none-eabi-ar -r tx.a tx_event_flags_info_get.o tx_event_flags_initialize.o tx_event_flags_performance_info_get.o tx_event_flags_performance_system_info_get.o
arm-none-eabi-ar -r tx.a tx_event_flags_set.o tx_event_flags_set_notify.o tx_initialize_high_level.o tx_initialize_kernel_enter.o tx_initialize_kernel_setup.o
arm-none-eabi-ar -r tx.a tx_mutex_cleanup.o tx_mutex_create.o tx_mutex_delete.o tx_mutex_get.o tx_mutex_info_get.o tx_mutex_initialize.o tx_mutex_performance_info_get.o
arm-none-eabi-ar -r tx.a tx_mutex_performance_system_info_get.o tx_mutex_prioritize.o tx_mutex_priority_change.o tx_mutex_put.o tx_queue_cleanup.o tx_queue_create.o
arm-none-eabi-ar -r tx.a tx_queue_delete.o tx_queue_flush.o tx_queue_front_send.o tx_queue_info_get.o tx_queue_initialize.o tx_queue_performance_info_get.o
arm-none-eabi-ar -r tx.a tx_queue_performance_system_info_get.o tx_queue_prioritize.o tx_queue_receive.o tx_queue_send.o tx_queue_send_notify.o tx_semaphore_ceiling_put.o
arm-none-eabi-ar -r tx.a tx_semaphore_cleanup.o tx_semaphore_create.o tx_semaphore_delete.o tx_semaphore_get.o tx_semaphore_info_get.o tx_semaphore_initialize.o
arm-none-eabi-ar -r tx.a tx_semaphore_performance_info_get.o tx_semaphore_performance_system_info_get.o tx_semaphore_prioritize.o tx_semaphore_put.o tx_semaphore_put_notify.o
arm-none-eabi-ar -r tx.a tx_thread_create.o tx_thread_delete.o tx_thread_entry_exit_notify.o tx_thread_identify.o tx_thread_info_get.o tx_thread_initialize.o
arm-none-eabi-ar -r tx.a tx_thread_performance_info_get.o tx_thread_performance_system_info_get.o tx_thread_preemption_change.o tx_thread_priority_change.o tx_thread_relinquish.o
arm-none-eabi-ar -r tx.a tx_thread_reset.o tx_thread_resume.o tx_thread_shell_entry.o tx_thread_sleep.o tx_thread_stack_analyze.o tx_thread_stack_error_handler.o
arm-none-eabi-ar -r tx.a tx_thread_stack_error_notify.o tx_thread_suspend.o tx_thread_system_preempt_check.o tx_thread_system_resume.o tx_thread_system_suspend.o
arm-none-eabi-ar -r tx.a tx_thread_terminate.o tx_thread_time_slice.o tx_thread_time_slice_change.o tx_thread_timeout.o tx_thread_wait_abort.o tx_time_get.o
arm-none-eabi-ar -r tx.a tx_time_set.o tx_timer_activate.o tx_timer_change.o tx_timer_create.o tx_timer_deactivate.o tx_timer_delete.o tx_timer_expiration_process.o
arm-none-eabi-ar -r tx.a tx_timer_info_get.o tx_timer_initialize.o tx_timer_performance_info_get.o tx_timer_performance_system_info_get.o tx_timer_system_activate.o
arm-none-eabi-ar -r tx.a tx_timer_system_deactivate.o tx_timer_thread_entry.o tx_trace_enable.o tx_trace_disable.o tx_trace_initialize.o tx_trace_interrupt_control.o
arm-none-eabi-ar -r tx.a tx_trace_isr_enter_insert.o tx_trace_isr_exit_insert.o tx_trace_object_register.o tx_trace_object_unregister.o tx_trace_user_event_insert.o
arm-none-eabi-ar -r tx.a tx_trace_buffer_full_notify.o tx_trace_event_filter.o tx_trace_event_unfilter.o
arm-none-eabi-ar -r tx.a txe_block_allocate.o txe_block_pool_create.o txe_block_pool_delete.o txe_block_pool_info_get.o txe_block_pool_prioritize.o txe_block_release.o
arm-none-eabi-ar -r tx.a txe_byte_allocate.o txe_byte_pool_create.o txe_byte_pool_delete.o txe_byte_pool_info_get.o txe_byte_pool_prioritize.o txe_byte_release.o
arm-none-eabi-ar -r tx.a txe_event_flags_create.o txe_event_flags_delete.o txe_event_flags_get.o txe_event_flags_info_get.o txe_event_flags_set.o
arm-none-eabi-ar -r tx.a txe_event_flags_set_notify.o txe_mutex_create.o txe_mutex_delete.o txe_mutex_get.o txe_mutex_info_get.o txe_mutex_prioritize.o
arm-none-eabi-ar -r tx.a txe_mutex_put.o txe_queue_create.o txe_queue_delete.o txe_queue_flush.o txe_queue_front_send.o txe_queue_info_get.o txe_queue_prioritize.o
arm-none-eabi-ar -r tx.a txe_queue_receive.o txe_queue_send.o txe_queue_send_notify.o txe_semaphore_ceiling_put.o txe_semaphore_create.o txe_semaphore_delete.o
arm-none-eabi-ar -r tx.a txe_semaphore_get.o txe_semaphore_info_get.o txe_semaphore_prioritize.o txe_semaphore_put.o txe_semaphore_put_notify.o txe_thread_create.o
arm-none-eabi-ar -r tx.a txe_thread_delete.o txe_thread_entry_exit_notify.o txe_thread_info_get.o txe_thread_preemption_change.o txe_thread_priority_change.o
arm-none-eabi-ar -r tx.a txe_thread_relinquish.o txe_thread_reset.o txe_thread_resume.o txe_thread_suspend.o txe_thread_terminate.o txe_thread_time_slice_change.o
arm-none-eabi-ar -r tx.a txe_thread_wait_abort.o txe_timer_activate.o txe_timer_change.o txe_timer_create.o txe_timer_deactivate.o txe_timer_delete.o txe_timer_info_get.o

View File

@ -0,0 +1,7 @@
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb tx_simulator_startup.S
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb cortexm7_crt0.S
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb tx_initialize_low_level.S
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mthumb -I../../../../common/inc -I../inc sample_threadx.c
arm-none-eabi-ld -A cortex-m7 -ereset_handler -T sample_threadx.ld tx_simulator_startup.o cortexm7_crt0.o tx_initialize_low_level.o sample_threadx.o tx.a libc.a -o sample_threadx.out -M > sample_threadx.map

View File

@ -0,0 +1,127 @@
.global _start
.extern main
.section .init, "ax"
.code 16
.align 2
.thumb_func
_start:
CPSID i
ldr r1, =__stack_end__
mov sp, r1
/* Copy initialised sections into RAM if required. */
ldr r0, =__data_load_start__
ldr r1, =__data_start__
ldr r2, =__data_end__
bl crt0_memory_copy
ldr r0, =__text_load_start__
ldr r1, =__text_start__
ldr r2, =__text_end__
bl crt0_memory_copy
ldr r0, =__fast_load_start__
ldr r1, =__fast_start__
ldr r2, =__fast_end__
bl crt0_memory_copy
ldr r0, =__ctors_load_start__
ldr r1, =__ctors_start__
ldr r2, =__ctors_end__
bl crt0_memory_copy
ldr r0, =__dtors_load_start__
ldr r1, =__dtors_start__
ldr r2, =__dtors_end__
bl crt0_memory_copy
ldr r0, =__rodata_load_start__
ldr r1, =__rodata_start__
ldr r2, =__rodata_end__
bl crt0_memory_copy
/* Zero bss. */
ldr r0, =__bss_start__
ldr r1, =__bss_end__
mov r2, #0
bl crt0_memory_set
/* Setup heap - not recommended for Threadx but here for compatibility reasons */
ldr r0, = __heap_start__
ldr r1, = __heap_end__
sub r1, r1, r0
mov r2, #0
str r2, [r0]
add r0, r0, #4
str r1, [r0]
/* constructors in case of using C++ */
ldr r0, =__ctors_start__
ldr r1, =__ctors_end__
crt0_ctor_loop:
cmp r0, r1
beq crt0_ctor_end
ldr r2, [r0]
add r0, #4
push {r0-r1}
blx r2
pop {r0-r1}
b crt0_ctor_loop
crt0_ctor_end:
/* Setup call frame for main() */
mov r0, #0
mov lr, r0
mov r12, sp
start:
/* Jump to main() */
mov r0, #0
mov r1, #0
ldr r2, =main
blx r2
/* when main returns, loop forever. */
crt0_exit_loop:
b crt0_exit_loop
/* Startup helper functions. */
crt0_memory_copy:
cmp r0, r1
beq memory_copy_done
sub r2, r2, r1
beq memory_copy_done
memory_copy_loop:
ldrb r3, [r0]
add r0, r0, #1
strb r3, [r1]
add r1, r1, #1
sub r2, r2, #1
bne memory_copy_loop
memory_copy_done:
bx lr
crt0_memory_set:
cmp r0, r1
beq memory_set_done
strb r2, [r0]
add r0, r0, #1
b crt0_memory_set
memory_set_done:
bx lr
/* Setup attibutes of stack and heap sections so they don't take up room in the elf file */
.section .stack, "wa", %nobits
.section .stack_process, "wa", %nobits
.section .heap, "wa", %nobits

View File

@ -0,0 +1,370 @@
/* This is a small demo of the high-performance ThreadX kernel. It includes examples of eight
threads of different priorities, using a message queue, semaphore, mutex, event flags group,
byte pool, and block pool. */
#include "tx_api.h"
#define DEMO_STACK_SIZE 1024
#define DEMO_BYTE_POOL_SIZE 9120
#define DEMO_BLOCK_POOL_SIZE 100
#define DEMO_QUEUE_SIZE 100
/* Define the ThreadX object control blocks... */
TX_THREAD thread_0;
TX_THREAD thread_1;
TX_THREAD thread_2;
TX_THREAD thread_3;
TX_THREAD thread_4;
TX_THREAD thread_5;
TX_THREAD thread_6;
TX_THREAD thread_7;
TX_QUEUE queue_0;
TX_SEMAPHORE semaphore_0;
TX_MUTEX mutex_0;
TX_EVENT_FLAGS_GROUP event_flags_0;
TX_BYTE_POOL byte_pool_0;
TX_BLOCK_POOL block_pool_0;
UCHAR memory_area[DEMO_BYTE_POOL_SIZE];
/* Define the counters used in the demo application... */
ULONG thread_0_counter;
ULONG thread_1_counter;
ULONG thread_1_messages_sent;
ULONG thread_2_counter;
ULONG thread_2_messages_received;
ULONG thread_3_counter;
ULONG thread_4_counter;
ULONG thread_5_counter;
ULONG thread_6_counter;
ULONG thread_7_counter;
/* Define thread prototypes. */
void thread_0_entry(ULONG thread_input);
void thread_1_entry(ULONG thread_input);
void thread_2_entry(ULONG thread_input);
void thread_3_and_4_entry(ULONG thread_input);
void thread_5_entry(ULONG thread_input);
void thread_6_and_7_entry(ULONG thread_input);
/* Define main entry point. */
int main()
{
/* Enter the ThreadX kernel. */
tx_kernel_enter();
}
/* Define what the initial system looks like. */
void tx_application_define(void *first_unused_memory)
{
CHAR *pointer = TX_NULL;
/* Create a byte memory pool from which to allocate the thread stacks. */
tx_byte_pool_create(&byte_pool_0, "byte pool 0", memory_area, DEMO_BYTE_POOL_SIZE);
/* Put system definition stuff in here, e.g. thread creates and other assorted
create information. */
/* Allocate the stack for thread 0. */
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
/* Create the main thread. */
tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
pointer, DEMO_STACK_SIZE,
1, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
/* Allocate the stack for thread 1. */
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
/* Create threads 1 and 2. These threads pass information through a ThreadX
message queue. It is also interesting to note that these threads have a time
slice. */
tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
pointer, DEMO_STACK_SIZE,
16, 16, 4, TX_AUTO_START);
/* Allocate the stack for thread 2. */
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
pointer, DEMO_STACK_SIZE,
16, 16, 4, TX_AUTO_START);
/* Allocate the stack for thread 3. */
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
/* Create threads 3 and 4. These threads compete for a ThreadX counting semaphore.
An interesting thing here is that both threads share the same instruction area. */
tx_thread_create(&thread_3, "thread 3", thread_3_and_4_entry, 3,
pointer, DEMO_STACK_SIZE,
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
/* Allocate the stack for thread 4. */
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
tx_thread_create(&thread_4, "thread 4", thread_3_and_4_entry, 4,
pointer, DEMO_STACK_SIZE,
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
/* Allocate the stack for thread 5. */
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
/* Create thread 5. This thread simply pends on an event flag which will be set
by thread_0. */
tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
pointer, DEMO_STACK_SIZE,
4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
/* Allocate the stack for thread 6. */
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
/* Create threads 6 and 7. These threads compete for a ThreadX mutex. */
tx_thread_create(&thread_6, "thread 6", thread_6_and_7_entry, 6,
pointer, DEMO_STACK_SIZE,
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
/* Allocate the stack for thread 7. */
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
tx_thread_create(&thread_7, "thread 7", thread_6_and_7_entry, 7,
pointer, DEMO_STACK_SIZE,
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
/* Allocate the message queue. */
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_QUEUE_SIZE*sizeof(ULONG), TX_NO_WAIT);
/* Create the message queue shared by threads 1 and 2. */
tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, DEMO_QUEUE_SIZE*sizeof(ULONG));
/* Create the semaphore used by threads 3 and 4. */
tx_semaphore_create(&semaphore_0, "semaphore 0", 1);
/* Create the event flags group used by threads 1 and 5. */
tx_event_flags_create(&event_flags_0, "event flags 0");
/* Create the mutex used by thread 6 and 7 without priority inheritance. */
tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
/* Allocate the memory for a small block pool. */
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_BLOCK_POOL_SIZE, TX_NO_WAIT);
/* Create a block memory pool to allocate a message buffer from. */
tx_block_pool_create(&block_pool_0, "block pool 0", sizeof(ULONG), pointer, DEMO_BLOCK_POOL_SIZE);
/* Allocate a block and release the block memory. */
tx_block_allocate(&block_pool_0, (VOID **) &pointer, TX_NO_WAIT);
/* Release the block back to the pool. */
tx_block_release(pointer);
}
/* Define the test threads. */
void thread_0_entry(ULONG thread_input)
{
UINT status;
/* This thread simply sits in while-forever-sleep loop. */
while(1)
{
/* Increment the thread counter. */
thread_0_counter++;
/* Sleep for 10 ticks. */
tx_thread_sleep(10);
/* Set event flag 0 to wakeup thread 5. */
status = tx_event_flags_set(&event_flags_0, 0x1, TX_OR);
/* Check status. */
if (status != TX_SUCCESS)
break;
}
}
void thread_1_entry(ULONG thread_input)
{
UINT status;
/* This thread simply sends messages to a queue shared by thread 2. */
while(1)
{
/* Increment the thread counter. */
thread_1_counter++;
/* Send message to queue 0. */
status = tx_queue_send(&queue_0, &thread_1_messages_sent, TX_WAIT_FOREVER);
/* Check completion status. */
if (status != TX_SUCCESS)
break;
/* Increment the message sent. */
thread_1_messages_sent++;
}
}
void thread_2_entry(ULONG thread_input)
{
ULONG received_message;
UINT status;
/* This thread retrieves messages placed on the queue by thread 1. */
while(1)
{
/* Increment the thread counter. */
thread_2_counter++;
/* Retrieve a message from the queue. */
status = tx_queue_receive(&queue_0, &received_message, TX_WAIT_FOREVER);
/* Check completion status and make sure the message is what we
expected. */
if ((status != TX_SUCCESS) || (received_message != thread_2_messages_received))
break;
/* Otherwise, all is okay. Increment the received message count. */
thread_2_messages_received++;
}
}
void thread_3_and_4_entry(ULONG thread_input)
{
UINT status;
/* This function is executed from thread 3 and thread 4. As the loop
below shows, these function compete for ownership of semaphore_0. */
while(1)
{
/* Increment the thread counter. */
if (thread_input == 3)
thread_3_counter++;
else
thread_4_counter++;
/* Get the semaphore with suspension. */
status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
/* Check status. */
if (status != TX_SUCCESS)
break;
/* Sleep for 2 ticks to hold the semaphore. */
tx_thread_sleep(2);
/* Release the semaphore. */
status = tx_semaphore_put(&semaphore_0);
/* Check status. */
if (status != TX_SUCCESS)
break;
}
}
void thread_5_entry(ULONG thread_input)
{
UINT status;
ULONG actual_flags;
/* This thread simply waits for an event in a forever loop. */
while(1)
{
/* Increment the thread counter. */
thread_5_counter++;
/* Wait for event flag 0. */
status = tx_event_flags_get(&event_flags_0, 0x1, TX_OR_CLEAR,
&actual_flags, TX_WAIT_FOREVER);
/* Check status. */
if ((status != TX_SUCCESS) || (actual_flags != 0x1))
break;
}
}
void thread_6_and_7_entry(ULONG thread_input)
{
UINT status;
/* This function is executed from thread 6 and thread 7. As the loop
below shows, these function compete for ownership of mutex_0. */
while(1)
{
/* Increment the thread counter. */
if (thread_input == 6)
thread_6_counter++;
else
thread_7_counter++;
/* Get the mutex with suspension. */
status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
/* Check status. */
if (status != TX_SUCCESS)
break;
/* Get the mutex again with suspension. This shows
that an owning thread may retrieve the mutex it
owns multiple times. */
status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
/* Check status. */
if (status != TX_SUCCESS)
break;
/* Sleep for 2 ticks to hold the mutex. */
tx_thread_sleep(2);
/* Release the mutex. */
status = tx_mutex_put(&mutex_0);
/* Check status. */
if (status != TX_SUCCESS)
break;
/* Release the mutex again. This will actually
release ownership since it was obtained twice. */
status = tx_mutex_put(&mutex_0);
/* Check status. */
if (status != TX_SUCCESS)
break;
}
}

View File

@ -0,0 +1,206 @@
MEMORY
{
UNPLACED_SECTIONS (wx) : ORIGIN = 0x100000000, LENGTH = 0
CM3_System_Control_Space (wx) : ORIGIN = 0xe000e000, LENGTH = 0x00001000
AHB_Peripherals (wx) : ORIGIN = 0x50000000, LENGTH = 0x00200000
APB1_Peripherals (wx) : ORIGIN = 0x40080000, LENGTH = 0x00080000
APB0_Peripherals (wx) : ORIGIN = 0x40000000, LENGTH = 0x00080000
GPIO (wx) : ORIGIN = 0x2009c000, LENGTH = 0x00004000
AHBSRAM1 (wx) : ORIGIN = 0x20080000, LENGTH = 0x00004000
AHBSRAM0 (wx) : ORIGIN = 0x2007c000, LENGTH = 0x00004000
RAM (wx) : ORIGIN = 0x10000000, LENGTH = 0x00008000
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00080000
}
SECTIONS
{
__CM3_System_Control_Space_segment_start__ = 0xe000e000;
__CM3_System_Control_Space_segment_end__ = 0xe000f000;
__AHB_Peripherals_segment_start__ = 0x50000000;
__AHB_Peripherals_segment_end__ = 0x50200000;
__APB1_Peripherals_segment_start__ = 0x40080000;
__APB1_Peripherals_segment_end__ = 0x40100000;
__APB0_Peripherals_segment_start__ = 0x40000000;
__APB0_Peripherals_segment_end__ = 0x40080000;
__GPIO_segment_start__ = 0x2009c000;
__GPIO_segment_end__ = 0x200a0000;
__AHBSRAM1_segment_start__ = 0x20080000;
__AHBSRAM1_segment_end__ = 0x20084000;
__AHBSRAM0_segment_start__ = 0x2007c000;
__AHBSRAM0_segment_end__ = 0x20080000;
__RAM_segment_start__ = 0x10000000;
__RAM_segment_end__ = 0x10008000;
__FLASH_segment_start__ = 0x00000000;
__FLASH_segment_end__ = 0x00080000;
__STACKSIZE__ = 1024;
__STACKSIZE_PROCESS__ = 0;
__STACKSIZE_IRQ__ = 0;
__STACKSIZE_FIQ__ = 0;
__STACKSIZE_SVC__ = 0;
__STACKSIZE_ABT__ = 0;
__STACKSIZE_UND__ = 0;
__HEAPSIZE__ = 128;
__vectors_load_start__ = __FLASH_segment_start__;
.vectors __FLASH_segment_start__ : AT(__FLASH_segment_start__)
{
__vectors_start__ = .;
*(.vectors .vectors.*)
}
__vectors_end__ = __vectors_start__ + SIZEOF(.vectors);
. = ASSERT(__vectors_end__ >= __FLASH_segment_start__ && __vectors_end__ <= (__FLASH_segment_start__ + 0x00080000) , "error: .vectors is too large to fit in FLASH memory segment");
__init_load_start__ = ALIGN(__vectors_end__ , 4);
.init ALIGN(__vectors_end__ , 4) : AT(ALIGN(__vectors_end__ , 4))
{
__init_start__ = .;
*(.init .init.*)
}
__init_end__ = __init_start__ + SIZEOF(.init);
. = ASSERT(__init_end__ >= __FLASH_segment_start__ && __init_end__ <= (__FLASH_segment_start__ + 0x00080000) , "error: .init is too large to fit in FLASH memory segment");
__text_load_start__ = ALIGN(__init_end__ , 4);
.text ALIGN(__init_end__ , 4) : AT(ALIGN(__init_end__ , 4))
{
__text_start__ = .;
*(.text .text.* .glue_7t .glue_7 .gnu.linkonce.t.* .gcc_except_table)
}
__text_end__ = __text_start__ + SIZEOF(.text);
. = ASSERT(__text_end__ >= __FLASH_segment_start__ && __text_end__ <= (__FLASH_segment_start__ + 0x00080000) , "error: .text is too large to fit in FLASH memory segment");
__dtors_load_start__ = ALIGN(__text_end__ , 4);
.dtors ALIGN(__text_end__ , 4) : AT(ALIGN(__text_end__ , 4))
{
__dtors_start__ = .;
KEEP (*(SORT(.dtors.*))) KEEP (*(.dtors))
}
__dtors_end__ = __dtors_start__ + SIZEOF(.dtors);
. = ASSERT(__dtors_end__ >= __FLASH_segment_start__ && __dtors_end__ <= (__FLASH_segment_start__ + 0x00080000) , "error: .dtors is too large to fit in FLASH memory segment");
__ctors_load_start__ = ALIGN(__dtors_end__ , 4);
.ctors ALIGN(__dtors_end__ , 4) : AT(ALIGN(__dtors_end__ , 4))
{
__ctors_start__ = .;
KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors))
}
__ctors_end__ = __ctors_start__ + SIZEOF(.ctors);
. = ASSERT(__ctors_end__ >= __FLASH_segment_start__ && __ctors_end__ <= (__FLASH_segment_start__ + 0x00080000) , "error: .ctors is too large to fit in FLASH memory segment");
__rodata_load_start__ = ALIGN(__ctors_end__ , 4);
.rodata ALIGN(__ctors_end__ , 4) : AT(ALIGN(__ctors_end__ , 4))
{
__rodata_start__ = .;
*(.rodata .rodata.* .gnu.linkonce.r.*)
}
__rodata_end__ = __rodata_start__ + SIZEOF(.rodata);
. = ASSERT(__rodata_end__ >= __FLASH_segment_start__ && __rodata_end__ <= (__FLASH_segment_start__ + 0x00080000) , "error: .rodata is too large to fit in FLASH memory segment");
__fast_load_start__ = ALIGN(__rodata_end__ , 4);
.fast ALIGN(__RAM_segment_start__ , 4) : AT(ALIGN(__rodata_end__ , 4))
{
__fast_start__ = .;
*(.fast .fast.*)
}
__fast_end__ = __fast_start__ + SIZEOF(.fast);
__fast_load_end__ = __fast_load_start__ + SIZEOF(.fast);
. = ASSERT((__fast_load_start__ + SIZEOF(.fast)) >= __FLASH_segment_start__ && (__fast_load_start__ + SIZEOF(.fast)) <= (__FLASH_segment_start__ + 0x00080000) , "error: .fast is too large to fit in FLASH memory segment");
.fast_run ALIGN(__RAM_segment_start__ , 4) (NOLOAD) :
{
__fast_run_start__ = .;
. = MAX(__fast_run_start__ + SIZEOF(.fast), .);
}
__fast_run_end__ = __fast_run_start__ + SIZEOF(.fast_run);
. = ASSERT(__fast_run_end__ >= __RAM_segment_start__ && __fast_run_end__ <= (__RAM_segment_start__ + 0x00008000) , "error: .fast_run is too large to fit in RAM memory segment");
__data_load_start__ = ALIGN(__fast_load_start__ + SIZEOF(.fast) , 4);
.data ALIGN(__fast_run_end__ , 4) : AT(ALIGN(__fast_load_start__ + SIZEOF(.fast) , 4))
{
__data_start__ = .;
*(.data .data.* .gnu.linkonce.d.*)
}
__data_end__ = __data_start__ + SIZEOF(.data);
__data_load_end__ = __data_load_start__ + SIZEOF(.data);
__FLASH_segment_used_end__ = ALIGN(__fast_load_start__ + SIZEOF(.fast) , 4) + SIZEOF(.data);
. = ASSERT((__data_load_start__ + SIZEOF(.data)) >= __FLASH_segment_start__ && (__data_load_start__ + SIZEOF(.data)) <= (__FLASH_segment_start__ + 0x00080000) , "error: .data is too large to fit in FLASH memory segment");
.data_run ALIGN(__fast_run_end__ , 4) (NOLOAD) :
{
__data_run_start__ = .;
. = MAX(__data_run_start__ + SIZEOF(.data), .);
}
__data_run_end__ = __data_run_start__ + SIZEOF(.data_run);
. = ASSERT(__data_run_end__ >= __RAM_segment_start__ && __data_run_end__ <= (__RAM_segment_start__ + 0x00008000) , "error: .data_run is too large to fit in RAM memory segment");
__bss_load_start__ = ALIGN(__data_run_end__ , 4);
.bss ALIGN(__data_run_end__ , 4) (NOLOAD) : AT(ALIGN(__data_run_end__ , 4))
{
__bss_start__ = .;
*(.bss .bss.* .gnu.linkonce.b.*) *(COMMON)
}
__bss_end__ = __bss_start__ + SIZEOF(.bss);
. = ASSERT(__bss_end__ >= __RAM_segment_start__ && __bss_end__ <= (__RAM_segment_start__ + 0x00008000) , "error: .bss is too large to fit in RAM memory segment");
__non_init_load_start__ = ALIGN(__bss_end__ , 4);
.non_init ALIGN(__bss_end__ , 4) (NOLOAD) : AT(ALIGN(__bss_end__ , 4))
{
__non_init_start__ = .;
*(.non_init .non_init.*)
}
__non_init_end__ = __non_init_start__ + SIZEOF(.non_init);
. = ASSERT(__non_init_end__ >= __RAM_segment_start__ && __non_init_end__ <= (__RAM_segment_start__ + 0x00008000) , "error: .non_init is too large to fit in RAM memory segment");
__heap_load_start__ = ALIGN(__non_init_end__ , 4);
.heap ALIGN(__non_init_end__ , 4) (NOLOAD) : AT(ALIGN(__non_init_end__ , 4))
{
__heap_start__ = .;
*(.heap)
. = ALIGN(MAX(__heap_start__ + __HEAPSIZE__ , .), 4);
}
__heap_end__ = __heap_start__ + SIZEOF(.heap);
. = ASSERT(__heap_end__ >= __RAM_segment_start__ && __heap_end__ <= (__RAM_segment_start__ + 0x00008000) , "error: .heap is too large to fit in RAM memory segment");
__stack_load_start__ = ALIGN(__heap_end__ , 4);
.stack ALIGN(__heap_end__ , 4) (NOLOAD) : AT(ALIGN(__heap_end__ , 4))
{
__stack_start__ = .;
*(.stack)
. = ALIGN(MAX(__stack_start__ + __STACKSIZE__ , .), 4);
}
__stack_end__ = __stack_start__ + SIZEOF(.stack);
. = ASSERT(__stack_end__ >= __RAM_segment_start__ && __stack_end__ <= (__RAM_segment_start__ + 0x00008000) , "error: .stack is too large to fit in RAM memory segment");
__stack_process_load_start__ = ALIGN(__stack_end__ , 4);
.stack_process ALIGN(__stack_end__ , 4) (NOLOAD) : AT(ALIGN(__stack_end__ , 4))
{
__stack_process_start__ = .;
*(.stack_process)
. = ALIGN(MAX(__stack_process_start__ + __STACKSIZE_PROCESS__ , .), 4);
}
__stack_process_end__ = __stack_process_start__ + SIZEOF(.stack_process);
__RAM_segment_used_end__ = ALIGN(__stack_end__ , 4) + SIZEOF(.stack_process);
. = ASSERT(__stack_process_end__ >= __RAM_segment_start__ && __stack_process_end__ <= (__RAM_segment_start__ + 0x00008000) , "error: .stack_process is too large to fit in RAM memory segment");
}

View File

@ -0,0 +1,232 @@
@/**************************************************************************/
@/* */
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
@/* */
@/* This software is licensed under the Microsoft Software License */
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
@/* and in the root directory of this software. */
@/* */
@/**************************************************************************/
@
@
@/**************************************************************************/
@/**************************************************************************/
@/** */
@/** ThreadX Component */
@/** */
@/** Initialize */
@/** */
@/**************************************************************************/
@/**************************************************************************/
@
@
.global _tx_thread_system_stack_ptr
.global _tx_initialize_unused_memory
.global __RAM_segment_used_end__
.global _tx_timer_interrupt
.global __main
.global __tx_SVCallHandler
.global __tx_PendSVHandler
.global _vectors
.global __tx_NMIHandler @ NMI
.global __tx_BadHandler @ HardFault
.global __tx_SVCallHandler @ SVCall
.global __tx_DBGHandler @ Monitor
.global __tx_PendSVHandler @ PendSV
.global __tx_SysTickHandler @ SysTick
.global __tx_IntHandler @ Int 0
@
@
SYSTEM_CLOCK = 6000000
SYSTICK_CYCLES = ((SYSTEM_CLOCK / 100) -1)
.text 32
.align 4
.syntax unified
@/**************************************************************************/
@/* */
@/* FUNCTION RELEASE */
@/* */
@/* _tx_initialize_low_level Cortex-M7/GNU */
@/* 6.1 */
@/* AUTHOR */
@/* */
@/* William E. Lamie, Microsoft Corporation */
@/* */
@/* DESCRIPTION */
@/* */
@/* This function is responsible for any low-level processor */
@/* initialization, including setting up interrupt vectors, setting */
@/* up a periodic timer interrupt source, saving the system stack */
@/* pointer for use in ISR processing later, and finding the first */
@/* available RAM memory address for tx_application_define. */
@/* */
@/* INPUT */
@/* */
@/* None */
@/* */
@/* OUTPUT */
@/* */
@/* None */
@/* */
@/* CALLS */
@/* */
@/* None */
@/* */
@/* CALLED BY */
@/* */
@/* _tx_initialize_kernel_enter ThreadX entry function */
@/* */
@/* RELEASE HISTORY */
@/* */
@/* DATE NAME DESCRIPTION */
@/* */
@/* 05-19-2020 William E. Lamie Initial Version 6.0 */
@/* 09-30-2020 William E. Lamie Modified Comment(s), fixed */
@/* GNU assembly comment, clean */
@/* up whitespace, resulting */
@/* in version 6.1 */
@/* */
@/**************************************************************************/
@VOID _tx_initialize_low_level(VOID)
@{
.global _tx_initialize_low_level
.thumb_func
_tx_initialize_low_level:
@
@ /* Disable interrupts during ThreadX initialization. */
@
CPSID i
@
@ /* Set base of available memory to end of non-initialised RAM area. */
@
LDR r0, =_tx_initialize_unused_memory @ Build address of unused memory pointer
LDR r1, =__RAM_segment_used_end__ @ Build first free address
ADD r1, r1, #4 @
STR r1, [r0] @ Setup first unused memory pointer
@
@ /* Setup Vector Table Offset Register. */
@
MOV r0, #0xE000E000 @ Build address of NVIC registers
LDR r1, =_vectors @ Pickup address of vector table
STR r1, [r0, #0xD08] @ Set vector table address
@
@ /* Set system stack pointer from vector value. */
@
LDR r0, =_tx_thread_system_stack_ptr @ Build address of system stack pointer
LDR r1, =_vectors @ Pickup address of vector table
LDR r1, [r1] @ Pickup reset stack pointer
STR r1, [r0] @ Save system stack pointer
@
@ /* Enable the cycle count register. */
@
LDR r0, =0xE0001000 @ Build address of DWT register
LDR r1, [r0] @ Pickup the current value
ORR r1, r1, #1 @ Set the CYCCNTENA bit
STR r1, [r0] @ Enable the cycle count register
@
@ /* Configure SysTick for 100Hz clock, or 16384 cycles if no reference. */
@
MOV r0, #0xE000E000 @ Build address of NVIC registers
LDR r1, =SYSTICK_CYCLES
STR r1, [r0, #0x14] @ Setup SysTick Reload Value
MOV r1, #0x7 @ Build SysTick Control Enable Value
STR r1, [r0, #0x10] @ Setup SysTick Control
@
@ /* Configure handler priorities. */
@
LDR r1, =0x00000000 @ Rsrv, UsgF, BusF, MemM
STR r1, [r0, #0xD18] @ Setup System Handlers 4-7 Priority Registers
LDR r1, =0xFF000000 @ SVCl, Rsrv, Rsrv, Rsrv
STR r1, [r0, #0xD1C] @ Setup System Handlers 8-11 Priority Registers
@ Note: SVC must be lowest priority, which is 0xFF
LDR r1, =0x40FF0000 @ SysT, PnSV, Rsrv, DbgM
STR r1, [r0, #0xD20] @ Setup System Handlers 12-15 Priority Registers
@ Note: PnSV must be lowest priority, which is 0xFF
@
@ /* Return to caller. */
@
BX lr
@}
@
@/* Define shells for each of the unused vectors. */
@
.global __tx_BadHandler
.thumb_func
__tx_BadHandler:
B __tx_BadHandler
@ /* added to catch the hardfault */
.global __tx_HardfaultHandler
.thumb_func
__tx_HardfaultHandler:
B __tx_HardfaultHandler
@ /* added to catch the SVC */
.global __tx_SVCallHandler
.thumb_func
__tx_SVCallHandler:
B __tx_SVCallHandler
@ /* Generic interrupt handler template */
.global __tx_IntHandler
.thumb_func
__tx_IntHandler:
@ VOID InterruptHandler (VOID)
@ {
PUSH {r0, lr}
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
BL _tx_execution_isr_enter @ Call the ISR enter function
#endif
@ /* Do interrupt handler work here */
@ /* BL <your C Function>.... */
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
BL _tx_execution_isr_exit @ Call the ISR exit function
#endif
POP {r0, lr}
BX LR
@ }
@ /* System Tick timer interrupt handler */
.global __tx_SysTickHandler
.global SysTick_Handler
.thumb_func
__tx_SysTickHandler:
.thumb_func
SysTick_Handler:
@ VOID TimerInterruptHandler (VOID)
@ {
@
PUSH {r0, lr}
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
BL _tx_execution_isr_enter @ Call the ISR enter function
#endif
BL _tx_timer_interrupt
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
BL _tx_execution_isr_exit @ Call the ISR exit function
#endif
POP {r0, lr}
BX LR
@ }
@ /* NMI, DBG handlers */
.global __tx_NMIHandler
.thumb_func
__tx_NMIHandler:
B __tx_NMIHandler
.global __tx_DBGHandler
.thumb_func
__tx_DBGHandler:
B __tx_DBGHandler

View File

@ -0,0 +1,84 @@
.global reset_handler
.global __tx_NMIHandler
.global __tx_BadHandler
.global __tx_SVCallHandler
.global __tx_DBGHandler
.global __tx_PendSVHandler
.global __tx_SysTickHandler
.global __tx_BadHandler
.syntax unified
.section .vectors, "ax"
.code 16
.align 0
.global _vectors
_vectors:
.word __stack_end__
.word reset_handler
.word __tx_NMIHandler
.word __tx_HardfaultHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word 0 // Reserved
.word 0 // Reserved
.word 0 // Reserved
.word 0 // Reserved
.word __tx_SVCallHandler //_SVC_Handler - used by Threadx scheduler //
.word __tx_DBGHandler
.word 0 // Reserved
.word __tx_PendSVHandler
.word __tx_SysTickHandler // Used by Threadx timer functionality
.word __tx_BadHandler // Populate with user Interrupt handler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.word __tx_BadHandler
.section .init, "ax"
.thumb_func
reset_handler:
// low level hardware config, such as PLL setup goes here
b _start

View File

@ -0,0 +1,717 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Port Specific */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h Cortex-M7/GNU */
/* 6.1.10 */
/* */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file contains data type definitions that make the ThreadX */
/* real-time kernel function identically on a variety of different */
/* processor architectures. For example, the size or number of bits */
/* in an "int" data type vary between microprocessor architectures and */
/* even C compilers for the same microprocessor. ThreadX does not */
/* directly use native C data types. Instead, ThreadX creates its */
/* own special types that can be mapped to actual data types by this */
/* file to guarantee consistency in the interface and functionality. */
/* */
/* This file replaces the previous Cortex-M3/M4/M7 files. It unifies */
/* the ARMv7-M architecture and compilers into one common file. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-02-2021 Scott Larson Initial Version 6.1.7 */
/* 01-31-2022 Scott Larson Modified comments, updated */
/* typedef to fix misra */
/* violation, */
/* fixed predefined macro, */
/* resulting in version 6.1.10 */
/* */
/**************************************************************************/
#ifndef TX_PORT_H
#define TX_PORT_H
/* Determine if the optional ThreadX user define file should be used. */
#ifdef TX_INCLUDE_USER_DEFINE_FILE
/* Yes, include the user defines in tx_user.h. The defines in this file may
alternately be defined on the command line. */
#include "tx_user.h"
#endif
/* Define compiler library include files. */
#include <stdlib.h>
#include <string.h>
#ifdef __ICCARM__
#include <intrinsics.h> /* IAR Intrinsics */
#define __asm__ __asm /* Define to make all inline asm look similar */
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
#include <yvals.h>
#endif
#endif /* __ICCARM__ */
#ifdef __ghs__
#include <arm_ghs.h>
#include "tx_ghs.h"
#endif /* __ghs__ */
#if !defined(__GNUC__) && !defined(__CC_ARM)
#define __get_control_value __get_CONTROL
#define __set_control_value __set_CONTROL
#endif
#ifndef __GNUC__
#define __get_ipsr_value __get_IPSR
#endif
/* Define ThreadX basic types for this port. */
#define VOID void
typedef char CHAR;
typedef unsigned char UCHAR;
typedef int INT;
typedef unsigned int UINT;
typedef long LONG;
typedef unsigned long ULONG;
typedef unsigned long long ULONG64;
typedef short SHORT;
typedef unsigned short USHORT;
#define ULONG64_DEFINED
/* Define the priority levels for ThreadX. Legal values range
from 32 to 1024 and MUST be evenly divisible by 32. */
#ifndef TX_MAX_PRIORITIES
#define TX_MAX_PRIORITIES 32
#endif
/* Define the minimum stack for a ThreadX thread on this processor. If the size supplied during
thread creation is less than this value, the thread create call will return an error. */
#ifndef TX_MINIMUM_STACK
#define TX_MINIMUM_STACK 200 /* Minimum stack size for this port */
#endif
/* Define the system timer thread's default stack size and priority. These are only applicable
if TX_TIMER_PROCESS_IN_ISR is not defined. */
#ifndef TX_TIMER_THREAD_STACK_SIZE
#define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */
#endif
#ifndef TX_TIMER_THREAD_PRIORITY
#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */
#endif
/* Define various constants for the ThreadX Cortex-M port. */
#define TX_INT_DISABLE 1 /* Disable interrupts */
#define TX_INT_ENABLE 0 /* Enable interrupts */
/* Define the clock source for trace event entry time stamp. The following two item are port specific.
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
source constants would be:
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
#define TX_TRACE_TIME_MASK 0x0000FFFFUL
*/
#ifndef TX_MISRA_ENABLE
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004)
#endif
#else
ULONG _tx_misra_time_stamp_get(VOID);
#define TX_TRACE_TIME_SOURCE _tx_misra_time_stamp_get()
#endif
#ifndef TX_TRACE_TIME_MASK
#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL
#endif
#ifdef __ghs__
/* Define constants for Green Hills EventAnalyzer. */
/* Define the number of ticks per second. This informs the EventAnalyzer what the timestamps
represent. By default, this is set to 1,000,000 i.e., one tick every microsecond. */
#define TX_EL_TICKS_PER_SECOND 1000000
/* Define the method of how to get the upper and lower 32-bits of the time stamp. By default, simply
simulate the time-stamp source with a counter. */
#define read_tbu() _tx_el_time_base_upper
#define read_tbl() ++_tx_el_time_base_lower
#endif /* __ghs__ */
/* Define the port specific options for the _tx_build_options variable. This variable indicates
how the ThreadX library was built. */
#define TX_PORT_SPECIFIC_BUILD_OPTIONS (0)
/* Define the in-line initialization constant so that modules with in-line
initialization capabilities can prevent their initialization from being
a function call. */
#ifdef TX_MISRA_ENABLE
#define TX_DISABLE_INLINE
#else
#define TX_INLINE_INITIALIZATION
#endif
/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is
disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack
checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING
define is negated, thereby forcing the stack fill which is necessary for the stack checking
logic. */
#ifndef TX_MISRA_ENABLE
#ifdef TX_ENABLE_STACK_CHECKING
#undef TX_DISABLE_STACK_FILLING
#endif
#endif
/* Define the TX_THREAD control block extensions for this port. The main reason
for the multiple macros is so that backward compatibility can be maintained with
existing ThreadX kernel awareness modules. */
#define TX_THREAD_EXTENSION_0
#define TX_THREAD_EXTENSION_1
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer;
#elif defined(__ghs__)
#define TX_THREAD_EXTENSION_2 VOID * tx_thread_eh_globals; \
int Errno; /* errno. */ \
char * strtok_saved_pos; /* strtok() position. */
#else
#define TX_THREAD_EXTENSION_2
#endif
#define TX_THREAD_EXTENSION_3
/* Define the port extensions of the remaining ThreadX objects. */
#define TX_BLOCK_POOL_EXTENSION
#define TX_BYTE_POOL_EXTENSION
#define TX_EVENT_FLAGS_GROUP_EXTENSION
#define TX_MUTEX_EXTENSION
#define TX_QUEUE_EXTENSION
#define TX_SEMAPHORE_EXTENSION
#define TX_TIMER_EXTENSION
/* Define the user extension field of the thread control block. Nothing
additional is needed for this port so it is defined as white space. */
#ifndef TX_THREAD_USER_EXTENSION
#define TX_THREAD_USER_EXTENSION
#endif
/* Define the macros for processing extensions in tx_thread_create, tx_thread_delete,
tx_thread_shell_entry, and tx_thread_terminate. */
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
#if (__VER__ < 8000000)
#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate();
#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \
thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL;
#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0);
#else
void *_tx_iar_create_per_thread_tls_area(void);
void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr);
void __iar_Initlocks(void);
#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area();
#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \
thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0);
#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0);
#endif
#else
#define TX_THREAD_CREATE_EXTENSION(thread_ptr)
#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
#endif
#if defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__)
#ifdef TX_MISRA_ENABLE
ULONG _tx_misra_control_get(void);
void _tx_misra_control_set(ULONG value);
ULONG _tx_misra_fpccr_get(void);
void _tx_misra_vfp_touch(void);
#else /* TX_MISRA_ENABLE not defined */
/* Define some helper functions (these are intrinsics in some compilers). */
#ifdef __GNUC__ /* GCC and ARM Compiler 6 */
__attribute__( ( always_inline ) ) static inline ULONG __get_control_value(void)
{
ULONG control_value;
__asm__ volatile (" MRS %0,CONTROL ": "=r" (control_value) );
return(control_value);
}
__attribute__( ( always_inline ) ) static inline void __set_control_value(ULONG control_value)
{
__asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" );
}
#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0");
#elif defined(__CC_ARM) /* ARM Compiler 5 */
__attribute__( ( always_inline ) ) ULONG __get_control_value(void)
{
ULONG control_value;
__asm volatile ("MRS control_value,CONTROL");
return(control_value);
}
__attribute__( ( always_inline ) ) void __set_control_value(ULONG control_value)
{
__asm__ volatile ("MSR CONTROL,control_value");
}
/* Can't access VFP registers with inline asm, so define this in tx_thread_schedule. */
void _tx_vfp_access(void);
#define TX_VFP_TOUCH() _tx_vfp_access();
#elif defined(__ICCARM__) /* IAR */
#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0");
#endif /* Helper functions for different compilers */
#endif /* TX_MISRA_ENABLE */
/* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA
in order to ensure no lazy stacking will occur. */
#ifndef TX_MISRA_ENABLE
#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \
ULONG _tx_vfp_state; \
_tx_vfp_state = __get_control_value(); \
_tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \
__set_control_value(_tx_vfp_state); \
}
#else
#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \
ULONG _tx_vfp_state; \
_tx_vfp_state = _tx_misra_control_get(); \
_tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \
_tx_misra_control_set(_tx_vfp_state); \
}
#endif
/* A thread can be terminated by another thread, so we first check if it's self-terminating and not in an ISR.
If so, deactivate the FPU via CONTROL.FPCA. Otherwise we are in an interrupt or another thread is terminating
this one, so if the FPCCR.LSPACT bit is set, we need to save the CONTROL.FPCA state, touch the FPU to flush
the lazy FPU save, then restore the CONTROL.FPCA state. */
#ifndef TX_MISRA_ENABLE
#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \
ULONG _tx_system_state; \
_tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \
if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \
{ \
ULONG _tx_vfp_state; \
_tx_vfp_state = __get_control_value(); \
_tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \
__set_control_value(_tx_vfp_state); \
} \
else \
{ \
ULONG _tx_fpccr; \
_tx_fpccr = *((ULONG *) 0xE000EF34); \
_tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
if (_tx_fpccr == ((ULONG) 0x01)) \
{ \
ULONG _tx_vfp_state; \
_tx_vfp_state = __get_control_value(); \
_tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \
TX_VFP_TOUCH(); \
if (_tx_vfp_state == ((ULONG) 0)) \
{ \
_tx_vfp_state = __get_control_value(); \
_tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \
__set_control_value(_tx_vfp_state); \
} \
} \
} \
}
#else
#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \
ULONG _tx_system_state; \
_tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \
if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \
{ \
ULONG _tx_vfp_state; \
_tx_vfp_state = _tx_misra_control_get(); \
_tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \
_tx_misra_control_set(_tx_vfp_state); \
} \
else \
{ \
ULONG _tx_fpccr; \
_tx_fpccr = _tx_misra_fpccr_get(); \
_tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \
if (_tx_fpccr == ((ULONG) 0x01)) \
{ \
ULONG _tx_vfp_state; \
_tx_vfp_state = _tx_misra_control_get(); \
_tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \
_tx_misra_vfp_touch(); \
if (_tx_vfp_state == ((ULONG) 0)) \
{ \
_tx_vfp_state = _tx_misra_control_get(); \
_tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \
_tx_misra_control_set(_tx_vfp_state); \
} \
} \
} \
}
#endif
#else /* No VFP in use */
#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr)
#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr)
#endif /* defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */
/* Define the ThreadX object creation extensions for the remaining objects. */
#define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr)
#define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr)
#define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr)
#define TX_MUTEX_CREATE_EXTENSION(mutex_ptr)
#define TX_QUEUE_CREATE_EXTENSION(queue_ptr)
#define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr)
#define TX_TIMER_CREATE_EXTENSION(timer_ptr)
/* Define the ThreadX object deletion extensions for the remaining objects. */
#define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr)
#define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr)
#define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr)
#define TX_MUTEX_DELETE_EXTENSION(mutex_ptr)
#define TX_QUEUE_DELETE_EXTENSION(queue_ptr)
#define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr)
#define TX_TIMER_DELETE_EXTENSION(timer_ptr)
/* Define the get system state macro. */
#ifndef TX_THREAD_GET_SYSTEM_STATE
#ifndef TX_MISRA_ENABLE
#ifdef __CC_ARM /* ARM Compiler 5 */
register unsigned int _ipsr __asm("ipsr");
#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _ipsr)
#elif defined(__GNUC__) /* GCC and ARM Compiler 6 */
__attribute__( ( always_inline ) ) static inline unsigned int __get_ipsr_value(void)
{
unsigned int ipsr_value;
__asm__ volatile (" MRS %0,IPSR ": "=r" (ipsr_value) );
return(ipsr_value);
}
#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_ipsr_value())
#elif defined(__ICCARM__) /* IAR */
#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_IPSR())
#endif /* TX_THREAD_GET_SYSTEM_STATE for different compilers */
#else /* TX_MISRA_ENABLE is defined, use MISRA function. */
ULONG _tx_misra_ipsr_get(VOID);
#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get())
#endif /* TX_MISRA_ENABLE */
#endif /* TX_THREAD_GET_SYSTEM_STATE */
/* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value
indicates that _tx_thread_system_return should not be called. This overrides the definition in tx_thread.h
for Cortex-M since so we don't waste time checking the _tx_thread_system_state variable that is always
zero after initialization for Cortex-M ports. */
#ifndef TX_THREAD_SYSTEM_RETURN_CHECK
#define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable);
#endif
/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to
prevent early scheduling on Cortex-M parts. */
#define TX_PORT_SPECIFIC_POST_INITIALIZATION _tx_thread_preempt_disable++;
#ifndef TX_DISABLE_INLINE
/* Define the TX_LOWEST_SET_BIT_CALCULATE macro for each compiler. */
#ifdef __ICCARM__ /* IAR Compiler */
#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __CLZ(__RBIT((m)));
#elif defined(__CC_ARM) /* AC5 Compiler */
#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m)));
#elif defined(__GNUC__) /* GCC and AC6 Compiler */
#define TX_LOWEST_SET_BIT_CALCULATE(m, b) __asm__ volatile (" RBIT %0,%1 ": "=r" (m) : "r" (m) ); \
__asm__ volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) );
#endif
/* Define the interrupt disable/restore macros for each compiler. */
#if defined(__GNUC__) || defined(__ICCARM__)
/*** GCC/AC6 and IAR ***/
__attribute__( ( always_inline ) ) static inline unsigned int __get_interrupt_posture(void)
{
unsigned int posture;
#ifdef TX_PORT_USE_BASEPRI
__asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture));
#else
__asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture));
#endif
return(posture);
}
#ifdef TX_PORT_USE_BASEPRI
__attribute__( ( always_inline ) ) static inline void __set_basepri_value(unsigned int basepri_value)
{
__asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value));
}
#else
__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void)
{
__asm__ volatile ("CPSIE i": : : "memory");
}
#endif
__attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture)
{
#ifdef TX_PORT_USE_BASEPRI
__set_basepri_value(int_posture);
//__asm__ volatile ("MSR BASEPRI,%0": : "r" (int_posture): "memory");
#else
__asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory");
#endif
}
__attribute__( ( always_inline ) ) static inline unsigned int __disable_interrupts(void)
{
unsigned int int_posture;
int_posture = __get_interrupt_posture();
#ifdef TX_PORT_USE_BASEPRI
__set_basepri_value(TX_PORT_BASEPRI);
#else
__asm__ volatile ("CPSID i" : : : "memory");
#endif
return(int_posture);
}
__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void)
{
unsigned int interrupt_save;
/* Set PendSV to invoke ThreadX scheduler. */
*((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
if (__get_ipsr_value() == 0)
{
interrupt_save = __get_interrupt_posture();
#ifdef TX_PORT_USE_BASEPRI
__set_basepri_value(0);
#else
__enable_interrupts();
#endif
__restore_interrupt(interrupt_save);
}
}
#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save;
#define TX_DISABLE interrupt_save = __disable_interrupts();
#define TX_RESTORE __restore_interrupt(interrupt_save);
/*** End GCC/AC6 and IAR ***/
#elif defined(__CC_ARM)
/*** AC5 ***/
static __inline unsigned int __get_interrupt_posture(void)
{
unsigned int posture;
#ifdef TX_PORT_USE_BASEPRI
__asm__ volatile ("MRS #posture, BASEPRI");
#else
__asm__ volatile ("MRS #posture, PRIMASK");
#endif
return(posture);
}
#ifdef TX_PORT_USE_BASEPRI
static __inline void __set_basepri_value(unsigned int basepri_value)
{
__asm__ volatile ("MSR BASEPRI, #basepri_value");
}
#endif
static __inline unsigned int __disable_interrupts(void)
{
unsigned int int_posture;
int_posture = __get_interrupt_posture();
#ifdef TX_PORT_USE_BASEPRI
__set_basepri_value(TX_PORT_BASEPRI);
#else
__asm__ volatile ("CPSID i");
#endif
return(int_posture);
}
static __inline void __restore_interrupt(unsigned int int_posture)
{
#ifdef TX_PORT_USE_BASEPRI
__set_basepri_value(int_posture);
#else
__asm__ volatile ("MSR PRIMASK, #int_posture");
#endif
}
static void _tx_thread_system_return_inline(void)
{
unsigned int interrupt_save;
/* Set PendSV to invoke ThreadX scheduler. */
*((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
if (_ipsr == 0)
{
#ifdef TX_PORT_USE_BASEPRI
interrupt_save = __get_interrupt_posture();
__set_basepri_value(0);
__set_basepri_value(interrupt_save);
#else
interrupt_save = __disable_irq();
__enable_irq();
if (interrupt_save != 0)
__disable_irq();
#endif
}
}
#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save;
#define TX_DISABLE interrupt_save = __disable_interrupts();
#define TX_RESTORE __restore_interrupt(interrupt_save);
/*** End AC5 ***/
#endif /* Interrupt disable/restore macros for each compiler. */
/* Redefine _tx_thread_system_return for improved performance. */
#define _tx_thread_system_return _tx_thread_system_return_inline
#else /* TX_DISABLE_INLINE is defined */
UINT _tx_thread_interrupt_disable(VOID);
VOID _tx_thread_interrupt_restore(UINT previous_posture);
#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save;
#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable();
#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save);
#endif /* TX_DISABLE_INLINE */
/* Define FPU extension for the Cortex-M. Each is assumed to be called in the context of the executing
thread. These are no longer needed, but are preserved for backward compatibility only. */
void tx_thread_fpu_enable(void);
void tx_thread_fpu_disable(void);
/* Define the version ID of ThreadX. This may be utilized by the application. */
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M7/GNU Version 6.1.9 *";
#else
#ifdef TX_MISRA_ENABLE
extern CHAR _tx_version_id[100];
#else
extern CHAR _tx_version_id[];
#endif
#endif
#endif

View File

@ -0,0 +1,209 @@
Microsoft's Azure RTOS ThreadX for ARMv7-M
(Cortex-M3, Cortex-M4, Cortex-M7)
Using the GNU Tools
1. Building the ThreadX run-time Library
Navigate to the "example_build" directory. Ensure that
you have setup your path and other environment variables necessary for the ARM
GNU compiler. At this point you may run the build_threadx.bat batch file.
This will build the ThreadX run-time environment in the "example_build"
directory.
You should observe assembly and compilation of a series of ThreadX source
files. At the end of the batch file, they are all combined into the
run-time library file: tx.a. This file must be linked with your
application in order to use ThreadX.
2. Demonstration System
The ThreadX demonstration is designed to execute on Cortex-M evaluation boards
or on a dedicated simulator.
Building the demonstration is easy, simply execute the build_threadx_sample.bat
batch file while inside the "example_build" directory.
You should observe the compilation of sample_threadx.c (which is the demonstration
application) and linking with tx.a. The resulting file sample_threadx.out is a binary
file that can be downloaded and executed on the a simulator, or downloaded to a board.
3. System Initialization
The entry point in ThreadX for the Cortex-M using gnu tools uses the standard GNU
Cortex-M reset sequence. From the reset vector the C runtime will be initialized.
The ThreadX tx_initialize_low_level.S file is responsible for setting up
various system data structures, the vector area, and a periodic timer interrupt
source.
In addition, _tx_initialize_low_level determines the first available
address for use by the application, which is supplied as the sole input
parameter to your application definition function, tx_application_define.
4. Register Usage and Stack Frames
The following defines the saved context stack frames for context switches
that occur as a result of interrupt handling or from thread-level API calls.
All suspended threads have the same stack frame in the Cortex-M version of
ThreadX. The top of the suspended thread's stack is pointed to by
tx_thread_stack_ptr in the associated thread control block TX_THREAD.
Non-FPU Stack Frame:
Stack Offset Stack Contents
0x00 lr Interrupted lr (lr at time of PENDSV)
0x04 r4 Software stacked GP registers
0x08 r5
0x0C r6
0x10 r7
0x14 r8
0x18 r9
0x1C r10
0x20 r11
0x24 r0 Hardware stacked registers
0x28 r1
0x2C r2
0x30 r3
0x34 r12
0x38 lr
0x3C pc
0x40 xPSR
FPU Stack Frame (only interrupted thread with FPU enabled):
Stack Offset Stack Contents
0x00 lr Interrupted lr (lr at time of PENDSV)
0x04 s16 Software stacked FPU registers
0x08 s17
0x0C s18
0x10 s19
0x14 s20
0x18 s21
0x1C s22
0x20 s23
0x24 s24
0x28 s25
0x2C s26
0x30 s27
0x34 s28
0x38 s29
0x3C s30
0x40 s31
0x44 r4 Software stacked registers
0x48 r5
0x4C r6
0x50 r7
0x54 r8
0x58 r9
0x5C r10
0x60 r11
0x64 r0 Hardware stacked registers
0x68 r1
0x6C r2
0x70 r3
0x74 r12
0x78 lr
0x7C pc
0x80 xPSR
0x84 s0 Hardware stacked FPU registers
0x88 s1
0x8C s2
0x90 s3
0x94 s4
0x98 s5
0x9C s6
0xA0 s7
0xA4 s8
0xA8 s9
0xAC s10
0xB0 s11
0xB4 s12
0xB8 s13
0xBC s14
0xC0 s15
0xC4 fpscr
5. Improving Performance
The distribution version of ThreadX is built without any compiler optimizations.
This makes it easy to debug because you can trace or set breakpoints inside of
ThreadX itself. Of course, this costs some performance. To make it run faster,
you can change the build_threadx.bat file to remove the -g option and enable
all compiler optimizations.
In addition, you can eliminate the ThreadX basic API error checking by
compiling your application code with the symbol TX_DISABLE_ERROR_CHECKING
defined.
6. Interrupt Handling
ThreadX provides complete and high-performance interrupt handling for Cortex-M
targets. There are a certain set of requirements that are defined in the
following sub-sections:
6.1 Vector Area
The Cortex-M vectors start at the label __tx_vectors or similar. The application may modify
the vector area according to its needs. There is code in tx_initialize_low_level() that will
configure the vector base register.
6.2 Managed Interrupts
A ThreadX managed interrupt is defined below. By following these conventions, the
application ISR is then allowed access to various ThreadX services from the ISR.
Here is the standard template for managed ISRs in ThreadX:
.global __tx_IntHandler
.thumb_func
__tx_IntHandler:
; VOID InterruptHandler (VOID)
; {
PUSH {r0, lr}
; /* Do interrupt handler work here */
; /* BL <your interrupt routine in C> */
POP {r0, lr}
BX lr
; }
Note: the Cortex-M requires exception handlers to be thumb labels, this implies bit 0 set.
To accomplish this, the declaration of the label has to be preceded by the assembler directive
.thumb_func to instruct the linker to create thumb labels. The label __tx_IntHandler needs to
be inserted in the correct location in the interrupt vector table. This table is typically
located in either your runtime startup file or in the tx_initialize_low_level.S file.
7. FPU Support
ThreadX for Cortex-M supports automatic ("lazy") VFP support, which means that applications threads
can simply use the VFP and ThreadX automatically maintains the VFP registers as part of the thread
context - no additional setup by the application.
8. Revision History
For generic code revision information, please refer to the readme_threadx_generic.txt
file, which is included in your distribution. The following details the revision
information associated with this specific port of ThreadX:
06-02-2021 Initial ThreadX version 6.1.7 for Cortex-M using GNU tools.
Copyright(c) 1996-2021 Microsoft Corporation
https://azure.com/rtos

View File

@ -0,0 +1,82 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
.global _tx_execution_isr_exit
#endif
.text
.align 4
.syntax unified
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_context_restore Cortex-M7/GNU */
/* 6.1.7 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is only needed for legacy applications and it should */
/* not be called in any new development on a Cortex-M. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* [_tx_execution_isr_exit] Execution profiling ISR exit */
/* */
/* CALLED BY */
/* */
/* ISRs Interrupt Service Routines */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-02-2021 Scott Larson Initial Version 6.1.7 */
/* */
/**************************************************************************/
// VOID _tx_thread_context_restore(VOID)
// {
.global _tx_thread_context_restore
.thumb_func
_tx_thread_context_restore:
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
/* Call the ISR exit function to indicate an ISR is complete. */
PUSH {r0, lr} // Save return address
BL _tx_execution_isr_exit // Call the ISR exit function
POP {r0, lr} // Recover return address
#endif
BX lr
// }

View File

@ -0,0 +1,80 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
.text
.align 4
.syntax unified
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_context_save Cortex-M7/GNU */
/* 6.1.7 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is only needed for legacy applications and it should */
/* not be called in any new development on a Cortex-M. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* [_tx_execution_isr_enter] Execution profiling ISR enter */
/* */
/* CALLED BY */
/* */
/* ISRs */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-02-2021 Scott Larson Initial Version 6.1.7 */
/* */
/**************************************************************************/
// VOID _tx_thread_context_save(VOID)
// {
.global _tx_thread_context_save
.thumb_func
_tx_thread_context_save:
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
/* Call the ISR enter function to indicate an ISR is starting. */
PUSH {r0, lr} // Save return address
BL _tx_execution_isr_enter // Call the ISR enter function
POP {r0, lr} // Recover return address
#endif
/* Context is already saved - just return. */
BX lr
// }

View File

@ -0,0 +1,79 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
.text 32
.align 4
.syntax unified
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_control Cortex-M7/GNU */
/* 6.1.7 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is responsible for changing the interrupt lockout */
/* posture of the system. */
/* */
/* INPUT */
/* */
/* new_posture New interrupt lockout posture */
/* */
/* OUTPUT */
/* */
/* old_posture Old interrupt lockout posture */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-02-2021 Scott Larson Initial Version 6.1.7 */
/* */
/**************************************************************************/
// UINT _tx_thread_interrupt_control(UINT new_posture)
// {
.global _tx_thread_interrupt_control
.thumb_func
_tx_thread_interrupt_control:
#ifdef TX_PORT_USE_BASEPRI
MRS r1, BASEPRI // Pickup current interrupt posture
MSR BASEPRI, r0 // Apply the new interrupt posture
MOV r0, r1 // Transfer old to return register
#else
MRS r1, PRIMASK // Pickup current interrupt lockout
MSR PRIMASK, r0 // Apply the new interrupt lockout
MOV r0, r1 // Transfer old to return register
#endif
BX lr // Return to caller
// }

View File

@ -0,0 +1,79 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
.text 32
.align 4
.syntax unified
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_disable Cortex-M7/GNU */
/* 6.1.7 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is responsible for disabling interrupts and returning */
/* the previous interrupt lockout posture. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* old_posture Old interrupt lockout posture */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-02-2021 Scott Larson Initial Version 6.1.7 */
/* */
/**************************************************************************/
// UINT _tx_thread_interrupt_disable(VOID)
// {
.global _tx_thread_interrupt_disable
.thumb_func
_tx_thread_interrupt_disable:
/* Return current interrupt lockout posture. */
#ifdef TX_PORT_USE_BASEPRI
MRS r0, BASEPRI
LDR r1, =TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
MRS r0, PRIMASK
CPSID i
#endif
BX lr
// }

View File

@ -0,0 +1,76 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
.text 32
.align 4
.syntax unified
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_restore Cortex-M7/GNU */
/* 6.1.7 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is responsible for restoring the previous */
/* interrupt lockout posture. */
/* */
/* INPUT */
/* */
/* previous_posture Previous interrupt posture */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-02-2021 Scott Larson Initial Version 6.1.7 */
/* */
/**************************************************************************/
// VOID _tx_thread_interrupt_restore(UINT previous_posture)
// {
.global _tx_thread_interrupt_restore
.thumb_func
_tx_thread_interrupt_restore:
/* Restore previous interrupt lockout posture. */
#ifdef TX_PORT_USE_BASEPRI
MSR BASEPRI, r0
#else
MSR PRIMASK, r0
#endif
BX lr
// }

View File

@ -0,0 +1,289 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
.global _tx_thread_current_ptr
.global _tx_thread_execute_ptr
.global _tx_timer_time_slice
.global _tx_execution_thread_enter
.global _tx_execution_thread_exit
#ifdef TX_LOW_POWER
.global tx_low_power_enter
.global tx_low_power_exit
#endif
.text
.align 4
.syntax unified
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M7/GNU */
/* 6.1.10 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function waits for a thread control block pointer to appear in */
/* the _tx_thread_execute_ptr variable. Once a thread pointer appears */
/* in the variable, the corresponding thread is resumed. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _tx_initialize_kernel_enter ThreadX entry function */
/* _tx_thread_system_return Return to system from thread */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-02-2021 Scott Larson Initial Version 6.1.7 */
/* 01-31-2022 Scott Larson Fixed predefined macro name, */
/* resulting in version 6.1.10 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
// {
.global _tx_thread_schedule
.thumb_func
_tx_thread_schedule:
/* This function should only ever be called on Cortex-M
from the first schedule request. Subsequent scheduling occurs
from the PendSV handling routine below. */
/* Clear the preempt-disable flag to enable rescheduling after initialization on Cortex-M targets. */
MOV r0, #0 // Build value for TX_FALSE
LDR r2, =_tx_thread_preempt_disable // Build address of preempt disable flag
STR r0, [r2, #0] // Clear preempt disable flag
/* Clear CONTROL.FPCA bit so VFP registers aren't unnecessarily stacked. */
#ifdef __ARM_FP
MRS r0, CONTROL // Pickup current CONTROL register
BIC r0, r0, #4 // Clear the FPCA bit
MSR CONTROL, r0 // Setup new CONTROL register
#endif
/* Enable interrupts */
CPSIE i
/* Enter the scheduler for the first time. */
MOV r0, #0x10000000 // Load PENDSVSET bit
MOV r1, #0xE000E000 // Load NVIC base
STR r0, [r1, #0xD04] // Set PENDSVBIT in ICSR
DSB // Complete all memory accesses
ISB // Flush pipeline
/* Wait here for the PendSV to take place. */
__tx_wait_here:
B __tx_wait_here // Wait for the PendSV to happen
// }
/* Generic context switching PendSV handler. */
.global TX_PendSV_Handler
.global __tx_PendSVHandler
.syntax unified
.thumb_func
TX_PendSV_Handler:
.thumb_func
__tx_PendSVHandler:
/* Get current thread value and new thread pointer. */
__tx_ts_handler:
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
/* Call the thread exit function to indicate the thread is no longer executing. */
CPSID i // Disable interrupts
PUSH {r0, lr} // Save LR (and r0 just for alignment)
BL _tx_execution_thread_exit // Call the thread exit function
POP {r0, lr} // Recover LR
CPSIE i // Enable interrupts
#endif
LDR r0, =_tx_thread_current_ptr // Build current thread pointer address
LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address
MOV r3, #0 // Build NULL value
LDR r1, [r0] // Pickup current thread pointer
/* Determine if there is a current thread to finish preserving. */
CBZ r1, __tx_ts_new // If NULL, skip preservation
/* Recover PSP and preserve current thread context. */
STR r3, [r0] // Set _tx_thread_current_ptr to NULL
MRS r12, PSP // Pickup PSP pointer (thread's stack pointer)
STMDB r12!, {r4-r11} // Save its remaining registers
#ifdef __ARM_FP
TST LR, #0x10 // Determine if the VFP extended frame is present
BNE _skip_vfp_save
VSTMDB r12!,{s16-s31} // Yes, save additional VFP registers
_skip_vfp_save:
#endif
LDR r4, =_tx_timer_time_slice // Build address of time-slice variable
STMDB r12!, {LR} // Save LR on the stack
/* Determine if time-slice is active. If it isn't, skip time handling processing. */
LDR r5, [r4] // Pickup current time-slice
STR r12, [r1, #8] // Save the thread stack pointer
CBZ r5, __tx_ts_new // If not active, skip processing
/* Time-slice is active, save the current thread's time-slice and clear the global time-slice variable. */
STR r5, [r1, #24] // Save current time-slice
/* Clear the global time-slice. */
STR r3, [r4] // Clear time-slice
/* Executing thread is now completely preserved!!! */
__tx_ts_new:
/* Now we are looking for a new thread to execute! */
CPSID i // Disable interrupts
LDR r1, [r2] // Is there another thread ready to execute?
CBZ r1, __tx_ts_wait // No, skip to the wait processing
/* Yes, another thread is ready for else, make the current thread the new thread. */
STR r1, [r0] // Setup the current thread pointer to the new thread
CPSIE i // Enable interrupts
/* Increment the thread run count. */
__tx_ts_restore:
LDR r7, [r1, #4] // Pickup the current thread run count
LDR r4, =_tx_timer_time_slice // Build address of time-slice variable
LDR r5, [r1, #24] // Pickup thread's current time-slice
ADD r7, r7, #1 // Increment the thread run count
STR r7, [r1, #4] // Store the new run count
/* Setup global time-slice with thread's current time-slice. */
STR r5, [r4] // Setup global time-slice
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
/* Call the thread entry function to indicate the thread is executing. */
PUSH {r0, r1} // Save r0 and r1
BL _tx_execution_thread_enter // Call the thread execution enter function
POP {r0, r1} // Recover r0 and r1
#endif
/* Restore the thread context and PSP. */
LDR r12, [r1, #8] // Pickup thread's stack pointer
LDMIA r12!, {LR} // Pickup LR
#ifdef __ARM_FP
TST LR, #0x10 // Determine if the VFP extended frame is present
BNE _skip_vfp_restore // If not, skip VFP restore
VLDMIA r12!, {s16-s31} // Yes, restore additional VFP registers
_skip_vfp_restore:
#endif
LDMIA r12!, {r4-r11} // Recover thread's registers
MSR PSP, r12 // Setup the thread's stack pointer
/* Return to thread. */
BX lr // Return to thread!
/* The following is the idle wait processing... in this case, no threads are ready for execution and the
system will simply be idle until an interrupt occurs that makes a thread ready. Note that interrupts
are disabled to allow use of WFI for waiting for a thread to arrive. */
__tx_ts_wait:
CPSID i // Disable interrupts
LDR r1, [r2] // Pickup the next thread to execute pointer
STR r1, [r0] // Store it in the current pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
#ifdef TX_LOW_POWER
PUSH {r0-r3}
BL tx_low_power_enter // Possibly enter low power mode
POP {r0-r3}
#endif
#ifdef TX_ENABLE_WFI
DSB // Ensure no outstanding memory transactions
WFI // Wait for interrupt
ISB // Ensure pipeline is flushed
#endif
#ifdef TX_LOW_POWER
PUSH {r0-r3}
BL tx_low_power_exit // Exit low power mode
POP {r0-r3}
#endif
CPSIE i // Enable interrupts
B __tx_ts_wait // Loop to continue waiting
/* At this point, we have a new thread ready to go. Clear any newly pended PendSV - since we are
already in the handler! */
__tx_ts_ready:
MOV r7, #0x08000000 // Build clear PendSV value
MOV r8, #0xE000E000 // Build base NVIC address
STR r7, [r8, #0xD04] // Clear any PendSV
/* Re-enable interrupts and restore new thread. */
CPSIE i // Enable interrupts
B __tx_ts_restore // Restore the thread
// }
#ifdef __ARM_FP
.global tx_thread_fpu_enable
.thumb_func
tx_thread_fpu_enable:
.global tx_thread_fpu_disable
.thumb_func
tx_thread_fpu_disable:
/* Automatic VPF logic is supported, this function is present only for
backward compatibility purposes and therefore simply returns. */
BX LR // Return to caller
#endif

View File

@ -0,0 +1,133 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
.text
.align 4
.syntax unified
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_stack_build Cortex-M7/GNU */
/* 6.1.7 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function builds a stack frame on the supplied thread's stack. */
/* The stack frame results in a fake interrupt return to the supplied */
/* function pointer. */
/* */
/* INPUT */
/* */
/* thread_ptr Pointer to thread control blk */
/* function_ptr Pointer to return function */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _tx_thread_create Create thread service */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-02-2021 Scott Larson Initial Version 6.1.7 */
/* */
/**************************************************************************/
// VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID))
// {
.global _tx_thread_stack_build
.thumb_func
_tx_thread_stack_build:
/* Build a fake interrupt frame. The form of the fake interrupt stack
on the Cortex-M should look like the following after it is built:
Stack Top:
LR Interrupted LR (LR at time of PENDSV)
r4 Initial value for r4
r5 Initial value for r5
r6 Initial value for r6
r7 Initial value for r7
r8 Initial value for r8
r9 Initial value for r9
r10 Initial value for r10
r11 Initial value for r11
r0 Initial value for r0 (Hardware stack starts here!!)
r1 Initial value for r1
r2 Initial value for r2
r3 Initial value for r3
r12 Initial value for r12
lr Initial value for lr
pc Initial value for pc
xPSR Initial value for xPSR
Stack Bottom: (higher memory address) */
LDR r2, [r0, #16] // Pickup end of stack area
BIC r2, r2, #0x7 // Align frame for 8-byte alignment
SUB r2, r2, #68 // Subtract frame size
LDR r3, =0xFFFFFFFD // Build initial LR value
STR r3, [r2, #0] // Save on the stack
/* Actually build the stack frame. */
MOV r3, #0 // Build initial register value
STR r3, [r2, #4] // Store initial r4
STR r3, [r2, #8] // Store initial r5
STR r3, [r2, #12] // Store initial r6
STR r3, [r2, #16] // Store initial r7
STR r3, [r2, #20] // Store initial r8
STR r3, [r2, #24] // Store initial r9
STR r3, [r2, #28] // Store initial r10
STR r3, [r2, #32] // Store initial r11
/* Hardware stack follows. */
STR r3, [r2, #36] // Store initial r0
STR r3, [r2, #40] // Store initial r1
STR r3, [r2, #44] // Store initial r2
STR r3, [r2, #48] // Store initial r3
STR r3, [r2, #52] // Store initial r12
MOV r3, #0xFFFFFFFF // Poison EXC_RETURN value
STR r3, [r2, #56] // Store initial lr
STR r1, [r2, #60] // Store initial pc
MOV r3, #0x01000000 // Only T-bit need be set
STR r3, [r2, #64] // Store initial xPSR
/* Setup stack pointer. */
// thread_ptr -> tx_thread_stack_ptr = r2;
STR r2, [r0, #8] // Save stack pointer in thread's
// control block
BX lr // Return to caller
// }

View File

@ -0,0 +1,93 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
.text 32
.align 4
.syntax unified
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_system_return Cortex-M7/GNU */
/* 6.1.7 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is target processor specific. It is used to transfer */
/* control from a thread back to the ThreadX system. Only a */
/* minimal context is saved since the compiler assumes temp registers */
/* are going to get slicked by a function call anyway. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _tx_thread_schedule Thread scheduling loop */
/* */
/* CALLED BY */
/* */
/* ThreadX components */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-02-2021 Scott Larson Initial Version 6.1.7 */
/* */
/**************************************************************************/
// VOID _tx_thread_system_return(VOID)
// {
.thumb_func
.global _tx_thread_system_return
_tx_thread_system_return:
/* Return to real scheduler via PendSV. Note that this routine is often
replaced with in-line assembly in tx_port.h to improved performance. */
MOV r0, #0x10000000 // Load PENDSVSET bit
MOV r1, #0xE000E000 // Load NVIC base
STR r0, [r1, #0xD04] // Set PENDSVBIT in ICSR
MRS r0, IPSR // Pickup IPSR
CMP r0, #0 // Is it a thread returning?
BNE _isr_context // If ISR, skip interrupt enable
#ifdef TX_PORT_USE_BASEPRI
MRS r1, BASEPRI // Thread context returning, pickup BASEPRI
MOV r0, #0
MSR BASEPRI, r0 // Enable interrupts
MSR BASEPRI, r1 // Restore original interrupt posture
#else
MRS r1, PRIMASK // Thread context returning, pickup PRIMASK
CPSIE i // Enable interrupts
MSR PRIMASK, r1 // Restore original interrupt posture
#endif
_isr_context:
BX lr // Return to caller
// }

View File

@ -0,0 +1,255 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Timer */
/** */
/**************************************************************************/
/**************************************************************************/
.global _tx_timer_time_slice
.global _tx_timer_system_clock
.global _tx_timer_current_ptr
.global _tx_timer_list_start
.global _tx_timer_list_end
.global _tx_timer_expired_time_slice
.global _tx_timer_expired
.global _tx_thread_time_slice
.global _tx_timer_expiration_process
.text
.align 4
.syntax unified
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_timer_interrupt Cortex-M7/GNU */
/* 6.1.10 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function processes the hardware timer interrupt. This */
/* processing includes incrementing the system clock and checking for */
/* time slice and/or timer expiration. If either is found, the */
/* expiration functions are called. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _tx_timer_expiration_process Timer expiration processing */
/* _tx_thread_time_slice Time slice interrupted thread */
/* */
/* CALLED BY */
/* */
/* interrupt vector */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-02-2021 Scott Larson Initial Version 6.1.7 */
/* 01-31-2022 Scott Larson Modified comment(s), added */
/* TX_NO_TIMER support, */
/* resulting in version 6.1.10 */
/* */
/**************************************************************************/
// VOID _tx_timer_interrupt(VOID)
// {
#ifndef TX_NO_TIMER
.global _tx_timer_interrupt
.thumb_func
_tx_timer_interrupt:
/* Upon entry to this routine, it is assumed that the compiler scratch registers are available
for use. */
/* Increment the system clock. */
// _tx_timer_system_clock++;
LDR r1, =_tx_timer_system_clock // Pickup address of system clock
LDR r0, [r1, #0] // Pickup system clock
ADD r0, r0, #1 // Increment system clock
STR r0, [r1, #0] // Store new system clock
/* Test for time-slice expiration. */
// if (_tx_timer_time_slice)
// {
LDR r3, =_tx_timer_time_slice // Pickup address of time-slice
LDR r2, [r3, #0] // Pickup time-slice
CBZ r2, __tx_timer_no_time_slice // Is it non-active?
// Yes, skip time-slice processing
/* Decrement the time_slice. */
// _tx_timer_time_slice--;
SUB r2, r2, #1 // Decrement the time-slice
STR r2, [r3, #0] // Store new time-slice value
/* Check for expiration. */
// if (__tx_timer_time_slice == 0)
CBNZ r2, __tx_timer_no_time_slice // Has it expired?
// No, skip expiration processing
/* Set the time-slice expired flag. */
// _tx_timer_expired_time_slice = TX_TRUE;
LDR r3, =_tx_timer_expired_time_slice // Pickup address of expired flag
MOV r0, #1 // Build expired value
STR r0, [r3, #0] // Set time-slice expiration flag
// }
__tx_timer_no_time_slice:
/* Test for timer expiration. */
// if (*_tx_timer_current_ptr)
// {
LDR r1, =_tx_timer_current_ptr // Pickup current timer pointer address
LDR r0, [r1, #0] // Pickup current timer
LDR r2, [r0, #0] // Pickup timer list entry
CBZ r2, __tx_timer_no_timer // Is there anything in the list?
// No, just increment the timer
/* Set expiration flag. */
// _tx_timer_expired = TX_TRUE;
LDR r3, =_tx_timer_expired // Pickup expiration flag address
MOV r2, #1 // Build expired value
STR r2, [r3, #0] // Set expired flag
B __tx_timer_done // Finished timer processing
// }
// else
// {
__tx_timer_no_timer:
/* No timer expired, increment the timer pointer. */
// _tx_timer_current_ptr++;
ADD r0, r0, #4 // Move to next timer
/* Check for wrap-around. */
// if (_tx_timer_current_ptr == _tx_timer_list_end)
LDR r3, =_tx_timer_list_end // Pickup addr of timer list end
LDR r2, [r3, #0] // Pickup list end
CMP r0, r2 // Are we at list end?
BNE __tx_timer_skip_wrap // No, skip wrap-around logic
/* Wrap to beginning of list. */
// _tx_timer_current_ptr = _tx_timer_list_start;
LDR r3, =_tx_timer_list_start // Pickup addr of timer list start
LDR r0, [r3, #0] // Set current pointer to list start
__tx_timer_skip_wrap:
STR r0, [r1, #0] // Store new current timer pointer
// }
__tx_timer_done:
/* See if anything has expired. */
// if ((_tx_timer_expired_time_slice) || (_tx_timer_expired))
// {
LDR r3, =_tx_timer_expired_time_slice // Pickup addr of expired flag
LDR r2, [r3, #0] // Pickup time-slice expired flag
CBNZ r2, __tx_something_expired // Did a time-slice expire?
// If non-zero, time-slice expired
LDR r1, =_tx_timer_expired // Pickup addr of other expired flag
LDR r0, [r1, #0] // Pickup timer expired flag
CBZ r0, __tx_timer_nothing_expired // Did a timer expire?
// No, nothing expired
__tx_something_expired:
STMDB sp!, {r0, lr} // Save the lr register on the stack
// and save r0 just to keep 8-byte alignment
/* Did a timer expire? */
// if (_tx_timer_expired)
// {
LDR r1, =_tx_timer_expired // Pickup addr of expired flag
LDR r0, [r1, #0] // Pickup timer expired flag
CBZ r0, __tx_timer_dont_activate // Check for timer expiration
// If not set, skip timer activation
/* Process timer expiration. */
// _tx_timer_expiration_process();
BL _tx_timer_expiration_process // Call the timer expiration handling routine
// }
__tx_timer_dont_activate:
/* Did time slice expire? */
// if (_tx_timer_expired_time_slice)
// {
LDR r3, =_tx_timer_expired_time_slice // Pickup addr of time-slice expired
LDR r2, [r3, #0] // Pickup the actual flag
CBZ r2, __tx_timer_not_ts_expiration // See if the flag is set
// No, skip time-slice processing
/* Time slice interrupted thread. */
// _tx_thread_time_slice();
BL _tx_thread_time_slice // Call time-slice processing
LDR r0, =_tx_thread_preempt_disable // Build address of preempt disable flag
LDR r1, [r0] // Is the preempt disable flag set?
CBNZ r1, __tx_timer_skip_time_slice // Yes, skip the PendSV logic
LDR r0, =_tx_thread_current_ptr // Build current thread pointer address
LDR r1, [r0] // Pickup the current thread pointer
LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address
LDR r3, [r2] // Pickup the execute thread pointer
LDR r0, =0xE000ED04 // Build address of control register
LDR r2, =0x10000000 // Build value for PendSV bit
CMP r1, r3 // Are they the same?
BEQ __tx_timer_skip_time_slice // If the same, there was no time-slice performed
STR r2, [r0] // Not the same, issue the PendSV for preemption
__tx_timer_skip_time_slice:
// }
__tx_timer_not_ts_expiration:
LDMIA sp!, {r0, lr} // Recover lr register (r0 is just there for
// the 8-byte stack alignment
// }
__tx_timer_nothing_expired:
DSB // Complete all memory access
BX lr // Return to caller
// }
#endif

@ -0,0 +1 @@
Subproject commit 3b203634dce8fc51e77ac67ec28d91d693c2c570

@ -0,0 +1 @@
Subproject commit fafaebe513129e0899a832b0899fa9e69187ee06

@ -0,0 +1 @@
Subproject commit 11303a0e1bb184c87ef267b582e5272054006edc

@ -0,0 +1 @@
Subproject commit 8f56ef4e4492dd66c2161b7c1534c6f4442852a4

View File

@ -1,11 +1,11 @@
#MicroXplorer Configuration settings - do not modify
CORTEX_M7.AccessPermission-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_REGION_FULL_ACCESS
CORTEX_M7.CPU_DCache=Enabled
CORTEX_M7.CPU_ICache=Enabled
CORTEX_M7.CPU_DCache=Disabled
CORTEX_M7.CPU_ICache=Disabled
CORTEX_M7.Enable-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_REGION_ENABLE
CORTEX_M7.IPParameters=MPU_Control,Enable-Cortex_Memory_Protection_Unit_Region0_Settings,Size-Cortex_Memory_Protection_Unit_Region0_Settings,AccessPermission-Cortex_Memory_Protection_Unit_Region0_Settings,IsShareable-Cortex_Memory_Protection_Unit_Region0_Settings,CPU_ICache,CPU_DCache
CORTEX_M7.IsShareable-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_ACCESS_SHAREABLE
CORTEX_M7.MPU_Control=MPU_PRIVILEGED_DEFAULT
CORTEX_M7.MPU_Control=__NULL
CORTEX_M7.Size-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_REGION_SIZE_4GB
Dma.Request0=SAI3_A
Dma.RequestsNb=1
@ -15,11 +15,11 @@ Dma.SAI3_A.0.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.SAI3_A.0.Instance=DMA1_Stream0
Dma.SAI3_A.0.MemDataAlignment=DMA_MDATAALIGN_HALFWORD
Dma.SAI3_A.0.MemInc=DMA_MINC_ENABLE
Dma.SAI3_A.0.Mode=DMA_NORMAL
Dma.SAI3_A.0.Mode=DMA_CIRCULAR
Dma.SAI3_A.0.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD
Dma.SAI3_A.0.PeriphInc=DMA_PINC_DISABLE
Dma.SAI3_A.0.Polarity=HAL_DMAMUX_REQ_GEN_RISING
Dma.SAI3_A.0.Priority=DMA_PRIORITY_LOW
Dma.SAI3_A.0.Priority=DMA_PRIORITY_MEDIUM
Dma.SAI3_A.0.RequestNumber=1
Dma.SAI3_A.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
Dma.SAI3_A.0.SignalID=NONE
@ -29,7 +29,10 @@ Dma.SAI3_A.0.SyncRequestNumber=1
Dma.SAI3_A.0.SyncSignalID=NONE
File.Version=6
GPIO.groupedBy=Group By Peripherals
I2C4.IPParameters=Timing
I2C4.I2C_Fall_Time=0
I2C4.I2C_Rise_Time=0
I2C4.I2C_Speed_Mode=I2C_Standard
I2C4.IPParameters=Timing,I2C_Speed_Mode,I2C_Fall_Time,I2C_Rise_Time
I2C4.Timing=0x107075B0
KeepUserPlacement=false
Mcu.Family=STM32H7
@ -53,40 +56,42 @@ Mcu.Pin1=PC14-OSC32_IN (OSC32_IN)
Mcu.Pin10=PD11
Mcu.Pin11=PD12
Mcu.Pin12=PD13
Mcu.Pin13=PD15
Mcu.Pin14=PC6
Mcu.Pin15=PC7
Mcu.Pin16=PC8
Mcu.Pin17=PC9
Mcu.Pin18=PA9
Mcu.Pin19=PA10
Mcu.Pin13=PD14
Mcu.Pin14=PD15
Mcu.Pin15=PC6
Mcu.Pin16=PC7
Mcu.Pin17=PC8
Mcu.Pin18=PC9
Mcu.Pin19=PA8
Mcu.Pin2=PC15-OSC32_OUT (OSC32_OUT)
Mcu.Pin20=PA11
Mcu.Pin21=PA12
Mcu.Pin22=PA13 (JTMS/SWDIO)
Mcu.Pin23=PA14 (JTCK/SWCLK)
Mcu.Pin24=PD0
Mcu.Pin25=PD1
Mcu.Pin26=PD4
Mcu.Pin27=PB4 (NJTRST)
Mcu.Pin28=PB6
Mcu.Pin29=PB7
Mcu.Pin20=PA9
Mcu.Pin21=PA10
Mcu.Pin22=PA11
Mcu.Pin23=PA12
Mcu.Pin24=PA13 (JTMS/SWDIO)
Mcu.Pin25=PA14 (JTCK/SWCLK)
Mcu.Pin26=PD0
Mcu.Pin27=PD1
Mcu.Pin28=PD4
Mcu.Pin29=PB4 (NJTRST)
Mcu.Pin3=PH0-OSC_IN (PH0)
Mcu.Pin30=PB8
Mcu.Pin31=VP_RAMECC_VS_D1_1
Mcu.Pin32=VP_RAMECC_VS_D2_1
Mcu.Pin33=VP_RAMECC_VS_D2_2
Mcu.Pin34=VP_RAMECC_VS_D2_3
Mcu.Pin35=VP_RAMECC_VS_D2_4
Mcu.Pin36=VP_RAMECC_VS_D2_5
Mcu.Pin37=VP_SYS_VS_Systick
Mcu.Pin30=PB6
Mcu.Pin31=PB7
Mcu.Pin32=PB8
Mcu.Pin33=VP_RAMECC_VS_D1_1
Mcu.Pin34=VP_RAMECC_VS_D2_1
Mcu.Pin35=VP_RAMECC_VS_D2_2
Mcu.Pin36=VP_RAMECC_VS_D2_3
Mcu.Pin37=VP_RAMECC_VS_D2_4
Mcu.Pin38=VP_RAMECC_VS_D2_5
Mcu.Pin39=VP_SYS_VS_tim7
Mcu.Pin4=PH1-OSC_OUT (PH1)
Mcu.Pin5=PA1
Mcu.Pin6=PB2
Mcu.Pin7=PD8
Mcu.Pin8=PD9
Mcu.Pin9=PD10
Mcu.PinsNb=38
Mcu.PinsNb=40
Mcu.ThirdPartyNb=0
Mcu.UserConstants=
Mcu.UserName=STM32H750VBTx
@ -104,17 +109,20 @@ NVIC.I2C4_ER_IRQn=true\:0\:0\:true\:false\:true\:true\:true
NVIC.I2C4_EV_IRQn=true\:0\:0\:true\:false\:true\:true\:true
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false
NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false
NVIC.OTG_FS_EP1_IN_IRQn=true\:0\:0\:true\:false\:true\:true\:true
NVIC.OTG_FS_EP1_OUT_IRQn=true\:0\:0\:true\:false\:true\:true\:true
NVIC.OTG_FS_IRQn=true\:0\:0\:true\:false\:true\:true\:true
NVIC.OTG_FS_EP1_IN_IRQn=true\:4\:0\:true\:false\:true\:true\:true
NVIC.OTG_FS_EP1_OUT_IRQn=true\:4\:0\:true\:false\:true\:true\:true
NVIC.OTG_FS_IRQn=true\:4\:0\:true\:false\:true\:true\:true
NVIC.PVD_AVD_IRQn=true\:0\:0\:false\:false\:true\:true\:true
NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false
NVIC.PendSV_IRQn=true\:15\:0\:true\:false\:true\:false\:false
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
NVIC.QUADSPI_IRQn=true\:0\:0\:true\:false\:true\:true\:true
NVIC.RCC_IRQn=true\:0\:0\:false\:false\:true\:true\:false
NVIC.SAI3_IRQn=true\:0\:0\:true\:false\:true\:true\:true
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true
NVIC.SVCall_IRQn=true\:15\:0\:true\:false\:true\:false\:false
NVIC.SysTick_IRQn=true\:4\:0\:true\:false\:true\:false\:true
NVIC.TIM7_IRQn=true\:15\:0\:false\:false\:true\:false\:true
NVIC.TimeBase=TIM7_IRQn
NVIC.TimeBaseIP=TIM7
NVIC.USART1_IRQn=true\:0\:0\:true\:false\:true\:true\:true
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false
PA1.GPIOParameters=PinState,GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultOutputPP
@ -139,6 +147,10 @@ PA13\ (JTMS/SWDIO).Signal=DEBUG_JTMS-SWDIO
PA14\ (JTCK/SWCLK).Locked=true
PA14\ (JTCK/SWCLK).Mode=Serial_Wire
PA14\ (JTCK/SWCLK).Signal=DEBUG_JTCK-SWCLK
PA8.GPIOParameters=GPIO_Label
PA8.GPIO_Label=MCU_OSC24EN
PA8.Locked=true
PA8.Signal=GPIO_Output
PA9.Locked=true
PA9.Mode=Asynchronous
PA9.Signal=USART1_TX
@ -251,6 +263,10 @@ PD12.Signal=QUADSPI_BK1_IO1
PD13.Locked=true
PD13.Mode=Single Bank 1
PD13.Signal=QUADSPI_BK1_IO3
PD14.GPIOParameters=GPIO_Label
PD14.GPIO_Label=MCU_OSC22EN
PD14.Locked=true
PD14.Signal=GPIO_Output
PD15.Locked=true
PD15.Mode=SAI_A_MasterWithClock
PD15.Signal=SAI3_MCLK_A
@ -316,7 +332,7 @@ RAMECC.Instance-RAMECC2_Monitor2=RAMECC2_Monitor2
RAMECC.Instance-RAMECC2_Monitor3=RAMECC2_Monitor3
RAMECC.Instance-RAMECC2_Monitor4=RAMECC2_Monitor4
RAMECC.Instance-RAMECC2_Monitor5=RAMECC2_Monitor5
RCC.ADCFreq_Value=62914568.86574074
RCC.ADCFreq_Value=24575951.597744364
RCC.AHB12Freq_Value=120000000
RCC.AHB4Freq_Value=120000000
RCC.APB1Freq_Value=60000000
@ -336,20 +352,20 @@ RCC.D3PPRE=RCC_APB4_DIV2
RCC.DFSDMACLkFreq_Value=24000000
RCC.DFSDMFreq_Value=60000000
RCC.DIVM1=16
RCC.DIVM2=6
RCC.DIVM2=7
RCC.DIVN1=60
RCC.DIVN2=106
RCC.DIVN2=51
RCC.DIVP1Freq_Value=120000000
RCC.DIVP2=18
RCC.DIVP2Freq_Value=62914568.86574074
RCC.DIVP2=19
RCC.DIVP2Freq_Value=24575951.597744364
RCC.DIVP3Freq_Value=129000000
RCC.DIVQ1=10
RCC.DIVQ1Freq_Value=24000000
RCC.DIVQ2Freq_Value=566231119.7916666
RCC.DIVQ2Freq_Value=233471540.17857146
RCC.DIVQ3Freq_Value=129000000
RCC.DIVR1=25
RCC.DIVR1Freq_Value=9600000
RCC.DIVR2Freq_Value=566231119.7916666
RCC.DIVR2Freq_Value=233471540.17857146
RCC.DIVR3Freq_Value=129000000
RCC.EXTERNAL_CLOCK_VALUE=24576000
RCC.FDCANFreq_Value=24000000
@ -369,7 +385,7 @@ RCC.LPUART1Freq_Value=60000000
RCC.LTDCFreq_Value=129000000
RCC.MCO1PinFreq_Value=64000000
RCC.MCO2PinFreq_Value=120000000
RCC.PLL2FRACN=1379
RCC.PLL2FRACN=589
RCC.PLL3FRACN=0
RCC.PLLFRACN=0
RCC.PWR_Regulator_Voltage_Scale=PWR_REGULATOR_VOLTAGE_SCALE2
@ -398,32 +414,42 @@ RCC.USART234578Freq_Value=60000000
RCC.USBCLockSelection=RCC_USBCLKSOURCE_HSI48
RCC.USBFreq_Value=48000000
RCC.VCO1OutputFreq_Value=240000000
RCC.VCO2OutputFreq_Value=1132462239.5833333
RCC.VCO2OutputFreq_Value=466943080.3571429
RCC.VCO3OutputFreq_Value=258000000
RCC.VCOInput1Freq_Value=4000000
RCC.VCOInput2Freq_Value=10666666.666666666
RCC.VCOInput2Freq_Value=9142857.142857144
RCC.VCOInput3Freq_Value=2000000
SAI3.ActiveFrameLength-SAI_A_MasterWithClock=16
SAI3.AudioFrequency-SAI_A_MasterWithClock=SAI_AUDIO_FREQUENCY_48K
SAI3.ClockStrobing-SAI_A_MasterWithClock=SAI_CLOCKSTROBING_RISINGEDGE
SAI3.CompandingMode-SAI_A_MasterWithClock=SAI_NOCOMPANDING
SAI3.DataSize-SAI_A_MasterWithClock=SAI_DATASIZE_16
SAI3.ErrorAudioFreq-SAI_A_MasterWithClock=0.0 %
SAI3.FIFOThreshold-SAI_A_MasterWithClock=SAI_FIFOTHRESHOLD_3QF
SAI3.FIFOThreshold-SAI_A_MasterWithClock=SAI_FIFOTHRESHOLD_1QF
SAI3.FSDefinition-SAI_A_MasterWithClock=SAI_FS_CHANNEL_IDENTIFICATION
SAI3.FSOffset-SAI_A_MasterWithClock=SAI_FS_BEFOREFIRSTBIT
SAI3.FSPolarity-SAI_A_MasterWithClock=SAI_FS_ACTIVE_LOW
SAI3.FirstBitOffset-SAI_A_MasterWithClock=0
SAI3.FrameLength-SAI_A_MasterWithClock=32
SAI3.IPParameters=Instance-SAI_A_MasterWithClock,VirtualMode-SAI_A_MasterWithClock,MClockEnable-SAI_A_MasterWithClock,RealAudioFreq-SAI_A_MasterWithClock,ErrorAudioFreq-SAI_A_MasterWithClock,AudioFrequency-SAI_A_MasterWithClock,FIFOThreshold-SAI_A_MasterWithClock,OutputDrive-SAI_A_MasterWithClock,NoDivider-SAI_A_MasterWithClock,FrameLength-SAI_A_MasterWithClock,DataSize-SAI_A_MasterWithClock,TriState-SAI_A_MasterWithClock,SlotNumber-SAI_A_MasterWithClock,VirtualSlotActive-SAI_A_MasterWithClock,SlotActive-SAI_A_MasterWithClock,ClockStrobing-SAI_A_MasterWithClock
SAI3.IPParameters=Instance-SAI_A_MasterWithClock,VirtualMode-SAI_A_MasterWithClock,MClockEnable-SAI_A_MasterWithClock,RealAudioFreq-SAI_A_MasterWithClock,ErrorAudioFreq-SAI_A_MasterWithClock,AudioFrequency-SAI_A_MasterWithClock,FIFOThreshold-SAI_A_MasterWithClock,OutputDrive-SAI_A_MasterWithClock,NoDivider-SAI_A_MasterWithClock,TriState-SAI_A_MasterWithClock,CompandingMode-SAI_A_MasterWithClock,FrameLength-SAI_A_MasterWithClock,DataSize-SAI_A_MasterWithClock,VirtualSlotActive-SAI_A_MasterWithClock,SlotActive-SAI_A_MasterWithClock,SlotNumber-SAI_A_MasterWithClock,ClockStrobing-SAI_A_MasterWithClock,FirstBitOffset-SAI_A_MasterWithClock,VirtualSlotActive0-SAI_A_MasterWithClock,VirtualSlotActive1-SAI_A_MasterWithClock,FSOffset-SAI_A_MasterWithClock,ActiveFrameLength-SAI_A_MasterWithClock,FSDefinition-SAI_A_MasterWithClock,FSPolarity-SAI_A_MasterWithClock,SlotSize-SAI_A_MasterWithClock
SAI3.Instance-SAI_A_MasterWithClock=SAI$Index_Block_A
SAI3.MClockEnable-SAI_A_MasterWithClock=SAI_MASTERCLOCK_ENABLE
SAI3.NoDivider-SAI_A_MasterWithClock=SAI_MASTERDIVIDER_ENABLE
SAI3.OutputDrive-SAI_A_MasterWithClock=SAI_OUTPUTDRIVE_ENABLE
SAI3.RealAudioFreq-SAI_A_MasterWithClock=48.0 KHz
SAI3.SlotActive-SAI_A_MasterWithClock=0x0000FFFF
SAI3.SlotActive-SAI_A_MasterWithClock=0x00000003
SAI3.SlotNumber-SAI_A_MasterWithClock=2
SAI3.SlotSize-SAI_A_MasterWithClock=SAI_SLOTSIZE_16B
SAI3.TriState-SAI_A_MasterWithClock=SAI_OUTPUT_NOTRELEASED
SAI3.VirtualMode-SAI_A_MasterWithClock=VM_MASTER
SAI3.VirtualSlotActive-SAI_A_MasterWithClock=SAI_SLOTACTIVE_ALL
SAI3.VirtualSlotActive-SAI_A_MasterWithClock=SAI_SLOT_USERSETTING
SAI3.VirtualSlotActive0-SAI_A_MasterWithClock=true
SAI3.VirtualSlotActive1-SAI_A_MasterWithClock=true
USART1.IPParameters=VirtualMode-Asynchronous
USART1.VirtualMode-Asynchronous=VM_ASYNC
USB_OTG_FS.IPParameters=VirtualMode
USB_OTG_FS.IPParameters=VirtualMode,dma_enable
USB_OTG_FS.VirtualMode=Device_Only
USB_OTG_FS.dma_enable=DISABLE
VP_RAMECC_VS_D1_1.Mode=RAMECC1_Monitor1
VP_RAMECC_VS_D1_1.Signal=RAMECC_VS_D1_1
VP_RAMECC_VS_D2_1.Mode=RAMECC2_Monitor1
@ -436,6 +462,6 @@ VP_RAMECC_VS_D2_4.Mode=RAMECC2_Monitor4
VP_RAMECC_VS_D2_4.Signal=RAMECC_VS_D2_4
VP_RAMECC_VS_D2_5.Mode=RAMECC2_Monitor5
VP_RAMECC_VS_D2_5.Signal=RAMECC_VS_D2_5
VP_SYS_VS_Systick.Mode=SysTick
VP_SYS_VS_Systick.Signal=SYS_VS_Systick
VP_SYS_VS_tim7.Mode=TIM7
VP_SYS_VS_tim7.Signal=SYS_VS_tim7
board=custom

View File

@ -0,0 +1,14 @@
cmake_minimum_required(VERSION 3.10)
project(tpa6130)
set(TPA6130_SOURCES
"src/tpa6130a2.c"
)
set(TPA6130_INCLUDES
"include"
)
add_library(${PROJECT_NAME} ${TPA6130_SOURCES})
target_include_directories(${PROJECT_NAME} PUBLIC ${TPA6130_INCLUDES})

View File

@ -0,0 +1,32 @@
#ifndef TPA6130A2_H
#define TPA6130A2_H
#include <stdint.h>
typedef enum {
TPA6130_OK,
TPA6130_FAIL,
} tpa6130_ret_t;
typedef enum {
TPA6130_CH_NONE = 0U,
TPA6130_CH_L = 0x80U,
TPA6130_CH_R = 0x40U,
} tpa6130_ch_t;
typedef struct {
tpa6130_ret_t (*read_reg_cb)(void *handle, uint8_t slaveaddr, uint8_t reg, uint8_t *value);
tpa6130_ret_t (*write_reg_cb)(void *handle, uint8_t slaveaddr, uint8_t reg, uint8_t value);
} tpa6130_cb_t;
typedef struct {
void *user_data;
tpa6130_cb_t cb;
} tpa6130_t;
tpa6130_ret_t tpa6130a2_revision(tpa6130_t *tpa, uint8_t *rev);
tpa6130_ret_t tpa6130a2_enable_channel(tpa6130_t *tpa, tpa6130_ch_t ch);
tpa6130_ret_t tpa6130a2_set_volume(tpa6130_t *tpa, uint8_t volume);
tpa6130_ret_t tpa6130a2_set_mute(tpa6130_t *tpa, tpa6130_ch_t ch);
#endif

View File

@ -0,0 +1,102 @@
#include "tpa6130a2.h"
#define TPA_SLAVE_ADDR 0x60
#define TPA_REG_CTRL 0x01
#define TPA_REG_VOL 0x02
#define TPA_REG_OUT_HIZ 0x03
#define TPA_REG_REV 0x04
#define TPA_REG_CTRL_HPEN_L_Pos 7
#define TPA_REG_CTRL_HPEN_L_Msk (1U << TPA_REG_CTRL_HPEN_L_Pos)
#define TPA_REG_CTRL_HPEN_R_Pos 6
#define TPA_REG_CTRL_HPEN_R_Msk (1U << TPA_REG_CTRL_HPEN_R_Pos)
#define TPA_REG_CTRL_HPEN_Msk (TPA_REG_CTRL_HPEN_L_Msk | TPA_REG_CTRL_HPEN_R_Msk)
#define TPA_REG_VOL_MUTE_L_Pos 7
#define TPA_REG_VOL_MUTE_L_Msk (1U << TPA_REG_VOL_MUTE_L_Pos)
#define TPA_REG_VOL_MUTE_R_Pos 6
#define TPA_REG_VOL_MUTE_R_Msk (1U << TPA_REG_VOL_MUTE_R_Pos)
#define TPA_REG_VOL_MUTE_Msk (TPA_REG_VOL_MUTE_L_Msk | TPA_REG_VOL_MUTE_R_Msk)
#define TPA_REG_VOL_VOL_Pos 0
#define TPA_REG_VOL_VOL_Msk (63U << TPA_REG_VOL_VOL_Pos)
#define TPA_REG_REV_VERSION_Pos 0
#define TPA_REG_REV_VERSION_Msk (0x0FU << TPA_REG_REV_VERSION_Pos)
#define TPA_ERROR_CHECK(x) \
if (x != TPA6130_OK) return TPA6130_FAIL
/**
* @brief Get TPA6130 silicon revision. Through datasheet, the only valid
* revision for a production TPA6130A2 is 0010b(2).
*
* @param tpa pointer to tps6130_t structure
* @param rev pointer to the revision number
* @return tpa6130_ret_t TPA6130_OK for success, TPA6130_FAIL for errors.
*/
tpa6130_ret_t tpa6130a2_revision(tpa6130_t *tpa, uint8_t *rev) {
uint8_t rev_reg;
TPA_ERROR_CHECK(tpa->cb.read_reg_cb(tpa->user_data, TPA_SLAVE_ADDR, TPA_REG_REV, &rev_reg));
*rev = rev_reg & TPA_REG_REV_VERSION_Msk;
return TPA6130_OK;
}
/**
* @brief Enable amplifier channel outputs
*
* @param tpa pointer to tps6130_t structure
* @param ch tpa6130_ch_t bitmask, e.g. TPA6130_CH_L for left channel
* @return tpa6130_ret_t TPA6130_OK for success, TPA6130_FAIL for errors.
*/
tpa6130_ret_t tpa6130a2_enable_channel(tpa6130_t *tpa, tpa6130_ch_t ch) {
uint8_t ctrl_reg;
TPA_ERROR_CHECK(tpa->cb.read_reg_cb(tpa->user_data, TPA_SLAVE_ADDR, TPA_REG_CTRL, &ctrl_reg));
ctrl_reg &= ~TPA_REG_CTRL_HPEN_Msk;
ctrl_reg |= ch & TPA_REG_CTRL_HPEN_Msk;
TPA_ERROR_CHECK(tpa->cb.write_reg_cb(tpa->user_data, TPA_SLAVE_ADDR, TPA_REG_CTRL, ctrl_reg));
return TPA6130_OK;
}
/**
* @brief Set amplifier volume.
*
* @param tpa pointer to tps6130_t structure
* @param volume volume to be set, valid range from 0 to 63, invalid bits will be clipped.
* @return tpa6130_ret_t TPA6130_OK for success, TPA6130_FAIL for errors.
*/
tpa6130_ret_t tpa6130a2_set_volume(tpa6130_t *tpa, uint8_t volume) {
uint8_t vol_reg;
TPA_ERROR_CHECK(tpa->cb.read_reg_cb(tpa->user_data, TPA_SLAVE_ADDR, TPA_REG_VOL, &vol_reg));
vol_reg &= ~TPA_REG_VOL_VOL_Msk;
vol_reg |= volume & TPA_REG_VOL_VOL_Msk;
TPA_ERROR_CHECK(tpa->cb.write_reg_cb(tpa->user_data, TPA_SLAVE_ADDR, TPA_REG_VOL, vol_reg));
return TPA6130_OK;
}
/**
* @brief Mute or unmute amplifier
*
* @param tpa pointer to tps6130_t structure
* @param ch tpa6130_ch_t bitmask, e.g. TPA6130_CH_L for left channel, TPA6130_NONE for unmute all channels.
* @return tpa6130_ret_t TPA6130_OK for success, TPA6130_FAIL for errors.
*/
tpa6130_ret_t tpa6130a2_set_mute(tpa6130_t *tpa, tpa6130_ch_t ch) {
uint8_t vol_reg;
TPA_ERROR_CHECK(tpa->cb.read_reg_cb(tpa->user_data, TPA_SLAVE_ADDR, TPA_REG_VOL, &vol_reg));
vol_reg &= ~TPA_REG_VOL_MUTE_Msk;
vol_reg |= ch & TPA_REG_VOL_MUTE_Msk;
TPA_ERROR_CHECK(tpa->cb.write_reg_cb(tpa->user_data, TPA_SLAVE_ADDR, TPA_REG_VOL, vol_reg));
return TPA6130_OK;
}