diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..21606f0 --- /dev/null +++ b/.gitmodules @@ -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 diff --git a/CMakeLists.txt b/CMakeLists.txt index 1813574..e59d118 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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}) diff --git a/Core/Inc/audio/audio_amp.h b/Core/Inc/audio/audio_amp.h new file mode 100644 index 0000000..e5efa20 --- /dev/null +++ b/Core/Inc/audio/audio_amp.h @@ -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 \ No newline at end of file diff --git a/Core/Inc/audio/audio_clocksel.h b/Core/Inc/audio/audio_clocksel.h new file mode 100644 index 0000000..0d119c3 --- /dev/null +++ b/Core/Inc/audio/audio_clocksel.h @@ -0,0 +1,13 @@ +#ifndef AUDIO_CLKSEL_H +#define AUDIO_CLKSEL_H + +#include + +typedef enum { + AUDIO_CLKIN_22M = 0, + AUDIO_CLKIN_24M = 1, +} audio_clock_t; + +uint8_t audio_clock_select(audio_clock_t clock); + +#endif \ No newline at end of file diff --git a/Core/Inc/audio/audio_leds.h b/Core/Inc/audio/audio_leds.h new file mode 100644 index 0000000..e69de29 diff --git a/Core/Inc/azrtos/tx_user.h b/Core/Inc/azrtos/tx_user.h new file mode 100644 index 0000000..e22babf --- /dev/null +++ b/Core/Inc/azrtos/tx_user.h @@ -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 + diff --git a/Core/Inc/azrtos/usbx_dcd/ux_dcd_stm32.h b/Core/Inc/azrtos/usbx_dcd/ux_dcd_stm32.h new file mode 100644 index 0000000..f57605e --- /dev/null +++ b/Core/Inc/azrtos/usbx_dcd/ux_dcd_stm32.h @@ -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 + diff --git a/Core/Inc/azrtos/usbx_dcd/ux_stm32_config.h b/Core/Inc/azrtos/usbx_dcd/ux_stm32_config.h new file mode 100644 index 0000000..f6c1746 --- /dev/null +++ b/Core/Inc/azrtos/usbx_dcd/ux_stm32_config.h @@ -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__ */ diff --git a/Core/Inc/main.h b/Core/Inc/main.h index 0316488..993dfcd 100644 --- a/Core/Inc/main.h +++ b/Core/Inc/main.h @@ -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 */ diff --git a/Core/Inc/stm32h7xx_hal_conf.h b/Core/Inc/stm32h7xx_hal_conf.h index ad6777e..40a1df4 100644 --- a/Core/Inc/stm32h7xx_hal_conf.h +++ b/Core/Inc/stm32h7xx_hal_conf.h @@ -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 */ diff --git a/Core/Inc/stm32h7xx_it.h b/Core/Inc/stm32h7xx_it.h index 3fa1200..6395e82 100644 --- a/Core/Inc/stm32h7xx_it.h +++ b/Core/Inc/stm32h7xx_it.h @@ -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); diff --git a/Core/Inc/usbd_descriptors.h b/Core/Inc/usbd_descriptors.h new file mode 100644 index 0000000..30034da --- /dev/null +++ b/Core/Inc/usbd_descriptors.h @@ -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 */ + 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 \ No newline at end of file diff --git a/Core/Src/audio/audio_amp.c b/Core/Src/audio/audio_amp.c new file mode 100644 index 0000000..39cdacb --- /dev/null +++ b/Core/Src/audio/audio_amp.c @@ -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; +} \ No newline at end of file diff --git a/Core/Src/audio/audio_clocksel.c b/Core/Src/audio/audio_clocksel.c new file mode 100644 index 0000000..f8f012f --- /dev/null +++ b/Core/Src/audio/audio_clocksel.c @@ -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; +} \ No newline at end of file diff --git a/Core/Src/audio/audio_leds.c b/Core/Src/audio/audio_leds.c new file mode 100644 index 0000000..e69de29 diff --git a/Core/Src/audio/impl/tpa6130a2_impl.c b/Core/Src/audio/impl/tpa6130a2_impl.c new file mode 100644 index 0000000..3dd51f5 --- /dev/null +++ b/Core/Src/audio/impl/tpa6130a2_impl.c @@ -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, ®, 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; +} \ No newline at end of file diff --git a/Core/Src/azrtos/usbx_dcd/readme.txt b/Core/Src/azrtos/usbx_dcd/readme.txt new file mode 100644 index 0000000..f2484d5 --- /dev/null +++ b/Core/Src/azrtos/usbx_dcd/readme.txt @@ -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 diff --git a/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_callback.c b/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_callback.c new file mode 100644 index 0000000..e51f528 --- /dev/null +++ b/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_callback.c @@ -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(); + } +} diff --git a/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_endpoint_create.c b/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_endpoint_create.c new file mode 100644 index 0000000..bedf27c --- /dev/null +++ b/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_endpoint_create.c @@ -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); +} + diff --git a/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_endpoint_destroy.c b/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_endpoint_destroy.c new file mode 100644 index 0000000..b9b3a2a --- /dev/null +++ b/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_endpoint_destroy.c @@ -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); +} + diff --git a/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_endpoint_reset.c b/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_endpoint_reset.c new file mode 100644 index 0000000..0d00a38 --- /dev/null +++ b/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_endpoint_reset.c @@ -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); + +} + diff --git a/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_endpoint_stall.c b/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_endpoint_stall.c new file mode 100644 index 0000000..7b53a0c --- /dev/null +++ b/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_endpoint_stall.c @@ -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); +} + diff --git a/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_endpoint_status.c b/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_endpoint_status.c new file mode 100644 index 0000000..08c479e --- /dev/null +++ b/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_endpoint_status.c @@ -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); +} + diff --git a/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_frame_number_get.c b/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_frame_number_get.c new file mode 100644 index 0000000..5b9f8b8 --- /dev/null +++ b/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_frame_number_get.c @@ -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); +} + diff --git a/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_function.c b/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_function.c new file mode 100644 index 0000000..eca9488 --- /dev/null +++ b/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_function.c @@ -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); +} + diff --git a/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_initialize.c b/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_initialize.c new file mode 100644 index 0000000..003ea85 --- /dev/null +++ b/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_initialize.c @@ -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); +} + diff --git a/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_initialize_complete.c b/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_initialize_complete.c new file mode 100644 index 0000000..f675a64 --- /dev/null +++ b/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_initialize_complete.c @@ -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); +} + diff --git a/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_interrupt_handler.c b/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_interrupt_handler.c new file mode 100644 index 0000000..ff98026 --- /dev/null +++ b/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_interrupt_handler.c @@ -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); + +} diff --git a/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_transfer_request.c b/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_transfer_request.c new file mode 100644 index 0000000..8ac43c6 --- /dev/null +++ b/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_transfer_request.c @@ -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); +} + diff --git a/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_uninitialize.c b/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_uninitialize.c new file mode 100644 index 0000000..a6166cf --- /dev/null +++ b/Core/Src/azrtos/usbx_dcd/ux_dcd_stm32_uninitialize.c @@ -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); +} diff --git a/Core/Src/main.c b/Core/Src/main.c index 09f7b3a..fef107a 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -23,6 +23,18 @@ /* USER CODE BEGIN Includes */ #include +#include +#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 */ } /** diff --git a/Core/Src/stm32h7xx_hal_msp.c b/Core/Src/stm32h7xx_hal_msp.c index b1991d4..0eedd61 100644 --- a/Core/Src/stm32h7xx_hal_msp.c +++ b/Core/Src/stm32h7xx_hal_msp.c @@ -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) { diff --git a/Core/Src/stm32h7xx_hal_timebase_tim.c b/Core/Src/stm32h7xx_hal_timebase_tim.c new file mode 100644 index 0000000..395d4a0 --- /dev/null +++ b/Core/Src/stm32h7xx_hal_timebase_tim.c @@ -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); +} + diff --git a/Core/Src/stm32h7xx_it.c b/Core/Src/stm32h7xx_it.c index 073eaa1..5a660f3 100644 --- a/Core/Src/stm32h7xx_it.c +++ b/Core/Src/stm32h7xx_it.c @@ -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. */ diff --git a/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/CMakeLists.txt b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/CMakeLists.txt new file mode 100755 index 0000000..6a8d585 --- /dev/null +++ b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/CMakeLists.txt @@ -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 +) diff --git a/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/example_build/build_threadx.bat b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/example_build/build_threadx.bat new file mode 100644 index 0000000..aa0a36f --- /dev/null +++ b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/example_build/build_threadx.bat @@ -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 diff --git a/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/example_build/build_threadx_sample.bat b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/example_build/build_threadx_sample.bat new file mode 100644 index 0000000..28117ef --- /dev/null +++ b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/example_build/build_threadx_sample.bat @@ -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 + + diff --git a/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/example_build/cortexm7_crt0.s b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/example_build/cortexm7_crt0.s new file mode 100644 index 0000000..d4cb163 --- /dev/null +++ b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/example_build/cortexm7_crt0.s @@ -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 + \ No newline at end of file diff --git a/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/example_build/sample_threadx.c b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/example_build/sample_threadx.c new file mode 100644 index 0000000..597f373 --- /dev/null +++ b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/example_build/sample_threadx.c @@ -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; + } +} diff --git a/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/example_build/sample_threadx.ld b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/example_build/sample_threadx.ld new file mode 100644 index 0000000..28f203f --- /dev/null +++ b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/example_build/sample_threadx.ld @@ -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"); + +} + diff --git a/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/example_build/tx_initialize_low_level.S b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/example_build/tx_initialize_low_level.S new file mode 100644 index 0000000..85e612a --- /dev/null +++ b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/example_build/tx_initialize_low_level.S @@ -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 .... */ + +#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 diff --git a/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/example_build/tx_simulator_startup.s b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/example_build/tx_simulator_startup.s new file mode 100644 index 0000000..cf0db97 --- /dev/null +++ b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/example_build/tx_simulator_startup.s @@ -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 + + + diff --git a/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/inc/tx_port.h b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/inc/tx_port.h new file mode 100644 index 0000000..1c351bb --- /dev/null +++ b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/inc/tx_port.h @@ -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 +#include + +#ifdef __ICCARM__ +#include /* IAR Intrinsics */ +#define __asm__ __asm /* Define to make all inline asm look similar */ +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#include +#endif +#endif /* __ICCARM__ */ + +#ifdef __ghs__ +#include +#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 diff --git a/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/readme_threadx.txt b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/readme_threadx.txt new file mode 100644 index 0000000..d9063d6 --- /dev/null +++ b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/readme_threadx.txt @@ -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 */ + + 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 + diff --git a/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/src/tx_thread_context_restore.S b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/src/tx_thread_context_restore.S new file mode 100644 index 0000000..888d544 --- /dev/null +++ b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/src/tx_thread_context_restore.S @@ -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 +// } diff --git a/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/src/tx_thread_context_save.S b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/src/tx_thread_context_save.S new file mode 100644 index 0000000..6111ffe --- /dev/null +++ b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/src/tx_thread_context_save.S @@ -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 +// } diff --git a/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/src/tx_thread_interrupt_control.S b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/src/tx_thread_interrupt_control.S new file mode 100644 index 0000000..2ea849d --- /dev/null +++ b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/src/tx_thread_interrupt_control.S @@ -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 +// } diff --git a/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/src/tx_thread_interrupt_disable.S b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/src/tx_thread_interrupt_disable.S new file mode 100644 index 0000000..16935d5 --- /dev/null +++ b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/src/tx_thread_interrupt_disable.S @@ -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 +// } diff --git a/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/src/tx_thread_interrupt_restore.S b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/src/tx_thread_interrupt_restore.S new file mode 100644 index 0000000..27f8c5b --- /dev/null +++ b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/src/tx_thread_interrupt_restore.S @@ -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 +// } diff --git a/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/src/tx_thread_schedule.S b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/src/tx_thread_schedule.S new file mode 100644 index 0000000..5b4090c --- /dev/null +++ b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/src/tx_thread_schedule.S @@ -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 diff --git a/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/src/tx_thread_stack_build.S b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/src/tx_thread_stack_build.S new file mode 100644 index 0000000..7c2cb83 --- /dev/null +++ b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/src/tx_thread_stack_build.S @@ -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 +// } diff --git a/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/src/tx_thread_system_return.S b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/src/tx_thread_system_return.S new file mode 100644 index 0000000..307af29 --- /dev/null +++ b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/src/tx_thread_system_return.S @@ -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 +// } diff --git a/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/src/tx_timer_interrupt.S b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/src/tx_timer_interrupt.S new file mode 100644 index 0000000..d0fc692 --- /dev/null +++ b/Middlewares/Third_Party/azrtos/cubemx_port/cortex_m7/gnu/src/tx_timer_interrupt.S @@ -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 diff --git a/Middlewares/Third_Party/azrtos/filex b/Middlewares/Third_Party/azrtos/filex new file mode 160000 index 0000000..3b20363 --- /dev/null +++ b/Middlewares/Third_Party/azrtos/filex @@ -0,0 +1 @@ +Subproject commit 3b203634dce8fc51e77ac67ec28d91d693c2c570 diff --git a/Middlewares/Third_Party/azrtos/netxduo b/Middlewares/Third_Party/azrtos/netxduo new file mode 160000 index 0000000..fafaebe --- /dev/null +++ b/Middlewares/Third_Party/azrtos/netxduo @@ -0,0 +1 @@ +Subproject commit fafaebe513129e0899a832b0899fa9e69187ee06 diff --git a/Middlewares/Third_Party/azrtos/threadx b/Middlewares/Third_Party/azrtos/threadx new file mode 160000 index 0000000..11303a0 --- /dev/null +++ b/Middlewares/Third_Party/azrtos/threadx @@ -0,0 +1 @@ +Subproject commit 11303a0e1bb184c87ef267b582e5272054006edc diff --git a/Middlewares/Third_Party/azrtos/usbx b/Middlewares/Third_Party/azrtos/usbx new file mode 160000 index 0000000..8f56ef4 --- /dev/null +++ b/Middlewares/Third_Party/azrtos/usbx @@ -0,0 +1 @@ +Subproject commit 8f56ef4e4492dd66c2161b7c1534c6f4442852a4 diff --git a/STM32H750VB_DAC_CS4344_A1.ioc b/STM32H750VB_DAC_CS4344_A1.ioc index 7f1af96..a9c64d5 100644 --- a/STM32H750VB_DAC_CS4344_A1.ioc +++ b/STM32H750VB_DAC_CS4344_A1.ioc @@ -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 diff --git a/lib/tpa6130a2/CMakeLists.txt b/lib/tpa6130a2/CMakeLists.txt new file mode 100644 index 0000000..d084851 --- /dev/null +++ b/lib/tpa6130a2/CMakeLists.txt @@ -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}) \ No newline at end of file diff --git a/lib/tpa6130a2/include/tpa6130a2.h b/lib/tpa6130a2/include/tpa6130a2.h new file mode 100644 index 0000000..8802eb1 --- /dev/null +++ b/lib/tpa6130a2/include/tpa6130a2.h @@ -0,0 +1,32 @@ +#ifndef TPA6130A2_H +#define TPA6130A2_H + +#include + +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 \ No newline at end of file diff --git a/lib/tpa6130a2/src/tpa6130a2.c b/lib/tpa6130a2/src/tpa6130a2.c new file mode 100644 index 0000000..aaf5468 --- /dev/null +++ b/lib/tpa6130a2/src/tpa6130a2.c @@ -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; +} \ No newline at end of file