1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

minimal: ss: embedded: RT595S ACM transport

Adds an example for NXP RT595S eval board, using serialized SS over CDC /
ACM USB composite device, one ttyACM for logs and the other for the SSS
link.
This commit is contained in:
Andy Green 2021-10-06 11:43:06 +01:00
parent 99f7e572ca
commit 2761badd0f
112 changed files with 106337 additions and 4 deletions

View file

@ -38,7 +38,7 @@ extern "C" {
#include "lws_config.h"
#ifdef LWS_HAVE_SYS_TYPES_H
#if defined(LWS_HAVE_SYS_TYPES_H) && !defined(LWS_PLAT_BAREMETAL)
#include <sys/types.h>
#endif
@ -145,6 +145,7 @@ typedef int suseconds_t;
#else /* NOT WIN32 */
#include <unistd.h>
#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP)
#include <sys/capability.h>
#endif
@ -209,6 +210,7 @@ typedef int suseconds_t;
#endif /* not shared */
#define LWS_WARN_DEPRECATED __attribute__ ((deprecated))
#undef printf
#define LWS_FORMAT(string_index) __attribute__ ((format(printf, string_index, string_index+1)))
#else /* not GNUC */

View file

@ -527,6 +527,7 @@ typedef struct lws_transport_mux {
uint64_t us_ping_in;
uint64_t us_ping_out;
uint64_t us_unixtime_peer;
uint64_t us_unixtime_peer_loc;
uint64_t mp_time;
uint64_t mp_time1;
enum lwstmc_parser mp_state;

View file

@ -167,7 +167,7 @@ sul_ping_cb(lws_sorted_usec_list_t *sul)
sul_ping_cb, 2 * LWS_US_PER_SEC);
}
#if defined(PICO_SDK_PATH)
#if defined(PICO_SDK_PATH) || defined(LWS_PLAT_BAREMETAL)
#if 0
struct stv {
uint32_t tv_sec;
@ -623,7 +623,8 @@ lws_transport_mux_rx_parse(lws_transport_mux_t *tm,
lwsl_user("%s: got PONGACK: ustime %llu\n",
__func__,
(unsigned long long)tm->mp_time);
tm->us_unixtime_peer = tm->mp_time - get_us_timeofday();
tm->us_unixtime_peer = tm->mp_time;
tm->us_unixtime_peer_loc = (uint64_t)lws_now_usecs();
tm->mp_state = LWSTMCPAR_CMD;
lws_transport_set_link(tm, LWSTM_OPERATIONAL);
lws_sul_cancel(&tm->sul_ping);

View file

@ -280,7 +280,7 @@ lws_sspc_txp_tx(lws_sspc_handle_t *h, size_t metadata_limit)
lws_ser_wu16be(s + 1, (uint16_t)txl);
/* SSSv1: add protocol version byte (initially 1) */
*(s + 3) = (uint8_t)LWS_SSS_CLIENT_PROTOCOL_VERSION;
#if defined(WIN32)
#if defined(WIN32) || defined(LWS_PLAT_BAREMETAL)
lws_ser_wu32be(s + 4, (uint32_t)0);
#else
lws_ser_wu32be(s + 4, (uint32_t)getpid());

View file

@ -0,0 +1,159 @@
cmake_minimum_required(VERSION 3.13)
set(TOOLCHAIN_PATH "/usr/local/mcuxpressoide-11.4.1_6260/ide/plugins/com.nxp.mcuxpresso.tools.linux_11.4.0.202103011116/tools/bin/arm-none-eabi")
set(CMAKE_C_COMPILER "${TOOLCHAIN_PATH}-gcc")
set(CMAKE_CXX_COMPILER "${TOOLCHAIN_PATH}-g++")
#
# We set up the general build flags first so everything built the same.
#
# We build libwebsockets.a, with LWS_ONLY_SSPC and LWS_PLAT_BAREMETAL etc.
#
# Then we build project/ with LWS_SS_USE_SSPC and link him to our libwebsockets.a
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_CROSSCOMPILING 1)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -specs=redlib.specs -fno-common -g3 -mcpu=cortex-m33 -ffunction-sections -fdata-sections -ffreestanding -fno-builtin -fmerge-constants -mfpu=fpv5-sp-d16 -mfloat-abi=hard -mthumb -D__NEWLIB__ -nostdlib -Xlinker --gc-sections" )
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}")
#SET(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN_DIR}/${TARGET_TRIPLET} ${EXTRA_FIND_PATH})
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
project(rt500-hello C)
add_link_options( -ffreestanding -nostdlib -mcpu=cortex-m33 -mfpu=fpv5-sp-d16 -mfloat-abi=hard -mthumb -Xlinker --gc-sections -L ${PROJECT_SOURCE_DIR}/project/Debug -T evkmimxrt595_dev_composite_cdc_vcom_cdc_vcom_bm_Debug.ld )
set(LWS_WITH_SSL 0 CACHE BOOL a)
set(LWS_WITH_TLS 0 CACHE BOOL b)
set(LWS_WITH_SHARED 0 CACHE BOOL c)
set(LWS_PLAT_BAREMETAL 1 CACHE BOOL d)
set(LWS_WITH_NETWORK 0 CACHE BOOL e)
set(LWS_ONLY_SSPC 1 CACHE BOOL f) # remove everything except SSPC pieces from library build
include_directories(${PROJECT_SOURCE_DIR}/project/source)
add_compile_definitions(
__REDLIB__
uid_t=int
gid_t=int
CPU_MIMXRT595SFFOC
CPU_MIMXRT595SFFOC_cm33
_DEBUG=1
BOOT_HEADER_ENABLE=1
CPU_MIMXRT595SEVKA=1
MCUXPRESSO_SDK
CR_INTEGER_PRINTF
PRINTF_FLOAT_ENABLE=0
__MCUXPRESSO
__USE_CMSIS
CPU_MIMXRT595SFAWC_cm33
SERIAL_PORT_TYPE_UART
ssize_t=long
)
# build lws as part of this
add_subdirectory(libwebsockets)
add_executable(${PROJECT_NAME}
project/utilities/fsl_assert.c
project/utilities/fsl_debug_console.c
project/usb/phy/usb_phy.c
project/usb/device/source/lpcip3511/usb_device_lpcip3511.c
project/usb/device/source/usb_device_ch9.c
project/usb/device/source/usb_device_dci.c
project/usb/device/class/cdc/usb_device_cdc_acm.c
project/usb/device/class/usb_device_class.c
project/startup/startup_mimxrt595s_cm33.c
project/source/sspc/binance-ss.c
project/source/sspc/get-ss.c
project/source/sspc/helpers.c
project/source/sspc/main.c
project/source/sspc/system.c
project/source/sspc/transport-serial.c
project/source/composite.c
project/source/semihost_hardfault.c
project/source/usb_device_descriptor.c
project/source/virtual_com.c
project/flash_config/flash_config.c
project/drivers/fsl_cache.c
project/drivers/fsl_clock.c
project/drivers/fsl_common.c
project/drivers/fsl_common_arm.c
project/drivers/fsl_flexcomm.c
project/drivers/fsl_flexspi.c
project/drivers/fsl_gpio.c
project/drivers/fsl_iap.c
project/drivers/fsl_power.c
project/drivers/fsl_reset.c
project/drivers/fsl_usart.c
project/device/system_MIMXRT595S_cm33.c
project/component/uart/fsl_adapter_usart.c
project/component/osa/fsl_os_abstraction_bm.c
project/component/lists/fsl_component_generic_list.c
project/board/board.c
project/board/clock_config.c
project/board/pin_mux.c
)
target_compile_definitions(${PROJECT_NAME} PUBLIC
__REDLIB__
uid_t=int
gid_t=int
STANDALONE=1
CPU_MIMXRT595SFFOC
CPU_MIMXRT595SFFOC_cm33
_DEBUG=1
BOOT_HEADER_ENABLE=1
FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE=1
USB_STACK_BM
CPU_MIMXRT595SEVKA=1
USB_STACK_USE_DEDICATED_RAM=1
FSL_OSA_BM_TASK_ENABLE=0
FSL_OSA_BM_TIMER_CONFIG=0
SDK_DEBUGCONSOLE=1
MCUXPRESSO_SDK
CR_INTEGER_PRINTF
PRINTF_FLOAT_ENABLE=0
__MCUXPRESSO
__USE_CMSIS
CPU_MIMXRT595SFAWC_cm33
SERIAL_PORT_TYPE_UART
LWS_SS_USE_SSPC)
target_include_directories(${PROJECT_NAME} PRIVATE
project/board
project/devices/MIMXRT595S/drivers
project/devices/MIMXRT595S/
project/CMSIS/Core/Include
project/devices/MIMXRT595S/utilities/debug_console
project/component/lists
project/component/serial_manager
project/component/uart
project/component/osa
project/CMSIS
project/device
project/drivers
project/usb/include
project/usb/phy
project/usb/device/source
project/usb/device/class
project/usb/device/class/cdc
project/usb/device/source/lpcip3511
project/usb/device/include
project/source
project/source/sspc
project/utilities
# lws_config.h generated into here
${PROJECT_BINARY_DIR}/libwebsockets
# source includes will do for everything else
libwebsockets/include )
set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".axf")
target_link_libraries(${PROJECT_NAME} websockets)

View file

@ -0,0 +1,275 @@
# SS example for RT595S Eval Board
## Overview
This example uses serialized Secure Streams to run the binance example and a
simple get example stream on the RT595S eval board, via an SS proxy over the
UART / CDC ACM link, with no networking available at the RT595S.
It operates over a composite CDC ACM (ie, serial port) USB device link to a
host PC, one CDC channel is used to show logs from the RT595S and the second is
used to pass serialized SS to the SS proxy to make it work.
It shows live information from binance, and every 5s does a get from
libwebsockets.org and dumps the start and end of each chunk, demonstrating
multiple streams working simultaneously over a single ACM link.
## Setting up
1) Set SW7 boot mode `1: OFF, 2: OFF, 3: ON`
2) Hook J40 Micro USB B to Host PC -- this is the flashing tool connection
and appears as `/dev/ttyACM0`
3) Hook J38 Micro USB B to Host PC -- this is the user USB connection we will
be controlling with this example, after it is flashed and running, it will
appear as `/dev/ttyACM1` and `2`
4) Build lws on the host PC with `-DLWS_WITH_MINIMAL_EXAMPLES=1` and
`-DLWS_WITH_SECURE_STREAMS_PROXY_API=1`, it should produce an example in
the build dir `./bin/lws-minimal-ssproxy-custom-transport-uart`
## Building
First edit the `TOOLCHAIN_PATH` at the top of CMakeLists.txt in this dir to
point to the NXP toolchain
A typical path is like
```
set(TOOLCHAIN_PATH "/usr/local/mcuxpressoide-11.4.1_6260/ide/plugins/com.nxp.mcuxpresso.tools.linux_11.4.0.202103011116/tools/bin/arm-none-eabi")
```
Then build this example in a build dir
```
$ mkdir build <<<=== the subdir build is mandatory
$ cd build
$ cmake .. && make
```
...that builds a tiny libwebsockets.a and produces the `rt500-hello.axf`
selfcontained elf already linked to the library.
## Flashing the RT595S eval board
To flash the board, run the commandline flasher that is part of mcuxpresso IDE,
its path is like this
```
$ /usr/local/mcuxpressoide-11.4.1_6260/ide/plugins/com.nxp.mcuxpresso.tools.bin.linux_11.4.0.202109131312/binaries/crt_emu_cm_redlink
-flash-load-exec rt500-hello.axf \
-vendor=NXP \
-flash-driver=MIMXRT500_SFDP_MXIC_OSPI.cfx \
-p MIMXRT595S \
-x ../project/Debug
```
This will look like
```
Ns: MCUXpresso IDE RedlinkMulti Driver v11.4 (Sep 13 2021 15:09:55 - crt_emu_cm_redlink build 16)
Wc(03). No cache support.
Nc: Found chip XML file in ../project/Debug/MIMXRT595S.xml
Nc: Reconnected to existing LinkServer process.
Nc: Probe Firmware: LPC-LINK2 CMSIS-DAP V5.361 (NXP Semiconductors)
Nc: Serial Number: FRAQBQAR
Nc: VID:PID: 1FC9:0090
Nc: USB Path: /dev/hidraw7
Nc: Using memory from core 0 after searching for a good core
Pc: ( 30) Emulator Connected
Nc: processor is in secure mode
Pc: ( 40) Debug Halt
Pc: ( 50) CPU ID
Nc: debug interface type = CoreSight DP (DAP DP ID 6BA02477) over SWD TAP 0
Nc: processor type = Cortex-M33 (CPU ID 00000D21) on DAP AP 0
Nc: number of h/w breakpoints = 8
Nc: number of flash patches = 0
Nc: number of h/w watchpoints = 4
Nc: Probe(0): Connected&Reset. DpID: 6BA02477. CpuID: 00000D21. Info: <None>
Nc: Debug protocol: SWD. RTCK: Disabled. Vector catch: Disabled.
Ns: Content of CoreSight Debug ROM(s):
Nc: RBASE E00FE000: CID B105100D PID 0000095000 ROM (type 0x1)
Nc: ROM 1 E00FF000: CID B105100D PID 04000BB4C9 ROM (type 0x1)
Nc: ROM 2 E000E000: CID B105900D PID 04000BBD21 CSt ARM ARMv8-M type 0x0 Misc - Undefined
Nc: ROM 2 E0001000: CID B105900D PID 04000BBD21 CSt ARM DWTv2 type 0x0 Misc - Undefined
Nc: ROM 2 E0002000: CID B105900D PID 04000BBD21 CSt ARM FPBv2 type 0x0 Misc - Undefined
Nc: ROM 2 E0000000: CID B105900D PID 04000BBD21 CSt ARM ITMv2 type 0x43 Trace Source - Bus
Nc: ROM 2 E0041000: CID B105900D PID 04002BBD21 CSt ARM ETMv4.0 type 0x13 Trace Source - Core
Nc: ROM 2 E0042000: CID B105900D PID 04000BBD21 CSt ARM CTIv2 type 0x14 Debug Control - Trigger, e.g. ECT
Nc: ROM 1 E0040000: CID B105900D PID 04000BBD21 CSt type 0x11 Trace Sink - TPIU
Nc: NXP: MIMXRT595S
Nc: DAP stride is 1024 bytes (256 words)
Nc: Inspected v.2 External Flash Device on SPI using SFDP JEDEC ID MIMXRT500_SFDP_MXIC_OSPI.cfx
Nc: Image 'iMXRT500_SFDP_MXIC_OSPI Sep 14 2021 15:07:17'
Nc: Opening flash driver MIMXRT500_SFDP_MXIC_OSPI.cfx
Nc: Sending VECTRESET to run flash driver
Nc: Flash variant 'JEDEC_FlexSPI_Device' detected (64MB = 1024*64K at 0x8000000)
Nc: Closing flash driver MIMXRT500_SFDP_MXIC_OSPI.cfx
Nt: Loading 'rt500-hello.axf' ELF 0x08000000 len 0x17F90
Nc: Opening flash driver MIMXRT500_SFDP_MXIC_OSPI.cfx (already resident)
Nc: Sending VECTRESET to run flash driver
Nc: Flash variant 'JEDEC_FlexSPI_Device' detected (64MB = 1024*64K at 0x8000000)
Nc: Sectors written: 2, unchanged: 0, total: 2
Nc: Closing flash driver MIMXRT500_SFDP_MXIC_OSPI.cfx
Nt: Loaded 0x17F90 bytes in 1094ms (about 89kB/s)
Nt: Reset target (system)
Nc: Starting execution using system reset
Nc: processor is in non-secure mode
Nc: state - running or following reset request - re-read of state failed - rc Nn(05). Wire ACK Fault in DAP access
Xw:
```
... the last bit is normal, the cpu is reset and running the flashed code.
## Connecting a logging console
You should be able to open a terminal emulator on the host PC to `/dev/ttyACM1`,
the baud rate and other serial details are ignored, so 115200/8/N/1 is fine.
The log shows the logging of the firmware running on the RT595S, initially
something like
```
17227078: (null): sul_ping_cb: no PONG came
19227106: (null): sul_ping_cb: issuing ping
21227133: (null): sul_ping_cb: no PONG came
23227160: (null): sul_ping_cb: issuing ping
25227186: (null): sul_ping_cb: no PONG came
27227214: (null): sul_ping_cb: issuing ping
29227240: (null): sul_ping_cb: no PONG came
```
since there is no SS proxy for it to link up to yet.
If you run on the host PC from the lws build dir
```
$ ./bin/lws-minimal-ssproxy-custom-transport-uart -i /dev/ttyACM2
```
then after a second or two the RT595 firmware and the SS proxy should link up
over ttyACM2, and start updating the bitcoin information and dumping the GET
every 5s. That looks like this kind of thing
```
155228906: (null): sul_ping_cb: issuing ping
157228932: (null): sul_ping_cb: no PONG came
157633108: lws_sspc_create: txp path txp_inside_sspc -> txpmuxc
157633235: (null): lws_transport_mux_retry_connect
157633286: (null): lws_transport_path_client_dump: lws_transport_mux_retry_connect: MUX: 0x852ec, IN: ops=txp_inside_sspc, priv=0x853f8, ONW: ops=txpmuxc, priv=0x0
157633333: (null): lws_transport_mux_retry_connect: transport not operational
157633375: binance_state: LWSSSCS_UPSTREAM_LINK_RETRY (18), ord 0x0
157633444: lws_sspc_create: txp path txp_inside_sspc -> txpmuxc
157633481: (null): lws_transport_mux_retry_connect
157633530: (null): lws_transport_path_client_dump: lws_transport_mux_retry_connect: MUX: 0x852ec, IN: ops=txp_inside_sspc, priv=0x876d4, ONW: ops=txpmuxc, priv=0x0
157633579: (null): lws_transport_mux_retry_connect: transport not operational
157633616: get_state: LWSSSCS_UPSTREAM_LINK_RETRY (18), ord 0x0
157633685: (null): lws_transport_mux_rx_parse: got PING
157633779: (null): lws_transport_mux_pending: send RESET_TRANSPORT
157633824: (null): lws_transport_mux_pending: issuing PING
157633864: (null): lws_transport_mux_pending: issuing PONG
157633924: (null): lws_transport_path_client_dump: cpath: MUX: 0x0, IN: ops=txpmuxc, priv=0x852ec (IsTM), ONW: ops=txpserial, priv=0x0
157633966: (null): txp_serial_write: writing 27
157634016: (null): lws_transport_mux_rx_parse: PONG payload mismatch 0xab4fba 0x9654d3d
157634180: (null): lws_transport_mux_rx_parse: got PONG
157634213: (null): lws_transport_mux_rx_parse: got PONGACK: ustime 1635076485985673
157634252: (null): lws_transport_set_link: ******* transport mux link is UP
157634305: (null): lws_transport_mux_pending: issuing PONGACK
157634370: (null): lws_transport_path_client_dump: cpath: MUX: 0x0, IN: ops=txpmuxc, priv=0x852ec (IsTM), ONW: ops=txpserial, priv=0x0
157634414: (null): txp_serial_write: writing 9
158633431: (null): lws_transport_mux_retry_connect
158633480: (null): lws_transport_path_client_dump: lws_transport_mux_retry_connect: MUX: 0x852ec, IN: ops=txp_inside_sspc, priv=0x853f8, ONW: ops=txpmuxc, priv=0x0
158633537: (null): lws_transport_mux_retry_connect: added channel
158633618: (null): lws_transport_path_client_dump: cpath: MUX: 0x0, IN: ops=txpmuxc, priv=0x852ec (IsTM), ONW: ops=txpserial, priv=0x0
158633659: (null): txp_serial_write: writing 2
158633689: (null): lws_transport_mux_retry_connect
158633737: (null): lws_transport_path_client_dump: lws_transport_mux_retry_connect: MUX: 0x852ec, IN: ops=txp_inside_sspc, priv=0x876d4, ONW: ops=txpmuxc, priv=0x0
158633788: (null): lws_transport_mux_retry_connect: added channel
158633890: (null): lws_transport_path_client_dump: cpath: MUX: 0x0, IN: ops=txpmuxc, priv=0x852ec (IsTM), ONW: ops=txpserial, priv=0x0
158633931: (null): txp_serial_write: writing 2
158634079: (null): lws_transport_mux_rx_parse: ch 255 fully open
158634112: ltm_ch_opens: 0
158634143: lws_sspc_txp_connect_disposition: CONNECTED (binance), txpmuxc
158634213: (null): lws_transport_mux_write: 19
158634249: (null): txp_serial_write: writing 23
158634292: (null): lws_transport_mux_rx_parse: ch 254 fully open
158634330: ltm_ch_opens: 0
158634358: lws_sspc_txp_connect_disposition: CONNECTED (mintest-lws), txpmuxc
158634456: (null): lws_transport_mux_write: 23
158634484: (null): txp_serial_write: writing 27
158634845: lws_ss_serialize_state_transition: LPCSCLI_WAITING_CREATE_RESULT -> LPCSCLI_LOCAL_CONNECTED
158634896: lws_ss_check_next_state_sspc: (unset) -> LWSSSCS_CREATING
158634933: binance_state: LWSSSCS_CREATING (1), ord 0x0
158635016: lws_sspc_txp_tx: (local_conn) onward connect
158635062: (null): lws_transport_mux_write: 3
158635089: (null): txp_serial_write: writing 7
158635144: lws_ss_check_next_state_sspc: LWSSSCS_CREATING -> LWSSSCS_CONNECTING
158635191: binance_state: LWSSSCS_CONNECTING (6), ord 0x0
158635303: lws_ss_serialize_state_transition: LPCSCLI_WAITING_CREATE_RESULT -> LPCSCLI_LOCAL_CONNECTED
158635345: lws_ss_check_next_state_sspc: (unset) -> LWSSSCS_CREATING
158635381: get_state: LWSSSCS_CREATING (1), ord 0x0
158635467: lws_sspc_txp_tx: (local_conn) onward connect
158635503: (null): lws_transport_mux_write: 3
158635530: (null): txp_serial_write: writing 7
158635816: lws_ss_check_next_state_sspc: LWSSSCS_CREATING -> LWSSSCS_CONNECTING
158635853: get_state: LWSSSCS_CONNECTING (6), ord 0x0
159693591: lws_sspc_deserialize_parse: CONNECTED binance
159693623: lws_ss_serialize_state_transition: LPCSCLI_LOCAL_CONNECTED -> LPCSCLI_OPERATIONAL
159693665: lws_ss_check_next_state_sspc: LWSSSCS_CONNECTING -> LWSSSCS_CONNECTED
159693701: binance_state: LWSSSCS_CONNECTED (5), ord 0x0
160693746: (null): sul_hz_cb: price: min: 6031470¢, max: 6032348¢, avg: 6031713¢, (31 prices/s)
160693801: (null): sul_hz_cb: elatency: min: 136ms, max: 361ms, avg: 206ms, (31 msg/s, 72 KiBytes/s SS RX)
161693748: (null): sul_hz_cb: price: min: 6028681¢, max: 6032500¢, avg: 6030043¢, (30 prices/s)
161693801: (null): sul_hz_cb: elatency: min: 136ms, max: 175ms, avg: 144ms, (30 msg/s, 126 KiBytes/s SS RX)
162693751: (null): sul_hz_cb: price: min: 5968822¢, max: 6029283¢, avg: 6026034¢, (30 prices/s)
162693812: (null): sul_hz_cb: elatency: min: 135ms, max: 173ms, avg: 142ms, (30 msg/s, 123 KiBytes/s SS RX)
162800988: get_rx: RX 5, flags 0x43
162801104: (null): 0000: 7B 22 70 65 65 00 00 00 00 00 00 F4 3C A8 9B AA {"pee.......<...
162801135: (null):
162801221: lws_sspc_deserialize_parse: CONNECTED mintest-lws
162801254: lws_ss_serialize_state_transition: LPCSCLI_LOCAL_CONNECTED -> LPCSCLI_OPERATIONAL
162801297: lws_ss_check_next_state_sspc: LWSSSCS_CONNECTING -> LWSSSCS_CONNECTED
162801335: get_state: LWSSSCS_CONNECTED (5), ord 0x0
162802084: get_rx: RX 1520, flags 0x1
162802194: (null): 0000: 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E 0A <!DOCTYPE html>.
162802226: (null):
162802318: (null): 0000: 3C 6C 69 3E 38 30 20 6D 69 6E 69 6D 61 6C 20 65 <li>80 minimal e
162802352: (null):
162802731: get_rx: RX 1520, flags 0x0
162802840: (null): 0000: 78 61 6D 70 6C 65 73 3A 20 3C 61 20 68 72 65 66 xamples: <a href
162802872: (null):
162802964: (null): 0000: AD 98 3C 2F 74 64 3E 3C 74 64 20 63 6C 61 73 73 ..</td><td class
162802998: (null):
162803403: get_rx: RX 1520, flags 0x0
162803512: (null): 0000: 3D 22 67 22 3E E2 AD 98 3C 2F 74 64 3E 3C 2F 74 ="g">...</td></t
162803544: (null):
162803636: (null): 0000: 77 65 62 73 6F 63 6B 65 74 73 2F 74 72 65 65 2F websockets/tree/
162803670: (null):
162804105: get_rx: RX 1520, flags 0x0
162804215: (null): 0000: 6C 69 62 2F 65 76 65 6E 74 2D 6C 69 62 73 22 20 lib/event-libs"
162804247: (null):
162804339: (null): 0000: 31 36 20 69 62 22 3E 0A 20 20 20 20 20 3C 68 31 16 ib">. <h1
162804373: (null):
162804708: get_rx: RX 1277, flags 0x0
162804818: (null): 0000: 3E 51 41 3C 2F 68 31 3E 0A 20 20 20 20 20 20 4C >QA</h1>. L
162804849: (null):
162804941: (null): 0000: 3C 2F 62 6F 64 79 3E 0A 3C 2F 68 74 6D 6C 3E 0A </body>.</html>.
162804975: (null):
162805084: get_rx: RX 0, flags 0x2
162805120: lws_ss_check_next_state_sspc: LWSSSCS_CONNECTED -> LWSSSCS_QOS_ACK_REMOTE
162805160: get_state: LWSSSCS_QOS_ACK_REMOTE (10), ord 0x0
162805198: lws_ss_serialize_state_transition: LPCSCLI_OPERATIONAL -> LPCSCLI_LOCAL_CONNECTED
162805239: lws_ss_check_next_state_sspc: LWSSSCS_QOS_ACK_REMOTE -> LWSSSCS_DISCONNECTED
162805276: get_state: LWSSSCS_DISCONNECTED (2), ord 0x0
163635428: (null): lws_sspc_request_tx: state 8, conn_req_state 0
163635484: lws_sspc_txp_tx: (local_conn) onward connect
163635527: (null): lws_transport_mux_write: 3
163635555: (null): txp_serial_write: writing 7
163636075: lws_ss_check_next_state_sspc: LWSSSCS_DISCONNECTED -> LWSSSCS_CONNECTING
163636114: get_state: LWSSSCS_CONNECTING (6), ord 0x0
163693754: (null): sul_hz_cb: price: min: 6025722¢, max: 6026388¢, avg: 6026199¢, (31 prices/s)
163693805: (null): sul_hz_cb: elatency: min: 134ms, max: 170ms, avg: 139ms, (31 msg/s, 72 KiBytes/s SS RX)
164693759: (null): sul_hz_cb: price: min: 6025359¢, max: 6026340¢, avg: 6025954¢, (30 prices/s)
164693810: (null): sul_hz_cb: elatency: min: 135ms, max: 143ms, avg: 137ms, (30 msg/s, 93 KiBytes/s SS RX)
...
```

View file

@ -0,0 +1,164 @@
<?xml version="1.0" encoding="UTF-8"?>
<ksdk:examples xmlns:ksdk="http://nxp.com/ksdk/2.0/ksdk_manifest_v3.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://nxp.com/ksdk/2.0/ksdk_manifest_v3.0.xsd manifest.xsd">
<externalDefinitions>
<definition extID="cm33_MIMXRT595S"/>
<definition extID="platform.drivers.common.MIMXRT595S"/>
<definition extID="platform.drivers.clock.MIMXRT595S"/>
<definition extID="platform.drivers.power.MIMXRT595S"/>
<definition extID="platform.drivers.reset.MIMXRT595S"/>
<definition extID="device.MIMXRT595S_CMSIS.MIMXRT595S"/>
<definition extID="utility.debug_console.MIMXRT595S"/>
<definition extID="platform.utilities.assert.MIMXRT595S"/>
<definition extID="component.usart_adapter.MIMXRT595S"/>
<definition extID="platform.drivers.flexspi.MIMXRT595S"/>
<definition extID="platform.drivers.cache_cache64.MIMXRT595S"/>
<definition extID="component.serial_manager.MIMXRT595S"/>
<definition extID="component.lists.MIMXRT595S"/>
<definition extID="component.serial_manager_uart.MIMXRT595S"/>
<definition extID="platform.drivers.flexcomm_usart.MIMXRT595S"/>
<definition extID="platform.drivers.flash_config.MIMXRT595S"/>
<definition extID="device.MIMXRT595S_startup.MIMXRT595S"/>
<definition extID="platform.drivers.flexcomm.MIMXRT595S"/>
<definition extID="platform.drivers.lpc_iopctl.MIMXRT595S"/>
<definition extID="platform.drivers.lpc_gpio.MIMXRT595S"/>
<definition extID="CMSIS_Include_core_cm.MIMXRT595S"/>
<definition extID="platform.utilities.misc_utilities.MIMXRT595S"/>
<definition extID="platform.drivers.iap.MIMXRT595S"/>
<definition extID="iar"/>
<definition extID="mdk"/>
<definition extID="armgcc"/>
<definition extID="mcuxpresso"/>
<definition extID="com.nxp.mcuxpresso"/>
<definition extID="com.crt.advproject.config.exe.debug"/>
<definition extID="com.crt.advproject.config.exe.release"/>
</externalDefinitions>
<example id="evkmimxrt595_hello_world" name="hello_world" device_core="cm33_MIMXRT595S" dependency="platform.drivers.common.MIMXRT595S platform.drivers.clock.MIMXRT595S platform.drivers.power.MIMXRT595S platform.drivers.reset.MIMXRT595S device.MIMXRT595S_CMSIS.MIMXRT595S utility.debug_console.MIMXRT595S platform.utilities.assert.MIMXRT595S component.usart_adapter.MIMXRT595S platform.drivers.flexspi.MIMXRT595S platform.drivers.cache_cache64.MIMXRT595S component.serial_manager.MIMXRT595S component.lists.MIMXRT595S component.serial_manager_uart.MIMXRT595S platform.drivers.flexcomm_usart.MIMXRT595S platform.drivers.flash_config.MIMXRT595S device.MIMXRT595S_startup.MIMXRT595S platform.drivers.flexcomm.MIMXRT595S platform.drivers.lpc_iopctl.MIMXRT595S platform.drivers.lpc_gpio.MIMXRT595S CMSIS_Include_core_cm.MIMXRT595S platform.utilities.misc_utilities.MIMXRT595S platform.drivers.iap.MIMXRT595S" category="demo_apps">
<projects>
<project type="com.crt.advproject.projecttype.exe" nature="org.eclipse.cdt.core.cnature"/>
</projects>
<memory>
<memoryBlock id="QSPI_FLASH_MIMXRT595S" name="QSPI_FLASH" addr="08000000" size="04000000" type="ExtFlash" access="RO"/>
<memoryBlock id="SRAM_MIMXRT595S" name="SRAM" addr="20080000" size="00280000" type="RAM" access="RW"/>
<memoryBlock id="USB_RAM_MIMXRT595S" name="USB_RAM" addr="40140000" size="00004000" type="RAM" access="RW"/>
</memory>
<toolchainSettings>
<toolchainSetting id_refs="com.nxp.mcuxpresso">
<option id="gnu.c.compiler.option.preprocessor.def.symbols" type="stringList">
<value>CPU_MIMXRT595SFFOC_cm33</value>
<value>BOOT_HEADER_ENABLE=1</value>
<value>FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE=1</value>
<value>SERIAL_PORT_TYPE_UART=1</value>
<value>MCUXPRESSO_SDK</value>
</option>
<option id="com.crt.advproject.gas.fpu" type="enum">
<value>com.crt.advproject.gas.fpu.fpv5sp.hard</value>
</option>
<option id="com.crt.advproject.gcc.fpu" type="enum">
<value>com.crt.advproject.gcc.fpu.fpv5sp.hard</value>
</option>
<option id="gnu.c.compiler.option.optimization.flags" type="string">
<value>-fno-common</value>
</option>
<option id="com.crt.advproject.c.misc.dialect" type="enum">
<value>com.crt.advproject.misc.dialect.gnu99</value>
</option>
<option id="gnu.c.compiler.option.misc.other" type="string">
<value>-mcpu=cortex-m33 -c -ffunction-sections -fdata-sections -ffreestanding -fno-builtin</value>
</option>
<option id="gnu.c.compiler.option.warnings.allwarn" type="boolean">
<value>false</value>
</option>
<option id="com.crt.advproject.link.fpu" type="enum">
<value>com.crt.advproject.link.fpu.fpv5sp.hard</value>
</option>
<option id="gnu.c.link.option.nostdlibs" type="boolean">
<value>true</value>
</option>
</toolchainSetting>
</toolchainSettings>
<debug_configurations>
<debug_configuration id_refs="com.crt.advproject.config.exe.debug com.crt.advproject.config.exe.release">
<drivers>
<driver id_refs="QSPI_FLASH_MIMXRT595S">
<driverBinary path="devices/MIMXRT595S/mcuxpresso" project_relative_path="binary" type="binary">
<files mask="MIMXRT500_SFDP_MXIC_OSPI.cfx"/>
</driverBinary>
</driver>
</drivers>
</debug_configuration>
</debug_configurations>
<include_paths>
<include_path path="boards/evkmimxrt595/demo_apps/hello_world" project_relative_path="board" type="c_include"/>
<include_path path="boards/evkmimxrt595/demo_apps/hello_world" project_relative_path="evkmimxrt595/demo_apps/hello_world" type="c_include"/>
</include_paths>
<source path="boards/evkmimxrt595/demo_apps/hello_world/iar" project_relative_path="./" type="workspace" toolchain="iar">
<files mask="hello_world.ewd"/>
<files mask="hello_world.ewp"/>
<files mask="hello_world.eww"/>
</source>
<source path="boards/evkmimxrt595/demo_apps/hello_world/mdk" project_relative_path="./" type="workspace" toolchain="mdk">
<files mask="hello_world.uvoptx"/>
<files mask="hello_world.uvprojx"/>
<files mask="JLinkSettings.ini"/>
<files mask="hello_world.uvmpw"/>
</source>
<source path="boards/evkmimxrt595/demo_apps/hello_world/armgcc" project_relative_path="./" type="workspace" toolchain="armgcc">
<files mask="build_all.bat"/>
<files mask="build_all.sh"/>
<files mask="clean.bat"/>
<files mask="clean.sh"/>
<files mask="CMakeLists.txt"/>
<files mask="flags.cmake"/>
<files mask="config.cmake"/>
<files mask="build_debug.bat"/>
<files mask="build_debug.sh"/>
<files mask="build_release.bat"/>
<files mask="build_release.sh"/>
<files mask="build_flash_debug.bat"/>
<files mask="build_flash_debug.sh"/>
<files mask="build_flash_release.bat"/>
<files mask="build_flash_release.sh"/>
</source>
<source path="boards/evkmimxrt595/demo_apps/hello_world" project_relative_path="source" type="src">
<files mask="hello_world.c"/>
</source>
<source path="boards/evkmimxrt595/demo_apps/hello_world" project_relative_path="board" type="src">
<files mask="pin_mux.c"/>
</source>
<source path="boards/evkmimxrt595/demo_apps/hello_world" project_relative_path="board" type="c_include">
<files mask="pin_mux.h"/>
</source>
<source path="boards/evkmimxrt595/demo_apps/hello_world" project_relative_path="." type="other">
<files mask="hello_world.mex" hidden="true"/>
</source>
<source path="boards/evkmimxrt595/demo_apps/hello_world" project_relative_path="evkmimxrt595/demo_apps/hello_world" type="binary">
<files mask="hello_world.bin" hidden="true"/>
</source>
<source path="boards/evkmimxrt595/demo_apps/hello_world" project_relative_path="board" type="src">
<files mask="board.c"/>
<files mask="clock_config.c"/>
</source>
<source path="boards/evkmimxrt595/demo_apps/hello_world" project_relative_path="board" type="c_include">
<files mask="board.h"/>
<files mask="clock_config.h"/>
</source>
<source path="boards/evkmimxrt595/demo_apps/hello_world" project_relative_path="doc" type="doc" toolchain="iar mdk mcuxpresso armgcc">
<files mask="readme.txt"/>
</source>
<source path="boards/evkmimxrt595/demo_apps/hello_world/iar" project_relative_path="MIMXRT595S/iar" type="linker" toolchain="iar">
<files mask="MIMXRT595Sxxxx_cm33_ram.icf"/>
<files mask="MIMXRT595Sxxxx_cm33_flash.icf"/>
</source>
<source path="boards/evkmimxrt595/demo_apps/hello_world/mdk" project_relative_path="MIMXRT595S/arm" type="linker" toolchain="mdk">
<files mask="MIMXRT595Sxxxx_cm33_ram.scf"/>
<files mask="MIMXRT595Sxxxx_cm33_flash.scf"/>
</source>
<source path="boards/evkmimxrt595/demo_apps/hello_world/armgcc" project_relative_path="MIMXRT595S/gcc" type="linker" toolchain="armgcc">
<files mask="MIMXRT595Sxxxx_cm33_ram.ld"/>
<files mask="MIMXRT595Sxxxx_cm33_flash.ld"/>
</source>
<source path="boards/evkmimxrt595/demo_apps/hello_world/mdk" project_relative_path="generator/templates/mdk/app_evkmimxrt595" type="configuration" toolchain="mdk">
<files mask="flashdebug.ini"/>
</source>
</example>
</ksdk:examples>

View file

@ -0,0 +1 @@
../../../..

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<configuration id="com.crt.advproject.config.exe.debug.1881597443" name="Debug">
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuildCommandParser" id="com.crt.advproject.GCCBuildCommandParser" keep-relative-paths="false" name="MCU GCC Build Output Parser" parameter="(arm-none-eabi-gcc)|(arm-none-eabi-[gc]\+\+)|(gcc)|([gc]\+\+)|(clang)" prefer-non-shared="true"/>
<provider class="com.crt.advproject.specs.MCUGCCBuiltinSpecsDetector" console="false" env-hash="153932990861307738" id="com.crt.advproject.GCCBuildSpecCompilerParser" keep-relative-paths="false" name="MCU GCC Built-in Compiler Parser" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
</extension>
</configuration>
<configuration id="com.crt.advproject.config.exe.release.930801483" name="Release">
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider copy-of="extension" id="com.crt.advproject.GCCBuildCommandParser"/>
<provider class="com.crt.advproject.specs.MCUGCCBuiltinSpecsDetector" console="false" env-hash="195095928804160250" id="com.crt.advproject.GCCBuildSpecCompilerParser" keep-relative-paths="false" name="MCU GCC Built-in Compiler Parser" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
</extension>
</configuration>
</project>

View file

@ -0,0 +1,894 @@
/**************************************************************************//**
* @file cmsis_armcc.h
* @brief CMSIS compiler ARMCC (Arm Compiler 5) header file
* @version V5.1.0
* @date 08. May 2019
******************************************************************************/
/*
* Copyright (c) 2009-2019 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __CMSIS_ARMCC_H
#define __CMSIS_ARMCC_H
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)
#error "Please use Arm Compiler Toolchain V4.0.677 or later!"
#endif
/* CMSIS compiler control architecture macros */
#if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \
(defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) )
#define __ARM_ARCH_6M__ 1
#endif
#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1))
#define __ARM_ARCH_7M__ 1
#endif
#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1))
#define __ARM_ARCH_7EM__ 1
#endif
/* __ARM_ARCH_8M_BASE__ not applicable */
/* __ARM_ARCH_8M_MAIN__ not applicable */
/* CMSIS compiler control DSP macros */
#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
#define __ARM_FEATURE_DSP 1
#endif
/* CMSIS compiler specific defines */
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE __inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static __inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE static __forceinline
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __declspec(noreturn)
#endif
#ifndef __USED
#define __USED __attribute__((used))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __PACKED
#define __PACKED __attribute__((packed))
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT __packed struct
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION __packed union
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
#define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x)))
#endif
#ifndef __UNALIGNED_UINT16_WRITE
#define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
#define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr)))
#endif
#ifndef __UNALIGNED_UINT32_WRITE
#define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
#define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr)))
#endif
#ifndef __ALIGNED
#define __ALIGNED(x) __attribute__((aligned(x)))
#endif
#ifndef __RESTRICT
#define __RESTRICT __restrict
#endif
#ifndef __COMPILER_BARRIER
#define __COMPILER_BARRIER() __memory_changed()
#endif
/* ######################### Startup and Lowlevel Init ######################## */
#ifndef __PROGRAM_START
#define __PROGRAM_START __main
#endif
#ifndef __INITIAL_SP
#define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit
#endif
#ifndef __STACK_LIMIT
#define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base
#endif
#ifndef __VECTOR_TABLE
#define __VECTOR_TABLE __Vectors
#endif
#ifndef __VECTOR_TABLE_ATTRIBUTE
#define __VECTOR_TABLE_ATTRIBUTE __attribute((used, section("RESET")))
#endif
/* ########################### Core Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{
*/
/**
\brief Enable IRQ Interrupts
\details Enables IRQ interrupts by clearing the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
/* intrinsic void __enable_irq(); */
/**
\brief Disable IRQ Interrupts
\details Disables IRQ interrupts by setting the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
/* intrinsic void __disable_irq(); */
/**
\brief Get Control Register
\details Returns the content of the Control Register.
\return Control Register value
*/
__STATIC_INLINE uint32_t __get_CONTROL(void)
{
register uint32_t __regControl __ASM("control");
return(__regControl);
}
/**
\brief Set Control Register
\details Writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__STATIC_INLINE void __set_CONTROL(uint32_t control)
{
register uint32_t __regControl __ASM("control");
__regControl = control;
}
/**
\brief Get IPSR Register
\details Returns the content of the IPSR Register.
\return IPSR Register value
*/
__STATIC_INLINE uint32_t __get_IPSR(void)
{
register uint32_t __regIPSR __ASM("ipsr");
return(__regIPSR);
}
/**
\brief Get APSR Register
\details Returns the content of the APSR Register.
\return APSR Register value
*/
__STATIC_INLINE uint32_t __get_APSR(void)
{
register uint32_t __regAPSR __ASM("apsr");
return(__regAPSR);
}
/**
\brief Get xPSR Register
\details Returns the content of the xPSR Register.
\return xPSR Register value
*/
__STATIC_INLINE uint32_t __get_xPSR(void)
{
register uint32_t __regXPSR __ASM("xpsr");
return(__regXPSR);
}
/**
\brief Get Process Stack Pointer
\details Returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t __regProcessStackPointer __ASM("psp");
return(__regProcessStackPointer);
}
/**
\brief Set Process Stack Pointer
\details Assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
register uint32_t __regProcessStackPointer __ASM("psp");
__regProcessStackPointer = topOfProcStack;
}
/**
\brief Get Main Stack Pointer
\details Returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t __regMainStackPointer __ASM("msp");
return(__regMainStackPointer);
}
/**
\brief Set Main Stack Pointer
\details Assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
register uint32_t __regMainStackPointer __ASM("msp");
__regMainStackPointer = topOfMainStack;
}
/**
\brief Get Priority Mask
\details Returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__STATIC_INLINE uint32_t __get_PRIMASK(void)
{
register uint32_t __regPriMask __ASM("primask");
return(__regPriMask);
}
/**
\brief Set Priority Mask
\details Assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
register uint32_t __regPriMask __ASM("primask");
__regPriMask = (priMask);
}
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
/**
\brief Enable FIQ
\details Enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __enable_fault_irq __enable_fiq
/**
\brief Disable FIQ
\details Disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __disable_fault_irq __disable_fiq
/**
\brief Get Base Priority
\details Returns the current value of the Base Priority register.
\return Base Priority register value
*/
__STATIC_INLINE uint32_t __get_BASEPRI(void)
{
register uint32_t __regBasePri __ASM("basepri");
return(__regBasePri);
}
/**
\brief Set Base Priority
\details Assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
{
register uint32_t __regBasePri __ASM("basepri");
__regBasePri = (basePri & 0xFFU);
}
/**
\brief Set Base Priority with condition
\details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
or the new value increases the BASEPRI priority level.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
{
register uint32_t __regBasePriMax __ASM("basepri_max");
__regBasePriMax = (basePri & 0xFFU);
}
/**
\brief Get Fault Mask
\details Returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
register uint32_t __regFaultMask __ASM("faultmask");
return(__regFaultMask);
}
/**
\brief Set Fault Mask
\details Assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
register uint32_t __regFaultMask __ASM("faultmask");
__regFaultMask = (faultMask & (uint32_t)1U);
}
#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
/**
\brief Get FPSCR
\details Returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__STATIC_INLINE uint32_t __get_FPSCR(void)
{
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
register uint32_t __regfpscr __ASM("fpscr");
return(__regfpscr);
#else
return(0U);
#endif
}
/**
\brief Set FPSCR
\details Assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
{
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
register uint32_t __regfpscr __ASM("fpscr");
__regfpscr = (fpscr);
#else
(void)fpscr;
#endif
}
/*@} end of CMSIS_Core_RegAccFunctions */
/* ########################## Core Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions
@{
*/
/**
\brief No Operation
\details No Operation does nothing. This instruction can be used for code alignment purposes.
*/
#define __NOP __nop
/**
\brief Wait For Interrupt
\details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
*/
#define __WFI __wfi
/**
\brief Wait For Event
\details Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
#define __WFE __wfe
/**
\brief Send Event
\details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
#define __SEV __sev
/**
\brief Instruction Synchronization Barrier
\details Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or memory,
after the instruction has been completed.
*/
#define __ISB() do {\
__schedule_barrier();\
__isb(0xF);\
__schedule_barrier();\
} while (0U)
/**
\brief Data Synchronization Barrier
\details Acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
#define __DSB() do {\
__schedule_barrier();\
__dsb(0xF);\
__schedule_barrier();\
} while (0U)
/**
\brief Data Memory Barrier
\details Ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
#define __DMB() do {\
__schedule_barrier();\
__dmb(0xF);\
__schedule_barrier();\
} while (0U)
/**
\brief Reverse byte order (32 bit)
\details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412.
\param [in] value Value to reverse
\return Reversed value
*/
#define __REV __rev
/**
\brief Reverse byte order (16 bit)
\details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
#endif
/**
\brief Reverse byte order (16 bit)
\details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value)
{
revsh r0, r0
bx lr
}
#endif
/**
\brief Rotate Right in unsigned value (32 bit)
\details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] op1 Value to rotate
\param [in] op2 Number of Bits to rotate
\return Rotated value
*/
#define __ROR __ror
/**
\brief Breakpoint
\details Causes the processor to enter Debug state.
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
\param [in] value is ignored by the processor.
If required, a debugger can use it to store additional information about the breakpoint.
*/
#define __BKPT(value) __breakpoint(value)
/**
\brief Reverse bit order of value
\details Reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
#define __RBIT __rbit
#else
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
{
uint32_t result;
uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */
result = value; /* r will be reversed bits of v; first get LSB of v */
for (value >>= 1U; value != 0U; value >>= 1U)
{
result <<= 1U;
result |= value & 1U;
s--;
}
result <<= s; /* shift when v's highest bits are zero */
return result;
}
#endif
/**
\brief Count leading zeros
\details Counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
#define __CLZ __clz
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
/**
\brief LDR Exclusive (8 bit)
\details Executes a exclusive LDR instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
#else
#define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief LDR Exclusive (16 bit)
\details Executes a exclusive LDR instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
#else
#define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief LDR Exclusive (32 bit)
\details Executes a exclusive LDR instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
#else
#define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief STR Exclusive (8 bit)
\details Executes a exclusive STR instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXB(value, ptr) __strex(value, ptr)
#else
#define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief STR Exclusive (16 bit)
\details Executes a exclusive STR instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXH(value, ptr) __strex(value, ptr)
#else
#define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief STR Exclusive (32 bit)
\details Executes a exclusive STR instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXW(value, ptr) __strex(value, ptr)
#else
#define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief Remove the exclusive lock
\details Removes the exclusive lock which is created by LDREX.
*/
#define __CLREX __clrex
/**
\brief Signed Saturate
\details Saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT __ssat
/**
\brief Unsigned Saturate
\details Saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT __usat
/**
\brief Rotate Right with Extend (32 bit)
\details Moves each bit of a bitstring right by one bit.
The carry input is shifted in at the left end of the bitstring.
\param [in] value Value to rotate
\return Rotated value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
{
rrx r0, r0
bx lr
}
#endif
/**
\brief LDRT Unprivileged (8 bit)
\details Executes a Unprivileged LDRT instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr))
/**
\brief LDRT Unprivileged (16 bit)
\details Executes a Unprivileged LDRT instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr))
/**
\brief LDRT Unprivileged (32 bit)
\details Executes a Unprivileged LDRT instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr))
/**
\brief STRT Unprivileged (8 bit)
\details Executes a Unprivileged STRT instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRBT(value, ptr) __strt(value, ptr)
/**
\brief STRT Unprivileged (16 bit)
\details Executes a Unprivileged STRT instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRHT(value, ptr) __strt(value, ptr)
/**
\brief STRT Unprivileged (32 bit)
\details Executes a Unprivileged STRT instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRT(value, ptr) __strt(value, ptr)
#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
/**
\brief Signed Saturate
\details Saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat)
{
if ((sat >= 1U) && (sat <= 32U))
{
const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U);
const int32_t min = -1 - max ;
if (val > max)
{
return max;
}
else if (val < min)
{
return min;
}
}
return val;
}
/**
\brief Unsigned Saturate
\details Saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat)
{
if (sat <= 31U)
{
const uint32_t max = ((1U << sat) - 1U);
if (val > (int32_t)max)
{
return max;
}
else if (val < 0)
{
return 0U;
}
}
return (uint32_t)val;
}
#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
/* ################### Compiler specific Intrinsics ########################### */
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
Access to dedicated SIMD instructions
@{
*/
#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
#define __SADD8 __sadd8
#define __QADD8 __qadd8
#define __SHADD8 __shadd8
#define __UADD8 __uadd8
#define __UQADD8 __uqadd8
#define __UHADD8 __uhadd8
#define __SSUB8 __ssub8
#define __QSUB8 __qsub8
#define __SHSUB8 __shsub8
#define __USUB8 __usub8
#define __UQSUB8 __uqsub8
#define __UHSUB8 __uhsub8
#define __SADD16 __sadd16
#define __QADD16 __qadd16
#define __SHADD16 __shadd16
#define __UADD16 __uadd16
#define __UQADD16 __uqadd16
#define __UHADD16 __uhadd16
#define __SSUB16 __ssub16
#define __QSUB16 __qsub16
#define __SHSUB16 __shsub16
#define __USUB16 __usub16
#define __UQSUB16 __uqsub16
#define __UHSUB16 __uhsub16
#define __SASX __sasx
#define __QASX __qasx
#define __SHASX __shasx
#define __UASX __uasx
#define __UQASX __uqasx
#define __UHASX __uhasx
#define __SSAX __ssax
#define __QSAX __qsax
#define __SHSAX __shsax
#define __USAX __usax
#define __UQSAX __uqsax
#define __UHSAX __uhsax
#define __USAD8 __usad8
#define __USADA8 __usada8
#define __SSAT16 __ssat16
#define __USAT16 __usat16
#define __UXTB16 __uxtb16
#define __UXTAB16 __uxtab16
#define __SXTB16 __sxtb16
#define __SXTAB16 __sxtab16
#define __SMUAD __smuad
#define __SMUADX __smuadx
#define __SMLAD __smlad
#define __SMLADX __smladx
#define __SMLALD __smlald
#define __SMLALDX __smlaldx
#define __SMUSD __smusd
#define __SMUSDX __smusdx
#define __SMLSD __smlsd
#define __SMLSDX __smlsdx
#define __SMLSLD __smlsld
#define __SMLSLDX __smlsldx
#define __SEL __sel
#define __QADD __qadd
#define __QSUB __qsub
#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
((int64_t)(ARG3) << 32U) ) >> 32U))
#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
/*@} end of group CMSIS_SIMD_intrinsics */
#endif /* __CMSIS_ARMCC_H */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,283 @@
/**************************************************************************//**
* @file cmsis_compiler.h
* @brief CMSIS compiler generic header file
* @version V5.1.0
* @date 09. October 2018
******************************************************************************/
/*
* Copyright (c) 2009-2018 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __CMSIS_COMPILER_H
#define __CMSIS_COMPILER_H
#include <stdint.h>
/*
* Arm Compiler 4/5
*/
#if defined ( __CC_ARM )
#include "cmsis_armcc.h"
/*
* Arm Compiler 6.6 LTM (armclang)
*/
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) && (__ARMCC_VERSION < 6100100)
#include "cmsis_armclang_ltm.h"
/*
* Arm Compiler above 6.10.1 (armclang)
*/
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100)
#include "cmsis_armclang.h"
/*
* GNU Compiler
*/
#elif defined ( __GNUC__ )
#include "cmsis_gcc.h"
/*
* IAR Compiler
*/
#elif defined ( __ICCARM__ )
#include <cmsis_iccarm.h>
/*
* TI Arm Compiler
*/
#elif defined ( __TI_ARM__ )
#include <cmsis_ccs.h>
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __STATIC_INLINE
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __attribute__((noreturn))
#endif
#ifndef __USED
#define __USED __attribute__((used))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __PACKED
#define __PACKED __attribute__((packed))
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT struct __attribute__((packed))
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION union __attribute__((packed))
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
struct __attribute__((packed)) T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#define __ALIGNED(x) __attribute__((aligned(x)))
#endif
#ifndef __RESTRICT
#define __RESTRICT __restrict
#endif
#ifndef __COMPILER_BARRIER
#warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
#define __COMPILER_BARRIER() (void)0
#endif
/*
* TASKING Compiler
*/
#elif defined ( __TASKING__ )
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __STATIC_INLINE
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __attribute__((noreturn))
#endif
#ifndef __USED
#define __USED __attribute__((used))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __PACKED
#define __PACKED __packed__
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT struct __packed__
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION union __packed__
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
struct __packed__ T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#define __ALIGNED(x) __align(x)
#endif
#ifndef __RESTRICT
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
#define __RESTRICT
#endif
#ifndef __COMPILER_BARRIER
#warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
#define __COMPILER_BARRIER() (void)0
#endif
/*
* COSMIC Compiler
*/
#elif defined ( __CSMC__ )
#include <cmsis_csm.h>
#ifndef __ASM
#define __ASM _asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __STATIC_INLINE
#endif
#ifndef __NO_RETURN
// NO RETURN is automatically detected hence no warning here
#define __NO_RETURN
#endif
#ifndef __USED
#warning No compiler specific solution for __USED. __USED is ignored.
#define __USED
#endif
#ifndef __WEAK
#define __WEAK __weak
#endif
#ifndef __PACKED
#define __PACKED @packed
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT @packed struct
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION @packed union
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
@packed struct T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored.
#define __ALIGNED(x)
#endif
#ifndef __RESTRICT
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
#define __RESTRICT
#endif
#ifndef __COMPILER_BARRIER
#warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
#define __COMPILER_BARRIER() (void)0
#endif
#else
#error Unknown compiler.
#endif
#endif /* __CMSIS_COMPILER_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,964 @@
/**************************************************************************//**
* @file cmsis_iccarm.h
* @brief CMSIS compiler ICCARM (IAR Compiler for Arm) header file
* @version V5.1.0
* @date 08. May 2019
******************************************************************************/
//------------------------------------------------------------------------------
//
// Copyright (c) 2017-2019 IAR Systems
// Copyright (c) 2017-2019 Arm Limited. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License")
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//------------------------------------------------------------------------------
#ifndef __CMSIS_ICCARM_H__
#define __CMSIS_ICCARM_H__
#ifndef __ICCARM__
#error This file should only be compiled by ICCARM
#endif
#pragma system_include
#define __IAR_FT _Pragma("inline=forced") __intrinsic
#if (__VER__ >= 8000000)
#define __ICCARM_V8 1
#else
#define __ICCARM_V8 0
#endif
#ifndef __ALIGNED
#if __ICCARM_V8
#define __ALIGNED(x) __attribute__((aligned(x)))
#elif (__VER__ >= 7080000)
/* Needs IAR language extensions */
#define __ALIGNED(x) __attribute__((aligned(x)))
#else
#warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored.
#define __ALIGNED(x)
#endif
#endif
/* Define compiler macros for CPU architecture, used in CMSIS 5.
*/
#if __ARM_ARCH_6M__ || __ARM_ARCH_7M__ || __ARM_ARCH_7EM__ || __ARM_ARCH_8M_BASE__ || __ARM_ARCH_8M_MAIN__
/* Macros already defined */
#else
#if defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__)
#define __ARM_ARCH_8M_MAIN__ 1
#elif defined(__ARM8M_BASELINE__)
#define __ARM_ARCH_8M_BASE__ 1
#elif defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'M'
#if __ARM_ARCH == 6
#define __ARM_ARCH_6M__ 1
#elif __ARM_ARCH == 7
#if __ARM_FEATURE_DSP
#define __ARM_ARCH_7EM__ 1
#else
#define __ARM_ARCH_7M__ 1
#endif
#endif /* __ARM_ARCH */
#endif /* __ARM_ARCH_PROFILE == 'M' */
#endif
/* Alternativ core deduction for older ICCARM's */
#if !defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_7M__) && !defined(__ARM_ARCH_7EM__) && \
!defined(__ARM_ARCH_8M_BASE__) && !defined(__ARM_ARCH_8M_MAIN__)
#if defined(__ARM6M__) && (__CORE__ == __ARM6M__)
#define __ARM_ARCH_6M__ 1
#elif defined(__ARM7M__) && (__CORE__ == __ARM7M__)
#define __ARM_ARCH_7M__ 1
#elif defined(__ARM7EM__) && (__CORE__ == __ARM7EM__)
#define __ARM_ARCH_7EM__ 1
#elif defined(__ARM8M_BASELINE__) && (__CORE == __ARM8M_BASELINE__)
#define __ARM_ARCH_8M_BASE__ 1
#elif defined(__ARM8M_MAINLINE__) && (__CORE == __ARM8M_MAINLINE__)
#define __ARM_ARCH_8M_MAIN__ 1
#elif defined(__ARM8EM_MAINLINE__) && (__CORE == __ARM8EM_MAINLINE__)
#define __ARM_ARCH_8M_MAIN__ 1
#else
#error "Unknown target."
#endif
#endif
#if defined(__ARM_ARCH_6M__) && __ARM_ARCH_6M__==1
#define __IAR_M0_FAMILY 1
#elif defined(__ARM_ARCH_8M_BASE__) && __ARM_ARCH_8M_BASE__==1
#define __IAR_M0_FAMILY 1
#else
#define __IAR_M0_FAMILY 0
#endif
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __COMPILER_BARRIER
#define __COMPILER_BARRIER() __ASM volatile("":::"memory")
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __NO_RETURN
#if __ICCARM_V8
#define __NO_RETURN __attribute__((__noreturn__))
#else
#define __NO_RETURN _Pragma("object_attribute=__noreturn")
#endif
#endif
#ifndef __PACKED
#if __ICCARM_V8
#define __PACKED __attribute__((packed, aligned(1)))
#else
/* Needs IAR language extensions */
#define __PACKED __packed
#endif
#endif
#ifndef __PACKED_STRUCT
#if __ICCARM_V8
#define __PACKED_STRUCT struct __attribute__((packed, aligned(1)))
#else
/* Needs IAR language extensions */
#define __PACKED_STRUCT __packed struct
#endif
#endif
#ifndef __PACKED_UNION
#if __ICCARM_V8
#define __PACKED_UNION union __attribute__((packed, aligned(1)))
#else
/* Needs IAR language extensions */
#define __PACKED_UNION __packed union
#endif
#endif
#ifndef __RESTRICT
#if __ICCARM_V8
#define __RESTRICT __restrict
#else
/* Needs IAR language extensions */
#define __RESTRICT restrict
#endif
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __FORCEINLINE
#define __FORCEINLINE _Pragma("inline=forced")
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __FORCEINLINE __STATIC_INLINE
#endif
#ifndef __UNALIGNED_UINT16_READ
#pragma language=save
#pragma language=extended
__IAR_FT uint16_t __iar_uint16_read(void const *ptr)
{
return *(__packed uint16_t*)(ptr);
}
#pragma language=restore
#define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
#pragma language=save
#pragma language=extended
__IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val)
{
*(__packed uint16_t*)(ptr) = val;;
}
#pragma language=restore
#define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL)
#endif
#ifndef __UNALIGNED_UINT32_READ
#pragma language=save
#pragma language=extended
__IAR_FT uint32_t __iar_uint32_read(void const *ptr)
{
return *(__packed uint32_t*)(ptr);
}
#pragma language=restore
#define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
#pragma language=save
#pragma language=extended
__IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val)
{
*(__packed uint32_t*)(ptr) = val;;
}
#pragma language=restore
#define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL)
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
#pragma language=save
#pragma language=extended
__packed struct __iar_u32 { uint32_t v; };
#pragma language=restore
#define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v)
#endif
#ifndef __USED
#if __ICCARM_V8
#define __USED __attribute__((used))
#else
#define __USED _Pragma("__root")
#endif
#endif
#ifndef __WEAK
#if __ICCARM_V8
#define __WEAK __attribute__((weak))
#else
#define __WEAK _Pragma("__weak")
#endif
#endif
#ifndef __PROGRAM_START
#define __PROGRAM_START __iar_program_start
#endif
#ifndef __INITIAL_SP
#define __INITIAL_SP CSTACK$$Limit
#endif
#ifndef __STACK_LIMIT
#define __STACK_LIMIT CSTACK$$Base
#endif
#ifndef __VECTOR_TABLE
#define __VECTOR_TABLE __vector_table
#endif
#ifndef __VECTOR_TABLE_ATTRIBUTE
#define __VECTOR_TABLE_ATTRIBUTE @".intvec"
#endif
#ifndef __ICCARM_INTRINSICS_VERSION__
#define __ICCARM_INTRINSICS_VERSION__ 0
#endif
#if __ICCARM_INTRINSICS_VERSION__ == 2
#if defined(__CLZ)
#undef __CLZ
#endif
#if defined(__REVSH)
#undef __REVSH
#endif
#if defined(__RBIT)
#undef __RBIT
#endif
#if defined(__SSAT)
#undef __SSAT
#endif
#if defined(__USAT)
#undef __USAT
#endif
#include "iccarm_builtin.h"
#define __disable_fault_irq __iar_builtin_disable_fiq
#define __disable_irq __iar_builtin_disable_interrupt
#define __enable_fault_irq __iar_builtin_enable_fiq
#define __enable_irq __iar_builtin_enable_interrupt
#define __arm_rsr __iar_builtin_rsr
#define __arm_wsr __iar_builtin_wsr
#define __get_APSR() (__arm_rsr("APSR"))
#define __get_BASEPRI() (__arm_rsr("BASEPRI"))
#define __get_CONTROL() (__arm_rsr("CONTROL"))
#define __get_FAULTMASK() (__arm_rsr("FAULTMASK"))
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
#define __get_FPSCR() (__arm_rsr("FPSCR"))
#define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", (VALUE)))
#else
#define __get_FPSCR() ( 0 )
#define __set_FPSCR(VALUE) ((void)VALUE)
#endif
#define __get_IPSR() (__arm_rsr("IPSR"))
#define __get_MSP() (__arm_rsr("MSP"))
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure MSPLIM is RAZ/WI
#define __get_MSPLIM() (0U)
#else
#define __get_MSPLIM() (__arm_rsr("MSPLIM"))
#endif
#define __get_PRIMASK() (__arm_rsr("PRIMASK"))
#define __get_PSP() (__arm_rsr("PSP"))
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure PSPLIM is RAZ/WI
#define __get_PSPLIM() (0U)
#else
#define __get_PSPLIM() (__arm_rsr("PSPLIM"))
#endif
#define __get_xPSR() (__arm_rsr("xPSR"))
#define __set_BASEPRI(VALUE) (__arm_wsr("BASEPRI", (VALUE)))
#define __set_BASEPRI_MAX(VALUE) (__arm_wsr("BASEPRI_MAX", (VALUE)))
#define __set_CONTROL(VALUE) (__arm_wsr("CONTROL", (VALUE)))
#define __set_FAULTMASK(VALUE) (__arm_wsr("FAULTMASK", (VALUE)))
#define __set_MSP(VALUE) (__arm_wsr("MSP", (VALUE)))
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure MSPLIM is RAZ/WI
#define __set_MSPLIM(VALUE) ((void)(VALUE))
#else
#define __set_MSPLIM(VALUE) (__arm_wsr("MSPLIM", (VALUE)))
#endif
#define __set_PRIMASK(VALUE) (__arm_wsr("PRIMASK", (VALUE)))
#define __set_PSP(VALUE) (__arm_wsr("PSP", (VALUE)))
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure PSPLIM is RAZ/WI
#define __set_PSPLIM(VALUE) ((void)(VALUE))
#else
#define __set_PSPLIM(VALUE) (__arm_wsr("PSPLIM", (VALUE)))
#endif
#define __TZ_get_CONTROL_NS() (__arm_rsr("CONTROL_NS"))
#define __TZ_set_CONTROL_NS(VALUE) (__arm_wsr("CONTROL_NS", (VALUE)))
#define __TZ_get_PSP_NS() (__arm_rsr("PSP_NS"))
#define __TZ_set_PSP_NS(VALUE) (__arm_wsr("PSP_NS", (VALUE)))
#define __TZ_get_MSP_NS() (__arm_rsr("MSP_NS"))
#define __TZ_set_MSP_NS(VALUE) (__arm_wsr("MSP_NS", (VALUE)))
#define __TZ_get_SP_NS() (__arm_rsr("SP_NS"))
#define __TZ_set_SP_NS(VALUE) (__arm_wsr("SP_NS", (VALUE)))
#define __TZ_get_PRIMASK_NS() (__arm_rsr("PRIMASK_NS"))
#define __TZ_set_PRIMASK_NS(VALUE) (__arm_wsr("PRIMASK_NS", (VALUE)))
#define __TZ_get_BASEPRI_NS() (__arm_rsr("BASEPRI_NS"))
#define __TZ_set_BASEPRI_NS(VALUE) (__arm_wsr("BASEPRI_NS", (VALUE)))
#define __TZ_get_FAULTMASK_NS() (__arm_rsr("FAULTMASK_NS"))
#define __TZ_set_FAULTMASK_NS(VALUE)(__arm_wsr("FAULTMASK_NS", (VALUE)))
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure PSPLIM is RAZ/WI
#define __TZ_get_PSPLIM_NS() (0U)
#define __TZ_set_PSPLIM_NS(VALUE) ((void)(VALUE))
#else
#define __TZ_get_PSPLIM_NS() (__arm_rsr("PSPLIM_NS"))
#define __TZ_set_PSPLIM_NS(VALUE) (__arm_wsr("PSPLIM_NS", (VALUE)))
#endif
#define __TZ_get_MSPLIM_NS() (__arm_rsr("MSPLIM_NS"))
#define __TZ_set_MSPLIM_NS(VALUE) (__arm_wsr("MSPLIM_NS", (VALUE)))
#define __NOP __iar_builtin_no_operation
#define __CLZ __iar_builtin_CLZ
#define __CLREX __iar_builtin_CLREX
#define __DMB __iar_builtin_DMB
#define __DSB __iar_builtin_DSB
#define __ISB __iar_builtin_ISB
#define __LDREXB __iar_builtin_LDREXB
#define __LDREXH __iar_builtin_LDREXH
#define __LDREXW __iar_builtin_LDREX
#define __RBIT __iar_builtin_RBIT
#define __REV __iar_builtin_REV
#define __REV16 __iar_builtin_REV16
__IAR_FT int16_t __REVSH(int16_t val)
{
return (int16_t) __iar_builtin_REVSH(val);
}
#define __ROR __iar_builtin_ROR
#define __RRX __iar_builtin_RRX
#define __SEV __iar_builtin_SEV
#if !__IAR_M0_FAMILY
#define __SSAT __iar_builtin_SSAT
#endif
#define __STREXB __iar_builtin_STREXB
#define __STREXH __iar_builtin_STREXH
#define __STREXW __iar_builtin_STREX
#if !__IAR_M0_FAMILY
#define __USAT __iar_builtin_USAT
#endif
#define __WFE __iar_builtin_WFE
#define __WFI __iar_builtin_WFI
#if __ARM_MEDIA__
#define __SADD8 __iar_builtin_SADD8
#define __QADD8 __iar_builtin_QADD8
#define __SHADD8 __iar_builtin_SHADD8
#define __UADD8 __iar_builtin_UADD8
#define __UQADD8 __iar_builtin_UQADD8
#define __UHADD8 __iar_builtin_UHADD8
#define __SSUB8 __iar_builtin_SSUB8
#define __QSUB8 __iar_builtin_QSUB8
#define __SHSUB8 __iar_builtin_SHSUB8
#define __USUB8 __iar_builtin_USUB8
#define __UQSUB8 __iar_builtin_UQSUB8
#define __UHSUB8 __iar_builtin_UHSUB8
#define __SADD16 __iar_builtin_SADD16
#define __QADD16 __iar_builtin_QADD16
#define __SHADD16 __iar_builtin_SHADD16
#define __UADD16 __iar_builtin_UADD16
#define __UQADD16 __iar_builtin_UQADD16
#define __UHADD16 __iar_builtin_UHADD16
#define __SSUB16 __iar_builtin_SSUB16
#define __QSUB16 __iar_builtin_QSUB16
#define __SHSUB16 __iar_builtin_SHSUB16
#define __USUB16 __iar_builtin_USUB16
#define __UQSUB16 __iar_builtin_UQSUB16
#define __UHSUB16 __iar_builtin_UHSUB16
#define __SASX __iar_builtin_SASX
#define __QASX __iar_builtin_QASX
#define __SHASX __iar_builtin_SHASX
#define __UASX __iar_builtin_UASX
#define __UQASX __iar_builtin_UQASX
#define __UHASX __iar_builtin_UHASX
#define __SSAX __iar_builtin_SSAX
#define __QSAX __iar_builtin_QSAX
#define __SHSAX __iar_builtin_SHSAX
#define __USAX __iar_builtin_USAX
#define __UQSAX __iar_builtin_UQSAX
#define __UHSAX __iar_builtin_UHSAX
#define __USAD8 __iar_builtin_USAD8
#define __USADA8 __iar_builtin_USADA8
#define __SSAT16 __iar_builtin_SSAT16
#define __USAT16 __iar_builtin_USAT16
#define __UXTB16 __iar_builtin_UXTB16
#define __UXTAB16 __iar_builtin_UXTAB16
#define __SXTB16 __iar_builtin_SXTB16
#define __SXTAB16 __iar_builtin_SXTAB16
#define __SMUAD __iar_builtin_SMUAD
#define __SMUADX __iar_builtin_SMUADX
#define __SMMLA __iar_builtin_SMMLA
#define __SMLAD __iar_builtin_SMLAD
#define __SMLADX __iar_builtin_SMLADX
#define __SMLALD __iar_builtin_SMLALD
#define __SMLALDX __iar_builtin_SMLALDX
#define __SMUSD __iar_builtin_SMUSD
#define __SMUSDX __iar_builtin_SMUSDX
#define __SMLSD __iar_builtin_SMLSD
#define __SMLSDX __iar_builtin_SMLSDX
#define __SMLSLD __iar_builtin_SMLSLD
#define __SMLSLDX __iar_builtin_SMLSLDX
#define __SEL __iar_builtin_SEL
#define __QADD __iar_builtin_QADD
#define __QSUB __iar_builtin_QSUB
#define __PKHBT __iar_builtin_PKHBT
#define __PKHTB __iar_builtin_PKHTB
#endif
#else /* __ICCARM_INTRINSICS_VERSION__ == 2 */
#if __IAR_M0_FAMILY
/* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */
#define __CLZ __cmsis_iar_clz_not_active
#define __SSAT __cmsis_iar_ssat_not_active
#define __USAT __cmsis_iar_usat_not_active
#define __RBIT __cmsis_iar_rbit_not_active
#define __get_APSR __cmsis_iar_get_APSR_not_active
#endif
#if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)) ))
#define __get_FPSCR __cmsis_iar_get_FPSR_not_active
#define __set_FPSCR __cmsis_iar_set_FPSR_not_active
#endif
#ifdef __INTRINSICS_INCLUDED
#error intrinsics.h is already included previously!
#endif
#include <intrinsics.h>
#if __IAR_M0_FAMILY
/* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */
#undef __CLZ
#undef __SSAT
#undef __USAT
#undef __RBIT
#undef __get_APSR
__STATIC_INLINE uint8_t __CLZ(uint32_t data)
{
if (data == 0U) { return 32U; }
uint32_t count = 0U;
uint32_t mask = 0x80000000U;
while ((data & mask) == 0U)
{
count += 1U;
mask = mask >> 1U;
}
return count;
}
__STATIC_INLINE uint32_t __RBIT(uint32_t v)
{
uint8_t sc = 31U;
uint32_t r = v;
for (v >>= 1U; v; v >>= 1U)
{
r <<= 1U;
r |= v & 1U;
sc--;
}
return (r << sc);
}
__STATIC_INLINE uint32_t __get_APSR(void)
{
uint32_t res;
__asm("MRS %0,APSR" : "=r" (res));
return res;
}
#endif
#if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)) ))
#undef __get_FPSCR
#undef __set_FPSCR
#define __get_FPSCR() (0)
#define __set_FPSCR(VALUE) ((void)VALUE)
#endif
#pragma diag_suppress=Pe940
#pragma diag_suppress=Pe177
#define __enable_irq __enable_interrupt
#define __disable_irq __disable_interrupt
#define __NOP __no_operation
#define __get_xPSR __get_PSR
#if (!defined(__ARM_ARCH_6M__) || __ARM_ARCH_6M__==0)
__IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr)
{
return __LDREX((unsigned long *)ptr);
}
__IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr)
{
return __STREX(value, (unsigned long *)ptr);
}
#endif
/* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */
#if (__CORTEX_M >= 0x03)
__IAR_FT uint32_t __RRX(uint32_t value)
{
uint32_t result;
__ASM("RRX %0, %1" : "=r"(result) : "r" (value) : "cc");
return(result);
}
__IAR_FT void __set_BASEPRI_MAX(uint32_t value)
{
__asm volatile("MSR BASEPRI_MAX,%0"::"r" (value));
}
#define __enable_fault_irq __enable_fiq
#define __disable_fault_irq __disable_fiq
#endif /* (__CORTEX_M >= 0x03) */
__IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2)
{
return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2));
}
#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
(defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
__IAR_FT uint32_t __get_MSPLIM(void)
{
uint32_t res;
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure MSPLIM is RAZ/WI
res = 0U;
#else
__asm volatile("MRS %0,MSPLIM" : "=r" (res));
#endif
return res;
}
__IAR_FT void __set_MSPLIM(uint32_t value)
{
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure MSPLIM is RAZ/WI
(void)value;
#else
__asm volatile("MSR MSPLIM,%0" :: "r" (value));
#endif
}
__IAR_FT uint32_t __get_PSPLIM(void)
{
uint32_t res;
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure PSPLIM is RAZ/WI
res = 0U;
#else
__asm volatile("MRS %0,PSPLIM" : "=r" (res));
#endif
return res;
}
__IAR_FT void __set_PSPLIM(uint32_t value)
{
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure PSPLIM is RAZ/WI
(void)value;
#else
__asm volatile("MSR PSPLIM,%0" :: "r" (value));
#endif
}
__IAR_FT uint32_t __TZ_get_CONTROL_NS(void)
{
uint32_t res;
__asm volatile("MRS %0,CONTROL_NS" : "=r" (res));
return res;
}
__IAR_FT void __TZ_set_CONTROL_NS(uint32_t value)
{
__asm volatile("MSR CONTROL_NS,%0" :: "r" (value));
}
__IAR_FT uint32_t __TZ_get_PSP_NS(void)
{
uint32_t res;
__asm volatile("MRS %0,PSP_NS" : "=r" (res));
return res;
}
__IAR_FT void __TZ_set_PSP_NS(uint32_t value)
{
__asm volatile("MSR PSP_NS,%0" :: "r" (value));
}
__IAR_FT uint32_t __TZ_get_MSP_NS(void)
{
uint32_t res;
__asm volatile("MRS %0,MSP_NS" : "=r" (res));
return res;
}
__IAR_FT void __TZ_set_MSP_NS(uint32_t value)
{
__asm volatile("MSR MSP_NS,%0" :: "r" (value));
}
__IAR_FT uint32_t __TZ_get_SP_NS(void)
{
uint32_t res;
__asm volatile("MRS %0,SP_NS" : "=r" (res));
return res;
}
__IAR_FT void __TZ_set_SP_NS(uint32_t value)
{
__asm volatile("MSR SP_NS,%0" :: "r" (value));
}
__IAR_FT uint32_t __TZ_get_PRIMASK_NS(void)
{
uint32_t res;
__asm volatile("MRS %0,PRIMASK_NS" : "=r" (res));
return res;
}
__IAR_FT void __TZ_set_PRIMASK_NS(uint32_t value)
{
__asm volatile("MSR PRIMASK_NS,%0" :: "r" (value));
}
__IAR_FT uint32_t __TZ_get_BASEPRI_NS(void)
{
uint32_t res;
__asm volatile("MRS %0,BASEPRI_NS" : "=r" (res));
return res;
}
__IAR_FT void __TZ_set_BASEPRI_NS(uint32_t value)
{
__asm volatile("MSR BASEPRI_NS,%0" :: "r" (value));
}
__IAR_FT uint32_t __TZ_get_FAULTMASK_NS(void)
{
uint32_t res;
__asm volatile("MRS %0,FAULTMASK_NS" : "=r" (res));
return res;
}
__IAR_FT void __TZ_set_FAULTMASK_NS(uint32_t value)
{
__asm volatile("MSR FAULTMASK_NS,%0" :: "r" (value));
}
__IAR_FT uint32_t __TZ_get_PSPLIM_NS(void)
{
uint32_t res;
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure PSPLIM is RAZ/WI
res = 0U;
#else
__asm volatile("MRS %0,PSPLIM_NS" : "=r" (res));
#endif
return res;
}
__IAR_FT void __TZ_set_PSPLIM_NS(uint32_t value)
{
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure PSPLIM is RAZ/WI
(void)value;
#else
__asm volatile("MSR PSPLIM_NS,%0" :: "r" (value));
#endif
}
__IAR_FT uint32_t __TZ_get_MSPLIM_NS(void)
{
uint32_t res;
__asm volatile("MRS %0,MSPLIM_NS" : "=r" (res));
return res;
}
__IAR_FT void __TZ_set_MSPLIM_NS(uint32_t value)
{
__asm volatile("MSR MSPLIM_NS,%0" :: "r" (value));
}
#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */
#endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */
#define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value))
#if __IAR_M0_FAMILY
__STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat)
{
if ((sat >= 1U) && (sat <= 32U))
{
const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U);
const int32_t min = -1 - max ;
if (val > max)
{
return max;
}
else if (val < min)
{
return min;
}
}
return val;
}
__STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat)
{
if (sat <= 31U)
{
const uint32_t max = ((1U << sat) - 1U);
if (val > (int32_t)max)
{
return max;
}
else if (val < 0)
{
return 0U;
}
}
return (uint32_t)val;
}
#endif
#if (__CORTEX_M >= 0x03) /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */
__IAR_FT uint8_t __LDRBT(volatile uint8_t *addr)
{
uint32_t res;
__ASM("LDRBT %0, [%1]" : "=r" (res) : "r" (addr) : "memory");
return ((uint8_t)res);
}
__IAR_FT uint16_t __LDRHT(volatile uint16_t *addr)
{
uint32_t res;
__ASM("LDRHT %0, [%1]" : "=r" (res) : "r" (addr) : "memory");
return ((uint16_t)res);
}
__IAR_FT uint32_t __LDRT(volatile uint32_t *addr)
{
uint32_t res;
__ASM("LDRT %0, [%1]" : "=r" (res) : "r" (addr) : "memory");
return res;
}
__IAR_FT void __STRBT(uint8_t value, volatile uint8_t *addr)
{
__ASM("STRBT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory");
}
__IAR_FT void __STRHT(uint16_t value, volatile uint16_t *addr)
{
__ASM("STRHT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory");
}
__IAR_FT void __STRT(uint32_t value, volatile uint32_t *addr)
{
__ASM("STRT %1, [%0]" : : "r" (addr), "r" (value) : "memory");
}
#endif /* (__CORTEX_M >= 0x03) */
#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
(defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
__IAR_FT uint8_t __LDAB(volatile uint8_t *ptr)
{
uint32_t res;
__ASM volatile ("LDAB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
return ((uint8_t)res);
}
__IAR_FT uint16_t __LDAH(volatile uint16_t *ptr)
{
uint32_t res;
__ASM volatile ("LDAH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
return ((uint16_t)res);
}
__IAR_FT uint32_t __LDA(volatile uint32_t *ptr)
{
uint32_t res;
__ASM volatile ("LDA %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
return res;
}
__IAR_FT void __STLB(uint8_t value, volatile uint8_t *ptr)
{
__ASM volatile ("STLB %1, [%0]" :: "r" (ptr), "r" (value) : "memory");
}
__IAR_FT void __STLH(uint16_t value, volatile uint16_t *ptr)
{
__ASM volatile ("STLH %1, [%0]" :: "r" (ptr), "r" (value) : "memory");
}
__IAR_FT void __STL(uint32_t value, volatile uint32_t *ptr)
{
__ASM volatile ("STL %1, [%0]" :: "r" (ptr), "r" (value) : "memory");
}
__IAR_FT uint8_t __LDAEXB(volatile uint8_t *ptr)
{
uint32_t res;
__ASM volatile ("LDAEXB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
return ((uint8_t)res);
}
__IAR_FT uint16_t __LDAEXH(volatile uint16_t *ptr)
{
uint32_t res;
__ASM volatile ("LDAEXH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
return ((uint16_t)res);
}
__IAR_FT uint32_t __LDAEX(volatile uint32_t *ptr)
{
uint32_t res;
__ASM volatile ("LDAEX %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
return res;
}
__IAR_FT uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr)
{
uint32_t res;
__ASM volatile ("STLEXB %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory");
return res;
}
__IAR_FT uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr)
{
uint32_t res;
__ASM volatile ("STLEXH %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory");
return res;
}
__IAR_FT uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr)
{
uint32_t res;
__ASM volatile ("STLEX %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory");
return res;
}
#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */
#undef __IAR_FT
#undef __IAR_M0_FAMILY
#undef __ICCARM_V8
#pragma diag_default=Pe940
#pragma diag_default=Pe177
#endif /* __CMSIS_ICCARM_H__ */

View file

@ -0,0 +1,39 @@
/**************************************************************************//**
* @file cmsis_version.h
* @brief CMSIS Core(M) Version definitions
* @version V5.0.3
* @date 24. June 2019
******************************************************************************/
/*
* Copyright (c) 2009-2019 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__clang__)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CMSIS_VERSION_H
#define __CMSIS_VERSION_H
/* CMSIS Version definitions */
#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */
#define __CM_CMSIS_VERSION_SUB ( 3U) /*!< [15:0] CMSIS Core(M) sub version */
#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \
__CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,346 @@
/******************************************************************************
* @file mpu_armv8.h
* @brief CMSIS MPU API for Armv8-M and Armv8.1-M MPU
* @version V5.1.0
* @date 08. March 2019
******************************************************************************/
/*
* Copyright (c) 2017-2019 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__clang__)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef ARM_MPU_ARMV8_H
#define ARM_MPU_ARMV8_H
/** \brief Attribute for device memory (outer only) */
#define ARM_MPU_ATTR_DEVICE ( 0U )
/** \brief Attribute for non-cacheable, normal memory */
#define ARM_MPU_ATTR_NON_CACHEABLE ( 4U )
/** \brief Attribute for normal memory (outer and inner)
* \param NT Non-Transient: Set to 1 for non-transient data.
* \param WB Write-Back: Set to 1 to use write-back update policy.
* \param RA Read Allocation: Set to 1 to use cache allocation on read miss.
* \param WA Write Allocation: Set to 1 to use cache allocation on write miss.
*/
#define ARM_MPU_ATTR_MEMORY_(NT, WB, RA, WA) \
(((NT & 1U) << 3U) | ((WB & 1U) << 2U) | ((RA & 1U) << 1U) | (WA & 1U))
/** \brief Device memory type non Gathering, non Re-ordering, non Early Write Acknowledgement */
#define ARM_MPU_ATTR_DEVICE_nGnRnE (0U)
/** \brief Device memory type non Gathering, non Re-ordering, Early Write Acknowledgement */
#define ARM_MPU_ATTR_DEVICE_nGnRE (1U)
/** \brief Device memory type non Gathering, Re-ordering, Early Write Acknowledgement */
#define ARM_MPU_ATTR_DEVICE_nGRE (2U)
/** \brief Device memory type Gathering, Re-ordering, Early Write Acknowledgement */
#define ARM_MPU_ATTR_DEVICE_GRE (3U)
/** \brief Memory Attribute
* \param O Outer memory attributes
* \param I O == ARM_MPU_ATTR_DEVICE: Device memory attributes, else: Inner memory attributes
*/
#define ARM_MPU_ATTR(O, I) (((O & 0xFU) << 4U) | (((O & 0xFU) != 0U) ? (I & 0xFU) : ((I & 0x3U) << 2U)))
/** \brief Normal memory non-shareable */
#define ARM_MPU_SH_NON (0U)
/** \brief Normal memory outer shareable */
#define ARM_MPU_SH_OUTER (2U)
/** \brief Normal memory inner shareable */
#define ARM_MPU_SH_INNER (3U)
/** \brief Memory access permissions
* \param RO Read-Only: Set to 1 for read-only memory.
* \param NP Non-Privileged: Set to 1 for non-privileged memory.
*/
#define ARM_MPU_AP_(RO, NP) (((RO & 1U) << 1U) | (NP & 1U))
/** \brief Region Base Address Register value
* \param BASE The base address bits [31:5] of a memory region. The value is zero extended. Effective address gets 32 byte aligned.
* \param SH Defines the Shareability domain for this memory region.
* \param RO Read-Only: Set to 1 for a read-only memory region.
* \param NP Non-Privileged: Set to 1 for a non-privileged memory region.
* \oaram XN eXecute Never: Set to 1 for a non-executable memory region.
*/
#define ARM_MPU_RBAR(BASE, SH, RO, NP, XN) \
((BASE & MPU_RBAR_BASE_Msk) | \
((SH << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | \
((ARM_MPU_AP_(RO, NP) << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | \
((XN << MPU_RBAR_XN_Pos) & MPU_RBAR_XN_Msk))
/** \brief Region Limit Address Register value
* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended.
* \param IDX The attribute index to be associated with this memory region.
*/
#define ARM_MPU_RLAR(LIMIT, IDX) \
((LIMIT & MPU_RLAR_LIMIT_Msk) | \
((IDX << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \
(MPU_RLAR_EN_Msk))
#if defined(MPU_RLAR_PXN_Pos)
/** \brief Region Limit Address Register with PXN value
* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended.
* \param PXN Privileged execute never. Defines whether code can be executed from this privileged region.
* \param IDX The attribute index to be associated with this memory region.
*/
#define ARM_MPU_RLAR_PXN(LIMIT, PXN, IDX) \
((LIMIT & MPU_RLAR_LIMIT_Msk) | \
((PXN << MPU_RLAR_PXN_Pos) & MPU_RLAR_PXN_Msk) | \
((IDX << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \
(MPU_RLAR_EN_Msk))
#endif
/**
* Struct for a single MPU Region
*/
typedef struct {
uint32_t RBAR; /*!< Region Base Address Register value */
uint32_t RLAR; /*!< Region Limit Address Register value */
} ARM_MPU_Region_t;
/** Enable the MPU.
* \param MPU_Control Default access permissions for unconfigured regions.
*/
__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control)
{
MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
#endif
__DSB();
__ISB();
}
/** Disable the MPU.
*/
__STATIC_INLINE void ARM_MPU_Disable(void)
{
__DMB();
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
#endif
MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk;
}
#ifdef MPU_NS
/** Enable the Non-secure MPU.
* \param MPU_Control Default access permissions for unconfigured regions.
*/
__STATIC_INLINE void ARM_MPU_Enable_NS(uint32_t MPU_Control)
{
MPU_NS->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
#endif
__DSB();
__ISB();
}
/** Disable the Non-secure MPU.
*/
__STATIC_INLINE void ARM_MPU_Disable_NS(void)
{
__DMB();
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
SCB_NS->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
#endif
MPU_NS->CTRL &= ~MPU_CTRL_ENABLE_Msk;
}
#endif
/** Set the memory attribute encoding to the given MPU.
* \param mpu Pointer to the MPU to be configured.
* \param idx The attribute index to be set [0-7]
* \param attr The attribute value to be set.
*/
__STATIC_INLINE void ARM_MPU_SetMemAttrEx(MPU_Type* mpu, uint8_t idx, uint8_t attr)
{
const uint8_t reg = idx / 4U;
const uint32_t pos = ((idx % 4U) * 8U);
const uint32_t mask = 0xFFU << pos;
if (reg >= (sizeof(mpu->MAIR) / sizeof(mpu->MAIR[0]))) {
return; // invalid index
}
mpu->MAIR[reg] = ((mpu->MAIR[reg] & ~mask) | ((attr << pos) & mask));
}
/** Set the memory attribute encoding.
* \param idx The attribute index to be set [0-7]
* \param attr The attribute value to be set.
*/
__STATIC_INLINE void ARM_MPU_SetMemAttr(uint8_t idx, uint8_t attr)
{
ARM_MPU_SetMemAttrEx(MPU, idx, attr);
}
#ifdef MPU_NS
/** Set the memory attribute encoding to the Non-secure MPU.
* \param idx The attribute index to be set [0-7]
* \param attr The attribute value to be set.
*/
__STATIC_INLINE void ARM_MPU_SetMemAttr_NS(uint8_t idx, uint8_t attr)
{
ARM_MPU_SetMemAttrEx(MPU_NS, idx, attr);
}
#endif
/** Clear and disable the given MPU region of the given MPU.
* \param mpu Pointer to MPU to be used.
* \param rnr Region number to be cleared.
*/
__STATIC_INLINE void ARM_MPU_ClrRegionEx(MPU_Type* mpu, uint32_t rnr)
{
mpu->RNR = rnr;
mpu->RLAR = 0U;
}
/** Clear and disable the given MPU region.
* \param rnr Region number to be cleared.
*/
__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr)
{
ARM_MPU_ClrRegionEx(MPU, rnr);
}
#ifdef MPU_NS
/** Clear and disable the given Non-secure MPU region.
* \param rnr Region number to be cleared.
*/
__STATIC_INLINE void ARM_MPU_ClrRegion_NS(uint32_t rnr)
{
ARM_MPU_ClrRegionEx(MPU_NS, rnr);
}
#endif
/** Configure the given MPU region of the given MPU.
* \param mpu Pointer to MPU to be used.
* \param rnr Region number to be configured.
* \param rbar Value for RBAR register.
* \param rlar Value for RLAR register.
*/
__STATIC_INLINE void ARM_MPU_SetRegionEx(MPU_Type* mpu, uint32_t rnr, uint32_t rbar, uint32_t rlar)
{
mpu->RNR = rnr;
mpu->RBAR = rbar;
mpu->RLAR = rlar;
}
/** Configure the given MPU region.
* \param rnr Region number to be configured.
* \param rbar Value for RBAR register.
* \param rlar Value for RLAR register.
*/
__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rnr, uint32_t rbar, uint32_t rlar)
{
ARM_MPU_SetRegionEx(MPU, rnr, rbar, rlar);
}
#ifdef MPU_NS
/** Configure the given Non-secure MPU region.
* \param rnr Region number to be configured.
* \param rbar Value for RBAR register.
* \param rlar Value for RLAR register.
*/
__STATIC_INLINE void ARM_MPU_SetRegion_NS(uint32_t rnr, uint32_t rbar, uint32_t rlar)
{
ARM_MPU_SetRegionEx(MPU_NS, rnr, rbar, rlar);
}
#endif
/** Memcopy with strictly ordered memory access, e.g. for register targets.
* \param dst Destination data is copied to.
* \param src Source data is copied from.
* \param len Amount of data words to be copied.
*/
__STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len)
{
uint32_t i;
for (i = 0U; i < len; ++i)
{
dst[i] = src[i];
}
}
/** Load the given number of MPU regions from a table to the given MPU.
* \param mpu Pointer to the MPU registers to be used.
* \param rnr First region number to be configured.
* \param table Pointer to the MPU configuration table.
* \param cnt Amount of regions to be configured.
*/
__STATIC_INLINE void ARM_MPU_LoadEx(MPU_Type* mpu, uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt)
{
const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U;
if (cnt == 1U) {
mpu->RNR = rnr;
ARM_MPU_OrderedMemcpy(&(mpu->RBAR), &(table->RBAR), rowWordSize);
} else {
uint32_t rnrBase = rnr & ~(MPU_TYPE_RALIASES-1U);
uint32_t rnrOffset = rnr % MPU_TYPE_RALIASES;
mpu->RNR = rnrBase;
while ((rnrOffset + cnt) > MPU_TYPE_RALIASES) {
uint32_t c = MPU_TYPE_RALIASES - rnrOffset;
ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), c*rowWordSize);
table += c;
cnt -= c;
rnrOffset = 0U;
rnrBase += MPU_TYPE_RALIASES;
mpu->RNR = rnrBase;
}
ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), cnt*rowWordSize);
}
}
/** Load the given number of MPU regions from a table.
* \param rnr First region number to be configured.
* \param table Pointer to the MPU configuration table.
* \param cnt Amount of regions to be configured.
*/
__STATIC_INLINE void ARM_MPU_Load(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt)
{
ARM_MPU_LoadEx(MPU, rnr, table, cnt);
}
#ifdef MPU_NS
/** Load the given number of MPU regions from a table to the Non-secure MPU.
* \param rnr First region number to be configured.
* \param table Pointer to the MPU configuration table.
* \param cnt Amount of regions to be configured.
*/
__STATIC_INLINE void ARM_MPU_Load_NS(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt)
{
ARM_MPU_LoadEx(MPU_NS, rnr, table, cnt);
}
#endif
#endif

View file

@ -0,0 +1,70 @@
/******************************************************************************
* @file tz_context.h
* @brief Context Management for Armv8-M TrustZone
* @version V1.0.1
* @date 10. January 2018
******************************************************************************/
/*
* Copyright (c) 2017-2018 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__clang__)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef TZ_CONTEXT_H
#define TZ_CONTEXT_H
#include <stdint.h>
#ifndef TZ_MODULEID_T
#define TZ_MODULEID_T
/// \details Data type that identifies secure software modules called by a process.
typedef uint32_t TZ_ModuleId_t;
#endif
/// \details TZ Memory ID identifies an allocated memory slot.
typedef uint32_t TZ_MemoryId_t;
/// Initialize secure context memory system
/// \return execution status (1: success, 0: error)
uint32_t TZ_InitContextSystem_S (void);
/// Allocate context memory for calling secure software modules in TrustZone
/// \param[in] module identifies software modules called from non-secure mode
/// \return value != 0 id TrustZone memory slot identifier
/// \return value 0 no memory available or internal error
TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module);
/// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S
/// \param[in] id TrustZone memory slot identifier
/// \return execution status (1: success, 0: error)
uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id);
/// Load secure context (called on RTOS thread context switch)
/// \param[in] id TrustZone memory slot identifier
/// \return execution status (1: success, 0: error)
uint32_t TZ_LoadContext_S (TZ_MemoryId_t id);
/// Store secure context (called on RTOS thread context switch)
/// \param[in] id TrustZone memory slot identifier
/// \return execution status (1: success, 0: error)
uint32_t TZ_StoreContext_S (TZ_MemoryId_t id);
#endif // TZ_CONTEXT_H

View file

@ -0,0 +1,5 @@
<directory>
<chips chipVendor='NXP' >
<chip name='MIMXRT595S' xml_file='MIMXRT595S_part.xml' />
</chips>
</directory>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<infoList vendor="NXP">&#x0A;<info chip="MIMXRT595S" name="MIMXRT595S">&#x0A;<chip>&#x0A;<name>MIMXRT595S</name>&#x0A;<family>MIMXRT500</family>&#x0A;<vendor>NXP</vendor>&#x0A;<memory can_program="true" id="Flash" is_ro="true" size="0" type="Flash"/>&#x0A;<memory id="RAM" size="5120" type="RAM"/>&#x0A;<memoryInstance derived_from="Flash" driver="MIMXRT500_SFDP_MXIC_OSPI.cfx" id="QSPI_FLASH" location="0x8000000" size="0x800000"/>&#x0A;<memoryInstance derived_from="RAM" id="SRAM" location="0x80000" size="0x280000"/>&#x0A;<memoryInstance derived_from="RAM" id="USB_RAM" location="0x40140000" size="0x4000"/>&#x0A;</chip>&#x0A;<processor>&#x0A;<name gcc_name="cortex-m33">Cortex-M33</name>&#x0A;<family>Cortex-M</family>&#x0A;</processor>&#x0A;</info>&#x0A;</infoList>

View file

@ -0,0 +1,279 @@
<!-- DTD file for infoList/info blocks. These define boards, chips,
and RTOSes/app-structures. Note that the files themselves may
use many includes to build up the information, but only one
DTD is used for all of it. -->
<!ELEMENT infoList (info*)><!ATTLIST infoList
vendor CDATA #IMPLIED>
<!-- An info is defined as a container for a whole debuggable
target. This can be a board+chip, chip only, or one of those
with an rtos or app structure. The info has a name, which
is the name the user will use to select it when running
tools (e.g. stub, targ, etc); normally, this is a compacted
form of the chip name or board name (e.g. LPC2124, LMEV811,
etc.) The chip name must be specified and uses the standard
naming convention established by CRT. The proc is optional
and is the processor family (e.g. ARM7 or Cortex-M). The
match_ID is a number that has a local meaning. It is used
to auto-detect chips and boards when a register can be
looked up based on some knowledge (e.g. vendor, family of
chips, etc). match_ID may be a comma-separated list where
a chip may have multiple IDs -->
<!ELEMENT info (chip?,link*,processor?,emulator?)> <!ATTLIST info
name ID #REQUIRED
chip CDATA #REQUIRED
proc CDATA #IMPLIED
stub CDATA #IMPLIED
match_ID CDATA #IMPLIED>
<!-- Chip defines the details of the chip itself, including
memory, reset rules, vendor information, peripheral
information, and programming for flash. The determined
attribute is not used in the file, but is used when this
data is emitted by a tool live. -->
<!ELEMENT chip (vendor?|name?|reset?|clock?|memory*|
memoryInstance*|prog_flash*|peripheralInstance*)> <!ATTLIST chip
determined (detected|specified|installation) #IMPLIED>
<!-- Vendor provides the vendor name for the chip. This is the
full name and not the 3 letter short name. -->
<!ELEMENT vendor (#PCDATA)>
<!-- Name provides a more accurate version of the chip name
for display to a user. Version is the internal version
number if known. -->
<!ELEMENT name (#PCDATA)> <!ATTLIST name
ver NMTOKENS #IMPLIED>
<!-- Family is the chip family this belongs to. This usually
means "x" used for the last few digits/characters of the
name. How broad a family is depends on the vendor. So,
"2xxx" may be used for a big family in some cases and
"21xx" may be for medium sized family, and "213x" may be
used for a narrow family. The notion of family is usually
based on mostly shared peripherals and style (but not
size) of memory. -->
<!ELEMENT family (#PCDATA)>
<!-- Reset provides information on what happens when
the user requests a reset of the target (including
after a full load of a target app). This includes
board level reset, system reset (peripherals), and
core/cpu reset. Fake means that the tool will
write the correct values into registers. Real
means that the device will truly reset itself (within
any limits of debuggability. -->
<!ELEMENT reset EMPTY> <!ATTLIST reset
board (none|real|fake) "none"
sys (none|real|fake) "none"
core (none|real|fake) "fake">
<!-- Clock provides information on the chip's clocking
mechanism, including external osc/crystal and
PLL mechanism. The freq attr is not normally
provided in the file form (but may be pushed down
from a board definition), and so is used when a
tool provides this information. The freqency is
expressed in MHz and may have a "." in it as well
as end with MHz. Is_accurate is true when the
clock speed can be accurately determined; if not,
it must come from the board definition or the user
if needed for flash. Changeable indicates if the
clock speed can be changed dynamically, such as
programming a PLL -->
<!ELEMENT clock EMPTY> <!ATTLIST clock
freq NMTOKENS #IMPLIED
is_accurate (true|false) #IMPLIED
changeable (true|false) #IMPLIED>
<!-- Memory is used to define all memory types on the chip.
This includes ROM, Flash, RAM, external memory
(if known or knowable), and peripheral memory.
Note that the file may contain a subset of information.
The output from a tool will include all dynamic
information (determined at connect time). The
memory is defined with type, default size, and
access rules. The instances of such memory is then
derived from the template. This definition and
instance model makes it easier to define common
memory types, and then have instances per chip.
The instances provide the location and an optional
size override. Note that programmable Flash's
programming information is defined using the
prog_flash element. -->
<!ELEMENT memory (#PCDATA)> <!ATTLIST memory
id ID #REQUIRED
type (Unknown|ROM|Flash|EEPROM|ExtFlash|
RAM|ExtRAM|Peripheral|ExtPeripheral)
#REQUIRED
size NMTOKEN #IMPLIED
is_ro (true|false) #IMPLIED
is_wo (true|false) #IMPLIED
is_volatile (true|false) #IMPLIED
can_program (true|false) #IMPLIED>
<!-- MemoryInstance is an instantiation of a memory
type previously defined. It provides location,
an optional size override (required if the
size is not provided by the memory definition).
The enable indicates a test for the memory being
enabled (an expression from memory reads). -->
<!ELEMENT memoryInstance EMPTY> <!ATTLIST memoryInstance
id ID #REQUIRED
derived_from IDREF #REQUIRED
location NMTOKENS #REQUIRED
size NMTOKEN #IMPLIED
enable CDATA #IMPLIED>
<!-- Prog_flash is used to define the programming
rules for flash which can be programmed by the
tools. The flash must also be defined via the
memory and memoryInstance elements. The location
must be within a memoryInstance. For flashes
with variable sized blocks (sectors), there will
be more than one prog_flash element. For example,
if there are 8 2K blocks and then 2 32K blocks,
the 1st prog_flash will have a blocksz of 2K,
a size of 16K, and a location at the memoryInstance
start. The 2nd prog_flash will have a blocksz of 32K,
a size of 64K, and a location at 16K beyond the
memoryInstance start. The prog_flash elements must
be in address order.
The locked attr is true if the area is not writable
by programming. This is for pre-locked rather than
detectable dynamically locked.
The rules for self_erase, readwhileprog, and
progwithcode are not normally in the file, since
this information is understood by the flash algo
code (which is code). The algoName attr is an optional
algorithm name for chip families and boards with
more than one flash type. The maxPrgBuff attr is
optional and only used when RAM is needed for the
flash programming. It gives a reduced RAM buff size if
this device has a smaller max copy size than normal. -->
<!ELEMENT prog_flash (#PCDATA)> <!ATTLIST prog_flash
location NMTOKENS #REQUIRED
size NMTOKEN #REQUIRED
blocksz NMTOKEN #REQUIRED
wordsz NMTOKEN #REQUIRED
locked (true|false) #IMPLIED
self_erase (true|false) #IMPLIED
readwhileprog (true|false) #IMPLIED
progwithcode (true|false) #IMPLIED
algoName NMTOKEN #IMPLIED
maxPrgBuff NMTOKEN #IMPLIED>
<!-- PeripheralInstance defines the instantiation of
peripherals defined in a separate file (see link
element). Instances define the location and what
the instance is derived from. The tool output form
may also include enables for cases where the
peripheral can be validated as enabled or disabled
on the chip using a register; this is the same form
as peripheral enable in crt_peripheral_defs.dtd.
The determined attribute is not normally set in a file,
but is used for output. It indicates where the
peripheralInstance came from (what file, if any) and
if a static conclusion (vs. determined after
a connect). -->
<!ELEMENT peripheralInstance EMPTY> <!ATTLIST peripheralInstance
id ID #REQUIRED
derived_from IDREF #REQUIRED
location CDATA #REQUIRED
enable CDATA #IMPLIED
determined (defFile|infoFile|Dynamic) "infoFile">
<!-- The link element is used to point to a peripheral definition
file (or a set of them). It contains a file reference,
which may be relative to this file or a full URI. The
type reference may currently only be "simple". The show
reference may currently only be "embed". -->
<!ELEMENT link EMPTY> <!ATTLIST link
href CDATA #REQUIRED
type (simple) "simple"
show (embed) "embed">
<!-- The processor element is an output only element. That is,
it is not in a file, but emitted by tools. The determined
attribute indicates how the tool knows details about
the processor (such as version). -->
<!ELEMENT processor (name,family,regFormat*)> <!ATTLIST processor
determined (detected|specified|installation) #IMPLIED>
<!-- Name is the processors specific name (within a family)
and attributes define extra information of known. The
meaning of revision and ID is specific to each processor.
But, ARM processors use the r1p1 style format for rev. -->
<!ELEMENT name (#PCDATA)> <!ATTLIST name
rev NMTOKENS #IMPLIED
ID CDATA #IMPLIED
gcc_name CDATA #IMPLIED>
<!-- Family defines the processor family that the processor
is a member of. -->
<!ELEMENT family (#PCDATA)>
<!-- regFormat is used for processor specific registers that use
an unsual format. If not specified here, it is assumed that
the format will be hex and 32-bits. This allows for regs with
their own enumeration as well as bit-packed, such as flags.
Note that id is the name of the register when accessing
as a register (if missing, then cannot be written through
this interface), and name is the name it will show as when
formatted. Special is a marker for special registers or display
lines, such as PSR, PSR as text (bits expanded), Fault info,
and Cycle counter. -->
<!ELEMENT regFormat (field)> <!ATTLIST regFormat
id CDATA #IMPLIED
name CDATA #IMPLIED
gdb_name CDATA #IMPLIED
special (PSR|PSR_TEXT|FAULT|FAULT_TEXT|CYCLE) #IMPLIED
description CDATA #IMPLIED>
<!-- fieldFormat is used to give the bit breakout of the
register. If type is toggle, then it has two value
states. If the type is enum, then it is only given
as an enum. If the type is mixed, then it is given as
a value and an enum. If toggle, then on and off are
defined with the strings that represent them. Offset
is a bit in [] or a range in []. Optionally, enumList is
given as a comma separated list of enum constants, if
enum or mixed. -->
<!ELEMENT fieldFormat EMPTY> <!ATTLIST fieldFormat
id CDATA #IMPLIED
type (toggle|enum|mixed|value) #IMPLIED
offset CDATA #REQUIRED
on CDATA #IMPLIED
off CDATA #IMPLIED
enumList CDATA #IMPLIED
description CDATA #IMPLIED>
<!-- The emulator element is an output only element. That is,
it is not in a file, but emitted by tools. The attribute
indicates what "wire type" it uses (including simulator
or software connection). The rest of the details are in
sub-elements. -->
<!ELEMENT emulator (vendor,name,description,instance,speed)><!ATTLIST emulator
type (SWD|JTAG|Monitor|Simulator|Agent) #IMPLIED>
<!-- vendor may be inaccurate if more than one emulator
uses the same protocol, for example. The vendor name
may reflect on the software driver and not the emulator
probe vendor. It may be "Unknown" if not determined. -->
<!ELEMENT vendor (#PCDATA)>
<!-- name is normally the name of the software package that
supports the emulator. It may be a fully descriptive
name, rather than a trade name. -->
<!ELEMENT name (#PCDATA)>
<!-- description is normally info on the target if known, else
not provided. For example, name of emulator or board. -->
<!ELEMENT description (#PCDATA)>
<!-- instance reflects the choice from a list, if more
than one emulator is available. For USB emulators,
it will give the selected one and its USB name. A
TCP/IP one would give the port and hostname. -->
<!ELEMENT instance (#PCDATA)><!ATTLIST instance
index CDATA #IMPLIED>
<!-- Speed provides the current wire speed (if meaningful)
for the emulator. It also indicates the fastest and
slowest speeds possible, all in KHz. Note that speed
may be a bit misleading if the emulator driver uses
wire delays to get speeds between two wire rates. Run
speed is used when the target memory can be accessed
while the target runs (it often has to be slower).
Determined indicates how the speed was selected.-->
<!ELEMENT speed (#PCDATA)><!ATTLIST speed
fastestKHz CDATA #REQUIRED
slowestKHz CDATA #REQUIRED
step CDATA #IMPLIED
speed CDATA #REQUIRED
delay NMTOKEN #IMPLIED
run_speed CDATA #IMPLIED
run_delay NMTOKEN #IMPLIED
run_speedKHz NMTOKEN #IMPLIED
determined (test|setting|stored) "test">

View file

@ -0,0 +1,233 @@
/*
* GENERATED FILE - DO NOT EDIT
* Copyright (c) 2008-2013 Code Red Technologies Ltd,
* Copyright 2015, 2018-2019 NXP
* (c) NXP Semiconductors 2013-2021
* Generated linker script file for MIMXRT595S
* Created from linkscript.ldt by FMCreateLinkLibraries
* Using Freemarker v2.3.30
* MCUXpresso IDE v11.4.1 [Build 6260] [2021-09-15] on Oct 24, 2021, 10:02:43 AM
*/
INCLUDE "evkmimxrt595_dev_composite_cdc_vcom_cdc_vcom_bm_Debug_library.ld"
INCLUDE "evkmimxrt595_dev_composite_cdc_vcom_cdc_vcom_bm_Debug_memory.ld"
ENTRY(ResetISR)
SECTIONS
{
/* Image Vector Table and Boot Data for booting from external flash */
.boot_hdr : ALIGN(4)
{
FILL(0x00)
__boot_hdr_start__ = ABSOLUTE(.) ;
. = 0x400 ;
__flash_conf_hdr_start__ = ABSOLUTE(.) ;
KEEP(*(.flash_conf))
__flash_conf_hdr_end__ = ABSOLUTE(.) ;
. = 0x1000 ;
__boot_hdr_end__ = ABSOLUTE(.) ;
} >QSPI_FLASH
/* MAIN TEXT SECTION */
.text : ALIGN(4)
{
FILL(0xff)
__vectors_start__ = ABSOLUTE(.) ;
KEEP(*(.isr_vector))
/* Global Section Table */
. = ALIGN(4) ;
__section_table_start = .;
__data_section_table = .;
LONG(LOADADDR(.data));
LONG( ADDR(.data));
LONG( SIZEOF(.data));
LONG(LOADADDR(.data_RAM2));
LONG( ADDR(.data_RAM2));
LONG( SIZEOF(.data_RAM2));
__data_section_table_end = .;
__bss_section_table = .;
LONG( ADDR(.bss));
LONG( SIZEOF(.bss));
LONG( ADDR(.bss_RAM2));
LONG( SIZEOF(.bss_RAM2));
__bss_section_table_end = .;
__section_table_end = . ;
/* End of Global Section Table */
*(.after_vectors*)
} > QSPI_FLASH
.text : ALIGN(4)
{
*(.text*)
*(.rodata .rodata.* .constdata .constdata.*)
. = ALIGN(4);
} > QSPI_FLASH
/*
* for exception handling/unwind - some Newlib functions (in common
* with C++ and STDC++) use this.
*/
.ARM.extab : ALIGN(4)
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > QSPI_FLASH
.ARM.exidx : ALIGN(4)
{
__exidx_start = .;
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
__exidx_end = .;
} > QSPI_FLASH
_etext = .;
/* USB_RAM */
.m_usb_data (NOLOAD) :
{
*(m_usb_global)
} > USB_RAM AT> USB_RAM
/* DATA section for USB_RAM */
.data_RAM2 : ALIGN(4)
{
FILL(0xff)
PROVIDE(__start_data_RAM2 = .) ;
PROVIDE(__start_data_USB_RAM = .) ;
*(.ramfunc.$RAM2)
*(.ramfunc.$USB_RAM)
*(.data.$RAM2)
*(.data.$USB_RAM)
*(.data.$RAM2.*)
*(.data.$USB_RAM.*)
. = ALIGN(4) ;
PROVIDE(__end_data_RAM2 = .) ;
PROVIDE(__end_data_USB_RAM = .) ;
} > USB_RAM AT>QSPI_FLASH
/* MAIN DATA SECTION */
.uninit_RESERVED (NOLOAD) : ALIGN(4)
{
_start_uninit_RESERVED = .;
KEEP(*(.bss.$RESERVED*))
. = ALIGN(4) ;
_end_uninit_RESERVED = .;
} > SRAM AT> SRAM
/* Main DATA section (SRAM) */
.data : ALIGN(4)
{
FILL(0xff)
_data = . ;
PROVIDE(__start_data_RAM = .) ;
PROVIDE(__start_data_SRAM = .) ;
*(vtable)
*(.ramfunc*)
KEEP(*(CodeQuickAccess))
KEEP(*(DataQuickAccess))
*(RamFunction)
*(.data*)
. = ALIGN(4) ;
_edata = . ;
PROVIDE(__end_data_RAM = .) ;
PROVIDE(__end_data_SRAM = .) ;
} > SRAM AT>QSPI_FLASH
/* BSS section for USB_RAM */
.bss_RAM2 : ALIGN(4)
{
PROVIDE(__start_bss_RAM2 = .) ;
PROVIDE(__start_bss_USB_RAM = .) ;
*(.bss.$RAM2)
*(.bss.$USB_RAM)
*(.bss.$RAM2.*)
*(.bss.$USB_RAM.*)
. = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */
PROVIDE(__end_bss_RAM2 = .) ;
PROVIDE(__end_bss_USB_RAM = .) ;
} > USB_RAM AT> USB_RAM
/* MAIN BSS SECTION */
.bss : ALIGN(4)
{
_bss = .;
PROVIDE(__start_bss_RAM = .) ;
PROVIDE(__start_bss_SRAM = .) ;
*(.bss*)
*(COMMON)
. = ALIGN(4) ;
_ebss = .;
PROVIDE(__end_bss_RAM = .) ;
PROVIDE(__end_bss_SRAM = .) ;
PROVIDE(end = .);
} > SRAM AT> SRAM
/* NOINIT section for USB_RAM */
.noinit_RAM2 (NOLOAD) : ALIGN(4)
{
PROVIDE(__start_noinit_RAM2 = .) ;
PROVIDE(__start_noinit_USB_RAM = .) ;
*(.noinit.$RAM2)
*(.noinit.$USB_RAM)
*(.noinit.$RAM2.*)
*(.noinit.$USB_RAM.*)
. = ALIGN(4) ;
PROVIDE(__end_noinit_RAM2 = .) ;
PROVIDE(__end_noinit_USB_RAM = .) ;
} > USB_RAM AT> USB_RAM
/* DEFAULT NOINIT SECTION */
.noinit (NOLOAD): ALIGN(4)
{
_noinit = .;
PROVIDE(__start_noinit_RAM = .) ;
PROVIDE(__start_noinit_SRAM = .) ;
*(.noinit*)
. = ALIGN(4) ;
_end_noinit = .;
PROVIDE(__end_noinit_RAM = .) ;
PROVIDE(__end_noinit_SRAM = .) ;
} > SRAM AT> SRAM
/* Reserve and place Heap within memory map */
_HeapSize = 0x20000;
.heap : ALIGN(4)
{
_pvHeapStart = .;
. += _HeapSize;
. = ALIGN(4);
_pvHeapLimit = .;
} > SRAM
_StackSize = 0x1000;
/* Reserve space in memory for Stack */
.heap2stackfill :
{
. += _StackSize;
} > SRAM
/* Locate actual Stack in memory map */
.stack ORIGIN(SRAM) + LENGTH(SRAM) - _StackSize - 0: ALIGN(4)
{
_vStackBase = .;
. = ALIGN(4);
_vStackTop = . + _StackSize;
} > SRAM
/* Provide basic symbols giving location and size of main text
* block, including initial values of RW data sections. Note that
* these will need extending to give a complete picture with
* complex images (e.g multiple Flash banks).
*/
_image_start = LOADADDR(.text);
_image_end = LOADADDR(.data) + SIZEOF(.data);
_image_size = _image_end - _image_start;
/* Provide symbols for MIMXRT500 parts for startup code to use
* to set image to be plain load image or XIP.
* Config : Plain load image = false
*/
__imghdr_loadaddress = LOADADDR(.text);
__imghdr_imagetype = 0;
}

View file

@ -0,0 +1,17 @@
/*
* GENERATED FILE - DO NOT EDIT
* Copyright (c) 2008-2013 Code Red Technologies Ltd,
* Copyright 2015, 2018-2019 NXP
* (c) NXP Semiconductors 2013-2021
* Generated linker script file for MIMXRT595S
* Created from library.ldt by FMCreateLinkLibraries
* Using Freemarker v2.3.30
* MCUXpresso IDE v11.4.1 [Build 6260] [2021-09-15] on Oct 24, 2021, 10:02:43 AM
*/
GROUP (
"libcr_nohost_nf.a"
"libcr_c.a"
"libcr_eabihelpers.a"
"libgcc.a"
)

View file

@ -0,0 +1,32 @@
/*
* GENERATED FILE - DO NOT EDIT
* Copyright (c) 2008-2013 Code Red Technologies Ltd,
* Copyright 2015, 2018-2019 NXP
* (c) NXP Semiconductors 2013-2021
* Generated linker script file for MIMXRT595S
* Created from memory.ldt by FMCreateLinkMemory
* Using Freemarker v2.3.30
* MCUXpresso IDE v11.4.1 [Build 6260] [2021-09-15] on Oct 24, 2021, 10:02:43 AM
*/
MEMORY
{
/* Define each memory region */
QSPI_FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 0x800000 /* 8M bytes (alias Flash) */
SRAM (rwx) : ORIGIN = 0x80000, LENGTH = 0x280000 /* 2560K bytes (alias RAM) */
USB_RAM (rwx) : ORIGIN = 0x40140000, LENGTH = 0x4000 /* 16K bytes (alias RAM2) */
}
/* Define a symbol for the top of each memory region */
__base_QSPI_FLASH = 0x8000000 ; /* QSPI_FLASH */
__base_Flash = 0x8000000 ; /* Flash */
__top_QSPI_FLASH = 0x8000000 + 0x800000 ; /* 8M bytes */
__top_Flash = 0x8000000 + 0x800000 ; /* 8M bytes */
__base_SRAM = 0x80000 ; /* SRAM */
__base_RAM = 0x80000 ; /* RAM */
__top_SRAM = 0x80000 + 0x280000 ; /* 2560K bytes */
__top_RAM = 0x80000 + 0x280000 ; /* 2560K bytes */
__base_USB_RAM = 0x40140000 ; /* USB_RAM */
__base_RAM2 = 0x40140000 ; /* RAM2 */
__top_USB_RAM = 0x40140000 + 0x4000 ; /* 16K bytes */
__top_RAM2 = 0x40140000 + 0x4000 ; /* 16K bytes */

View file

@ -0,0 +1,2 @@
1 Devices Found:
0. ID: 0x6BA02477 IR Length: 4*

View file

@ -0,0 +1,64 @@
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
-include ../makefile.init
RM := rm -rf
# All of the sources participating in the build are defined here
-include sources.mk
-include utilities/subdir.mk
-include usb/phy/subdir.mk
-include usb/device/source/lpcip3511/subdir.mk
-include usb/device/source/subdir.mk
-include usb/device/class/cdc/subdir.mk
-include usb/device/class/subdir.mk
-include startup/subdir.mk
-include source/sspc/subdir.mk
-include source/subdir.mk
-include flash_config/subdir.mk
-include drivers/subdir.mk
-include device/subdir.mk
-include component/uart/subdir.mk
-include component/osa/subdir.mk
-include component/lists/subdir.mk
-include board/subdir.mk
-include subdir.mk
-include objects.mk
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(strip $(C_DEPS)),)
-include $(C_DEPS)
endif
endif
-include ../makefile.defs
# Add inputs and outputs from these tool invocations to the build variables
# All Target
all: evkmimxrt595_dev_composite_cdc_vcom_cdc_vcom_bm.axf
# Tool invocations
evkmimxrt595_dev_composite_cdc_vcom_cdc_vcom_bm.axf: $(OBJS) $(USER_OBJS)
@echo 'Building target: $@'
@echo 'Invoking: MCU Linker'
arm-none-eabi-gcc -nostdlib -L"/home/agreen/Documents/MCUXpresso_11.4.1_6260/workspace/evkmimxrt595_dev_composite_cdc_vcom_cdc_vcom_bm/source" -Xlinker -Map="evkmimxrt595_dev_composite_cdc_vcom_cdc_vcom_bm.map" -Xlinker --gc-sections -Xlinker -print-memory-usage -Xlinker --sort-section=alignment -Xlinker --cref -mcpu=cortex-m33 -mfpu=fpv5-sp-d16 -mfloat-abi=hard -mthumb -T evkmimxrt595_dev_composite_cdc_vcom_cdc_vcom_bm_Debug.ld -o "evkmimxrt595_dev_composite_cdc_vcom_cdc_vcom_bm.axf" $(OBJS) $(USER_OBJS) $(LIBS)
@echo 'Finished building target: $@'
@echo ' '
$(MAKE) --no-print-directory post-build
# Other Targets
clean:
-$(RM) $(EXECUTABLES)$(OBJS)$(C_DEPS) evkmimxrt595_dev_composite_cdc_vcom_cdc_vcom_bm.axf
-@echo ' '
post-build:
-@echo 'Performing post-build steps'
-arm-none-eabi-size "evkmimxrt595_dev_composite_cdc_vcom_cdc_vcom_bm.axf"; # arm-none-eabi-objcopy -v -O binary "evkmimxrt595_dev_composite_cdc_vcom_cdc_vcom_bm.axf" "evkmimxrt595_dev_composite_cdc_vcom_cdc_vcom_bm.bin" ; # checksum -p MIMXRT595S -d "evkmimxrt595_dev_composite_cdc_vcom_cdc_vcom_bm.bin";
-@echo ' '
.PHONY: all clean dependents post-build
-include ../makefile.targets

View file

@ -0,0 +1,622 @@
/*
* Copyright 2018-2021 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdint.h>
#include "fsl_common.h"
#include "fsl_debug_console.h"
#include "fsl_clock.h"
#include "fsl_flexspi.h"
#include "fsl_cache.h"
#include "fsl_power.h"
#include "clock_config.h"
#include "board.h"
#if defined(SDK_I2C_BASED_COMPONENT_USED) && SDK_I2C_BASED_COMPONENT_USED
#include "fsl_i2c.h"
#endif /* SDK_I2C_BASED_COMPONENT_USED */
#if defined BOARD_USE_CODEC
#include "fsl_i3c.h"
#endif
/*******************************************************************************
* Definitions
******************************************************************************/
#define BOARD_FLEXSPI_DLL_LOCK_RETRY (10)
/*******************************************************************************
* Variables
******************************************************************************/
/*******************************************************************************
* Prototypes
******************************************************************************/
static status_t flexspi_hyper_ram_write_mcr(FLEXSPI_Type *base, uint8_t regAddr, uint32_t *mrVal);
static status_t flexspi_hyper_ram_get_mcr(FLEXSPI_Type *base, uint8_t regAddr, uint32_t *mrVal);
static status_t flexspi_hyper_ram_reset(FLEXSPI_Type *base);
/*******************************************************************************
* Code
******************************************************************************/
/* Initialize debug console. */
void BOARD_InitDebugConsole(void)
{
uint32_t uartClkSrcFreq;
/* attach FRG0 clock to FLEXCOMM0 (debug console) */
CLOCK_SetFRGClock(BOARD_DEBUG_UART_FRG_CLK);
CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
uartClkSrcFreq = BOARD_DEBUG_UART_CLK_FREQ;
DbgConsole_Init(BOARD_DEBUG_UART_INSTANCE, BOARD_DEBUG_UART_BAUDRATE, BOARD_DEBUG_UART_TYPE, uartClkSrcFreq);
}
static status_t flexspi_hyper_ram_write_mcr(FLEXSPI_Type *base, uint8_t regAddr, uint32_t *mrVal)
{
flexspi_transfer_t flashXfer;
status_t status;
/* Write data */
flashXfer.deviceAddress = regAddr;
flashXfer.port = kFLEXSPI_PortA1;
flashXfer.cmdType = kFLEXSPI_Write;
flashXfer.SeqNumber = 1;
flashXfer.seqIndex = 3;
flashXfer.data = mrVal;
flashXfer.dataSize = 1;
status = FLEXSPI_TransferBlocking(base, &flashXfer);
return status;
}
static status_t flexspi_hyper_ram_get_mcr(FLEXSPI_Type *base, uint8_t regAddr, uint32_t *mrVal)
{
flexspi_transfer_t flashXfer;
status_t status;
/* Read data */
flashXfer.deviceAddress = regAddr;
flashXfer.port = kFLEXSPI_PortA1;
flashXfer.cmdType = kFLEXSPI_Read;
flashXfer.SeqNumber = 1;
flashXfer.seqIndex = 2;
flashXfer.data = mrVal;
flashXfer.dataSize = 2;
status = FLEXSPI_TransferBlocking(base, &flashXfer);
return status;
}
static status_t flexspi_hyper_ram_reset(FLEXSPI_Type *base)
{
flexspi_transfer_t flashXfer;
status_t status;
/* Write data */
flashXfer.deviceAddress = 0x0U;
flashXfer.port = kFLEXSPI_PortA1;
flashXfer.cmdType = kFLEXSPI_Command;
flashXfer.SeqNumber = 1;
flashXfer.seqIndex = 4;
status = FLEXSPI_TransferBlocking(base, &flashXfer);
if (status == kStatus_Success)
{
/* for loop of 50000 is about 1ms (@200 MHz CPU) */
for (uint32_t i = 2000000U; i > 0; i--)
{
__NOP();
}
}
return status;
}
/* Initialize psram. */
status_t BOARD_InitPsRam(void)
{
flexspi_device_config_t deviceconfig = {
.flexspiRootClk = 396000000, /* 396MHZ SPI serial clock, DDR serial clock 198M */
.isSck2Enabled = false,
.flashSize = 0x2000, /* 64Mb/KByte */
.CSIntervalUnit = kFLEXSPI_CsIntervalUnit1SckCycle,
.CSInterval = 5,
.CSHoldTime = 3,
.CSSetupTime = 3,
.dataValidTime = 1,
.columnspace = 0,
.enableWordAddress = false,
.AWRSeqIndex = 1,
.AWRSeqNumber = 1,
.ARDSeqIndex = 0,
.ARDSeqNumber = 1,
.AHBWriteWaitUnit = kFLEXSPI_AhbWriteWaitUnit2AhbCycle,
.AHBWriteWaitInterval = 0,
.enableWriteMask = true,
};
uint32_t customLUT[64] = {
/* Read Data */
[0] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x20),
[1] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DUMMY_RWDS_DDR, kFLEXSPI_8PAD, 0x07, kFLEXSPI_Command_READ_DDR,
kFLEXSPI_8PAD, 0x04),
/* Write Data */
[4] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x20),
[5] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DUMMY_RWDS_DDR, kFLEXSPI_8PAD, 0x07, kFLEXSPI_Command_WRITE_DDR,
kFLEXSPI_8PAD, 0x04),
/* Read Register */
[8] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_8PAD, 0x40, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x20),
[9] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DUMMY_RWDS_DDR, kFLEXSPI_8PAD, 0x07, kFLEXSPI_Command_READ_DDR,
kFLEXSPI_8PAD, 0x04),
/* Write Register */
[12] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_8PAD, 0xC0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x20),
[13] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x08, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD,
0x00),
/* reset */
[16] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_8PAD, 0xFF, kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_8PAD, 0x03),
};
uint32_t mr0mr1[1];
uint32_t mr4mr8[1];
uint32_t mr0Val[1];
uint32_t mr4Val[1];
uint32_t mr8Val[1];
flexspi_config_t config;
cache64_config_t cacheCfg;
status_t status = kStatus_Success;
POWER_DisablePD(kPDRUNCFG_APD_FLEXSPI1_SRAM);
POWER_DisablePD(kPDRUNCFG_PPD_FLEXSPI1_SRAM);
POWER_ApplyPD();
CLOCK_AttachClk(kAUX0_PLL_to_FLEXSPI1_CLK);
CLOCK_SetClkDiv(kCLOCK_DivFlexspi1Clk, 1);
RESET_PeripheralReset(kFLEXSPI1_RST_SHIFT_RSTn);
#if (defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Need to explicitly enable FlexSPI1 clock in mpi_loader_extram_loader case.
* In that case, FlexSPI driver need to be used before data sections copy. So
* global variables are forbidden with FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL=1.
*/
CLOCK_EnableClock(kCLOCK_Flexspi1);
#endif
/* As cache depends on FlexSPI power and clock, cache must be initialized after FlexSPI power/clock is set */
CACHE64_GetDefaultConfig(&cacheCfg);
CACHE64_Init(CACHE64_POLSEL1, &cacheCfg);
#if BOARD_ENABLE_PSRAM_CACHE
CACHE64_EnableWriteBuffer(CACHE64_CTRL1, true);
CACHE64_EnableCache(CACHE64_CTRL1);
#endif
/* Get FLEXSPI default settings and configure the flexspi. */
FLEXSPI_GetDefaultConfig(&config);
/* Init FLEXSPI. */
config.rxSampleClock = kFLEXSPI_ReadSampleClkExternalInputFromDqsPad;
/*Set AHB buffer size for reading data through AHB bus. */
config.ahbConfig.enableAHBPrefetch = true;
config.ahbConfig.enableAHBBufferable = true;
config.ahbConfig.enableAHBCachable = true;
config.ahbConfig.enableReadAddressOpt = true;
for (uint8_t i = 1; i < FSL_FEATURE_FLEXSPI_AHB_BUFFER_COUNT - 1; i++)
{
config.ahbConfig.buffer[i].bufferSize = 0;
}
/* FlexSPI1 has total 2KB RX buffer.
* Set GPU/Display master to use AHB Rx Buffer0.
*/
config.ahbConfig.buffer[0].masterIndex = 11; /* GPU/Display */
config.ahbConfig.buffer[0].bufferSize = 1024; /* Allocate 1KB bytes for GPU/Display */
config.ahbConfig.buffer[0].enablePrefetch = true;
config.ahbConfig.buffer[0].priority = 7; /* Set GPU/Display to highest priority. */
/* All other masters use last buffer with 1KB bytes. */
config.ahbConfig.buffer[FSL_FEATURE_FLEXSPI_AHB_BUFFER_COUNT - 1].bufferSize = 1024;
#if !(defined(FSL_FEATURE_FLEXSPI_HAS_NO_MCR0_COMBINATIONEN) && FSL_FEATURE_FLEXSPI_HAS_NO_MCR0_COMBINATIONEN)
config.enableCombination = true;
#endif
FLEXSPI_Init(BOARD_FLEXSPI_PSRAM, &config);
/* Configure flash settings according to serial flash feature. */
FLEXSPI_SetFlashConfig(BOARD_FLEXSPI_PSRAM, &deviceconfig, kFLEXSPI_PortA1);
/* Update LUT table. */
FLEXSPI_UpdateLUT(BOARD_FLEXSPI_PSRAM, 0, customLUT, ARRAY_SIZE(customLUT));
/* Do software reset. */
FLEXSPI_SoftwareReset(BOARD_FLEXSPI_PSRAM);
/* Reset hyper ram. */
status = flexspi_hyper_ram_reset(BOARD_FLEXSPI_PSRAM);
if (status != kStatus_Success)
{
return status;
}
status = flexspi_hyper_ram_get_mcr(BOARD_FLEXSPI_PSRAM, 0x0, mr0mr1);
if (status != kStatus_Success)
{
return status;
}
status = flexspi_hyper_ram_get_mcr(BOARD_FLEXSPI_PSRAM, 0x4, mr4mr8);
if (status != kStatus_Success)
{
return status;
}
/* Enable RBX, burst length set to 1K. - MR8 */
mr8Val[0] = (mr4mr8[0] & 0xFF00U) >> 8U;
mr8Val[0] = mr8Val[0] | 0x0F;
status = flexspi_hyper_ram_write_mcr(BOARD_FLEXSPI_PSRAM, 0x8, mr8Val);
if (status != kStatus_Success)
{
return status;
}
/* Set LC code to 0x04(LC=7, maximum frequency 200M) - MR0. */
mr0Val[0] = mr0mr1[0] & 0x00FFU;
mr0Val[0] = (mr0Val[0] & ~0x3CU) | (4U << 2U);
status = flexspi_hyper_ram_write_mcr(BOARD_FLEXSPI_PSRAM, 0x0, mr0Val);
if (status != kStatus_Success)
{
return status;
}
/* Set WLC code to 0x01(WLC=7, maximum frequency 200M) - MR4. */
mr4Val[0] = mr4mr8[0] & 0x00FFU;
mr4Val[0] = (mr4Val[0] & ~0xE0U) | (1U << 5U);
status = flexspi_hyper_ram_write_mcr(BOARD_FLEXSPI_PSRAM, 0x4, mr4Val);
if (status != kStatus_Success)
{
return status;
}
return status;
}
void BOARD_DeinitFlash(FLEXSPI_Type *base)
{
/* Enable FLEXSPI clock again */
CLKCTL0->PSCCTL0_SET = CLKCTL0_PSCCTL0_SET_FLEXSPI0_OTFAD_CLK_MASK;
/* Enable FLEXSPI module */
base->MCR0 &= ~FLEXSPI_MCR0_MDIS_MASK;
/* Wait until FLEXSPI is not busy */
while (!((base->STS0 & FLEXSPI_STS0_ARBIDLE_MASK) && (base->STS0 & FLEXSPI_STS0_SEQIDLE_MASK)))
{
}
/* Disable module during the reset procedure */
base->MCR0 |= FLEXSPI_MCR0_MDIS_MASK;
}
void BOARD_InitFlash(FLEXSPI_Type *base)
{
uint32_t status;
uint32_t lastStatus;
uint32_t retry;
/* If serial root clock is >= 100 MHz, DLLEN set to 1, OVRDEN set to 0, then SLVDLYTARGET setting of 0x0 is
* recommended. */
base->DLLCR[0] = 0x1U;
/* Enable FLEXSPI module */
base->MCR0 &= ~FLEXSPI_MCR0_MDIS_MASK;
base->MCR0 |= FLEXSPI_MCR0_SWRESET_MASK;
while (base->MCR0 & FLEXSPI_MCR0_SWRESET_MASK)
{
}
/* Need to wait DLL locked if DLL enabled */
if (0U != (base->DLLCR[0] & FLEXSPI_DLLCR_DLLEN_MASK))
{
lastStatus = base->STS2;
retry = BOARD_FLEXSPI_DLL_LOCK_RETRY;
/* Wait slave delay line locked and slave reference delay line locked. */
do
{
status = base->STS2;
if ((status & (FLEXSPI_STS2_AREFLOCK_MASK | FLEXSPI_STS2_ASLVLOCK_MASK)) ==
(FLEXSPI_STS2_AREFLOCK_MASK | FLEXSPI_STS2_ASLVLOCK_MASK))
{
/* Locked */
retry = 100;
break;
}
else if (status == lastStatus)
{
/* Same delay cell number in calibration */
retry--;
}
else
{
retry = BOARD_FLEXSPI_DLL_LOCK_RETRY;
lastStatus = status;
}
} while (retry > 0);
/* According to ERR011377, need to delay at least 100 NOPs to ensure the DLL is locked. */
for (; retry > 0U; retry--)
{
__NOP();
}
}
}
/* BOARD_SetFlexspiClock run in RAM used to configure FlexSPI clock source and divider when XIP. */
void BOARD_SetFlexspiClock(FLEXSPI_Type *base, uint32_t src, uint32_t divider)
{
if (base == FLEXSPI0)
{
if ((CLKCTL0->FLEXSPI0FCLKSEL != CLKCTL0_FLEXSPI0FCLKSEL_SEL(src)) ||
((CLKCTL0->FLEXSPI0FCLKDIV & CLKCTL0_FLEXSPI0FCLKDIV_DIV_MASK) != (divider - 1)))
{
/* Always deinit FLEXSPI and init FLEXSPI for the flash to make sure the flash works correctly after the
FLEXSPI root clock changed as the default FLEXSPI configuration may does not work for the new root clock
frequency. */
BOARD_DeinitFlash(base);
/* Disable clock before changing clock source */
CLKCTL0->PSCCTL0_CLR = CLKCTL0_PSCCTL0_CLR_FLEXSPI0_OTFAD_CLK_MASK;
/* Update flexspi clock. */
CLKCTL0->FLEXSPI0FCLKSEL = CLKCTL0_FLEXSPI0FCLKSEL_SEL(src);
CLKCTL0->FLEXSPI0FCLKDIV |= CLKCTL0_FLEXSPI0FCLKDIV_RESET_MASK; /* Reset the divider counter */
CLKCTL0->FLEXSPI0FCLKDIV = CLKCTL0_FLEXSPI0FCLKDIV_DIV(divider - 1);
while ((CLKCTL0->FLEXSPI0FCLKDIV) & CLKCTL0_FLEXSPI0FCLKDIV_REQFLAG_MASK)
{
}
/* Enable FLEXSPI clock again */
CLKCTL0->PSCCTL0_SET = CLKCTL0_PSCCTL0_SET_FLEXSPI0_OTFAD_CLK_MASK;
BOARD_InitFlash(base);
}
}
else if (base == FLEXSPI1)
{
if ((CLKCTL0->FLEXSPI1FCLKSEL != CLKCTL0_FLEXSPI1FCLKSEL_SEL(src)) ||
((CLKCTL0->FLEXSPI1FCLKDIV & CLKCTL0_FLEXSPI1FCLKDIV_DIV_MASK) != (divider - 1)))
{
/* Always deinit FLEXSPI and init FLEXSPI for the flash to make sure the flash works correctly after the
FLEXSPI root clock changed as the default FLEXSPI configuration may does not work for the new root clock
frequency. */
BOARD_DeinitFlash(base);
/* Disable clock before changing clock source */
CLKCTL0->PSCCTL0_CLR = CLKCTL0_PSCCTL0_CLR_FLEXSPI1_CLK_MASK;
/* Update flexspi clock. */
CLKCTL0->FLEXSPI1FCLKSEL = CLKCTL0_FLEXSPI1FCLKSEL_SEL(src);
CLKCTL0->FLEXSPI1FCLKDIV |= CLKCTL0_FLEXSPI1FCLKDIV_RESET_MASK; /* Reset the divider counter */
CLKCTL0->FLEXSPI1FCLKDIV = CLKCTL0_FLEXSPI1FCLKDIV_DIV(divider - 1);
while ((CLKCTL0->FLEXSPI1FCLKDIV) & CLKCTL0_FLEXSPI1FCLKDIV_REQFLAG_MASK)
{
}
/* Enable FLEXSPI clock again */
CLKCTL0->PSCCTL0_SET = CLKCTL0_PSCCTL0_SET_FLEXSPI1_CLK_MASK;
BOARD_InitFlash(base);
}
}
else
{
return;
}
}
/* This function is used to change FlexSPI clock to a stable source before clock sources(Such as PLL and Main clock)
* updating in case XIP(execute code on FLEXSPI memory.) */
void BOARD_FlexspiClockSafeConfig(void)
{
/* Move FLEXSPI clock source from main clock to FRO192M / 2 to avoid instruction/data fetch issue in XIP when
* updating PLL and main clock.
*/
BOARD_SetFlexspiClock(FLEXSPI0, 3U, 2U);
}
#if defined(SDK_I2C_BASED_COMPONENT_USED) && SDK_I2C_BASED_COMPONENT_USED
void BOARD_I2C_Init(I2C_Type *base, uint32_t clkSrc_Hz)
{
i2c_master_config_t i2cConfig = {0};
I2C_MasterGetDefaultConfig(&i2cConfig);
I2C_MasterInit(base, &i2cConfig, clkSrc_Hz);
}
status_t BOARD_I2C_Send(I2C_Type *base,
uint8_t deviceAddress,
uint32_t subAddress,
uint8_t subaddressSize,
uint8_t *txBuff,
uint8_t txBuffSize)
{
i2c_master_transfer_t masterXfer;
/* Prepare transfer structure. */
masterXfer.slaveAddress = deviceAddress;
masterXfer.direction = kI2C_Write;
masterXfer.subaddress = subAddress;
masterXfer.subaddressSize = subaddressSize;
masterXfer.data = txBuff;
masterXfer.dataSize = txBuffSize;
masterXfer.flags = kI2C_TransferDefaultFlag;
return I2C_MasterTransferBlocking(base, &masterXfer);
}
status_t BOARD_I2C_Receive(I2C_Type *base,
uint8_t deviceAddress,
uint32_t subAddress,
uint8_t subaddressSize,
uint8_t *rxBuff,
uint8_t rxBuffSize)
{
i2c_master_transfer_t masterXfer;
/* Prepare transfer structure. */
masterXfer.slaveAddress = deviceAddress;
masterXfer.subaddress = subAddress;
masterXfer.subaddressSize = subaddressSize;
masterXfer.data = rxBuff;
masterXfer.dataSize = rxBuffSize;
masterXfer.direction = kI2C_Read;
masterXfer.flags = kI2C_TransferDefaultFlag;
return I2C_MasterTransferBlocking(base, &masterXfer);
}
#endif
#if defined BOARD_USE_CODEC
void BOARD_I3C_Init(I3C_Type *base, uint32_t clkSrc_Hz)
{
i3c_master_config_t i3cConfig;
I3C_MasterGetDefaultConfig(&i3cConfig);
I3C_MasterInit(base, &i3cConfig, clkSrc_Hz);
}
status_t BOARD_I3C_Send(I3C_Type *base,
uint8_t deviceAddress,
uint32_t subAddress,
uint8_t subaddressSize,
uint8_t *txBuff,
uint8_t txBuffSize)
{
i3c_master_transfer_t masterXfer;
/* Prepare transfer structure. */
masterXfer.slaveAddress = deviceAddress;
masterXfer.direction = kI3C_Write;
masterXfer.busType = kI3C_TypeI2C;
masterXfer.subaddress = subAddress;
masterXfer.subaddressSize = subaddressSize;
masterXfer.data = txBuff;
masterXfer.dataSize = txBuffSize;
masterXfer.flags = kI3C_TransferDefaultFlag;
masterXfer.busType = kI3C_TypeI2C;
return I3C_MasterTransferBlocking(base, &masterXfer);
}
status_t BOARD_I3C_Receive(I3C_Type *base,
uint8_t deviceAddress,
uint32_t subAddress,
uint8_t subaddressSize,
uint8_t *rxBuff,
uint8_t rxBuffSize)
{
i3c_master_transfer_t masterXfer;
/* Prepare transfer structure. */
masterXfer.slaveAddress = deviceAddress;
masterXfer.subaddress = subAddress;
masterXfer.subaddressSize = subaddressSize;
masterXfer.data = rxBuff;
masterXfer.dataSize = rxBuffSize;
masterXfer.direction = kI3C_Read;
masterXfer.busType = kI3C_TypeI2C;
masterXfer.flags = kI3C_TransferDefaultFlag;
masterXfer.busType = kI3C_TypeI2C;
return I3C_MasterTransferBlocking(base, &masterXfer);
}
void BOARD_Codec_I2C_Init(void)
{
#if BOARD_I3C_CODEC
BOARD_I3C_Init(BOARD_CODEC_I2C_BASEADDR, BOARD_CODEC_I2C_CLOCK_FREQ);
#else
BOARD_I2C_Init(BOARD_CODEC_I2C_BASEADDR, BOARD_CODEC_I2C_CLOCK_FREQ);
#endif
}
status_t BOARD_Codec_I2C_Send(
uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, const uint8_t *txBuff, uint8_t txBuffSize)
{
#if BOARD_I3C_CODEC
return BOARD_I3C_Send(BOARD_CODEC_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, (uint8_t *)txBuff,
#else
return BOARD_I2C_Send(BOARD_CODEC_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, (uint8_t *)txBuff,
#endif
txBuffSize);
}
status_t BOARD_Codec_I2C_Receive(
uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, uint8_t *rxBuff, uint8_t rxBuffSize)
{
#if BOARD_I3C_CODEC
return BOARD_I3C_Receive(BOARD_CODEC_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, rxBuff, rxBuffSize);
#else
return BOARD_I2C_Receive(BOARD_CODEC_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, rxBuff, rxBuffSize);
#endif
}
#endif
#if defined(SDK_I2C_BASED_COMPONENT_USED) && SDK_I2C_BASED_COMPONENT_USED
void BOARD_PMIC_I2C_Init(void)
{
BOARD_I2C_Init(BOARD_PMIC_I2C_BASEADDR, BOARD_PMIC_I2C_CLOCK_FREQ);
}
status_t BOARD_PMIC_I2C_Send(
uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, const uint8_t *txBuff, uint8_t txBuffSize)
{
return BOARD_I2C_Send(BOARD_PMIC_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, (uint8_t *)txBuff,
txBuffSize);
}
status_t BOARD_PMIC_I2C_Receive(
uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, uint8_t *rxBuff, uint8_t rxBuffSize)
{
return BOARD_I2C_Receive(BOARD_PMIC_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, rxBuff, rxBuffSize);
}
void BOARD_MIPIPanelTouch_I2C_Init(void)
{
BOARD_I2C_Init(BOARD_MIPI_PANEL_TOUCH_I2C_BASEADDR, BOARD_MIPI_PANEL_TOUCH_I2C_CLOCK_FREQ);
}
status_t BOARD_MIPIPanelTouch_I2C_Send(
uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, const uint8_t *txBuff, uint8_t txBuffSize)
{
return BOARD_I2C_Send(BOARD_MIPI_PANEL_TOUCH_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize,
(uint8_t *)txBuff, txBuffSize);
}
status_t BOARD_MIPIPanelTouch_I2C_Receive(
uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, uint8_t *rxBuff, uint8_t rxBuffSize)
{
return BOARD_I2C_Receive(BOARD_MIPI_PANEL_TOUCH_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, rxBuff,
rxBuffSize);
}
void BOARD_Accel_I2C_Init(void)
{
BOARD_I2C_Init(BOARD_ACCEL_I2C_BASEADDR, BOARD_ACCEL_I2C_CLOCK_FREQ);
}
status_t BOARD_Accel_I2C_Send(uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, uint32_t txBuff)
{
uint8_t data = (uint8_t)txBuff;
return BOARD_I2C_Send(BOARD_ACCEL_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, &data, 1);
}
status_t BOARD_Accel_I2C_Receive(
uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, uint8_t *rxBuff, uint8_t rxBuffSize)
{
return BOARD_I2C_Receive(BOARD_ACCEL_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, rxBuff, rxBuffSize);
}
#endif /* SDK_I2C_BASED_COMPONENT_USED */

View file

@ -0,0 +1,281 @@
/*
* Copyright 2018-2021 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _BOARD_H_
#define _BOARD_H_
#include "clock_config.h"
#include "fsl_common.h"
#include "fsl_reset.h"
#include "fsl_gpio.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief The board name */
#define BOARD_NAME "EVK-MIMXRT595"
#define BOARD_I3C_CODEC (1)
/*! @brief The UART to use for debug messages. */
#define BOARD_DEBUG_UART_TYPE kSerialPort_Uart
#define BOARD_DEBUG_UART_BASEADDR (uint32_t) USART0
#define BOARD_DEBUG_UART_INSTANCE 0U
#define BOARD_DEBUG_UART_CLK_FREQ CLOCK_GetFlexcommClkFreq(0)
#define BOARD_DEBUG_UART_FRG_CLK \
(&(const clock_frg_clk_config_t){0U, kCLOCK_FrgPllDiv, 255U, 0U}) /*!< Select FRG0 mux as frg_pll */
#define BOARD_DEBUG_UART_CLK_ATTACH kFRG_to_FLEXCOMM0
#define BOARD_UART_IRQ_HANDLER FLEXCOMM0_IRQHandler
#define BOARD_UART_IRQ FLEXCOMM0_IRQn
#if BOARD_I3C_CODEC
#define BOARD_CODEC_I2C_BASEADDR I3C0
#define BOARD_CODEC_I2C_INSTANCE 0
#define BOARD_CODEC_I2C_CLOCK_FREQ CLOCK_GetI3cClkFreq()
#else
#define BOARD_CODEC_I2C_BASEADDR I2C4
#define BOARD_CODEC_I2C_INSTANCE 4
#define BOARD_CODEC_I2C_CLOCK_FREQ CLOCK_GetFlexcommClkFreq(4)
#endif
#define BOARD_FLEXSPI_PSRAM FLEXSPI1
#ifndef BOARD_ENABLE_PSRAM_CACHE
#define BOARD_ENABLE_PSRAM_CACHE 1
#endif
#ifndef BOARD_DEBUG_UART_BAUDRATE
#define BOARD_DEBUG_UART_BAUDRATE 115200
#endif /* BOARD_DEBUG_UART_BAUDRATE */
/* PCA9420 */
#define BOARD_PMIC_I2C_BASEADDR I2C15
#define BOARD_PMIC_I2C_CLOCK_FREQ CLOCK_GetFlexcommClkFreq(15)
/* Accelerometer */
#define BOARD_ACCEL_I2C_BASEADDR I2C4
#define BOARD_ACCEL_I2C_ADDR 0x1E
#define BOARD_ACCEL_I2C_CLOCK_FREQ CLOCK_GetFlexcommClkFreq(4)
/* Board led color mapping */
#define LOGIC_LED_ON 1U
#define LOGIC_LED_OFF 0U
#ifndef BOARD_LED_RED_GPIO
#define BOARD_LED_RED_GPIO GPIO
#endif
#define BOARD_LED_RED_GPIO_PORT 0U
#ifndef BOARD_LED_RED_GPIO_PIN
#define BOARD_LED_RED_GPIO_PIN 14U
#endif
#ifndef BOARD_LED_GREEN_GPIO
#define BOARD_LED_GREEN_GPIO GPIO
#endif
#define BOARD_LED_GREEN_GPIO_PORT 1U
#ifndef BOARD_LED_GREEN_GPIO_PIN
#define BOARD_LED_GREEN_GPIO_PIN 0U
#endif
#ifndef BOARD_LED_BLUE_GPIO
#define BOARD_LED_BLUE_GPIO GPIO
#endif
#define BOARD_LED_BLUE_GPIO_PORT 3U
#ifndef BOARD_LED_BLUE_GPIO_PIN
#define BOARD_LED_BLUE_GPIO_PIN 17U
#endif
#ifndef BOARD_FLASH_RESET_GPIO
#define BOARD_FLASH_RESET_GPIO GPIO
#endif
#ifndef BOARD_FLASH_RESET_GPIO_PORT
#define BOARD_FLASH_RESET_GPIO_PORT 4U
#endif
#ifndef BOARD_FLASH_RESET_GPIO_PIN
#define BOARD_FLASH_RESET_GPIO_PIN 5U
#endif
#define LED_RED_INIT(output) \
GPIO_PinInit(BOARD_LED_RED_GPIO, BOARD_LED_RED_GPIO_PORT, BOARD_LED_RED_GPIO_PIN, \
&(gpio_pin_config_t){kGPIO_DigitalOutput, (output)}) /*!< Enable target LED_RED */
#define LED_RED_ON() \
GPIO_PortSet(BOARD_LED_RED_GPIO, BOARD_LED_RED_GPIO_PORT, \
1U << BOARD_LED_RED_GPIO_PIN) /*!< Turn on target LED_RED */
#define LED_RED_OFF() \
GPIO_PortClear(BOARD_LED_RED_GPIO, BOARD_LED_RED_GPIO_PORT, \
1U << BOARD_LED_RED_GPIO_PIN) /*!< Turn off target LED_RED */
#define LED_RED_TOGGLE() \
GPIO_PortToggle(BOARD_LED_RED_GPIO, BOARD_LED_RED_GPIO_PORT, \
1U << BOARD_LED_RED_GPIO_PIN) /*!< Toggle on target LED_RED */
#define LED_GREEN_INIT(output) \
GPIO_PinInit(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PORT, BOARD_LED_GREEN_GPIO_PIN, \
&(gpio_pin_config_t){kGPIO_DigitalOutput, (output)}) /*!< Enable target LED_GREEN */
#define LED_GREEN_ON() \
GPIO_PortSet(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PORT, \
1U << BOARD_LED_GREEN_GPIO_PIN) /*!< Turn on target LED_GREEN */
#define LED_GREEN_OFF() \
GPIO_PortClear(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PORT, \
1U << BOARD_LED_GREEN_GPIO_PIN) /*!< Turn off target LED_GREEN */
#define LED_GREEN_TOGGLE() \
GPIO_PortToggle(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PORT, \
1U << BOARD_LED_GREEN_GPIO_PIN) /*!< Toggle on target LED_GREEN */
#define LED_BLUE_INIT(output) \
GPIO_PinInit(BOARD_LED_BLUE_GPIO, BOARD_LED_BLUE_GPIO_PORT, BOARD_LED_BLUE_GPIO_PIN, \
&(gpio_pin_config_t){kGPIO_DigitalOutput, (output)}) /*!< Enable target LED_BLUE */
#define LED_BLUE_ON() \
GPIO_PortSet(BOARD_LED_BLUE_GPIO, BOARD_LED_BLUE_GPIO_PORT, \
1U << BOARD_LED_BLUE_GPIO_PIN) /*!< Turn on target LED_BLUE */
#define LED_BLUE_OFF() \
GPIO_PortClear(BOARD_LED_BLUE_GPIO, BOARD_LED_BLUE_GPIO_PORT, \
1U << BOARD_LED_BLUE_GPIO_PIN) /*!< Turn off target LED_BLUE */
#define LED_BLUE_TOGGLE() \
GPIO_PortToggle(BOARD_LED_BLUE_GPIO, BOARD_LED_BLUE_GPIO_PORT, \
1U << BOARD_LED_BLUE_GPIO_PIN) /*!< Toggle on target LED_BLUE */
/* Board SW PIN */
#ifndef BOARD_SW1_GPIO
#define BOARD_SW1_GPIO GPIO
#endif
#define BOARD_SW1_GPIO_PORT 0U
#ifndef BOARD_SW1_GPIO_PIN
#define BOARD_SW1_GPIO_PIN 25U
#endif
#ifndef BOARD_SW2_GPIO
#define BOARD_SW2_GPIO GPIO
#endif
#define BOARD_SW2_GPIO_PORT 0U
#ifndef BOARD_SW2_GPIO_PIN
#define BOARD_SW2_GPIO_PIN 10U
#endif
/* USB PHY condfiguration */
#define BOARD_USB_PHY_D_CAL (0x0CU)
#define BOARD_USB_PHY_TXCAL45DP (0x06U)
#define BOARD_USB_PHY_TXCAL45DM (0x06U)
#define BOARD_FLASH_SIZE (0x4000000U)
/* SSD1963 (TFT_PROTO_5) panel. */
/* RST pin. */
#define BOARD_SSD1963_RST_PORT 5
#define BOARD_SSD1963_RST_PIN 0
/* CS pin. */
#define BOARD_SSD1963_CS_PORT 5
#define BOARD_SSD1963_CS_PIN 1
/* D/C pin, also named RS pin. */
#define BOARD_SSD1963_RS_PORT 4
#define BOARD_SSD1963_RS_PIN 31
/* Touch panel. */
#define BOARD_SSD1963_TOUCH_I2C_BASEADDR I2C4
#define BOARD_SSD1963_TOUCH_I2C_CLOCK_FREQ CLOCK_GetFlexcommClkFreq(4)
/* MIPI panel. */
/* RST pin. */
#define BOARD_MIPI_RST_PORT 3
#define BOARD_MIPI_RST_PIN 21
/* POWER pin .*/
#define BOARD_MIPI_POWER_PORT 3
#define BOARD_MIPI_POWER_PIN 15
/* Backlight pin. */
#define BOARD_MIPI_BL_PORT 0
#define BOARD_MIPI_BL_PIN 12
/* TE pin. */
#define BOARD_MIPI_TE_PORT 3
#define BOARD_MIPI_TE_PIN 18
/* Touch panel. */
#define BOARD_MIPI_PANEL_TOUCH_I2C_BASEADDR I2C4
#define BOARD_MIPI_PANEL_TOUCH_I2C_CLOCK_FREQ CLOCK_GetFlexcommClkFreq(4)
#define BOARD_MIPI_PANEL_TOUCH_RST_PORT 4
#define BOARD_MIPI_PANEL_TOUCH_RST_PIN 4
#define BOARD_MIPI_PANEL_TOUCH_INT_PORT 3
#define BOARD_MIPI_PANEL_TOUCH_INT_PIN 19
#define BOARD_BT_UART_INSTANCE 12
#define BOARD_BT_UART_BAUDRATE 3000000
#define BOARD_BT_UART_CLK_FREQ CLOCK_GetFlexcommClkFreq(12U)
#define BOARD_BT_UART_FRG_CLK \
(&(const clock_frg_clk_config_t){12, kCLOCK_FrgMainClk, 255, 12}) /*!< Select FRG0 mux as frg_pll */
#define BOARD_BT_UART_CLK_ATTACH kFRG_to_FLEXCOMM12
#define BOARD_BT_UART_RST kFC12_RST_SHIFT_RSTn
#define BOARD_BT_UART_IRQ FLEXCOMM12_IRQn
#define BOARD_BT_UART_IRQ_HANDLER FLEXCOMM12_IRQHandler
#define BOARD_BT_UART_CLKSRC kCLOCK_Flexcomm12
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
/*******************************************************************************
* API
******************************************************************************/
void BOARD_InitDebugConsole(void);
status_t BOARD_InitPsRam(void);
void BOARD_FlexspiClockSafeConfig(void);
AT_QUICKACCESS_SECTION_CODE(void BOARD_SetFlexspiClock(FLEXSPI_Type *base, uint32_t src, uint32_t divider));
AT_QUICKACCESS_SECTION_CODE(void BOARD_DeinitFlash(FLEXSPI_Type *base));
AT_QUICKACCESS_SECTION_CODE(void BOARD_InitFlash(FLEXSPI_Type *base));
#if defined(SDK_I2C_BASED_COMPONENT_USED) && SDK_I2C_BASED_COMPONENT_USED
void BOARD_I2C_Init(I2C_Type *base, uint32_t clkSrc_Hz);
status_t BOARD_I2C_Send(I2C_Type *base,
uint8_t deviceAddress,
uint32_t subAddress,
uint8_t subaddressSize,
uint8_t *txBuff,
uint8_t txBuffSize);
status_t BOARD_I2C_Receive(I2C_Type *base,
uint8_t deviceAddress,
uint32_t subAddress,
uint8_t subaddressSize,
uint8_t *rxBuff,
uint8_t rxBuffSize);
void BOARD_PMIC_I2C_Init(void);
status_t BOARD_PMIC_I2C_Send(
uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, const uint8_t *txBuff, uint8_t txBuffSize);
status_t BOARD_PMIC_I2C_Receive(
uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, uint8_t *rxBuff, uint8_t rxBuffSize);
void BOARD_MIPIPanelTouch_I2C_Init(void);
status_t BOARD_MIPIPanelTouch_I2C_Send(
uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, const uint8_t *txBuff, uint8_t txBuffSize);
status_t BOARD_MIPIPanelTouch_I2C_Receive(
uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, uint8_t *rxBuff, uint8_t rxBuffSize);
void BOARD_Accel_I2C_Init(void);
status_t BOARD_Accel_I2C_Send(uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, uint32_t txBuff);
status_t BOARD_Accel_I2C_Receive(
uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, uint8_t *rxBuff, uint8_t rxBuffSize);
#endif /* SDK_I2C_BASED_COMPONENT_USED */
#if defined BOARD_USE_CODEC
void BOARD_I3C_Init(I3C_Type *base, uint32_t clkSrc_Hz);
status_t BOARD_I3C_Send(I3C_Type *base,
uint8_t deviceAddress,
uint32_t subAddress,
uint8_t subaddressSize,
uint8_t *txBuff,
uint8_t txBuffSize);
status_t BOARD_I3C_Receive(I3C_Type *base,
uint8_t deviceAddress,
uint32_t subAddress,
uint8_t subaddressSize,
uint8_t *rxBuff,
uint8_t rxBuffSize);
void BOARD_Codec_I2C_Init(void);
status_t BOARD_Codec_I2C_Send(
uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, const uint8_t *txBuff, uint8_t txBuffSize);
status_t BOARD_Codec_I2C_Receive(
uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, uint8_t *rxBuff, uint8_t rxBuffSize);
#endif
#if defined(__cplusplus)
}
#endif /* __cplusplus */
#endif /* _BOARD_H_ */

View file

@ -0,0 +1,246 @@
/*
* Copyright 2019-2020 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/***********************************************************************************************************************
* This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file
* will be overwritten if the respective MCUXpresso Config Tools is used to update this file.
**********************************************************************************************************************/
/*
* How to set up clock using clock driver functions:
*
* 1. Setup clock sources.
*
* 2. Set up all selectors to provide selected clocks.
*
* 3. Set up all dividers.
*/
/* clang-format off */
/* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
!!GlobalInfo
product: Clocks v7.0
processor: MIMXRT595S
package_id: MIMXRT595SFFOC
mcu_data: ksdk2_0
processor_version: 0.8.1
board: MIMXRT595-EVK
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/
/* clang-format on */
#include "fsl_power.h"
#include "fsl_clock.h"
#include "clock_config.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
/* System clock frequency. */
extern uint32_t SystemCoreClock;
/*FUNCTION**********************************************************************
*
* Function Name : BOARD_FlexspiClockSafeConfig
* Description : FLEXSPI clock source safe configuration weak function.
* Called before clock source(Such as PLL, Main clock) configuration.
* Note : Users need override this function to change FLEXSPI clock source to stable source when executing
* code on FLEXSPI memory(XIP). If XIP, the function should runs in RAM and move the FLEXSPI clock
*source to an stable clock to avoid instruction/data fetch issue during clock updating.
*END**************************************************************************/
__attribute__((weak)) void BOARD_FlexspiClockSafeConfig(void)
{
}
/*FUNCTION**********************************************************************
*
* Function Name : BOARD_SetFlexspiClock
* Description : This function should be overridden if executing code on FLEXSPI memory(XIP).
* To Change FLEXSPI clock, should move to run from RAM and then configure FLEXSPI clock source.
* After the clock is changed and stable, move back to run on FLEXSPI.
* Param base : FLEXSPI peripheral base address.
* Param src : FLEXSPI clock source.
* Param divider : FLEXSPI clock divider.
*END**************************************************************************/
__attribute__((weak)) void BOARD_SetFlexspiClock(FLEXSPI_Type *base, uint32_t src, uint32_t divider)
{
if (FLEXSPI0 == base)
{
CLKCTL0->FLEXSPI0FCLKSEL = CLKCTL0_FLEXSPI0FCLKSEL_SEL(src);
CLKCTL0->FLEXSPI0FCLKDIV |= CLKCTL0_FLEXSPI0FCLKDIV_RESET_MASK; /* Reset the divider counter */
CLKCTL0->FLEXSPI0FCLKDIV = CLKCTL0_FLEXSPI0FCLKDIV_DIV(divider - 1);
while ((CLKCTL0->FLEXSPI0FCLKDIV) & CLKCTL0_FLEXSPI0FCLKDIV_REQFLAG_MASK)
{
}
}
else if (FLEXSPI1 == base)
{
CLKCTL0->FLEXSPI1FCLKSEL = CLKCTL0_FLEXSPI1FCLKSEL_SEL(src);
CLKCTL0->FLEXSPI1FCLKDIV |= CLKCTL0_FLEXSPI1FCLKDIV_RESET_MASK; /* Reset the divider counter */
CLKCTL0->FLEXSPI1FCLKDIV = CLKCTL0_FLEXSPI1FCLKDIV_DIV(divider - 1);
while ((CLKCTL0->FLEXSPI1FCLKDIV) & CLKCTL0_FLEXSPI1FCLKDIV_REQFLAG_MASK)
{
}
}
else
{
return;
}
}
/*******************************************************************************
************************ BOARD_InitBootClocks function ************************
******************************************************************************/
void BOARD_InitBootClocks(void)
{
BOARD_BootClockRUN();
}
/*******************************************************************************
********************** Configuration BOARD_BootClockRUN ***********************
******************************************************************************/
/* clang-format off */
/* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
!!Configuration
name: BOARD_BootClockRUN
called_from_default_init: true
outputs:
- {id: CLKOUT_clock.outFreq, value: 960 kHz}
- {id: FLEXSPI0_clock.outFreq, value: 198 MHz}
- {id: LPOSC1M_clock.outFreq, value: 1 MHz}
- {id: OSTIMER_clock.outFreq, value: 1 MHz}
- {id: SYSTICK_clock.outFreq, value: 198 MHz}
- {id: System_clock.outFreq, value: 198 MHz}
- {id: TRACE_clock.outFreq, value: 198 MHz}
- {id: USBPHY_clock.outFreq, value: 99 MHz}
- {id: WAKE_32K_clock.outFreq, value: 976.5625 Hz}
settings:
- {id: AUDIOPLL0_PFD0_CLK_GATE, value: Enabled}
- {id: CLKCTL.A32KHZWAKECLKDIV.scale, value: '32', locked: true}
- {id: CLKCTL.AUDIOPLL0CLKSEL.sel, value: CLKCTL.OSC_CLKSEL}
- {id: CLKCTL.AUDIOPLL0_PFD0_DIV.scale, value: '26', locked: true}
- {id: CLKCTL.AUDIOPLLCLKDIV.scale, value: '15', locked: true}
- {id: CLKCTL.AUDIO_PLL0_PFD0_MUL.scale, value: '18', locked: true}
- {id: CLKCTL.CLKOUTFCLKDIV.scale, value: '100', locked: true}
- {id: CLKCTL.CLKOUTSEL0.sel, value: CLKCTL.FRO_DIV2_EN}
- {id: CLKCTL.CLKOUTSEL1.sel, value: CLKCTL.CLKOUTSEL0}
- {id: CLKCTL.DMIC0FCLKDIV.scale, value: '1', locked: true}
- {id: CLKCTL.DSPCPUCLKDIV.scale, value: '1', locked: true}
- {id: CLKCTL.FLEXSPI0FCLKDIV.scale, value: '2', locked: true}
- {id: CLKCTL.FLEXSPI0FCLKSEL.sel, value: CLKCTL.MAINCLKSELB}
- {id: CLKCTL.FRGPLLCLKDIV.scale, value: '11', locked: true}
- {id: CLKCTL.I3C01FCLKSDIV.scale, value: '1', locked: true}
- {id: CLKCTL.MAINCLKSELB.sel, value: CLKCTL.MAINPLLCLKDIV}
- {id: CLKCTL.PFC0DIV.scale, value: '2', locked: true}
- {id: CLKCTL.PFC1DIV.scale, value: '4', locked: true}
- {id: CLKCTL.PLL0.denom, value: '1', locked: true}
- {id: CLKCTL.PLL0.div, value: '22', locked: true}
- {id: CLKCTL.PLL0.num, value: '0'}
- {id: CLKCTL.PLL0_PFD0_DIV.scale, value: '24', locked: true}
- {id: CLKCTL.PLL0_PFD0_MUL.scale, value: '18', locked: true}
- {id: CLKCTL.PLL0_PFD2_DIV.scale, value: '24', locked: true}
- {id: CLKCTL.PLL0_PFD2_MUL.scale, value: '18', locked: true}
- {id: CLKCTL.PLL1.denom, value: '27000', locked: true}
- {id: CLKCTL.PLL1.div, value: '22', locked: true}
- {id: CLKCTL.PLL1.num, value: '5040', locked: true}
- {id: CLKCTL.SYSCPUAHBCLKDIV.scale, value: '2', locked: true}
- {id: CLKCTL.SYSPLL0CLKSEL.sel, value: CLKCTL.OSC_CLKSEL}
- {id: CLKCTL.SYSTICKFCLKDIV.scale, value: '2', locked: true}
- {id: CLKCTL.SYSTICKFCLKSEL.sel, value: CLKCTL.SYSTICKFCLKDIV}
- {id: FRO_DIV16_EN_CFG, value: Enabled}
- {id: FRO_DIV1_EN_CFG, value: Enabled}
- {id: FRO_DIV2_EN_CFG, value: Enabled}
- {id: FRO_DIV4_EN_CFG, value: Enabled}
- {id: FRO_DIV8_EN_CFG, value: Enabled}
- {id: PLL0_PFD0_CLK_GATE, value: Enabled}
- {id: PLL0_PFD2_CLK_GATE, value: Enabled}
- {id: SYSCTL_PDRUNCFG_AUDIOPLL_CFG, value: 'No'}
- {id: SYSCTL_PDRUNCFG_SYSPLL_CFG, value: 'No'}
- {id: SYSCTL_PDRUNCFG_SYSXTAL_CFG, value: Power_up}
- {id: XTAL_LP_Enable, value: LowPowerMode}
sources:
- {id: CLKCTL.XTAL.outFreq, value: 24 MHz, enabled: true}
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/
/* clang-format on */
/*******************************************************************************
* Variables for BOARD_BootClockRUN configuration
******************************************************************************/
const clock_sys_pll_config_t g_sysPllConfig_BOARD_BootClockRUN = {
.sys_pll_src = kCLOCK_SysPllXtalIn, /* OSC clock */
.numerator = 0, /* Numerator of the SYSPLL0 fractional loop divider is 0 */
.denominator = 1, /* Denominator of the SYSPLL0 fractional loop divider is 1 */
.sys_pll_mult = kCLOCK_SysPllMult22 /* Divide by 22 */
};
const clock_audio_pll_config_t g_audioPllConfig_BOARD_BootClockRUN = {
.audio_pll_src = kCLOCK_AudioPllXtalIn, /* OSC clock */
.numerator = 5040, /* Numerator of the Audio PLL fractional loop divider is 0 */
.denominator = 27000, /* Denominator of the Audio PLL fractional loop divider is 1 */
.audio_pll_mult = kCLOCK_AudioPllMult22 /* Divide by 22 */
};
/*******************************************************************************
* Code for BOARD_BootClockRUN configuration
******************************************************************************/
void BOARD_BootClockRUN(void)
{
/* Configure LPOSC 1M */
POWER_DisablePD(kPDRUNCFG_PD_LPOSC); /* Power on LPOSC (1MHz) */
CLOCK_EnableLpOscClk(); /* Wait until LPOSC stable */
/* Configure FRO clock source */
POWER_DisablePD(kPDRUNCFG_PD_FFRO); /* Power on FRO (192MHz or 96MHz) */
/* FRO_DIV1 is always enabled and used as Main clock during PLL update. */
CLOCK_EnableFroClk(kCLOCK_FroAllOutEn); /* Enable all FRO outputs */
/* Call function BOARD_FlexspiClockSafeConfig() to move FlexSPI clock to a stable clock source to avoid
instruction/data fetch issue when updating PLL and Main clock if XIP(execute code on FLEXSPI memory). */
BOARD_FlexspiClockSafeConfig();
/* Let CPU run on FRO with divider 2 for safe switching. */
CLOCK_SetClkDiv(kCLOCK_DivSysCpuAhbClk, 2);
CLOCK_AttachClk(kFRO_DIV1_to_MAIN_CLK);
/* Configure SYSOSC clock source. */
POWER_DisablePD(kPDRUNCFG_PD_SYSXTAL); /* Power on SYSXTAL */
POWER_UpdateOscSettlingTime(BOARD_SYSOSC_SETTLING_US); /* Updated XTAL oscillator settling time */
CLOCK_EnableSysOscClk(true, true, BOARD_SYSOSC_SETTLING_US); /* Enable system OSC */
CLOCK_SetXtalFreq(BOARD_XTAL_SYS_CLK_HZ); /* Sets external XTAL OSC freq */
/* Configure SysPLL0 clock source. */
CLOCK_InitSysPll(&g_sysPllConfig_BOARD_BootClockRUN);
CLOCK_InitSysPfd(kCLOCK_Pfd0, 24); /* Enable MAIN PLL clock */
CLOCK_InitSysPfd(kCLOCK_Pfd2, 24); /* Enable AUX0 PLL clock */
/* Configure Audio PLL clock source. */
CLOCK_InitAudioPll(&g_audioPllConfig_BOARD_BootClockRUN);
CLOCK_InitAudioPfd(kCLOCK_Pfd0, 26); /* Enable Audio PLL clock */
CLOCK_SetClkDiv(kCLOCK_DivSysCpuAhbClk, 2U); /* Set SYSCPUAHBCLKDIV divider to value 2 */
/* Set up clock selectors - Attach clocks to the peripheries. */
CLOCK_AttachClk(kMAIN_PLL_to_MAIN_CLK); /* Switch MAIN_CLK to MAIN_PLL */
CLOCK_AttachClk(kMAIN_CLK_DIV_to_SYSTICK_CLK); /* Switch SYSTICK_CLK to MAIN_CLK_DIV */
CLOCK_AttachClk(kFRO_DIV2_to_CLKOUT); /* Switch CLKOUT to FRO_DIV2 */
/* Set up dividers. */
CLOCK_SetClkDiv(kCLOCK_DivAudioPllClk, 15U); /* Set AUDIOPLLCLKDIV divider to value 15 */
CLOCK_SetClkDiv(kCLOCK_DivPLLFRGClk, 11U); /* Set FRGPLLCLKDIV divider to value 11 */
CLOCK_SetClkDiv(kCLOCK_DivSystickClk, 2U); /* Set SYSTICKFCLKDIV divider to value 2 */
CLOCK_SetClkDiv(kCLOCK_DivPfc0Clk, 2U); /* Set PFC0DIV divider to value 2 */
CLOCK_SetClkDiv(kCLOCK_DivPfc1Clk, 4U); /* Set PFC1DIV divider to value 4 */
CLOCK_SetClkDiv(kCLOCK_DivClockOut, 100U); /* Set CLKOUTFCLKDIV divider to value 100 */
/* Call function BOARD_SetFlexspiClock() to set user configured clock source/divider for FlexSPI. */
BOARD_SetFlexspiClock(FLEXSPI0, 0U, 2U);
/* Set SystemCoreClock variable. */
SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK;
/* Set main clock to FRO as deep sleep clock by default. */
POWER_SetDeepSleepClock(kDeepSleepClk_Fro);
}

View file

@ -0,0 +1,67 @@
/*
* Copyright 2019-2020 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/***********************************************************************************************************************
* This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file
* will be overwritten if the respective MCUXpresso Config Tools is used to update this file.
**********************************************************************************************************************/
#ifndef _CLOCK_CONFIG_H_
#define _CLOCK_CONFIG_H_
#include "fsl_common.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define BOARD_SYSOSC_SETTLING_US 220U /*!< Board System oscillator settling time in us */
#define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32K frequency in Hz */
#define BOARD_XTAL_SYS_CLK_HZ 24000000U /*!< Board xtal frequency in Hz */
/*******************************************************************************
************************ BOARD_InitBootClocks function ************************
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus*/
/*!
* @brief This function executes default configuration of clocks.
*
*/
void BOARD_InitBootClocks(void);
#if defined(__cplusplus)
}
#endif /* __cplusplus*/
/*******************************************************************************
********************** Configuration BOARD_BootClockRUN ***********************
******************************************************************************/
/*******************************************************************************
* Definitions for BOARD_BootClockRUN configuration
******************************************************************************/
#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 198000000U /*!< Core clock frequency: 198000000Hz */
/*******************************************************************************
* API for BOARD_BootClockRUN configuration
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus*/
/*!
* @brief This function executes configuration of clocks.
*
*/
void BOARD_BootClockRUN(void);
#if defined(__cplusplus)
}
#endif /* __cplusplus*/
#endif /* _CLOCK_CONFIG_H_ */

View file

@ -0,0 +1,108 @@
/*
* Copyright 2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/***********************************************************************************************************************
* This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file
* will be overwritten if the respective MCUXpresso Config Tools is used to update this file.
**********************************************************************************************************************/
/* clang-format off */
/*
* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
!!GlobalInfo
product: Pins v9.0
processor: MIMXRT595S
package_id: MIMXRT595SFFOC
mcu_data: ksdk2_0
processor_version: 0.9.0
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
*/
/* clang-format on */
#include "fsl_common.h"
#include "fsl_iopctl.h"
#include "pin_mux.h"
/* FUNCTION ************************************************************************************************************
*
* Function Name : BOARD_InitBootPins
* Description : Calls initialization functions.
*
* END ****************************************************************************************************************/
void BOARD_InitBootPins(void)
{
BOARD_InitPins();
}
/* clang-format off */
/*
* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
BOARD_InitPins:
- options: {callFromInitBoot: 'true', coreID: cm33, enableClock: 'true'}
- pin_list:
- {pin_num: H16, peripheral: FLEXCOMM0, signal: RXD_SDA_MOSI_DATA, pin_signal: PIO0_2/FC0_RXD_SDA_MOSI_DATA/CTIMER0_MAT2/I2S_BRIDGE_DATA_IN/SEC_PIO0_2, ibena: enabled}
- {pin_num: G16, peripheral: FLEXCOMM0, signal: TXD_SCL_MISO_WS, pin_signal: PIO0_1/FC0_TXD_SCL_MISO_WS/CTIMER0_MAT1/I2S_BRIDGE_WS_IN/SEC_PIO0_1}
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
*/
/* clang-format on */
/* FUNCTION ************************************************************************************************************
*
* Function Name : BOARD_InitPins
* Description : Configures pin routing and optionally pin electrical features.
*
* END ****************************************************************************************************************/
/* Function assigned for the Cortex-M33 */
void BOARD_InitPins(void)
{
const uint32_t port0_pin1_config = (/* Pin is configured as FC0_TXD_SCL_MISO_WS */
IOPCTL_PIO_FUNC1 |
/* Disable pull-up / pull-down function */
IOPCTL_PIO_PUPD_DI |
/* Enable pull-down function */
IOPCTL_PIO_PULLDOWN_EN |
/* Disable input buffer function */
IOPCTL_PIO_INBUF_DI |
/* Normal mode */
IOPCTL_PIO_SLEW_RATE_NORMAL |
/* Normal drive */
IOPCTL_PIO_FULLDRIVE_DI |
/* Analog mux is disabled */
IOPCTL_PIO_ANAMUX_DI |
/* Pseudo Output Drain is disabled */
IOPCTL_PIO_PSEDRAIN_DI |
/* Input function is not inverted */
IOPCTL_PIO_INV_DI);
/* PORT0 PIN1 (coords: G16) is configured as FC0_TXD_SCL_MISO_WS */
IOPCTL_PinMuxSet(IOPCTL, 0U, 1U, port0_pin1_config);
const uint32_t port0_pin2_config = (/* Pin is configured as FC0_RXD_SDA_MOSI_DATA */
IOPCTL_PIO_FUNC1 |
/* Disable pull-up / pull-down function */
IOPCTL_PIO_PUPD_DI |
/* Enable pull-down function */
IOPCTL_PIO_PULLDOWN_EN |
/* Enables input buffer function */
IOPCTL_PIO_INBUF_EN |
/* Normal mode */
IOPCTL_PIO_SLEW_RATE_NORMAL |
/* Normal drive */
IOPCTL_PIO_FULLDRIVE_DI |
/* Analog mux is disabled */
IOPCTL_PIO_ANAMUX_DI |
/* Pseudo Output Drain is disabled */
IOPCTL_PIO_PSEDRAIN_DI |
/* Input function is not inverted */
IOPCTL_PIO_INV_DI);
/* PORT0 PIN2 (coords: H16) is configured as FC0_RXD_SDA_MOSI_DATA */
IOPCTL_PinMuxSet(IOPCTL, 0U, 2U, port0_pin2_config);
}
/***********************************************************************************************************************
* EOF
**********************************************************************************************************************/

View file

@ -0,0 +1,64 @@
/*
* Copyright 2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/***********************************************************************************************************************
* This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file
* will be overwritten if the respective MCUXpresso Config Tools is used to update this file.
**********************************************************************************************************************/
#ifndef _PIN_MUX_H_
#define _PIN_MUX_H_
/*!
* @addtogroup pin_mux
* @{
*/
/***********************************************************************************************************************
* API
**********************************************************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @brief Calls initialization functions.
*
*/
void BOARD_InitBootPins(void);
#define IOPCTL_PIO_ANAMUX_DI 0x00u /*!<@brief Analog mux is disabled */
#define IOPCTL_PIO_FULLDRIVE_DI 0x00u /*!<@brief Normal drive */
#define IOPCTL_PIO_FUNC1 0x01u /*!<@brief Selects pin function 1 */
#define IOPCTL_PIO_INBUF_DI 0x00u /*!<@brief Disable input buffer function */
#define IOPCTL_PIO_INBUF_EN 0x40u /*!<@brief Enables input buffer function */
#define IOPCTL_PIO_INV_DI 0x00u /*!<@brief Input function is not inverted */
#define IOPCTL_PIO_PSEDRAIN_DI 0x00u /*!<@brief Pseudo Output Drain is disabled */
#define IOPCTL_PIO_PULLDOWN_EN 0x00u /*!<@brief Enable pull-down function */
#define IOPCTL_PIO_PUPD_DI 0x00u /*!<@brief Disable pull-up / pull-down function */
#define IOPCTL_PIO_SLEW_RATE_NORMAL 0x00u /*!<@brief Normal mode */
/*!
* @brief Configures pin routing and optionally pin electrical features.
*
*/
void BOARD_InitPins(void); /* Function assigned for the Cortex-M33 */
#if defined(__cplusplus)
}
#endif
/*!
* @}
*/
#endif /* _PIN_MUX_H_ */
/***********************************************************************************************************************
* EOF
**********************************************************************************************************************/

View file

@ -0,0 +1,493 @@
/*
* Copyright 2018-2019 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*! *********************************************************************************
*************************************************************************************
* Include
*************************************************************************************
********************************************************************************** */
#include "fsl_component_generic_list.h"
#if defined(OSA_USED)
#include "fsl_os_abstraction.h"
#if (defined(USE_RTOS) && (USE_RTOS > 0U))
#define LIST_ENTER_CRITICAL() \
OSA_SR_ALLOC(); \
OSA_ENTER_CRITICAL()
#define LIST_EXIT_CRITICAL() OSA_EXIT_CRITICAL()
#else
#define LIST_ENTER_CRITICAL()
#define LIST_EXIT_CRITICAL()
#endif
#else
#define LIST_ENTER_CRITICAL() uint32_t regPrimask = DisableGlobalIRQ();
#define LIST_EXIT_CRITICAL() EnableGlobalIRQ(regPrimask);
#endif
static list_status_t LIST_Error_Check(list_handle_t list, list_element_handle_t newElement)
{
list_status_t listStatus = kLIST_Ok;
#if (defined(GENERIC_LIST_DUPLICATED_CHECKING) && (GENERIC_LIST_DUPLICATED_CHECKING > 0U))
list_element_handle_t element = list->head;
#endif
if ((list->max != 0U) && (list->max == list->size))
{
listStatus = kLIST_Full; /*List is full*/
}
#if (defined(GENERIC_LIST_DUPLICATED_CHECKING) && (GENERIC_LIST_DUPLICATED_CHECKING > 0U))
else
{
while (element != NULL) /*Scan list*/
{
/* Determine if element is duplicated */
if (element == newElement)
{
listStatus = kLIST_DuplicateError;
break;
}
element = element->next;
}
}
#endif
return listStatus;
}
/*! *********************************************************************************
*************************************************************************************
* Public functions
*************************************************************************************
********************************************************************************** */
/*! *********************************************************************************
* \brief Initialises the list descriptor.
*
* \param[in] list - LIST_ handle to init.
* max - Maximum number of elements in list. 0 for unlimited.
*
* \return void.
*
* \pre
*
* \post
*
* \remarks
*
********************************************************************************** */
void LIST_Init(list_handle_t list, uint32_t max)
{
list->head = NULL;
list->tail = NULL;
list->max = (uint16_t)max;
list->size = 0;
}
/*! *********************************************************************************
* \brief Gets the list that contains the given element.
*
* \param[in] element - Handle of the element.
*
* \return NULL if element is orphan.
* Handle of the list the element is inserted into.
*
* \pre
*
* \post
*
* \remarks
*
********************************************************************************** */
list_handle_t LIST_GetList(list_element_handle_t element)
{
return element->list;
}
/*! *********************************************************************************
* \brief Links element to the tail of the list.
*
* \param[in] list - ID of list to insert into.
* element - element to add
*
* \return kLIST_Full if list is full.
* kLIST_Ok if insertion was successful.
*
* \pre
*
* \post
*
* \remarks
*
********************************************************************************** */
list_status_t LIST_AddTail(list_handle_t list, list_element_handle_t element)
{
LIST_ENTER_CRITICAL();
list_status_t listStatus = kLIST_Ok;
listStatus = LIST_Error_Check(list, element);
if (listStatus == kLIST_Ok) /* Avoiding list status error */
{
if (list->size == 0U)
{
list->head = element;
}
else
{
list->tail->next = element;
}
#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
#else
element->prev = list->tail;
#endif
element->list = list;
element->next = NULL;
list->tail = element;
list->size++;
}
LIST_EXIT_CRITICAL();
return listStatus;
}
/*! *********************************************************************************
* \brief Links element to the head of the list.
*
* \param[in] list - ID of list to insert into.
* element - element to add
*
* \return kLIST_Full if list is full.
* kLIST_Ok if insertion was successful.
*
* \pre
*
* \post
*
* \remarks
*
********************************************************************************** */
list_status_t LIST_AddHead(list_handle_t list, list_element_handle_t element)
{
LIST_ENTER_CRITICAL();
list_status_t listStatus = kLIST_Ok;
listStatus = LIST_Error_Check(list, element);
if (listStatus == kLIST_Ok) /* Avoiding list status error */
{
/* Links element to the head of the list */
if (list->size == 0U)
{
list->tail = element;
}
#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
#else
else
{
list->head->prev = element;
}
element->prev = NULL;
#endif
element->list = list;
element->next = list->head;
list->head = element;
list->size++;
}
LIST_EXIT_CRITICAL();
return listStatus;
}
/*! *********************************************************************************
* \brief Unlinks element from the head of the list.
*
* \param[in] list - ID of list to remove from.
*
* \return NULL if list is empty.
* ID of removed element(pointer) if removal was successful.
*
* \pre
*
* \post
*
* \remarks
*
********************************************************************************** */
list_element_handle_t LIST_RemoveHead(list_handle_t list)
{
list_element_handle_t element;
LIST_ENTER_CRITICAL();
if ((NULL == list) || (list->size == 0U))
{
element = NULL; /*LIST_ is empty*/
}
else
{
element = list->head;
list->size--;
if (list->size == 0U)
{
list->tail = NULL;
}
#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
#else
else
{
element->next->prev = NULL;
}
#endif
element->list = NULL;
list->head = element->next; /*Is NULL if element is head*/
}
LIST_EXIT_CRITICAL();
return element;
}
/*! *********************************************************************************
* \brief Gets head element ID.
*
* \param[in] list - ID of list.
*
* \return NULL if list is empty.
* ID of head element if list is not empty.
*
* \pre
*
* \post
*
* \remarks
*
********************************************************************************** */
list_element_handle_t LIST_GetHead(list_handle_t list)
{
return list->head;
}
/*! *********************************************************************************
* \brief Gets next element ID.
*
* \param[in] element - ID of the element.
*
* \return NULL if element is tail.
* ID of next element if exists.
*
* \pre
*
* \post
*
* \remarks
*
********************************************************************************** */
list_element_handle_t LIST_GetNext(list_element_handle_t element)
{
return element->next;
}
/*! *********************************************************************************
* \brief Gets previous element ID.
*
* \param[in] element - ID of the element.
*
* \return NULL if element is head.
* ID of previous element if exists.
*
* \pre
*
* \post
*
* \remarks
*
********************************************************************************** */
list_element_handle_t LIST_GetPrev(list_element_handle_t element)
{
#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
return NULL;
#else
return element->prev;
#endif
}
/*! *********************************************************************************
* \brief Unlinks an element from its list.
*
* \param[in] element - ID of the element to remove.
*
* \return kLIST_OrphanElement if element is not part of any list.
* kLIST_Ok if removal was successful.
*
* \pre
*
* \post
*
* \remarks
*
********************************************************************************** */
list_status_t LIST_RemoveElement(list_element_handle_t element)
{
list_status_t listStatus = kLIST_Ok;
LIST_ENTER_CRITICAL();
if (element->list == NULL)
{
listStatus = kLIST_OrphanElement; /*Element was previusly removed or never added*/
}
else
{
#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
list_element_handle_t element_list = element->list->head;
while (NULL != element_list)
{
if (element->list->head == element)
{
element->list->head = element_list->next;
break;
}
if (element_list->next == element)
{
element_list->next = element->next;
break;
}
element_list = element_list->next;
}
#else
if (element->prev == NULL) /*Element is head or solo*/
{
element->list->head = element->next; /*is null if solo*/
}
if (element->next == NULL) /*Element is tail or solo*/
{
element->list->tail = element->prev; /*is null if solo*/
}
if (element->prev != NULL) /*Element is not head*/
{
element->prev->next = element->next;
}
if (element->next != NULL) /*Element is not tail*/
{
element->next->prev = element->prev;
}
#endif
element->list->size--;
element->list = NULL;
}
LIST_EXIT_CRITICAL();
return listStatus;
}
/*! *********************************************************************************
* \brief Links an element in the previous position relative to a given member
* of a list.
*
* \param[in] element - ID of a member of a list.
* newElement - new element to insert before the given member.
*
* \return kLIST_OrphanElement if element is not part of any list.
* kLIST_Full if list is full.
* kLIST_Ok if insertion was successful.
*
* \pre
*
* \post
*
* \remarks
*
********************************************************************************** */
list_status_t LIST_AddPrevElement(list_element_handle_t element, list_element_handle_t newElement)
{
list_status_t listStatus = kLIST_Ok;
LIST_ENTER_CRITICAL();
if (element->list == NULL)
{
listStatus = kLIST_OrphanElement; /*Element was previusly removed or never added*/
}
else
{
listStatus = LIST_Error_Check(element->list, newElement);
if (listStatus == kLIST_Ok)
{
#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
list_element_handle_t element_list = element->list->head;
while (NULL != element_list)
{
if ((element_list->next == element) || (element_list == element))
{
if (element_list == element)
{
element->list->head = newElement;
}
else
{
element_list->next = newElement;
}
newElement->list = element->list;
newElement->next = element;
element->list->size++;
break;
}
element_list = element_list->next;
}
#else
if (element->prev == NULL) /*Element is list head*/
{
element->list->head = newElement;
}
else
{
element->prev->next = newElement;
}
newElement->list = element->list;
element->list->size++;
newElement->next = element;
newElement->prev = element->prev;
element->prev = newElement;
#endif
}
}
LIST_EXIT_CRITICAL();
return listStatus;
}
/*! *********************************************************************************
* \brief Gets the current size of a list.
*
* \param[in] list - ID of the list.
*
* \return Current size of the list.
*
* \pre
*
* \post
*
* \remarks
*
********************************************************************************** */
uint32_t LIST_GetSize(list_handle_t list)
{
return list->size;
}
/*! *********************************************************************************
* \brief Gets the number of free places in the list.
*
* \param[in] list - ID of the list.
*
* \return Available size of the list.
*
* \pre
*
* \post
*
* \remarks
*
********************************************************************************** */
uint32_t LIST_GetAvailableSize(list_handle_t list)
{
return ((uint32_t)list->max - (uint32_t)list->size); /*Gets the number of free places in the list*/
}

View file

@ -0,0 +1,201 @@
/*
* Copyright 2018-2020 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _GENERIC_LIST_H_
#define _GENERIC_LIST_H_
#include "fsl_common.h"
/*!
* @addtogroup GenericList
* @{
*/
/**********************************************************************************
* Include
***********************************************************************************/
/**********************************************************************************
* Public macro definitions
***********************************************************************************/
/*! @brief Definition to determine whether use list light. */
#ifndef GENERIC_LIST_LIGHT
#define GENERIC_LIST_LIGHT (1)
#endif
/*! @brief Definition to determine whether enable list duplicated checking. */
#ifndef GENERIC_LIST_DUPLICATED_CHECKING
#define GENERIC_LIST_DUPLICATED_CHECKING (0)
#endif
/**********************************************************************************
* Public type definitions
***********************************************************************************/
/*! @brief The list status */
typedef enum _list_status
{
kLIST_Ok = kStatus_Success, /*!< Success */
kLIST_DuplicateError = MAKE_STATUS(kStatusGroup_LIST, 1), /*!< Duplicate Error */
kLIST_Full = MAKE_STATUS(kStatusGroup_LIST, 2), /*!< FULL */
kLIST_Empty = MAKE_STATUS(kStatusGroup_LIST, 3), /*!< Empty */
kLIST_OrphanElement = MAKE_STATUS(kStatusGroup_LIST, 4), /*!< Orphan Element */
kLIST_NotSupport = MAKE_STATUS(kStatusGroup_LIST, 5), /*!< Not Support */
} list_status_t;
/*! @brief The list structure*/
typedef struct list_label
{
struct list_element_tag *head; /*!< list head */
struct list_element_tag *tail; /*!< list tail */
uint16_t size; /*!< list size */
uint16_t max; /*!< list max number of elements */
} list_label_t, *list_handle_t;
#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
/*! @brief The list element*/
typedef struct list_element_tag
{
struct list_element_tag *next; /*!< next list element */
struct list_label *list; /*!< pointer to the list */
} list_element_t, *list_element_handle_t;
#else
/*! @brief The list element*/
typedef struct list_element_tag
{
struct list_element_tag *next; /*!< next list element */
struct list_element_tag *prev; /*!< previous list element */
struct list_label *list; /*!< pointer to the list */
} list_element_t, *list_element_handle_t;
#endif
/**********************************************************************************
* Public prototypes
***********************************************************************************/
/**********************************************************************************
* API
**********************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* _cplusplus */
/*!
* @brief Initialize the list.
*
* This function initialize the list.
*
* @param list - List handle to initialize.
* @param max - Maximum number of elements in list. 0 for unlimited.
*/
void LIST_Init(list_handle_t list, uint32_t max);
/*!
* @brief Gets the list that contains the given element.
*
*
* @param element - Handle of the element.
* @retval NULL if element is orphan, Handle of the list the element is inserted into.
*/
list_handle_t LIST_GetList(list_element_handle_t element);
/*!
* @brief Links element to the head of the list.
*
* @param list - Handle of the list.
* @param element - Handle of the element.
* @retval kLIST_Full if list is full, kLIST_Ok if insertion was successful.
*/
list_status_t LIST_AddHead(list_handle_t list, list_element_handle_t element);
/*!
* @brief Links element to the tail of the list.
*
* @param list - Handle of the list.
* @param element - Handle of the element.
* @retval kLIST_Full if list is full, kLIST_Ok if insertion was successful.
*/
list_status_t LIST_AddTail(list_handle_t list, list_element_handle_t element);
/*!
* @brief Unlinks element from the head of the list.
*
* @param list - Handle of the list.
*
* @retval NULL if list is empty, handle of removed element(pointer) if removal was successful.
*/
list_element_handle_t LIST_RemoveHead(list_handle_t list);
/*!
* @brief Gets head element handle.
*
* @param list - Handle of the list.
*
* @retval NULL if list is empty, handle of removed element(pointer) if removal was successful.
*/
list_element_handle_t LIST_GetHead(list_handle_t list);
/*!
* @brief Gets next element handle for given element handle.
*
* @param element - Handle of the element.
*
* @retval NULL if list is empty, handle of removed element(pointer) if removal was successful.
*/
list_element_handle_t LIST_GetNext(list_element_handle_t element);
/*!
* @brief Gets previous element handle for given element handle.
*
* @param element - Handle of the element.
*
* @retval NULL if list is empty, handle of removed element(pointer) if removal was successful.
*/
list_element_handle_t LIST_GetPrev(list_element_handle_t element);
/*!
* @brief Unlinks an element from its list.
*
* @param element - Handle of the element.
*
* @retval kLIST_OrphanElement if element is not part of any list.
* @retval kLIST_Ok if removal was successful.
*/
list_status_t LIST_RemoveElement(list_element_handle_t element);
/*!
* @brief Links an element in the previous position relative to a given member of a list.
*
* @param element - Handle of the element.
* @param newElement - New element to insert before the given member.
*
* @retval kLIST_OrphanElement if element is not part of any list.
* @retval kLIST_Ok if removal was successful.
*/
list_status_t LIST_AddPrevElement(list_element_handle_t element, list_element_handle_t newElement);
/*!
* @brief Gets the current size of a list.
*
* @param list - Handle of the list.
*
* @retval Current size of the list.
*/
uint32_t LIST_GetSize(list_handle_t list);
/*!
* @brief Gets the number of free places in the list.
*
* @param list - Handle of the list.
*
* @retval Available size of the list.
*/
uint32_t LIST_GetAvailableSize(list_handle_t list);
/* @} */
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /*_GENERIC_LIST_H_*/

View file

@ -0,0 +1,906 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2020 NXP
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_OS_ABSTRACTION_H_
#define _FSL_OS_ABSTRACTION_H_
#include "fsl_common.h"
#include "fsl_os_abstraction_config.h"
#include "fsl_component_generic_list.h"
/*!
* @addtogroup osa_adapter
* @{
*/
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief Type for the Task Priority*/
typedef uint16_t osa_task_priority_t;
/*! @brief Type for a task handler */
typedef void *osa_task_handle_t;
/*! @brief Type for the parameter to be passed to the task at its creation */
typedef void *osa_task_param_t;
/*! @brief Type for task pointer. Task prototype declaration */
typedef void (*osa_task_ptr_t)(osa_task_param_t task_param);
/*! @brief Type for the semaphore handler */
typedef void *osa_semaphore_handle_t;
/*! @brief Type for the mutex handler */
typedef void *osa_mutex_handle_t;
/*! @brief Type for the event handler */
typedef void *osa_event_handle_t;
/*! @brief Type for an event flags group, bit 32 is reserved. */
typedef uint32_t osa_event_flags_t;
/*! @brief Message definition. */
typedef void *osa_msg_handle_t;
/*! @brief Type for the message queue handler */
typedef void *osa_msgq_handle_t;
/*! @brief Type for the Timer handler */
typedef void *osa_timer_handle_t;
/*! @brief Type for the Timer callback function pointer. */
typedef void (*osa_timer_fct_ptr_t)(void const *argument);
/*! @brief Thread Definition structure contains startup information of a thread.*/
typedef struct osa_task_def_tag
{
osa_task_ptr_t pthread; /*!< start address of thread function*/
uint32_t tpriority; /*!< initial thread priority*/
uint32_t instances; /*!< maximum number of instances of that thread function*/
uint32_t stacksize; /*!< stack size requirements in bytes; 0 is default stack size*/
uint32_t *tstack; /*!< stack pointer*/
void *tlink; /*!< link pointer*/
uint8_t *tname; /*!< name pointer*/
uint8_t useFloat; /*!< is use float*/
} osa_task_def_t;
/*! @brief Thread Link Definition structure .*/
typedef struct osa_thread_link_tag
{
uint8_t link[12]; /*!< link*/
osa_task_handle_t osThreadId; /*!< thread id*/
osa_task_def_t *osThreadDefHandle; /*!< pointer of thread define handle*/
uint32_t *osThreadStackHandle; /*!< pointer of thread stack handle*/
} osa_thread_link_t, *osa_thread_link_handle_t;
/*! @brief Definition structure contains timer parameters.*/
typedef struct osa_time_def_tag
{
osa_timer_fct_ptr_t pfCallback; /* < start address of a timer function */
void *argument; /* < argument of a timer function */
} osa_time_def_t;
/*! @brief Type for the timer definition*/
typedef enum _osa_timer
{
KOSA_TimerOnce = 0, /*!< one-shot timer*/
KOSA_TimerPeriodic = 1 /*!< repeating timer*/
} osa_timer_t;
/*! @brief Defines the return status of OSA's functions */
typedef enum _osa_status
{
KOSA_StatusSuccess = kStatus_Success, /*!< Success */
KOSA_StatusError = MAKE_STATUS(kStatusGroup_OSA, 1), /*!< Failed */
KOSA_StatusTimeout = MAKE_STATUS(kStatusGroup_OSA, 2), /*!< Timeout occurs while waiting */
KOSA_StatusIdle = MAKE_STATUS(kStatusGroup_OSA, 3), /*!< Used for bare metal only, the wait object is not ready
and timeout still not occur */
} osa_status_t;
#ifdef USE_RTOS
#undef USE_RTOS
#endif
#if defined(SDK_OS_MQX)
#define USE_RTOS (1)
#elif defined(SDK_OS_FREE_RTOS)
#define USE_RTOS (1)
#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
#define OSA_TASK_HANDLE_SIZE (12U)
#else
#define OSA_TASK_HANDLE_SIZE (16U)
#endif
#define OSA_EVENT_HANDLE_SIZE (8U)
#define OSA_SEM_HANDLE_SIZE (4U)
#define OSA_MUTEX_HANDLE_SIZE (4U)
#define OSA_MSGQ_HANDLE_SIZE (4U)
#define OSA_MSG_HANDLE_SIZE (0U)
#elif defined(SDK_OS_UCOSII)
#define USE_RTOS (1)
#elif defined(SDK_OS_UCOSIII)
#define USE_RTOS (1)
#elif defined(FSL_RTOS_THREADX)
#define USE_RTOS (1)
#else
#define USE_RTOS (0)
#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
#define OSA_TASK_HANDLE_SIZE (24U)
#else
#define OSA_TASK_HANDLE_SIZE (28U)
#endif
#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
#define OSA_EVENT_HANDLE_SIZE (20U)
#else
#define OSA_EVENT_HANDLE_SIZE (16U)
#endif /* FSL_OSA_TASK_ENABLE */
#if (defined(FSL_OSA_BM_TIMEOUT_ENABLE) && (FSL_OSA_BM_TIMEOUT_ENABLE > 0U))
#define OSA_SEM_HANDLE_SIZE (12U)
#define OSA_MUTEX_HANDLE_SIZE (12U)
#else
#define OSA_SEM_HANDLE_SIZE (4U)
#define OSA_MUTEX_HANDLE_SIZE (4U)
#endif
#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
#define OSA_MSGQ_HANDLE_SIZE (32U)
#else
#define OSA_MSGQ_HANDLE_SIZE (28U)
#endif /* FSL_OSA_TASK_ENABLE */
#define OSA_MSG_HANDLE_SIZE (4U)
#endif
/*! @brief Priority setting for OSA. */
#ifndef OSA_PRIORITY_IDLE
#define OSA_PRIORITY_IDLE (6)
#endif
#ifndef OSA_PRIORITY_LOW
#define OSA_PRIORITY_LOW (5)
#endif
#ifndef OSA_PRIORITY_BELOW_NORMAL
#define OSA_PRIORITY_BELOW_NORMAL (4)
#endif
#ifndef OSA_PRIORITY_NORMAL
#define OSA_PRIORITY_NORMAL (3)
#endif
#ifndef OSA_PRIORITY_ABOVE_NORMAL
#define OSA_PRIORITY_ABOVE_NORMAL (2)
#endif
#ifndef OSA_PRIORITY_HIGH
#define OSA_PRIORITY_HIGH (1)
#endif
#ifndef OSA_PRIORITY_REAL_TIME
#define OSA_PRIORITY_REAL_TIME (0)
#endif
#ifndef OSA_TASK_PRIORITY_MAX
#define OSA_TASK_PRIORITY_MAX (0)
#endif
#ifndef OSA_TASK_PRIORITY_MIN
#define OSA_TASK_PRIORITY_MIN (15)
#endif
#define SIZE_IN_UINT32_UNITS(size) (((size) + sizeof(uint32_t) - 1) / sizeof(uint32_t))
/*! @brief Constant to pass as timeout value in order to wait indefinitely. */
#define osaWaitNone_c ((uint32_t)(0))
#define osaWaitForever_c ((uint32_t)(-1))
#define osaEventFlagsAll_c ((osa_event_flags_t)(0x00FFFFFF))
#define osThreadStackArray(name) osThread_##name##_stack
#define osThreadStackDef(name, stacksize, instances) \
const uint32_t osThreadStackArray(name)[SIZE_IN_UINT32_UNITS(stacksize) * (instances)];
/* ==== Thread Management ==== */
/* Create a Thread Definition with function, priority, and stack requirements.
* \param name name of the thread function.
* \param priority initial priority of the thread function.
* \param instances number of possible thread instances.
* \param stackSz stack size (in bytes) requirements for the thread function.
* \param useFloat
*/
#if defined(SDK_OS_MQX)
#define OSA_TASK_DEFINE(name, priority, instances, stackSz, useFloat) \
osa_thread_link_t osThreadLink_##name[instances] = {0}; \
osThreadStackDef(name, stackSz, instances) osa_task_def_t os_thread_def_##name = { \
(name), (priority), (instances), (stackSz), osThreadStackArray(name), osThreadLink_##name, \
(uint8_t *)#name, (useFloat)}
#elif defined(SDK_OS_UCOSII)
#if gTaskMultipleInstancesManagement_c
#define OSA_TASK_DEFINE(name, priority, instances, stackSz, useFloat) \
osa_thread_link_t osThreadLink_##name[instances] = {0}; \
osThreadStackDef(name, stackSz, instances) osa_task_def_t os_thread_def_##name = { \
(name), (priority), (instances), (stackSz), osThreadStackArray(name), osThreadLink_##name, \
(uint8_t *)#name, (useFloat)}
#else
#define OSA_TASK_DEFINE(name, priority, instances, stackSz, useFloat) \
osThreadStackDef(name, stackSz, instances) osa_task_def_t os_thread_def_##name = { \
(name), (priority), (instances), (stackSz), osThreadStackArray(name), NULL, (uint8_t *)#name, (useFloat)}
#endif
#elif defined(FSL_RTOS_THREADX)
#define OSA_TASK_DEFINE(name, priority, instances, stackSz, useFloat) \
uint32_t s_stackBuffer##name[(stackSz + sizeof(uint32_t) - 1U) / sizeof(uint32_t)]; \
static const osa_task_def_t os_thread_def_##name = { \
(name), (priority), (instances), (stackSz), s_stackBuffer##name, NULL, (uint8_t *)#name, (useFloat)}
#else
#define OSA_TASK_DEFINE(name, priority, instances, stackSz, useFloat) \
const osa_task_def_t os_thread_def_##name = {(name), (priority), (instances), (stackSz), \
NULL, NULL, (uint8_t *)#name, (useFloat)}
#endif
/* Access a Thread defintion.
* \param name name of the thread definition object.
*/
#define OSA_TASK(name) (const osa_task_def_t *)&os_thread_def_##name
#define OSA_TASK_PROTO(name) extern osa_task_def_t os_thread_def_##name
/* ==== Timer Management ====
* Define a Timer object.
* \param name name of the timer object.
* \param function name of the timer call back function.
*/
#define OSA_TIMER_DEF(name, function) osa_time_def_t os_timer_def_##name = {(function), NULL}
/* Access a Timer definition.
* \param name name of the timer object.
*/
#define OSA_TIMER(name) &os_timer_def_##name
/* ==== Buffer Definition ==== */
/*!
* @brief Defines the semaphore handle
*
* This macro is used to define a 4 byte aligned semaphore handle.
* Then use "(osa_semaphore_handle_t)name" to get the semaphore handle.
*
* The macro should be global and could be optional. You could also define semaphore handle by yourself.
*
* This is an example,
* @code
* OSA_SEMAPHORE_HANDLE_DEFINE(semaphoreHandle);
* @endcode
*
* @param name The name string of the semaphore handle.
*/
#define OSA_SEMAPHORE_HANDLE_DEFINE(name) \
uint32_t name[(OSA_SEM_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t)]
/*!
* @brief Defines the mutex handle
*
* This macro is used to define a 4 byte aligned mutex handle.
* Then use "(osa_mutex_handle_t)name" to get the mutex handle.
*
* The macro should be global and could be optional. You could also define mutex handle by yourself.
*
* This is an example,
* @code
* OSA_MUTEX_HANDLE_DEFINE(mutexHandle);
* @endcode
*
* @param name The name string of the mutex handle.
*/
#define OSA_MUTEX_HANDLE_DEFINE(name) uint32_t name[(OSA_MUTEX_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t)]
/*!
* @brief Defines the event handle
*
* This macro is used to define a 4 byte aligned event handle.
* Then use "(osa_event_handle_t)name" to get the event handle.
*
* The macro should be global and could be optional. You could also define event handle by yourself.
*
* This is an example,
* @code
* OSA_EVENT_HANDLE_DEFINE(eventHandle);
* @endcode
*
* @param name The name string of the event handle.
*/
#define OSA_EVENT_HANDLE_DEFINE(name) uint32_t name[(OSA_EVENT_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t)]
/*!
* @brief Defines the message queue handle
*
* This macro is used to define a 4 byte aligned message queue handle.
* Then use "(osa_msgq_handle_t)name" to get the message queue handle.
*
* The macro should be global and could be optional. You could also define message queue handle by yourself.
*
* This is an example,
* @code
* OSA_MSGQ_HANDLE_DEFINE(msgqHandle, 3, sizeof(msgStruct));
* @endcode
*
* @param name The name string of the message queue handle.
* @param numberOfMsgs Number of messages.
* @param msgSize Message size.
*
*/
#if defined(SDK_OS_FREE_RTOS)
/*< Macro For FREE_RTOS*/
#define OSA_MSGQ_HANDLE_DEFINE(name, numberOfMsgs, msgSize) \
uint32_t name[(OSA_MSGQ_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t)]
#else
/*< Macro For BARE_MATEL*/
#define OSA_MSGQ_HANDLE_DEFINE(name, numberOfMsgs, msgSize) \
uint32_t name[((OSA_MSGQ_HANDLE_SIZE + numberOfMsgs * msgSize) + sizeof(uint32_t) - 1U) / sizeof(uint32_t)]
#endif
/*!
* @brief Defines the TASK handle
*
* This macro is used to define a 4 byte aligned TASK handle.
* Then use "(osa_task_handle_t)name" to get the TASK handle.
*
* The macro should be global and could be optional. You could also define TASK handle by yourself.
*
* This is an example,
* @code
* OSA_TASK_HANDLE_DEFINE(taskHandle);
* @endcode
*
* @param name The name string of the TASK handle.
*/
#define OSA_TASK_HANDLE_DEFINE(name) uint32_t name[(OSA_TASK_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t)]
#if defined(SDK_OS_FREE_RTOS)
#include "fsl_os_abstraction_free_rtos.h"
#elif defined(FSL_RTOS_THREADX)
#include "fsl_os_abstraction_threadx.h"
#else
#include "fsl_os_abstraction_bm.h"
#endif
extern const uint8_t gUseRtos_c;
/*
* alloc the temporary memory to store the status
*/
#define OSA_SR_ALLOC() uint32_t osaCurrentSr;
/*
* Enter critical mode
*/
#define OSA_ENTER_CRITICAL() OSA_EnterCritical(&osaCurrentSr)
/*
* Exit critical mode and retore the previous mode
*/
#define OSA_EXIT_CRITICAL() OSA_ExitCritical(osaCurrentSr)
/*******************************************************************************
* API
******************************************************************************/
/*!
* @brief Reserves the requested amount of memory in bytes.
*
* The function is used to reserve the requested amount of memory in bytes and initializes it to 0.
*
* @param length Amount of bytes to reserve.
*
* @return Pointer to the reserved memory. NULL if memory can't be allocated.
*/
void *OSA_MemoryAllocate(uint32_t length);
/*!
* @brief Frees the memory previously reserved.
*
* The function is used to free the memory block previously reserved.
*
* @param p Pointer to the start of the memory block previously reserved.
*
*/
void OSA_MemoryFree(void *p);
/*!
* @brief Enter critical with nesting mode.
*
* @param sr Store current status and return to caller.
*/
void OSA_EnterCritical(uint32_t *sr);
/*!
* @brief Exit critical with nesting mode.
*
* @param sr Previous status to restore.
*/
void OSA_ExitCritical(uint32_t sr);
/*!
* @name Task management
* @{
*/
/*!
* @brief Initialize OSA.
*
* This function is used to setup the basic services.
*
* Example below shows how to use this API to create the task handle.
* @code
* OSA_Init();
* @endcode
*/
#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
void OSA_Init(void);
#endif
/*!
* @brief Start OSA schedule.
*
* This function is used to start OSA scheduler.
*
* Example below shows how to use this API to start osa schedule.
* @code
* OSA_Start();
* @endcode
*/
#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
void OSA_Start(void);
#endif
/*!
* @brief Creates a task.
*
* This function is used to create task based on the resources defined
* by the macro OSA_TASK_DEFINE.
*
* Example below shows how to use this API to create the task handle.
* @code
* OSA_TASK_HANDLE_DEFINE(taskHandle);
* OSA_TASK_DEFINE( Job1, OSA_PRIORITY_HIGH, 1, 800, 0);
* OSA_TaskCreate((osa_task_handle_t)taskHandle, OSA_TASK(Job1), (osa_task_param_t)NULL);
* @endcode
*
* @param taskHandle Pointer to a memory space of size OSA_TASK_HANDLE_SIZE allocated by the caller, task handle.
* The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
* You can define the handle in the following two ways:
* #OSA_TASK_HANDLE_DEFINE(taskHandle);
* or
* uint32_t taskHandle[((OSA_TASK_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
* @param thread_def pointer to theosa_task_def_t structure which defines the task.
* @param task_param Pointer to be passed to the task when it is created.
* @retval KOSA_StatusSuccess The task is successfully created.
* @retval KOSA_StatusError The task can not be created.
*/
#if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U))
osa_status_t OSA_TaskCreate(osa_task_handle_t taskHandle,
const osa_task_def_t *thread_def,
osa_task_param_t task_param);
#endif /* FSL_OSA_TASK_ENABLE */
/*!
* @brief Gets the handler of active task.
*
* @return Handler to current active task.
*/
#if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U))
osa_task_handle_t OSA_TaskGetCurrentHandle(void);
#endif /* FSL_OSA_TASK_ENABLE */
/*!
* @brief Puts the active task to the end of scheduler's queue.
*
* When a task calls this function, it gives up the CPU and puts itself to the
* end of a task ready list.
*
* @retval KOSA_StatusSuccess The function is called successfully.
* @retval KOSA_StatusError Error occurs with this function.
*/
#if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U))
osa_status_t OSA_TaskYield(void);
#endif /* FSL_OSA_TASK_ENABLE */
/*!
* @brief Gets the priority of a task.
*
* @param taskHandle The handler of the task whose priority is received.
*
* @return Task's priority.
*/
#if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U))
osa_task_priority_t OSA_TaskGetPriority(osa_task_handle_t taskHandle);
#endif /* FSL_OSA_TASK_ENABLE */
/*!
* @brief Sets the priority of a task.
*
* @param taskHandle The handler of the task whose priority is set.
* @param taskPriority The priority to set.
*
* @retval KOSA_StatusSuccess Task's priority is set successfully.
* @retval KOSA_StatusError Task's priority can not be set.
*/
#if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U))
osa_status_t OSA_TaskSetPriority(osa_task_handle_t taskHandle, osa_task_priority_t taskPriority);
#endif /* FSL_OSA_TASK_ENABLE */
/*!
* @brief Destroys a previously created task.
*
* @param taskHandle The handler of the task to destroy.
*
* @retval KOSA_StatusSuccess The task was successfully destroyed.
* @retval KOSA_StatusError Task destruction failed or invalid parameter.
*/
#if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U))
osa_status_t OSA_TaskDestroy(osa_task_handle_t taskHandle);
#endif /* FSL_OSA_TASK_ENABLE */
/*!
* @brief Creates a semaphore with a given value.
*
* This function creates a semaphore and sets the value to the parameter
* initValue.
*
* Example below shows how to use this API to create the semaphore handle.
* @code
* OSA_SEMAPHORE_HANDLE_DEFINE(semaphoreHandle);
* OSA_SemaphoreCreate((osa_semaphore_handle_t)semaphoreHandle, 0xff);
* @endcode
*
* @param semaphoreHandle Pointer to a memory space of size OSA_SEM_HANDLE_SIZE allocated by the caller.
* The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
* You can define the handle in the following two ways:
* #OSA_SEMAPHORE_HANDLE_DEFINE(semaphoreHandle);
* or
* uint32_t semaphoreHandle[((OSA_SEM_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
* @param initValue Initial value the semaphore will be set to.
*
* @retval KOSA_StatusSuccess the new semaphore if the semaphore is created successfully.
* @retval KOSA_StatusError if the semaphore can not be created.
*/
osa_status_t OSA_SemaphoreCreate(osa_semaphore_handle_t semaphoreHandle, uint32_t initValue);
/*!
* @brief Destroys a previously created semaphore.
*
* @param semaphoreHandle The semaphore handle.
* The macro SEMAPHORE_HANDLE_BUFFER_GET is used to get the semaphore buffer pointer,
* and should not be used before the macro SEMAPHORE_HANDLE_BUFFER_DEFINE is used.
*
* @retval KOSA_StatusSuccess The semaphore is successfully destroyed.
* @retval KOSA_StatusError The semaphore can not be destroyed.
*/
osa_status_t OSA_SemaphoreDestroy(osa_semaphore_handle_t semaphoreHandle);
/*!
* @brief Pending a semaphore with timeout.
*
* This function checks the semaphore's counting value. If it is positive,
* decreases it and returns KOSA_StatusSuccess. Otherwise, a timeout is used
* to wait.
*
* @param semaphoreHandle The semaphore handle.
* @param millisec The maximum number of milliseconds to wait if semaphore is not
* positive. Pass osaWaitForever_c to wait indefinitely, pass 0
* will return KOSA_StatusTimeout immediately.
*
* @retval KOSA_StatusSuccess The semaphore is received.
* @retval KOSA_StatusTimeout The semaphore is not received within the specified 'timeout'.
* @retval KOSA_StatusError An incorrect parameter was passed.
*/
osa_status_t OSA_SemaphoreWait(osa_semaphore_handle_t semaphoreHandle, uint32_t millisec);
/*!
* @brief Signals for someone waiting on the semaphore to wake up.
*
* Wakes up one task that is waiting on the semaphore. If no task is waiting, increases
* the semaphore's counting value.
*
* @param semaphoreHandle The semaphore handle to signal.
*
* @retval KOSA_StatusSuccess The semaphore is successfully signaled.
* @retval KOSA_StatusError The object can not be signaled or invalid parameter.
*
*/
osa_status_t OSA_SemaphorePost(osa_semaphore_handle_t semaphoreHandle);
/*!
* @brief Create an unlocked mutex.
*
* This function creates a non-recursive mutex and sets it to unlocked status.
*
* Example below shows how to use this API to create the mutex handle.
* @code
* OSA_MUTEX_HANDLE_DEFINE(mutexHandle);
* OSA_MutexCreate((osa_mutex_handle_t)mutexHandle);
* @endcode
*
* @param mutexHandle Pointer to a memory space of size OSA_MUTEX_HANDLE_SIZE allocated by the caller.
* The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
* You can define the handle in the following two ways:
* #OSA_MUTEX_HANDLE_DEFINE(mutexHandle);
* or
* uint32_t mutexHandle[((OSA_MUTEX_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
* @retval KOSA_StatusSuccess the new mutex if the mutex is created successfully.
* @retval KOSA_StatusError if the mutex can not be created.
*/
osa_status_t OSA_MutexCreate(osa_mutex_handle_t mutexHandle);
/*!
* @brief Waits for a mutex and locks it.
*
* This function checks the mutex's status. If it is unlocked, locks it and returns the
* KOSA_StatusSuccess. Otherwise, waits for a timeout in milliseconds to lock.
*
* @param mutexHandle The mutex handle.
* @param millisec The maximum number of milliseconds to wait for the mutex.
* If the mutex is locked, Pass the value osaWaitForever_c will
* wait indefinitely, pass 0 will return KOSA_StatusTimeout
* immediately.
*
* @retval KOSA_StatusSuccess The mutex is locked successfully.
* @retval KOSA_StatusTimeout Timeout occurred.
* @retval KOSA_StatusError Incorrect parameter was passed.
*
* @note This is non-recursive mutex, a task can not try to lock the mutex it has locked.
*/
osa_status_t OSA_MutexLock(osa_mutex_handle_t mutexHandle, uint32_t millisec);
/*!
* @brief Unlocks a previously locked mutex.
*
* @param mutexHandle The mutex handle.
*
* @retval KOSA_StatusSuccess The mutex is successfully unlocked.
* @retval KOSA_StatusError The mutex can not be unlocked or invalid parameter.
*/
osa_status_t OSA_MutexUnlock(osa_mutex_handle_t mutexHandle);
/*!
* @brief Destroys a previously created mutex.
*
* @param mutexHandle The mutex handle.
*
* @retval KOSA_StatusSuccess The mutex is successfully destroyed.
* @retval KOSA_StatusError The mutex can not be destroyed.
*
*/
osa_status_t OSA_MutexDestroy(osa_mutex_handle_t mutexHandle);
/*!
* @brief Initializes an event object with all flags cleared.
*
* This function creates an event object and set its clear mode. If autoClear
* is 1, when a task gets the event flags, these flags will be
* cleared automatically. Otherwise these flags must
* be cleared manually.
*
* Example below shows how to use this API to create the event handle.
* @code
* OSA_EVENT_HANDLE_DEFINE(eventHandle);
* OSA_EventCreate((osa_event_handle_t)eventHandle, 0);
* @endcode
*
* @param eventHandle Pointer to a memory space of size OSA_EVENT_HANDLE_SIZE allocated by the caller.
* The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
* You can define the handle in the following two ways:
* #OSA_EVENT_HANDLE_DEFINE(eventHandle);
* or
* uint32_t eventHandle[((OSA_EVENT_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
* @param autoClear 1 The event is auto-clear.
* 0 The event manual-clear
* @retval KOSA_StatusSuccess the new event if the event is created successfully.
* @retval KOSA_StatusError if the event can not be created.
*/
osa_status_t OSA_EventCreate(osa_event_handle_t eventHandle, uint8_t autoClear);
/*!
* @brief Sets one or more event flags.
*
* Sets specified flags of an event object.
*
* @param eventHandle The event handle.
* @param flagsToSet Flags to be set.
*
* @retval KOSA_StatusSuccess The flags were successfully set.
* @retval KOSA_StatusError An incorrect parameter was passed.
*/
osa_status_t OSA_EventSet(osa_event_handle_t eventHandle, osa_event_flags_t flagsToSet);
/*!
* @brief Clears one or more flags.
*
* Clears specified flags of an event object.
*
* @param eventHandle The event handle.
* @param flagsToClear Flags to be clear.
*
* @retval KOSA_StatusSuccess The flags were successfully cleared.
* @retval KOSA_StatusError An incorrect parameter was passed.
*/
osa_status_t OSA_EventClear(osa_event_handle_t eventHandle, osa_event_flags_t flagsToClear);
/*!
* @brief Get event's flags.
*
* Get specified flags of an event object.
*
* @param eventHandle The event handle.
* The macro EVENT_HANDLE_BUFFER_GET is used to get the event buffer pointer,
* and should not be used before the macro EVENT_HANDLE_BUFFER_DEFINE is used.
* @param flagsMask The flags user want to get are specified by this parameter.
* @param pFlagsOfEvent The event flags are obtained by this parameter.
*
* @retval KOSA_StatusSuccess The event flags were successfully got.
* @retval KOSA_StatusError An incorrect parameter was passed.
*/
osa_status_t OSA_EventGet(osa_event_handle_t eventHandle,
osa_event_flags_t flagsMask,
osa_event_flags_t *pFlagsOfEvent);
/*!
* @brief Waits for specified event flags to be set.
*
* This function waits for a combination of flags to be set in an event object.
* Applications can wait for any/all bits to be set. Also this function could
* obtain the flags who wakeup the waiting task.
*
* @param eventHandle The event handle.
* @param flagsToWait Flags that to wait.
* @param waitAll Wait all flags or any flag to be set.
* @param millisec The maximum number of milliseconds to wait for the event.
* If the wait condition is not met, pass osaWaitForever_c will
* wait indefinitely, pass 0 will return KOSA_StatusTimeout
* immediately.
* @param pSetFlags Flags that wakeup the waiting task are obtained by this parameter.
*
* @retval KOSA_StatusSuccess The wait condition met and function returns successfully.
* @retval KOSA_StatusTimeout Has not met wait condition within timeout.
* @retval KOSA_StatusError An incorrect parameter was passed.
*
* @note Please pay attention to the flags bit width, FreeRTOS uses the most
* significant 8 bis as control bits, so do not wait these bits while using
* FreeRTOS.
*
*/
osa_status_t OSA_EventWait(osa_event_handle_t eventHandle,
osa_event_flags_t flagsToWait,
uint8_t waitAll,
uint32_t millisec,
osa_event_flags_t *pSetFlags);
/*!
* @brief Destroys a previously created event object.
*
* @param eventHandle The event handle.
*
* @retval KOSA_StatusSuccess The event is successfully destroyed.
* @retval KOSA_StatusError Event destruction failed.
*/
osa_status_t OSA_EventDestroy(osa_event_handle_t eventHandle);
/*!
* @brief Initializes a message queue.
*
* This function allocates memory for and initializes a message queue. Message queue elements are hardcoded as void*.
*
* Example below shows how to use this API to create the massage queue handle.
* @code
* OSA_MSGQ_HANDLE_DEFINE(msgqHandle);
* OSA_MsgQCreate((osa_msgq_handle_t)msgqHandle, 5U, sizeof(msg));
* @endcode
*
* @param msgqHandle Pointer to a memory space of size #(OSA_MSGQ_HANDLE_SIZE + msgNo*msgSize) on bare-matel
* and #(OSA_MSGQ_HANDLE_SIZE) on FreeRTOS allocated by the caller, message queue handle.
* The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
* You can define the handle in the following two ways:
* #OSA_MSGQ_HANDLE_DEFINE(msgqHandle);
* or
* For bm: uint32_t msgqHandle[((OSA_MSGQ_HANDLE_SIZE + msgNo*msgSize + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
* For freertos: uint32_t msgqHandle[((OSA_MSGQ_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
* @param msgNo :number of messages the message queue should accommodate.
* @param msgSize :size of a single message structure.
*
* @retval KOSA_StatusSuccess Message queue successfully Create.
* @retval KOSA_StatusError Message queue create failure.
*/
osa_status_t OSA_MsgQCreate(osa_msgq_handle_t msgqHandle, uint32_t msgNo, uint32_t msgSize);
/*!
* @brief Puts a message at the end of the queue.
*
* This function puts a message to the end of the message queue. If the queue
* is full, this function returns the KOSA_StatusError;
*
* @param msgqHandle Message Queue handler.
* @param pMessage Pointer to the message to be put into the queue.
*
* @retval KOSA_StatusSuccess Message successfully put into the queue.
* @retval KOSA_StatusError The queue was full or an invalid parameter was passed.
*/
osa_status_t OSA_MsgQPut(osa_msgq_handle_t msgqHandle, osa_msg_handle_t pMessage);
/*!
* @brief Reads and remove a message at the head of the queue.
*
* This function gets a message from the head of the message queue. If the
* queue is empty, timeout is used to wait.
*
* @param msgqHandle Message Queue handler.
* @param pMessage Pointer to a memory to save the message.
* @param millisec The number of milliseconds to wait for a message. If the
* queue is empty, pass osaWaitForever_c will wait indefinitely,
* pass 0 will return KOSA_StatusTimeout immediately.
*
* @retval KOSA_StatusSuccess Message successfully obtained from the queue.
* @retval KOSA_StatusTimeout The queue remains empty after timeout.
* @retval KOSA_StatusError Invalid parameter.
*/
osa_status_t OSA_MsgQGet(osa_msgq_handle_t msgqHandle, osa_msg_handle_t pMessage, uint32_t millisec);
/*!
* @brief Get the available message
*
* This function is used to get the available message.
*
* @param msgqHandle Message Queue handler.
*
* @return Available message count
*/
int OSA_MsgQAvailableMsgs(osa_msgq_handle_t msgqHandle);
/*!
* @brief Destroys a previously created queue.
*
* @param msgqHandle Message Queue handler.
*
* @retval KOSA_StatusSuccess The queue was successfully destroyed.
* @retval KOSA_StatusError Message queue destruction failed.
*/
osa_status_t OSA_MsgQDestroy(osa_msgq_handle_t msgqHandle);
/*!
* @brief Enable all interrupts.
*/
void OSA_InterruptEnable(void);
/*!
* @brief Disable all interrupts.
*/
void OSA_InterruptDisable(void);
/*!
* @brief Enable all interrupts using PRIMASK.
*/
void OSA_EnableIRQGlobal(void);
/*!
* @brief Disable all interrupts using PRIMASK.
*/
void OSA_DisableIRQGlobal(void);
/*!
* @brief Delays execution for a number of milliseconds.
*
* @param millisec The time in milliseconds to wait.
*/
void OSA_TimeDelay(uint32_t millisec);
/*!
* @brief This function gets current time in milliseconds.
*
* @retval current time in milliseconds
*/
uint32_t OSA_TimeGetMsec(void);
/*!
* @brief Installs the interrupt handler.
*
* @param IRQNumber IRQ number of the interrupt.
* @param handler The interrupt handler to install.
*/
void OSA_InstallIntHandler(uint32_t IRQNumber, void (*handler)(void));
/*! @}*/
#ifdef __cplusplus
}
#endif
/*! @}*/
#endif

View file

@ -0,0 +1,72 @@
/*
* Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc.
* Copyright 2016-2020 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#if !defined(__FSL_OS_ABSTRACTION_BM_H__)
#define __FSL_OS_ABSTRACTION_BM_H__
/*!
* @addtogroup os_abstraction_bm
* @{
*/
/*******************************************************************************
* Declarations
******************************************************************************/
/*! @brief Bare Metal does not use timer. */
#ifndef FSL_OSA_BM_TIMER_NONE
#define FSL_OSA_BM_TIMER_NONE 0U
#endif
/*! @brief Bare Metal uses SYSTICK as timer. */
#ifndef FSL_OSA_BM_TIMER_SYSTICK
#define FSL_OSA_BM_TIMER_SYSTICK 1U
#endif
/*! @brief Configure what timer is used in Bare Metal. */
#ifndef FSL_OSA_BM_TIMER_CONFIG
#define FSL_OSA_BM_TIMER_CONFIG FSL_OSA_BM_TIMER_NONE
#endif
/*! @brief Type for task parameter */
typedef void *task_param_t;
/*! @brief Type for an event flags group, bit 32 is reserved */
typedef uint32_t event_flags_t;
/*! @brief Constant to pass as timeout value in order to wait indefinitely. */
#define OSA_WAIT_FOREVER 0xFFFFFFFFU
/*! @brief How many tasks can the bare metal support. */
#ifndef TASK_MAX_NUM
#define TASK_MAX_NUM 7
#endif
/*! @brief OSA's time range in millisecond, OSA time wraps if exceeds this value. */
#define FSL_OSA_TIME_RANGE 0xFFFFFFFFU
/*! @brief The default interrupt handler installed in vector table. */
#define OSA_DEFAULT_INT_HANDLER ((osa_int_handler_t)(&DefaultISR))
/*! @brief The default interrupt handler installed in vector table. */
extern void DefaultISR(void);
/*!
* @name Thread management
* @{
*/
/*!
* @brief To provide unified priority for upper layer, OSA layer makes conversation.
*/
#define PRIORITY_OSA_TO_RTOS(osa_prio) (osa_prio)
#define PRIORITY_RTOS_TO_OSA(rtos_prio) (rtos_prio)
/*! @}*/
/*! @}*/
#endif /* __FSL_OS_ABSTRACTION_BM_H__ */
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,44 @@
/*!
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2018 NXP
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_OS_ABSTRACTION_CONFIG_H_
#define _FSL_OS_ABSTRACTION_CONFIG_H_
#ifndef gMainThreadStackSize_c
#define gMainThreadStackSize_c 1024
#endif
#ifndef gMainThreadPriority_c
#define gMainThreadPriority_c 7
#endif
#ifndef gTaskMultipleInstancesManagement_c
#define gTaskMultipleInstancesManagement_c 0
#endif
/*! @brief Definition to determine whether enable OSA's TASK module. */
#ifndef OSA_USED
#ifndef FSL_OSA_TASK_ENABLE
#define FSL_OSA_TASK_ENABLE 0U
#endif
#else
#if defined(FSL_OSA_TASK_ENABLE)
#undef FSL_OSA_TASK_ENABLE
#endif
#define FSL_OSA_TASK_ENABLE 1U
#endif /* OSA_USED */
#ifndef FSL_OSA_MAIN_FUNC_ENABLE
#define FSL_OSA_MAIN_FUNC_ENABLE 1U
#endif
#ifndef FSL_OSA_BM_TIMEOUT_ENABLE
#define FSL_OSA_BM_TIMEOUT_ENABLE 0U
#endif
#endif /* _FSL_OS_ABSTRACTION_CONFIG_H_ */

View file

@ -0,0 +1,834 @@
/*
* Copyright 2018-2020 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __HAL_UART_ADAPTER_H__
#define __HAL_UART_ADAPTER_H__
#include "fsl_common.h"
#if defined(SDK_OS_FREE_RTOS)
#include "FreeRTOS.h"
#endif
/*!
* @addtogroup UART_Adapter
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief Enable or disable UART adapter non-blocking mode (1 - enable, 0 - disable) */
#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
#define UART_ADAPTER_NON_BLOCKING_MODE (1U)
#else
#ifndef SERIAL_MANAGER_NON_BLOCKING_MODE
#define UART_ADAPTER_NON_BLOCKING_MODE (0U)
#else
#define UART_ADAPTER_NON_BLOCKING_MODE SERIAL_MANAGER_NON_BLOCKING_MODE
#endif
#endif
#if defined(__GIC_PRIO_BITS)
#ifndef HAL_UART_ISR_PRIORITY
#define HAL_UART_ISR_PRIORITY (25U)
#endif
#else
#if defined(configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY)
#ifndef HAL_UART_ISR_PRIORITY
#define HAL_UART_ISR_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY)
#endif
#else
/* The default value 3 is used to support different ARM Core, such as CM0P, CM4, CM7, and CM33, etc.
* The minimum number of priority bits implemented in the NVIC is 2 on these SOCs. The value of mininum
* priority is 3 (2^2 - 1). So, the default value is 3.
*/
#ifndef HAL_UART_ISR_PRIORITY
#define HAL_UART_ISR_PRIORITY (3U)
#endif
#endif
#endif
#ifndef HAL_UART_ADAPTER_LOWPOWER
#define HAL_UART_ADAPTER_LOWPOWER (0U)
#endif /* HAL_UART_ADAPTER_LOWPOWER */
#ifndef HAL_UART_ADAPTER_FIFO
#define HAL_UART_ADAPTER_FIFO (0U)
#endif /* HAL_UART_ADAPTER_FIFO */
#ifndef HAL_UART_DMA_ENABLE
#define HAL_UART_DMA_ENABLE (0U)
#endif /* HAL_UART_DMA_ENABLE */
/*! @brief Enable or disable master SPI DMA adapter int mode (1 - enable, 0 - disable) */
#ifndef HAL_UART_DMA_INIT_ENABLE
#define HAL_UART_DMA_INIT_ENABLE (0U)
#endif /* HAL_SPI_MASTER_DMA_INIT_ENABLE */
/*! @brief Definition of uart dma adapter software idleline detection timeout value in ms. */
#ifndef HAL_UART_DMA_IDLELINE_TIMEOUT
#define HAL_UART_DMA_IDLELINE_TIMEOUT (1U)
#endif /* HAL_UART_DMA_IDLELINE_TIMEOUT */
/*! @brief Definition of uart adapter handle size. */
#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
#define HAL_UART_HANDLE_SIZE (92U + HAL_UART_ADAPTER_LOWPOWER * 16U + HAL_UART_DMA_ENABLE * 4)
#define HAL_UART_BLOCK_HANDLE_SIZE (8U + HAL_UART_ADAPTER_LOWPOWER * 16U + HAL_UART_DMA_ENABLE * 4)
#else
#define HAL_UART_HANDLE_SIZE (8U + HAL_UART_ADAPTER_LOWPOWER * 16U + HAL_UART_DMA_ENABLE * 4)
#endif
/*! @brief Definition of uart dma adapter handle size. */
#if (defined(HAL_UART_DMA_ENABLE) && (HAL_UART_DMA_ENABLE > 0U))
#if (defined(FSL_FEATURE_SOC_DMA_COUNT) && (FSL_FEATURE_SOC_DMA_COUNT > 0U))
#define HAL_UART_DMA_HANDLE_SIZE (124U)
#elif (defined(FSL_FEATURE_SOC_EDMA_COUNT) && (FSL_FEATURE_SOC_EDMA_COUNT > 0U))
#define HAL_UART_DMA_HANDLE_SIZE (140U)
#else
#error This SOC does not have DMA or EDMA available!
#endif
#endif /* HAL_UART_DMA_ENABLE */
/*!
* @brief Defines the uart handle
*
* This macro is used to define a 4 byte aligned uart handle.
* Then use "(hal_uart_handle_t)name" to get the uart handle.
*
* The macro should be global and could be optional. You could also define uart handle by yourself.
*
* This is an example,
* @code
* UART_HANDLE_DEFINE(uartHandle);
* @endcode
*
* @param name The name string of the uart handle.
*/
#define UART_HANDLE_DEFINE(name) uint32_t name[((HAL_UART_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))]
#if (defined(HAL_UART_DMA_ENABLE) && (HAL_UART_DMA_ENABLE > 0U))
#define UART_DMA_HANDLE_DEFINE(name) \
uint32_t name[((HAL_UART_DMA_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))]
#endif
/*! @brief Whether enable transactional function of the UART. (0 - disable, 1 - enable) */
#ifndef HAL_UART_TRANSFER_MODE
#define HAL_UART_TRANSFER_MODE (0U)
#endif
/*! @brief The handle of uart adapter. */
typedef void *hal_uart_handle_t;
/*! @brief The handle of uart dma adapter. */
typedef void *hal_uart_dma_handle_t;
/*! @brief UART status */
typedef enum _hal_uart_status
{
kStatus_HAL_UartSuccess = kStatus_Success, /*!< Successfully */
kStatus_HAL_UartTxBusy = MAKE_STATUS(kStatusGroup_HAL_UART, 1), /*!< TX busy */
kStatus_HAL_UartRxBusy = MAKE_STATUS(kStatusGroup_HAL_UART, 2), /*!< RX busy */
kStatus_HAL_UartTxIdle = MAKE_STATUS(kStatusGroup_HAL_UART, 3), /*!< HAL UART transmitter is idle. */
kStatus_HAL_UartRxIdle = MAKE_STATUS(kStatusGroup_HAL_UART, 4), /*!< HAL UART receiver is idle */
kStatus_HAL_UartBaudrateNotSupport =
MAKE_STATUS(kStatusGroup_HAL_UART, 5), /*!< Baudrate is not support in current clock source */
kStatus_HAL_UartProtocolError = MAKE_STATUS(
kStatusGroup_HAL_UART,
6), /*!< Error occurs for Noise, Framing, Parity, etc.
For transactional transfer, The up layer needs to abort the transfer and then starts again */
kStatus_HAL_UartError = MAKE_STATUS(kStatusGroup_HAL_UART, 7), /*!< Error occurs on HAL UART */
} hal_uart_status_t;
/*! @brief UART parity mode. */
typedef enum _hal_uart_parity_mode
{
kHAL_UartParityDisabled = 0x0U, /*!< Parity disabled */
kHAL_UartParityEven = 0x2U, /*!< Parity even enabled */
kHAL_UartParityOdd = 0x3U, /*!< Parity odd enabled */
} hal_uart_parity_mode_t;
#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
/*! @brief UART Block Mode. */
typedef enum _hal_uart_block_mode
{
kHAL_UartNonBlockMode = 0x0U, /*!< Uart NonBlock Mode */
kHAL_UartBlockMode = 0x1U, /*!< Uart Block Mode */
} hal_uart_block_mode_t;
#endif /* UART_ADAPTER_NON_BLOCKING_MODE */
/*! @brief UART stop bit count. */
typedef enum _hal_uart_stop_bit_count
{
kHAL_UartOneStopBit = 0U, /*!< One stop bit */
kHAL_UartTwoStopBit = 1U, /*!< Two stop bits */
} hal_uart_stop_bit_count_t;
/*! @brief UART configuration structure. */
typedef struct _hal_uart_config
{
uint32_t srcClock_Hz; /*!< Source clock */
uint32_t baudRate_Bps; /*!< Baud rate */
hal_uart_parity_mode_t parityMode; /*!< Parity mode, disabled (default), even, odd */
hal_uart_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits */
uint8_t enableRx; /*!< Enable RX */
uint8_t enableTx; /*!< Enable TX */
uint8_t enableRxRTS; /*!< Enable RX RTS */
uint8_t enableTxCTS; /*!< Enable TX CTS */
uint8_t instance; /*!< Instance (0 - UART0, 1 - UART1, ...), detail information please refer to the
SOC corresponding RM.
Invalid instance value will cause initialization failure. */
#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
hal_uart_block_mode_t mode; /*!< Uart block mode */
#endif /* UART_ADAPTER_NON_BLOCKING_MODE */
#if (defined(HAL_UART_ADAPTER_FIFO) && (HAL_UART_ADAPTER_FIFO > 0u))
uint8_t txFifoWatermark;
uint8_t rxFifoWatermark;
#endif
} hal_uart_config_t;
#if (defined(HAL_UART_DMA_ENABLE) && (HAL_UART_DMA_ENABLE > 0U))
/*! @brief UART DMA status */
typedef enum _hal_uart_dma_status
{
kStatus_HAL_UartDmaSuccess = 0U,
kStatus_HAL_UartDmaRxIdle = (1U << 1U),
kStatus_HAL_UartDmaRxBusy = (1U << 2U),
kStatus_HAL_UartDmaTxIdle = (1U << 3U),
kStatus_HAL_UartDmaTxBusy = (1U << 4U),
kStatus_HAL_UartDmaIdleline = (1U << 5U),
kStatus_HAL_UartDmaError = (1U << 6U),
} hal_uart_dma_status_t;
typedef struct _dma_mux_configure_t
{
union
{
struct
{
uint8_t dma_mux_instance;
uint32_t rx_request;
uint32_t tx_request;
} dma_dmamux_configure;
};
} dma_mux_configure_t;
typedef struct _dma_channel_mux_configure_t
{
union
{
struct
{
uint32_t dma_rx_channel_mux;
uint32_t dma_tx_channel_mux;
} dma_dmamux_configure;
};
} dma_channel_mux_configure_t;
typedef struct _hal_uart_dma_config_t
{
uint8_t uart_instance;
uint8_t dma_instance;
uint8_t rx_channel;
uint8_t tx_channel;
void *dma_mux_configure;
void *dma_channel_mux_configure;
} hal_uart_dma_config_t;
#endif /* HAL_UART_DMA_ENABLE */
/*! @brief UART transfer callback function. */
typedef void (*hal_uart_transfer_callback_t)(hal_uart_handle_t handle, hal_uart_status_t status, void *callbackParam);
#if (defined(HAL_UART_DMA_ENABLE) && (HAL_UART_DMA_ENABLE > 0U))
typedef struct _dma_callback_msg
{
hal_uart_dma_status_t status;
uint8_t *data;
uint32_t dataSize;
} hal_dma_callback_msg_t;
/*! @brief UART transfer callback function. */
typedef void (*hal_uart_dma_transfer_callback_t)(hal_uart_dma_handle_t handle,
hal_dma_callback_msg_t *msg,
void *callbackParam);
#endif /* HAL_UART_DMA_ENABLE */
/*! @brief UART transfer structure. */
typedef struct _hal_uart_transfer
{
uint8_t *data; /*!< The buffer of data to be transfer.*/
size_t dataSize; /*!< The byte count to be transfer. */
} hal_uart_transfer_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* _cplusplus */
/*!
* @name Initialization and deinitialization
* @{
*/
/*!
* @brief Initializes a UART instance with the UART handle and the user configuration structure.
*
* This function configures the UART module with user-defined settings. The user can configure the configuration
* structure. The parameter handle is a pointer to point to a memory space of size #HAL_UART_HANDLE_SIZE allocated by
* the caller. Example below shows how to use this API to configure the UART.
* @code
* UART_HANDLE_DEFINE(g_UartHandle);
* hal_uart_config_t config;
* config.srcClock_Hz = 48000000;
* config.baudRate_Bps = 115200U;
* config.parityMode = kHAL_UartParityDisabled;
* config.stopBitCount = kHAL_UartOneStopBit;
* config.enableRx = 1;
* config.enableTx = 1;
* config.enableRxRTS = 0;
* config.enableTxCTS = 0;
* config.instance = 0;
* HAL_UartInit((hal_uart_handle_t)g_UartHandle, &config);
* @endcode
*
* @param handle Pointer to point to a memory space of size #HAL_UART_HANDLE_SIZE allocated by the caller.
* The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
* You can define the handle in the following two ways:
* #UART_HANDLE_DEFINE(handle);
* or
* uint32_t handle[((HAL_UART_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
* @param config Pointer to user-defined configuration structure.
* @retval kStatus_HAL_UartBaudrateNotSupport Baudrate is not support in current clock source.
* @retval kStatus_HAL_UartSuccess UART initialization succeed
*/
hal_uart_status_t HAL_UartInit(hal_uart_handle_t handle, const hal_uart_config_t *config);
/*!
* @brief Deinitializes a UART instance.
*
* This function waits for TX complete, disables TX and RX, and disables the UART clock.
*
* @param handle UART handle pointer.
* @retval kStatus_HAL_UartSuccess UART de-initialization succeed
*/
hal_uart_status_t HAL_UartDeinit(hal_uart_handle_t handle);
/*! @}*/
/*!
* @name Blocking bus Operations
* @{
*/
/*!
* @brief Reads RX data register using a blocking method.
*
* This function polls the RX register, waits for the RX register to be full or for RX FIFO to
* have data, and reads data from the RX register.
*
* @note The function #HAL_UartReceiveBlocking and the function HAL_UartTransferReceiveNonBlocking
* cannot be used at the same time.
* And, the function HAL_UartTransferAbortReceive cannot be used to abort the transmission of this function.
*
* @param handle UART handle pointer.
* @param data Start address of the buffer to store the received data.
* @param length Size of the buffer.
* @retval kStatus_HAL_UartError An error occurred while receiving data.
* @retval kStatus_HAL_UartParityError A parity error occurred while receiving data.
* @retval kStatus_HAL_UartSuccess Successfully received all data.
*/
hal_uart_status_t HAL_UartReceiveBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length);
/*!
* @brief Writes to the TX register using a blocking method.
*
* This function polls the TX register, waits for the TX register to be empty or for the TX FIFO
* to have room and writes data to the TX buffer.
*
* @note The function #HAL_UartSendBlocking and the function HAL_UartTransferSendNonBlocking
* cannot be used at the same time.
* And, the function HAL_UartTransferAbortSend cannot be used to abort the transmission of this function.
*
* @param handle UART handle pointer.
* @param data Start address of the data to write.
* @param length Size of the data to write.
* @retval kStatus_HAL_UartSuccess Successfully sent all data.
*/
hal_uart_status_t HAL_UartSendBlocking(hal_uart_handle_t handle, const uint8_t *data, size_t length);
/*! @}*/
#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
/*!
* @name Transactional
* @note The transactional API and the functional API cannot be used at the same time. The macro
* #HAL_UART_TRANSFER_MODE is used to set which one will be used. If #HAL_UART_TRANSFER_MODE is zero, the
* functional API with non-blocking mode will be used. Otherwise, transactional API will be used.
* @{
*/
/*!
* @brief Installs a callback and callback parameter.
*
* This function is used to install the callback and callback parameter for UART module.
* When any status of the UART changed, the driver will notify the upper layer by the installed callback
* function. And the status is also passed as status parameter when the callback is called.
*
* @param handle UART handle pointer.
* @param callback The callback function.
* @param callbackParam The parameter of the callback function.
* @retval kStatus_HAL_UartSuccess Successfully install the callback.
*/
hal_uart_status_t HAL_UartTransferInstallCallback(hal_uart_handle_t handle,
hal_uart_transfer_callback_t callback,
void *callbackParam);
/*!
* @brief Receives a buffer of data using an interrupt method.
*
* This function receives data using an interrupt method. This is a non-blocking function, which
* returns directly without waiting for all data to be received.
* The receive request is saved by the UART driver.
* When the new data arrives, the receive request is serviced first.
* When all data is received, the UART driver notifies the upper layer
* through a callback function and passes the status parameter @ref kStatus_UART_RxIdle.
*
* @note The function #HAL_UartReceiveBlocking and the function #HAL_UartTransferReceiveNonBlocking
* cannot be used at the same time.
*
* @param handle UART handle pointer.
* @param transfer UART transfer structure, see #hal_uart_transfer_t.
* @retval kStatus_HAL_UartSuccess Successfully queue the transfer into transmit queue.
* @retval kStatus_HAL_UartRxBusy Previous receive request is not finished.
* @retval kStatus_HAL_UartError An error occurred.
*/
hal_uart_status_t HAL_UartTransferReceiveNonBlocking(hal_uart_handle_t handle, hal_uart_transfer_t *transfer);
/*!
* @brief Transmits a buffer of data using the interrupt method.
*
* This function sends data using an interrupt method. This is a non-blocking function, which
* returns directly without waiting for all data to be written to the TX register. When
* all data is written to the TX register in the ISR, the UART driver calls the callback
* function and passes the @ref kStatus_UART_TxIdle as status parameter.
*
* @note The function #HAL_UartSendBlocking and the function #HAL_UartTransferSendNonBlocking
* cannot be used at the same time.
*
* @param handle UART handle pointer.
* @param transfer UART transfer structure. See #hal_uart_transfer_t.
* @retval kStatus_HAL_UartSuccess Successfully start the data transmission.
* @retval kStatus_HAL_UartTxBusy Previous transmission still not finished; data not all written to TX register yet.
* @retval kStatus_HAL_UartError An error occurred.
*/
hal_uart_status_t HAL_UartTransferSendNonBlocking(hal_uart_handle_t handle, hal_uart_transfer_t *transfer);
/*!
* @brief Gets the number of bytes that have been received.
*
* This function gets the number of bytes that have been received.
*
* @param handle UART handle pointer.
* @param count Receive bytes count.
* @retval kStatus_HAL_UartError An error occurred.
* @retval kStatus_Success Get successfully through the parameter \p count.
*/
hal_uart_status_t HAL_UartTransferGetReceiveCount(hal_uart_handle_t handle, uint32_t *count);
/*!
* @brief Gets the number of bytes written to the UART TX register.
*
* This function gets the number of bytes written to the UART TX
* register by using the interrupt method.
*
* @param handle UART handle pointer.
* @param count Send bytes count.
* @retval kStatus_HAL_UartError An error occurred.
* @retval kStatus_Success Get successfully through the parameter \p count.
*/
hal_uart_status_t HAL_UartTransferGetSendCount(hal_uart_handle_t handle, uint32_t *count);
/*!
* @brief Aborts the interrupt-driven data receiving.
*
* This function aborts the interrupt-driven data receiving. The user can get the remainBytes to know
* how many bytes are not received yet.
*
* @note The function #HAL_UartTransferAbortReceive cannot be used to abort the transmission of
* the function #HAL_UartReceiveBlocking.
*
* @param handle UART handle pointer.
* @retval kStatus_Success Get successfully abort the receiving.
*/
hal_uart_status_t HAL_UartTransferAbortReceive(hal_uart_handle_t handle);
/*!
* @brief Aborts the interrupt-driven data sending.
*
* This function aborts the interrupt-driven data sending. The user can get the remainBytes to find out
* how many bytes are not sent out.
*
* @note The function #HAL_UartTransferAbortSend cannot be used to abort the transmission of
* the function #HAL_UartSendBlocking.
*
* @param handle UART handle pointer.
* @retval kStatus_Success Get successfully abort the sending.
*/
hal_uart_status_t HAL_UartTransferAbortSend(hal_uart_handle_t handle);
/*! @}*/
#else
/*!
* @name Functional API with non-blocking mode.
* @note The functional API and the transactional API cannot be used at the same time. The macro
* #HAL_UART_TRANSFER_MODE is used to set which one will be used. If #HAL_UART_TRANSFER_MODE is zero, the
* functional API with non-blocking mode will be used. Otherwise, transactional API will be used.
* @{
*/
/*!
* @brief Installs a callback and callback parameter.
*
* This function is used to install the callback and callback parameter for UART module.
* When non-blocking sending or receiving finished, the adapter will notify the upper layer by the installed callback
* function. And the status is also passed as status parameter when the callback is called.
*
* @param handle UART handle pointer.
* @param callback The callback function.
* @param callbackParam The parameter of the callback function.
* @retval kStatus_HAL_UartSuccess Successfully install the callback.
*/
hal_uart_status_t HAL_UartInstallCallback(hal_uart_handle_t handle,
hal_uart_transfer_callback_t callback,
void *callbackParam);
/*!
* @brief Receives a buffer of data using an interrupt method.
*
* This function receives data using an interrupt method. This is a non-blocking function, which
* returns directly without waiting for all data to be received.
* The receive request is saved by the UART adapter.
* When the new data arrives, the receive request is serviced first.
* When all data is received, the UART adapter notifies the upper layer
* through a callback function and passes the status parameter @ref kStatus_UART_RxIdle.
*
* @note The function #HAL_UartReceiveBlocking and the function #HAL_UartReceiveNonBlocking
* cannot be used at the same time.
*
* @param handle UART handle pointer.
* @param data Start address of the data to write.
* @param length Size of the data to write.
* @retval kStatus_HAL_UartSuccess Successfully queue the transfer into transmit queue.
* @retval kStatus_HAL_UartRxBusy Previous receive request is not finished.
* @retval kStatus_HAL_UartError An error occurred.
*/
hal_uart_status_t HAL_UartReceiveNonBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length);
/*!
* @brief Transmits a buffer of data using the interrupt method.
*
* This function sends data using an interrupt method. This is a non-blocking function, which
* returns directly without waiting for all data to be written to the TX register. When
* all data is written to the TX register in the ISR, the UART driver calls the callback
* function and passes the @ref kStatus_UART_TxIdle as status parameter.
*
* @note The function #HAL_UartSendBlocking and the function #HAL_UartSendNonBlocking
* cannot be used at the same time.
*
* @param handle UART handle pointer.
* @param data Start address of the data to write.
* @param length Size of the data to write.
* @retval kStatus_HAL_UartSuccess Successfully start the data transmission.
* @retval kStatus_HAL_UartTxBusy Previous transmission still not finished; data not all written to TX register yet.
* @retval kStatus_HAL_UartError An error occurred.
*/
hal_uart_status_t HAL_UartSendNonBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length);
/*!
* @brief Gets the number of bytes that have been received.
*
* This function gets the number of bytes that have been received.
*
* @param handle UART handle pointer.
* @param count Receive bytes count.
* @retval kStatus_HAL_UartError An error occurred.
* @retval kStatus_Success Get successfully through the parameter \p count.
*/
hal_uart_status_t HAL_UartGetReceiveCount(hal_uart_handle_t handle, uint32_t *reCount);
/*!
* @brief Gets the number of bytes written to the UART TX register.
*
* This function gets the number of bytes written to the UART TX
* register by using the interrupt method.
*
* @param handle UART handle pointer.
* @param count Send bytes count.
* @retval kStatus_HAL_UartError An error occurred.
* @retval kStatus_Success Get successfully through the parameter \p count.
*/
hal_uart_status_t HAL_UartGetSendCount(hal_uart_handle_t handle, uint32_t *seCount);
/*!
* @brief Aborts the interrupt-driven data receiving.
*
* This function aborts the interrupt-driven data receiving. The user can get the remainBytes to know
* how many bytes are not received yet.
*
* @note The function #HAL_UartAbortReceive cannot be used to abort the transmission of
* the function #HAL_UartReceiveBlocking.
*
* @param handle UART handle pointer.
* @retval kStatus_Success Get successfully abort the receiving.
*/
hal_uart_status_t HAL_UartAbortReceive(hal_uart_handle_t handle);
/*!
* @brief Aborts the interrupt-driven data sending.
*
* This function aborts the interrupt-driven data sending. The user can get the remainBytes to find out
* how many bytes are not sent out.
*
* @note The function #HAL_UartAbortSend cannot be used to abort the transmission of
* the function #HAL_UartSendBlocking.
*
* @param handle UART handle pointer.
* @retval kStatus_Success Get successfully abort the sending.
*/
hal_uart_status_t HAL_UartAbortSend(hal_uart_handle_t handle);
/*! @}*/
#endif
#endif
#if (defined(HAL_UART_DMA_ENABLE) && (HAL_UART_DMA_ENABLE > 0U))
/*!
* @brief Initializes a UART dma instance with the UART dma handle and the user configuration structure.
*
* This function configures the UART dma module with user-defined settings. The user can configure the configuration
* structure. The parameter handle is a pointer to point to a memory space of size #HAL_UART_DMA_HANDLE_SIZE allocated
* by the caller. Example below shows how to use this API to configure the UART.
* @code
*
* Init TimerManager, only used in UART without Idleline interrupt
* timer_config_t timerConfig;
* timerConfig.srcClock_Hz = 16000000;
* timerConfig.instance = 0;
* TM_Init(&timerConfig);
*
* Init the DMA module
* DMA_Init(DMA0);
*
* Define a uart dma handle
* UART_HANDLE_DEFINE(g_uartHandle);
* UART_DMA_HANDLE_DEFINE(g_UartDmaHandle);
*
* Configure uart settings
* hal_uart_config_t uartConfig;
* uartConfig.srcClock_Hz = 48000000;
* uartConfig.baudRate_Bps = 115200;
* uartConfig.parityMode = kHAL_UartParityDisabled;
* uartConfig.stopBitCount = kHAL_UartOneStopBit;
* uartConfig.enableRx = 1;
* uartConfig.enableTx = 1;
* uartConfig.enableRxRTS = 0;
* uartConfig.enableTxCTS = 0;
* uartConfig.instance = 0;
*
* Init uart
* HAL_UartInit((hal_uart_handle_t *)g_uartHandle, &uartConfig);
*
* Configure uart dma settings
* hal_uart_dma_config_t dmaConfig;
* dmaConfig.uart_instance = 0;
* dmaConfig.dma_instance = 0;
* dmaConfig.rx_channel = 0;
* dmaConfig.tx_channel = 1;
*
* Init uart dma
* HAL_UartDMAInit((hal_uart_handle_t *)g_uartHandle, (hal_uart_dma_handle_t *)g_uartDmaHandle, &dmaConfig);
* @endcode
*
* @param handle UART handle pointer.
* @param dmaHandle Pointer to point to a memory space of size #HAL_UART_DMA_HANDLE_SIZE allocated by the caller.
* The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
* You can define the handle in the following two ways:
* #UART_DMA_HANDLE_DEFINE(handle);
* or
* uint32_t handle[((HAL_UART_DMA_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
* @param dmaConfig Pointer to user-defined configuration structure.
* @retval kStatus_HAL_UartDmaError UART dma initialization failed.
* @retval kStatus_HAL_UartDmaSuccess UART dma initialization succeed.
*/
hal_uart_dma_status_t HAL_UartDMAInit(hal_uart_handle_t handle,
hal_uart_dma_handle_t dmaHandle,
hal_uart_dma_config_t *dmaConfig);
/*!
* @brief Deinitializes a UART DMA instance.
*
* This function will abort uart dma receive/send transfer and deinitialize UART.
*
* @param handle UART handle pointer.
* @retval kStatus_HAL_UartDmaSuccess UART DMA de-initialization succeed
*/
hal_uart_dma_status_t HAL_UartDMADeinit(hal_uart_handle_t handle);
/*!
* @brief Installs a callback and callback parameter.
*
* This function is used to install the callback and callback parameter for UART DMA module.
* When any status of the UART DMA changed, the driver will notify the upper layer by the installed callback
* function. And the status is also passed as status parameter when the callback is called.
*
* @param handle UART handle pointer.
* @param callback The callback function.
* @param callbackParam The parameter of the callback function.
* @retval kStatus_HAL_UartDmaSuccess Successfully install the callback.
*/
hal_uart_dma_status_t HAL_UartDMATransferInstallCallback(hal_uart_handle_t handle,
hal_uart_dma_transfer_callback_t callback,
void *callbackParam);
/*!
* @brief Receives a buffer of data using an dma method.
*
* This function receives data using an dma method. This is a non-blocking function, which
* returns directly without waiting for all data to be received.
* The receive request is saved by the UART DMA driver.
* When all data is received, the UART DMA adapter notifies the upper layer
* through a callback function and passes the status parameter @ref kStatus_HAL_UartDmaRxIdle.
*
* When an idleline is detected, the UART DMA adapter notifies the upper layer through a callback function,
* and passes the status parameter @ref kStatus_HAL_UartDmaIdleline. For the UARTs without hardware idleline
* interrupt(like usart), it will use a software idleline detection method with the help of TimerManager.
*
* When the soc support cache, uplayer should do cache maintain operations for transfer buffer before call this API.
*
* @param handle UART handle pointer.
* @param data data Start address of the buffer to store the received data.
* @param length Size of the buffer.
* @param receiveAll Idleline interrupt will not end transfer process if set true.
* @retval kStatus_HAL_UartDmaSuccess Successfully start the data receive.
* @retval kStatus_HAL_UartDmaRxBusy Previous receive request is not finished.
*/
hal_uart_dma_status_t HAL_UartDMATransferReceive(hal_uart_handle_t handle,
uint8_t *data,
size_t length,
bool receiveAll);
/*!
* @brief Transmits a buffer of data using an dma method.
*
* This function sends data using an dma method. This is a non-blocking function, which
* returns directly without waiting for all data to be written to the TX register. When
* all data is written to the TX register by DMA, the UART DMA driver calls the callback
* function and passes the @ref kStatus_HAL_UartDmaTxIdle as status parameter.
*
* When the soc support cache, uplayer should do cache maintain operations for transfer buffer before call this API.
*
* @param handle UART handle pointer.
* @param data data Start address of the data to write.
* @param length Size of the data to write.
* @retval kStatus_HAL_UartDmaSuccess Successfully start the data transmission.
* @retval kStatus_HAL_UartDmaTxBusy Previous send request is not finished.
*/
hal_uart_dma_status_t HAL_UartDMATransferSend(hal_uart_handle_t handle, uint8_t *data, size_t length);
/*!
* @brief Gets the number of bytes that have been received.
*
* This function gets the number of bytes that have been received.
*
* @param handle UART handle pointer.
* @param reCount Receive bytes count.
* @retval kStatus_HAL_UartDmaError An error occurred.
* @retval kStatus_HAL_UartDmaSuccess Get successfully through the parameter \p reCount.
*/
hal_uart_dma_status_t HAL_UartDMAGetReceiveCount(hal_uart_handle_t handle, uint32_t *reCount);
/*!
* @brief Gets the number of bytes written to the UART TX register.
*
* This function gets the number of bytes written to the UART TX
* register by using the DMA method.
*
* @param handle UART handle pointer.
* @param count Send bytes count.
* @retval kStatus_HAL_UartDmaError An error occurred.
* @retval kStatus_HAL_UartDmaSuccess Get successfully through the parameter \p seCount.
*/
hal_uart_dma_status_t HAL_UartDMAGetSendCount(hal_uart_handle_t handle, uint32_t *seCount);
/*!
* @brief Aborts the DMA-driven data receiving.
*
* This function aborts the DMA-driven data receiving.
*
* @param handle UART handle pointer.
* @retval kStatus_HAL_UartDmaSuccess Get successfully abort the receiving.
*/
hal_uart_dma_status_t HAL_UartDMAAbortReceive(hal_uart_handle_t handle);
/*!
* @brief Aborts the DMA-driven data sending.
*
* This function aborts the DMA-driven data sending.
*
* @param handle UART handle pointer.
* @retval kStatus_Success Get successfully abort the sending.
*/
hal_uart_dma_status_t HAL_UartDMAAbortSend(hal_uart_handle_t handle);
#endif /* HAL_UART_DMA_ENABLE */
/*!
* @brief Prepares to enter low power consumption.
*
* This function is used to prepare to enter low power consumption.
*
* @param handle UART handle pointer.
* @retval kStatus_HAL_UartSuccess Successful operation.
* @retval kStatus_HAL_UartError An error occurred.
*/
hal_uart_status_t HAL_UartEnterLowpower(hal_uart_handle_t handle);
/*!
* @brief Restores from low power consumption.
*
* This function is used to restore from low power consumption.
*
* @param handle UART handle pointer.
* @retval kStatus_HAL_UartSuccess Successful operation.
* @retval kStatus_HAL_UartError An error occurred.
*/
hal_uart_status_t HAL_UartExitLowpower(hal_uart_handle_t handle);
#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
/*!
* @brief UART IRQ handle function.
*
* This function handles the UART transmit and receive IRQ request.
*
* @param handle UART handle pointer.
*/
void HAL_UartIsrFunction(hal_uart_handle_t handle);
#endif
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* __HAL_UART_ADAPTER_H__ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,627 @@
/*
** ###################################################################
** Version: rev. 4.0, 2020-05-18
** Build: b210526
**
** Abstract:
** Chip specific module features.
**
** Copyright 2016 Freescale Semiconductor, Inc.
** Copyright 2016-2021 NXP
** All rights reserved.
**
** SPDX-License-Identifier: BSD-3-Clause
**
** http: www.nxp.com
** mail: support@nxp.com
**
** Revisions:
** - rev. 1.0 (2019-04-19)
** Initial version.
** - rev. 2.0 (2019-07-22)
** Base on rev 0.7 RM.
** - rev. 3.0 (2020-03-16)
** Base on Rev.A RM.
** - rev. 4.0 (2020-05-18)
** Base on Rev.B RM.
**
** ###################################################################
*/
#ifndef _MIMXRT595S_cm33_FEATURES_H_
#define _MIMXRT595S_cm33_FEATURES_H_
/* SOC module features */
/* @brief ACMP availability on the SoC. */
#define FSL_FEATURE_SOC_ACMP_COUNT (1)
/* @brief AIPS availability on the SoC. */
#define FSL_FEATURE_SOC_AIPS_COUNT (2)
/* @brief CACHE64_CTRL availability on the SoC. */
#define FSL_FEATURE_SOC_CACHE64_CTRL_COUNT (2)
/* @brief CACHE64_POLSEL availability on the SoC. */
#define FSL_FEATURE_SOC_CACHE64_POLSEL_COUNT (2)
/* @brief CASPER availability on the SoC. */
#define FSL_FEATURE_SOC_CASPER_COUNT (1)
/* @brief CLKCTL0 availability on the SoC. */
#define FSL_FEATURE_SOC_CLKCTL0_COUNT (1)
/* @brief CLKCTL1 availability on the SoC. */
#define FSL_FEATURE_SOC_CLKCTL1_COUNT (1)
/* @brief CRC availability on the SoC. */
#define FSL_FEATURE_SOC_CRC_COUNT (1)
/* @brief CTIMER availability on the SoC. */
#define FSL_FEATURE_SOC_CTIMER_COUNT (5)
/* @brief DMA availability on the SoC. */
#define FSL_FEATURE_SOC_DMA_COUNT (2)
/* @brief DMIC availability on the SoC. */
#define FSL_FEATURE_SOC_DMIC_COUNT (1)
/* @brief FLEXCOMM availability on the SoC. */
#define FSL_FEATURE_SOC_FLEXCOMM_COUNT (17)
/* @brief FLEXIO availability on the SoC. */
#define FSL_FEATURE_SOC_FLEXIO_COUNT (1)
/* @brief FLEXSPI availability on the SoC. */
#define FSL_FEATURE_SOC_FLEXSPI_COUNT (2)
/* @brief FREQME availability on the SoC. */
#define FSL_FEATURE_SOC_FREQME_COUNT (1)
/* @brief GPIO availability on the SoC. */
#define FSL_FEATURE_SOC_GPIO_COUNT (1)
/* @brief SECGPIO availability on the SoC. */
#define FSL_FEATURE_SOC_SECGPIO_COUNT (1)
/* @brief HASHCRYPT availability on the SoC. */
#define FSL_FEATURE_SOC_HASHCRYPT_COUNT (1)
/* @brief I2C availability on the SoC. */
#define FSL_FEATURE_SOC_I2C_COUNT (15)
/* @brief I3C availability on the SoC. */
#define FSL_FEATURE_SOC_I3C_COUNT (2)
/* @brief I2S availability on the SoC. */
#define FSL_FEATURE_SOC_I2S_COUNT (14)
/* @brief INPUTMUX availability on the SoC. */
#define FSL_FEATURE_SOC_INPUTMUX_COUNT (1)
/* @brief IOPCTL availability on the SoC. */
#define FSL_FEATURE_SOC_IOPCTL_COUNT (1)
/* @brief LCDIF availability on the SoC. */
#define FSL_FEATURE_SOC_LCDIF_COUNT (1)
/* @brief LPADC availability on the SoC. */
#define FSL_FEATURE_SOC_LPADC_COUNT (1)
/* @brief MIPI_DSI_HOST availability on the SoC. */
#define FSL_FEATURE_SOC_MIPI_DSI_HOST_COUNT (1)
/* @brief MRT availability on the SoC. */
#define FSL_FEATURE_SOC_MRT_COUNT (1)
/* @brief MU availability on the SoC. */
#define FSL_FEATURE_SOC_MU_COUNT (1)
/* @brief OCOTP availability on the SoC. */
#define FSL_FEATURE_SOC_OCOTP_COUNT (1)
/* @brief OSTIMER availability on the SoC. */
#define FSL_FEATURE_SOC_OSTIMER_COUNT (1)
/* @brief OTFAD availability on the SoC. */
#define FSL_FEATURE_SOC_OTFAD_COUNT (1)
/* @brief PINT availability on the SoC. */
#define FSL_FEATURE_SOC_PINT_COUNT (1)
/* @brief PMC availability on the SoC. */
#define FSL_FEATURE_SOC_PMC_COUNT (1)
/* @brief POWERQUAD availability on the SoC. */
#define FSL_FEATURE_SOC_POWERQUAD_COUNT (1)
/* @brief PUF availability on the SoC. */
#define FSL_FEATURE_SOC_PUF_COUNT (1)
/* @brief RSTCTL0 availability on the SoC. */
#define FSL_FEATURE_SOC_RSTCTL0_COUNT (1)
/* @brief RSTCTL1 availability on the SoC. */
#define FSL_FEATURE_SOC_RSTCTL1_COUNT (1)
/* @brief RTC availability on the SoC. */
#define FSL_FEATURE_SOC_RTC_COUNT (1)
/* @brief SCT availability on the SoC. */
#define FSL_FEATURE_SOC_SCT_COUNT (1)
/* @brief SEMA42 availability on the SoC. */
#define FSL_FEATURE_SOC_SEMA42_COUNT (1)
/* @brief SMARTDMA availability on the SoC. */
#define FSL_FEATURE_SOC_SMARTDMA_COUNT (1)
/* @brief SPI availability on the SoC. */
#define FSL_FEATURE_SOC_SPI_COUNT (16)
/* @brief SYSCTL0 availability on the SoC. */
#define FSL_FEATURE_SOC_SYSCTL0_COUNT (1)
/* @brief SYSCTL1 availability on the SoC. */
#define FSL_FEATURE_SOC_SYSCTL1_COUNT (1)
/* @brief TRNG availability on the SoC. */
#define FSL_FEATURE_SOC_TRNG_COUNT (1)
/* @brief USART availability on the SoC. */
#define FSL_FEATURE_SOC_USART_COUNT (14)
/* @brief USBHSD availability on the SoC. */
#define FSL_FEATURE_SOC_USBHSD_COUNT (1)
/* @brief USBHSDCD availability on the SoC. */
#define FSL_FEATURE_SOC_USBHSDCD_COUNT (1)
/* @brief USBHSH availability on the SoC. */
#define FSL_FEATURE_SOC_USBHSH_COUNT (1)
/* @brief USBPHY availability on the SoC. */
#define FSL_FEATURE_SOC_USBPHY_COUNT (1)
/* @brief USDHC availability on the SoC. */
#define FSL_FEATURE_SOC_USDHC_COUNT (2)
/* @brief UTICK availability on the SoC. */
#define FSL_FEATURE_SOC_UTICK_COUNT (1)
/* @brief WWDT availability on the SoC. */
#define FSL_FEATURE_SOC_WWDT_COUNT (2)
/* ACMP module features */
/* @brief Has CMP_C3. */
#define FSL_FEATURE_ACMP_HAS_C3_REG (1)
/* @brief Has C0 LINKEN Bit */
#define FSL_FEATURE_ACMP_HAS_C0_LINKEN_BIT (1)
/* @brief Has C0 OFFSET Bit */
#define FSL_FEATURE_ACMP_HAS_C0_OFFSET_BIT (0)
/* @brief Has C1 INPSEL Bit */
#define FSL_FEATURE_ACMP_HAS_C1_INPSEL_BIT (0)
/* @brief Has C1 INNSEL Bit */
#define FSL_FEATURE_ACMP_HAS_C1_INNSEL_BIT (0)
/* @brief Has C1 DACOE Bit */
#define FSL_FEATURE_ACMP_HAS_C1_DACOE_BIT (0)
/* @brief Has C1 DMODE Bit */
#define FSL_FEATURE_ACMP_HAS_C1_DMODE_BIT (1)
/* @brief Has C2 RRE Bit */
#define FSL_FEATURE_ACMP_HAS_C2_RRE_BIT (0)
/* LPADC module features */
/* @brief FIFO availability on the SoC. */
#define FSL_FEATURE_LPADC_FIFO_COUNT (2)
/* @brief Does not support two simultanious single ended conversions (bitfield TCTRL[FIFO_SEL_B]). */
#define FSL_FEATURE_LPADC_HAS_NO_TCTRL_FIFO_SEL_B (1)
/* @brief Has subsequent trigger priority (bitfield CFG[TPRICTRL]). */
#define FSL_FEATURE_LPADC_HAS_CFG_SUBSEQUENT_PRIORITY (1)
/* @brief Has differential mode (bitfield CMDLn[DIFF]). */
#define FSL_FEATURE_LPADC_HAS_CMDL_DIFF (1)
/* @brief Has channel scale (bitfield CMDLn[CSCALE]). */
#define FSL_FEATURE_LPADC_HAS_CMDL_CSCALE (1)
/* @brief Has conversion type select (bitfield CMDLn[CTYPE]). */
#define FSL_FEATURE_LPADC_HAS_CMDL_CTYPE (0)
/* @brief Has conversion resolution select (bitfield CMDLn[MODE]). */
#define FSL_FEATURE_LPADC_HAS_CMDL_MODE (0)
/* @brief Has Wait for trigger assertion before execution (bitfield CMDHn[WAIT_TRIG]). */
#define FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG (1)
/* @brief Has offset calibration (bitfield CTRL[CALOFS]). */
#define FSL_FEATURE_LPADC_HAS_CTRL_CALOFS (0)
/* @brief Has gain calibration (bitfield CTRL[CAL_REQ]). */
#define FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ (0)
/* @brief Has calibration average (bitfield CTRL[CAL_AVGS]). */
#define FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS (0)
/* @brief Has internal clock (bitfield CFG[ADCKEN]). */
#define FSL_FEATURE_LPADC_HAS_CFG_ADCKEN (0)
/* @brief Enable support for low voltage reference on option 1 reference (bitfield CFG[VREF1RNG]). */
#define FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG (0)
/* @brief Has calibration (bitfield CFG[CALOFS]). */
#define FSL_FEATURE_LPADC_HAS_CFG_CALOFS (0)
/* @brief Has offset trim (register OFSTRIM). */
#define FSL_FEATURE_LPADC_HAS_OFSTRIM (0)
/* CACHE64_CTRL module features */
/* @brief Cache Line size in byte. */
#define FSL_FEATURE_CACHE64_CTRL_LINESIZE_BYTE (32)
/* CACHE64_POLSEL module features */
/* No feature definitions */
/* CASPER module features */
/* @brief Base address of the CASPER dedicated RAM. */
#define FSL_FEATURE_CASPER_RAM_BASE_ADDRESS (0x40202000u)
/* CRC module features */
/* @brief Has data register with name CRC */
#define FSL_FEATURE_CRC_HAS_CRC_REG (0)
/* DMA module features */
/* @brief Number of channels */
#define FSL_FEATURE_DMA_NUMBER_OF_CHANNELSn(x) (37)
/* @brief Number of all DMA channels */
#define FSL_FEATURE_DMA_ALL_CHANNELS (74)
/* @brief Max Number of DMA channels */
#define FSL_FEATURE_DMA_MAX_CHANNELS (37)
/* @brief Align size of DMA descriptor */
#define FSL_FEATURE_DMA_DESCRIPTOR_ALIGN_SIZE (1024)
/* @brief DMA head link descriptor table align size */
#define FSL_FEATURE_DMA_LINK_DESCRIPTOR_ALIGN_SIZE (16U)
/* DMIC module features */
/* @brief Number of channels */
#define FSL_FEATURE_DMIC_CHANNEL_NUM (8)
/* @brief DMIC channel support stereo data */
#define FSL_FEATURE_DMIC_IO_HAS_STEREO_2_4_6 (1)
/* @brief DMIC does not support bypass channel clock */
#define FSL_FEATURE_DMIC_IO_HAS_NO_BYPASS (1)
/* @brief DMIC channel FIFO register support sign extended */
#define FSL_FEATURE_DMIC_CHANNEL_HAS_SIGNEXTEND (1)
/* @brief DMIC has no IOCFG register */
#define FSL_FEATURE_DMIC_HAS_NO_IOCFG (1)
/* @brief DMIC has decimator reset function */
#define FSL_FEATURE_DMIC_HAS_DECIMATOR_RESET_FUNC (1)
/* @brief DMIC has global channel synchronization function */
#define FSL_FEATURE_DMIC_HAS_GLOBAL_SYNC_FUNC (1)
/* FLEXCOMM module features */
/* @brief FLEXCOMM0 USART INDEX 0 */
#define FSL_FEATURE_FLEXCOMM0_USART_INDEX (0)
/* @brief FLEXCOMM0 SPI INDEX 0 */
#define FSL_FEATURE_FLEXCOMM0_SPI_INDEX (0)
/* @brief FLEXCOMM0 I2C INDEX 0 */
#define FSL_FEATURE_FLEXCOMM0_I2C_INDEX (0)
/* @brief FLEXCOMM0 I2S INDEX 0 */
#define FSL_FEATURE_FLEXCOMM0_I2S_INDEX (0)
/* @brief FLEXCOMM1 USART INDEX 1 */
#define FSL_FEATURE_FLEXCOMM1_USART_INDEX (1)
/* @brief FLEXCOMM1 SPI INDEX 1 */
#define FSL_FEATURE_FLEXCOMM1_SPI_INDEX (1)
/* @brief FLEXCOMM1 I2C INDEX 1 */
#define FSL_FEATURE_FLEXCOMM1_I2C_INDEX (1)
/* @brief FLEXCOMM1 I2S INDEX 1 */
#define FSL_FEATURE_FLEXCOMM1_I2S_INDEX (1)
/* @brief FLEXCOMM2 USART INDEX 2 */
#define FSL_FEATURE_FLEXCOMM2_USART_INDEX (2)
/* @brief FLEXCOMM2 SPI INDEX 2 */
#define FSL_FEATURE_FLEXCOMM2_SPI_INDEX (2)
/* @brief FLEXCOMM2 I2C INDEX 2 */
#define FSL_FEATURE_FLEXCOMM2_I2C_INDEX (2)
/* @brief FLEXCOMM2 I2S INDEX 2 */
#define FSL_FEATURE_FLEXCOMM2_I2S_INDEX (2)
/* @brief FLEXCOMM3 USART INDEX 3 */
#define FSL_FEATURE_FLEXCOMM3_USART_INDEX (3)
/* @brief FLEXCOMM3 SPI INDEX 3 */
#define FSL_FEATURE_FLEXCOMM3_SPI_INDEX (3)
/* @brief FLEXCOMM3 I2C INDEX 3 */
#define FSL_FEATURE_FLEXCOMM3_I2C_INDEX (3)
/* @brief FLEXCOMM3 I2S INDEX 3 */
#define FSL_FEATURE_FLEXCOMM3_I2S_INDEX (3)
/* @brief FLEXCOMM4 USART INDEX 4 */
#define FSL_FEATURE_FLEXCOMM4_USART_INDEX (4)
/* @brief FLEXCOMM4 SPI INDEX 4 */
#define FSL_FEATURE_FLEXCOMM4_SPI_INDEX (4)
/* @brief FLEXCOMM4 I2C INDEX 4 */
#define FSL_FEATURE_FLEXCOMM4_I2C_INDEX (4)
/* @brief FLEXCOMM4 I2S INDEX 4 */
#define FSL_FEATURE_FLEXCOMM4_I2S_INDEX (4)
/* @brief FLEXCOMM5 USART INDEX 5 */
#define FSL_FEATURE_FLEXCOMM5_USART_INDEX (5)
/* @brief FLEXCOMM5 SPI INDEX 5 */
#define FSL_FEATURE_FLEXCOMM5_SPI_INDEX (5)
/* @brief FLEXCOMM5 I2C INDEX 5 */
#define FSL_FEATURE_FLEXCOMM5_I2C_INDEX (5)
/* @brief FLEXCOMM5 I2S INDEX 5 */
#define FSL_FEATURE_FLEXCOMM5_I2S_INDEX (5)
/* @brief FLEXCOMM6 USART INDEX 6 */
#define FSL_FEATURE_FLEXCOMM6_USART_INDEX (6)
/* @brief FLEXCOMM6 SPI INDEX 6 */
#define FSL_FEATURE_FLEXCOMM6_SPI_INDEX (6)
/* @brief FLEXCOMM6 I2C INDEX 6 */
#define FSL_FEATURE_FLEXCOMM6_I2C_INDEX (6)
/* @brief FLEXCOMM6 I2S INDEX 6 */
#define FSL_FEATURE_FLEXCOMM6_I2S_INDEX (6)
/* @brief FLEXCOMM7 USART INDEX 7 */
#define FSL_FEATURE_FLEXCOMM7_USART_INDEX (7)
/* @brief FLEXCOMM7 SPI INDEX 7 */
#define FSL_FEATURE_FLEXCOMM7_SPI_INDEX (7)
/* @brief FLEXCOMM7 I2C INDEX 7 */
#define FSL_FEATURE_FLEXCOMM7_I2C_INDEX (7)
/* @brief FLEXCOMM7 I2S INDEX 7 */
#define FSL_FEATURE_FLEXCOMM7_I2S_INDEX (7)
/* @brief I2S has DMIC interconnection */
#define FSL_FEATURE_FLEXCOMM_INSTANCE_I2S_HAS_DMIC_INTERCONNECTIONn(x) \
(((x) == FLEXCOMM0) ? (1) : \
(((x) == FLEXCOMM1) ? (0) : \
(((x) == FLEXCOMM2) ? (0) : \
(((x) == FLEXCOMM3) ? (0) : \
(((x) == FLEXCOMM4) ? (0) : \
(((x) == FLEXCOMM5) ? (0) : \
(((x) == FLEXCOMM6) ? (0) : \
(((x) == FLEXCOMM7) ? (0) : \
(((x) == FLEXCOMM14) ? (0) : \
(((x) == FLEXCOMM15) ? (0) : \
(((x) == FLEXCOMM16) ? (0) : \
(((x) == FLEXCOMM8) ? (0) : \
(((x) == FLEXCOMM9) ? (0) : \
(((x) == FLEXCOMM10) ? (0) : \
(((x) == FLEXCOMM11) ? (0) : \
(((x) == FLEXCOMM12) ? (0) : \
(((x) == FLEXCOMM13) ? (0) : (-1))))))))))))))))))
/* @brief FLEXCOMM14 SPI(HS_SPI) INDEX 14 */
#define FSL_FEATURE_FLEXCOMM14_SPI_INDEX (14)
/* @brief FLEXCOMM15 I2C INDEX 15 */
#define FSL_FEATURE_FLEXCOMM15_I2C_INDEX (15)
/* @brief FLEXCOMM16 SPI(HS_SPI) INDEX 16 */
#define FSL_FEATURE_FLEXCOMM16_SPI_INDEX (16)
/* @brief FLEXCOMM8 USART INDEX 8 */
#define FSL_FEATURE_FLEXCOMM8_USART_INDEX (8)
/* @brief FLEXCOMM9 USART INDEX 9 */
#define FSL_FEATURE_FLEXCOMM9_USART_INDEX (9)
/* @brief FLEXCOMM10 USART INDEX 10 */
#define FSL_FEATURE_FLEXCOMM10_USART_INDEX (10)
/* @brief FLEXCOMM11 USART INDEX 11 */
#define FSL_FEATURE_FLEXCOMM11_USART_INDEX (11)
/* @brief FLEXCOMM12 USART INDEX 12 */
#define FSL_FEATURE_FLEXCOMM12_USART_INDEX (12)
/* @brief FLEXCOMM13 USART INDEX 13 */
#define FSL_FEATURE_FLEXCOMM13_USART_INDEX (13)
/* @brief FLEXCOMM8 SPI INDEX 8 */
#define FSL_FEATURE_FLEXCOMM8_SPI_INDEX (8)
/* @brief FLEXCOMM9 SPI INDEX 9 */
#define FSL_FEATURE_FLEXCOMM9_SPI_INDEX (9)
/* @brief FLEXCOMM10 SPI INDEX 10 */
#define FSL_FEATURE_FLEXCOMM10_SPI_INDEX (10)
/* @brief FLEXCOMM11 SPI INDEX 11 */
#define FSL_FEATURE_FLEXCOMM11_SPI_INDEX (11)
/* @brief FLEXCOMM12 SPI INDEX 12 */
#define FSL_FEATURE_FLEXCOMM12_SPI_INDEX (12)
/* @brief FLEXCOMM13 SPI INDEX 13 */
#define FSL_FEATURE_FLEXCOMM13_SPI_INDEX (13)
/* @brief FLEXCOMM8 I2C INDEX 8 */
#define FSL_FEATURE_FLEXCOMM8_I2C_INDEX (8)
/* @brief FLEXCOMM9 I2C INDEX 9 */
#define FSL_FEATURE_FLEXCOMM9_I2C_INDEX (9)
/* @brief FLEXCOMM10 I2C INDEX 10 */
#define FSL_FEATURE_FLEXCOMM10_I2C_INDEX (10)
/* @brief FLEXCOMM11 I2C INDEX 11 */
#define FSL_FEATURE_FLEXCOMM11_I2C_INDEX (11)
/* @brief FLEXCOMM12 I2C INDEX 12 */
#define FSL_FEATURE_FLEXCOMM12_I2C_INDEX (12)
/* @brief FLEXCOMM13 I2C INDEX 13 */
#define FSL_FEATURE_FLEXCOMM13_I2C_INDEX (13)
/* @brief FLEXCOMM8 I2S INDEX 8 */
#define FSL_FEATURE_FLEXCOMM8_I2S_INDEX (8)
/* @brief FLEXCOMM9 I2S INDEX 9 */
#define FSL_FEATURE_FLEXCOMM9_I2S_INDEX (9)
/* @brief FLEXCOMM10 I2S INDEX 10 */
#define FSL_FEATURE_FLEXCOMM10_I2S_INDEX (10)
/* @brief FLEXCOMM11 I2S INDEX 11 */
#define FSL_FEATURE_FLEXCOMM11_I2S_INDEX (11)
/* @brief FLEXCOMM12 I2S INDEX 12 */
#define FSL_FEATURE_FLEXCOMM12_I2S_INDEX (12)
/* @brief FLEXCOMM13 I2S INDEX 13 */
#define FSL_FEATURE_FLEXCOMM13_I2S_INDEX (13)
/* FLEXIO module features */
/* @brief FLEXIO support reset from RSTCTL */
#define FSL_FEATURE_FLEXIO_HAS_RESET (1)
/* @brief Has Shifter Status Register (FLEXIO_SHIFTSTAT) */
#define FSL_FEATURE_FLEXIO_HAS_SHIFTER_STATUS (1)
/* @brief Has Pin Data Input Register (FLEXIO_PIN) */
#define FSL_FEATURE_FLEXIO_HAS_PIN_STATUS (1)
/* @brief Has Shifter Buffer N Nibble Byte Swapped Register (FLEXIO_SHIFTBUFNBSn) */
#define FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP (1)
/* @brief Has Shifter Buffer N Half Word Swapped Register (FLEXIO_SHIFTBUFHWSn) */
#define FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP (1)
/* @brief Has Shifter Buffer N Nibble Swapped Register (FLEXIO_SHIFTBUFNISn) */
#define FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP (1)
/* @brief Supports Shifter State Mode (FLEXIO_SHIFTCTLn[SMOD]) */
#define FSL_FEATURE_FLEXIO_HAS_STATE_MODE (1)
/* @brief Supports Shifter Logic Mode (FLEXIO_SHIFTCTLn[SMOD]) */
#define FSL_FEATURE_FLEXIO_HAS_LOGIC_MODE (1)
/* @brief Supports paralle width (FLEXIO_SHIFTCFGn[PWIDTH]) */
#define FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH (1)
/* @brief Reset value of the FLEXIO_VERID register */
#define FSL_FEATURE_FLEXIO_VERID_RESET_VALUE (0x2010003)
/* @brief Reset value of the FLEXIO_PARAM register */
#define FSL_FEATURE_FLEXIO_PARAM_RESET_VALUE (0x10100808)
/* FLEXSPI module features */
/* @brief FlexSPI AHB buffer count */
#define FSL_FEATURE_FLEXSPI_AHB_BUFFER_COUNTn(x) (8)
/* @brief FlexSPI0 and FlexSPI1 have shared IRQ */
#define FSL_FEATURE_FLEXSPI_HAS_SHARED_IRQ0_IRQ1 (1)
/* @brief FlexSPI has no MCR0 ARDFEN bit */
#define FSL_FEATURE_FLEXSPI_HAS_NO_MCR0_ARDFEN (1)
/* @brief FlexSPI has no MCR0 ATDFEN bit */
#define FSL_FEATURE_FLEXSPI_HAS_NO_MCR0_ATDFEN (1)
/* @brief FlexSPI DMA needs multiple DES to transfer */
#define FSL_FEATURE_FLEXSPI_DMA_MULTIPLE_DES (1)
/* @brief FlexSPI uses min DQS delay */
#define FSL_FEATURE_FLEXSPI_DQS_DELAY_MIN (1)
/* @brief FlexSPI has no MCR0 COMBINATIONEN bit */
#define FSL_FEATURE_FLEXSPI_HAS_NO_MCR0_COMBINATIONEN (1)
/* GPIO module features */
/* @brief GPIO has interrupts */
#define FSL_FEATURE_GPIO_HAS_INTERRUPT (1)
/* HASHCRYPT module features */
/* @brief hashcrypt has reload feature */
#define FSL_FEATURE_HASHCRYPT_HAS_RELOAD_FEATURE (1)
/* I2S module features */
/* @brief I2S support dual channel transfer. */
#define FSL_FEATURE_I2S_SUPPORT_SECONDARY_CHANNEL (1)
/* @brief I2S has DMIC interconnection. */
#define FSL_FEATURE_FLEXCOMM_I2S_HAS_DMIC_INTERCONNECTION (1)
/* INPUTMUX module features */
/* @brief Number of channels */
#define FSL_FEATURE_INPUTMUX_HAS_SIGNAL_ENA (1)
/* @brief Inputmux has channel mux control */
#define FSL_FEATURE_INPUTMUX_HAS_CHANNEL_MUX (1)
/* MIPI_DSI_HOST module features */
/* @brief Does not have DPHY PLL */
#define FSL_FEATURE_MIPI_DSI_HOST_NO_DPHY_PLL (1)
/* @brief Support TX ULPS */
#define FSL_FEATURE_MIPI_DSI_HOST_HAS_ULPS (0)
/* @brief Has control register to enable or disable TX ULPS */
#define FSL_FEATURE_MIPI_DSI_HOST_HAS_ULPS_CTRL (0)
/* @brief Has pixel-link to DPI remap */
#define FSL_FEATURE_MIPI_DSI_HOST_HAS_PXL2DPI (0)
/* MRT module features */
/* @brief number of channels. */
#define FSL_FEATURE_MRT_NUMBER_OF_CHANNELS (4)
/* MU module features */
/* @brief MU side for current core */
#define FSL_FEATURE_MU_SIDE_A (1)
/* @brief MU Has register CCR */
#define FSL_FEATURE_MU_HAS_CCR (0)
/* @brief MU Has register SR[RS], BSR[ARS] */
#define FSL_FEATURE_MU_HAS_SR_RS (1)
/* @brief MU Has register CR[RDIE], CR[RAIE], SR[RDIP], SR[RAIP] */
#define FSL_FEATURE_MU_HAS_RESET_INT (1)
/* @brief MU Has register SR[MURIP] */
#define FSL_FEATURE_MU_HAS_SR_MURIP (0)
/* @brief brief MU Has register SR[HRIP] */
#define FSL_FEATURE_MU_HAS_SR_HRIP (0)
/* @brief brief MU does not support enable clock of the other core, CR[CLKE] or CCR[CLKE]. */
#define FSL_FEATURE_MU_NO_CLKE (1)
/* @brief brief MU does not support NMI, CR[NMI]. */
#define FSL_FEATURE_MU_NO_NMI (1)
/* @brief brief MU does not support hold the other core reset. CR[RSTH] or CCR[RSTH]. */
#define FSL_FEATURE_MU_NO_RSTH (1)
/* @brief brief MU does not supports MU reset, CR[MUR]. */
#define FSL_FEATURE_MU_NO_MUR (0)
/* @brief brief MU does not supports hardware reset, CR[HR] or CCR[HR]. */
#define FSL_FEATURE_MU_NO_HR (1)
/* @brief brief MU supports mask the hardware reset. CR[HRM] or CCR[HRM]. */
#define FSL_FEATURE_MU_HAS_HRM (0)
/* OTFAD module features */
/* @brief OTFAD has Security Violation Mode (SVM) */
#define FSL_FEATURE_OTFAD_HAS_SVM_MODE (0)
/* @brief OTFAD has Key Blob Processing */
#define FSL_FEATURE_OTFAD_HAS_KEYBLOB_PROCESSING (0)
/* @brief OTFAD has interrupt request enable */
#define FSL_FEATURE_OTFAD_HAS_HAS_IRQ_ENABLE (0)
/* @brief OTFAD has Force Error */
#define FSL_FEATURE_OTFAD_HAS_FORCE_ERR (0)
/* PINT module features */
/* @brief Number of connected outputs */
#define FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS (8)
/* PMC module features */
/* @brief Has no OS Timer control register in PMC. */
#define FSL_FEATURE_PMC_HAS_NO_OSTIMER_REG (1)
/* PUF module features */
/* @brief PUF need to setup SRAM manually */
#define FSL_FEATURE_PUF_PWR_HAS_MANUAL_SLEEP_CONTROL (1)
/* @brief PUF has SHIFT_STATUS register. */
#define FSL_FEATURE_PUF_HAS_SHIFT_STATUS (0)
/* @brief PUF has IDXBLK_SHIFT register. */
#define FSL_FEATURE_PUF_HAS_IDXBLK_SHIFT (0)
/* RTC module features */
/* @brief RTC does not support reset from RSTCTL. */
#define FSL_FEATURE_RTC_HAS_NO_RESET (1)
/* SCT module features */
/* @brief Number of events */
#define FSL_FEATURE_SCT_NUMBER_OF_EVENTS (16)
/* @brief Number of states */
#define FSL_FEATURE_SCT_NUMBER_OF_STATES (32)
/* @brief Number of match capture */
#define FSL_FEATURE_SCT_NUMBER_OF_MATCH_CAPTURE (16)
/* @brief Number of outputs */
#define FSL_FEATURE_SCT_NUMBER_OF_OUTPUTS (10)
/* SECGPIO module features */
/* @brief GPIO has interrupts */
#define FSL_FEATURE_SECGPIO_HAS_INTERRUPT (1)
/* SEMA42 module features */
/* @brief Gate counts */
#define FSL_FEATURE_SEMA42_GATE_COUNT (16)
/* TRNG module features */
/* @brief Need configure default frequency minimum value */
#define FSL_FEATURE_TRNG_FORCE_USER_CONFIG_DEFAULT_FREQUENCY_MINIMUM (1)
/* @brief The user configured frequency minimum value */
#define FSL_FEATURE_TRNG_USER_CONFIG_DEFAULT_FREQUENCY_MINIMUM_VALUE (0)
/* USBHSD module features */
/* @brief Size of the USB dedicated RAM */
#define FSL_FEATURE_USBHSD_USB_RAM (0x00004000)
/* @brief Base address of the USB dedicated RAM */
#define FSL_FEATURE_USBHSD_USB_RAM_BASE_ADDRESS (0x40140000)
/* @brief USBHSD version */
#define FSL_FEATURE_USBHSD_VERSION (300)
/* @brief Number of the endpoint in USB HS */
#define FSL_FEATURE_USBHSD_EP_NUM (6)
/* @brief The controller doesn't exit HS mode automatically after vbus becomes invalid */
#define FSL_FEATURE_USBHSD_HAS_EXIT_HS_ISSUE (1)
/* USBHSH module features */
/* @brief Size of the USB dedicated RAM */
#define FSL_FEATURE_USBHSH_USB_RAM (0x00004000)
/* @brief Base address of the USB dedicated RAM */
#define FSL_FEATURE_USBHSH_USB_RAM_BASE_ADDRESS (0x40140000)
/* @brief USBHSH version */
#define FSL_FEATURE_USBHSH_VERSION (300)
/* @brief USBHSH has packet turnaround time-out register */
#define FSL_FEATURE_USBHSH_HAS_TURNAROUND_TIMEOUT (0)
/* USBPHY module features */
/* @brief USBPHY contain DCD analog module */
#define FSL_FEATURE_USBPHY_HAS_DCD_ANALOG (1)
/* @brief USBPHY has register TRIM_OVERRIDE_EN */
#define FSL_FEATURE_USBPHY_HAS_TRIM_OVERRIDE_EN (1)
/* @brief USBPHY is 28FDSOI */
#define FSL_FEATURE_USBPHY_28FDSOI (0)
/* USDHC module features */
/* @brief Has external DMA support (VEND_SPEC[EXT_DMA_EN]) */
#define FSL_FEATURE_USDHC_HAS_EXT_DMA (0)
/* @brief Has HS400 mode (MIX_CTRL[HS400_MODE]) */
#define FSL_FEATURE_USDHC_HAS_HS400_MODE (1)
/* @brief Has SDR50 support (HOST_CTRL_CAP[SDR50_SUPPORT]) */
#define FSL_FEATURE_USDHC_HAS_SDR50_MODE (1)
/* @brief Has SDR104 support (HOST_CTRL_CAP[SDR104_SUPPORT]) */
#define FSL_FEATURE_USDHC_HAS_SDR104_MODE (1)
/* @brief USDHC has reset control */
#define FSL_FEATURE_USDHC_HAS_RESET (1)
/* @brief USDHC has no bitfield WTMK_LVL[WR_BRST_LEN] and WTMK_LVL[RD_BRST_LEN] */
#define FSL_FEATURE_USDHC_HAS_NO_RW_BURST_LEN (0)
/* @brief If USDHC instance support 8 bit width */
#define FSL_FEATURE_USDHC_INSTANCE_SUPPORT_8_BIT_WIDTHn(x) (1)
/* @brief If USDHC instance support HS400 mode */
#define FSL_FEATURE_USDHC_INSTANCE_SUPPORT_HS400_MODEn(x) \
(((x) == USDHC0) ? (1) : \
(((x) == USDHC1) ? (0) : (-1)))
/* @brief If USDHC instance support 1v8 signal */
#define FSL_FEATURE_USDHC_INSTANCE_SUPPORT_1V8_SIGNALn(x) (1)
/* @brief Has no retuning time counter (HOST_CTRL_CAP[TIME_COUNT_RETURNING]) */
#define FSL_FEATURE_USDHC_REGISTER_HOST_CTRL_CAP_HAS_NO_RETUNING_TIME_COUNTER (0)
/* UTICK module features */
/* @brief UTICK does not support power down configure. */
#define FSL_FEATURE_UTICK_HAS_NO_PDCFG (1)
/* WWDT module features */
/* @brief WWDT does not support oscillator lock. */
#define FSL_FEATURE_WWDT_HAS_NO_OSCILLATOR_LOCK (0)
/* @brief WWDT does not support power down configure. */
#define FSL_FEATURE_WWDT_HAS_NO_PDCFG (1)
#endif /* _MIMXRT595S_cm33_FEATURES_H_ */

View file

@ -0,0 +1,44 @@
/*
* Copyright 2014-2016 Freescale Semiconductor, Inc.
* Copyright 2016-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef __FSL_DEVICE_REGISTERS_H__
#define __FSL_DEVICE_REGISTERS_H__
/*
* Include the cpu specific register header files.
*
* The CPU macro should be declared in the project or makefile.
*/
#if (defined(CPU_MIMXRT595SFAWC_cm33) || defined(CPU_MIMXRT595SFFOC_cm33))
#define MIMXRT595S_cm33_SERIES
/* CMSIS-style register definitions */
#include "MIMXRT595S_cm33.h"
/* CPU specific feature definitions */
#include "MIMXRT595S_cm33_features.h"
#elif (defined(CPU_MIMXRT595SFAWC_dsp) || defined(CPU_MIMXRT595SFFOC_dsp))
#define MIMXRT595S_dsp_SERIES
/* CMSIS-style register definitions */
#include "MIMXRT595S_dsp.h"
/* CPU specific feature definitions */
#include "MIMXRT595S_dsp_features.h"
#else
#error "No valid CPU defined!"
#endif
#endif /* __FSL_DEVICE_REGISTERS_H__ */
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,232 @@
/*
** ###################################################################
** Processors: MIMXRT595SFAWC_cm33
** MIMXRT595SFFOC_cm33
**
** Compilers: GNU C Compiler
** IAR ANSI C/C++ Compiler for ARM
** Keil ARM C/C++ Compiler
** MCUXpresso Compiler
**
** Reference manual: RT500 Reference Manual. Rev.C, 8/2020
** Version: rev. 5.0, 2020-08-27
** Build: b201016
**
** Abstract:
** Provides a system configuration function and a global variable that
** contains the system frequency. It configures the device and initializes
** the oscillator (PLL) that is part of the microcontroller device.
**
** Copyright 2016 Freescale Semiconductor, Inc.
** Copyright 2016-2020 NXP
** All rights reserved.
**
** SPDX-License-Identifier: BSD-3-Clause
**
** http: www.nxp.com
** mail: support@nxp.com
**
** Revisions:
** - rev. 1.0 (2019-04-19)
** Initial version.
** - rev. 2.0 (2019-07-22)
** Base on rev 0.7 RM.
** - rev. 3.0 (2020-03-16)
** Base on Rev.A RM.
** - rev. 4.0 (2020-05-18)
** Base on Rev.B RM.
** - rev. 5.0 (2020-08-27)
** Base on Rev.C RM.
**
** ###################################################################
*/
/*!
* @file MIMXRT595S_cm33
* @version 5.0
* @date 2020-08-27
* @brief Device specific configuration file for MIMXRT595S_cm33 (implementation
* file)
*
* Provides a system configuration function and a global variable that contains
* the system frequency. It configures the device and initializes the oscillator
* (PLL) that is part of the microcontroller device.
*/
#include <stdint.h>
#include "fsl_device_registers.h"
#define SYSTEM_IS_XIP_FLEXSPI() \
((((uint32_t)SystemCoreClockUpdate >= 0x08000000U) && ((uint32_t)SystemCoreClockUpdate < 0x10000000U)) || \
(((uint32_t)SystemCoreClockUpdate >= 0x18000000U) && ((uint32_t)SystemCoreClockUpdate < 0x20000000U)))
/* Get OSC clock from SYSOSCBYPASS */
static uint32_t getOscClk(void)
{
return (CLKCTL0->SYSOSCBYPASS == 0U) ? CLK_XTAL_OSC_CLK : ((CLKCTL0->SYSOSCBYPASS == 1U) ? CLK_EXT_CLKIN : 0U);
}
/* Get FRO DIV clock from FRODIVSEL */
static uint32_t getFroDivClk(void)
{
uint32_t freq = 0U;
switch ((CLKCTL0->FRODIVSEL) & CLKCTL0_FRODIVSEL_SEL_MASK)
{
case CLKCTL0_FRODIVSEL_SEL(0):
freq = CLK_FRO_DIV2_CLK;
break;
case CLKCTL0_FRODIVSEL_SEL(1):
freq = CLK_FRO_DIV4_CLK;
break;
case CLKCTL0_FRODIVSEL_SEL(2):
freq = CLK_FRO_DIV8_CLK;
break;
case CLKCTL0_FRODIVSEL_SEL(3):
freq = CLK_FRO_DIV16_CLK;
break;
default:
freq = 0U;
break;
}
return freq;
}
/* ----------------------------------------------------------------------------
-- Core clock
---------------------------------------------------------------------------- */
uint32_t SystemCoreClock = DEFAULT_SYSTEM_CLOCK;
/* ----------------------------------------------------------------------------
-- SystemInit()
---------------------------------------------------------------------------- */
__attribute__((weak)) void SystemInit(void)
{
#if ((__FPU_PRESENT == 1) && (__FPU_USED == 1))
SCB->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); /* set CP10, CP11 Full Access in Secure mode */
#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
SCB_NS->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); /* set CP10, CP11 Full Access in Non-secure mode */
#endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
#endif /* ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) */
SCB->CPACR |= ((3UL << 0 * 2) | (3UL << 1 * 2)); /* set CP0, CP1 Full Access in Secure mode (enable PowerQuad) */
#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
SCB_NS->CPACR |=
((3UL << 0 * 2) | (3UL << 1 * 2)); /* set CP0, CP1 Full Access in Non-secure mode (enable PowerQuad) */
#endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
SCB->NSACR |= ((3UL << 0) | (3UL << 10)); /* enable CP0, CP1, CP10, CP11 Non-secure Access */
SYSCTL0->DSPSTALL = SYSCTL0_DSPSTALL_DSPSTALL_MASK;
PMC->CTRL |= PMC_CTRL_CLKDIVEN_MASK; /* enable the internal clock divider for power saving */
if (SYSTEM_IS_XIP_FLEXSPI() && (CACHE64_POLSEL0->POLSEL == 0U)) /* set CAHCHE64 if not configured */
{
/* set command to invalidate all ways and write GO bit to initiate command */
CACHE64_CTRL0->CCR = CACHE64_CTRL_CCR_INVW1_MASK | CACHE64_CTRL_CCR_INVW0_MASK;
CACHE64_CTRL0->CCR |= CACHE64_CTRL_CCR_GO_MASK;
/* Wait until the command completes */
while ((CACHE64_CTRL0->CCR & CACHE64_CTRL_CCR_GO_MASK) != 0U)
{
}
/* Enable cache, enable write buffer */
CACHE64_CTRL0->CCR = (CACHE64_CTRL_CCR_ENWRBUF_MASK | CACHE64_CTRL_CCR_ENCACHE_MASK);
/* Set whole FlexSPI0 space to write through. */
CACHE64_POLSEL0->REG0_TOP = 0x07FFFC00U;
CACHE64_POLSEL0->REG1_TOP = 0x0U;
CACHE64_POLSEL0->POLSEL = 0x1U;
__ISB();
__DSB();
}
SystemInitHook();
}
/* ----------------------------------------------------------------------------
-- SystemCoreClockUpdate()
---------------------------------------------------------------------------- */
void SystemCoreClockUpdate(void)
{
/* iMXRT5xx systemCoreClockUpdate */
uint32_t freq = 0U;
uint64_t freqTmp = 0U;
switch ((CLKCTL0->MAINCLKSELB) & CLKCTL0_MAINCLKSELB_SEL_MASK)
{
case CLKCTL0_MAINCLKSELB_SEL(0): /* MAINCLKSELA clock */
switch ((CLKCTL0->MAINCLKSELA) & CLKCTL0_MAINCLKSELA_SEL_MASK)
{
case CLKCTL0_MAINCLKSELA_SEL(0): /* Low Power Oscillator Clock (1m_lposc) */
freq = CLK_LPOSC_1MHZ;
break;
case CLKCTL0_MAINCLKSELA_SEL(1): /* FRO DIV clock */
freq = getFroDivClk();
break;
case CLKCTL0_MAINCLKSELA_SEL(2): /* OSC clock */
freq = getOscClk();
break;
case CLKCTL0_MAINCLKSELA_SEL(3): /* FRO clock */
freq = CLK_FRO_CLK;
break;
default:
freq = 0U;
break;
}
break;
case CLKCTL0_MAINCLKSELB_SEL(1): /* Main System PLL clock */
switch ((CLKCTL0->SYSPLL0CLKSEL) & CLKCTL0_SYSPLL0CLKSEL_SEL_MASK)
{
case CLKCTL0_SYSPLL0CLKSEL_SEL(0): /* FRO_DIV8 clock */
freq = CLK_FRO_DIV8_CLK;
break;
case CLKCTL0_SYSPLL0CLKSEL_SEL(1): /* OSC clock */
freq = getOscClk();
break;
default:
freq = 0U;
break;
}
if (((CLKCTL0->SYSPLL0CTL0) & CLKCTL0_SYSPLL0CTL0_BYPASS_MASK) == 0U)
{
/* PLL output frequency = Fref * (DIV_SELECT + NUM/DENOM). */
freqTmp = ((uint64_t)freq * ((uint64_t)(CLKCTL0->SYSPLL0NUM))) / ((uint64_t)(CLKCTL0->SYSPLL0DENOM));
freq *= ((CLKCTL0->SYSPLL0CTL0) & CLKCTL0_SYSPLL0CTL0_MULT_MASK) >> CLKCTL0_SYSPLL0CTL0_MULT_SHIFT;
freq += (uint32_t)freqTmp;
freq =
(uint32_t)((uint64_t)freq * 18U /
((CLKCTL0->SYSPLL0PFD & CLKCTL0_SYSPLL0PFD_PFD0_MASK) >> CLKCTL0_SYSPLL0PFD_PFD0_SHIFT));
}
freq = freq / ((CLKCTL0->MAINPLLCLKDIV & CLKCTL0_MAINPLLCLKDIV_DIV_MASK) + 1U);
break;
case CLKCTL0_MAINCLKSELB_SEL(2): /* RTC 32KHz clock */
freq = CLK_RTC_32K_CLK;
break;
default:
freq = 0U;
break;
}
SystemCoreClock = freq / ((CLKCTL0->SYSCPUAHBCLKDIV & CLKCTL0_SYSCPUAHBCLKDIV_DIV_MASK) + 1U);
}
/* ----------------------------------------------------------------------------
-- SystemInitHook()
---------------------------------------------------------------------------- */
__attribute__((weak)) void SystemInitHook(void)
{
/* Void implementation of the weak function. */
}

View file

@ -0,0 +1,124 @@
/*
** ###################################################################
** Processors: MIMXRT595SFAWC_cm33
** MIMXRT595SFFOC_cm33
**
** Compilers: GNU C Compiler
** IAR ANSI C/C++ Compiler for ARM
** Keil ARM C/C++ Compiler
** MCUXpresso Compiler
**
** Reference manual: RT500 Reference Manual. Rev.C, 8/2020
** Version: rev. 5.0, 2020-08-27
** Build: b201016
**
** Abstract:
** Provides a system configuration function and a global variable that
** contains the system frequency. It configures the device and initializes
** the oscillator (PLL) that is part of the microcontroller device.
**
** Copyright 2016 Freescale Semiconductor, Inc.
** Copyright 2016-2020 NXP
** All rights reserved.
**
** SPDX-License-Identifier: BSD-3-Clause
**
** http: www.nxp.com
** mail: support@nxp.com
**
** Revisions:
** - rev. 1.0 (2019-04-19)
** Initial version.
** - rev. 2.0 (2019-07-22)
** Base on rev 0.7 RM.
** - rev. 3.0 (2020-03-16)
** Base on Rev.A RM.
** - rev. 4.0 (2020-05-18)
** Base on Rev.B RM.
** - rev. 5.0 (2020-08-27)
** Base on Rev.C RM.
**
** ###################################################################
*/
/*!
* @file MIMXRT595S_cm33
* @version 5.0
* @date 2020-08-27
* @brief Device specific configuration file for MIMXRT595S_cm33 (header file)
*
* Provides a system configuration function and a global variable that contains
* the system frequency. It configures the device and initializes the oscillator
* (PLL) that is part of the microcontroller device.
*/
#ifndef _SYSTEM_MIMXRT595S_cm33_H_
#define _SYSTEM_MIMXRT595S_cm33_H_ /**< Symbol preventing repeated inclusion */
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#define DEFAULT_SYSTEM_CLOCK 1000000u /* Default System clock value */
#ifndef CLK_XTAL_OSC_CLK
#define CLK_XTAL_OSC_CLK 24000000u /* Default XTAL OSC clock */
#endif
#define CLK_RTC_32K_CLK 32768u /* RTC oscillator 32 kHz (32k_clk) */
#define CLK_LPOSC_1MHZ 1000000u /* Low power oscillator 1 MHz (1m_lposc) */
#define CLK_FRO_CLK ((CLKCTL0->FRO_SCTRIM & 0x3FU) == 0x2FU ? 96000000u : 192000000u) /* FRO clock frequency */
#define CLK_FRO_DIV2_CLK (CLK_FRO_CLK / 2u) /* FRO_DIV2 clock frequency */
#define CLK_FRO_DIV4_CLK (CLK_FRO_CLK / 4u) /* FRO_DIV4 clock frequency */
#define CLK_FRO_DIV8_CLK (CLK_FRO_CLK / 8u) /* FRO_DIV8 clock frequency */
#define CLK_FRO_DIV16_CLK (CLK_FRO_CLK / 16u) /* FRO_DIV16 clock frequency */
#ifndef CLK_EXT_CLKIN
#define CLK_EXT_CLKIN 0u /* Default external CLKIN pin clock */
#endif
/**
* @brief System clock frequency (core clock)
*
* The system clock frequency supplied to the SysTick timer and the processor
* core clock. This variable can be used by the user application to setup the
* SysTick timer or configure other parameters. It may also be used by debugger to
* query the frequency of the debug timer or configure the trace clock speed
* SystemCoreClock is initialized with a correct predefined value.
*/
extern uint32_t SystemCoreClock;
/**
* @brief Setup the microcontroller system.
*
* Typically this function configures the oscillator (PLL) that is part of the
* microcontroller device. For systems with variable clock speed it also updates
* the variable SystemCoreClock. SystemInit is called from startup_device file.
*/
void SystemInit(void);
/**
* @brief Updates the SystemCoreClock variable.
*
* It must be called whenever the core clock is changed during program
* execution. SystemCoreClockUpdate() evaluates the clock register settings and calculates
* the current core clock.
*/
void SystemCoreClockUpdate(void);
/**
* @brief SystemInit function hook.
*
* This weak function allows to call specific initialization code during the
* SystemInit() execution.This can be used when an application specific code needs
* to be called as close to the reset entry as possible (for example the Multicore
* Manager MCMGR_EarlyInit() function call).
* NOTE: No global r/w variables can be used in this hook function because the
* initialization of these variables happens after this function.
*/
void SystemInitHook(void);
#ifdef __cplusplus
}
#endif
#endif /* _SYSTEM_MIMXRT595S_cm33_H_ */

View file

@ -0,0 +1,372 @@
/*
* Copyright 2016-2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_cache.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.cache_cache64"
#endif
#if (FSL_FEATURE_SOC_CACHE64_CTRL_COUNT > 0)
/*******************************************************************************
* Variables
******************************************************************************/
/* Array of CACHE64_CTRL peripheral base address. */
static CACHE64_CTRL_Type *const s_cache64ctrlBases[] = CACHE64_CTRL_BASE_PTRS;
/* Array of CACHE64_POLSEL peripheral base address. */
static CACHE64_POLSEL_Type *const s_cache64polselBases[] = CACHE64_POLSEL_BASE_PTRS;
/* Array of CACHE64 physical memory base address. */
static uint32_t const s_cache64PhymemBases[] = CACHE64_CTRL_PHYMEM_BASES;
/* Array of CACHE64 physical memory size. */
static uint32_t const s_cache64PhymemSizes[] = CACHE64_CTRL_PHYMEM_SIZES;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Array of CACHE64_CTRL clock name. */
static const clock_ip_name_t s_cache64Clocks[] = CACHE64_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/*******************************************************************************
* Code
******************************************************************************/
/*!
* brief Returns an instance number given periphearl base address.
*
* param base The peripheral base address.
* return CACHE64_POLSEL instance number starting from 0.
*/
uint32_t CACHE64_GetInstance(CACHE64_POLSEL_Type *base)
{
uint32_t i;
for (i = 0; i < ARRAY_SIZE(s_cache64polselBases); i++)
{
if (base == s_cache64polselBases[i])
{
break;
}
}
assert(i < ARRAY_SIZE(s_cache64polselBases));
return i;
}
/*!
* brief Returns an instance number given physical memory address.
*
* param address The physical memory address.
* return CACHE64_CTRL instance number starting from 0.
*/
uint32_t CACHE64_GetInstanceByAddr(uint32_t address)
{
uint32_t i;
for (i = 0; i < ARRAY_SIZE(s_cache64ctrlBases); i++)
{
if ((address >= s_cache64PhymemBases[i]) && (address < s_cache64PhymemBases[i] + s_cache64PhymemSizes[i]))
{
break;
}
}
return i;
}
/*!
* @brief Initializes an CACHE64 instance with the user configuration structure.
*
* This function configures the CACHE64 module with user-defined settings. Call the CACHE64_GetDefaultConfig() function
* to configure the configuration structure and get the default configuration.
*
* @param base CACHE64_POLSEL peripheral base address.
* @param config Pointer to a user-defined configuration structure.
* @retval kStatus_Success CACHE64 initialize succeed
*/
status_t CACHE64_Init(CACHE64_POLSEL_Type *base, const cache64_config_t *config)
{
volatile uint32_t *topReg = &base->REG0_TOP;
uint32_t i;
uint32_t polsel = 0;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
uint32_t instance = CACHE64_GetInstance(base);
/* Enable CACHE64 clock */
CLOCK_EnableClock(s_cache64Clocks[instance]);
#endif
for (i = 0; i < CACHE64_REGION_NUM - 1U; i++)
{
assert((config->boundaryAddr[i] & (CACHE64_REGION_ALIGNMENT - 1U)) == 0U);
((volatile uint32_t *)topReg)[i] = config->boundaryAddr[i] >= CACHE64_REGION_ALIGNMENT ?
config->boundaryAddr[i] - CACHE64_REGION_ALIGNMENT :
0U;
}
for (i = 0; i < CACHE64_REGION_NUM; i++)
{
polsel |= (((uint32_t)config->policy[i]) << (2U * i));
}
base->POLSEL = polsel;
return kStatus_Success;
}
/*!
* @brief Gets the default configuration structure.
*
* This function initializes the CACHE64 configuration structure to a default value. The default
* values are first region covers whole cacheable area, and policy set to write back.
*
* @param config Pointer to a configuration structure.
*/
void CACHE64_GetDefaultConfig(cache64_config_t *config)
{
(void)memset(config, 0, sizeof(cache64_config_t));
config->boundaryAddr[0] = s_cache64PhymemSizes[0];
config->policy[0] = kCACHE64_PolicyWriteBack;
}
/*!
* brief Enables the cache.
*
*/
void CACHE64_EnableCache(CACHE64_CTRL_Type *base)
{
/* First, invalidate the entire cache. */
CACHE64_InvalidateCache(base);
/* Now enable the cache. */
base->CCR |= CACHE64_CTRL_CCR_ENCACHE_MASK;
}
/*!
* brief Disables the cache.
*
*/
void CACHE64_DisableCache(CACHE64_CTRL_Type *base)
{
/* First, push any modified contents. */
CACHE64_CleanCache(base);
/* Now disable the cache. */
base->CCR &= ~CACHE64_CTRL_CCR_ENCACHE_MASK;
}
/*!
* brief Invalidates the cache.
*
*/
void CACHE64_InvalidateCache(CACHE64_CTRL_Type *base)
{
/* Invalidate all lines in both ways and initiate the cache command. */
base->CCR |= CACHE64_CTRL_CCR_INVW0_MASK | CACHE64_CTRL_CCR_INVW1_MASK | CACHE64_CTRL_CCR_GO_MASK;
/* Wait until the cache command completes. */
while ((base->CCR & CACHE64_CTRL_CCR_GO_MASK) != 0x00U)
{
}
/* As a precaution clear the bits to avoid inadvertently re-running this command. */
base->CCR &= ~(CACHE64_CTRL_CCR_INVW0_MASK | CACHE64_CTRL_CCR_INVW1_MASK);
}
/*!
* brief Invalidates cache by range.
*
* param address The physical address of cache.
* param size_byte size of the memory to be invalidated.
* note Address and size should be aligned to "L1CODCACHE_LINESIZE_BYTE".
* The startAddr here will be forced to align to CACHE64_LINESIZE_BYTE if
* startAddr is not aligned. For the size_byte, application should make sure the
* alignment or make sure the right operation order if the size_byte is not aligned.
*/
void CACHE64_InvalidateCacheByRange(uint32_t address, uint32_t size_byte)
{
uint32_t endAddr = address + size_byte;
uint32_t pccReg = 0;
/* Align address to cache line size. */
uint32_t startAddr = address & ~((uint32_t)CACHE64_LINESIZE_BYTE - 1U);
uint32_t instance = CACHE64_GetInstanceByAddr(address);
uint32_t endLim;
CACHE64_CTRL_Type *base;
if (instance >= ARRAY_SIZE(s_cache64ctrlBases))
{
return;
}
base = s_cache64ctrlBases[instance];
endLim = s_cache64PhymemBases[instance] + s_cache64PhymemSizes[instance];
endAddr = endAddr > endLim ? endLim : endAddr;
/* Set the invalidate by line command and use the physical address. */
pccReg = (base->CLCR & ~CACHE64_CTRL_CLCR_LCMD_MASK) | CACHE64_CTRL_CLCR_LCMD(1) | CACHE64_CTRL_CLCR_LADSEL_MASK;
base->CLCR = pccReg;
while (startAddr < endAddr)
{
/* Set the address and initiate the command. */
base->CSAR = (startAddr & CACHE64_CTRL_CSAR_PHYADDR_MASK) | CACHE64_CTRL_CSAR_LGO_MASK;
/* Wait until the cache command completes. */
while ((base->CSAR & CACHE64_CTRL_CSAR_LGO_MASK) != 0x00U)
{
}
startAddr += (uint32_t)CACHE64_LINESIZE_BYTE;
}
}
/*!
* brief Cleans the cache.
*
*/
void CACHE64_CleanCache(CACHE64_CTRL_Type *base)
{
/* Enable the to push all modified lines. */
base->CCR |= CACHE64_CTRL_CCR_PUSHW0_MASK | CACHE64_CTRL_CCR_PUSHW1_MASK | CACHE64_CTRL_CCR_GO_MASK;
/* Wait until the cache command completes. */
while ((base->CCR & CACHE64_CTRL_CCR_GO_MASK) != 0x00U)
{
}
/* As a precaution clear the bits to avoid inadvertently re-running this command. */
base->CCR &= ~(CACHE64_CTRL_CCR_PUSHW0_MASK | CACHE64_CTRL_CCR_PUSHW1_MASK);
}
/*!
* brief Cleans cache by range.
*
* param address The physical address of cache.
* param size_byte size of the memory to be cleaned.
* note Address and size should be aligned to "CACHE64_LINESIZE_BYTE".
* The startAddr here will be forced to align to CACHE64_LINESIZE_BYTE if
* startAddr is not aligned. For the size_byte, application should make sure the
* alignment or make sure the right operation order if the size_byte is not aligned.
*/
void CACHE64_CleanCacheByRange(uint32_t address, uint32_t size_byte)
{
uint32_t endAddr = address + size_byte;
uint32_t pccReg = 0;
/* Align address to cache line size. */
uint32_t startAddr = address & ~((uint32_t)CACHE64_LINESIZE_BYTE - 1U);
uint32_t instance = CACHE64_GetInstanceByAddr(address);
uint32_t endLim;
CACHE64_CTRL_Type *base;
if (instance >= ARRAY_SIZE(s_cache64ctrlBases))
{
return;
}
base = s_cache64ctrlBases[instance];
endLim = s_cache64PhymemBases[instance] + s_cache64PhymemSizes[instance];
endAddr = endAddr > endLim ? endLim : endAddr;
/* Set the push by line command. */
pccReg = (base->CLCR & ~CACHE64_CTRL_CLCR_LCMD_MASK) | CACHE64_CTRL_CLCR_LCMD(2) | CACHE64_CTRL_CLCR_LADSEL_MASK;
base->CLCR = pccReg;
while (startAddr < endAddr)
{
/* Set the address and initiate the command. */
base->CSAR = (startAddr & CACHE64_CTRL_CSAR_PHYADDR_MASK) | CACHE64_CTRL_CSAR_LGO_MASK;
/* Wait until the cache command completes. */
while ((base->CSAR & CACHE64_CTRL_CSAR_LGO_MASK) != 0x00U)
{
}
startAddr += (uint32_t)CACHE64_LINESIZE_BYTE;
}
}
/*!
* brief Cleans and invalidates the cache.
*
*/
void CACHE64_CleanInvalidateCache(CACHE64_CTRL_Type *base)
{
/* Push and invalidate all. */
base->CCR |= CACHE64_CTRL_CCR_PUSHW0_MASK | CACHE64_CTRL_CCR_PUSHW1_MASK | CACHE64_CTRL_CCR_INVW0_MASK |
CACHE64_CTRL_CCR_INVW1_MASK | CACHE64_CTRL_CCR_GO_MASK;
/* Wait until the cache command completes. */
while ((base->CCR & CACHE64_CTRL_CCR_GO_MASK) != 0x00U)
{
}
/* As a precaution clear the bits to avoid inadvertently re-running this command. */
base->CCR &= ~(CACHE64_CTRL_CCR_PUSHW0_MASK | CACHE64_CTRL_CCR_PUSHW1_MASK | CACHE64_CTRL_CCR_INVW0_MASK |
CACHE64_CTRL_CCR_INVW1_MASK);
}
/*!
* brief Cleans and invalidate cache by range.
*
* param address The physical address of cache.
* param size_byte size of the memory to be Cleaned and Invalidated.
* note Address and size should be aligned to "CACHE64_LINESIZE_BYTE".
* The startAddr here will be forced to align to CACHE64_LINESIZE_BYTE if
* startAddr is not aligned. For the size_byte, application should make sure the
* alignment or make sure the right operation order if the size_byte is not aligned.
*/
void CACHE64_CleanInvalidateCacheByRange(uint32_t address, uint32_t size_byte)
{
uint32_t endAddr = address + size_byte;
uint32_t pccReg = 0;
/* Align address to cache line size. */
uint32_t startAddr = address & ~((uint32_t)CACHE64_LINESIZE_BYTE - 1U);
uint32_t instance = CACHE64_GetInstanceByAddr(address);
uint32_t endLim;
CACHE64_CTRL_Type *base;
if (instance >= ARRAY_SIZE(s_cache64ctrlBases))
{
return;
}
base = s_cache64ctrlBases[instance];
endLim = s_cache64PhymemBases[instance] + s_cache64PhymemSizes[instance];
endAddr = endAddr > endLim ? endLim : endAddr;
/* Set the push by line command. */
pccReg = (base->CLCR & ~CACHE64_CTRL_CLCR_LCMD_MASK) | CACHE64_CTRL_CLCR_LCMD(3) | CACHE64_CTRL_CLCR_LADSEL_MASK;
base->CLCR = pccReg;
while (startAddr < endAddr)
{
/* Set the address and initiate the command. */
base->CSAR = (startAddr & CACHE64_CTRL_CSAR_PHYADDR_MASK) | CACHE64_CTRL_CSAR_LGO_MASK;
/* Wait until the cache command completes. */
while ((base->CSAR & CACHE64_CTRL_CSAR_LGO_MASK) != 0x00U)
{
}
startAddr += (uint32_t)CACHE64_LINESIZE_BYTE;
}
}
/*!
* brief Enable the cache write buffer.
*
*/
void CACHE64_EnableWriteBuffer(CACHE64_CTRL_Type *base, bool enable)
{
if (enable)
{
base->CCR |= CACHE64_CTRL_CCR_ENWRBUF_MASK;
}
else
{
base->CCR &= ~CACHE64_CTRL_CCR_ENWRBUF_MASK;
}
}
#endif /* FSL_FEATURE_SOC_CACHE64_CTRL_COUNT > 0 */

View file

@ -0,0 +1,267 @@
/*
* Copyright 2016-2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_CACHE_H_
#define _FSL_CACHE_H_
#include "fsl_common.h"
/*!
* @addtogroup cache64
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief cache driver version 2.0.4. */
#define FSL_CACHE_DRIVER_VERSION (MAKE_VERSION(2, 0, 4))
/*@}*/
/*! @brief cache line size. */
#define CACHE64_LINESIZE_BYTE (FSL_FEATURE_CACHE64_CTRL_LINESIZE_BYTE)
/*! @brief cache region number. */
#define CACHE64_REGION_NUM (3U)
/*! @brief cache region alignment. */
#define CACHE64_REGION_ALIGNMENT (0x400U)
/*! @brief Level 2 cache controller way size. */
typedef enum _cache64_policy
{
kCACHE64_PolicyNonCacheable = 0, /*!< Non-cacheable */
kCACHE64_PolicyWriteThrough = 1, /*!< Write through */
kCACHE64_PolicyWriteBack = 2, /*!< Write back */
} cache64_policy_t;
/*! @brief CACHE64 configuration structure. */
typedef struct _cache64_config
{
/*!< The cache controller can divide whole memory into 3 regions.
* Boundary address is the FlexSPI internal address (start from 0) instead of system
* address (start from FlexSPI AMBA base) to split adjacent regions and must be 1KB
* aligned. The boundary address itself locates in upper region. */
uint32_t boundaryAddr[CACHE64_REGION_NUM - 1];
/*!< Cacheable policy for each region. */
cache64_policy_t policy[CACHE64_REGION_NUM];
} cache64_config_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name cache control for cache64
*@{
*/
/*!
* @brief Returns an instance number given periphearl base address.
*
* @param base The peripheral base address.
* @return CACHE64_POLSEL instance number starting from 0.
*/
uint32_t CACHE64_GetInstance(CACHE64_POLSEL_Type *base);
/*!
* brief Returns an instance number given physical memory address.
*
* param address The physical memory address.
* @return CACHE64_CTRL instance number starting from 0.
*/
uint32_t CACHE64_GetInstanceByAddr(uint32_t address);
/*!
* @brief Initializes an CACHE64 instance with the user configuration structure.
*
* This function configures the CACHE64 module with user-defined settings. Call the CACHE64_GetDefaultConfig() function
* to configure the configuration structure and get the default configuration.
*
* @param base CACHE64_POLSEL peripheral base address.
* @param config Pointer to a user-defined configuration structure.
* @retval kStatus_Success CACHE64 initialize succeed
*/
status_t CACHE64_Init(CACHE64_POLSEL_Type *base, const cache64_config_t *config);
/*!
* @brief Gets the default configuration structure.
*
* This function initializes the CACHE64 configuration structure to a default value. The default
* values are first region covers whole cacheable area, and policy set to write back.
*
* @param config Pointer to a configuration structure.
*/
void CACHE64_GetDefaultConfig(cache64_config_t *config);
/*!
* @brief Enables the cache.
*
* @param base CACHE64_CTRL peripheral base address.
*
*/
void CACHE64_EnableCache(CACHE64_CTRL_Type *base);
/*!
* @brief Disables the cache.
*
* @param base CACHE64_CTRL peripheral base address.
*
*/
void CACHE64_DisableCache(CACHE64_CTRL_Type *base);
/*!
* @brief Invalidates the cache.
*
* @param base CACHE64_CTRL peripheral base address.
*
*/
void CACHE64_InvalidateCache(CACHE64_CTRL_Type *base);
/*!
* @brief Invalidates cache by range.
*
* @param address The physical address of cache.
* @param size_byte size of the memory to be invalidated.
* @note Address and size should be aligned to "CACHE64_LINESIZE_BYTE".
* The startAddr here will be forced to align to CACHE64_LINESIZE_BYTE if
* startAddr is not aligned. For the size_byte, application should make sure the
* alignment or make sure the right operation order if the size_byte is not aligned.
*/
void CACHE64_InvalidateCacheByRange(uint32_t address, uint32_t size_byte);
/*!
* @brief Cleans the cache.
*
* @param base CACHE64_CTRL peripheral base address.
*
*/
void CACHE64_CleanCache(CACHE64_CTRL_Type *base);
/*!
* @brief Cleans cache by range.
*
* @param address The physical address of cache.
* @param size_byte size of the memory to be cleaned.
* @note Address and size should be aligned to "CACHE64_LINESIZE_BYTE".
* The startAddr here will be forced to align to CACHE64_LINESIZE_BYTE if
* startAddr is not aligned. For the size_byte, application should make sure the
* alignment or make sure the right operation order if the size_byte is not aligned.
*/
void CACHE64_CleanCacheByRange(uint32_t address, uint32_t size_byte);
/*!
* @brief Cleans and invalidates the cache.
*
* @param base CACHE64_CTRL peripheral base address.
*
*/
void CACHE64_CleanInvalidateCache(CACHE64_CTRL_Type *base);
/*!
* @brief Cleans and invalidate cache by range.
*
* @param address The physical address of cache.
* @param size_byte size of the memory to be Cleaned and Invalidated.
* @note Address and size should be aligned to "CACHE64_LINESIZE_BYTE".
* The startAddr here will be forced to align to CACHE64_LINESIZE_BYTE if
* startAddr is not aligned. For the size_byte, application should make sure the
* alignment or make sure the right operation order if the size_byte is not aligned.
*/
void CACHE64_CleanInvalidateCacheByRange(uint32_t address, uint32_t size_byte);
/*!
* @brief Enables/disables the write buffer.
*
* @param base CACHE64_CTRL peripheral base address.
* @param enable The enable or disable flag.
* true - enable the write buffer.
* false - disable the write buffer.
*/
void CACHE64_EnableWriteBuffer(CACHE64_CTRL_Type *base, bool enable);
/*@}*/
/*!
* @name Unified Cache Control for all caches
*@{
*/
/*!
* @brief Invalidates instruction cache by range.
*
* @param address The physical address.
* @param size_byte size of the memory to be invalidated.
* @note Address and size should be aligned to CACHE64_LINESIZE_BYTE due to the cache operation unit
* FSL_FEATURE_CACHE64_CTRL_LINESIZE_BYTE. The startAddr here will be forced to align to the cache line
* size if startAddr is not aligned. For the size_byte, application should make sure the
* alignment or make sure the right operation order if the size_byte is not aligned.
*/
static inline void ICACHE_InvalidateByRange(uint32_t address, uint32_t size_byte)
{
CACHE64_InvalidateCacheByRange(address, size_byte);
}
/*!
* @brief Invalidates data cache by range.
*
* @param address The physical address.
* @param size_byte size of the memory to be invalidated.
* @note Address and size should be aligned to CACHE64_LINESIZE_BYTE due to the cache operation unit
* FSL_FEATURE_CACHE64_CTRL_LINESIZE_BYTE. The startAddr here will be forced to align to the cache line
* size if startAddr is not aligned. For the size_byte, application should make sure the
* alignment or make sure the right operation order if the size_byte is not aligned.
*/
static inline void DCACHE_InvalidateByRange(uint32_t address, uint32_t size_byte)
{
CACHE64_InvalidateCacheByRange(address, size_byte);
}
/*!
* @brief Clean data cache by range.
*
* @param address The physical address.
* @param size_byte size of the memory to be cleaned.
* @note Address and size should be aligned to CACHE64_LINESIZE_BYTE due to the cache operation unit
* FSL_FEATURE_CACHE64_CTRL_LINESIZE_BYTE. The startAddr here will be forced to align to the cache line
* size if startAddr is not aligned. For the size_byte, application should make sure the
* alignment or make sure the right operation order if the size_byte is not aligned.
*/
static inline void DCACHE_CleanByRange(uint32_t address, uint32_t size_byte)
{
CACHE64_CleanCacheByRange(address, size_byte);
}
/*!
* @brief Cleans and Invalidates data cache by range.
*
* @param address The physical address.
* @param size_byte size of the memory to be Cleaned and Invalidated.
* @note Address and size should be aligned to CACHE64_LINESIZE_BYTE due to the cache operation unit
* FSL_FEATURE_CACHE64_CTRL_LINESIZE_BYTE. The startAddr here will be forced to align to the cache line
* size if startAddr is not aligned. For the size_byte, application should make sure the
* alignment or make sure the right operation order if the size_byte is not aligned.
*/
static inline void DCACHE_CleanInvalidateByRange(uint32_t address, uint32_t size_byte)
{
CACHE64_CleanInvalidateCacheByRange(address, size_byte);
}
/*@}*/
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* _FSL_CACHE_H_*/

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,83 @@
/*
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
* Copyright 2016-2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_common.h"
#define SDK_MEM_MAGIC_NUMBER 12345U
typedef struct _mem_align_control_block
{
uint16_t identifier; /*!< Identifier for the memory control block. */
uint16_t offset; /*!< offset from aligned address to real address */
} mem_align_cb_t;
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.common"
#endif
void *SDK_Malloc(size_t size, size_t alignbytes)
{
mem_align_cb_t *p_cb = NULL;
uint32_t alignedsize;
/* Check overflow. */
alignedsize = SDK_SIZEALIGN(size, alignbytes);
if (alignedsize < size)
{
return NULL;
}
if (alignedsize > SIZE_MAX - alignbytes - sizeof(mem_align_cb_t))
{
return NULL;
}
alignedsize += alignbytes + sizeof(mem_align_cb_t);
union
{
void *pointer_value;
uint32_t unsigned_value;
} p_align_addr, p_addr;
p_addr.pointer_value = malloc(alignedsize);
if (p_addr.pointer_value == NULL)
{
return NULL;
}
p_align_addr.unsigned_value = SDK_SIZEALIGN(p_addr.unsigned_value + sizeof(mem_align_cb_t), alignbytes);
p_cb = (mem_align_cb_t *)(p_align_addr.unsigned_value - 4U);
p_cb->identifier = SDK_MEM_MAGIC_NUMBER;
p_cb->offset = (uint16_t)(p_align_addr.unsigned_value - p_addr.unsigned_value);
return p_align_addr.pointer_value;
}
void SDK_Free(void *ptr)
{
union
{
void *pointer_value;
uint32_t unsigned_value;
} p_free;
p_free.pointer_value = ptr;
mem_align_cb_t *p_cb = (mem_align_cb_t *)(p_free.unsigned_value - 4U);
if (p_cb->identifier != SDK_MEM_MAGIC_NUMBER)
{
return;
}
p_free.unsigned_value = p_free.unsigned_value - p_cb->offset;
free(p_free.pointer_value);
}

View file

@ -0,0 +1,293 @@
/*
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
* Copyright 2016-2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_COMMON_H_
#define _FSL_COMMON_H_
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#if defined(__ICCARM__) || (defined(__CC_ARM) || defined(__ARMCC_VERSION)) || defined(__GNUC__)
#include <stddef.h>
#endif
#include "fsl_device_registers.h"
/*!
* @addtogroup ksdk_common
* @{
*/
/*******************************************************************************
* Configurations
******************************************************************************/
/*! @brief Macro to use the default weak IRQ handler in drivers. */
#ifndef FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ
#define FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ 1
#endif
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief Construct a status code value from a group and code number. */
#define MAKE_STATUS(group, code) ((((group)*100) + (code)))
/*! @brief Construct the version number for drivers. */
#define MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix))
/*! @name Driver version */
/*@{*/
/*! @brief common driver version. */
#define FSL_COMMON_DRIVER_VERSION (MAKE_VERSION(2, 3, 0))
/*@}*/
/* Debug console type definition. */
#define DEBUG_CONSOLE_DEVICE_TYPE_NONE 0U /*!< No debug console. */
#define DEBUG_CONSOLE_DEVICE_TYPE_UART 1U /*!< Debug console based on UART. */
#define DEBUG_CONSOLE_DEVICE_TYPE_LPUART 2U /*!< Debug console based on LPUART. */
#define DEBUG_CONSOLE_DEVICE_TYPE_LPSCI 3U /*!< Debug console based on LPSCI. */
#define DEBUG_CONSOLE_DEVICE_TYPE_USBCDC 4U /*!< Debug console based on USBCDC. */
#define DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM 5U /*!< Debug console based on FLEXCOMM. */
#define DEBUG_CONSOLE_DEVICE_TYPE_IUART 6U /*!< Debug console based on i.MX UART. */
#define DEBUG_CONSOLE_DEVICE_TYPE_VUSART 7U /*!< Debug console based on LPC_VUSART. */
#define DEBUG_CONSOLE_DEVICE_TYPE_MINI_USART 8U /*!< Debug console based on LPC_USART. */
#define DEBUG_CONSOLE_DEVICE_TYPE_SWO 9U /*!< Debug console based on SWO. */
#define DEBUG_CONSOLE_DEVICE_TYPE_QSCI 10U /*!< Debug console based on QSCI. */
/*! @brief Status group numbers. */
enum _status_groups
{
kStatusGroup_Generic = 0, /*!< Group number for generic status codes. */
kStatusGroup_FLASH = 1, /*!< Group number for FLASH status codes. */
kStatusGroup_LPSPI = 4, /*!< Group number for LPSPI status codes. */
kStatusGroup_FLEXIO_SPI = 5, /*!< Group number for FLEXIO SPI status codes. */
kStatusGroup_DSPI = 6, /*!< Group number for DSPI status codes. */
kStatusGroup_FLEXIO_UART = 7, /*!< Group number for FLEXIO UART status codes. */
kStatusGroup_FLEXIO_I2C = 8, /*!< Group number for FLEXIO I2C status codes. */
kStatusGroup_LPI2C = 9, /*!< Group number for LPI2C status codes. */
kStatusGroup_UART = 10, /*!< Group number for UART status codes. */
kStatusGroup_I2C = 11, /*!< Group number for UART status codes. */
kStatusGroup_LPSCI = 12, /*!< Group number for LPSCI status codes. */
kStatusGroup_LPUART = 13, /*!< Group number for LPUART status codes. */
kStatusGroup_SPI = 14, /*!< Group number for SPI status code.*/
kStatusGroup_XRDC = 15, /*!< Group number for XRDC status code.*/
kStatusGroup_SEMA42 = 16, /*!< Group number for SEMA42 status code.*/
kStatusGroup_SDHC = 17, /*!< Group number for SDHC status code */
kStatusGroup_SDMMC = 18, /*!< Group number for SDMMC status code */
kStatusGroup_SAI = 19, /*!< Group number for SAI status code */
kStatusGroup_MCG = 20, /*!< Group number for MCG status codes. */
kStatusGroup_SCG = 21, /*!< Group number for SCG status codes. */
kStatusGroup_SDSPI = 22, /*!< Group number for SDSPI status codes. */
kStatusGroup_FLEXIO_I2S = 23, /*!< Group number for FLEXIO I2S status codes */
kStatusGroup_FLEXIO_MCULCD = 24, /*!< Group number for FLEXIO LCD status codes */
kStatusGroup_FLASHIAP = 25, /*!< Group number for FLASHIAP status codes */
kStatusGroup_FLEXCOMM_I2C = 26, /*!< Group number for FLEXCOMM I2C status codes */
kStatusGroup_I2S = 27, /*!< Group number for I2S status codes */
kStatusGroup_IUART = 28, /*!< Group number for IUART status codes */
kStatusGroup_CSI = 29, /*!< Group number for CSI status codes */
kStatusGroup_MIPI_DSI = 30, /*!< Group number for MIPI DSI status codes */
kStatusGroup_SDRAMC = 35, /*!< Group number for SDRAMC status codes. */
kStatusGroup_POWER = 39, /*!< Group number for POWER status codes. */
kStatusGroup_ENET = 40, /*!< Group number for ENET status codes. */
kStatusGroup_PHY = 41, /*!< Group number for PHY status codes. */
kStatusGroup_TRGMUX = 42, /*!< Group number for TRGMUX status codes. */
kStatusGroup_SMARTCARD = 43, /*!< Group number for SMARTCARD status codes. */
kStatusGroup_LMEM = 44, /*!< Group number for LMEM status codes. */
kStatusGroup_QSPI = 45, /*!< Group number for QSPI status codes. */
kStatusGroup_DMA = 50, /*!< Group number for DMA status codes. */
kStatusGroup_EDMA = 51, /*!< Group number for EDMA status codes. */
kStatusGroup_DMAMGR = 52, /*!< Group number for DMAMGR status codes. */
kStatusGroup_FLEXCAN = 53, /*!< Group number for FlexCAN status codes. */
kStatusGroup_LTC = 54, /*!< Group number for LTC status codes. */
kStatusGroup_FLEXIO_CAMERA = 55, /*!< Group number for FLEXIO CAMERA status codes. */
kStatusGroup_LPC_SPI = 56, /*!< Group number for LPC_SPI status codes. */
kStatusGroup_LPC_USART = 57, /*!< Group number for LPC_USART status codes. */
kStatusGroup_DMIC = 58, /*!< Group number for DMIC status codes. */
kStatusGroup_SDIF = 59, /*!< Group number for SDIF status codes.*/
kStatusGroup_SPIFI = 60, /*!< Group number for SPIFI status codes. */
kStatusGroup_OTP = 61, /*!< Group number for OTP status codes. */
kStatusGroup_MCAN = 62, /*!< Group number for MCAN status codes. */
kStatusGroup_CAAM = 63, /*!< Group number for CAAM status codes. */
kStatusGroup_ECSPI = 64, /*!< Group number for ECSPI status codes. */
kStatusGroup_USDHC = 65, /*!< Group number for USDHC status codes.*/
kStatusGroup_LPC_I2C = 66, /*!< Group number for LPC_I2C status codes.*/
kStatusGroup_DCP = 67, /*!< Group number for DCP status codes.*/
kStatusGroup_MSCAN = 68, /*!< Group number for MSCAN status codes.*/
kStatusGroup_ESAI = 69, /*!< Group number for ESAI status codes. */
kStatusGroup_FLEXSPI = 70, /*!< Group number for FLEXSPI status codes. */
kStatusGroup_MMDC = 71, /*!< Group number for MMDC status codes. */
kStatusGroup_PDM = 72, /*!< Group number for MIC status codes. */
kStatusGroup_SDMA = 73, /*!< Group number for SDMA status codes. */
kStatusGroup_ICS = 74, /*!< Group number for ICS status codes. */
kStatusGroup_SPDIF = 75, /*!< Group number for SPDIF status codes. */
kStatusGroup_LPC_MINISPI = 76, /*!< Group number for LPC_MINISPI status codes. */
kStatusGroup_HASHCRYPT = 77, /*!< Group number for Hashcrypt status codes */
kStatusGroup_LPC_SPI_SSP = 78, /*!< Group number for LPC_SPI_SSP status codes. */
kStatusGroup_I3C = 79, /*!< Group number for I3C status codes */
kStatusGroup_LPC_I2C_1 = 97, /*!< Group number for LPC_I2C_1 status codes. */
kStatusGroup_NOTIFIER = 98, /*!< Group number for NOTIFIER status codes. */
kStatusGroup_DebugConsole = 99, /*!< Group number for debug console status codes. */
kStatusGroup_SEMC = 100, /*!< Group number for SEMC status codes. */
kStatusGroup_ApplicationRangeStart = 101, /*!< Starting number for application groups. */
kStatusGroup_IAP = 102, /*!< Group number for IAP status codes */
kStatusGroup_SFA = 103, /*!< Group number for SFA status codes*/
kStatusGroup_SPC = 104, /*!< Group number for SPC status codes. */
kStatusGroup_PUF = 105, /*!< Group number for PUF status codes. */
kStatusGroup_TOUCH_PANEL = 106, /*!< Group number for touch panel status codes */
kStatusGroup_HAL_GPIO = 121, /*!< Group number for HAL GPIO status codes. */
kStatusGroup_HAL_UART = 122, /*!< Group number for HAL UART status codes. */
kStatusGroup_HAL_TIMER = 123, /*!< Group number for HAL TIMER status codes. */
kStatusGroup_HAL_SPI = 124, /*!< Group number for HAL SPI status codes. */
kStatusGroup_HAL_I2C = 125, /*!< Group number for HAL I2C status codes. */
kStatusGroup_HAL_FLASH = 126, /*!< Group number for HAL FLASH status codes. */
kStatusGroup_HAL_PWM = 127, /*!< Group number for HAL PWM status codes. */
kStatusGroup_HAL_RNG = 128, /*!< Group number for HAL RNG status codes. */
kStatusGroup_HAL_I2S = 129, /*!< Group number for HAL I2S status codes. */
kStatusGroup_TIMERMANAGER = 135, /*!< Group number for TiMER MANAGER status codes. */
kStatusGroup_SERIALMANAGER = 136, /*!< Group number for SERIAL MANAGER status codes. */
kStatusGroup_LED = 137, /*!< Group number for LED status codes. */
kStatusGroup_BUTTON = 138, /*!< Group number for BUTTON status codes. */
kStatusGroup_EXTERN_EEPROM = 139, /*!< Group number for EXTERN EEPROM status codes. */
kStatusGroup_SHELL = 140, /*!< Group number for SHELL status codes. */
kStatusGroup_MEM_MANAGER = 141, /*!< Group number for MEM MANAGER status codes. */
kStatusGroup_LIST = 142, /*!< Group number for List status codes. */
kStatusGroup_OSA = 143, /*!< Group number for OSA status codes. */
kStatusGroup_COMMON_TASK = 144, /*!< Group number for Common task status codes. */
kStatusGroup_MSG = 145, /*!< Group number for messaging status codes. */
kStatusGroup_SDK_OCOTP = 146, /*!< Group number for OCOTP status codes. */
kStatusGroup_SDK_FLEXSPINOR = 147, /*!< Group number for FLEXSPINOR status codes.*/
kStatusGroup_CODEC = 148, /*!< Group number for codec status codes. */
kStatusGroup_ASRC = 149, /*!< Group number for codec status ASRC. */
kStatusGroup_OTFAD = 150, /*!< Group number for codec status codes. */
kStatusGroup_SDIOSLV = 151, /*!< Group number for SDIOSLV status codes. */
kStatusGroup_MECC = 152, /*!< Group number for MECC status codes. */
kStatusGroup_ENET_QOS = 153, /*!< Group number for ENET_QOS status codes. */
kStatusGroup_LOG = 154, /*!< Group number for LOG status codes. */
kStatusGroup_I3CBUS = 155, /*!< Group number for I3CBUS status codes. */
kStatusGroup_QSCI = 156, /*!< Group number for QSCI status codes. */
kStatusGroup_SNT = 157, /*!< Group number for SNT status codes. */
};
/*! \public
* @brief Generic status return codes.
*/
enum
{
kStatus_Success = MAKE_STATUS(kStatusGroup_Generic, 0), /*!< Generic status for Success. */
kStatus_Fail = MAKE_STATUS(kStatusGroup_Generic, 1), /*!< Generic status for Fail. */
kStatus_ReadOnly = MAKE_STATUS(kStatusGroup_Generic, 2), /*!< Generic status for read only failure. */
kStatus_OutOfRange = MAKE_STATUS(kStatusGroup_Generic, 3), /*!< Generic status for out of range access. */
kStatus_InvalidArgument = MAKE_STATUS(kStatusGroup_Generic, 4), /*!< Generic status for invalid argument check. */
kStatus_Timeout = MAKE_STATUS(kStatusGroup_Generic, 5), /*!< Generic status for timeout. */
kStatus_NoTransferInProgress = MAKE_STATUS(kStatusGroup_Generic, 6), /*!< Generic status for no transfer in progress. */
kStatus_Busy = MAKE_STATUS(kStatusGroup_Generic, 7), /*!< Generic status for module is busy. */
};
/*! @brief Type used for all status and error return values. */
typedef int32_t status_t;
/*!
* @name Min/max macros
* @{
*/
#if !defined(MIN)
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
#if !defined(MAX)
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
/* @} */
/*! @brief Computes the number of elements in an array. */
#if !defined(ARRAY_SIZE)
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#endif
/*! @name UINT16_MAX/UINT32_MAX value */
/* @{ */
#if !defined(UINT16_MAX)
#define UINT16_MAX ((uint16_t)-1)
#endif
#if !defined(UINT32_MAX)
#define UINT32_MAX ((uint32_t)-1)
#endif
/* @} */
/*! @name Suppress fallthrough warning macro */
/* For switch case code block, if case section ends without "break;" statement, there wil be
fallthrough warning with compiler flag -Wextra or -Wimplicit-fallthrough=n when using armgcc.
To suppress this warning, "SUPPRESS_FALL_THROUGH_WARNING();" need to be added at the end of each
case section which misses "break;"statement.
*/
/* @{ */
#if defined(__GNUC__) && !defined(__ARMCC_VERSION)
#define SUPPRESS_FALL_THROUGH_WARNING() __attribute__ ((fallthrough))
#else
#define SUPPRESS_FALL_THROUGH_WARNING()
#endif
/* @} */
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @brief Allocate memory with given alignment and aligned size.
*
* This is provided to support the dynamically allocated memory
* used in cache-able region.
* @param size The length required to malloc.
* @param alignbytes The alignment size.
* @retval The allocated memory.
*/
void *SDK_Malloc(size_t size, size_t alignbytes);
/*!
* @brief Free memory.
*
* @param ptr The memory to be release.
*/
void SDK_Free(void *ptr);
/*!
* @brief Delay at least for some time.
* Please note that, this API uses while loop for delay, different run-time environments make the time not precise,
* if precise delay count was needed, please implement a new delay function with hardware timer.
*
* @param delayTime_us Delay time in unit of microsecond.
* @param coreClock_Hz Core clock frequency with Hz.
*/
void SDK_DelayAtLeastUs(uint32_t delayTime_us, uint32_t coreClock_Hz);
#if defined(__cplusplus)
}
#endif
/*! @} */
#if (defined(__DSC__) && defined(__CW__))
#include "fsl_common_dsc.h"
#elif defined(__XCC__)
#include "fsl_common_dsp.h"
#else
#include "fsl_common_arm.h"
#endif
#endif /* _FSL_COMMON_H_ */

View file

@ -0,0 +1,233 @@
/*
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
* Copyright 2016-2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_common.h"
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.common_arm"
#endif
#ifndef __GIC_PRIO_BITS
#if defined(ENABLE_RAM_VECTOR_TABLE)
uint32_t InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler)
{
#ifdef __VECTOR_TABLE
#undef __VECTOR_TABLE
#endif
/* Addresses for VECTOR_TABLE and VECTOR_RAM come from the linker file */
#if defined(__CC_ARM) || defined(__ARMCC_VERSION)
extern uint32_t Image$$VECTOR_ROM$$Base[];
extern uint32_t Image$$VECTOR_RAM$$Base[];
extern uint32_t Image$$RW_m_data$$Base[];
#define __VECTOR_TABLE Image$$VECTOR_ROM$$Base
#define __VECTOR_RAM Image$$VECTOR_RAM$$Base
#define __RAM_VECTOR_TABLE_SIZE (((uint32_t)Image$$RW_m_data$$Base - (uint32_t)Image$$VECTOR_RAM$$Base))
#elif defined(__ICCARM__)
extern uint32_t __RAM_VECTOR_TABLE_SIZE[];
extern uint32_t __VECTOR_TABLE[];
extern uint32_t __VECTOR_RAM[];
#elif defined(__GNUC__)
extern uint32_t __VECTOR_TABLE[];
extern uint32_t __VECTOR_RAM[];
extern uint32_t __RAM_VECTOR_TABLE_SIZE_BYTES[];
uint32_t __RAM_VECTOR_TABLE_SIZE = (uint32_t)(__RAM_VECTOR_TABLE_SIZE_BYTES);
#endif /* defined(__CC_ARM) || defined(__ARMCC_VERSION) */
uint32_t n;
uint32_t ret;
uint32_t irqMaskValue;
irqMaskValue = DisableGlobalIRQ();
if (SCB->VTOR != (uint32_t)__VECTOR_RAM)
{
/* Copy the vector table from ROM to RAM */
for (n = 0; n < ((uint32_t)__RAM_VECTOR_TABLE_SIZE) / sizeof(uint32_t); n++)
{
__VECTOR_RAM[n] = __VECTOR_TABLE[n];
}
/* Point the VTOR to the position of vector table */
SCB->VTOR = (uint32_t)__VECTOR_RAM;
}
ret = __VECTOR_RAM[(int32_t)irq + 16];
/* make sure the __VECTOR_RAM is noncachable */
__VECTOR_RAM[(int32_t)irq + 16] = irqHandler;
EnableGlobalIRQ(irqMaskValue);
return ret;
}
#endif /* ENABLE_RAM_VECTOR_TABLE. */
#endif /* __GIC_PRIO_BITS. */
#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0))
/*
* When FSL_FEATURE_POWERLIB_EXTEND is defined to non-zero value,
* powerlib should be used instead of these functions.
*/
#if !(defined(FSL_FEATURE_POWERLIB_EXTEND) && (FSL_FEATURE_POWERLIB_EXTEND != 0))
/*
* When the SYSCON STARTER registers are discontinuous, these functions are
* implemented in fsl_power.c.
*/
#if !(defined(FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS) && FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS)
void EnableDeepSleepIRQ(IRQn_Type interrupt)
{
uint32_t intNumber = (uint32_t)interrupt;
uint32_t index = 0;
while (intNumber >= 32u)
{
index++;
intNumber -= 32u;
}
SYSCON->STARTERSET[index] = 1UL << intNumber;
(void)EnableIRQ(interrupt); /* also enable interrupt at NVIC */
}
void DisableDeepSleepIRQ(IRQn_Type interrupt)
{
uint32_t intNumber = (uint32_t)interrupt;
(void)DisableIRQ(interrupt); /* also disable interrupt at NVIC */
uint32_t index = 0;
while (intNumber >= 32u)
{
index++;
intNumber -= 32u;
}
SYSCON->STARTERCLR[index] = 1UL << intNumber;
}
#endif /* FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS */
#endif /* FSL_FEATURE_POWERLIB_EXTEND */
#endif /* FSL_FEATURE_SOC_SYSCON_COUNT */
#if defined(SDK_DELAY_USE_DWT) && defined(DWT)
/* Use WDT. */
static void enableCpuCycleCounter(void)
{
/* Make sure the DWT trace fucntion is enabled. */
if (CoreDebug_DEMCR_TRCENA_Msk != (CoreDebug_DEMCR_TRCENA_Msk & CoreDebug->DEMCR))
{
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
}
/* CYCCNT not supported on this device. */
assert(DWT_CTRL_NOCYCCNT_Msk != (DWT->CTRL & DWT_CTRL_NOCYCCNT_Msk));
/* Read CYCCNT directly if CYCCENT has already been enabled, otherwise enable CYCCENT first. */
if (DWT_CTRL_CYCCNTENA_Msk != (DWT_CTRL_CYCCNTENA_Msk & DWT->CTRL))
{
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
}
}
static uint32_t getCpuCycleCount(void)
{
return DWT->CYCCNT;
}
#else /* defined(SDK_DELAY_USE_DWT) && defined(DWT) */
/* Use software loop. */
#if defined(__CC_ARM) /* This macro is arm v5 specific */
/* clang-format off */
__ASM static void DelayLoop(uint32_t count)
{
loop
SUBS R0, R0, #1
CMP R0, #0
BNE loop
BX LR
}
/* clang-format on */
#elif defined(__ARMCC_VERSION) || defined(__ICCARM__) || defined(__GNUC__)
/* Cortex-M0 has a smaller instruction set, SUBS isn't supported in thumb-16 mode reported from __GNUC__ compiler,
* use SUB and CMP here for compatibility */
static void DelayLoop(uint32_t count)
{
__ASM volatile(" MOV R0, %0" : : "r"(count));
__ASM volatile(
"loop: \n"
#if defined(__GNUC__) && !defined(__ARMCC_VERSION)
" SUB R0, R0, #1 \n"
#else
" SUBS R0, R0, #1 \n"
#endif
" CMP R0, #0 \n"
" BNE loop \n"
:
:
: "r0");
}
#endif /* defined(__CC_ARM) */
#endif /* defined(SDK_DELAY_USE_DWT) && defined(DWT) */
/*!
* @brief Delay at least for some time.
* Please note that, if not uses DWT, this API will use while loop for delay, different run-time environments have
* effect on the delay time. If precise delay is needed, please enable DWT delay. The two parmeters delayTime_us and
* coreClock_Hz have limitation. For example, in the platform with 1GHz coreClock_Hz, the delayTime_us only supports
* up to 4294967 in current code. If long time delay is needed, please implement a new delay function.
*
* @param delayTime_us Delay time in unit of microsecond.
* @param coreClock_Hz Core clock frequency with Hz.
*/
void SDK_DelayAtLeastUs(uint32_t delayTime_us, uint32_t coreClock_Hz)
{
uint64_t count;
if (delayTime_us > 0U)
{
count = USEC_TO_COUNT(delayTime_us, coreClock_Hz);
assert(count <= UINT32_MAX);
#if defined(SDK_DELAY_USE_DWT) && defined(DWT) /* Use DWT for better accuracy */
enableCpuCycleCounter();
/* Calculate the count ticks. */
count += getCpuCycleCount();
if (count > UINT32_MAX)
{
count -= UINT32_MAX;
/* Wait for cyccnt overflow. */
while (count < getCpuCycleCount())
{
}
}
/* Wait for cyccnt reach count value. */
while (count > getCpuCycleCount())
{
}
#else
/* Divide value may be different in various environment to ensure delay is precise.
* Every loop count includes three instructions, due to Cortex-M7 sometimes executes
* two instructions in one period, through test here set divide 1.5. Other M cores use
* divide 4. By the way, divide 1.5 or 4 could let the count lose precision, but it does
* not matter because other instructions outside while loop is enough to fill the time.
*/
#if (__CORTEX_M == 7)
count = count / 3U * 2U;
#else
count = count / 4U;
#endif
DelayLoop((uint32_t)count);
#endif /* defined(SDK_DELAY_USE_DWT) && defined(DWT) */
}
}

View file

@ -0,0 +1,660 @@
/*
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
* Copyright 2016-2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_COMMON_ARM_H_
#define _FSL_COMMON_ARM_H_
/*
* For CMSIS pack RTE.
* CMSIS pack RTE generates "RTC_Components.h" which contains the statements
* of the related <RTE_Components_h> element for all selected software components.
*/
#ifdef _RTE_
#include "RTE_Components.h"
#endif
/*!
* @addtogroup ksdk_common
* @{
*/
/*! @name Atomic modification
*
* These macros are used for atomic access, such as read-modify-write
* to the peripheral registers.
*
* - SDK_ATOMIC_LOCAL_ADD
* - SDK_ATOMIC_LOCAL_SET
* - SDK_ATOMIC_LOCAL_CLEAR
* - SDK_ATOMIC_LOCAL_TOGGLE
* - SDK_ATOMIC_LOCAL_CLEAR_AND_SET
*
* Take SDK_ATOMIC_LOCAL_CLEAR_AND_SET as an example: the parameter @c addr
* means the address of the peripheral register or variable you want to modify
* atomically, the parameter @c clearBits is the bits to clear, the parameter
* @c setBits it the bits to set.
* For example, to set a 32-bit register bit1:bit0 to 0b10, use like this:
*
* @code
volatile uint32_t * reg = (volatile uint32_t *)REG_ADDR;
SDK_ATOMIC_LOCAL_CLEAR_AND_SET(reg, 0x03, 0x02);
@endcode
*
* In this example, the register bit1:bit0 are cleared and bit1 is set, as a result,
* register bit1:bit0 = 0b10.
*
* @note For the platforms don't support exclusive load and store, these macros
* disable the global interrupt to pretect the modification.
*
* @note These macros only guarantee the local processor atomic operations. For
* the multi-processor devices, use hardware semaphore such as SEMA42 to
* guarantee exclusive access if necessary.
*
* @{
*/
/* clang-format off */
#if ((defined(__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined(__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
(defined(__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
(defined(__ARM_ARCH_8M_BASE__) && (__ARM_ARCH_8M_BASE__ == 1)))
/* clang-format on */
/* If the LDREX and STREX are supported, use them. */
#define _SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, val, ops) \
do \
{ \
(val) = __LDREXB(addr); \
(ops); \
} while (0UL != __STREXB((val), (addr)))
#define _SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, val, ops) \
do \
{ \
(val) = __LDREXH(addr); \
(ops); \
} while (0UL != __STREXH((val), (addr)))
#define _SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, val, ops) \
do \
{ \
(val) = __LDREXW(addr); \
(ops); \
} while (0UL != __STREXW((val), (addr)))
static inline void _SDK_AtomicLocalAdd1Byte(volatile uint8_t *addr, uint8_t val)
{
uint8_t s_val;
_SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val += val);
}
static inline void _SDK_AtomicLocalAdd2Byte(volatile uint16_t *addr, uint16_t val)
{
uint16_t s_val;
_SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val += val);
}
static inline void _SDK_AtomicLocalAdd4Byte(volatile uint32_t *addr, uint32_t val)
{
uint32_t s_val;
_SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val += val);
}
static inline void _SDK_AtomicLocalSub1Byte(volatile uint8_t *addr, uint8_t val)
{
uint8_t s_val;
_SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val -= val);
}
static inline void _SDK_AtomicLocalSub2Byte(volatile uint16_t *addr, uint16_t val)
{
uint16_t s_val;
_SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val -= val);
}
static inline void _SDK_AtomicLocalSub4Byte(volatile uint32_t *addr, uint32_t val)
{
uint32_t s_val;
_SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val -= val);
}
static inline void _SDK_AtomicLocalSet1Byte(volatile uint8_t *addr, uint8_t bits)
{
uint8_t s_val;
_SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val |= bits);
}
static inline void _SDK_AtomicLocalSet2Byte(volatile uint16_t *addr, uint16_t bits)
{
uint16_t s_val;
_SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val |= bits);
}
static inline void _SDK_AtomicLocalSet4Byte(volatile uint32_t *addr, uint32_t bits)
{
uint32_t s_val;
_SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val |= bits);
}
static inline void _SDK_AtomicLocalClear1Byte(volatile uint8_t *addr, uint8_t bits)
{
uint8_t s_val;
_SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val &= ~bits);
}
static inline void _SDK_AtomicLocalClear2Byte(volatile uint16_t *addr, uint16_t bits)
{
uint16_t s_val;
_SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val &= ~bits);
}
static inline void _SDK_AtomicLocalClear4Byte(volatile uint32_t *addr, uint32_t bits)
{
uint32_t s_val;
_SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val &= ~bits);
}
static inline void _SDK_AtomicLocalToggle1Byte(volatile uint8_t *addr, uint8_t bits)
{
uint8_t s_val;
_SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val ^= bits);
}
static inline void _SDK_AtomicLocalToggle2Byte(volatile uint16_t *addr, uint16_t bits)
{
uint16_t s_val;
_SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val ^= bits);
}
static inline void _SDK_AtomicLocalToggle4Byte(volatile uint32_t *addr, uint32_t bits)
{
uint32_t s_val;
_SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val ^= bits);
}
static inline void _SDK_AtomicLocalClearAndSet1Byte(volatile uint8_t *addr, uint8_t clearBits, uint8_t setBits)
{
uint8_t s_val;
_SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val = (s_val & ~clearBits) | setBits);
}
static inline void _SDK_AtomicLocalClearAndSet2Byte(volatile uint16_t *addr, uint16_t clearBits, uint16_t setBits)
{
uint16_t s_val;
_SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val = (s_val & ~clearBits) | setBits);
}
static inline void _SDK_AtomicLocalClearAndSet4Byte(volatile uint32_t *addr, uint32_t clearBits, uint32_t setBits)
{
uint32_t s_val;
_SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val = (s_val & ~clearBits) | setBits);
}
#define SDK_ATOMIC_LOCAL_ADD(addr, val) \
((1UL == sizeof(*(addr))) ? _SDK_AtomicLocalAdd1Byte((volatile uint8_t*)(volatile void*)(addr), (val)) : \
((2UL == sizeof(*(addr))) ? _SDK_AtomicLocalAdd2Byte((volatile uint16_t*)(volatile void*)(addr), (val)) : \
_SDK_AtomicLocalAdd4Byte((volatile uint32_t *)(volatile void*)(addr), (val))))
#define SDK_ATOMIC_LOCAL_SET(addr, bits) \
((1UL == sizeof(*(addr))) ? _SDK_AtomicLocalSet1Byte((volatile uint8_t*)(volatile void*)(addr), (bits)) : \
((2UL == sizeof(*(addr))) ? _SDK_AtomicLocalSet2Byte((volatile uint16_t*)(volatile void*)(addr), (bits)) : \
_SDK_AtomicLocalSet4Byte((volatile uint32_t *)(volatile void*)(addr), (bits))))
#define SDK_ATOMIC_LOCAL_CLEAR(addr, bits) \
((1UL == sizeof(*(addr))) ? _SDK_AtomicLocalClear1Byte((volatile uint8_t*)(volatile void*)(addr), (bits)) : \
((2UL == sizeof(*(addr))) ? _SDK_AtomicLocalClear2Byte((volatile uint16_t*)(volatile void*)(addr), (bits)) : \
_SDK_AtomicLocalClear4Byte((volatile uint32_t *)(volatile void*)(addr), (bits))))
#define SDK_ATOMIC_LOCAL_TOGGLE(addr, bits) \
((1UL == sizeof(*(addr))) ? _SDK_AtomicLocalToggle1Byte((volatile uint8_t*)(volatile void*)(addr), (bits)) : \
((2UL == sizeof(*(addr))) ? _SDK_AtomicLocalToggle2Byte((volatile uint16_t*)(volatile void*)(addr), (bits)) : \
_SDK_AtomicLocalToggle4Byte((volatile uint32_t *)(volatile void*)(addr), (bits))))
#define SDK_ATOMIC_LOCAL_CLEAR_AND_SET(addr, clearBits, setBits) \
((1UL == sizeof(*(addr))) ? _SDK_AtomicLocalClearAndSet1Byte((volatile uint8_t*)(volatile void*)(addr), (clearBits), (setBits)) : \
((2UL == sizeof(*(addr))) ? _SDK_AtomicLocalClearAndSet2Byte((volatile uint16_t*)(volatile void*)(addr), (clearBits), (setBits)) : \
_SDK_AtomicLocalClearAndSet4Byte((volatile uint32_t *)(volatile void*)(addr), (clearBits), (setBits))))
#else
#define SDK_ATOMIC_LOCAL_ADD(addr, val) \
do { \
uint32_t s_atomicOldInt; \
s_atomicOldInt = DisableGlobalIRQ(); \
*(addr) += (val); \
EnableGlobalIRQ(s_atomicOldInt); \
} while (0)
#define SDK_ATOMIC_LOCAL_SET(addr, bits) \
do { \
uint32_t s_atomicOldInt; \
s_atomicOldInt = DisableGlobalIRQ(); \
*(addr) |= (bits); \
EnableGlobalIRQ(s_atomicOldInt); \
} while (0)
#define SDK_ATOMIC_LOCAL_CLEAR(addr, bits) \
do { \
uint32_t s_atomicOldInt; \
s_atomicOldInt = DisableGlobalIRQ(); \
*(addr) &= ~(bits); \
EnableGlobalIRQ(s_atomicOldInt); \
} while (0)
#define SDK_ATOMIC_LOCAL_TOGGLE(addr, bits) \
do { \
uint32_t s_atomicOldInt; \
s_atomicOldInt = DisableGlobalIRQ(); \
*(addr) ^= (bits); \
EnableGlobalIRQ(s_atomicOldInt); \
} while (0)
#define SDK_ATOMIC_LOCAL_CLEAR_AND_SET(addr, clearBits, setBits) \
do { \
uint32_t s_atomicOldInt; \
s_atomicOldInt = DisableGlobalIRQ(); \
*(addr) = (*(addr) & ~(clearBits)) | (setBits); \
EnableGlobalIRQ(s_atomicOldInt); \
} while (0)
#endif
/* @} */
/*! @name Timer utilities */
/* @{ */
/*! Macro to convert a microsecond period to raw count value */
#define USEC_TO_COUNT(us, clockFreqInHz) (uint64_t)(((uint64_t)(us) * (clockFreqInHz)) / 1000000U)
/*! Macro to convert a raw count value to microsecond */
#define COUNT_TO_USEC(count, clockFreqInHz) (uint64_t)((uint64_t)(count) * 1000000U / (clockFreqInHz))
/*! Macro to convert a millisecond period to raw count value */
#define MSEC_TO_COUNT(ms, clockFreqInHz) (uint64_t)((uint64_t)(ms) * (clockFreqInHz) / 1000U)
/*! Macro to convert a raw count value to millisecond */
#define COUNT_TO_MSEC(count, clockFreqInHz) (uint64_t)((uint64_t)(count) * 1000U / (clockFreqInHz))
/* @} */
/*! @name ISR exit barrier
* @{
*
* ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
* exception return operation might vector to incorrect interrupt.
* For Cortex-M7, if core speed much faster than peripheral register write speed,
* the peripheral interrupt flags may be still set after exiting ISR, this results to
* the same error similar with errata 83869.
*/
#if (defined __CORTEX_M) && ((__CORTEX_M == 4U) || (__CORTEX_M == 7U))
#define SDK_ISR_EXIT_BARRIER __DSB()
#else
#define SDK_ISR_EXIT_BARRIER
#endif
/* @} */
/*! @name Alignment variable definition macros */
/* @{ */
#if (defined(__ICCARM__))
/*
* Workaround to disable MISRA C message suppress warnings for IAR compiler.
* http:/ /supp.iar.com/Support/?note=24725
*/
_Pragma("diag_suppress=Pm120")
#define SDK_PRAGMA(x) _Pragma(#x)
_Pragma("diag_error=Pm120")
/*! Macro to define a variable with alignbytes alignment */
#define SDK_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var
#elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
/*! Macro to define a variable with alignbytes alignment */
#define SDK_ALIGN(var, alignbytes) __attribute__((aligned(alignbytes))) var
#elif defined(__GNUC__)
/*! Macro to define a variable with alignbytes alignment */
#define SDK_ALIGN(var, alignbytes) var __attribute__((aligned(alignbytes)))
#else
#error Toolchain not supported
#endif
/*! Macro to define a variable with L1 d-cache line size alignment */
#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
#define SDK_L1DCACHE_ALIGN(var) SDK_ALIGN(var, FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
#endif
/*! Macro to define a variable with L2 cache line size alignment */
#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
#define SDK_L2CACHE_ALIGN(var) SDK_ALIGN(var, FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
#endif
/*! Macro to change a value to a given size aligned value */
#define SDK_SIZEALIGN(var, alignbytes) \
((unsigned int)((var) + ((alignbytes)-1U)) & (unsigned int)(~(unsigned int)((alignbytes)-1U)))
/* @} */
/*! @name Non-cacheable region definition macros */
/* For initialized non-zero non-cacheable variables, please using "AT_NONCACHEABLE_SECTION_INIT(var) ={xx};" or
* "AT_NONCACHEABLE_SECTION_ALIGN_INIT(var) ={xx};" in your projects to define them, for zero-inited non-cacheable variables,
* please using "AT_NONCACHEABLE_SECTION(var);" or "AT_NONCACHEABLE_SECTION_ALIGN(var);" to define them, these zero-inited variables
* will be initialized to zero in system startup.
*/
/* @{ */
#if ((!(defined(FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION) && FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION)) && defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE))
#if (defined(__ICCARM__))
#define AT_NONCACHEABLE_SECTION(var) var @"NonCacheable"
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var @"NonCacheable"
#define AT_NONCACHEABLE_SECTION_INIT(var) var @"NonCacheable.init"
#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var @"NonCacheable.init"
#elif(defined(__CC_ARM) || defined(__ARMCC_VERSION))
#define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var
#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \
__attribute__((section("NonCacheable.init"))) __attribute__((aligned(alignbytes))) var
#if(defined(__CC_ARM))
#define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable"), zero_init)) var
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
__attribute__((section("NonCacheable"), zero_init)) __attribute__((aligned(alignbytes))) var
#else
#define AT_NONCACHEABLE_SECTION(var) __attribute__((section(".bss.NonCacheable"))) var
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
__attribute__((section(".bss.NonCacheable"))) __attribute__((aligned(alignbytes))) var
#endif
#elif(defined(__GNUC__))
/* For GCC, when the non-cacheable section is required, please define "__STARTUP_INITIALIZE_NONCACHEDATA"
* in your projects to make sure the non-cacheable section variables will be initialized in system startup.
*/
#define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var
#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \
__attribute__((section("NonCacheable.init"))) var __attribute__((aligned(alignbytes)))
#define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable,\"aw\",%nobits @"))) var
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
__attribute__((section("NonCacheable,\"aw\",%nobits @"))) var __attribute__((aligned(alignbytes)))
#else
#error Toolchain not supported.
#endif
#else
#define AT_NONCACHEABLE_SECTION(var) var
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) SDK_ALIGN(var, alignbytes)
#define AT_NONCACHEABLE_SECTION_INIT(var) var
#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) SDK_ALIGN(var, alignbytes)
#endif
/* @} */
/*!
* @name Time sensitive region
* @{
*/
#if (defined(FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE) && FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE)
#if (defined(__ICCARM__))
#define AT_QUICKACCESS_SECTION_CODE(func) func @"CodeQuickAccess"
#define AT_QUICKACCESS_SECTION_DATA(func) func @"DataQuickAccess"
#elif(defined(__CC_ARM) || defined(__ARMCC_VERSION))
#define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section("CodeQuickAccess"), __noinline__)) func
#define AT_QUICKACCESS_SECTION_DATA(func) __attribute__((section("DataQuickAccess"))) func
#elif(defined(__GNUC__))
#define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section("CodeQuickAccess"), __noinline__)) func
#define AT_QUICKACCESS_SECTION_DATA(func) __attribute__((section("DataQuickAccess"))) func
#else
#error Toolchain not supported.
#endif /* defined(__ICCARM__) */
#else /* __FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE */
#define AT_QUICKACCESS_SECTION_CODE(func) func
#define AT_QUICKACCESS_SECTION_DATA(func) func
#endif /* __FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE */
/* @} */
/*! @name Ram Function */
#if (defined(__ICCARM__))
#define RAMFUNCTION_SECTION_CODE(func) func @"RamFunction"
#elif(defined(__CC_ARM) || defined(__ARMCC_VERSION))
#define RAMFUNCTION_SECTION_CODE(func) __attribute__((section("RamFunction"))) func
#elif(defined(__GNUC__))
#define RAMFUNCTION_SECTION_CODE(func) __attribute__((section("RamFunction"))) func
#else
#error Toolchain not supported.
#endif /* defined(__ICCARM__) */
/* @} */
#if defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 )
void DefaultISR(void);
#endif
/*
* The fsl_clock.h is included here because it needs MAKE_VERSION/MAKE_STATUS/status_t
* defined in previous of this file.
*/
#include "fsl_clock.h"
/*
* Chip level peripheral reset API, for MCUs that implement peripheral reset control external to a peripheral
*/
#if ((defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) || \
(defined(FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT) && (FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT > 0)))
#include "fsl_reset.h"
#endif
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus*/
/*!
* @brief Enable specific interrupt.
*
* Enable LEVEL1 interrupt. For some devices, there might be multiple interrupt
* levels. For example, there are NVIC and intmux. Here the interrupts connected
* to NVIC are the LEVEL1 interrupts, because they are routed to the core directly.
* The interrupts connected to intmux are the LEVEL2 interrupts, they are routed
* to NVIC first then routed to core.
*
* This function only enables the LEVEL1 interrupts. The number of LEVEL1 interrupts
* is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS.
*
* @param interrupt The IRQ number.
* @retval kStatus_Success Interrupt enabled successfully
* @retval kStatus_Fail Failed to enable the interrupt
*/
static inline status_t EnableIRQ(IRQn_Type interrupt)
{
status_t status = kStatus_Success;
if (NotAvail_IRQn == interrupt)
{
status = kStatus_Fail;
}
#if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0)
else if ((int32_t)interrupt >= (int32_t)FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS)
{
status = kStatus_Fail;
}
#endif
else
{
#if defined(__GIC_PRIO_BITS)
GIC_EnableIRQ(interrupt);
#else
NVIC_EnableIRQ(interrupt);
#endif
}
return status;
}
/*!
* @brief Disable specific interrupt.
*
* Disable LEVEL1 interrupt. For some devices, there might be multiple interrupt
* levels. For example, there are NVIC and intmux. Here the interrupts connected
* to NVIC are the LEVEL1 interrupts, because they are routed to the core directly.
* The interrupts connected to intmux are the LEVEL2 interrupts, they are routed
* to NVIC first then routed to core.
*
* This function only disables the LEVEL1 interrupts. The number of LEVEL1 interrupts
* is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS.
*
* @param interrupt The IRQ number.
* @retval kStatus_Success Interrupt disabled successfully
* @retval kStatus_Fail Failed to disable the interrupt
*/
static inline status_t DisableIRQ(IRQn_Type interrupt)
{
status_t status = kStatus_Success;
if (NotAvail_IRQn == interrupt)
{
status = kStatus_Fail;
}
#if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0)
else if ((int32_t)interrupt >= (int32_t)FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS)
{
status = kStatus_Fail;
}
#endif
else
{
#if defined(__GIC_PRIO_BITS)
GIC_DisableIRQ(interrupt);
#else
NVIC_DisableIRQ(interrupt);
#endif
}
return status;
}
/*!
* @brief Disable the global IRQ
*
* Disable the global interrupt and return the current primask register. User is required to provided the primask
* register for the EnableGlobalIRQ().
*
* @return Current primask value.
*/
static inline uint32_t DisableGlobalIRQ(void)
{
#if defined(CPSR_I_Msk)
uint32_t cpsr = __get_CPSR() & CPSR_I_Msk;
__disable_irq();
return cpsr;
#else
uint32_t regPrimask = __get_PRIMASK();
__disable_irq();
return regPrimask;
#endif
}
/*!
* @brief Enable the global IRQ
*
* Set the primask register with the provided primask value but not just enable the primask. The idea is for the
* convenience of integration of RTOS. some RTOS get its own management mechanism of primask. User is required to
* use the EnableGlobalIRQ() and DisableGlobalIRQ() in pair.
*
* @param primask value of primask register to be restored. The primask value is supposed to be provided by the
* DisableGlobalIRQ().
*/
static inline void EnableGlobalIRQ(uint32_t primask)
{
#if defined(CPSR_I_Msk)
__set_CPSR((__get_CPSR() & ~CPSR_I_Msk) | primask);
#else
__set_PRIMASK(primask);
#endif
}
#if defined(ENABLE_RAM_VECTOR_TABLE)
/*!
* @brief install IRQ handler
*
* @param irq IRQ number
* @param irqHandler IRQ handler address
* @return The old IRQ handler address
*/
uint32_t InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler);
#endif /* ENABLE_RAM_VECTOR_TABLE. */
#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0))
/*
* When FSL_FEATURE_POWERLIB_EXTEND is defined to non-zero value,
* powerlib should be used instead of these functions.
*/
#if !(defined(FSL_FEATURE_POWERLIB_EXTEND) && (FSL_FEATURE_POWERLIB_EXTEND != 0))
/*!
* @brief Enable specific interrupt for wake-up from deep-sleep mode.
*
* Enable the interrupt for wake-up from deep sleep mode.
* Some interrupts are typically used in sleep mode only and will not occur during
* deep-sleep mode because relevant clocks are stopped. However, it is possible to enable
* those clocks (significantly increasing power consumption in the reduced power mode),
* making these wake-ups possible.
*
* @note This function also enables the interrupt in the NVIC (EnableIRQ() is called internaly).
*
* @param interrupt The IRQ number.
*/
void EnableDeepSleepIRQ(IRQn_Type interrupt);
/*!
* @brief Disable specific interrupt for wake-up from deep-sleep mode.
*
* Disable the interrupt for wake-up from deep sleep mode.
* Some interrupts are typically used in sleep mode only and will not occur during
* deep-sleep mode because relevant clocks are stopped. However, it is possible to enable
* those clocks (significantly increasing power consumption in the reduced power mode),
* making these wake-ups possible.
*
* @note This function also disables the interrupt in the NVIC (DisableIRQ() is called internaly).
*
* @param interrupt The IRQ number.
*/
void DisableDeepSleepIRQ(IRQn_Type interrupt);
#endif /* FSL_FEATURE_POWERLIB_EXTEND */
#endif /* FSL_FEATURE_SOC_SYSCON_COUNT */
#if defined(__cplusplus)
}
#endif /* __cplusplus*/
/*! @} */
#endif /* _FSL_COMMON_ARM_H_ */

View file

@ -0,0 +1,412 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2019 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_common.h"
#include "fsl_flexcomm.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.flexcomm"
#endif
/*!
* @brief Used for conversion between `void*` and `uint32_t`.
*/
typedef union pvoid_to_u32
{
void *pvoid;
uint32_t u32;
} pvoid_to_u32_t;
/*******************************************************************************
* Prototypes
******************************************************************************/
/*! @brief Set the FLEXCOMM mode . */
static status_t FLEXCOMM_SetPeriph(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph, int lock);
/*! @brief check whether flexcomm supports peripheral type */
static bool FLEXCOMM_PeripheralIsPresent(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph);
/*******************************************************************************
* Variables
******************************************************************************/
/*! @brief Array to map FLEXCOMM instance number to base address. */
static const uint32_t s_flexcommBaseAddrs[] = FLEXCOMM_BASE_ADDRS;
/*! @brief Pointers to real IRQ handlers installed by drivers for each instance. */
static flexcomm_irq_handler_t s_flexcommIrqHandler[ARRAY_SIZE(s_flexcommBaseAddrs)];
/*! @brief Pointers to handles for each instance to provide context to interrupt routines */
static void *s_flexcommHandle[ARRAY_SIZE(s_flexcommBaseAddrs)];
/*! @brief Array to map FLEXCOMM instance number to IRQ number. */
IRQn_Type const kFlexcommIrqs[] = FLEXCOMM_IRQS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief IDs of clock for each FLEXCOMM module */
static const clock_ip_name_t s_flexcommClocks[] = FLEXCOMM_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if !(defined(FSL_FEATURE_FLEXCOMM_HAS_NO_RESET) && FSL_FEATURE_FLEXCOMM_HAS_NO_RESET)
/*! @brief Pointers to FLEXCOMM resets for each instance. */
static const reset_ip_name_t s_flexcommResets[] = FLEXCOMM_RSTS;
#endif
/*******************************************************************************
* Code
******************************************************************************/
/* check whether flexcomm supports peripheral type */
static bool FLEXCOMM_PeripheralIsPresent(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph)
{
if (periph == FLEXCOMM_PERIPH_NONE)
{
return true;
}
else if (periph <= FLEXCOMM_PERIPH_I2S_TX)
{
return (base->PSELID & (1UL << ((uint32_t)periph + 3U))) > 0UL ? true : false;
}
else if (periph == FLEXCOMM_PERIPH_I2S_RX)
{
return (base->PSELID & (1U << 7U)) > (uint32_t)0U ? true : false;
}
else
{
return false;
}
}
/* Get the index corresponding to the FLEXCOMM */
/*! brief Returns instance number for FLEXCOMM module with given base address. */
uint32_t FLEXCOMM_GetInstance(void *base)
{
uint32_t i;
pvoid_to_u32_t BaseAddr;
BaseAddr.pvoid = base;
for (i = 0U; i < (uint32_t)FSL_FEATURE_SOC_FLEXCOMM_COUNT; i++)
{
if (BaseAddr.u32 == s_flexcommBaseAddrs[i])
{
break;
}
}
assert(i < (uint32_t)FSL_FEATURE_SOC_FLEXCOMM_COUNT);
return i;
}
/* Changes FLEXCOMM mode */
static status_t FLEXCOMM_SetPeriph(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph, int lock)
{
/* Check whether peripheral type is present */
if (!FLEXCOMM_PeripheralIsPresent(base, periph))
{
return kStatus_OutOfRange;
}
/* Flexcomm is locked to different peripheral type than expected */
if (((base->PSELID & FLEXCOMM_PSELID_LOCK_MASK) != 0U) &&
((base->PSELID & FLEXCOMM_PSELID_PERSEL_MASK) != (uint32_t)periph))
{
return kStatus_Fail;
}
/* Check if we are asked to lock */
if (lock != 0)
{
base->PSELID = (uint32_t)periph | FLEXCOMM_PSELID_LOCK_MASK;
}
else
{
base->PSELID = (uint32_t)periph;
}
return kStatus_Success;
}
/*! brief Initializes FLEXCOMM and selects peripheral mode according to the second parameter. */
status_t FLEXCOMM_Init(void *base, FLEXCOMM_PERIPH_T periph)
{
uint32_t idx = FLEXCOMM_GetInstance(base);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Enable the peripheral clock */
CLOCK_EnableClock(s_flexcommClocks[idx]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if !(defined(FSL_FEATURE_FLEXCOMM_HAS_NO_RESET) && FSL_FEATURE_FLEXCOMM_HAS_NO_RESET)
/* Reset the FLEXCOMM module */
RESET_PeripheralReset(s_flexcommResets[idx]);
#endif
/* Set the FLEXCOMM to given peripheral */
return FLEXCOMM_SetPeriph((FLEXCOMM_Type *)base, periph, 0);
}
/*! brief Sets IRQ handler for given FLEXCOMM module. It is used by drivers register IRQ handler according to FLEXCOMM
* mode */
void FLEXCOMM_SetIRQHandler(void *base, flexcomm_irq_handler_t handler, void *flexcommHandle)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(base);
/* Clear handler first to avoid execution of the handler with wrong handle */
s_flexcommIrqHandler[instance] = NULL;
s_flexcommHandle[instance] = flexcommHandle;
s_flexcommIrqHandler[instance] = handler;
SDK_ISR_EXIT_BARRIER;
}
/* IRQ handler functions overloading weak symbols in the startup */
#if defined(FLEXCOMM0)
void FLEXCOMM0_DriverIRQHandler(void);
void FLEXCOMM0_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM0);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM1)
void FLEXCOMM1_DriverIRQHandler(void);
void FLEXCOMM1_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM1);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM2)
void FLEXCOMM2_DriverIRQHandler(void);
void FLEXCOMM2_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM2);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM3)
void FLEXCOMM3_DriverIRQHandler(void);
void FLEXCOMM3_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM3);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM4)
void FLEXCOMM4_DriverIRQHandler(void);
void FLEXCOMM4_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM4);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM5)
void FLEXCOMM5_DriverIRQHandler(void);
void FLEXCOMM5_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM5);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM6)
void FLEXCOMM6_DriverIRQHandler(void);
void FLEXCOMM6_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM6);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM7)
void FLEXCOMM7_DriverIRQHandler(void);
void FLEXCOMM7_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM7);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM8)
void FLEXCOMM8_DriverIRQHandler(void);
void FLEXCOMM8_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM8);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM9)
void FLEXCOMM9_DriverIRQHandler(void);
void FLEXCOMM9_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM9);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM10)
void FLEXCOMM10_DriverIRQHandler(void);
void FLEXCOMM10_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM10);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM11)
void FLEXCOMM11_DriverIRQHandler(void);
void FLEXCOMM11_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM11);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM12)
void FLEXCOMM12_DriverIRQHandler(void);
void FLEXCOMM12_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM12);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM13)
void FLEXCOMM13_DriverIRQHandler(void);
void FLEXCOMM13_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM13);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM14)
void FLEXCOMM14_DriverIRQHandler(void);
void FLEXCOMM14_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM14);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM15)
void FLEXCOMM15_DriverIRQHandler(void);
void FLEXCOMM15_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM15);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM16)
void FLEXCOMM16_DriverIRQHandler(void);
void FLEXCOMM16_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM16);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif

View file

@ -0,0 +1,64 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2019 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_FLEXCOMM_H_
#define _FSL_FLEXCOMM_H_
#include "fsl_common.h"
/*!
* @addtogroup flexcomm_driver
* @{
*/
/*! @name Driver version */
/*@{*/
/*! @brief FlexCOMM driver version 2.0.2. */
#define FSL_FLEXCOMM_DRIVER_VERSION (MAKE_VERSION(2, 0, 2))
/*@}*/
/*! @brief FLEXCOMM peripheral modes. */
typedef enum
{
FLEXCOMM_PERIPH_NONE, /*!< No peripheral */
FLEXCOMM_PERIPH_USART, /*!< USART peripheral */
FLEXCOMM_PERIPH_SPI, /*!< SPI Peripheral */
FLEXCOMM_PERIPH_I2C, /*!< I2C Peripheral */
FLEXCOMM_PERIPH_I2S_TX, /*!< I2S TX Peripheral */
FLEXCOMM_PERIPH_I2S_RX, /*!< I2S RX Peripheral */
} FLEXCOMM_PERIPH_T;
/*! @brief Typedef for interrupt handler. */
typedef void (*flexcomm_irq_handler_t)(void *base, void *handle);
/*! @brief Array with IRQ number for each FLEXCOMM module. */
extern IRQn_Type const kFlexcommIrqs[];
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*! @brief Returns instance number for FLEXCOMM module with given base address. */
uint32_t FLEXCOMM_GetInstance(void *base);
/*! @brief Initializes FLEXCOMM and selects peripheral mode according to the second parameter. */
status_t FLEXCOMM_Init(void *base, FLEXCOMM_PERIPH_T periph);
/*! @brief Sets IRQ handler for given FLEXCOMM module. It is used by drivers register IRQ handler according to FLEXCOMM
* mode */
void FLEXCOMM_SetIRQHandler(void *base, flexcomm_irq_handler_t handler, void *flexcommHandle);
#if defined(__cplusplus)
}
#endif
/*@}*/
#endif /* _FSL_FLEXCOMM_H_*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,864 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __FSL_FLEXSPI_H_
#define __FSL_FLEXSPI_H_
#include <stddef.h>
#include "fsl_device_registers.h"
#include "fsl_common.h"
/*!
* @addtogroup flexspi
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief FLEXSPI driver version 2.3.5. */
#define FSL_FLEXSPI_DRIVER_VERSION (MAKE_VERSION(2, 3, 5))
/*@}*/
#define FSL_FEATURE_FLEXSPI_AHB_BUFFER_COUNT FSL_FEATURE_FLEXSPI_AHB_BUFFER_COUNTn(0)
/*! @brief Formula to form FLEXSPI instructions in LUT table. */
#define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \
(FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \
FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1))
/*! @brief Status structure of FLEXSPI.*/
enum
{
kStatus_FLEXSPI_Busy = MAKE_STATUS(kStatusGroup_FLEXSPI, 0), /*!< FLEXSPI is busy */
kStatus_FLEXSPI_SequenceExecutionTimeout = MAKE_STATUS(kStatusGroup_FLEXSPI, 1), /*!< Sequence execution timeout
error occurred during FLEXSPI transfer. */
kStatus_FLEXSPI_IpCommandSequenceError = MAKE_STATUS(kStatusGroup_FLEXSPI, 2), /*!< IP command Sequence execution
timeout error occurred during FLEXSPI transfer. */
kStatus_FLEXSPI_IpCommandGrantTimeout = MAKE_STATUS(kStatusGroup_FLEXSPI, 3), /*!< IP command grant timeout error
occurred during FLEXSPI transfer. */
};
/*! @brief CMD definition of FLEXSPI, use to form LUT instruction, _flexspi_command. */
enum
{
kFLEXSPI_Command_STOP = 0x00U, /*!< Stop execution, deassert CS. */
kFLEXSPI_Command_SDR = 0x01U, /*!< Transmit Command code to Flash, using SDR mode. */
kFLEXSPI_Command_RADDR_SDR = 0x02U, /*!< Transmit Row Address to Flash, using SDR mode. */
kFLEXSPI_Command_CADDR_SDR = 0x03U, /*!< Transmit Column Address to Flash, using SDR mode. */
kFLEXSPI_Command_MODE1_SDR = 0x04U, /*!< Transmit 1-bit Mode bits to Flash, using SDR mode. */
kFLEXSPI_Command_MODE2_SDR = 0x05U, /*!< Transmit 2-bit Mode bits to Flash, using SDR mode. */
kFLEXSPI_Command_MODE4_SDR = 0x06U, /*!< Transmit 4-bit Mode bits to Flash, using SDR mode. */
kFLEXSPI_Command_MODE8_SDR = 0x07U, /*!< Transmit 8-bit Mode bits to Flash, using SDR mode. */
kFLEXSPI_Command_WRITE_SDR = 0x08U, /*!< Transmit Programming Data to Flash, using SDR mode. */
kFLEXSPI_Command_READ_SDR = 0x09U, /*!< Receive Read Data from Flash, using SDR mode. */
kFLEXSPI_Command_LEARN_SDR = 0x0AU, /*!< Receive Read Data or Preamble bit from Flash, SDR mode. */
kFLEXSPI_Command_DATSZ_SDR = 0x0BU, /*!< Transmit Read/Program Data size (byte) to Flash, SDR mode. */
kFLEXSPI_Command_DUMMY_SDR = 0x0CU, /*!< Leave data lines undriven by FlexSPI controller.*/
kFLEXSPI_Command_DUMMY_RWDS_SDR = 0x0DU, /*!< Leave data lines undriven by FlexSPI controller,
dummy cycles decided by RWDS. */
kFLEXSPI_Command_DDR = 0x21U, /*!< Transmit Command code to Flash, using DDR mode. */
kFLEXSPI_Command_RADDR_DDR = 0x22U, /*!< Transmit Row Address to Flash, using DDR mode. */
kFLEXSPI_Command_CADDR_DDR = 0x23U, /*!< Transmit Column Address to Flash, using DDR mode. */
kFLEXSPI_Command_MODE1_DDR = 0x24U, /*!< Transmit 1-bit Mode bits to Flash, using DDR mode. */
kFLEXSPI_Command_MODE2_DDR = 0x25U, /*!< Transmit 2-bit Mode bits to Flash, using DDR mode. */
kFLEXSPI_Command_MODE4_DDR = 0x26U, /*!< Transmit 4-bit Mode bits to Flash, using DDR mode. */
kFLEXSPI_Command_MODE8_DDR = 0x27U, /*!< Transmit 8-bit Mode bits to Flash, using DDR mode. */
kFLEXSPI_Command_WRITE_DDR = 0x28U, /*!< Transmit Programming Data to Flash, using DDR mode. */
kFLEXSPI_Command_READ_DDR = 0x29U, /*!< Receive Read Data from Flash, using DDR mode. */
kFLEXSPI_Command_LEARN_DDR = 0x2AU, /*!< Receive Read Data or Preamble bit from Flash, DDR mode. */
kFLEXSPI_Command_DATSZ_DDR = 0x2BU, /*!< Transmit Read/Program Data size (byte) to Flash, DDR mode. */
kFLEXSPI_Command_DUMMY_DDR = 0x2CU, /*!< Leave data lines undriven by FlexSPI controller.*/
kFLEXSPI_Command_DUMMY_RWDS_DDR = 0x2DU, /*!< Leave data lines undriven by FlexSPI controller,
dummy cycles decided by RWDS. */
kFLEXSPI_Command_JUMP_ON_CS = 0x1FU, /*!< Stop execution, deassert CS and save operand[7:0] as the
instruction start pointer for next sequence */
};
/*! @brief pad definition of FLEXSPI, use to form LUT instruction. */
typedef enum _flexspi_pad
{
kFLEXSPI_1PAD = 0x00U, /*!< Transmit command/address and transmit/receive data only through DATA0/DATA1. */
kFLEXSPI_2PAD = 0x01U, /*!< Transmit command/address and transmit/receive data only through DATA[1:0]. */
kFLEXSPI_4PAD = 0x02U, /*!< Transmit command/address and transmit/receive data only through DATA[3:0]. */
kFLEXSPI_8PAD = 0x03U, /*!< Transmit command/address and transmit/receive data only through DATA[7:0]. */
} flexspi_pad_t;
/*! @brief FLEXSPI interrupt status flags.*/
typedef enum _flexspi_flags
{
kFLEXSPI_SequenceExecutionTimeoutFlag = FLEXSPI_INTEN_SEQTIMEOUTEN_MASK, /*!< Sequence execution timeout. */
#if defined(FSL_FEATURE_FLEXSPI_HAS_INTEN_AHBBUSERROREN) && FSL_FEATURE_FLEXSPI_HAS_INTEN_AHBBUSERROREN
kFLEXSPI_AhbBusErrorFlag = FLEXSPI_INTEN_AHBBUSERROREN_MASK, /*!< AHB Bus error flag. */
#else
kFLEXSPI_AhbBusTimeoutFlag = FLEXSPI_INTEN_AHBBUSTIMEOUTEN_MASK, /*!< AHB Bus timeout. */
#endif
kFLEXSPI_SckStoppedBecauseTxEmptyFlag =
FLEXSPI_INTEN_SCKSTOPBYWREN_MASK, /*!< SCK is stopped during command
sequence because Async TX FIFO empty. */
kFLEXSPI_SckStoppedBecauseRxFullFlag =
FLEXSPI_INTEN_SCKSTOPBYRDEN_MASK, /*!< SCK is stopped during command
sequence because Async RX FIFO full. */
#if !((defined(FSL_FEATURE_FLEXSPI_HAS_NO_DATA_LEARN)) && (FSL_FEATURE_FLEXSPI_HAS_NO_DATA_LEARN))
kFLEXSPI_DataLearningFailedFlag = FLEXSPI_INTEN_DATALEARNFAILEN_MASK, /*!< Data learning failed. */
#endif
kFLEXSPI_IpTxFifoWatermarkEmptyFlag = FLEXSPI_INTEN_IPTXWEEN_MASK, /*!< IP TX FIFO WaterMark empty. */
kFLEXSPI_IpRxFifoWatermarkAvailableFlag = FLEXSPI_INTEN_IPRXWAEN_MASK, /*!< IP RX FIFO WaterMark available. */
kFLEXSPI_AhbCommandSequenceErrorFlag =
FLEXSPI_INTEN_AHBCMDERREN_MASK, /*!< AHB triggered Command Sequences Error. */
kFLEXSPI_IpCommandSequenceErrorFlag = FLEXSPI_INTEN_IPCMDERREN_MASK, /*!< IP triggered Command Sequences Error. */
kFLEXSPI_AhbCommandGrantTimeoutFlag =
FLEXSPI_INTEN_AHBCMDGEEN_MASK, /*!< AHB triggered Command Sequences Grant Timeout. */
kFLEXSPI_IpCommandGrantTimeoutFlag =
FLEXSPI_INTEN_IPCMDGEEN_MASK, /*!< IP triggered Command Sequences Grant Timeout. */
kFLEXSPI_IpCommandExecutionDoneFlag =
FLEXSPI_INTEN_IPCMDDONEEN_MASK, /*!< IP triggered Command Sequences Execution finished. */
kFLEXSPI_AllInterruptFlags = 0xFFFU, /*!< All flags. */
} flexspi_flags_t;
/*! @brief FLEXSPI sample clock source selection for Flash Reading.*/
typedef enum _flexspi_read_sample_clock
{
kFLEXSPI_ReadSampleClkLoopbackInternally = 0x0U, /*!< Dummy Read strobe generated by FlexSPI Controller
and loopback internally. */
kFLEXSPI_ReadSampleClkLoopbackFromDqsPad = 0x1U, /*!< Dummy Read strobe generated by FlexSPI Controller
and loopback from DQS pad. */
kFLEXSPI_ReadSampleClkLoopbackFromSckPad = 0x2U, /*!< SCK output clock and loopback from SCK pad. */
kFLEXSPI_ReadSampleClkExternalInputFromDqsPad = 0x3U, /*!< Flash provided Read strobe and input from DQS pad. */
} flexspi_read_sample_clock_t;
/*! @brief FLEXSPI interval unit for flash device select.*/
typedef enum _flexspi_cs_interval_cycle_unit
{
kFLEXSPI_CsIntervalUnit1SckCycle = 0x0U, /*!< Chip selection interval: CSINTERVAL * 1 serial clock cycle. */
kFLEXSPI_CsIntervalUnit256SckCycle = 0x1U, /*!< Chip selection interval: CSINTERVAL * 256 serial clock cycle. */
} flexspi_cs_interval_cycle_unit_t;
/*! @brief FLEXSPI AHB wait interval unit for writing.*/
typedef enum _flexspi_ahb_write_wait_unit
{
kFLEXSPI_AhbWriteWaitUnit2AhbCycle = 0x0U, /*!< AWRWAIT unit is 2 ahb clock cycle. */
kFLEXSPI_AhbWriteWaitUnit8AhbCycle = 0x1U, /*!< AWRWAIT unit is 8 ahb clock cycle. */
kFLEXSPI_AhbWriteWaitUnit32AhbCycle = 0x2U, /*!< AWRWAIT unit is 32 ahb clock cycle. */
kFLEXSPI_AhbWriteWaitUnit128AhbCycle = 0x3U, /*!< AWRWAIT unit is 128 ahb clock cycle. */
kFLEXSPI_AhbWriteWaitUnit512AhbCycle = 0x4U, /*!< AWRWAIT unit is 512 ahb clock cycle. */
kFLEXSPI_AhbWriteWaitUnit2048AhbCycle = 0x5U, /*!< AWRWAIT unit is 2048 ahb clock cycle. */
kFLEXSPI_AhbWriteWaitUnit8192AhbCycle = 0x6U, /*!< AWRWAIT unit is 8192 ahb clock cycle. */
kFLEXSPI_AhbWriteWaitUnit32768AhbCycle = 0x7U, /*!< AWRWAIT unit is 32768 ahb clock cycle. */
} flexspi_ahb_write_wait_unit_t;
/*! @brief Error Code when IP command Error detected.*/
typedef enum _flexspi_ip_error_code
{
kFLEXSPI_IpCmdErrorNoError = 0x0U, /*!< No error. */
kFLEXSPI_IpCmdErrorJumpOnCsInIpCmd = 0x2U, /*!< IP command with JMP_ON_CS instruction used. */
kFLEXSPI_IpCmdErrorUnknownOpCode = 0x3U, /*!< Unknown instruction opcode in the sequence. */
kFLEXSPI_IpCmdErrorSdrDummyInDdrSequence = 0x4U, /*!< Instruction DUMMY_SDR/DUMMY_RWDS_SDR
used in DDR sequence. */
kFLEXSPI_IpCmdErrorDdrDummyInSdrSequence = 0x5U, /*!< Instruction DUMMY_DDR/DUMMY_RWDS_DDR
used in SDR sequence. */
kFLEXSPI_IpCmdErrorInvalidAddress = 0x6U, /*!< Flash access start address exceed the whole
flash address range (A1/A2/B1/B2). */
kFLEXSPI_IpCmdErrorSequenceExecutionTimeout = 0xEU, /*!< Sequence execution timeout. */
kFLEXSPI_IpCmdErrorFlashBoundaryAcrosss = 0xFU, /*!< Flash boundary crossed. */
} flexspi_ip_error_code_t;
/*! @brief Error Code when AHB command Error detected.*/
typedef enum _flexspi_ahb_error_code
{
kFLEXSPI_AhbCmdErrorNoError = 0x0U, /*!< No error. */
kFLEXSPI_AhbCmdErrorJumpOnCsInWriteCmd = 0x2U, /*!< AHB Write command with JMP_ON_CS instruction
used in the sequence. */
kFLEXSPI_AhbCmdErrorUnknownOpCode = 0x3U, /*!< Unknown instruction opcode in the sequence. */
kFLEXSPI_AhbCmdErrorSdrDummyInDdrSequence = 0x4U, /*!< Instruction DUMMY_SDR/DUMMY_RWDS_SDR used
in DDR sequence. */
kFLEXSPI_AhbCmdErrorDdrDummyInSdrSequence = 0x5U, /*!< Instruction DUMMY_DDR/DUMMY_RWDS_DDR
used in SDR sequence. */
kFLEXSPI_AhbCmdSequenceExecutionTimeout = 0x6U, /*!< Sequence execution timeout. */
} flexspi_ahb_error_code_t;
/*! @brief FLEXSPI operation port select.*/
typedef enum _flexspi_port
{
kFLEXSPI_PortA1 = 0x0U, /*!< Access flash on A1 port. */
kFLEXSPI_PortA2, /*!< Access flash on A2 port. */
kFLEXSPI_PortB1, /*!< Access flash on B1 port. */
kFLEXSPI_PortB2, /*!< Access flash on B2 port. */
kFLEXSPI_PortCount
} flexspi_port_t;
/*! @brief Trigger source of current command sequence granted by arbitrator.*/
typedef enum _flexspi_arb_command_source
{
kFLEXSPI_AhbReadCommand = 0x0U,
kFLEXSPI_AhbWriteCommand = 0x1U,
kFLEXSPI_IpCommand = 0x2U,
kFLEXSPI_SuspendedCommand = 0x3U,
} flexspi_arb_command_source_t;
/*! @brief Command type. */
typedef enum _flexspi_command_type
{
kFLEXSPI_Command, /*!< FlexSPI operation: Only command, both TX and Rx buffer are ignored. */
kFLEXSPI_Config, /*!< FlexSPI operation: Configure device mode, the TX fifo size is fixed in LUT. */
kFLEXSPI_Read, /* /!< FlexSPI operation: Read, only Rx Buffer is effective. */
kFLEXSPI_Write, /* /!< FlexSPI operation: Read, only Tx Buffer is effective. */
} flexspi_command_type_t;
typedef struct _flexspi_ahbBuffer_config
{
uint8_t priority; /*!< This priority for AHB Master Read which this AHB RX Buffer is assigned. */
uint8_t masterIndex; /*!< AHB Master ID the AHB RX Buffer is assigned. */
uint16_t bufferSize; /*!< AHB buffer size in byte. */
bool enablePrefetch; /*!< AHB Read Prefetch Enable for current AHB RX Buffer corresponding Master, allows
prefetch disable/enable separately for each master. */
} flexspi_ahbBuffer_config_t;
/*! @brief FLEXSPI configuration structure. */
typedef struct _flexspi_config
{
flexspi_read_sample_clock_t rxSampleClock; /*!< Sample Clock source selection for Flash Reading. */
bool enableSckFreeRunning; /*!< Enable/disable SCK output free-running. */
#if !(defined(FSL_FEATURE_FLEXSPI_HAS_NO_MCR0_COMBINATIONEN) && FSL_FEATURE_FLEXSPI_HAS_NO_MCR0_COMBINATIONEN)
bool enableCombination; /*!< Enable/disable combining PORT A and B Data Pins
(SIOA[3:0] and SIOB[3:0]) to support Flash Octal mode. */
#endif
bool enableDoze; /*!< Enable/disable doze mode support. */
bool enableHalfSpeedAccess; /*!< Enable/disable divide by 2 of the clock for half
speed commands. */
bool enableSckBDiffOpt; /*!< Enable/disable SCKB pad use as SCKA differential clock
output, when enable, Port B flash access is not available. */
bool enableSameConfigForAll; /*!< Enable/disable same configuration for all connected devices
when enabled, same configuration in FLASHA1CRx is applied to all. */
uint16_t seqTimeoutCycle; /*!< Timeout wait cycle for command sequence execution,
timeout after ahbGrantTimeoutCyle*1024 serial root clock cycles. */
uint8_t ipGrantTimeoutCycle; /*!< Timeout wait cycle for IP command grant, timeout after
ipGrantTimeoutCycle*1024 AHB clock cycles. */
uint8_t txWatermark; /*!< FLEXSPI IP transmit watermark value. */
uint8_t rxWatermark; /*!< FLEXSPI receive watermark value. */
struct
{
#if !(defined(FSL_FEATURE_FLEXSPI_HAS_NO_MCR0_ATDFEN) && FSL_FEATURE_FLEXSPI_HAS_NO_MCR0_ATDFEN)
bool enableAHBWriteIpTxFifo; /*!< Enable AHB bus write access to IP TX FIFO. */
#endif
#if !(defined(FSL_FEATURE_FLEXSPI_HAS_NO_MCR0_ARDFEN) && FSL_FEATURE_FLEXSPI_HAS_NO_MCR0_ARDFEN)
bool enableAHBWriteIpRxFifo; /*!< Enable AHB bus write access to IP RX FIFO. */
#endif
uint8_t ahbGrantTimeoutCycle; /*!< Timeout wait cycle for AHB command grant,
timeout after ahbGrantTimeoutCyle*1024 AHB clock cycles. */
uint16_t ahbBusTimeoutCycle; /*!< Timeout wait cycle for AHB read/write access,
timeout after ahbBusTimeoutCycle*1024 AHB clock cycles. */
uint8_t resumeWaitCycle; /*!< Wait cycle for idle state before suspended command sequence
resume, timeout after ahbBusTimeoutCycle AHB clock cycles. */
flexspi_ahbBuffer_config_t buffer[FSL_FEATURE_FLEXSPI_AHB_BUFFER_COUNT]; /*!< AHB buffer size. */
bool enableClearAHBBufferOpt; /*!< Enable/disable automatically clean AHB RX Buffer and TX Buffer
when FLEXSPI returns STOP mode ACK. */
bool enableReadAddressOpt; /*!< Enable/disable remove AHB read burst start address alignment limitation.
when enable, there is no AHB read burst start address alignment limitation. */
bool enableAHBPrefetch; /*!< Enable/disable AHB read prefetch feature, when enabled, FLEXSPI
will fetch more data than current AHB burst. */
bool enableAHBBufferable; /*!< Enable/disable AHB bufferable write access support, when enabled,
FLEXSPI return before waiting for command execution finished. */
bool enableAHBCachable; /*!< Enable AHB bus cachable read access support. */
} ahbConfig;
} flexspi_config_t;
/*! @brief External device configuration items. */
typedef struct _flexspi_device_config
{
uint32_t flexspiRootClk; /*!< FLEXSPI serial root clock. */
bool isSck2Enabled; /*!< FLEXSPI use SCK2. */
uint32_t flashSize; /*!< Flash size in KByte. */
flexspi_cs_interval_cycle_unit_t CSIntervalUnit; /*!< CS interval unit, 1 or 256 cycle. */
uint16_t CSInterval; /*!< CS line assert interval, multiply CS interval unit to
get the CS line assert interval cycles. */
uint8_t CSHoldTime; /*!< CS line hold time. */
uint8_t CSSetupTime; /*!< CS line setup time. */
uint8_t dataValidTime; /*!< Data valid time for external device. */
uint8_t columnspace; /*!< Column space size. */
bool enableWordAddress; /*!< If enable word address.*/
uint8_t AWRSeqIndex; /*!< Sequence ID for AHB write command. */
uint8_t AWRSeqNumber; /*!< Sequence number for AHB write command. */
uint8_t ARDSeqIndex; /*!< Sequence ID for AHB read command. */
uint8_t ARDSeqNumber; /*!< Sequence number for AHB read command. */
flexspi_ahb_write_wait_unit_t AHBWriteWaitUnit; /*!< AHB write wait unit. */
uint16_t AHBWriteWaitInterval; /*!< AHB write wait interval, multiply AHB write interval
unit to get the AHB write wait cycles. */
bool enableWriteMask; /*!< Enable/Disable FLEXSPI drive DQS pin as write mask
when writing to external device. */
} flexspi_device_config_t;
/*! @brief Transfer structure for FLEXSPI. */
typedef struct _flexspi_transfer
{
uint32_t deviceAddress; /*!< Operation device address. */
flexspi_port_t port; /*!< Operation port. */
flexspi_command_type_t cmdType; /*!< Execution command type. */
uint8_t seqIndex; /*!< Sequence ID for command. */
uint8_t SeqNumber; /*!< Sequence number for command. */
uint32_t *data; /*!< Data buffer. */
size_t dataSize; /*!< Data size in bytes. */
} flexspi_transfer_t;
/* Forward declaration of the handle typedef. */
typedef struct _flexspi_handle flexspi_handle_t;
/*! @brief FLEXSPI transfer callback function. */
typedef void (*flexspi_transfer_callback_t)(FLEXSPI_Type *base,
flexspi_handle_t *handle,
status_t status,
void *userData);
/*! @brief Transfer handle structure for FLEXSPI. */
struct _flexspi_handle
{
uint32_t state; /*!< Internal state for FLEXSPI transfer */
uint32_t *data; /*!< Data buffer. */
size_t dataSize; /*!< Remaining Data size in bytes. */
size_t transferTotalSize; /*!< Total Data size in bytes. */
flexspi_transfer_callback_t completionCallback; /*!< Callback for users while transfer finish or error occurred */
void *userData; /*!< FLEXSPI callback function parameter.*/
};
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /*_cplusplus. */
/*!
* @name Initialization and deinitialization
* @{
*/
/*!
* @brief Get the instance number for FLEXSPI.
*
* @param base FLEXSPI base pointer.
*/
uint32_t FLEXSPI_GetInstance(FLEXSPI_Type *base);
/*!
* @brief Check and clear IP command execution errors.
*
* @param base FLEXSPI base pointer.
* @param status interrupt status.
*/
status_t FLEXSPI_CheckAndClearError(FLEXSPI_Type *base, uint32_t status);
/*!
* @brief Initializes the FLEXSPI module and internal state.
*
* This function enables the clock for FLEXSPI and also configures the FLEXSPI with the
* input configure parameters. Users should call this function before any FLEXSPI operations.
*
* @param base FLEXSPI peripheral base address.
* @param config FLEXSPI configure structure.
*/
void FLEXSPI_Init(FLEXSPI_Type *base, const flexspi_config_t *config);
/*!
* @brief Gets default settings for FLEXSPI.
*
* @param config FLEXSPI configuration structure.
*/
void FLEXSPI_GetDefaultConfig(flexspi_config_t *config);
/*!
* @brief Deinitializes the FLEXSPI module.
*
* Clears the FLEXSPI state and FLEXSPI module registers.
* @param base FLEXSPI peripheral base address.
*/
void FLEXSPI_Deinit(FLEXSPI_Type *base);
/*!
* @brief Update FLEXSPI DLL value depending on currently flexspi root clock.
*
* @param base FLEXSPI peripheral base address.
* @param config Flash configuration parameters.
* @param port FLEXSPI Operation port.
*/
void FLEXSPI_UpdateDllValue(FLEXSPI_Type *base, flexspi_device_config_t *config, flexspi_port_t port);
/*!
* @brief Configures the connected device parameter.
*
* This function configures the connected device relevant parameters, such as the size, command, and so on.
* The flash configuration value cannot have a default value. The user needs to configure it according to the
* connected device.
*
* @param base FLEXSPI peripheral base address.
* @param config Flash configuration parameters.
* @param port FLEXSPI Operation port.
*/
void FLEXSPI_SetFlashConfig(FLEXSPI_Type *base, flexspi_device_config_t *config, flexspi_port_t port);
/*!
* @brief Software reset for the FLEXSPI logic.
*
* This function sets the software reset flags for both AHB and buffer domain and
* resets both AHB buffer and also IP FIFOs.
*
* @param base FLEXSPI peripheral base address.
*/
static inline void FLEXSPI_SoftwareReset(FLEXSPI_Type *base)
{
base->MCR0 |= FLEXSPI_MCR0_SWRESET_MASK;
while (0U != (base->MCR0 & FLEXSPI_MCR0_SWRESET_MASK))
{
}
}
/*!
* @brief Enables or disables the FLEXSPI module.
*
* @param base FLEXSPI peripheral base address.
* @param enable True means enable FLEXSPI, false means disable.
*/
static inline void FLEXSPI_Enable(FLEXSPI_Type *base, bool enable)
{
if (enable)
{
base->MCR0 &= ~FLEXSPI_MCR0_MDIS_MASK;
}
else
{
base->MCR0 |= FLEXSPI_MCR0_MDIS_MASK;
}
}
/* @} */
/*!
* @name Interrupts
* @{
*/
/*!
* @brief Enables the FLEXSPI interrupts.
*
* @param base FLEXSPI peripheral base address.
* @param mask FLEXSPI interrupt source.
*/
static inline void FLEXSPI_EnableInterrupts(FLEXSPI_Type *base, uint32_t mask)
{
base->INTEN |= mask;
}
/*!
* @brief Disable the FLEXSPI interrupts.
*
* @param base FLEXSPI peripheral base address.
* @param mask FLEXSPI interrupt source.
*/
static inline void FLEXSPI_DisableInterrupts(FLEXSPI_Type *base, uint32_t mask)
{
base->INTEN &= ~mask;
}
/* @} */
/*! @name DMA control */
/*@{*/
/*!
* @brief Enables or disables FLEXSPI IP Tx FIFO DMA requests.
*
* @param base FLEXSPI peripheral base address.
* @param enable Enable flag for transmit DMA request. Pass true for enable, false for disable.
*/
static inline void FLEXSPI_EnableTxDMA(FLEXSPI_Type *base, bool enable)
{
if (enable)
{
base->IPTXFCR |= FLEXSPI_IPTXFCR_TXDMAEN_MASK;
}
else
{
base->IPTXFCR &= ~FLEXSPI_IPTXFCR_TXDMAEN_MASK;
}
}
/*!
* @brief Enables or disables FLEXSPI IP Rx FIFO DMA requests.
*
* @param base FLEXSPI peripheral base address.
* @param enable Enable flag for receive DMA request. Pass true for enable, false for disable.
*/
static inline void FLEXSPI_EnableRxDMA(FLEXSPI_Type *base, bool enable)
{
if (enable)
{
base->IPRXFCR |= FLEXSPI_IPRXFCR_RXDMAEN_MASK;
}
else
{
base->IPRXFCR &= ~FLEXSPI_IPRXFCR_RXDMAEN_MASK;
}
}
/*!
* @brief Gets FLEXSPI IP tx fifo address for DMA transfer.
*
* @param base FLEXSPI peripheral base address.
* @retval The tx fifo address.
*/
static inline uint32_t FLEXSPI_GetTxFifoAddress(FLEXSPI_Type *base)
{
return (uint32_t)&base->TFDR[0];
}
/*!
* @brief Gets FLEXSPI IP rx fifo address for DMA transfer.
*
* @param base FLEXSPI peripheral base address.
* @retval The rx fifo address.
*/
static inline uint32_t FLEXSPI_GetRxFifoAddress(FLEXSPI_Type *base)
{
return (uint32_t)&base->RFDR[0];
}
/*@}*/
/*! @name FIFO control */
/*@{*/
/*! @brief Clears the FLEXSPI IP FIFO logic.
*
* @param base FLEXSPI peripheral base address.
* @param txFifo Pass true to reset TX FIFO.
* @param rxFifo Pass true to reset RX FIFO.
*/
static inline void FLEXSPI_ResetFifos(FLEXSPI_Type *base, bool txFifo, bool rxFifo)
{
if (txFifo)
{
base->IPTXFCR |= FLEXSPI_IPTXFCR_CLRIPTXF_MASK;
}
if (rxFifo)
{
base->IPRXFCR |= FLEXSPI_IPRXFCR_CLRIPRXF_MASK;
}
}
/*!
* @brief Gets the valid data entries in the FLEXSPI FIFOs.
*
* @param base FLEXSPI peripheral base address.
* @param[out] txCount Pointer through which the current number of bytes in the transmit FIFO is returned.
* Pass NULL if this value is not required.
* @param[out] rxCount Pointer through which the current number of bytes in the receive FIFO is returned.
* Pass NULL if this value is not required.
*/
static inline void FLEXSPI_GetFifoCounts(FLEXSPI_Type *base, size_t *txCount, size_t *rxCount)
{
if (NULL != txCount)
{
*txCount = (((base->IPTXFSTS) & FLEXSPI_IPTXFSTS_FILL_MASK) >> FLEXSPI_IPTXFSTS_FILL_SHIFT) * 8U;
}
if (NULL != rxCount)
{
*rxCount = (((base->IPRXFSTS) & FLEXSPI_IPRXFSTS_FILL_MASK) >> FLEXSPI_IPRXFSTS_FILL_SHIFT) * 8U;
}
}
/*@}*/
/*!
* @name Status
* @{
*/
/*!
* @brief Get the FLEXSPI interrupt status flags.
*
* @param base FLEXSPI peripheral base address.
* @retval interrupt status flag, use status flag to AND #flexspi_flags_t could get the related status.
*/
static inline uint32_t FLEXSPI_GetInterruptStatusFlags(FLEXSPI_Type *base)
{
return base->INTR;
}
/*!
* @brief Get the FLEXSPI interrupt status flags.
*
* @param base FLEXSPI peripheral base address.
* @param mask FLEXSPI interrupt source.
*/
static inline void FLEXSPI_ClearInterruptStatusFlags(FLEXSPI_Type *base, uint32_t mask)
{
base->INTR |= mask;
}
#if !((defined(FSL_FEATURE_FLEXSPI_HAS_NO_DATA_LEARN)) && (FSL_FEATURE_FLEXSPI_HAS_NO_DATA_LEARN))
/*! @brief Gets the sampling clock phase selection after Data Learning.
*
* @param base FLEXSPI peripheral base address.
* @param portAPhase Pointer to a uint8_t type variable to receive the selected clock phase on PORTA.
* @param portBPhase Pointer to a uint8_t type variable to receive the selected clock phase on PORTB.
*/
static inline void FLEXSPI_GetDataLearningPhase(FLEXSPI_Type *base, uint8_t *portAPhase, uint8_t *portBPhase)
{
if (portAPhase != NULL)
{
*portAPhase = (uint8_t)((base->STS0 & FLEXSPI_STS0_DATALEARNPHASEA_MASK) >> FLEXSPI_STS0_DATALEARNPHASEA_SHIFT);
}
if (portBPhase != NULL)
{
*portBPhase = (uint8_t)((base->STS0 & FLEXSPI_STS0_DATALEARNPHASEB_MASK) >> FLEXSPI_STS0_DATALEARNPHASEB_SHIFT);
}
}
#endif
/*! @brief Gets the trigger source of current command sequence granted by arbitrator.
*
* @param base FLEXSPI peripheral base address.
* @retval trigger source of current command sequence.
*/
static inline flexspi_arb_command_source_t FLEXSPI_GetArbitratorCommandSource(FLEXSPI_Type *base)
{
return (flexspi_arb_command_source_t)(
(uint32_t)((base->STS0 & FLEXSPI_STS0_ARBCMDSRC_MASK) >> FLEXSPI_STS0_ARBCMDSRC_SHIFT));
}
/*! @brief Gets the error code when IP command error detected.
*
* @param base FLEXSPI peripheral base address.
* @param index Pointer to a uint8_t type variable to receive the sequence index when error detected.
* @retval error code when IP command error detected.
*/
static inline flexspi_ip_error_code_t FLEXSPI_GetIPCommandErrorCode(FLEXSPI_Type *base, uint8_t *index)
{
*index = (uint8_t)((base->STS1 & FLEXSPI_STS1_IPCMDERRID_MASK) >> FLEXSPI_STS1_IPCMDERRID_SHIFT);
return (flexspi_ip_error_code_t)(
(uint32_t)((base->STS1 & FLEXSPI_STS1_IPCMDERRCODE_MASK) >> FLEXSPI_STS1_IPCMDERRCODE_SHIFT));
}
/*! @brief Gets the error code when AHB command error detected.
*
* @param base FLEXSPI peripheral base address.
* @param index Pointer to a uint8_t type variable to receive the sequence index when error detected.
* @retval error code when AHB command error detected.
*/
static inline flexspi_ahb_error_code_t FLEXSPI_GetAHBCommandErrorCode(FLEXSPI_Type *base, uint8_t *index)
{
*index = (uint8_t)(base->STS1 & FLEXSPI_STS1_AHBCMDERRID_MASK) >> FLEXSPI_STS1_AHBCMDERRID_SHIFT;
return (flexspi_ahb_error_code_t)(
(uint32_t)((base->STS1 & FLEXSPI_STS1_AHBCMDERRCODE_MASK) >> FLEXSPI_STS1_AHBCMDERRCODE_SHIFT));
}
/*! @brief Returns whether the bus is idle.
*
* @param base FLEXSPI peripheral base address.
* @retval true Bus is idle.
* @retval false Bus is busy.
*/
static inline bool FLEXSPI_GetBusIdleStatus(FLEXSPI_Type *base)
{
return (0U != (base->STS0 & FLEXSPI_STS0_ARBIDLE_MASK)) && (0U != (base->STS0 & FLEXSPI_STS0_SEQIDLE_MASK));
}
/*@}*/
/*!
* @name Bus Operations
* @{
*/
/*! @brief Update read sample clock source
*
* @param base FLEXSPI peripheral base address.
* @param clockSource clockSource of type #flexspi_read_sample_clock_t
*/
void FLEXSPI_UpdateRxSampleClock(FLEXSPI_Type *base, flexspi_read_sample_clock_t clockSource);
/*! @brief Enables/disables the FLEXSPI IP command parallel mode.
*
* @param base FLEXSPI peripheral base address.
* @param enable True means enable parallel mode, false means disable parallel mode.
*/
static inline void FLEXSPI_EnableIPParallelMode(FLEXSPI_Type *base, bool enable)
{
if (enable)
{
base->IPCR1 |= FLEXSPI_IPCR1_IPAREN_MASK;
}
else
{
base->IPCR1 &= ~FLEXSPI_IPCR1_IPAREN_MASK;
}
}
/*! @brief Enables/disables the FLEXSPI AHB command parallel mode.
*
* @param base FLEXSPI peripheral base address.
* @param enable True means enable parallel mode, false means disable parallel mode.
*/
static inline void FLEXSPI_EnableAHBParallelMode(FLEXSPI_Type *base, bool enable)
{
if (enable)
{
base->AHBCR |= FLEXSPI_AHBCR_APAREN_MASK;
}
else
{
base->AHBCR &= ~FLEXSPI_AHBCR_APAREN_MASK;
}
}
/*! @brief Updates the LUT table.
*
* @param base FLEXSPI peripheral base address.
* @param index From which index start to update. It could be any index of the LUT table, which
* also allows user to update command content inside a command. Each command consists of up to
* 8 instructions and occupy 4*32-bit memory.
* @param cmd Command sequence array.
* @param count Number of sequences.
*/
void FLEXSPI_UpdateLUT(FLEXSPI_Type *base, uint32_t index, const uint32_t *cmd, uint32_t count);
/*!
* @brief Writes data into FIFO.
*
* @param base FLEXSPI peripheral base address
* @param data The data bytes to send
* @param fifoIndex Destination fifo index.
*/
static inline void FLEXSPI_WriteData(FLEXSPI_Type *base, uint32_t data, uint8_t fifoIndex)
{
base->TFDR[fifoIndex] = data;
}
/*!
* @brief Receives data from data FIFO.
*
* @param base FLEXSPI peripheral base address
* @param fifoIndex Source fifo index.
* @return The data in the FIFO.
*/
static inline uint32_t FLEXSPI_ReadData(FLEXSPI_Type *base, uint8_t fifoIndex)
{
return base->RFDR[fifoIndex];
}
/*!
* @brief Sends a buffer of data bytes using blocking method.
* @note This function blocks via polling until all bytes have been sent.
* @param base FLEXSPI peripheral base address
* @param buffer The data bytes to send
* @param size The number of data bytes to send
* @retval kStatus_Success write success without error
* @retval kStatus_FLEXSPI_SequenceExecutionTimeout sequence execution timeout
* @retval kStatus_FLEXSPI_IpCommandSequenceError IP command sequence error detected
* @retval kStatus_FLEXSPI_IpCommandGrantTimeout IP command grant timeout detected
*/
status_t FLEXSPI_WriteBlocking(FLEXSPI_Type *base, uint32_t *buffer, size_t size);
/*!
* @brief Receives a buffer of data bytes using a blocking method.
* @note This function blocks via polling until all bytes have been sent.
* @param base FLEXSPI peripheral base address
* @param buffer The data bytes to send
* @param size The number of data bytes to receive
* @retval kStatus_Success read success without error
* @retval kStatus_FLEXSPI_SequenceExecutionTimeout sequence execution timeout
* @retval kStatus_FLEXSPI_IpCommandSequenceError IP command sequencen error detected
* @retval kStatus_FLEXSPI_IpCommandGrantTimeout IP command grant timeout detected
*/
status_t FLEXSPI_ReadBlocking(FLEXSPI_Type *base, uint32_t *buffer, size_t size);
/*!
* @brief Execute command to transfer a buffer data bytes using a blocking method.
* @param base FLEXSPI peripheral base address
* @param xfer pointer to the transfer structure.
* @retval kStatus_Success command transfer success without error
* @retval kStatus_FLEXSPI_SequenceExecutionTimeout sequence execution timeout
* @retval kStatus_FLEXSPI_IpCommandSequenceError IP command sequence error detected
* @retval kStatus_FLEXSPI_IpCommandGrantTimeout IP command grant timeout detected
*/
status_t FLEXSPI_TransferBlocking(FLEXSPI_Type *base, flexspi_transfer_t *xfer);
/*! @} */
/*!
* @name Transactional
* @{
*/
/*!
* @brief Initializes the FLEXSPI handle which is used in transactional functions.
*
* @param base FLEXSPI peripheral base address.
* @param handle pointer to flexspi_handle_t structure to store the transfer state.
* @param callback pointer to user callback function.
* @param userData user parameter passed to the callback function.
*/
void FLEXSPI_TransferCreateHandle(FLEXSPI_Type *base,
flexspi_handle_t *handle,
flexspi_transfer_callback_t callback,
void *userData);
/*!
* @brief Performs a interrupt non-blocking transfer on the FLEXSPI bus.
*
* @note Calling the API returns immediately after transfer initiates. The user needs
* to call FLEXSPI_GetTransferCount to poll the transfer status to check whether
* the transfer is finished. If the return status is not kStatus_FLEXSPI_Busy, the transfer
* is finished. For FLEXSPI_Read, the dataSize should be multiple of rx watermark level, or
* FLEXSPI could not read data properly.
*
* @param base FLEXSPI peripheral base address.
* @param handle pointer to flexspi_handle_t structure which stores the transfer state.
* @param xfer pointer to flexspi_transfer_t structure.
* @retval kStatus_Success Successfully start the data transmission.
* @retval kStatus_FLEXSPI_Busy Previous transmission still not finished.
*/
status_t FLEXSPI_TransferNonBlocking(FLEXSPI_Type *base, flexspi_handle_t *handle, flexspi_transfer_t *xfer);
/*!
* @brief Gets the master transfer status during a interrupt non-blocking transfer.
*
* @param base FLEXSPI peripheral base address.
* @param handle pointer to flexspi_handle_t structure which stores the transfer state.
* @param count Number of bytes transferred so far by the non-blocking transaction.
* @retval kStatus_InvalidArgument count is Invalid.
* @retval kStatus_Success Successfully return the count.
*/
status_t FLEXSPI_TransferGetCount(FLEXSPI_Type *base, flexspi_handle_t *handle, size_t *count);
/*!
* @brief Aborts an interrupt non-blocking transfer early.
*
* @note This API can be called at any time when an interrupt non-blocking transfer initiates
* to abort the transfer early.
*
* @param base FLEXSPI peripheral base address.
* @param handle pointer to flexspi_handle_t structure which stores the transfer state
*/
void FLEXSPI_TransferAbort(FLEXSPI_Type *base, flexspi_handle_t *handle);
/*!
* @brief Master interrupt handler.
*
* @param base FLEXSPI peripheral base address.
* @param handle pointer to flexspi_handle_t structure.
*/
void FLEXSPI_TransferHandleIRQ(FLEXSPI_Type *base, flexspi_handle_t *handle);
/*! @} */
#if defined(__cplusplus)
}
#endif /*_cplusplus. */
/*@}*/
#endif /* __FSL_FLEXSPI_H_ */

View file

@ -0,0 +1,317 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_gpio.h"
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.lpc_gpio"
#endif
/*******************************************************************************
* Variables
******************************************************************************/
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Array to map FGPIO instance number to clock name. */
static const clock_ip_name_t s_gpioClockName[] = GPIO_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if !(defined(FSL_FEATURE_GPIO_HAS_NO_RESET) && FSL_FEATURE_GPIO_HAS_NO_RESET)
/*! @brief Pointers to GPIO resets for each instance. */
static const reset_ip_name_t s_gpioResets[] = GPIO_RSTS_N;
#endif
/*******************************************************************************
* Prototypes
************ ******************************************************************/
/*!
* @brief Enable GPIO port clock.
*
* @param base GPIO peripheral base pointer.
* @param port GPIO port number.
*/
static void GPIO_EnablePortClock(GPIO_Type *base, uint32_t port);
/*******************************************************************************
* Code
******************************************************************************/
static void GPIO_EnablePortClock(GPIO_Type *base, uint32_t port)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
assert(port < ARRAY_SIZE(s_gpioClockName));
/* Upgate the GPIO clock */
CLOCK_EnableClock(s_gpioClockName[port]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
/*!
* brief Initializes the GPIO peripheral.
*
* This function ungates the GPIO clock.
*
* param base GPIO peripheral base pointer.
* param port GPIO port number.
*/
void GPIO_PortInit(GPIO_Type *base, uint32_t port)
{
GPIO_EnablePortClock(base, port);
#if !(defined(FSL_FEATURE_GPIO_HAS_NO_RESET) && FSL_FEATURE_GPIO_HAS_NO_RESET)
/* Reset the GPIO module */
RESET_PeripheralReset(s_gpioResets[port]);
#endif
}
/*!
* brief Initializes a GPIO pin used by the board.
*
* To initialize the GPIO, define a pin configuration, either input or output, in the user file.
* Then, call the GPIO_PinInit() function.
*
* This is an example to define an input pin or output pin configuration:
* code
* Define a digital input pin configuration,
* gpio_pin_config_t config =
* {
* kGPIO_DigitalInput,
* 0,
* }
* Define a digital output pin configuration,
* gpio_pin_config_t config =
* {
* kGPIO_DigitalOutput,
* 0,
* }
* endcode
*
* param base GPIO peripheral base pointer(Typically GPIO)
* param port GPIO port number
* param pin GPIO pin number
* param config GPIO pin configuration pointer
*/
void GPIO_PinInit(GPIO_Type *base, uint32_t port, uint32_t pin, const gpio_pin_config_t *config)
{
GPIO_EnablePortClock(base, port);
if (config->pinDirection == kGPIO_DigitalInput)
{
#if defined(FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR) && (FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR)
base->DIRCLR[port] = 1UL << pin;
#else
base->DIR[port] &= ~(1UL << pin);
#endif /*FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR*/
}
else
{
/* Set default output value */
if (config->outputLogic == 0U)
{
base->CLR[port] = (1UL << pin);
}
else
{
base->SET[port] = (1UL << pin);
}
/* Set pin direction */
#if defined(FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR) && (FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR)
base->DIRSET[port] = 1UL << pin;
#else
base->DIR[port] |= 1UL << pin;
#endif /*FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR*/
}
}
#if defined(FSL_FEATURE_GPIO_HAS_INTERRUPT) && FSL_FEATURE_GPIO_HAS_INTERRUPT
/*!
* @brief Set the configuration of pin interrupt.
*
* @param base GPIO base pointer.
* @param port GPIO port number
* @param pin GPIO pin number.
* @param config GPIO pin interrupt configuration..
*/
void GPIO_SetPinInterruptConfig(GPIO_Type *base, uint32_t port, uint32_t pin, gpio_interrupt_config_t *config)
{
base->INTEDG[port] = (base->INTEDG[port] & ~(1UL << pin)) | ((uint32_t)config->mode << pin);
base->INTPOL[port] = (base->INTPOL[port] & ~(1UL << pin)) | ((uint32_t)config->polarity << pin);
}
/*!
* @brief Enables multiple pins interrupt.
*
* @param base GPIO base pointer.
* @param port GPIO port number.
* @param index GPIO interrupt number.
* @param mask GPIO pin number macro.
*/
void GPIO_PortEnableInterrupts(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask)
{
if ((uint32_t)kGPIO_InterruptA == index)
{
base->INTENA[port] = base->INTENA[port] | mask;
}
else if ((uint32_t)kGPIO_InterruptB == index)
{
base->INTENB[port] = base->INTENB[port] | mask;
}
else
{
/*Should not enter here*/
}
}
/*!
* @brief Disables multiple pins interrupt.
*
* @param base GPIO base pointer.
* @param port GPIO port number.
* @param index GPIO interrupt number.
* @param mask GPIO pin number macro.
*/
void GPIO_PortDisableInterrupts(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask)
{
if ((uint32_t)kGPIO_InterruptA == index)
{
base->INTENA[port] = base->INTENA[port] & ~mask;
}
else if ((uint32_t)kGPIO_InterruptB == index)
{
base->INTENB[port] = base->INTENB[port] & ~mask;
}
else
{
/*Should not enter here*/
}
}
/*!
* @brief Clears multiple pins interrupt flag. Status flags are cleared by
* writing a 1 to the corresponding bit position.
*
* @param base GPIO base pointer.
* @param port GPIO port number.
* @param index GPIO interrupt number.
* @param mask GPIO pin number macro.
*/
void GPIO_PortClearInterruptFlags(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask)
{
if ((uint32_t)kGPIO_InterruptA == index)
{
base->INTSTATA[port] = mask;
}
else if ((uint32_t)kGPIO_InterruptB == index)
{
base->INTSTATB[port] = mask;
}
else
{
/*Should not enter here*/
}
}
/*!
* @ Read port interrupt status.
*
* @param base GPIO base pointer.
* @param port GPIO port number
* @param index GPIO interrupt number.
* @retval masked GPIO status value
*/
uint32_t GPIO_PortGetInterruptStatus(GPIO_Type *base, uint32_t port, uint32_t index)
{
uint32_t status = 0U;
if ((uint32_t)kGPIO_InterruptA == index)
{
status = base->INTSTATA[port];
}
else if ((uint32_t)kGPIO_InterruptB == index)
{
status = base->INTSTATB[port];
}
else
{
/*Should not enter here*/
}
return status;
}
/*!
* @brief Enables the specific pin interrupt.
*
* @param base GPIO base pointer.
* @param port GPIO port number.
* @param pin GPIO pin number.
* @param index GPIO interrupt number.
*/
void GPIO_PinEnableInterrupt(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index)
{
if ((uint32_t)kGPIO_InterruptA == index)
{
base->INTENA[port] = base->INTENA[port] | (1UL << pin);
}
else if ((uint32_t)kGPIO_InterruptB == index)
{
base->INTENB[port] = base->INTENB[port] | (1UL << pin);
}
else
{
/*Should not enter here*/
}
}
/*!
* @brief Disables the specific pin interrupt.
*
* @param base GPIO base pointer.
* @param port GPIO port number.
* @param pin GPIO pin number.
* @param index GPIO interrupt number.
*/
void GPIO_PinDisableInterrupt(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index)
{
if ((uint32_t)kGPIO_InterruptA == index)
{
base->INTENA[port] = base->INTENA[port] & ~(1UL << pin);
}
else if ((uint32_t)kGPIO_InterruptB == index)
{
base->INTENB[port] = base->INTENB[port] & ~(1UL << pin);
}
else
{
/*Should not enter here*/
}
}
/*!
* @brief Clears the specific pin interrupt flag. Status flags are cleared by
* writing a 1 to the corresponding bit position.
*
* @param base GPIO base pointer.
* @param port GPIO port number.
* @param index GPIO interrupt number.
* @param mask GPIO pin number macro.
*/
void GPIO_PinClearInterruptFlag(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index)
{
if ((uint32_t)kGPIO_InterruptA == index)
{
base->INTSTATA[port] = 1UL << pin;
}
else if ((uint32_t)kGPIO_InterruptB == index)
{
base->INTSTATB[port] = 1UL << pin;
}
else
{
/*Should not enter here*/
}
}
#endif /* FSL_FEATURE_GPIO_HAS_INTERRUPT */

View file

@ -0,0 +1,364 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _LPC_GPIO_H_
#define _LPC_GPIO_H_
#include "fsl_common.h"
/*!
* @addtogroup lpc_gpio
* @{
*/
/*! @file */
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief LPC GPIO driver version. */
#define FSL_GPIO_DRIVER_VERSION (MAKE_VERSION(2, 1, 7))
/*@}*/
/*! @brief LPC GPIO direction definition */
typedef enum _gpio_pin_direction
{
kGPIO_DigitalInput = 0U, /*!< Set current pin as digital input*/
kGPIO_DigitalOutput = 1U, /*!< Set current pin as digital output*/
} gpio_pin_direction_t;
/*!
* @brief The GPIO pin configuration structure.
*
* Every pin can only be configured as either output pin or input pin at a time.
* If configured as a input pin, then leave the outputConfig unused.
*/
typedef struct _gpio_pin_config
{
gpio_pin_direction_t pinDirection; /*!< GPIO direction, input or output */
/* Output configurations, please ignore if configured as a input one */
uint8_t outputLogic; /*!< Set default output logic, no use in input */
} gpio_pin_config_t;
#if (defined(FSL_FEATURE_GPIO_HAS_INTERRUPT) && FSL_FEATURE_GPIO_HAS_INTERRUPT)
#define GPIO_PIN_INT_LEVEL 0x00U
#define GPIO_PIN_INT_EDGE 0x01U
#define PINT_PIN_INT_HIGH_OR_RISE_TRIGGER 0x00U
#define PINT_PIN_INT_LOW_OR_FALL_TRIGGER 0x01U
/*! @brief GPIO Pin Interrupt enable mode */
typedef enum _gpio_pin_enable_mode
{
kGPIO_PinIntEnableLevel = GPIO_PIN_INT_LEVEL, /*!< Generate Pin Interrupt on level mode */
kGPIO_PinIntEnableEdge = GPIO_PIN_INT_EDGE /*!< Generate Pin Interrupt on edge mode */
} gpio_pin_enable_mode_t;
/*! @brief GPIO Pin Interrupt enable polarity */
typedef enum _gpio_pin_enable_polarity
{
kGPIO_PinIntEnableHighOrRise =
PINT_PIN_INT_HIGH_OR_RISE_TRIGGER, /*!< Generate Pin Interrupt on high level or rising edge */
kGPIO_PinIntEnableLowOrFall =
PINT_PIN_INT_LOW_OR_FALL_TRIGGER /*!< Generate Pin Interrupt on low level or falling edge */
} gpio_pin_enable_polarity_t;
/*! @brief LPC GPIO interrupt index definition */
typedef enum _gpio_interrupt_index
{
kGPIO_InterruptA = 0U, /*!< Set current pin as interrupt A*/
kGPIO_InterruptB = 1U, /*!< Set current pin as interrupt B*/
} gpio_interrupt_index_t;
/*! @brief Configures the interrupt generation condition. */
typedef struct _gpio_interrupt_config
{
uint8_t mode; /* The trigger mode of GPIO interrupts */
uint8_t polarity; /* The polarity of GPIO interrupts */
} gpio_interrupt_config_t;
#endif
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*! @name GPIO Configuration */
/*@{*/
/*!
* @brief Initializes the GPIO peripheral.
*
* This function ungates the GPIO clock.
*
* @param base GPIO peripheral base pointer.
* @param port GPIO port number.
*/
void GPIO_PortInit(GPIO_Type *base, uint32_t port);
/*!
* @brief Initializes a GPIO pin used by the board.
*
* To initialize the GPIO, define a pin configuration, either input or output, in the user file.
* Then, call the GPIO_PinInit() function.
*
* This is an example to define an input pin or output pin configuration:
* @code
* Define a digital input pin configuration,
* gpio_pin_config_t config =
* {
* kGPIO_DigitalInput,
* 0,
* }
* Define a digital output pin configuration,
* gpio_pin_config_t config =
* {
* kGPIO_DigitalOutput,
* 0,
* }
* @endcode
*
* @param base GPIO peripheral base pointer(Typically GPIO)
* @param port GPIO port number
* @param pin GPIO pin number
* @param config GPIO pin configuration pointer
*/
void GPIO_PinInit(GPIO_Type *base, uint32_t port, uint32_t pin, const gpio_pin_config_t *config);
/*@}*/
/*! @name GPIO Output Operations */
/*@{*/
/*!
* @brief Sets the output level of the one GPIO pin to the logic 1 or 0.
*
* @param base GPIO peripheral base pointer(Typically GPIO)
* @param port GPIO port number
* @param pin GPIO pin number
* @param output GPIO pin output logic level.
* - 0: corresponding pin output low-logic level.
* - 1: corresponding pin output high-logic level.
*/
static inline void GPIO_PinWrite(GPIO_Type *base, uint32_t port, uint32_t pin, uint8_t output)
{
base->B[port][pin] = output;
}
/*@}*/
/*! @name GPIO Input Operations */
/*@{*/
/*!
* @brief Reads the current input value of the GPIO PIN.
*
* @param base GPIO peripheral base pointer(Typically GPIO)
* @param port GPIO port number
* @param pin GPIO pin number
* @retval GPIO port input value
* - 0: corresponding pin input low-logic level.
* - 1: corresponding pin input high-logic level.
*/
static inline uint32_t GPIO_PinRead(GPIO_Type *base, uint32_t port, uint32_t pin)
{
return (uint32_t)base->B[port][pin];
}
/*@}*/
/*!
* @brief Sets the output level of the multiple GPIO pins to the logic 1.
*
* @param base GPIO peripheral base pointer(Typically GPIO)
* @param port GPIO port number
* @param mask GPIO pin number macro
*/
static inline void GPIO_PortSet(GPIO_Type *base, uint32_t port, uint32_t mask)
{
base->SET[port] = mask;
}
/*!
* @brief Sets the output level of the multiple GPIO pins to the logic 0.
*
* @param base GPIO peripheral base pointer(Typically GPIO)
* @param port GPIO port number
* @param mask GPIO pin number macro
*/
static inline void GPIO_PortClear(GPIO_Type *base, uint32_t port, uint32_t mask)
{
base->CLR[port] = mask;
}
/*!
* @brief Reverses current output logic of the multiple GPIO pins.
*
* @param base GPIO peripheral base pointer(Typically GPIO)
* @param port GPIO port number
* @param mask GPIO pin number macro
*/
static inline void GPIO_PortToggle(GPIO_Type *base, uint32_t port, uint32_t mask)
{
base->NOT[port] = mask;
}
/*@}*/
/*!
* @brief Reads the current input value of the whole GPIO port.
*
* @param base GPIO peripheral base pointer(Typically GPIO)
* @param port GPIO port number
*/
static inline uint32_t GPIO_PortRead(GPIO_Type *base, uint32_t port)
{
return (uint32_t)base->PIN[port];
}
/*@}*/
/*! @name GPIO Mask Operations */
/*@{*/
/*!
* @brief Sets port mask, 0 - enable pin, 1 - disable pin.
*
* @param base GPIO peripheral base pointer(Typically GPIO)
* @param port GPIO port number
* @param mask GPIO pin number macro
*/
static inline void GPIO_PortMaskedSet(GPIO_Type *base, uint32_t port, uint32_t mask)
{
base->MASK[port] = mask;
}
/*!
* @brief Sets the output level of the masked GPIO port. Only pins enabled by GPIO_SetPortMask() will be affected.
*
* @param base GPIO peripheral base pointer(Typically GPIO)
* @param port GPIO port number
* @param output GPIO port output value.
*/
static inline void GPIO_PortMaskedWrite(GPIO_Type *base, uint32_t port, uint32_t output)
{
base->MPIN[port] = output;
}
/*!
* @brief Reads the current input value of the masked GPIO port. Only pins enabled by GPIO_SetPortMask() will be
* affected.
*
* @param base GPIO peripheral base pointer(Typically GPIO)
* @param port GPIO port number
* @retval masked GPIO port value
*/
static inline uint32_t GPIO_PortMaskedRead(GPIO_Type *base, uint32_t port)
{
return (uint32_t)base->MPIN[port];
}
#if defined(FSL_FEATURE_GPIO_HAS_INTERRUPT) && FSL_FEATURE_GPIO_HAS_INTERRUPT
/*!
* @brief Set the configuration of pin interrupt.
*
* @param base GPIO base pointer.
* @param port GPIO port number
* @param pin GPIO pin number.
* @param config GPIO pin interrupt configuration..
*/
void GPIO_SetPinInterruptConfig(GPIO_Type *base, uint32_t port, uint32_t pin, gpio_interrupt_config_t *config);
/*!
* @brief Enables multiple pins interrupt.
*
* @param base GPIO base pointer.
* @param port GPIO port number.
* @param index GPIO interrupt number.
* @param mask GPIO pin number macro.
*/
void GPIO_PortEnableInterrupts(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask);
/*!
* @brief Disables multiple pins interrupt.
*
* @param base GPIO base pointer.
* @param port GPIO port number.
* @param index GPIO interrupt number.
* @param mask GPIO pin number macro.
*/
void GPIO_PortDisableInterrupts(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask);
/*!
* @brief Clears pin interrupt flag. Status flags are cleared by
* writing a 1 to the corresponding bit position.
*
* @param base GPIO base pointer.
* @param port GPIO port number.
* @param index GPIO interrupt number.
* @param mask GPIO pin number macro.
*/
void GPIO_PortClearInterruptFlags(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask);
/*!
* @ Read port interrupt status.
*
* @param base GPIO base pointer.
* @param port GPIO port number
* @param index GPIO interrupt number.
* @retval masked GPIO status value
*/
uint32_t GPIO_PortGetInterruptStatus(GPIO_Type *base, uint32_t port, uint32_t index);
/*!
* @brief Enables the specific pin interrupt.
*
* @param base GPIO base pointer.
* @param port GPIO port number.
* @param pin GPIO pin number.
* @param index GPIO interrupt number.
*/
void GPIO_PinEnableInterrupt(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index);
/*!
* @brief Disables the specific pin interrupt.
*
* @param base GPIO base pointer.
* @param port GPIO port number.
* @param pin GPIO pin number.
* @param index GPIO interrupt number.
*/
void GPIO_PinDisableInterrupt(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index);
/*!
* @brief Clears the specific pin interrupt flag. Status flags are cleared by
* writing a 1 to the corresponding bit position.
*
* @param base GPIO base pointer.
* @param port GPIO port number.
* @param pin GPIO pin number.
* @param index GPIO interrupt number.
*/
void GPIO_PinClearInterruptFlag(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index);
#endif /* FSL_FEATURE_GPIO_HAS_INTERRUPT */
/*@}*/
#if defined(__cplusplus)
}
#endif
/*!
* @}
*/
#endif /* _LPC_GPIO_H_*/

View file

@ -0,0 +1,222 @@
/*
* Copyright 2018-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include "fsl_iap.h"
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.iap"
#endif
/*!
* @addtogroup rom_api
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief FLEXSPI Flash driver API Interface */
typedef struct
{
uint32_t version;
status_t (*init)(uint32_t instance, flexspi_nor_config_t *config);
status_t (*page_program)(uint32_t instance, flexspi_nor_config_t *config, uint32_t dstAddr, const uint32_t *src);
status_t (*erase_all)(uint32_t instance, flexspi_nor_config_t *config);
status_t (*erase)(uint32_t instance, flexspi_nor_config_t *config, uint32_t start, uint32_t length);
status_t (*erase_sector)(uint32_t instance, flexspi_nor_config_t *config, uint32_t address);
status_t (*erase_block)(uint32_t instance, flexspi_nor_config_t *config, uint32_t address);
status_t (*get_config)(uint32_t instance, flexspi_nor_config_t *config, serial_nor_config_option_t *option);
status_t (*read)(uint32_t instance, flexspi_nor_config_t *config, uint32_t *dst, uint32_t start, uint32_t bytes);
status_t (*xfer)(uint32_t instance, flexspi_xfer_t *xfer);
status_t (*update_lut)(uint32_t instance, uint32_t seqIndex, const uint32_t *lutBase, uint32_t numberOfSeq);
status_t (*set_clock_source)(uint32_t clockSrc);
void (*config_clock)(uint32_t instance, uint32_t freqOption, uint32_t sampleClkMode);
} flexspi_nor_flash_driver_t;
/*! @brief OTP driver API Interface */
typedef struct
{
status_t (*init)(uint32_t src_clk_freq);
status_t (*deinit)(void);
status_t (*fuse_read)(uint32_t addr, uint32_t *data);
status_t (*fuse_program)(uint32_t addr, uint32_t data, bool lock);
status_t (*crc_calc)(uint32_t *src, uint32_t numberOfWords, uint32_t *crcChecksum);
status_t (*reload)(void);
status_t (*crc_check)(uint32_t start_addr, uint32_t end_addr, uint32_t crc_addr);
} ocotp_driver_t;
/*!
* @brief Root of the bootloader API tree.
*
* An instance of this struct resides in read-only memory in the bootloader. It
* provides a user application access to APIs exported by the bootloader.
*
* @note The order of existing fields must not be changed.
*/
typedef struct BootloaderTree
{
void (*runBootloader)(iap_boot_option_t *arg); /*!< Function to start the bootloader executing. */
uint32_t version; /*!< Bootloader version number. */
const char *copyright; /*!< Copyright string. */
const uint32_t reserved0;
const uint32_t reserved1;
const uint32_t reserved2;
const uint32_t reserved3;
const flexspi_nor_flash_driver_t *flexspiNorDriver; /*!< FlexSPI NOR FLASH Driver API. */
const ocotp_driver_t *otpDriver; /*!< OTP driver API. */
const uint32_t reserved4;
} bootloader_tree_t;
/*******************************************************************************
* Definitions
******************************************************************************/
#define ROM_API_TREE ((uint32_t *)FSL_ROM_API_BASE_ADDR)
#define BOOTLOADER_API_TREE_POINTER ((bootloader_tree_t *)ROM_API_TREE)
/*! Get pointer to flexspi/otp driver API table in ROM. */
#define FLEXSPI_API_TREE BOOTLOADER_API_TREE_POINTER->flexspiNorDriver
#define OTP_API_TREE BOOTLOADER_API_TREE_POINTER->otpDriver
/*******************************************************************************
* Variables
******************************************************************************/
/*******************************************************************************
* runBootloader API
******************************************************************************/
void IAP_RunBootLoader(iap_boot_option_t *option)
{
BOOTLOADER_API_TREE_POINTER->runBootloader(option);
}
/*******************************************************************************
* FlexSPI NOR driver
******************************************************************************/
AT_QUICKACCESS_SECTION_CODE(status_t IAP_FlexspiNorInit(uint32_t instance, flexspi_nor_config_t *config))
{
return FLEXSPI_API_TREE->init(instance, config);
}
status_t IAP_FlexspiNorPageProgram(uint32_t instance,
flexspi_nor_config_t *config,
uint32_t dstAddr,
const uint32_t *src)
{
return FLEXSPI_API_TREE->page_program(instance, config, dstAddr, src);
}
status_t IAP_FlexspiNorEraseAll(uint32_t instance, flexspi_nor_config_t *config)
{
return FLEXSPI_API_TREE->erase_all(instance, config);
}
status_t IAP_FlexspiNorErase(uint32_t instance, flexspi_nor_config_t *config, uint32_t start, uint32_t length)
{
return FLEXSPI_API_TREE->erase(instance, config, start, length);
}
status_t IAP_FlexspiNorEraseSector(uint32_t instance, flexspi_nor_config_t *config, uint32_t address)
{
return FLEXSPI_API_TREE->erase_sector(instance, config, address);
}
status_t IAP_FlexspiNorEraseBlock(uint32_t instance, flexspi_nor_config_t *config, uint32_t address)
{
return FLEXSPI_API_TREE->erase_block(instance, config, address);
}
status_t IAP_FlexspiNorGetConfig(uint32_t instance, flexspi_nor_config_t *config, serial_nor_config_option_t *option)
{
return FLEXSPI_API_TREE->get_config(instance, config, option);
}
status_t IAP_FlexspiNorRead(
uint32_t instance, flexspi_nor_config_t *config, uint32_t *dst, uint32_t start, uint32_t bytes)
{
return FLEXSPI_API_TREE->read(instance, config, dst, start, bytes);
}
status_t IAP_FlexspiXfer(uint32_t instance, flexspi_xfer_t *xfer)
{
return FLEXSPI_API_TREE->xfer(instance, xfer);
}
status_t IAP_FlexspiUpdateLut(uint32_t instance, uint32_t seqIndex, const uint32_t *lutBase, uint32_t numberOfSeq)
{
return FLEXSPI_API_TREE->update_lut(instance, seqIndex, lutBase, numberOfSeq);
}
status_t IAP_FlexspiSetClockSource(uint32_t clockSrc)
{
return FLEXSPI_API_TREE->set_clock_source(clockSrc);
}
void IAP_FlexspiConfigClock(uint32_t instance, uint32_t freqOption, uint32_t sampleClkMode)
{
FLEXSPI_API_TREE->config_clock(instance, freqOption, sampleClkMode);
}
AT_QUICKACCESS_SECTION_CODE(status_t IAP_FlexspiNorAutoConfig(uint32_t instance,
flexspi_nor_config_t *config,
serial_nor_config_option_t *option))
{
/* Wait until the FLEXSPI is idle */
register uint32_t delaycnt = 10000u;
status_t status;
while ((delaycnt--) != 0U)
{
}
status = FLEXSPI_API_TREE->get_config(instance, config, option);
if (status == kStatus_Success)
{
status = FLEXSPI_API_TREE->init(instance, config);
}
return status;
}
/*******************************************************************************
* OTP driver
******************************************************************************/
status_t IAP_OtpInit(uint32_t src_clk_freq)
{
return OTP_API_TREE->init(src_clk_freq);
}
status_t IAP_OtpDeinit(void)
{
return OTP_API_TREE->deinit();
}
status_t IAP_OtpFuseRead(uint32_t addr, uint32_t *data)
{
return OTP_API_TREE->fuse_read(addr, data);
}
status_t IAP_OtpFuseProgram(uint32_t addr, uint32_t data, bool lock)
{
return OTP_API_TREE->fuse_program(addr, data, lock);
}
status_t IAP_OtpCrcCalc(uint32_t *src, uint32_t numberOfWords, uint32_t *crcChecksum)
{
return OTP_API_TREE->crc_calc(src, numberOfWords, crcChecksum);
}
status_t IAP_OtpShadowRegisterReload(void)
{
return OTP_API_TREE->reload();
}
status_t IAP_OtpCrcCheck(uint32_t start_addr, uint32_t end_addr, uint32_t crc_addr)
{
return OTP_API_TREE->crc_check(start_addr, end_addr, crc_addr);
}

View file

@ -0,0 +1,727 @@
/*
* Copyright 2018-2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __FSL_IAP_H_
#define __FSL_IAP_H_
#include "fsl_common.h"
/*!
* @addtogroup IAP_driver
* @{
*/
/*! @file */
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief IAP driver version 2.1.2. */
#define FSL_IAP_DRIVER_VERSION (MAKE_VERSION(2, 1, 2))
/*@}*/
/*!
* @addtogroup iap_flexspi_driver
* @{
*/
/*! @brief FlexSPI LUT command */
#define NOR_CMD_INDEX_READ 0 /*!< 0 */
#define NOR_CMD_INDEX_READSTATUS 1 /*!< 1 */
#define NOR_CMD_INDEX_WRITEENABLE 2 /*!< 2 */
#define NOR_CMD_INDEX_ERASESECTOR 3 /*!< 3 */
#define NOR_CMD_INDEX_PAGEPROGRAM 4 /*!< 4 */
#define NOR_CMD_INDEX_CHIPERASE 5 /*!< 5 */
#define NOR_CMD_INDEX_DUMMY 6 /*!< 6 */
#define NOR_CMD_INDEX_ERASEBLOCK 7 /*!< 7 */
#define NOR_CMD_LUT_SEQ_IDX_READ 0 /*!< 0 READ LUT sequence id in lookupTable stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_READSTATUS 1 /*!< 1 Read Status LUT sequence id in lookupTable stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \
2 /*!< 2 Read status DPI/QPI/OPI sequence id in lookupTable stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3 /*!< 3 Write Enable sequence id in lookupTable stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \
4 /*!< 4 Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 /*!< 5 Erase Sector sequence id in lookupTable stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 /*!< 8 Erase Block sequence id in lookupTable stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9 /*!< 9 Program sequence id in lookupTable stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 /*!< 11 Chip Erase sequence in lookupTable id stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 /*!< 13 Read SFDP sequence in lookupTable id stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \
14 /*!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \
15 /*!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk */
/*!
* @name FlexSPI status.
* @{
*/
/*! @brief FlexSPI Driver status group. */
enum
{
kStatusGroup_FlexSPI = 60,
kStatusGroup_FlexSPINOR = 201,
};
/*! @brief FlexSPI Driver status. */
enum _flexspi_status
{
kStatus_FLEXSPI_Success = MAKE_STATUS(kStatusGroup_Generic, 0), /*!< API is executed successfully*/
kStatus_FLEXSPI_Fail = MAKE_STATUS(kStatusGroup_Generic, 1), /*!< API is executed fails*/
kStatus_FLEXSPI_InvalidArgument = MAKE_STATUS(kStatusGroup_Generic, 4), /*!< Invalid argument*/
kStatus_FLEXSPI_SequenceExecutionTimeout =
MAKE_STATUS(kStatusGroup_FlexSPI, 0), /*!< The FlexSPI Sequence Execution timeout*/
kStatus_FLEXSPI_InvalidSequence = MAKE_STATUS(kStatusGroup_FlexSPI, 1), /*!< The FlexSPI LUT sequence invalid*/
kStatus_FLEXSPI_DeviceTimeout = MAKE_STATUS(kStatusGroup_FlexSPI, 2), /*!< The FlexSPI device timeout*/
kStatus_FLEXSPINOR_ProgramFail =
MAKE_STATUS(kStatusGroup_FlexSPINOR, 0), /*!< Status for Page programming failure */
kStatus_FLEXSPINOR_EraseSectorFail =
MAKE_STATUS(kStatusGroup_FlexSPINOR, 1), /*!< Status for Sector Erase failure */
kStatus_FLEXSPINOR_EraseAllFail = MAKE_STATUS(kStatusGroup_FlexSPINOR, 2), /*!< Status for Chip Erase failure */
kStatus_FLEXSPINOR_WaitTimeout = MAKE_STATUS(kStatusGroup_FlexSPINOR, 3), /*!< Status for timeout */
kStatus_FLEXSPINOR_NotSupported = MAKE_STATUS(kStatusGroup_FlexSPINOR, 4), /* Status for PageSize overflow */
kStatus_FLEXSPINOR_WriteAlignmentError =
MAKE_STATUS(kStatusGroup_FlexSPINOR, 5), /*!< Status for Alignement error */
kStatus_FLEXSPINOR_CommandFailure =
MAKE_STATUS(kStatusGroup_FlexSPINOR, 6), /*!< Status for Erase/Program Verify Error */
kStatus_FLEXSPINOR_SFDP_NotFound = MAKE_STATUS(kStatusGroup_FlexSPINOR, 7), /*!< Status for SFDP read failure */
kStatus_FLEXSPINOR_Unsupported_SFDP_Version =
MAKE_STATUS(kStatusGroup_FlexSPINOR, 8), /*!< Status for Unrecognized SFDP version */
kStatus_FLEXSPINOR_Flash_NotFound =
MAKE_STATUS(kStatusGroup_FlexSPINOR, 9), /*!< Status for Flash detection failure */
kStatus_FLEXSPINOR_DTRRead_DummyProbeFailed =
MAKE_STATUS(kStatusGroup_FlexSPINOR, 10), /*!< Status for DDR Read dummy probe failure */
};
/*! @} */
/*! @brief Flash Configuration Option0 device_type. */
enum
{
kSerialNorCfgOption_Tag = 0x0c,
kSerialNorCfgOption_DeviceType_ReadSFDP_SDR = 0,
kSerialNorCfgOption_DeviceType_ReadSFDP_DDR = 1,
kSerialNorCfgOption_DeviceType_HyperFLASH1V8 = 2,
kSerialNorCfgOption_DeviceType_HyperFLASH3V0 = 3,
kSerialNorCfgOption_DeviceType_MacronixOctalDDR = 4,
kSerialNorCfgOption_DeviceType_MacronixOctalSDR = 5, /* For RT600 devcies only. */
kSerialNorCfgOption_DeviceType_MicronOctalDDR = 6,
kSerialNorCfgOption_DeviceType_MicronOctalSDR = 7, /* For RT600 devcies only. */
kSerialNorCfgOption_DeviceType_AdestoOctalDDR = 8,
kSerialNorCfgOption_DeviceType_AdestoOctalSDR = 9, /* For RT600 devcies only. */
};
/*! @brief Flash Configuration Option0 quad_mode_setting. */
enum
{
kSerialNorQuadMode_NotConfig = 0,
kSerialNorQuadMode_StatusReg1_Bit6 = 1,
kSerialNorQuadMode_StatusReg2_Bit1 = 2,
kSerialNorQuadMode_StatusReg2_Bit7 = 3,
kSerialNorQuadMode_StatusReg2_Bit1_0x31 = 4,
};
/*! @brief Flash Configuration Option0 misc_mode. */
enum
{
kSerialNorEnhanceMode_Disabled = 0,
kSerialNorEnhanceMode_0_4_4_Mode = 1,
kSerialNorEnhanceMode_0_8_8_Mode = 2,
kSerialNorEnhanceMode_DataOrderSwapped = 3,
kSerialNorEnhanceMode_2ndPinMux = 4,
};
/*! @brief FLEXSPI_RESET_PIN boot configurations in OTP */
enum
{
kFlashResetLogic_Disabled = 0,
kFlashResetLogic_ResetPin = 1,
kFlashResetLogic_JedecHwReset = 2,
};
/*! @brief Flash Configuration Option1 flash_connection. */
enum
{
kSerialNorConnection_SinglePortA,
kSerialNorConnection_Parallel,
kSerialNorConnection_SinglePortB,
kSerialNorConnection_BothPorts
};
/*! @brief Serial NOR Configuration Option */
typedef struct _serial_nor_config_option
{
union
{
struct
{
uint32_t max_freq : 4; /*!< Maximum supported Frequency */
uint32_t misc_mode : 4; /*!< miscellaneous mode */
uint32_t quad_mode_setting : 4; /*!< Quad mode setting */
uint32_t cmd_pads : 4; /*!< Command pads */
uint32_t query_pads : 4; /*!< SFDP read pads */
uint32_t device_type : 4; /*!< Device type */
uint32_t option_size : 4; /*!< Option size, in terms of uint32_t, size = (option_size + 1) * 4 */
uint32_t tag : 4; /*!< Tag, must be 0x0E */
} B;
uint32_t U;
} option0;
union
{
struct
{
uint32_t dummy_cycles : 8; /*!< Dummy cycles before read */
uint32_t status_override : 8; /*!< Override status register value during device mode configuration */
uint32_t pinmux_group : 4; /*!< The pinmux group selection */
uint32_t dqs_pinmux_group : 4; /*!< The DQS Pinmux Group Selection */
uint32_t drive_strength : 4; /*!< The Drive Strength of FlexSPI Pads */
uint32_t flash_connection : 4; /*!< Flash connection option: 0 - Single Flash connected to port A, 1 - */
/*! Parallel mode, 2 - Single Flash connected to Port B */
} B;
uint32_t U;
} option1;
} serial_nor_config_option_t;
/*! @brief Flash Run Context */
typedef union
{
struct
{
uint8_t por_mode;
uint8_t current_mode;
uint8_t exit_no_cmd_sequence;
uint8_t restore_sequence;
} B;
uint32_t U;
} flash_run_context_t;
/*!@brief Flash Device Mode Configuration Sequence */
enum
{
kRestoreSequence_None = 0,
kRestoreSequence_HW_Reset = 1,
kRestoreSequence_4QPI_FF = 2,
kRestoreSequence_5QPI_FF = 3,
kRestoreSequence_8QPI_FF = 4,
kRestoreSequence_Send_F0 = 5,
kRestoreSequence_Send_66_99 = 6,
kRestoreSequence_Send_6699_9966 = 7,
kRestoreSequence_Send_06_FF = 8, /* Adesto EcoXIP */
};
/*!@brief Flash Config Mode Definition */
enum
{
kFlashInstMode_ExtendedSpi = 0x00,
kFlashInstMode_0_4_4_SDR = 0x01,
kFlashInstMode_0_4_4_DDR = 0x02,
kFlashInstMode_QPI_SDR = 0x41,
kFlashInstMode_QPI_DDR = 0x42,
kFlashInstMode_OPI_SDR = 0x81, /* For RT600 devices only. */
kFlashInstMode_OPI_DDR = 0x82,
};
/*!@brief Flash Device Type Definition */
enum
{
kFlexSpiDeviceType_SerialNOR = 1, /*!< Flash devices are Serial NOR */
kFlexSpiDeviceType_SerialNAND = 2, /*!< Flash devices are Serial NAND */
kFlexSpiDeviceType_SerialRAM = 3, /*!< Flash devices are Serial RAM/HyperFLASH */
kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, /*!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND */
kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, /*!< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs */
};
/*!@brief Flash Pad Definitions */
enum
{
kSerialFlash_1Pad = 1,
kSerialFlash_2Pads = 2,
kSerialFlash_4Pads = 4,
kSerialFlash_8Pads = 8,
};
/*!@brief FlexSPI LUT Sequence structure */
typedef struct _lut_sequence
{
uint8_t seqNum; /*!< Sequence Number, valid number: 1-16 */
uint8_t seqId; /*!< Sequence Index, valid number: 0-15 */
uint16_t reserved;
} flexspi_lut_seq_t;
/*!@brief Flash Configuration Command Type */
enum
{
kDeviceConfigCmdType_Generic, /*!< Generic command, for example: configure dummy cycles, drive strength, etc */
kDeviceConfigCmdType_QuadEnable, /*!< Quad Enable command */
kDeviceConfigCmdType_Spi2Xpi, /*!< Switch from SPI to DPI/QPI/OPI mode */
kDeviceConfigCmdType_Xpi2Spi, /*!< Switch from DPI/QPI/OPI to SPI mode */
kDeviceConfigCmdType_Spi2NoCmd, /*!< Switch to 0-4-4/0-8-8 mode */
kDeviceConfigCmdType_Reset, /*!< Reset device command */
};
/*!@brief FlexSPI Dll Time Block */
typedef struct
{
uint8_t time_100ps; /* Data valid time, in terms of 100ps */
uint8_t delay_cells; /* Data valid time, in terms of delay cells */
} flexspi_dll_time_t;
/*!@brief FlexSPI Memory Configuration Block */
typedef struct _FlexSPIConfig
{
uint32_t tag; /*!< [0x000-0x003] Tag, fixed value 0x42464346UL */
uint32_t version; /*!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix */
uint32_t reserved0; /*!< [0x008-0x00b] Reserved for future use */
uint8_t readSampleClkSrc; /*!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 */
uint8_t csHoldTime; /*!< [0x00d-0x00d] CS hold time, default value: 3 */
uint8_t csSetupTime; /*!< [0x00e-0x00e] CS setup time, default value: 3 */
uint8_t columnAddressWidth; /*!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For */
/*! Serial NAND, need to refer to datasheet */
uint8_t deviceModeCfgEnable; /*!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable */
uint8_t
deviceModeType; /*!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, */
/*! Generic configuration, etc. */
uint16_t waitTimeCfgCommands; /*!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for */
/*! DPI/QPI/OPI switch or reset command */
flexspi_lut_seq_t
deviceModeSeq; /*!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt */
/*! sequence number, [31:16] Reserved */
uint32_t deviceModeArg; /*!< [0x018-0x01b] Argument/Parameter for device configuration */
uint8_t configCmdEnable; /*!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable */
uint8_t configModeType[3]; /*!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe */
flexspi_lut_seq_t
configCmdSeqs[3]; /*!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq */
uint32_t reserved1; /*!< [0x02c-0x02f] Reserved for future use */
uint32_t configCmdArgs[3]; /*!< [0x030-0x03b] Arguments/Parameters for device Configuration commands */
uint32_t reserved2; /*!< [0x03c-0x03f] Reserved for future use */
uint32_t
controllerMiscOption; /*!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more */
/*! details */
uint8_t deviceType; /*!< [0x044-0x044] Device Type: See Flash Type Definition for more details */
uint8_t sflashPadType; /*!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal */
uint8_t serialClkFreq; /*!< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot */
/*! Chapter for more details */
uint8_t
lutCustomSeqEnable; /*!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot */
/*! be done using 1 LUT sequence, currently, only applicable to HyperFLASH */
uint32_t reserved3[2]; /*!< [0x048-0x04f] Reserved for future use */
uint32_t sflashA1Size; /*!< [0x050-0x053] Size of Flash connected to A1 */
uint32_t sflashA2Size; /*!< [0x054-0x057] Size of Flash connected to A2 */
uint32_t sflashB1Size; /*!< [0x058-0x05b] Size of Flash connected to B1 */
uint32_t sflashB2Size; /*!< [0x05c-0x05f] Size of Flash connected to B2 */
uint32_t csPadSettingOverride; /*!< [0x060-0x063] CS pad setting override value */
uint32_t sclkPadSettingOverride; /*!< [0x064-0x067] SCK pad setting override value */
uint32_t dataPadSettingOverride; /*!< [0x068-0x06b] data pad setting override value */
uint32_t dqsPadSettingOverride; /*!< [0x06c-0x06f] DQS pad setting override value */
uint32_t timeoutInMs; /*!< [0x070-0x073] Timeout threshold for read status command */
uint32_t commandInterval; /*!< [0x074-0x077] CS deselect interval between two commands */
flexspi_dll_time_t dataValidTime[2]; /*!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B */
uint16_t busyOffset; /*!< [0x07c-0x07d] Busy offset, valid value: 0-31 */
uint16_t
busyBitPolarity; /*!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - */
/*! busy flag is 0 when flash device is busy */
uint32_t lookupTable[64]; /*!< [0x080-0x17f] Lookup table holds Flash command sequences */
flexspi_lut_seq_t lutCustomSeq[12]; /*!< [0x180-0x1af] Customizable LUT Sequences */
uint32_t reserved4[4]; /*!< [0x1b0-0x1bf] Reserved for future use */
} flexspi_mem_config_block_t;
/*!@brief FlexSPI Operation Type */
typedef enum _FlexSPIOperationType
{
kFlexSpiOperation_Command = 0, /*!< FlexSPI operation: Only command, both TX and */
/*! RX buffer are ignored. */
kFlexSpiOperation_Config = 1, /*!< FlexSPI operation: Configure device mode, the */
/*! TX FIFO size is fixed in LUT. */
kFlexSpiOperation_Write = 2, /*!< FlexSPI operation: Write, only TX buffer is */
/*! effective */
kFlexSpiOperation_Read = 3, /*!< FlexSPI operation: Read, only Rx Buffer is */
/*! effective. */
kFlexSpiOperation_End = kFlexSpiOperation_Read,
} flexspi_operation_t;
/*!@brief FlexSPI Transfer Context */
typedef struct _FlexSpiXfer
{
flexspi_operation_t operation; /*!< FlexSPI operation */
uint32_t baseAddress; /*!< FlexSPI operation base address */
uint32_t seqId; /*!< Sequence Id */
uint32_t seqNum; /*!< Sequence Number */
bool isParallelModeEnable; /*!< Is a parallel transfer */
uint32_t *txBuffer; /*!< Tx buffer */
uint32_t txSize; /*!< Tx size in bytes */
uint32_t *rxBuffer; /*!< Rx buffer */
uint32_t rxSize; /*!< Rx size in bytes */
} flexspi_xfer_t;
/*!@brief Serial NOR configuration block */
typedef struct _flexspi_nor_config
{
flexspi_mem_config_block_t memConfig; /*!< Common memory configuration info via FlexSPI */
uint32_t pageSize; /*!< Page size of Serial NOR */
uint32_t sectorSize; /*!< Sector size of Serial NOR */
uint8_t ipcmdSerialClkFreq; /*!< Clock frequency for IP command */
uint8_t isUniformBlockSize; /*!< Sector/Block size is the same */
uint8_t isDataOrderSwapped; /*!< Data order (D0, D1, D2, D3) is swapped (D1,D0, D3, D2) */
uint8_t reserved0[1]; /*!< Reserved for future use */
uint8_t serialNorType; /*!< Serial NOR Flash type: 0/1/2/3 */
uint8_t needExitNoCmdMode; /*!< Need to exit NoCmd mode before other IP command */
uint8_t halfClkForNonReadCmd; /*!< Half the Serial Clock for non-read command: true/false */
uint8_t needRestoreNoCmdMode; /*!< Need to Restore NoCmd mode after IP commmand execution */
uint32_t blockSize; /*!< Block size */
uint32_t flashStateCtx; /*!< Flash State Context */
uint32_t reserve2[10]; /*!< Reserved for future use */
} flexspi_nor_config_t;
/*! @} */
/*!
* @addtogroup iap_otp_driver
* @{
*/
/*! @brief OTP Status Group */
enum
{
kStatusGroup_OtpGroup = 0x210,
};
/*! @brief OTP Error Status definitions */
enum
{
kStatus_OTP_InvalidAddress = MAKE_STATUS(kStatusGroup_OtpGroup, 1), /*!< Invalid OTP address */
kStatus_OTP_ProgramFail = MAKE_STATUS(kStatusGroup_OtpGroup, 2), /*!< Program Fail */
kStatus_OTP_CrcFail = MAKE_STATUS(kStatusGroup_OtpGroup, 3), /*!< CrcCheck Fail */
kStatus_OTP_Error = MAKE_STATUS(kStatusGroup_OtpGroup, 4), /*!< Errors happened during OTP operation */
kStatus_OTP_EccCheckFail = MAKE_STATUS(kStatusGroup_OtpGroup, 5), /*!< Ecc Check failed during OTP operation */
kStatus_OTP_Locked = MAKE_STATUS(kStatusGroup_OtpGroup, 6), /*!< OTP Fuse field has been locked */
kStatus_OTP_Timeout = MAKE_STATUS(kStatusGroup_OtpGroup, 7), /*!< OTP operation time out */
kStatus_OTP_CrcCheckPass = MAKE_STATUS(kStatusGroup_OtpGroup, 8), /*!< OTP CRC Check Pass */
};
/*! @} */
/*!
* @addtogroup iap_boot_driver
* @{
*/
/*! @brief IAP boot option. */
typedef struct _iap_boot_option
{
union
{
struct
{
uint32_t reserved : 8; /*! reserved field. */
uint32_t bootImageIndex : 4; /*! FlexSPI boot image index for FlexSPI NOR flash. */
uint32_t instance : 4; /*! Only used when boot interface is FlexSPI/SD/MMC. */
uint32_t bootInterface : 4; /*! RT500: 0: USART 2: SPI 3: USB HID 4:FlexSPI 6:SD 7:MMC.
RT600: 0: USART 1: I2C 2: SPI 3: USB HID 4:FlexSPI 7:SD 8:MMC*/
uint32_t mode : 4; /* boot mode, 0: Master boot mode; 1: ISP boot */
uint32_t tag : 8; /*! tag, should always be "0xEB". */
} B;
uint32_t U;
} option;
} iap_boot_option_t;
/*! IAP boot option tag */
#define IAP_BOOT_OPTION_TAG (0xEBU)
/*! IAP boot option mode */
#define IAP_BOOT_OPTION_MODE_MASTER (0U)
#define IAP_BOOT_OPTION_MODE_ISP (1U)
/*! @} */
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @addtogroup iap_boot_driver
* @{
*/
/*!
* @brief Invoke into ROM with specified boot parameters.
*
* @param option Boot parameters. Refer to #iap_boot_option_t.
*/
void IAP_RunBootLoader(iap_boot_option_t *option);
/*! @} */
/*!
* @addtogroup iap_flexspi_driver
* @{
*/
/*!
* @brief Initialize Serial NOR devices via FlexSPI.
*
* This function configures the FlexSPI controller with the arguments pointed by param config.
*
* @param instance FlexSPI controller instance, only support 0.
* @param config The Flash configuration block. Refer to #flexspi_nor_config_t.
* @return The status flags. This is a member of the
* enumeration ::_flexspi_status
*/
#if defined(DOXYGEN_OUTPUT) && DOXYGEN_OUTPUT
status_t IAP_FlexspiNorInit(uint32_t instance, flexspi_nor_config_t *config);
#else
AT_QUICKACCESS_SECTION_CODE(status_t IAP_FlexspiNorInit(uint32_t instance, flexspi_nor_config_t *config));
#endif
/*!
* @brief Program data to Serial NOR via FlexSPI.
*
* This function Program data to specified destination address.
*
* @param instance FlexSPI controller instance, only support 0.
* @param config The Flash configuration block. Refer to #flexspi_nor_config_t.
* @param dstAddr The destination address to be programmed.
* @param src Points to the buffer which hold the data to be programmed.
* @return The status flags. This is a member of the
* enumeration ::_flexspi_status
*/
status_t IAP_FlexspiNorPageProgram(uint32_t instance,
flexspi_nor_config_t *config,
uint32_t dstAddr,
const uint32_t *src);
/*!
* @brief Erase all the Serial NOR devices connected on FlexSPI.
*
* @param instance FlexSPI controller instance, only support 0.
* @param config The Flash configuration block. Refer to #flexspi_nor_config_t.
* @return The status flags. This is a member of the
* enumeration ::_flexspi_status
*/
status_t IAP_FlexspiNorEraseAll(uint32_t instance, flexspi_nor_config_t *config);
/*!
* @brief Erase Flash Region specified by address and length.
*
* @param instance FlexSPI controller instance, only support 0.
* @param config The Flash configuration block. Refer to #flexspi_nor_config_t.
* @param start The start address to be erased.
* @param length The length to be erased.
* @return The status flags. This is a member of the
* enumeration ::_flexspi_status
*/
status_t IAP_FlexspiNorErase(uint32_t instance, flexspi_nor_config_t *config, uint32_t start, uint32_t length);
/*!
* @brief Erase one sector specified by address.
*
* @param instance FlexSPI controller instance, only support 0.
* @param config The Flash configuration block. Refer to #flexspi_nor_config_t.
* @param address The address of the sector to be erased.
* @return The status flags. This is a member of the
* enumeration ::_flexspi_status
*/
status_t IAP_FlexspiNorEraseSector(uint32_t instance, flexspi_nor_config_t *config, uint32_t address);
/*!
* @brief Erase one block specified by address.
*
* @param instance FlexSPI controller instance, only support 0.
* @param config The Flash configuration block. Refer to #flexspi_nor_config_t.
* @param address The address of the block to be erased.
* @return The status flags. This is a member of the
* enumeration ::_flexspi_status
*/
status_t IAP_FlexspiNorEraseBlock(uint32_t instance, flexspi_nor_config_t *config, uint32_t address);
/*!
* @brief Get FlexSPI NOR Configuration Block based on specified option.
*
* @param instance FlexSPI controller instance, only support 0.
* @param config The Flash configuration block. Refer to #flexspi_nor_config_t.
* @param option The Flash Configuration Option block. Refer to #serial_nor_config_option_t.
* @return The status flags. This is a member of the
* enumeration ::_flexspi_status
*/
status_t IAP_FlexspiNorGetConfig(uint32_t instance, flexspi_nor_config_t *config, serial_nor_config_option_t *option);
/*!
* @brief Read data from Flexspi NOR Flash.
*
* @param instance FlexSPI controller instance, only support 0.
* @param config The Flash configuration block. Refer to #flexspi_nor_config_t.
* @param dst Buffer address used to store the read data.
* @param start The Read address.
* @param bytes The Read size
* @return The status flags. This is a member of the
* enumeration ::_flexspi_status
*/
status_t IAP_FlexspiNorRead(
uint32_t instance, flexspi_nor_config_t *config, uint32_t *dst, uint32_t start, uint32_t bytes);
/*!
* @brief Get FlexSPI Xfer data.
*
* @param instance FlexSPI controller instance, only support 0.
* @param xfer The FlexSPI Transfer Context block. Refer to #flexspi_xfer_t.
* @return The status flags. This is a member of the
* enumeration ::_flexspi_status
*/
status_t IAP_FlexspiXfer(uint32_t instance, flexspi_xfer_t *xfer);
/*!
* @brief Update FlexSPI Lookup table.
*
* @param instance FlexSPI controller instance, only support 0.
* @param seqIndex The index of FlexSPI LUT to be updated.
* @param lutBase Points to the buffer which hold the LUT data to be programmed.
* @param numberOfSeq The number of LUT seq that need to be updated.
* @return The status flags. This is a member of the
* enumeration ::_flexspi_status
*/
status_t IAP_FlexspiUpdateLut(uint32_t instance, uint32_t seqIndex, const uint32_t *lutBase, uint32_t numberOfSeq);
/*!
* @brief Set the clock source for FlexSPI.
*
* @param clockSrc Clock source for flexspi interface.
* @return The status flags. This is a member of the
* enumeration ::_flexspi_status
*/
status_t IAP_FlexspiSetClockSource(uint32_t clockSrc);
/*!
* @brief Configure the flexspi interface clock frequency and data sample mode.
*
* @param instance FlexSPI controller instance, only support 0.
* @param freqOption FlexSPI interface clock frequency selection.
* @param sampleClkMode FlexSPI controller data sample mode.
* @return The status flags. This is a member of the
* enumeration ::_flexspi_status
*/
void IAP_FlexspiConfigClock(uint32_t instance, uint32_t freqOption, uint32_t sampleClkMode);
/*!
* @brief Configure flexspi nor automatically.
*
* @param instance FlexSPI controller instance, only support 0.
* @param config The Flash configuration block. Refer to #flexspi_nor_config_t.
* @param option The Flash Configuration Option block. Refer to #serial_nor_config_option_t.
* @return The status flags. This is a member of the
* enumeration ::_flexspi_status
*/
#if defined(DOXYGEN_OUTPUT) && DOXYGEN_OUTPUT
status_t IAP_FlexspiNorAutoConfig(uint32_t instance, flexspi_nor_config_t *config, serial_nor_config_option_t *option);
#else
AT_QUICKACCESS_SECTION_CODE(status_t IAP_FlexspiNorAutoConfig(uint32_t instance,
flexspi_nor_config_t *config,
serial_nor_config_option_t *option));
#endif
/*! @} */
/*!
* @addtogroup iap_otp_driver
* @{
*/
/*!
* @brief Initialize OTP controller
*
* This function enables OTP Controller clock.
*
* @param src_clk_freq The Frequency of the source clock of OTP controller
* @return kStatus_Success
*/
status_t IAP_OtpInit(uint32_t src_clk_freq);
/*!
* @brief De-Initialize OTP controller
*
* This functin disables OTP Controller Clock.
* @return kStatus_Success
*/
status_t IAP_OtpDeinit(void);
/*!
* @brief Read Fuse value from OTP Fuse Block
*
* This function read fuse data from OTP Fuse block to specified data buffer.
*
* @param addr Fuse address
* @param data Buffer to hold the data read from OTP Fuse block
* @return kStatus_Success - Data read from OTP Fuse block successfully
* kStatus_InvalidArgument - data pointer is invalid
* kStatus_OTP_EccCheckFail - Ecc Check Failed
* kStatus_OTP_Error - Other Errors
*/
status_t IAP_OtpFuseRead(uint32_t addr, uint32_t *data);
/*!
* @brief Program value to OTP Fuse block
*
* This function program data to specified OTP Fuse address.
*
* @param addr Fuse address
* @param data data to be programmed into OTP Fuse block
* @param lock lock the fuse field or not
* @return kStatus_Success - Data has been programmed into OTP Fuse block successfully
* kStatus_OTP_ProgramFail - Fuse programming failed
* kStatus_OTP_Locked - The address to be programmed into is locked
* kStatus_OTP_Error - Other Errors
*/
status_t IAP_OtpFuseProgram(uint32_t addr, uint32_t data, bool lock);
/*!
* @brief Reload all shadow registers from OTP fuse block
*
* This function reloads all the shadow registers from OTP Fuse block
*
* @return kStatus_Success - Shadow registers' reloadding succeeded.
* kStatus_OTP_EccCheckFail - Ecc Check Failed
* kStatus_OTP_Error - Other Errors
*/
status_t IAP_OtpShadowRegisterReload(void);
/*!
* @brief Do CRC Check via OTP controller
*
* This function checks whether data in specified fuse address ranges match the crc value in the specified CRC address
* and return the actual crc value as needed.
*
* @param start_addr Start address of selected Fuse address range
* @param end_addr End address of selected Fuse address range
* @param crc_addr Address that hold CRC data
*
* @return kStatus_Success CRC check succeeded, CRC value matched.
* kStatus_InvalidArgument - Invalid Argument
* kStatus_OTP_EccCheckFail Ecc Check Failed
* kStatus_OTP_CrcFail CRC Check Failed
*/
status_t IAP_OtpCrcCheck(uint32_t start_addr, uint32_t end_addr, uint32_t crc_addr);
/*!
* @brief Calculate the CRC checksum for specified data for OTP
*
* This function calculates the CRC checksum for specified data for OTP
*
* @param src the source address of data
* @param numberOfWords number of Fuse words
* @param crcChecksum Buffer to store the CRC checksum
*
* @return kStatus_Success CRC checksum is computed successfully.
* kStatus_InvalidArgument - Invalid Argument
*/
status_t IAP_OtpCrcCalc(uint32_t *src, uint32_t numberOfWords, uint32_t *crcChecksum);
/*! @} */
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* __FSL_IAP_H_ */

View file

@ -0,0 +1,116 @@
/*
* Copyright 2013-2016, NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_IOPCTL_H_
#define _FSL_IOPCTL_H_
#include "fsl_common.h"
/*!
* @addtogroup iopctl_driver
* @{
*/
/*! @file */
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.lpc_iopctl"
#endif
/*! @name Driver version */
/*@{*/
/*! @brief IOPCTL driver version 2.0.0. */
#define LPC_IOPCTL_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
/*@}*/
/**
* @brief Array of IOPCTL pin definitions passed to IOPCTL_SetPinMuxing() must be in this format
*/
typedef struct _iopctl_group
{
uint32_t port : 8; /* Pin port */
uint32_t pin : 32; /* Pin number */
uint32_t modefunc : 12; /* Function and mode */
} iopctl_group_t;
/**
* @brief IOPCTL function and mode selection definitions
* @note See the User Manual for specific modes and functions supported by the various pins.
*/
#define IOPCTL_FUNC0 0x0 /*!< Selects pin function 0 */
#define IOPCTL_FUNC1 0x1 /*!< Selects pin function 1 */
#define IOPCTL_FUNC2 0x2 /*!< Selects pin function 2 */
#define IOPCTL_FUNC3 0x3 /*!< Selects pin function 3 */
#define IOPCTL_FUNC4 0x4 /*!< Selects pin function 4 */
#define IOPCTL_FUNC5 0x5 /*!< Selects pin function 5 */
#define IOPCTL_FUNC6 0x6 /*!< Selects pin function 6 */
#define IOPCTL_FUNC7 0x7 /*!< Selects pin function 7 */
#define IOPCTL_FUNC8 0x8 /*!< Selects pin function 8 */
#define IOPCTL_FUNC9 0x9 /*!< Selects pin function 9 */
#define IOPCTL_FUNC10 0xA /*!< Selects pin function 10 */
#define IOPCTL_FUNC11 0xB /*!< Selects pin function 11 */
#define IOPCTL_FUNC12 0xC /*!< Selects pin function 12 */
#define IOPCTL_FUNC13 0xD /*!< Selects pin function 13 */
#define IOPCTL_FUNC14 0xE /*!< Selects pin function 14 */
#define IOPCTL_FUNC15 0xF /*!< Selects pin function 15 */
#define IOPCTL_PUPD_EN (0x1 << 4) /*!< Enables Pullup / Pulldown */
#define IOPCTL_PULLDOWN_EN (0x0 << 5) /*!< Selects pull-down function */
#define IOPCTL_PULLUP_EN (0x1 << 5) /*!< Selects pull-up function */
#define IOPCTL_INBUF_EN (0x1 << 6) /*!< Enables buffer function on input */
#define IOPCTL_SLEW_RATE (0x0 << 7) /*!< Slew Rate Control */
#define IOPCTL_FULLDRIVE_EN (0x1 << 8) /*!< Selects full drive */
#define IOPCTL_ANAMUX_EN (0x1 << 9) /*!< Enables analog mux function by setting 0 to bit 7 */
#define IOPCTL_PSEDRAIN_EN (0x1 << 10) /*!< Enables pseudo output drain function */
#define IOPCTL_INV_EN (0x1 << 11) /*!< Enables invert function on input */
#if defined(__cplusplus)
extern "C" {
#endif
/**
* @brief Sets I/O Pad Control pin mux
* @param base : The base of IOPCTL peripheral on the chip
* @param port : Port to mux
* @param pin : Pin to mux
* @param modefunc : OR'ed values of type IOPCTL_*
* @return Nothing
*/
__STATIC_INLINE void IOPCTL_PinMuxSet(IOPCTL_Type *base, uint8_t port, uint8_t pin, uint32_t modefunc)
{
base->PIO[port][pin] = modefunc;
}
/**
* @brief Set all I/O Control pin muxing
* @param base : The base of IOPCTL peripheral on the chip
* @param pinArray : Pointer to array of pin mux selections
* @param arrayLength : Number of entries in pinArray
* @return Nothing
*/
__STATIC_INLINE void IOPCTL_SetPinMuxing(IOPCTL_Type *base, const iopctl_group_t *pinArray, uint32_t arrayLength)
{
uint32_t i;
for (i = 0; i < arrayLength; i++)
{
IOPCTL_PinMuxSet(base, pinArray[i].port, pinArray[i].pin, pinArray[i].modefunc);
}
}
/* @} */
#if defined(__cplusplus)
}
#endif
#endif /* _FSL_IOPCTL_H_ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,584 @@
/*
* Copyright 2018-2021, NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_POWER_H_
#define _FSL_POWER_H_
#include "fsl_common.h"
/*!
* @addtogroup power
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief power driver version 2.3.2. */
#define FSL_POWER_DRIVER_VERSION (MAKE_VERSION(2UL, 3UL, 2UL))
/*@}*/
#define MAKE_PD_BITS(reg, slot) (((reg) << 8) | (slot))
#define SYSCTL0_PDRCFGSET_REG(x) (*((volatile uint32_t *)((uint32_t)(&(SYSCTL0->PDRUNCFG0_SET)) + ((x) << 2U))))
#define SYSCTL0_PDRCFGCLR_REG(x) (*((volatile uint32_t *)((uint32_t)(&(SYSCTL0->PDRUNCFG0_CLR)) + ((x) << 2U))))
#define PDRCFG0 0x0U
#define PDRCFG1 0x1U
#define PDRCFG2 0x2U
#define PDRCFG3 0x3U
/* PMC FLAGS register bitfield MASK. */
#define PMC_FLAGS_PORCOREF_MASK (0x10000U)
#define PMC_FLAGS_POR1V8F_MASK (0x20000U)
#define PMC_FLAGS_PORAO18F_MASK (0x40000U)
#define PMC_FLAGS_LVDCOREF_MASK (0x100000U)
#define PMC_FLAGS_HVDCOREF_MASK (0x400000U)
#define PMC_FLAGS_HVD1V8F_MASK (0x1000000U)
#define PMC_FLAGS_RTCF_MASK (0x8000000U)
#define PMC_FLAGS_AUTOWKF_MASK (0x10000000U)
#define PMC_FLAGS_INTNPADF_MASK (0x20000000U)
#define PMC_FLAGS_RESETNPADF_MASK (0x40000000U)
#define PMC_FLAGS_DEEPPDF_MASK (0x80000000U)
#define PMC_CTRL_LVDCOREIE_MASK (0x100000U)
#define PMC_CTRL_HVDCOREIE_MASK (0x400000U)
#define PMC_CTRL_HVD1V8IE_MASK (0x1000000U)
#define PMC_CTRL_AUTOWKEN_MASK (0x10000000U)
#define PMC_CTRL_INTRPADEN_MASK (0x20000000U)
/*! PMIC is used but vddcore supply is always above LVD threshold. */
#define PMIC_VDDCORE_RECOVERY_TIME_IGNORE (0xFFFFFFFFU)
/**
* @brief PMC event flags.
*
* @note These enums are meant to be OR'd together to form a bit mask.
*/
enum _pmc_interrupt
{
kPMC_INT_LVDCORE = PMC_CTRL_LVDCOREIE_MASK, /*!< Vddcore Low-Voltage Detector Interrupt Enable. */
kPMC_INT_HVDCORE = PMC_CTRL_HVDCOREIE_MASK, /*!< Vddcore High-Voltage Detector Interrupt Enable. */
kPMC_INT_HVD1V8 = PMC_CTRL_HVD1V8IE_MASK, /*!< Vdd1v8 High-Voltage Detector Interrupt Enable. */
kPMC_INT_AUTOWK = PMC_CTRL_AUTOWKEN_MASK, /*!< PMC automatic wakeup enable and interrupt enable. */
kPMC_INT_INTRPAD =
PMC_CTRL_INTRPADEN_MASK /*!< Interrupt pad deep powerdown and deep sleep wake up & interrupt enable. */
};
/**
* @brief PMC event flags.
*
* @note These enums are meant to be OR'd together to form a bit mask.
*/
enum _pmc_event_flags
{
kPMC_FLAGS_PORCORE = PMC_FLAGS_PORCOREF_MASK, /*!< POR triggered by the vddcore POR monitor (0 = no, 1 = yes). */
kPMC_FLAGS_POR1V8 =
PMC_FLAGS_POR1V8F_MASK, /*!< vdd1v8 power on event detected since last cleared(0 = no, 1 = yes). */
kPMC_FLAGS_PORAO18 =
PMC_FLAGS_PORAO18F_MASK, /*!< vdd_ao18 power on event detected since last cleared (0 = no, 1 = yes). */
kPMC_FLAGS_LVDCORE =
PMC_FLAGS_LVDCOREF_MASK, /*!< LVD tripped since last time this bit was cleared (0 = no, 1 = yes). */
kPMC_FLAGS_HVDCORE =
PMC_FLAGS_HVDCOREF_MASK, /*!< HVD tripped since last time this bit was cleared (0 = no, 1 = yes). */
kPMC_FLAGS_HVD1V8 =
PMC_FLAGS_HVD1V8F_MASK, /*!< vdd1v8 HVD tripped since last time this bit was cleared (0 = no, 1 = yes). */
kPMC_FLAGS_RTC =
PMC_FLAGS_RTCF_MASK, /*!< RTC wakeup detected since last time flag was cleared (0 = no, 1 = yes). */
kPMC_FLAGS_AUTOWK =
PMC_FLAGS_AUTOWKF_MASK, /*!< PMC Auto wakeup caused a deep sleep wakeup and interrupt (0 = no, 1 = yes). */
kPMC_FLAGS_INTNPADF = PMC_FLAGS_INTNPADF_MASK, /*!< Pad interrupt caused a wakeup or interrupt event since the last
time this flag was cleared (0 = no, 1 = yes). */
kPMC_FLAGS_RESETNPAD = PMC_FLAGS_RESETNPADF_MASK, /*!< Reset pad wakeup caused a wakeup or reset event since the
last time this bit was cleared. (0 = no, 1 = yes). */
kPMC_FLAGS_DEEPPD = PMC_FLAGS_DEEPPDF_MASK /*!< Deep powerdown was entered since the last time this flag was cleared
(0 = no, 1 = yes). */
};
typedef enum pd_bits
{
kPDRUNCFG_PMC_MODE0 = MAKE_PD_BITS(PDRCFG0, 1U),
kPDRUNCFG_PMC_MODE1 = MAKE_PD_BITS(PDRCFG0, 2U),
kPDRUNCFG_LP_VDD_COREREG = MAKE_PD_BITS(PDRCFG0, 4U),
kPDRUNCFG_LP_PMCREF = MAKE_PD_BITS(PDRCFG0, 6U),
kPDRUNCFG_PD_HVD1V8 = MAKE_PD_BITS(PDRCFG0, 7U),
kPDRUNCFG_LP_LVDCORE = MAKE_PD_BITS(PDRCFG0, 9U),
kPDRUNCFG_PD_HVDCORE = MAKE_PD_BITS(PDRCFG0, 10U),
kPDRUNCFG_PD_RBB = MAKE_PD_BITS(PDRCFG0, 11U),
kPDRUNCFG_PD_FBB = MAKE_PD_BITS(PDRCFG0, 12U),
kPDRUNCFG_PD_SYSXTAL = MAKE_PD_BITS(PDRCFG0, 13U),
kPDRUNCFG_PD_LPOSC = MAKE_PD_BITS(PDRCFG0, 14U),
kPDRUNCFG_PD_RBBSRAM = MAKE_PD_BITS(PDRCFG0, 15U),
kPDRUNCFG_PD_FFRO = MAKE_PD_BITS(PDRCFG0, 16U),
kPDRUNCFG_PD_SYSPLL_LDO = MAKE_PD_BITS(PDRCFG0, 17U),
kPDRUNCFG_PD_SYSPLL_ANA = MAKE_PD_BITS(PDRCFG0, 18U),
kPDRUNCFG_PD_AUDPLL_LDO = MAKE_PD_BITS(PDRCFG0, 19U),
kPDRUNCFG_PD_AUDPLL_ANA = MAKE_PD_BITS(PDRCFG0, 20U),
kPDRUNCFG_PD_ADC = MAKE_PD_BITS(PDRCFG0, 21U),
kPDRUNCFG_LP_ADC = MAKE_PD_BITS(PDRCFG0, 22U),
kPDRUNCFG_PD_ADC_TEMPSNS = MAKE_PD_BITS(PDRCFG0, 23U),
kPDRUNCFG_PD_PMC_TEMPSNS = MAKE_PD_BITS(PDRCFG0, 24U),
kPDRUNCFG_PD_ACMP = MAKE_PD_BITS(PDRCFG0, 25U),
kPDRUNCFG_LP_HSPAD_FSPI0_VDET = MAKE_PD_BITS(PDRCFG0, 26U),
kPDRUNCFG_PD_HSPAD_FSPI0_REF = MAKE_PD_BITS(PDRCFG0, 27U),
kPDRUNCFG_LP_HSPAD_SDIO0_VDET = MAKE_PD_BITS(PDRCFG0, 28U),
kPDRUNCFG_PD_HSPAD_SDIO0_REF = MAKE_PD_BITS(PDRCFG0, 29U),
kPDRUNCFG_LP_HSPAD_FSPI1_VDET = MAKE_PD_BITS(PDRCFG0, 30U),
kPDRUNCFG_PD_HSPAD_FSPI1_REF = MAKE_PD_BITS(PDRCFG0, 31U),
kPDRUNCFG_PPD_PQ_SRAM = MAKE_PD_BITS(PDRCFG1, 1U),
kPDRUNCFG_APD_FLEXSPI0_SRAM = MAKE_PD_BITS(PDRCFG1, 2U),
kPDRUNCFG_PPD_FLEXSPI0_SRAM = MAKE_PD_BITS(PDRCFG1, 3U),
kPDRUNCFG_APD_FLEXSPI1_SRAM = MAKE_PD_BITS(PDRCFG1, 4U),
kPDRUNCFG_PPD_FLEXSPI1_SRAM = MAKE_PD_BITS(PDRCFG1, 5U),
kPDRUNCFG_APD_USBHS_SRAM = MAKE_PD_BITS(PDRCFG1, 6U),
kPDRUNCFG_PPD_USBHS_SRAM = MAKE_PD_BITS(PDRCFG1, 7U),
kPDRUNCFG_APD_USDHC0_SRAM = MAKE_PD_BITS(PDRCFG1, 8U),
kPDRUNCFG_PPD_USDHC0_SRAM = MAKE_PD_BITS(PDRCFG1, 9U),
kPDRUNCFG_APD_USDHC1_SRAM = MAKE_PD_BITS(PDRCFG1, 10U),
kPDRUNCFG_PPD_USDHC1_SRAM = MAKE_PD_BITS(PDRCFG1, 11U),
kPDRUNCFG_PPD_CASPER_SRAM = MAKE_PD_BITS(PDRCFG1, 13U),
kPDRUNCFG_APD_GPU_SRAM = MAKE_PD_BITS(PDRCFG1, 14U),
kPDRUNCFG_PPD_GPU_SRAM = MAKE_PD_BITS(PDRCFG1, 15U),
kPDRUNCFG_APD_SMARTDMA_SRAM = MAKE_PD_BITS(PDRCFG1, 16U),
kPDRUNCFG_PPD_SMARTDMA_SRAM = MAKE_PD_BITS(PDRCFG1, 17U),
kPDRUNCFG_APD_MIPIDSI_SRAM = MAKE_PD_BITS(PDRCFG1, 18U),
kPDRUNCFG_PPD_MIPIDSI_SRAM = MAKE_PD_BITS(PDRCFG1, 19U),
kPDRUNCFG_APD_DCNANO_SRAM = MAKE_PD_BITS(PDRCFG1, 20U),
kPDRUNCFG_PPD_DCNANO_SRAM = MAKE_PD_BITS(PDRCFG1, 21U),
kPDRUNCFG_PD_DSP = MAKE_PD_BITS(PDRCFG1, 25U),
kPDRUNCFG_PD_MIPIDSI = MAKE_PD_BITS(PDRCFG1, 26U),
kPDRUNCFG_PD_OTP = MAKE_PD_BITS(PDRCFG1, 27U),
kPDRUNCFG_PD_ROM = MAKE_PD_BITS(PDRCFG1, 28U),
kPDRUNCFG_LP_HSPAD_SDIO1_VDET = MAKE_PD_BITS(PDRCFG1, 29U),
kPDRUNCFG_PD_HSPAD_SDIO1_REF = MAKE_PD_BITS(PDRCFG1, 30U),
kPDRUNCFG_SRAM_SLEEP = MAKE_PD_BITS(PDRCFG1, 31U),
kPDRUNCFG_APD_SRAM_IF0 = MAKE_PD_BITS(PDRCFG2, 0U),
kPDRUNCFG_APD_SRAM_IF1 = MAKE_PD_BITS(PDRCFG2, 1U),
kPDRUNCFG_APD_SRAM_IF2 = MAKE_PD_BITS(PDRCFG2, 2U),
kPDRUNCFG_APD_SRAM_IF3 = MAKE_PD_BITS(PDRCFG2, 3U),
kPDRUNCFG_APD_SRAM_IF4 = MAKE_PD_BITS(PDRCFG2, 4U),
kPDRUNCFG_APD_SRAM_IF5 = MAKE_PD_BITS(PDRCFG2, 5U),
kPDRUNCFG_APD_SRAM_IF6 = MAKE_PD_BITS(PDRCFG2, 6U),
kPDRUNCFG_APD_SRAM_IF7 = MAKE_PD_BITS(PDRCFG2, 7U),
kPDRUNCFG_APD_SRAM_IF8 = MAKE_PD_BITS(PDRCFG2, 8U),
kPDRUNCFG_APD_SRAM_IF9 = MAKE_PD_BITS(PDRCFG2, 9U),
kPDRUNCFG_APD_SRAM_IF10 = MAKE_PD_BITS(PDRCFG2, 10U),
kPDRUNCFG_APD_SRAM_IF11 = MAKE_PD_BITS(PDRCFG2, 11U),
kPDRUNCFG_APD_SRAM_IF12 = MAKE_PD_BITS(PDRCFG2, 12U),
kPDRUNCFG_APD_SRAM_IF13 = MAKE_PD_BITS(PDRCFG2, 13U),
kPDRUNCFG_APD_SRAM_IF14 = MAKE_PD_BITS(PDRCFG2, 14U),
kPDRUNCFG_APD_SRAM_IF15 = MAKE_PD_BITS(PDRCFG2, 15U),
kPDRUNCFG_APD_SRAM_IF16 = MAKE_PD_BITS(PDRCFG2, 16U),
kPDRUNCFG_APD_SRAM_IF17 = MAKE_PD_BITS(PDRCFG2, 17U),
kPDRUNCFG_APD_SRAM_IF18 = MAKE_PD_BITS(PDRCFG2, 18U),
kPDRUNCFG_APD_SRAM_IF19 = MAKE_PD_BITS(PDRCFG2, 19U),
kPDRUNCFG_APD_SRAM_IF20 = MAKE_PD_BITS(PDRCFG2, 20U),
kPDRUNCFG_APD_SRAM_IF21 = MAKE_PD_BITS(PDRCFG2, 21U),
kPDRUNCFG_APD_SRAM_IF22 = MAKE_PD_BITS(PDRCFG2, 22U),
kPDRUNCFG_APD_SRAM_IF23 = MAKE_PD_BITS(PDRCFG2, 23U),
kPDRUNCFG_APD_SRAM_IF24 = MAKE_PD_BITS(PDRCFG2, 24U),
kPDRUNCFG_APD_SRAM_IF25 = MAKE_PD_BITS(PDRCFG2, 25U),
kPDRUNCFG_APD_SRAM_IF26 = MAKE_PD_BITS(PDRCFG2, 26U),
kPDRUNCFG_APD_SRAM_IF27 = MAKE_PD_BITS(PDRCFG2, 27U),
kPDRUNCFG_APD_SRAM_IF28 = MAKE_PD_BITS(PDRCFG2, 28U),
kPDRUNCFG_APD_SRAM_IF29 = MAKE_PD_BITS(PDRCFG2, 29U),
kPDRUNCFG_APD_SRAM_IF30 = MAKE_PD_BITS(PDRCFG2, 30U),
kPDRUNCFG_APD_SRAM_IF31 = MAKE_PD_BITS(PDRCFG2, 31U),
kPDRUNCFG_PPD_SRAM_IF0 = MAKE_PD_BITS(PDRCFG3, 0U),
kPDRUNCFG_PPD_SRAM_IF1 = MAKE_PD_BITS(PDRCFG3, 1U),
kPDRUNCFG_PPD_SRAM_IF2 = MAKE_PD_BITS(PDRCFG3, 2U),
kPDRUNCFG_PPD_SRAM_IF3 = MAKE_PD_BITS(PDRCFG3, 3U),
kPDRUNCFG_PPD_SRAM_IF4 = MAKE_PD_BITS(PDRCFG3, 4U),
kPDRUNCFG_PPD_SRAM_IF5 = MAKE_PD_BITS(PDRCFG3, 5U),
kPDRUNCFG_PPD_SRAM_IF6 = MAKE_PD_BITS(PDRCFG3, 6U),
kPDRUNCFG_PPD_SRAM_IF7 = MAKE_PD_BITS(PDRCFG3, 7U),
kPDRUNCFG_PPD_SRAM_IF8 = MAKE_PD_BITS(PDRCFG3, 8U),
kPDRUNCFG_PPD_SRAM_IF9 = MAKE_PD_BITS(PDRCFG3, 9U),
kPDRUNCFG_PPD_SRAM_IF10 = MAKE_PD_BITS(PDRCFG3, 10U),
kPDRUNCFG_PPD_SRAM_IF11 = MAKE_PD_BITS(PDRCFG3, 11U),
kPDRUNCFG_PPD_SRAM_IF12 = MAKE_PD_BITS(PDRCFG3, 12U),
kPDRUNCFG_PPD_SRAM_IF13 = MAKE_PD_BITS(PDRCFG3, 13U),
kPDRUNCFG_PPD_SRAM_IF14 = MAKE_PD_BITS(PDRCFG3, 14U),
kPDRUNCFG_PPD_SRAM_IF15 = MAKE_PD_BITS(PDRCFG3, 15U),
kPDRUNCFG_PPD_SRAM_IF16 = MAKE_PD_BITS(PDRCFG3, 16U),
kPDRUNCFG_PPD_SRAM_IF17 = MAKE_PD_BITS(PDRCFG3, 17U),
kPDRUNCFG_PPD_SRAM_IF18 = MAKE_PD_BITS(PDRCFG3, 18U),
kPDRUNCFG_PPD_SRAM_IF19 = MAKE_PD_BITS(PDRCFG3, 19U),
kPDRUNCFG_PPD_SRAM_IF20 = MAKE_PD_BITS(PDRCFG3, 20U),
kPDRUNCFG_PPD_SRAM_IF21 = MAKE_PD_BITS(PDRCFG3, 21U),
kPDRUNCFG_PPD_SRAM_IF22 = MAKE_PD_BITS(PDRCFG3, 22U),
kPDRUNCFG_PPD_SRAM_IF23 = MAKE_PD_BITS(PDRCFG3, 23U),
kPDRUNCFG_PPD_SRAM_IF24 = MAKE_PD_BITS(PDRCFG3, 24U),
kPDRUNCFG_PPD_SRAM_IF25 = MAKE_PD_BITS(PDRCFG3, 25U),
kPDRUNCFG_PPD_SRAM_IF26 = MAKE_PD_BITS(PDRCFG3, 26U),
kPDRUNCFG_PPD_SRAM_IF27 = MAKE_PD_BITS(PDRCFG3, 27U),
kPDRUNCFG_PPD_SRAM_IF28 = MAKE_PD_BITS(PDRCFG3, 28U),
kPDRUNCFG_PPD_SRAM_IF29 = MAKE_PD_BITS(PDRCFG3, 29U),
kPDRUNCFG_PPD_SRAM_IF30 = MAKE_PD_BITS(PDRCFG3, 30U),
kPDRUNCFG_PPD_SRAM_IF31 = MAKE_PD_BITS(PDRCFG3, 31U),
/*
This enum member has no practical meaning,it is used to avoid MISRA issue,
user should not trying to use it.
*/
kPDRUNCFG_ForceUnsigned = (int)0x80000000U,
} pd_bit_t;
/*! @brief Power mode configuration API parameter */
typedef enum _power_mode_config
{
kPmu_Sleep = 0U,
kPmu_Deep_Sleep = 1U,
kPmu_Deep_PowerDown = 2U,
kPmu_Full_Deep_PowerDown = 3U,
} power_mode_cfg_t;
/*! @brief Body Bias mode definition */
typedef enum _body_bias_mode
{
kPmu_Fbb = 0x01U, /* Forward Body Bias Mode. */
kPmu_Rbb = 0x02U, /* Reverse Body Bias Mode. */
kPmu_Nbb = 0x03U, /* Normal Body Bias Mode. */
} body_bias_mode_t;
/*! @brief PMIC mode pin configuration API parameter */
#define SYSCTL0_TUPLE_REG(reg) (*((volatile uint32_t *)(((uint32_t)(SYSCTL0)) + (((uint32_t)(reg)) & 0xFFFU))))
typedef enum _pmic_mode_reg
{
kCfg_Run = 0x610,
kCfg_Sleep = 0x600,
} pmic_mode_reg_t;
/*! @brief Clock source of main clock before entering deep sleep. */
typedef enum _power_deep_sleep_clk
{
kDeepSleepClk_LpOsc = 0U,
kDeepSleepClk_Fro = 1U,
} power_deep_sleep_clk_t;
/*!
* @brief pad voltage range value. Note, refer to Reference Manual PMC GPIO VDDIO Range Selection Control (PADVRANGE)
* register's description for the supported voltage by different VDDDIO.
*/
typedef enum _power_pad_vrange_val
{
kPadVol_171_360 = 0U, /*!< Deprecated! Voltage from 1.71V to 3.60V. */
kPadVol_Continuous = 0U, /*!< Continuous mode, VDDE detector on. */
kPadVol_171_198 = 1U, /*!< Voltage from 1.71V to 1.98V. VDDE detector off. */
kPadVol_300_360 = 2U, /*!< Voltage from 3.00V to 3.60V. VDDE detector off. */
} power_pad_vrange_val_t;
/*!
* @brief pad voltage range configuration.
*/
typedef struct _power_pad_vrange
{
uint32_t Vdde0Range : 2; /*!< VDDE0 voltage range for VDDIO_0. @ref power_pad_vrange_val_t */
uint32_t Vdde1Range : 2; /*!< VDDE1 voltage range for VDDIO_1. @ref power_pad_vrange_val_t */
uint32_t Vdde2Range : 2; /*!< VDDE2 voltage range for VDDIO_2. @ref power_pad_vrange_val_t */
uint32_t Vdde3Range : 2; /*!< VDDE3 voltage range for VDDIO_3. @ref power_pad_vrange_val_t */
uint32_t Vdde4Range : 2; /*!< VDDE4 voltage range for VDDIO_4. @ref power_pad_vrange_val_t */
uint32_t : 22; /*!< Reserved. */
} power_pad_vrange_t;
/*!
* @brief LVD falling trip voltage value.
*/
typedef enum _power_lvd_falling_trip_vol_val
{
kLvdFallingTripVol_720 = 0U, /*!< Voltage 720mV. */
kLvdFallingTripVol_735 = 1U, /*!< Voltage 735mV. */
kLvdFallingTripVol_750 = 2U, /*!< Voltage 750mV. */
kLvdFallingTripVol_765 = 3U, /*!< Voltage 765mV. */
kLvdFallingTripVol_780 = 4U, /*!< Voltage 780mV. */
kLvdFallingTripVol_795 = 5U, /*!< Voltage 795mV. */
kLvdFallingTripVol_810 = 6U, /*!< Voltage 810mV. */
kLvdFallingTripVol_825 = 7U, /*!< Voltage 825mV. */
kLvdFallingTripVol_840 = 8U, /*!< Voltage 840mV. */
kLvdFallingTripVol_855 = 9U, /*!< Voltage 855mV. */
kLvdFallingTripVol_870 = 10U, /*!< Voltage 870mV. */
kLvdFallingTripVol_885 = 11U, /*!< Voltage 885mV. */
kLvdFallingTripVol_900 = 12U, /*!< Voltage 900mV. */
kLvdFallingTripVol_915 = 13U, /*!< Voltage 915mV. */
kLvdFallingTripVol_930 = 14U, /*!< Voltage 930mV. */
kLvdFallingTripVol_945 = 15U, /*!< Voltage 945mV. */
} power_lvd_falling_trip_vol_val_t;
/*! Invalid voltage level. */
#define POWER_INVALID_VOLT_LEVEL (0xFFFFFFFFU)
/*! Core frequency levels number. */
#define POWER_FREQ_LEVELS_NUM (5U)
/*! Frequency levels defined in power library. */
extern const uint32_t powerFreqLevel[POWER_FREQ_LEVELS_NUM];
/*******************************************************************************
* API
******************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
/*!
* @brief API to enable PDRUNCFG bit in the Sysctl0. Note that enabling the bit powers down the peripheral
*
* @param en peripheral for which to enable the PDRUNCFG bit
*/
void POWER_EnablePD(pd_bit_t en);
/*!
* @brief API to disable PDRUNCFG bit in the Sysctl0. Note that disabling the bit powers up the peripheral
*
* @param en peripheral for which to disable the PDRUNCFG bit
*/
void POWER_DisablePD(pd_bit_t en);
/*!
* @brief API to enable deep sleep bit in the ARM Core.
*/
static inline void POWER_EnableDeepSleep(void)
{
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
}
/*!
* @brief API to disable deep sleep bit in the ARM Core.
*/
static inline void POWER_DisableDeepSleep(void)
{
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
}
/**
* @brief API to update XTAL oscillator settling time .
* @param osc_delay : OSC stabilization time in unit of microsecond
*/
void POWER_UpdateOscSettlingTime(uint32_t osc_delay);
/**
* @brief API to update on-board PMIC vddcore recovery time.
*
* NOTE: If LDO is used instead of PMIC, don't call it. Otherwise it must be called to allow power library to well
* handle the deep sleep process.
*
* @param pmic_delay : PMIC stabilization time in unit of microsecond, or PMIC_VDDCORE_RECOVERY_TIME_IGNORE if not
* care.
*/
void POWER_UpdatePmicRecoveryTime(uint32_t pmic_delay);
/*!
* @brief API to apply updated PMC PDRUNCFG bits in the Sysctl0.
*/
void POWER_ApplyPD(void);
/**
* @brief Clears the PMC event flags state.
* @param statusMask : A bitmask of event flags that are to be cleared.
*/
void POWER_ClearEventFlags(uint32_t statusMask);
/**
* @brief Get the PMC event flags state.
* @return PMC FLAGS register value
*/
uint32_t POWER_GetEventFlags(void);
/**
* @brief Enable the PMC interrupt requests.
* @param interruptMask : A bitmask of of interrupts to enable.
*/
void POWER_EnableInterrupts(uint32_t interruptMask);
/**
* @brief Disable the PMC interrupt requests.
* @param interruptMask : A bitmask of of interrupts to disable.
*/
void POWER_DisableInterrupts(uint32_t interruptMask);
/**
* @brief Set the PMC analog buffer for references or ATX2.
* @param enable : Set to true to enable analog buffer for references or ATX2, false to disable.
*/
void POWER_SetAnalogBuffer(bool enable);
/**
* @brief Get PMIC_MODE pins configure value.
* @param reg : PDSLEEPCFG0 or PDRUNCFG0 register offset
* @return PMIC_MODE pins value in PDSLEEPCFG0
*/
static inline uint32_t POWER_GetPmicMode(pmic_mode_reg_t reg)
{
uint32_t mode = (uint32_t)reg;
return ((SYSCTL0_TUPLE_REG(mode) & (SYSCTL0_PDSLEEPCFG0_PMIC_MODE0_MASK | SYSCTL0_PDSLEEPCFG0_PMIC_MODE1_MASK)) >>
SYSCTL0_PDSLEEPCFG0_PMIC_MODE0_SHIFT);
}
/**
* @brief Get RBB/FBB bit value.
* @param reg : PDSLEEPCFG0 or PDRUNCFG0 register offset
* @return Current body bias mode
*/
static inline body_bias_mode_t POWER_GetBodyBiasMode(pmic_mode_reg_t reg)
{
uint32_t mode = (uint32_t)reg;
uint32_t bbMode = (SYSCTL0_TUPLE_REG(mode) & (SYSCTL0_PDRUNCFG0_RBB_PD_MASK | SYSCTL0_PDRUNCFG0_FBB_PD_MASK)) >>
SYSCTL0_PDRUNCFG0_RBB_PD_SHIFT;
return (body_bias_mode_t)bbMode;
}
/*!
* @brief Configure pad voltage level. Wide voltage range cost more power due to enabled voltage detector.
*
* NOTE: BE CAUTIOUS TO CALL THIS API. IF THE PAD SUPPLY IS BEYOND THE SET RANGE, SILICON MIGHT BE DAMAGED.
*
* @param config pad voltage range configuration.
*/
void POWER_SetPadVolRange(const power_pad_vrange_t *config);
/**
* @brief PMC Enter Rbb mode function call
*/
void POWER_EnterRbb(void);
/**
* @brief PMC Enter Fbb mode function call
*/
void POWER_EnterFbb(void);
/**
* @brief PMC exit Rbb & Fbb mode function call
*/
void POWER_EnterNbb(void);
/**
* @brief PMC Set Ldo volatage for particular frequency.
* NOTE: If LVD falling trip voltage is higher than the required core voltage for particular frequency,
* LVD voltage will be decreased to safe level to avoid unexpected LVD reset or interrupt event.
* @param cm33_clk_freq : CM33 core frequency value
* @param dsp_clk_freq : dsp core frequency value
* @return true for success and false for CPU frequency out of specified voltOpRange.
*/
bool POWER_SetLdoVoltageForFreq(uint32_t cm33_clk_freq, uint32_t dsp_clk_freq);
/*!
* @brief Set vddcore low voltage detection falling trip voltage.
* @param volt target LVD voltage to set.
*/
void POWER_SetLvdFallingTripVoltage(power_lvd_falling_trip_vol_val_t volt);
/**
* @brief Get current vddcore low voltage detection falling trip voltage.
* @return Current LVD voltage.
*/
power_lvd_falling_trip_vol_val_t POWER_GetLvdFallingTripVoltage(void);
/**
* @brief Disable low voltage detection, no reset or interrupt is triggered when vddcore voltage drops below
* threshold.
* NOTE: This API is for internal use only. Application should not touch it.
*/
void POWER_DisableLVD(void);
/**
* @brief Restore low voltage detection setting.
* NOTE: This API is for internal use only. Application should not touch it.
*/
void POWER_RestoreLVD(void);
/**
* @brief Set PMIC_MODE pins configure value.
* @param mode : PMIC MODE pin value
* @param reg : PDSLEEPCFG0 or PDRUNCFG0 register offset
* @return PMIC_MODE pins value in PDSLEEPCFG0
*/
void POWER_SetPmicMode(uint32_t mode, pmic_mode_reg_t reg);
/**
* @brief Set deep sleep clock source of main clock.
* @param clk : clock source of main clock.
*/
void POWER_SetDeepSleepClock(power_deep_sleep_clk_t clk);
/**
* @brief Configures and enters in SLEEP low power mode
*/
void POWER_EnterSleep(void);
/**
* @brief PMC Deep Sleep function call
* @param exclude_from_pd Bit mask of the PDRUNCFG0 ~ PDRUNCFG3 that needs to be powered on during Deep Sleep mode
* selected.
*/
void POWER_EnterDeepSleep(const uint32_t exclude_from_pd[4]);
/**
* @brief PMC Deep Power Down function call
* @param exclude_from_pd Bit mask of the PDRUNCFG0 ~ PDRUNCFG3 that needs to be powered on during Deep Power Down
* mode selected.
*/
void POWER_EnterDeepPowerDown(const uint32_t exclude_from_pd[4]);
/**
* @brief PMC Full Deep Power Down function call
* @param exclude_from_pd Bit mask of the PDRUNCFG0 ~ PDRUNCFG3 that needs to be powered on during Full Deep Power
* Down mode selected.
*/
void POWER_EnterFullDeepPowerDown(const uint32_t exclude_from_pd[4]);
/*!
* @brief Power Library API to enter different power mode.
*
* @param mode Power mode to enter.
* @param exclude_from_pd Bit mask of the PDRUNCFG0 ~ PDRUNCFG3 that needs to be powered on during power mode selected.
*/
void POWER_EnterPowerMode(power_mode_cfg_t mode, const uint32_t exclude_from_pd[4]);
/*!
* @brief Enable specific interrupt for wake-up from deep-sleep mode.
* Enable the interrupt for wake-up from deep sleep mode.
* Some interrupts are typically used in sleep mode only and will not occur during
* deep-sleep mode because relevant clocks are stopped. However, it is possible to enable
* those clocks (significantly increasing power consumption in the reduced power mode),
* making these wake-ups possible.
* @note This function also enables the interrupt in the NVIC (EnableIRQ() is called internally).
* @param interrupt The IRQ number.
*/
void EnableDeepSleepIRQ(IRQn_Type interrupt);
/*!
* @brief Disable specific interrupt for wake-up from deep-sleep mode.
* Disable the interrupt for wake-up from deep sleep mode.
* Some interrupts are typically used in sleep mode only and will not occur during
* deep-sleep mode because relevant clocks are stopped. However, it is possible to enable
* those clocks (significantly increasing power consumption in the reduced power mode),
* making these wake-ups possible.
* @note This function also disables the interrupt in the NVIC (DisableIRQ() is called internally).
* @param interrupt The IRQ number.
*/
void DisableDeepSleepIRQ(IRQn_Type interrupt);
/*!
* @brief Power Library API to return the library version.
*
* @return version number of the power library
*/
uint32_t POWER_GetLibVersion(void);
#ifdef __cplusplus
}
#endif
/*!
* @}
*/
#endif /* _FSL_POWER_H_ */

View file

@ -0,0 +1,164 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2020, NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_common.h"
#include "fsl_reset.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.reset"
#endif
/*******************************************************************************
* Variables
******************************************************************************/
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Code
******************************************************************************/
/*!
* brief Assert reset to peripheral.
*
* Asserts reset signal to specified peripheral module.
*
* param peripheral Assert reset to this peripheral. The enum argument contains encoding of reset register
* and reset bit position in the reset register.
*/
void RESET_SetPeripheralReset(reset_ip_name_t peripheral)
{
const uint32_t regIndex = ((uint32_t)peripheral & 0x0000FF00u) >> 8;
const uint32_t bitPos = ((uint32_t)peripheral & 0x000000FFu);
const uint32_t bitMask = 1UL << bitPos;
assert(bitPos < 32u);
switch (regIndex)
{
case RST_CTL0_PSCCTL0:
RSTCTL0->PRSTCTL0_SET = bitMask;
while (0u == (RSTCTL0->PRSTCTL0 & bitMask))
{
}
break;
case RST_CTL0_PSCCTL1:
RSTCTL0->PRSTCTL1_SET = bitMask;
while (0u == (RSTCTL0->PRSTCTL1 & bitMask))
{
}
break;
case RST_CTL0_PSCCTL2:
RSTCTL0->PRSTCTL2_SET = bitMask;
while (0u == (RSTCTL0->PRSTCTL2 & bitMask))
{
}
break;
case RST_CTL1_PSCCTL0:
RSTCTL1->PRSTCTL0_SET = bitMask;
while (0u == (RSTCTL1->PRSTCTL0 & bitMask))
{
}
break;
case RST_CTL1_PSCCTL1:
RSTCTL1->PRSTCTL1_SET = bitMask;
while (0u == (RSTCTL1->PRSTCTL1 & bitMask))
{
}
break;
case RST_CTL1_PSCCTL2:
RSTCTL1->PRSTCTL2_SET = bitMask;
while (0u == (RSTCTL1->PRSTCTL2 & bitMask))
{
}
break;
default:
/* Added comments to prevent the violation of MISRA C-2012 rule. */
break;
}
}
/*!
* brief Clear reset to peripheral.
*
* Clears reset signal to specified peripheral module, allows it to operate.
*
* param peripheral Clear reset to this peripheral. The enum argument contains encoding of reset register
* and reset bit position in the reset register.
*/
void RESET_ClearPeripheralReset(reset_ip_name_t peripheral)
{
const uint32_t regIndex = ((uint32_t)peripheral & 0x0000FF00u) >> 8;
const uint32_t bitPos = ((uint32_t)peripheral & 0x000000FFu);
const uint32_t bitMask = 1UL << bitPos;
assert(bitPos < 32u);
switch (regIndex)
{
case RST_CTL0_PSCCTL0:
RSTCTL0->PRSTCTL0_CLR = bitMask;
while (bitMask == (RSTCTL0->PRSTCTL0 & bitMask))
{
}
break;
case RST_CTL0_PSCCTL1:
RSTCTL0->PRSTCTL1_CLR = bitMask;
while (bitMask == (RSTCTL0->PRSTCTL1 & bitMask))
{
}
break;
case RST_CTL0_PSCCTL2:
RSTCTL0->PRSTCTL2_CLR = bitMask;
while (bitMask == (RSTCTL0->PRSTCTL2 & bitMask))
{
}
break;
case RST_CTL1_PSCCTL0:
RSTCTL1->PRSTCTL0_CLR = bitMask;
while (bitMask == (RSTCTL1->PRSTCTL0 & bitMask))
{
}
break;
case RST_CTL1_PSCCTL1:
RSTCTL1->PRSTCTL1_CLR = bitMask;
while (bitMask == (RSTCTL1->PRSTCTL1 & bitMask))
{
}
break;
case RST_CTL1_PSCCTL2:
RSTCTL1->PRSTCTL2_CLR = bitMask;
while (bitMask == (RSTCTL1->PRSTCTL2 & bitMask))
{
}
break;
default:
/* Added comments to prevent the violation of MISRA C-2012 rule. */
break;
}
}
/*!
* brief Reset peripheral module.
*
* Reset peripheral module.
*
* param peripheral Peripheral to reset. The enum argument contains encoding of reset register
* and reset bit position in the reset register.
*/
void RESET_PeripheralReset(reset_ip_name_t peripheral)
{
RESET_SetPeripheralReset(peripheral);
RESET_ClearPeripheralReset(peripheral);
}

View file

@ -0,0 +1,290 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2020, NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_RESET_H_
#define _FSL_RESET_H_
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "fsl_device_registers.h"
/*!
* @addtogroup reset
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief reset driver version 2.0.1. */
#define FSL_RESET_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
/*@}*/
/*!
* @brief Reset control registers index
*/
#define RST_CTL0_PSCCTL0 0
#define RST_CTL0_PSCCTL1 1
#define RST_CTL0_PSCCTL2 2
#define RST_CTL1_PSCCTL0 3
#define RST_CTL1_PSCCTL1 4
#define RST_CTL1_PSCCTL2 5
/*!
* @brief Enumeration for peripheral reset control bits
*
* Defines the enumeration for peripheral reset control bits in RSTCLTx registers
*/
typedef enum _RSTCTL_RSTn
{
kDSP_RST_SHIFT_RSTn = (RST_CTL0_PSCCTL0 << 8) | 1U, /**< DSP reset control */
kAXI_SWITCH_RST_SHIFT_RSTn = (RST_CTL0_PSCCTL0 << 8) | 3U, /**< AXI Switch reset control */
kPOWERQUAD_RST_SHIFT_RSTn = (RST_CTL0_PSCCTL0 << 8) | 8U, /**< POWERQUAD reset control */
kCASPER_RST_SHIFT_RSTn = (RST_CTL0_PSCCTL0 << 8) | 9U, /**< CASPER reset control */
kHASHCRYPT_RST_SHIFT_RSTn = (RST_CTL0_PSCCTL0 << 8) | 10U, /**< HASHCRYPT reset control */
kPUF_RST_SHIFT_RSTn = (RST_CTL0_PSCCTL0 << 8) | 11U, /**< Physical unclonable function reset control */
kRNG_RST_SHIFT_RSTn = (RST_CTL0_PSCCTL0 << 8) | 12U, /**< Random number generator (RNG) reset control */
kFLEXSPI0_RST_SHIFT_RSTn = (RST_CTL0_PSCCTL0 << 8) | 16U, /**< FLEXSPI0/OTFAD reset control */
kFLEXSPI1_RST_SHIFT_RSTn = (RST_CTL0_PSCCTL0 << 8) | 18U, /**< FLEXSPI1 reset control */
kUSBHS_PHY_RST_SHIFT_RSTn = (RST_CTL0_PSCCTL0 << 8) | 20U, /**< High speed USB PHY reset control */
kUSBHS_DEVICE_RST_SHIFT_RSTn = (RST_CTL0_PSCCTL0 << 8) | 21U, /**< High speed USB Device reset control */
kUSBHS_HOST_RST_SHIFT_RSTn = (RST_CTL0_PSCCTL0 << 8) | 22U, /**< High speed USB Host reset control */
kUSBHS_SRAM_RST_SHIFT_RSTn = (RST_CTL0_PSCCTL0 << 8) | 23U, /**< High speed USB SRAM reset control */
kSCT_RST_SHIFT_RSTn = (RST_CTL0_PSCCTL0 << 8) | 24U, /**< Standard ctimers reset control */
kGPU_RST_SHIFT_RSTn = (RST_CTL0_PSCCTL0 << 8) | 26U, /**< GPU reset control */
kDISP_CTRL_RST_SHIFT_RSTn = (RST_CTL0_PSCCTL0 << 8) | 27U, /**< Display controller reset control */
kMIPI_DSI_CTRL_RST_SHIFT_RSTn = (RST_CTL0_PSCCTL0 << 8) | 28U, /**< MIPI DSI controller reset control */
kMIPI_DSI_PHY_RST_SHIFT_RSTn = (RST_CTL0_PSCCTL0 << 8) | 29U, /**< MIPI DSI PHY reset control */
kSMART_DMA_RST_SHIFT_RSTn = (RST_CTL0_PSCCTL0 << 8) | 30U, /**< Smart DMA reset control */
kSDIO0_RST_SHIFT_RSTn = (RST_CTL0_PSCCTL1 << 8) | 2U, /**< SDIO0 reset control */
kSDIO1_RST_SHIFT_RSTn = (RST_CTL0_PSCCTL1 << 8) | 3U, /**< SDIO1 reset control */
kACMP0_RST_SHIFT_RSTn = (RST_CTL0_PSCCTL1 << 8) | 15U, /**< Grouped interrupt (PINT) reset control. */
kADC0_RST_SHIFT_RSTn = (RST_CTL0_PSCCTL1 << 8) | 16U, /**< ADC0 reset control */
kSHSGPIO0_RST_SHIFT_RSTn = (RST_CTL0_PSCCTL1 << 8) | 24U, /**< Security HSGPIO 0 reset control */
kUTICK0_RST_SHIFT_RSTn = (RST_CTL0_PSCCTL2 << 8) | 0U, /**< Micro-tick timer reset control */
kWWDT0_RST_SHIFT_RSTn = (RST_CTL0_PSCCTL2 << 8) | 1U, /**< Windowed Watchdog timer 0 reset control */
kFC0_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL0 << 8) | 8U, /**< Flexcomm Interface 0 reset control */
kFC1_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL0 << 8) | 9U, /**< Flexcomm Interface 1 reset control */
kFC2_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL0 << 8) | 10U, /**< Flexcomm Interface 2 reset control */
kFC3_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL0 << 8) | 11U, /**< Flexcomm Interface 3 reset control */
kFC4_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL0 << 8) | 12U, /**< Flexcomm Interface 4 reset control */
kFC5_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL0 << 8) | 13U, /**< Flexcomm Interface 5 reset control */
kFC6_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL0 << 8) | 14U, /**< Flexcomm Interface 6 reset control */
kFC7_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL0 << 8) | 15U, /**< Flexcomm Interface 7 reset control */
kFC8_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL0 << 8) | 16U, /**< Flexcomm Interface 8 reset control */
kFC9_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL0 << 8) | 17U, /**< Flexcomm Interface 9 reset control */
kFC10_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL0 << 8) | 18U, /**< Flexcomm Interface 10 reset control */
kFC11_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL0 << 8) | 19U, /**< Flexcomm Interface 11 reset control */
kFC12_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL0 << 8) | 20U, /**< Flexcomm Interface 12 reset control */
kFC13_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL0 << 8) | 21U, /**< Flexcomm Interface 13 reset control */
kFC14_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL0 << 8) | 22U, /**< Flexcomm Interface 14 reset control */
kFC15_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL0 << 8) | 23U, /**< Flexcomm Interface 15 reset control */
kDMIC_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL0 << 8) | 24U, /**< Digital microphone interface reset control */
kFC16_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL0 << 8) | 25U, /**< Flexcomm Interface 16 reset control */
kOSEVENT_TIMER_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL0 << 8) | 27U, /**< Osevent Timer reset control */
kFLEXIO_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL0 << 8) | 29U, /**< FlexIO reset control */
kHSGPIO0_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL1 << 8) | 0U, /**< HSGPIO 0 reset control */
kHSGPIO1_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL1 << 8) | 1U, /**< HSGPIO 1 reset control */
kHSGPIO2_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL1 << 8) | 2U, /**< HSGPIO 2 reset control */
kHSGPIO3_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL1 << 8) | 3U, /**< HSGPIO 3 reset control */
kHSGPIO4_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL1 << 8) | 4U, /**< HSGPIO 4 reset control */
kHSGPIO5_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL1 << 8) | 5U, /**< HSGPIO 5 reset control */
kHSGPIO6_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL1 << 8) | 6U, /**< HSGPIO 6 reset control */
kHSGPIO7_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL1 << 8) | 7U, /**< HSGPIO 7 reset control */
kCRC_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL1 << 8) | 16U, /**< CRC reset control */
kDMAC0_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL1 << 8) | 23U, /**< DMA Controller 0 reset control */
kDMAC1_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL1 << 8) | 24U, /**< DMA Controller 1 reset control */
kMU_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL1 << 8) | 28U, /**< Message Unit reset control */
kSEMA_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL1 << 8) | 29U, /**< Semaphore reset control */
kFREQME_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL1 << 8) | 31U, /**< Frequency Measure reset control */
kCT32B0_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL2 << 8) | 0U, /**< CT32B0 reset control */
kCT32B1_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL2 << 8) | 1U, /**< CT32B1 reset control */
kCT32B2_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL2 << 8) | 2U, /**< CT32B3 reset control */
kCT32B3_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL2 << 8) | 3U, /**< CT32B4 reset control */
kCT32B4_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL2 << 8) | 4U, /**< CT32B4 reset control */
kMRT0_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL2 << 8) | 8U, /**< Multi-rate timer (MRT) reset control */
kWWDT1_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL2 << 8) | 10U, /**< Windowed Watchdog timer 1 reset control */
kI3C0_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL2 << 8) | 16U, /**< I3C0 reset control */
kI3C1_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL2 << 8) | 17U, /**< I3C1 reset control */
kPINT_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL2 << 8) | 30U, /**< GPIO Pin interrupt reset control */
kINPUTMUX_RST_SHIFT_RSTn = (RST_CTL1_PSCCTL2 << 8) | 31U, /**< Peripheral input muxes reset control */
} RSTCTL_RSTn_t;
/** Array initializers with peripheral reset bits **/
#define ADC_RSTS \
{ \
kADC0_RST_SHIFT_RSTn \
} /* Reset bits for ADC peripheral */
#define CASPER_RSTS \
{ \
kCASPER_RST_SHIFT_RSTn \
} /* Reset bits for Casper peripheral */
#define CRC_RSTS \
{ \
kCRC_RST_SHIFT_RSTn \
} /* Reset bits for CRC peripheral */
#define CTIMER_RSTS \
{ \
kCT32B0_RST_SHIFT_RSTn, kCT32B1_RST_SHIFT_RSTn, kCT32B2_RST_SHIFT_RSTn, kCT32B3_RST_SHIFT_RSTn, \
kCT32B4_RST_SHIFT_RSTn \
} /* Reset bits for TIMER peripheral */
#define DCNANO_RSTS \
{ \
kDISP_CTRL_RST_SHIFT_RSTn \
} /* Reset bits for CRC peripheral */
#define MIPI_DSI_RSTS \
{ \
kMIPI_DSI_CTRL_RST_SHIFT_RSTn \
} /* Reset bits for CRC peripheral */
#define DMA_RSTS_N \
{ \
kDMAC0_RST_SHIFT_RSTn, kDMAC1_RST_SHIFT_RSTn \
} /* Reset bits for DMA peripheral */
#define DMIC_RSTS \
{ \
kDMIC_RST_SHIFT_RSTn \
} /* Reset bits for ADC peripheral */
#define FLEXCOMM_RSTS \
{ \
kFC0_RST_SHIFT_RSTn, kFC1_RST_SHIFT_RSTn, kFC2_RST_SHIFT_RSTn, kFC3_RST_SHIFT_RSTn, kFC4_RST_SHIFT_RSTn, \
kFC5_RST_SHIFT_RSTn, kFC6_RST_SHIFT_RSTn, kFC7_RST_SHIFT_RSTn, kFC8_RST_SHIFT_RSTn, kFC9_RST_SHIFT_RSTn, \
kFC10_RST_SHIFT_RSTn, kFC11_RST_SHIFT_RSTn, kFC12_RST_SHIFT_RSTn, kFC13_RST_SHIFT_RSTn, \
kFC14_RST_SHIFT_RSTn, kFC15_RST_SHIFT_RSTn, kFC16_RST_SHIFT_RSTn \
} /* Reset bits for FLEXCOMM peripheral */
#define FLEXIO_RSTS \
{ \
kFLEXIO_RST_SHIFT_RSTn \
} /* Resets bits for FLEXIO peripheral */
#define FLEXSPI_RSTS \
{ \
kFLEXSPI0_RST_SHIFT_RSTn, kFLEXSPI1_RST_SHIFT_RSTn \
} /* Resets bits for FLEXSPI peripheral */
#define GPIO_RSTS_N \
{ \
kHSGPIO0_RST_SHIFT_RSTn, kHSGPIO1_RST_SHIFT_RSTn, kHSGPIO2_RST_SHIFT_RSTn, kHSGPIO3_RST_SHIFT_RSTn, \
kHSGPIO4_RST_SHIFT_RSTn, kHSGPIO5_RST_SHIFT_RSTn, kHSGPIO6_RST_SHIFT_RSTn, kHSGPIO7_RST_SHIFT_RSTn \
} /* Reset bits for GPIO peripheral */
#define HASHCRYPT_RSTS \
{ \
kHASHCRYPT_RST_SHIFT_RSTn \
} /* Reset bits for Hashcrypt peripheral */
#define I3C_RSTS \
{ \
kI3C0_RST_SHIFT_RSTn, kI3C1_RST_SHIFT_RSTn \
} /* Reset bits for I3C peripheral */
#define INPUTMUX_RSTS \
{ \
kINPUTMUX_RST_SHIFT_RSTn \
} /* Reset bits for INPUTMUX peripheral */
#define MRT_RSTS \
{ \
kMRT0_RST_SHIFT_RSTn \
} /* Reset bits for MRT peripheral */
#define MU_RSTS \
{ \
kMU_RST_SHIFT_RSTn \
} /* Reset bits for MU peripheral */
#define OSTIMER_RSTS \
{ \
kOSEVENT_TIMER_RST_SHIFT_RSTn \
} /* Reset bits for OSTIMER peripheral */
#define PINT_RSTS \
{ \
kPINT_RST_SHIFT_RSTn \
} /* Reset bits for PINT peripheral */
#define POWERQUAD_RSTS \
{ \
kPOWERQUAD_RST_SHIFT_RSTn \
} /* Reset bits for Powerquad peripheral */
#define PUF_RSTS \
{ \
kPUF_RST_SHIFT_RSTn \
} /* Reset bits for PUF peripheral */
#define SCT_RSTS \
{ \
kSCT_RST_SHIFT_RSTn \
} /* Reset bits for SCT peripheral */
#define SEMA42_RSTS \
{ \
kSEMA_RST_SHIFT_RSTn \
} /* Reset bits for SEMA42 peripheral */
#define TRNG_RSTS \
{ \
kRNG_RST_SHIFT_RSTn \
} /* Reset bits for TRNG peripheral */
#define USDHC_RSTS \
{ \
kSDIO0_RST_SHIFT_RSTn, kSDIO1_RST_SHIFT_RSTn \
} /* Reset bits for USDHC peripheral */
#define UTICK_RSTS \
{ \
kUTICK0_RST_SHIFT_RSTn \
} /* Reset bits for UTICK peripheral */
#define WWDT_RSTS \
{ \
kWWDT0_RST_SHIFT_RSTn, kWWDT1_RST_SHIFT_RSTn \
} /* Reset bits for WWDT peripheral */
/*!
* @brief IP reset handle
*/
typedef RSTCTL_RSTn_t reset_ip_name_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @brief Assert reset to peripheral.
*
* Asserts reset signal to specified peripheral module.
*
* @param peripheral Assert reset to this peripheral. The enum argument contains encoding of reset register
* and reset bit position in the reset register.
*/
void RESET_SetPeripheralReset(reset_ip_name_t peripheral);
/*!
* @brief Clear reset to peripheral.
*
* Clears reset signal to specified peripheral module, allows it to operate.
*
* @param peripheral Clear reset to this peripheral. The enum argument contains encoding of reset register
* and reset bit position in the reset register.
*/
void RESET_ClearPeripheralReset(reset_ip_name_t peripheral);
/*!
* @brief Reset peripheral module.
*
* Reset peripheral module.
*
* @param peripheral Peripheral to reset. The enum argument contains encoding of reset register
* and reset bit position in the reset register.
*/
void RESET_PeripheralReset(reset_ip_name_t peripheral);
#if defined(__cplusplus)
}
#endif
/*! @} */
#endif /* _FSL_RESET_H_ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,866 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_USART_H_
#define _FSL_USART_H_
#include "fsl_common.h"
/*!
* @addtogroup usart_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief USART driver version. */
#define FSL_USART_DRIVER_VERSION (MAKE_VERSION(2, 5, 1))
/*@}*/
#define USART_FIFOTRIG_TXLVL_GET(base) (((base)->FIFOTRIG & USART_FIFOTRIG_TXLVL_MASK) >> USART_FIFOTRIG_TXLVL_SHIFT)
#define USART_FIFOTRIG_RXLVL_GET(base) (((base)->FIFOTRIG & USART_FIFOTRIG_RXLVL_MASK) >> USART_FIFOTRIG_RXLVL_SHIFT)
/*! @brief Retry times for waiting flag. */
#ifndef UART_RETRY_TIMES
#define UART_RETRY_TIMES 0U /* Defining to zero means to keep waiting for the flag until it is assert/deassert. */
#endif
/*! @brief Error codes for the USART driver. */
enum
{
kStatus_USART_TxBusy = MAKE_STATUS(kStatusGroup_LPC_USART, 0), /*!< Transmitter is busy. */
kStatus_USART_RxBusy = MAKE_STATUS(kStatusGroup_LPC_USART, 1), /*!< Receiver is busy. */
kStatus_USART_TxIdle = MAKE_STATUS(kStatusGroup_LPC_USART, 2), /*!< USART transmitter is idle. */
kStatus_USART_RxIdle = MAKE_STATUS(kStatusGroup_LPC_USART, 3), /*!< USART receiver is idle. */
kStatus_USART_TxError = MAKE_STATUS(kStatusGroup_LPC_USART, 7), /*!< Error happens on txFIFO. */
kStatus_USART_RxError = MAKE_STATUS(kStatusGroup_LPC_USART, 9), /*!< Error happens on rxFIFO. */
kStatus_USART_RxRingBufferOverrun = MAKE_STATUS(kStatusGroup_LPC_USART, 8), /*!< Error happens on rx ring buffer */
kStatus_USART_NoiseError = MAKE_STATUS(kStatusGroup_LPC_USART, 10), /*!< USART noise error. */
kStatus_USART_FramingError = MAKE_STATUS(kStatusGroup_LPC_USART, 11), /*!< USART framing error. */
kStatus_USART_ParityError = MAKE_STATUS(kStatusGroup_LPC_USART, 12), /*!< USART parity error. */
kStatus_USART_BaudrateNotSupport =
MAKE_STATUS(kStatusGroup_LPC_USART, 13), /*!< Baudrate is not support in current clock source */
kStatus_USART_Timeout = MAKE_STATUS(kStatusGroup_LPC_USART, 14), /*!< USART time out. */
};
/*! @brief USART synchronous mode. */
typedef enum _usart_sync_mode
{
kUSART_SyncModeDisabled = 0x0U, /*!< Asynchronous mode. */
kUSART_SyncModeSlave = 0x2U, /*!< Synchronous slave mode. */
kUSART_SyncModeMaster = 0x3U, /*!< Synchronous master mode. */
} usart_sync_mode_t;
/*! @brief USART parity mode. */
typedef enum _usart_parity_mode
{
kUSART_ParityDisabled = 0x0U, /*!< Parity disabled */
kUSART_ParityEven = 0x2U, /*!< Parity enabled, type even, bit setting: PE|PT = 10 */
kUSART_ParityOdd = 0x3U, /*!< Parity enabled, type odd, bit setting: PE|PT = 11 */
} usart_parity_mode_t;
/*! @brief USART stop bit count. */
typedef enum _usart_stop_bit_count
{
kUSART_OneStopBit = 0U, /*!< One stop bit */
kUSART_TwoStopBit = 1U, /*!< Two stop bits */
} usart_stop_bit_count_t;
/*! @brief USART data size. */
typedef enum _usart_data_len
{
kUSART_7BitsPerChar = 0U, /*!< Seven bit mode */
kUSART_8BitsPerChar = 1U, /*!< Eight bit mode */
} usart_data_len_t;
/*! @brief USART clock polarity configuration, used in sync mode.*/
typedef enum _usart_clock_polarity
{
kUSART_RxSampleOnFallingEdge = 0x0U, /*!< Un_RXD is sampled on the falling edge of SCLK. */
kUSART_RxSampleOnRisingEdge = 0x1U, /*!< Un_RXD is sampled on the rising edge of SCLK. */
} usart_clock_polarity_t;
/*! @brief txFIFO watermark values */
typedef enum _usart_txfifo_watermark
{
kUSART_TxFifo0 = 0, /*!< USART tx watermark is empty */
kUSART_TxFifo1 = 1, /*!< USART tx watermark at 1 item */
kUSART_TxFifo2 = 2, /*!< USART tx watermark at 2 items */
kUSART_TxFifo3 = 3, /*!< USART tx watermark at 3 items */
kUSART_TxFifo4 = 4, /*!< USART tx watermark at 4 items */
kUSART_TxFifo5 = 5, /*!< USART tx watermark at 5 items */
kUSART_TxFifo6 = 6, /*!< USART tx watermark at 6 items */
kUSART_TxFifo7 = 7, /*!< USART tx watermark at 7 items */
} usart_txfifo_watermark_t;
/*! @brief rxFIFO watermark values */
typedef enum _usart_rxfifo_watermark
{
kUSART_RxFifo1 = 0, /*!< USART rx watermark at 1 item */
kUSART_RxFifo2 = 1, /*!< USART rx watermark at 2 items */
kUSART_RxFifo3 = 2, /*!< USART rx watermark at 3 items */
kUSART_RxFifo4 = 3, /*!< USART rx watermark at 4 items */
kUSART_RxFifo5 = 4, /*!< USART rx watermark at 5 items */
kUSART_RxFifo6 = 5, /*!< USART rx watermark at 6 items */
kUSART_RxFifo7 = 6, /*!< USART rx watermark at 7 items */
kUSART_RxFifo8 = 7, /*!< USART rx watermark at 8 items */
} usart_rxfifo_watermark_t;
/*!
* @brief USART interrupt configuration structure, default settings all disabled.
*/
enum _usart_interrupt_enable
{
kUSART_TxErrorInterruptEnable = (USART_FIFOINTENSET_TXERR_MASK),
kUSART_RxErrorInterruptEnable = (USART_FIFOINTENSET_RXERR_MASK),
kUSART_TxLevelInterruptEnable = (USART_FIFOINTENSET_TXLVL_MASK),
kUSART_RxLevelInterruptEnable = (USART_FIFOINTENSET_RXLVL_MASK),
};
/*!
* @brief USART status flags.
*
* This provides constants for the USART status flags for use in the USART functions.
*/
enum _usart_flags
{
kUSART_TxError = (USART_FIFOSTAT_TXERR_MASK), /*!< TEERR bit, sets if TX buffer is error */
kUSART_RxError = (USART_FIFOSTAT_RXERR_MASK), /*!< RXERR bit, sets if RX buffer is error */
kUSART_TxFifoEmptyFlag = (USART_FIFOSTAT_TXEMPTY_MASK), /*!< TXEMPTY bit, sets if TX buffer is empty */
kUSART_TxFifoNotFullFlag = (USART_FIFOSTAT_TXNOTFULL_MASK), /*!< TXNOTFULL bit, sets if TX buffer is not full */
kUSART_RxFifoNotEmptyFlag = (USART_FIFOSTAT_RXNOTEMPTY_MASK), /*!< RXNOEMPTY bit, sets if RX buffer is not empty */
kUSART_RxFifoFullFlag = (USART_FIFOSTAT_RXFULL_MASK), /*!< RXFULL bit, sets if RX buffer is full */
};
/*! @brief USART configuration structure. */
typedef struct _usart_config
{
uint32_t baudRate_Bps; /*!< USART baud rate */
usart_parity_mode_t parityMode; /*!< Parity mode, disabled (default), even, odd */
usart_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits */
usart_data_len_t bitCountPerChar; /*!< Data length - 7 bit, 8 bit */
bool loopback; /*!< Enable peripheral loopback */
bool enableRx; /*!< Enable RX */
bool enableTx; /*!< Enable TX */
bool enableContinuousSCLK; /*!< USART continuous Clock generation enable in synchronous master mode. */
bool enableMode32k; /*!< USART uses 32 kHz clock from the RTC oscillator as the clock source. */
bool enableHardwareFlowControl; /*!< Enable hardware control RTS/CTS */
usart_txfifo_watermark_t txWatermark; /*!< txFIFO watermark */
usart_rxfifo_watermark_t rxWatermark; /*!< rxFIFO watermark */
usart_sync_mode_t syncMode; /*!< Transfer mode select - asynchronous, synchronous master, synchronous slave. */
usart_clock_polarity_t clockPolarity; /*!< Selects the clock polarity and sampling edge in synchronous mode. */
} usart_config_t;
/*! @brief USART transfer structure. */
typedef struct _usart_transfer
{
/*
* Use separate TX and RX data pointer, because TX data is const data.
* The member data is kept for backward compatibility.
*/
union
{
uint8_t *data; /*!< The buffer of data to be transfer.*/
uint8_t *rxData; /*!< The buffer to receive data. */
const uint8_t *txData; /*!< The buffer of data to be sent. */
};
size_t dataSize; /*!< The byte count to be transfer. */
} usart_transfer_t;
/* Forward declaration of the handle typedef. */
typedef struct _usart_handle usart_handle_t;
/*! @brief USART transfer callback function. */
typedef void (*usart_transfer_callback_t)(USART_Type *base, usart_handle_t *handle, status_t status, void *userData);
/*! @brief USART handle structure. */
struct _usart_handle
{
const uint8_t *volatile txData; /*!< Address of remaining data to send. */
volatile size_t txDataSize; /*!< Size of the remaining data to send. */
size_t txDataSizeAll; /*!< Size of the data to send out. */
uint8_t *volatile rxData; /*!< Address of remaining data to receive. */
volatile size_t rxDataSize; /*!< Size of the remaining data to receive. */
size_t rxDataSizeAll; /*!< Size of the data to receive. */
uint8_t *rxRingBuffer; /*!< Start address of the receiver ring buffer. */
size_t rxRingBufferSize; /*!< Size of the ring buffer. */
volatile uint16_t rxRingBufferHead; /*!< Index for the driver to store received data into ring buffer. */
volatile uint16_t rxRingBufferTail; /*!< Index for the user to get data from the ring buffer. */
usart_transfer_callback_t callback; /*!< Callback function. */
void *userData; /*!< USART callback function parameter.*/
volatile uint8_t txState; /*!< TX transfer state. */
volatile uint8_t rxState; /*!< RX transfer state */
uint8_t txWatermark; /*!< txFIFO watermark */
uint8_t rxWatermark; /*!< rxFIFO watermark */
};
/*! @brief Typedef for usart interrupt handler. */
typedef void (*flexcomm_usart_irq_handler_t)(USART_Type *base, usart_handle_t *handle);
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* _cplusplus */
/*! @brief Returns instance number for USART peripheral base address. */
uint32_t USART_GetInstance(USART_Type *base);
/*!
* @name Initialization and deinitialization
* @{
*/
/*!
* @brief Initializes a USART instance with user configuration structure and peripheral clock.
*
* This function configures the USART module with the user-defined settings. The user can configure the configuration
* structure and also get the default configuration by using the USART_GetDefaultConfig() function.
* Example below shows how to use this API to configure USART.
* @code
* usart_config_t usartConfig;
* usartConfig.baudRate_Bps = 115200U;
* usartConfig.parityMode = kUSART_ParityDisabled;
* usartConfig.stopBitCount = kUSART_OneStopBit;
* USART_Init(USART1, &usartConfig, 20000000U);
* @endcode
*
* @param base USART peripheral base address.
* @param config Pointer to user-defined configuration structure.
* @param srcClock_Hz USART clock source frequency in HZ.
* @retval kStatus_USART_BaudrateNotSupport Baudrate is not support in current clock source.
* @retval kStatus_InvalidArgument USART base address is not valid
* @retval kStatus_Success Status USART initialize succeed
*/
status_t USART_Init(USART_Type *base, const usart_config_t *config, uint32_t srcClock_Hz);
/*!
* @brief Deinitializes a USART instance.
*
* This function waits for TX complete, disables TX and RX, and disables the USART clock.
*
* @param base USART peripheral base address.
*/
void USART_Deinit(USART_Type *base);
/*!
* @brief Gets the default configuration structure.
*
* This function initializes the USART configuration structure to a default value. The default
* values are:
* usartConfig->baudRate_Bps = 115200U;
* usartConfig->parityMode = kUSART_ParityDisabled;
* usartConfig->stopBitCount = kUSART_OneStopBit;
* usartConfig->bitCountPerChar = kUSART_8BitsPerChar;
* usartConfig->loopback = false;
* usartConfig->enableTx = false;
* usartConfig->enableRx = false;
*
* @param config Pointer to configuration structure.
*/
void USART_GetDefaultConfig(usart_config_t *config);
/*!
* @brief Sets the USART instance baud rate.
*
* This function configures the USART module baud rate. This function is used to update
* the USART module baud rate after the USART module is initialized by the USART_Init.
* @code
* USART_SetBaudRate(USART1, 115200U, 20000000U);
* @endcode
*
* @param base USART peripheral base address.
* @param baudrate_Bps USART baudrate to be set.
* @param srcClock_Hz USART clock source frequency in HZ.
* @retval kStatus_USART_BaudrateNotSupport Baudrate is not support in current clock source.
* @retval kStatus_Success Set baudrate succeed.
* @retval kStatus_InvalidArgument One or more arguments are invalid.
*/
status_t USART_SetBaudRate(USART_Type *base, uint32_t baudrate_Bps, uint32_t srcClock_Hz);
/*!
* @brief Enable 32 kHz mode which USART uses clock from the RTC oscillator as the clock source
*
* Please note that in order to use a 32 kHz clock to operate USART properly, the RTC oscillator
* and its 32 kHz output must be manully enabled by user, by calling RTC_Init and setting
* SYSCON_RTCOSCCTRL_EN bit to 1.
* And in 32kHz clocking mode the USART can only work at 9600 baudrate or at the baudrate that
* 9600 can evenly divide, eg: 4800, 3200.
*
* @param base USART peripheral base address.
* @param baudRate_Bps USART baudrate to be set..
* @param enableMode32k true is 32k mode, false is normal mode.
* @param srcClock_Hz USART clock source frequency in HZ.
* @retval kStatus_USART_BaudrateNotSupport Baudrate is not support in current clock source.
* @retval kStatus_Success Set baudrate succeed.
* @retval kStatus_InvalidArgument One or more arguments are invalid.
*/
status_t USART_Enable32kMode(USART_Type *base, uint32_t baudRate_Bps, bool enableMode32k, uint32_t srcClock_Hz);
/*!
* @brief Enable 9-bit data mode for USART.
*
* This function set the 9-bit mode for USART module. The 9th bit is not used for parity thus can be modified by user.
*
* @param base USART peripheral base address.
* @param enable true to enable, false to disable.
*/
void USART_Enable9bitMode(USART_Type *base, bool enable);
/*!
* @brief Set the USART slave address.
*
* This function configures the address for USART module that works as slave in 9-bit data mode. When the address
* detection is enabled, the frame it receices with MSB being 1 is considered as an address frame, otherwise it is
* considered as data frame. Once the address frame matches slave's own addresses, this slave is addressed. This
* address frame and its following data frames are stored in the receive buffer, otherwise the frames will be discarded.
* To un-address a slave, just send an address frame with unmatched address.
*
* @note Any USART instance joined in the multi-slave system can work as slave. The position of the address mark is the
* same as the parity bit when parity is enabled for 8 bit and 9 bit data formats.
*
* @param base USART peripheral base address.
* @param address USART slave address.
*/
static inline void USART_SetMatchAddress(USART_Type *base, uint8_t address)
{
/* Configure match address. */
base->ADDR = (uint32_t)address;
}
/*!
* @brief Enable the USART match address feature.
*
* @param base USART peripheral base address.
* @param match true to enable match address, false to disable.
*/
static inline void USART_EnableMatchAddress(USART_Type *base, bool match)
{
/* Configure match address enable bit. */
if (match)
{
base->CFG |= (uint32_t)USART_CFG_AUTOADDR_MASK;
base->CTL |= (uint32_t)USART_CTL_ADDRDET_MASK;
}
else
{
base->CFG &= ~(uint32_t)USART_CFG_AUTOADDR_MASK;
base->CTL &= ~(uint32_t)USART_CTL_ADDRDET_MASK;
}
}
/* @} */
/*!
* @name Status
* @{
*/
/*!
* @brief Get USART status flags.
*
* This function get all USART status flags, the flags are returned as the logical
* OR value of the enumerators @ref _usart_flags. To check a specific status,
* compare the return value with enumerators in @ref _usart_flags.
* For example, to check whether the TX is empty:
* @code
* if (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(USART1))
* {
* ...
* }
* @endcode
*
* @param base USART peripheral base address.
* @return USART status flags which are ORed by the enumerators in the _usart_flags.
*/
static inline uint32_t USART_GetStatusFlags(USART_Type *base)
{
return base->FIFOSTAT;
}
/*!
* @brief Clear USART status flags.
*
* This function clear supported USART status flags
* Flags that can be cleared or set are:
* kUSART_TxError
* kUSART_RxError
* For example:
* @code
* USART_ClearStatusFlags(USART1, kUSART_TxError | kUSART_RxError)
* @endcode
*
* @param base USART peripheral base address.
* @param mask status flags to be cleared.
*/
static inline void USART_ClearStatusFlags(USART_Type *base, uint32_t mask)
{
/* Only TXERR, RXERR fields support write. Remaining fields should be set to zero */
base->FIFOSTAT = mask & (USART_FIFOSTAT_TXERR_MASK | USART_FIFOSTAT_RXERR_MASK);
}
/* @} */
/*!
* @name Interrupts
* @{
*/
/*!
* @brief Enables USART interrupts according to the provided mask.
*
* This function enables the USART interrupts according to the provided mask. The mask
* is a logical OR of enumeration members. See @ref _usart_interrupt_enable.
* For example, to enable TX empty interrupt and RX full interrupt:
* @code
* USART_EnableInterrupts(USART1, kUSART_TxLevelInterruptEnable | kUSART_RxLevelInterruptEnable);
* @endcode
*
* @param base USART peripheral base address.
* @param mask The interrupts to enable. Logical OR of @ref _usart_interrupt_enable.
*/
static inline void USART_EnableInterrupts(USART_Type *base, uint32_t mask)
{
base->FIFOINTENSET = mask & 0xFUL;
}
/*!
* @brief Disables USART interrupts according to a provided mask.
*
* This function disables the USART interrupts according to a provided mask. The mask
* is a logical OR of enumeration members. See @ref _usart_interrupt_enable.
* This example shows how to disable the TX empty interrupt and RX full interrupt:
* @code
* USART_DisableInterrupts(USART1, kUSART_TxLevelInterruptEnable | kUSART_RxLevelInterruptEnable);
* @endcode
*
* @param base USART peripheral base address.
* @param mask The interrupts to disable. Logical OR of @ref _usart_interrupt_enable.
*/
static inline void USART_DisableInterrupts(USART_Type *base, uint32_t mask)
{
base->FIFOINTENCLR = mask & 0xFUL;
}
/*!
* @brief Returns enabled USART interrupts.
*
* This function returns the enabled USART interrupts.
*
* @param base USART peripheral base address.
*/
static inline uint32_t USART_GetEnabledInterrupts(USART_Type *base)
{
return base->FIFOINTENSET;
}
/*!
* @brief Enable DMA for Tx
*/
static inline void USART_EnableTxDMA(USART_Type *base, bool enable)
{
if (enable)
{
base->FIFOCFG |= USART_FIFOCFG_DMATX_MASK;
}
else
{
base->FIFOCFG &= ~(USART_FIFOCFG_DMATX_MASK);
}
}
/*!
* @brief Enable DMA for Rx
*/
static inline void USART_EnableRxDMA(USART_Type *base, bool enable)
{
if (enable)
{
base->FIFOCFG |= USART_FIFOCFG_DMARX_MASK;
}
else
{
base->FIFOCFG &= ~(USART_FIFOCFG_DMARX_MASK);
}
}
/*!
* @brief Enable CTS.
* This function will determine whether CTS is used for flow control.
*
* @param base USART peripheral base address.
* @param enable Enable CTS or not, true for enable and false for disable.
*/
static inline void USART_EnableCTS(USART_Type *base, bool enable)
{
if (enable)
{
base->CFG |= USART_CFG_CTSEN_MASK;
}
else
{
base->CFG &= ~USART_CFG_CTSEN_MASK;
}
}
/*!
* @brief Continuous Clock generation.
* By default, SCLK is only output while data is being transmitted in synchronous mode.
* Enable this funciton, SCLK will run continuously in synchronous mode, allowing
* characters to be received on Un_RxD independently from transmission on Un_TXD).
*
* @param base USART peripheral base address.
* @param enable Enable Continuous Clock generation mode or not, true for enable and false for disable.
*/
static inline void USART_EnableContinuousSCLK(USART_Type *base, bool enable)
{
if (enable)
{
base->CTL |= USART_CTL_CC_MASK;
}
else
{
base->CTL &= ~USART_CTL_CC_MASK;
}
}
/*!
* @brief Enable Continuous Clock generation bit auto clear.
* While enable this cuntion, the Continuous Clock bit is automatically cleared when a complete
* character has been received. This bit is cleared at the same time.
*
* @param base USART peripheral base address.
* @param enable Enable auto clear or not, true for enable and false for disable.
*/
static inline void USART_EnableAutoClearSCLK(USART_Type *base, bool enable)
{
if (enable)
{
base->CTL |= USART_CTL_CLRCCONRX_MASK;
}
else
{
base->CTL &= ~USART_CTL_CLRCCONRX_MASK;
}
}
/*!
* @brief Sets the rx FIFO watermark.
*
* @param base USART peripheral base address.
* @param water Rx FIFO watermark.
*/
static inline void USART_SetRxFifoWatermark(USART_Type *base, uint8_t water)
{
assert(water <= (USART_FIFOTRIG_RXLVL_MASK >> USART_FIFOTRIG_RXLVL_SHIFT));
base->FIFOTRIG = (base->FIFOTRIG & ~USART_FIFOTRIG_RXLVL_MASK) | USART_FIFOTRIG_RXLVL(water);
}
/*!
* @brief Sets the tx FIFO watermark.
*
* @param base USART peripheral base address.
* @param water Tx FIFO watermark.
*/
static inline void USART_SetTxFifoWatermark(USART_Type *base, uint8_t water)
{
assert(water <= (USART_FIFOTRIG_TXLVL_MASK >> USART_FIFOTRIG_TXLVL_SHIFT));
base->FIFOTRIG = (base->FIFOTRIG & ~USART_FIFOTRIG_TXLVL_MASK) | USART_FIFOTRIG_TXLVL(water);
}
/* @} */
/*!
* @name Bus Operations
* @{
*/
/*!
* @brief Writes to the FIFOWR register.
*
* This function writes data to the txFIFO directly. The upper layer must ensure
* that txFIFO has space for data to write before calling this function.
*
* @param base USART peripheral base address.
* @param data The byte to write.
*/
static inline void USART_WriteByte(USART_Type *base, uint8_t data)
{
base->FIFOWR = data;
}
/*!
* @brief Reads the FIFORD register directly.
*
* This function reads data from the rxFIFO directly. The upper layer must
* ensure that the rxFIFO is not empty before calling this function.
*
* @param base USART peripheral base address.
* @return The byte read from USART data register.
*/
static inline uint8_t USART_ReadByte(USART_Type *base)
{
return (uint8_t)base->FIFORD;
}
/*!
* @brief Gets the rx FIFO data count.
*
* @param base USART peripheral base address.
* @return rx FIFO data count.
*/
static inline uint8_t USART_GetRxFifoCount(USART_Type *base)
{
return (uint8_t)((base->FIFOSTAT & USART_FIFOSTAT_RXLVL_MASK) >> USART_FIFOSTAT_RXLVL_SHIFT);
}
/*!
* @brief Gets the tx FIFO data count.
*
* @param base USART peripheral base address.
* @return tx FIFO data count.
*/
static inline uint8_t USART_GetTxFifoCount(USART_Type *base)
{
return (uint8_t)((base->FIFOSTAT & USART_FIFOSTAT_TXLVL_MASK) >> USART_FIFOSTAT_TXLVL_SHIFT);
}
/*!
* @brief Transmit an address frame in 9-bit data mode.
*
* @param base USART peripheral base address.
* @param address USART slave address.
*/
void USART_SendAddress(USART_Type *base, uint8_t address);
/*!
* @brief Writes to the TX register using a blocking method.
*
* This function polls the TX register, waits for the TX register to be empty or for the TX FIFO
* to have room and writes data to the TX buffer.
*
* @param base USART peripheral base address.
* @param data Start address of the data to write.
* @param length Size of the data to write.
* @retval kStatus_USART_Timeout Transmission timed out and was aborted.
* @retval kStatus_InvalidArgument Invalid argument.
* @retval kStatus_Success Successfully wrote all data.
*/
status_t USART_WriteBlocking(USART_Type *base, const uint8_t *data, size_t length);
/*!
* @brief Read RX data register using a blocking method.
*
* This function polls the RX register, waits for the RX register to be full or for RX FIFO to
* have data and read data from the TX register.
*
* @param base USART peripheral base address.
* @param data Start address of the buffer to store the received data.
* @param length Size of the buffer.
* @retval kStatus_USART_FramingError Receiver overrun happened while receiving data.
* @retval kStatus_USART_ParityError Noise error happened while receiving data.
* @retval kStatus_USART_NoiseError Framing error happened while receiving data.
* @retval kStatus_USART_RxError Overflow or underflow rxFIFO happened.
* @retval kStatus_USART_Timeout Transmission timed out and was aborted.
* @retval kStatus_Success Successfully received all data.
*/
status_t USART_ReadBlocking(USART_Type *base, uint8_t *data, size_t length);
/* @} */
/*!
* @name Transactional
* @{
*/
/*!
* @brief Initializes the USART handle.
*
* This function initializes the USART handle which can be used for other USART
* transactional APIs. Usually, for a specified USART instance,
* call this API once to get the initialized handle.
*
* @param base USART peripheral base address.
* @param handle USART handle pointer.
* @param callback The callback function.
* @param userData The parameter of the callback function.
*/
status_t USART_TransferCreateHandle(USART_Type *base,
usart_handle_t *handle,
usart_transfer_callback_t callback,
void *userData);
/*!
* @brief Transmits a buffer of data using the interrupt method.
*
* This function sends data using an interrupt method. This is a non-blocking function, which
* returns directly without waiting for all data to be written to the TX register. When
* all data is written to the TX register in the IRQ handler, the USART driver calls the callback
* function and passes the @ref kStatus_USART_TxIdle as status parameter.
*
* @note The kStatus_USART_TxIdle is passed to the upper layer when all data is written
* to the TX register. However it does not ensure that all data are sent out. Before disabling the TX,
* check the kUSART_TransmissionCompleteFlag to ensure that the TX is finished.
*
* @param base USART peripheral base address.
* @param handle USART handle pointer.
* @param xfer USART transfer structure. See #usart_transfer_t.
* @retval kStatus_Success Successfully start the data transmission.
* @retval kStatus_USART_TxBusy Previous transmission still not finished, data not all written to TX register yet.
* @retval kStatus_InvalidArgument Invalid argument.
*/
status_t USART_TransferSendNonBlocking(USART_Type *base, usart_handle_t *handle, usart_transfer_t *xfer);
/*!
* @brief Sets up the RX ring buffer.
*
* This function sets up the RX ring buffer to a specific USART handle.
*
* When the RX ring buffer is used, data received are stored into the ring buffer even when the
* user doesn't call the USART_TransferReceiveNonBlocking() API. If there is already data received
* in the ring buffer, the user can get the received data from the ring buffer directly.
*
* @note When using the RX ring buffer, one byte is reserved for internal use. In other
* words, if @p ringBufferSize is 32, then only 31 bytes are used for saving data.
*
* @param base USART peripheral base address.
* @param handle USART handle pointer.
* @param ringBuffer Start address of the ring buffer for background receiving. Pass NULL to disable the ring buffer.
* @param ringBufferSize size of the ring buffer.
*/
void USART_TransferStartRingBuffer(USART_Type *base,
usart_handle_t *handle,
uint8_t *ringBuffer,
size_t ringBufferSize);
/*!
* @brief Aborts the background transfer and uninstalls the ring buffer.
*
* This function aborts the background transfer and uninstalls the ring buffer.
*
* @param base USART peripheral base address.
* @param handle USART handle pointer.
*/
void USART_TransferStopRingBuffer(USART_Type *base, usart_handle_t *handle);
/*!
* @brief Get the length of received data in RX ring buffer.
*
* @param handle USART handle pointer.
* @return Length of received data in RX ring buffer.
*/
size_t USART_TransferGetRxRingBufferLength(usart_handle_t *handle);
/*!
* @brief Aborts the interrupt-driven data transmit.
*
* This function aborts the interrupt driven data sending. The user can get the remainBtyes to find out
* how many bytes are still not sent out.
*
* @param base USART peripheral base address.
* @param handle USART handle pointer.
*/
void USART_TransferAbortSend(USART_Type *base, usart_handle_t *handle);
/*!
* @brief Get the number of bytes that have been sent out to bus.
*
* This function gets the number of bytes that have been sent out to bus by interrupt method.
*
* @param base USART peripheral base address.
* @param handle USART handle pointer.
* @param count Send bytes count.
* @retval kStatus_NoTransferInProgress No send in progress.
* @retval kStatus_InvalidArgument Parameter is invalid.
* @retval kStatus_Success Get successfully through the parameter \p count;
*/
status_t USART_TransferGetSendCount(USART_Type *base, usart_handle_t *handle, uint32_t *count);
/*!
* @brief Receives a buffer of data using an interrupt method.
*
* This function receives data using an interrupt method. This is a non-blocking function, which
* returns without waiting for all data to be received.
* If the RX ring buffer is used and not empty, the data in the ring buffer is copied and
* the parameter @p receivedBytes shows how many bytes are copied from the ring buffer.
* After copying, if the data in the ring buffer is not enough to read, the receive
* request is saved by the USART driver. When the new data arrives, the receive request
* is serviced first. When all data is received, the USART driver notifies the upper layer
* through a callback function and passes the status parameter @ref kStatus_USART_RxIdle.
* For example, the upper layer needs 10 bytes but there are only 5 bytes in the ring buffer.
* The 5 bytes are copied to the xfer->data and this function returns with the
* parameter @p receivedBytes set to 5. For the left 5 bytes, newly arrived data is
* saved from the xfer->data[5]. When 5 bytes are received, the USART driver notifies the upper layer.
* If the RX ring buffer is not enabled, this function enables the RX and RX interrupt
* to receive data to the xfer->data. When all data is received, the upper layer is notified.
*
* @param base USART peripheral base address.
* @param handle USART handle pointer.
* @param xfer USART transfer structure, see #usart_transfer_t.
* @param receivedBytes Bytes received from the ring buffer directly.
* @retval kStatus_Success Successfully queue the transfer into transmit queue.
* @retval kStatus_USART_RxBusy Previous receive request is not finished.
* @retval kStatus_InvalidArgument Invalid argument.
*/
status_t USART_TransferReceiveNonBlocking(USART_Type *base,
usart_handle_t *handle,
usart_transfer_t *xfer,
size_t *receivedBytes);
/*!
* @brief Aborts the interrupt-driven data receiving.
*
* This function aborts the interrupt-driven data receiving. The user can get the remainBytes to find out
* how many bytes not received yet.
*
* @param base USART peripheral base address.
* @param handle USART handle pointer.
*/
void USART_TransferAbortReceive(USART_Type *base, usart_handle_t *handle);
/*!
* @brief Get the number of bytes that have been received.
*
* This function gets the number of bytes that have been received.
*
* @param base USART peripheral base address.
* @param handle USART handle pointer.
* @param count Receive bytes count.
* @retval kStatus_NoTransferInProgress No receive in progress.
* @retval kStatus_InvalidArgument Parameter is invalid.
* @retval kStatus_Success Get successfully through the parameter \p count;
*/
status_t USART_TransferGetReceiveCount(USART_Type *base, usart_handle_t *handle, uint32_t *count);
/*!
* @brief USART IRQ handle function.
*
* This function handles the USART transmit and receive IRQ request.
*
* @param base USART peripheral base address.
* @param handle USART handle pointer.
*/
void USART_TransferHandleIRQ(USART_Type *base, usart_handle_t *handle);
/* @} */
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* _FSL_USART_H_ */

View file

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="com.crt.dsfdebug.crtmcu.launchType">
<stringAttribute key=".gdbinit" value=""/>
<booleanAttribute key="attach" value="false"/>
<stringAttribute key="bootrom.stall" value="0x50002034"/>
<stringAttribute key="com.crt.ctrlcenter.OFSemuDetails" value="LinkServer"/>
<booleanAttribute key="com.crt.ctrlcenter.crtInit" value="true"/>
<stringAttribute key="com.crt.ctrlcenter.currentWireType" value="SWD"/>
<booleanAttribute key="com.crt.ctrlcenter.mainBreakIsHardware" value="true"/>
<stringAttribute key="com.crt.ctrlcenter.serialNumber" value="LinkServerNXP SemiconductorsLPC-LINK2 CMSIS-DAP V5.361FRAQBQAR"/>
<mapAttribute key="com.crt.ctrlcenter.symbolsGroupSettings"/>
<intAttribute key="com.crt.ctrlcenter.version" value="6"/>
<stringAttribute key="com.nxp.mcuxpresso.flash.base.address" value="0x8000000"/>
<booleanAttribute key="com.nxp.mcuxpresso.flash.clear.console" value="true"/>
<booleanAttribute key="com.nxp.mcuxpresso.flash.confirm" value="false"/>
<stringAttribute key="com.nxp.mcuxpresso.flash.erase.algorithm" value="Mass erase"/>
<stringAttribute key="com.nxp.mcuxpresso.flash.executable" value="axf"/>
<stringAttribute key="com.nxp.mcuxpresso.flash.program.action" value="Program"/>
<booleanAttribute key="com.nxp.mcuxpresso.flash.reset.target" value="true"/>
<stringAttribute key="com.nxp.mcuxpresso.ide.probe.manufacturer" value="NXP Semiconductors"/>
<stringAttribute key="com.nxp.mcuxpresso.ide.probe.name" value="LPC-LINK2 CMSIS-DAP V5.361"/>
<stringAttribute key="com.nxp.mcuxpresso.ide.probe.type" value="LinkServer"/>
<stringAttribute key="debug.level" value="2"/>
<stringAttribute key="emu.speed" value=""/>
<stringAttribute key="flash.driver.reset" value=""/>
<booleanAttribute key="internal.attach.slave" value="false"/>
<booleanAttribute key="internal.cache" value="false"/>
<stringAttribute key="internal.connect.script" value="RT500_connect.scp"/>
<stringAttribute key="internal.core.index" value=""/>
<booleanAttribute key="internal.has_swo" value="true"/>
<booleanAttribute key="internal.multi.swd" value="true"/>
<stringAttribute key="internal.prelaunch.command" value=""/>
<stringAttribute key="internal.reset.script" value=""/>
<stringAttribute key="internal.resethandling" value=""/>
<stringAttribute key="internal.semihost" value="On"/>
<stringAttribute key="internal.wirespeed" value=""/>
<stringAttribute key="internal.wiretype" value="SWD"/>
<stringAttribute key="launch.config.handler" value="com.crt.ctrlcenter.launch.CRTLaunchConfigHandler"/>
<booleanAttribute key="mem.access" value="false"/>
<stringAttribute key="misc.options" value=""/>
<stringAttribute key="ondisconnect" value="cont"/>
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.delay" value="0"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doHalt" value="false"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doReset" value="false"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value=""/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.initCommands" value="set non-stop on&#10;set pagination off&#10;set mi-async&#10;set remotetimeout 60000&#10;##target_extended_remote##&#10;set mem inaccessible-by-default ${mem.access}&#10;mon ondisconnect ${ondisconnect}&#10;set arm force-mode thumb&#10;${load}"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="true"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.runCommands" value="${run}"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="false"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="true"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value="main"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value=""/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true"/>
<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="arm-none-eabi-gdb"/>
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_ON_FORK" value="false"/>
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.EXTERNAL_CONSOLE" value="false"/>
<stringAttribute key="org.eclipse.cdt.dsf.gdb.GDB_INIT" value=""/>
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.NON_STOP" value="true"/>
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.REVERSE" value="false"/>
<stringAttribute key="org.eclipse.cdt.dsf.gdb.REVERSE_MODE" value="UseSoftTrace"/>
<stringAttribute key="org.eclipse.cdt.dsf.gdb.TRACEPOINT_MODE" value="TP_NORMAL_ONLY"/>
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.UPDATE_THREADLIST_ON_SUSPEND" value="false"/>
<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/>
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_ID" value="gdb"/>
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_START_MODE" value="remote"/>
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="Debug/evkmimxrt595_dev_composite_cdc_vcom_cdc_vcom_bm.axf"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="evkmimxrt595_dev_composite_cdc_vcom_cdc_vcom_bm"/>
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="false"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="com.crt.advproject.config.exe.debug.1881597443"/>
<booleanAttribute key="org.eclipse.cdt.launch.use_terminal" value="false"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/evkmimxrt595_dev_composite_cdc_vcom_cdc_vcom_bm"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/>
</listAttribute>
<mapAttribute key="org.eclipse.debug.core.preferred_launchers">
<mapEntry key="[debug]" value="com.nxp.mcuxpresso.core.debug.support.linkserver.launch.LinkServerGdbLaunch"/>
</mapAttribute>
<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&lt;memoryBlockExpressionList context=&quot;reserved-for-future-use&quot;/&gt;"/>
<stringAttribute key="process_factory_id" value="com.nxp.mcuxpresso.core.debug.override.MCXProcessFactory"/>
<booleanAttribute key="redlink.disable.preconnect.script" value="false"/>
<booleanAttribute key="redlink.enable.flashhashing" value="true"/>
<booleanAttribute key="redlink.enable.rangestepping" value="true"/>
<stringAttribute key="run" value="cont"/>
<booleanAttribute key="vector.catch" value="false"/>
</launchConfiguration>

View file

@ -0,0 +1,79 @@
/*
* Copyright 2018-2019 NXP
* All rights reserved.
*
* SPDXLicense-Identifier: BSD-3-Clause
*/
#include "flash_config.h"
#include "board.h"
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.flash_config"
#endif
/*******************************************************************************
* Code
******************************************************************************/
#if defined(BOOT_HEADER_ENABLE) && (BOOT_HEADER_ENABLE == 1)
#if defined(__ARMCC_VERSION) || defined(__GNUC__)
__attribute__((section(".flash_conf"), used))
#elif defined(__ICCARM__)
#pragma location = ".flash_conf"
#endif
const flexspi_nor_config_t flash_config = {
.memConfig =
{
.tag = FLEXSPI_CFG_BLK_TAG,
.version = FLEXSPI_CFG_BLK_VERSION,
.readSampleClkSrc = kFlexSPIReadSampleClk_ExternalInputFromDqsPad,
.csHoldTime = 3,
.csSetupTime = 3,
.deviceModeCfgEnable = 1,
.deviceModeType = kDeviceConfigCmdType_Spi2Xpi,
.waitTimeCfgCommands = 1,
.deviceModeSeq =
{
.seqNum = 1,
.seqId = 6, /* See Lookup table for more details */
.reserved = 0,
},
.deviceModeArg = 2, /* Enable OPI DDR mode */
.controllerMiscOption =
(1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DdrModeEnable),
.deviceType = kFlexSpiDeviceType_SerialNOR,
.sflashPadType = kSerialFlash_8Pads,
.serialClkFreq = kFlexSpiSerialClk_80MHz,
.sflashA1Size = 64ul * 1024u * 1024u,
.dataValidTime =
{
[0] = {.time_100ps = 16},
},
.busyOffset = 0u,
.busyBitPolarity = 0u,
.lookupTable =
{
/* Read */
[0] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0xEE, CMD_DDR, FLEXSPI_8PAD, 0x11),
[1] = FLEXSPI_LUT_SEQ(RADDR_DDR, FLEXSPI_8PAD, 0x20, DUMMY_DDR, FLEXSPI_8PAD, 0x04),
[2] = FLEXSPI_LUT_SEQ(READ_DDR, FLEXSPI_8PAD, 0x04, STOP_EXE, FLEXSPI_1PAD, 0x00),
/* Read Status */
[4 * 1 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x04),
/* Write Enable */
[4 * 3 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP_EXE, FLEXSPI_1PAD, 0x00),
/* Enable OPI DDR mode */
[4 * 6 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x72, CMD_SDR, FLEXSPI_1PAD, 0x00),
[4 * 6 + 1] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x00, CMD_SDR, FLEXSPI_1PAD, 0x00),
[4 * 6 + 2] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x00, WRITE_SDR, FLEXSPI_1PAD, 0x01),
},
},
.pageSize = 256u,
.sectorSize = 4u * 1024u,
.blockSize = 64u * 1024u,
.flashStateCtx = 0x07008200u,
};
#endif /* BOOT_HEADER_ENABLE */

View file

@ -0,0 +1,101 @@
/*
* Copyright 2018-2019 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef __FLASH_CONFIG_H__
#define __FLASH_CONFIG_H__
#include <stdint.h>
#include "fsl_iap.h"
/*! @name Driver version */
/*@{*/
/*! @brief FLASH_CONFIG driver version 2.0.0. */
#define FSL_FLASH_CONFIG_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
/*@}*/
/*******************************************************************************
* Definition
******************************************************************************/
/* FLEXSPI memory config block related defintions */
#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) /* ascii "FCFB" Big Endian */
#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) /* V1.4.0 */
/* !@brief FLEXSPI clock configuration - When clock source is PLL */
enum
{
kFlexSpiSerialClk_30MHz = 1,
kFlexSpiSerialClk_50MHz = 2,
kFlexSpiSerialClk_60MHz = 3,
kFlexSpiSerialClk_80MHz = 4,
kFlexSpiSerialClk_100MHz = 5,
kFlexSpiSerialClk_120MHz = 6,
kFlexSpiSerialClk_133MHz = 7,
kFlexSpiSerialClk_166MHz = 8,
kFlexSpiSerialClk_200MHz = 9,
};
/* !@brief LUT instructions supported by FLEXSPI */
#define CMD_SDR 0x01
#define CMD_DDR 0x21
#define RADDR_SDR 0x02
#define RADDR_DDR 0x22
#define CADDR_SDR 0x03
#define CADDR_DDR 0x23
#define MODE1_SDR 0x04
#define MODE1_DDR 0x24
#define MODE2_SDR 0x05
#define MODE2_DDR 0x25
#define MODE4_SDR 0x06
#define MODE4_DDR 0x26
#define MODE8_SDR 0x07
#define MODE8_DDR 0x27
#define WRITE_SDR 0x08
#define WRITE_DDR 0x28
#define READ_SDR 0x09
#define READ_DDR 0x29
#define LEARN_SDR 0x0A
#define LEARN_DDR 0x2A
#define DATSZ_SDR 0x0B
#define DATSZ_DDR 0x2B
#define DUMMY_SDR 0x0C
#define DUMMY_DDR 0x2C
#define DUMMY_RWDS_SDR 0x0D
#define DUMMY_RWDS_DDR 0x2D
#define JMP_ON_CS 0x1F
#define STOP_EXE 0
#define FLEXSPI_1PAD 0
#define FLEXSPI_2PAD 1
#define FLEXSPI_4PAD 2
#define FLEXSPI_8PAD 3
#define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \
(FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \
FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1))
/* !@brief FlexSPI Read Sample Clock Source definition */
typedef enum _FlashReadSampleClkSource
{
kFlexSPIReadSampleClk_LoopbackInternally = 0,
kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1,
kFlexSPIReadSampleClk_LoopbackFromSckPad = 2,
kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3,
} flexspi_read_sample_clk_t;
/* !@brief Misc feature bit definitions */
enum
{
kFlexSpiMiscOffset_DiffClkEnable = 0, /* !< Bit for Differential clock enable */
kFlexSpiMiscOffset_ParallelEnable = 2, /* !< Bit for Parallel mode enable */
kFlexSpiMiscOffset_WordAddressableEnable = 3, /* !< Bit for Word Addressable enable */
kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, /* !< Bit for Safe Configuration Frequency enable */
kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, /* !< Bit for Pad setting override enable */
kFlexSpiMiscOffset_DdrModeEnable = 6, /* !< Bit for DDR clock confiuration indication. */
kFlexSpiMiscOffset_UseValidTimeForAllFreq = 7, /* !< Bit for DLLCR settings under all modes */
};
#endif

View file

@ -0,0 +1,379 @@
/*
* Copyright 2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "usb_device_config.h"
#include "usb.h"
#include "usb_device.h"
#include "usb_device_class.h"
#include "usb_device_cdc_acm.h"
#include "usb_device_ch9.h"
#include "usb_device_descriptor.h"
#include "fsl_device_registers.h"
#include "fsl_debug_console.h"
#include "composite.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
#if (defined(FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT > 0U))
#include "fsl_sysmpu.h"
#endif /* FSL_FEATURE_SOC_SYSMPU_COUNT */
#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
#include "usb_phy.h"
#endif
#include "fsl_power.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* Prototypes
******************************************************************************/
void BOARD_InitHardware(void);
void USB_DeviceClockInit(void);
void USB_DeviceIsrEnable(void);
#if USB_DEVICE_CONFIG_USE_TASK
void USB_DeviceTaskFn(void *deviceHandle);
#endif
/*!
* @brief USB device callback function.
*
* This function handles the usb device specific requests.
*
* @param handle The USB device handle.
* @param event The USB device event type.
* @param param The parameter of the device specific request.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceCallback(usb_device_handle handle, uint32_t event, void *param);
/*******************************************************************************
* Variables
******************************************************************************/
/* Composite device structure. */
usb_device_composite_struct_t g_composite;
extern usb_device_class_struct_t g_UsbDeviceCdcVcomConfig[2];
/* USB device class information */
usb_device_class_config_struct_t g_CompositeClassConfig[2] = {{
USB_DeviceCdcVcomCallback,
(class_handle_t)NULL,
&g_UsbDeviceCdcVcomConfig[0],
},
{
USB_DeviceCdcVcomCallback,
(class_handle_t)NULL,
&g_UsbDeviceCdcVcomConfig[1],
}};
/* USB device class configuration information */
usb_device_class_config_list_struct_t g_UsbDeviceCompositeConfigList = {
g_CompositeClassConfig,
USB_DeviceCallback,
2,
};
/*******************************************************************************
* Code
******************************************************************************/
void USB0_IRQHandler(void)
{
USB_DeviceLpcIp3511IsrFunction(g_composite.deviceHandle);
}
void USB_DeviceClockInit(void)
{
uint8_t usbClockDiv = 1;
uint32_t usbClockFreq;
usb_phy_config_struct_t phyConfig = {
BOARD_USB_PHY_D_CAL,
BOARD_USB_PHY_TXCAL45DP,
BOARD_USB_PHY_TXCAL45DM,
};
/* Make sure USDHC ram buffer and usb1 phy has power up */
POWER_DisablePD(kPDRUNCFG_APD_USBHS_SRAM);
POWER_DisablePD(kPDRUNCFG_PPD_USBHS_SRAM);
POWER_DisablePD(kPDRUNCFG_LP_HSPAD_FSPI0_VDET);
POWER_ApplyPD();
RESET_PeripheralReset(kUSBHS_PHY_RST_SHIFT_RSTn);
RESET_PeripheralReset(kUSBHS_DEVICE_RST_SHIFT_RSTn);
RESET_PeripheralReset(kUSBHS_HOST_RST_SHIFT_RSTn);
RESET_PeripheralReset(kUSBHS_SRAM_RST_SHIFT_RSTn);
/* enable usb ip clock */
CLOCK_EnableUsbHs0DeviceClock(kOSC_CLK_to_USB_CLK, usbClockDiv);
/* save usb ip clock freq*/
usbClockFreq = g_xtalFreq / usbClockDiv;
CLOCK_SetClkDiv(kCLOCK_DivPfc1Clk, 4);
/* enable usb ram clock */
CLOCK_EnableClock(kCLOCK_UsbhsSram);
/* enable USB PHY PLL clock, the phy bus clock (480MHz) source is same with USB IP */
CLOCK_EnableUsbHs0PhyPllClock(kOSC_CLK_to_USB_CLK, usbClockFreq);
/* USB PHY initialization */
USB_EhciPhyInit(CONTROLLER_ID, BOARD_XTAL_SYS_CLK_HZ, &phyConfig);
#if defined(FSL_FEATURE_USBHSD_USB_RAM) && (FSL_FEATURE_USBHSD_USB_RAM)
for (int i = 0; i < FSL_FEATURE_USBHSD_USB_RAM; i++)
{
((uint8_t *)FSL_FEATURE_USBHSD_USB_RAM_BASE_ADDRESS)[i] = 0x00U;
}
#endif
/* the following code should run after phy initialization and should wait some microseconds to make sure utmi clock
* valid */
/* enable usb1 host clock */
CLOCK_EnableClock(kCLOCK_UsbhsHost);
/* Wait until host_needclk de-asserts */
while (SYSCTL0->USB0CLKSTAT & SYSCTL0_USB0CLKSTAT_HOST_NEED_CLKST_MASK)
{
__ASM("nop");
}
/*According to reference mannual, device mode setting has to be set by access usb host register */
USBHSH->PORTMODE |= USBHSH_PORTMODE_DEV_ENABLE_MASK;
/* disable usb1 host clock */
CLOCK_DisableClock(kCLOCK_UsbhsHost);
}
void USB_DeviceIsrEnable(void)
{
uint8_t irqNumber;
uint8_t usbDeviceIP3511Irq[] = USBHSD_IRQS;
irqNumber = usbDeviceIP3511Irq[CONTROLLER_ID - kUSB_ControllerLpcIp3511Hs0];
/* Install isr, set priority, and enable IRQ. */
NVIC_SetPriority((IRQn_Type)irqNumber, USB_DEVICE_INTERRUPT_PRIORITY);
EnableIRQ((IRQn_Type)irqNumber);
}
#if USB_DEVICE_CONFIG_USE_TASK
void USB_DeviceTaskFn(void *deviceHandle)
{
USB_DeviceLpcIp3511TaskFunction(deviceHandle);
}
#endif
/*!
* @brief USB device callback function.
*
* This function handles the usb device specific requests.
*
* @param handle The USB device handle.
* @param event The USB device event type.
* @param param The parameter of the device specific request.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceCallback(usb_device_handle handle, uint32_t event, void *param)
{
usb_status_t error = kStatus_USB_InvalidRequest;
uint16_t *temp16 = (uint16_t *)param;
uint8_t *temp8 = (uint8_t *)param;
switch (event)
{
case kUSB_DeviceEventBusReset:
{
g_composite.attach = 0;
g_composite.currentConfiguration = 0U;
error = kStatus_USB_Success;
for (uint8_t i = 0; i < USB_DEVICE_CONFIG_CDC_ACM; i++)
{
g_composite.cdcVcom[i].recvSize = 0;
g_composite.cdcVcom[i].sendSize = 0;
g_composite.cdcVcom[i].attach = 0;
}
#if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)) || \
(defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))
/* Get USB speed to configure the device, including max packet size and interval of the endpoints. */
if (kStatus_USB_Success == USB_DeviceClassGetSpeed(CONTROLLER_ID, &g_composite.speed))
{
USB_DeviceSetSpeed(handle, g_composite.speed);
}
#endif
}
break;
case kUSB_DeviceEventSetConfiguration:
if (0U == (*temp8))
{
g_composite.attach = 0U;
g_composite.currentConfiguration = 0U;
error = kStatus_USB_Success;
for (uint8_t i = 0; i < USB_DEVICE_CONFIG_CDC_ACM; i++)
{
g_composite.cdcVcom[i].recvSize = 0;
g_composite.cdcVcom[i].sendSize = 0;
g_composite.cdcVcom[i].attach = 0;
}
}
else if (USB_COMPOSITE_CONFIGURE_INDEX == (*temp8))
{
g_composite.attach = 1;
USB_DeviceCdcVcomSetConfigure(g_composite.cdcVcom[0].cdcAcmHandle, *temp8);
g_composite.currentConfiguration = *temp8;
error = kStatus_USB_Success;
}
else
{
/* no action, return kStatus_USB_InvalidRequest */
}
break;
case kUSB_DeviceEventSetInterface:
if (g_composite.attach)
{
uint8_t interface = (uint8_t)((*temp16 & 0xFF00U) >> 0x08U);
uint8_t alternateSetting = (uint8_t)(*temp16 & 0x00FFU);
if (interface == USB_CDC_VCOM_CIC_INTERFACE_INDEX)
{
if (alternateSetting < USB_CDC_VCOM_CIC_INTERFACE_ALTERNATE_COUNT)
{
g_composite.currentInterfaceAlternateSetting[interface] = alternateSetting;
error = kStatus_USB_Success;
}
}
else if (interface == USB_CDC_VCOM_DIC_INTERFACE_INDEX)
{
if (alternateSetting < USB_CDC_VCOM_DIC_INTERFACE_ALTERNATE_COUNT)
{
g_composite.currentInterfaceAlternateSetting[interface] = alternateSetting;
error = kStatus_USB_Success;
}
}
else if (interface == USB_CDC_VCOM_CIC_INTERFACE_INDEX_2)
{
if (alternateSetting < USB_CDC_VCOM_CIC_INTERFACE_2_ALTERNATE_COUNT)
{
g_composite.currentInterfaceAlternateSetting[interface] = alternateSetting;
error = kStatus_USB_Success;
}
}
else if (interface == USB_CDC_VCOM_DIC_INTERFACE_INDEX_2)
{
if (alternateSetting < USB_CDC_VCOM_DIC_INTERFACE_2_ALTERNATE_COUNT)
{
g_composite.currentInterfaceAlternateSetting[interface] = alternateSetting;
error = kStatus_USB_Success;
}
}
else
{
/* no action, return kStatus_USB_InvalidRequest */
}
}
break;
case kUSB_DeviceEventGetConfiguration:
if (param)
{
*temp8 = g_composite.currentConfiguration;
error = kStatus_USB_Success;
}
break;
case kUSB_DeviceEventGetInterface:
if (param)
{
uint8_t interface = (uint8_t)((*temp16 & 0xFF00U) >> 0x08U);
if (interface < USB_INTERFACE_COUNT)
{
*temp16 = (*temp16 & 0xFF00U) | g_composite.currentInterfaceAlternateSetting[interface];
error = kStatus_USB_Success;
}
}
break;
case kUSB_DeviceEventGetDeviceDescriptor:
if (param)
{
error = USB_DeviceGetDeviceDescriptor(handle, (usb_device_get_device_descriptor_struct_t *)param);
}
break;
case kUSB_DeviceEventGetConfigurationDescriptor:
if (param)
{
error = USB_DeviceGetConfigurationDescriptor(handle,
(usb_device_get_configuration_descriptor_struct_t *)param);
}
break;
#if (defined(USB_DEVICE_CONFIG_CV_TEST) && (USB_DEVICE_CONFIG_CV_TEST > 0U))
case kUSB_DeviceEventGetDeviceQualifierDescriptor:
if (param)
{
/* Get device descriptor request */
error = USB_DeviceGetDeviceQualifierDescriptor(
handle, (usb_device_get_device_qualifier_descriptor_struct_t *)param);
}
break;
#endif
case kUSB_DeviceEventGetStringDescriptor:
if (param)
{
error = USB_DeviceGetStringDescriptor(handle, (usb_device_get_string_descriptor_struct_t *)param);
}
break;
default:
break;
}
return error;
}
/*!
* @brief Application initialization function.
*
* This function initializes the application.
*
* @return None.
*/
void USB_DeviceApplicationInit(void)
{
USB_DeviceClockInit();
#if (defined(FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT > 0U))
SYSMPU_Enable(SYSMPU, 0);
#endif /* FSL_FEATURE_SOC_SYSMPU_COUNT */
g_composite.speed = USB_SPEED_FULL;
g_composite.attach = 0;
for (uint8_t i = 0; i < USB_DEVICE_CONFIG_CDC_ACM; i++)
{
g_composite.cdcVcom[i].cdcAcmHandle = (class_handle_t)NULL;
}
g_composite.deviceHandle = NULL;
if (kStatus_USB_Success !=
USB_DeviceClassInit(CONTROLLER_ID, &g_UsbDeviceCompositeConfigList, &g_composite.deviceHandle))
{
usb_echo("USB device composite demo init failed\r\n");
return;
}
else
{
usb_echo("USB device composite demo\r\n");
/*Init classhandle in cdc instance*/
for (uint8_t i = 0; i < USB_DEVICE_CONFIG_CDC_ACM; i++)
{
g_composite.cdcVcom[i].cdcAcmHandle = g_UsbDeviceCompositeConfigList.config[i].classHandle;
}
USB_DeviceCdcVcomInit(&g_composite);
}
USB_DeviceIsrEnable();
/*Add one delay here to make the DP pull down long enough to allow host to detect the previous disconnection.*/
SDK_DelayAtLeastUs(5000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
USB_DeviceRun(g_composite.deviceHandle);
}

View file

@ -0,0 +1,87 @@
/*
* Copyright 2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _USB_DEVICE_COMPOSITE_H_
#define _USB_DEVICE_COMPOSITE_H_ 1
#include "virtual_com.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0)
#define CONTROLLER_ID kUSB_ControllerEhci0
#endif
#if defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0)
#define CONTROLLER_ID kUSB_ControllerKhci0
#endif
#if defined(USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)
#define CONTROLLER_ID kUSB_ControllerLpcIp3511Fs0
#endif
#if defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)
#define CONTROLLER_ID kUSB_ControllerLpcIp3511Hs0
#endif
#define USB_DEVICE_INTERRUPT_PRIORITY (3U)
typedef struct _usb_device_composite_struct
{
usb_device_handle deviceHandle; /* USB device handle. */
usb_cdc_vcom_struct_t cdcVcom[USB_DEVICE_CONFIG_CDC_ACM]; /* CDC virtual com device structure. */
uint8_t speed; /* Speed of USB device. USB_SPEED_FULL/USB_SPEED_LOW/USB_SPEED_HIGH. */
uint8_t attach; /* A flag to indicate whether a usb device is attached. 1: attached, 0: not attached */
uint8_t currentConfiguration; /* Current configuration value. */
uint8_t
currentInterfaceAlternateSetting[USB_INTERFACE_COUNT]; /* Current alternate setting value for each interface. */
} usb_device_composite_struct_t;
/*******************************************************************************
* API
******************************************************************************/
/*!
* @brief CDC class specific callback function.
*
* This function handles the CDC class specific requests.
*
* @param handle The CDC ACM class handle.
* @param event The CDC ACM class event type.
* @param param The parameter of the class specific request.
*
* @return A USB error code or kStatus_USB_Success.
*/
extern usb_status_t USB_DeviceCdcVcomCallback(class_handle_t handle, uint32_t event, void *param);
/*!
* @brief Virtual COM device set configuration function.
*
* This function sets configuration for CDC class.
*
* @param handle The CDC ACM class handle.
* @param configure The CDC ACM class configure index.
*
* @return A USB error code or kStatus_USB_Success.
*/
extern usb_status_t USB_DeviceCdcVcomSetConfigure(class_handle_t handle, uint8_t configure);
/*!
* @brief Virtual COM device initialization function.
*
* This function initializes the device with the composite device class information.
*
* @param deviceComposite The pointer to the composite device structure.
*
* @return A USB error code or kStatus_USB_Success.
*/
extern usb_status_t USB_DeviceCdcVcomInit(usb_device_composite_struct_t *deviceComposite);
/*!
* @brief Application task function.
*
* This function runs the task for application.
*
* @return None.
*/
extern void USB_DeviceCdcVcomTask(void);
#endif /* _USB_DEVICE_COMPOSITE_H_ */

View file

@ -0,0 +1,98 @@
// ****************************************************************************
// semihost_hardfault.c
// - Provides hard fault handler to allow semihosting code not
// to hang application when debugger not connected.
//
// ****************************************************************************
// Copyright 2017-2021 NXP
// All rights reserved.
//
// NXP Confidential. This software is owned or controlled by NXP and may only be
// used strictly in accordance with the applicable license terms.
//
// By expressly accepting such terms or by downloading, installing, activating
// and/or otherwise using the software, you are agreeing that you have read, and
// that you agree to comply with and are bound by, such license terms.
//
// If you do not agree to be bound by the applicable license terms, then you may not
// retain, install, activate or otherwise use the software.
// ****************************************************************************
//
// ===== DESCRIPTION =====
//
// One of the issues with applications that make use of semihosting operations
// (such as printf calls) is that the code will not execute correctly when the
// debugger is not connected. Generally this will show up with the application
// appearing to just hang. This may include the application running from reset
// or powering up the board (with the application already in FLASH), and also
// as the application failing to continue to execute after a debug session is
// terminated.
//
// The problem here is that the "bottom layer" of the semihosted variants of
// the C library, semihosting is implemented by a "BKPT 0xAB" instruction.
// When the debug tools are not connected, this instruction triggers a hard
// fault - and the default hard fault handler within an application will
// typically just contains an infinite loop - causing the application to
// appear to have hang when no debugger is connected.
//
// The below code provides an example hard fault handler which instead looks
// to see what the instruction that caused the hard fault was - and if it
// was a "BKPT 0xAB", then it instead returns back to the user application.
//
// In most cases this will allow applications containing semihosting
// operations to execute (to some degree) when the debugger is not connected.
//
// == NOTE ==
//
// Correct execution of the application containing semihosted operations
// which are vectored onto this hard fault handler cannot be guaranteed. This
// is because the handler may not return data or return codes that the higher
// level C library code or application code expects. This hard fault handler
// is meant as a development aid, and it is not recommended to leave
// semihosted code in a production build of your application!
//
// ****************************************************************************
// Allow handler to be removed by setting a define (via command line)
#if !defined (__SEMIHOST_HARDFAULT_DISABLE)
__attribute__((naked))
void HardFault_Handler(void){
__asm( ".syntax unified\n"
// Check which stack is in use
"MOVS R0, #4 \n"
"MOV R1, LR \n"
"TST R0, R1 \n"
"BEQ _MSP \n"
"MRS R0, PSP \n"
"B _process \n"
"_MSP: \n"
"MRS R0, MSP \n"
// Load the instruction that triggered hard fault
"_process: \n"
"LDR R1,[R0,#24] \n"
"LDRH R2,[r1] \n"
// Semihosting instruction is "BKPT 0xAB" (0xBEAB)
"LDR R3,=0xBEAB \n"
"CMP R2,R3 \n"
"BEQ _semihost_return \n"
// Wasn't semihosting instruction so enter infinite loop
"B . \n"
// Was semihosting instruction, so adjust location to
// return to by 1 instruction (2 bytes), then exit function
"_semihost_return: \n"
"ADDS R1,#2 \n"
"STR R1,[R0,#24] \n"
// Set a return value from semihosting operation.
// 32 is slightly arbitrary, but appears to allow most
// C Library IO functions sitting on top of semihosting to
// continue to operate to some degree
"MOVS R1,#32 \n"
"STR R1,[ R0,#0 ] \n" // R0 is at location 0 on stack
// Return from hard fault handler to application
"BX LR \n"
".syntax divided\n") ;
}
#endif

View file

@ -0,0 +1,223 @@
/*
* rt595-sspc-binance
*
* Written in 2010-2021 by Andy Green <andy@warmcat.com>
* Kutoga <kutoga@user.github.invalid>
*
* This file is made available under the Creative Commons CC0 1.0
* Universal Public Domain Dedication.
*
*
* This is a version of minimal-secure-streams-binance that uses a custom
* SS Serialization transport.
*/
#include "private.h"
#include <string.h>
#include <signal.h>
#include <ctype.h>
extern uint64_t
get_us_timeofday(void);
typedef struct range {
uint64_t sum;
uint64_t lowest;
uint64_t highest;
unsigned int samples;
} range_t;
LWS_SS_USER_TYPEDEF
uint64_t data_in;
uint64_t data_in_last_sec;
lws_sorted_usec_list_t sul_hz; /* 1hz summary dump */
char msgbuf[8192];
size_t msg_len;
range_t e_lat_range;
range_t price_range;
} binance_t;
/*
* Rest of the file is Binance application SS processing (UNCHANGED from
* minimal-secure-streams-binance)
*/
static void
range_reset(range_t *r)
{
r->sum = r->highest = 0;
r->lowest = 999999999999ull;
r->samples = 0;
}
static uint64_t
pennies(const char *s)
{
uint64_t price = (uint64_t)atoll(s) * 100;
s = strchr(s, '.');
if (s && isdigit(s[1]) && isdigit(s[2]))
price = price + (uint64_t)((10 * (s[1] - '0')) + (s[2] - '0'));
return price;
}
static void
sul_hz_cb(lws_sorted_usec_list_t *sul)
{
binance_t *bin = lws_container_of(sul, binance_t, sul_hz);
/*
* We are called once a second to dump statistics on the connection
*/
lws_sul_schedule(lws_ss_get_context(bin->ss), 0, &bin->sul_hz,
sul_hz_cb, LWS_US_PER_SEC);
if (bin->price_range.samples)
lwsl_user("%s: price: min: %llu¢, max: %llu¢, avg: %llu¢, "
"(%d prices/s)\n", __func__,
(unsigned long long)bin->price_range.lowest,
(unsigned long long)bin->price_range.highest,
(unsigned long long)(bin->price_range.sum /
bin->price_range.samples),
bin->price_range.samples);
if (bin->e_lat_range.samples)
lwsl_user("%s: elatency: min: %lums, max: %lums, "
"avg: %lums, (%d msg/s, %lu KiBytes/s SS RX)\n",
__func__,
(unsigned long)(bin->e_lat_range.lowest / 1000),
(unsigned long)(bin->e_lat_range.highest / 1000),
(unsigned long)((bin->e_lat_range.sum /
bin->e_lat_range.samples) / 1000),
bin->e_lat_range.samples,
(unsigned long)((bin->data_in -
bin->data_in_last_sec) / 1024));
range_reset(&bin->e_lat_range);
range_reset(&bin->price_range);
bin->data_in_last_sec = bin->data_in;
}
static lws_ss_state_return_t
binance_rx(void *userobj, const uint8_t *in, size_t len, int flags)
{
binance_t *bin = (binance_t *)userobj;
uint64_t latency_us, now_us, l1;
const uint8_t *msg;
char numbuf[20];
uint64_t price;
const char *p;
size_t alen;
bin->data_in += len;
msg = bin->msgbuf;
if (flags & LWSSS_FLAG_SOM) {
bin->msg_len = 0;
if (flags & LWSSS_FLAG_EOM) {
msg = in;
bin->msg_len = len;
goto handle;
}
}
if (bin->msg_len + len < sizeof(bin->msgbuf)) {
memcpy(bin->msgbuf + bin->msg_len, in, len);
bin->msg_len += len;
}
/* assemble a full message */
if (!(flags & LWSSS_FLAG_EOM))
return LWSSSSRET_OK;
handle:
//lwsl_notice("%s: chunk len %d\n", __func__, (int)len);
now_us = (uint64_t)get_us_timeofday();
p = lws_json_simple_find(msg, bin->msg_len, "\"depthUpdate\"",
&alen);
if (!p)
return LWSSSSRET_OK;
p = lws_json_simple_find(msg, bin->msg_len, "\"E\":", &alen);
if (!p) {
lwsl_err("%s: no E JSON\n", __func__);
return LWSSSSRET_OK;
}
lws_strnncpy(numbuf, p, alen, sizeof(numbuf));
l1 = ((uint64_t)atoll(numbuf) * LWS_US_PER_MS);
latency_us = now_us - l1;
// lwsl_notice("%s: now_us adjusted %llu, %llu, %llu, %s\n", __func__, tm->us_unixtime_peer, now_us, l1, numbuf);
if (latency_us < bin->e_lat_range.lowest)
bin->e_lat_range.lowest = latency_us;
if (latency_us > bin->e_lat_range.highest)
bin->e_lat_range.highest = latency_us;
bin->e_lat_range.sum += latency_us;
bin->e_lat_range.samples++;
p = lws_json_simple_find(msg, bin->msg_len, "\"a\":[[\"", &alen);
if (!p)
return LWSSSSRET_OK;
lws_strnncpy(numbuf, p, alen, sizeof(numbuf));
price = pennies(numbuf);
if (price < bin->price_range.lowest)
bin->price_range.lowest = price;
if (price > bin->price_range.highest)
bin->price_range.highest = price;
bin->price_range.sum += price;
bin->price_range.samples++;
return LWSSSSRET_OK;
}
static lws_ss_state_return_t
binance_state(void *userobj, void *h_src, lws_ss_constate_t state,
lws_ss_tx_ordinal_t ack)
{
binance_t *bin = (binance_t *)userobj;
lwsl_ss_info(bin->ss, "%s (%d), ord 0x%x",
lws_ss_state_name((int)state), state, (unsigned int)ack);
switch (state) {
case LWSSSCS_CONNECTED:
lws_sul_schedule(lws_ss_get_context(bin->ss), 0, &bin->sul_hz,
sul_hz_cb, LWS_US_PER_SEC);
range_reset(&bin->e_lat_range);
range_reset(&bin->price_range);
return LWSSSSRET_OK;
case LWSSSCS_DISCONNECTED:
lws_sul_cancel(&bin->sul_hz);
break;
default:
break;
}
return LWSSSSRET_OK;
}
LWS_SS_INFO("binance", binance_t)
.rx = binance_rx,
.state = binance_state,
};

View file

@ -0,0 +1,71 @@
/*
* rt595-sspc-binance
*
* Written in 2010 - 2021 by Andy Green <andy@warmcat.com>
*
* This file is made available under the Creative Commons CC0 1.0
* Universal Public Domain Dedication.
*
* The SS user struct for the "GET" stream... it reads from
* https://libwebsockets.org/index.html every 5s
*/
#include "private.h"
LWS_SS_USER_TYPEDEF
lws_sorted_usec_list_t sul5;
} get_t;
static void
sul_start_get(lws_sorted_usec_list_t *sul)
{
get_t *g = lws_container_of(sul, get_t, sul5);
lws_ss_request_tx(lws_ss_from_user(g));
lws_sul_schedule(lws_ss_cx_from_user(g), 0, sul, sul_start_get,
5 * LWS_US_PER_SEC);
}
static lws_ss_state_return_t
get_rx(void *userobj, const uint8_t *in, size_t len, int flags)
{
get_t *g = (get_t *)userobj;
lwsl_ss_notice(lws_ss_from_user(g), "RX %u, flags 0x%x",
(unsigned int)len, (unsigned int)flags);
if (len) {
lwsl_hexdump_notice(in, 16);
if (len >= 16)
lwsl_hexdump_notice(in + len - 16, 16);
}
return LWSSSSRET_OK;
}
static lws_ss_state_return_t
get_state(void *userobj, void *h_src, lws_ss_constate_t state,
lws_ss_tx_ordinal_t ack)
{
get_t *g = (get_t *)userobj;
lwsl_ss_notice(lws_ss_from_user(g), "%s (%d), ord 0x%x",
lws_ss_state_name((int)state), state, (unsigned int)ack);
switch (state) {
case LWSSSCS_CREATING:
lws_sul_schedule(lws_ss_cx_from_user(g), 0, &g->sul5,
sul_start_get, 5 * LWS_US_PER_SEC);
break;
case LWSSSCS_DESTROYING:
lws_sul_cancel(&g->sul5);
break;
}
return LWSSSSRET_OK;
}
LWS_SS_INFO("mintest-lws", get_t)
.rx = get_rx,
.state = get_state,
};

View file

@ -0,0 +1,151 @@
/*
* rt595-sspc-binance
*
* Written in 2010-2021 by Andy Green <andy@warmcat.com>
*
* This file is made available under the Creative Commons CC0 1.0
* Universal Public Domain Dedication.
*
* Since LWS_ONLY_SSPC chops down libwebsockets.a to have just the pieces needed
* for SSPC, we need to bring in our own copies of any other lws apis we use in
* the user Binance SS code
*/
#include "private.h"
#include <string.h>
#include <stdio.h>
const char *
lws_nstrstr(const char *buf, size_t len, const char *name, size_t nl)
{
const char *end = buf + len - nl + 1;
size_t n;
if (nl > len)
/* it cannot be found if the needle is longer than the haystack */
return NULL;
while (buf < end) {
if (*buf != name[0]) {
buf++;
continue;
}
if (nl == 1)
/* single char match, we are done */
return buf;
if (buf[nl - 1] == name[nl - 1]) {
/*
* This is looking interesting then... the first
* and last chars match, let's check the insides
*/
n = 1;
while (n < nl && buf[n] == name[n])
n++;
if (n == nl)
/* it's a hit */
return buf;
}
buf++;
}
return NULL;
}
const char *
lws_json_simple_find(const char *buf, size_t len, const char *name, size_t *alen)
{
size_t nl = strlen(name);
const char *np = lws_nstrstr(buf, len, name, nl),
*end = buf + len, *as;
int qu = 0;
if (!np)
return NULL;
np += nl;
while (np < end && (*np == ' ' || *np == '\t'))
np++;
if (np >= end)
return NULL;
/*
* The arg could be lots of things after "name": with JSON, commonly a
* string like "mystring", true, false, null, [...] or {...} ... we want
* to handle common, simple cases cheaply with this; the user can choose
* a full JSON parser like lejp if it's complicated. So if no opening
* quote, return until a terminator like , ] }. If there's an opening
* quote, return until closing quote, handling escaped quotes.
*/
if (*np == '\"') {
qu = 1;
np++;
}
as = np;
while (np < end &&
(!qu || *np != '\"') && /* end quote is EOT if quoted */
(qu || (*np != '}' && *np != ']' && *np != ',')) /* delimiters */
) {
if (qu && *np == '\\') /* skip next char if quoted escape */
np++;
np++;
}
*alen = (unsigned int)lws_ptr_diff(np, as);
return as;
}
void
lwsl_hexdump_level(int hexdump_level, const void *vbuf, size_t len)
{
unsigned char *buf = (unsigned char *)vbuf;
unsigned int n;
for (n = 0; n < len;) {
unsigned int start = n, m;
char line[80], *p = line;
p += snprintf(p, 10, "%04X: ", start);
for (m = 0; m < 16 && n < len; m++)
p += snprintf(p, 5, "%02X ", buf[n++]);
while (m++ < 16)
p += snprintf(p, 5, " ");
p += snprintf(p, 6, " ");
for (m = 0; m < 16 && (start + m) < len; m++) {
if (buf[start + m] >= ' ' && buf[start + m] < 127)
*p++ = (char)buf[start + m];
else
*p++ = '.';
}
while (m++ < 16)
*p++ = ' ';
*p++ = '\n';
*p = '\0';
_lws_log(hexdump_level, "%s", line);
(void)line;
}
_lws_log(hexdump_level, "\n");
}
uint64_t
get_us_timeofday(void)
{
if (!tm)
return lws_now_usecs();
return lws_now_usecs() - tm->us_unixtime_peer_loc + tm->us_unixtime_peer;
}

View file

@ -0,0 +1,130 @@
/*
* rt595-sspc-binance
*
* Written in 2010-2021 by Andy Green <andy@warmcat.com>
*
* This file is made available under the Creative Commons CC0 1.0
* Universal Public Domain Dedication.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "usb_device_config.h"
#include "usb.h"
#include "usb_device.h"
#include "usb_device_class.h"
#include "usb_device_cdc_acm.h"
#include "usb_device_ch9.h"
#include "usb_device_descriptor.h"
#include "fsl_device_registers.h"
#include "fsl_debug_console.h"
#include "composite.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
#include "private.h"
void USB_DeviceApplicationInit(void);
extern const lws_ss_info_t ssi_binance_t, /* binance-ss.c */
ssi_get_t; /* get-ss.c */
extern const lws_transport_client_ops_t lws_sss_ops_client_serial;
static struct lws_context_standalone cx = {
.txp_cpath.ops_onw = &lws_transport_mux_client_ops,
};
lws_transport_mux_t *tm;
/*
* Describes how the lws_transport path goes through the transport_mux
*/
lws_transport_info_t info_serial = {
.ping_interval_us = LWS_US_PER_SEC * 10,
.pong_grace_us = LWS_US_PER_SEC * 2,
.flags = 0,
}, info_mux = {
.ping_interval_us = LWS_US_PER_SEC * 10,
.pong_grace_us = LWS_US_PER_SEC * 2,
.txp_cpath = {
.ops_onw = &lws_sss_ops_client_serial,
/**< onward transport for mux is serial */
.ops_in = &lws_transport_mux_client_ops,
},
.onward_txp_info = &info_serial,
.flags = 0,
};
extern usb_cdc_acm_info_t s_usbCdcAcmInfo[USB_DEVICE_CONFIG_CDC_ACM];
#if defined(__CC_ARM) || (defined(__ARMCC_VERSION)) || defined(__GNUC__)
int main(void)
#else
void main(void)
#endif
{
unsigned int f = 0, din = 0;
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();
*((volatile uint32_t*)0xE0001000) = 0x40000001;
USB_DeviceApplicationInit();
/* create the ss transport mux object itself... only one of these */
tm = lws_transport_mux_create(&cx, &info_mux, NULL);
if (!tm) {
lwsl_err("%s: unable to create client mux\n", __func__);
return 1;
}
tm->info.txp_cpath.priv_in = tm;
cx.txp_cpath.mux = tm;
while (1) {
/*
* When the host link ttyACM is hooked up, create the SS. They could be
* created before the link, but delaying it like this means we will be
* able to hook up the log ttyACM and see the related logs for this.
*/
if (!din && (s_usbCdcAcmInfo[1].uartState & USB_DEVICE_CDC_UART_STATE_RX_CARRIER)) {
din = 1;
if (lws_ss_create(&cx, 0, &ssi_binance_t, NULL, NULL, NULL, NULL)) {
lwsl_err("failed to create binance secure stream\n");
f = 1;
}
if (lws_ss_create(&cx, 0, &ssi_get_t, NULL, NULL, NULL, NULL)) {
lwsl_err("failed to create get secure stream\n");
f = 2;
}
}
USB_DeviceCdcVcomTask();
lws_now_usecs();
serial_handle_events(tm);
/* check the scheduler */
while (scheduler.head) {
lws_sorted_usec_list_t *sul = lws_container_of(
scheduler.head, lws_sorted_usec_list_t, list);
if (sul->us > lws_now_usecs())
break;
lws_dll2_remove(&sul->list);
sul->cb(sul);
}
}
}

View file

@ -0,0 +1,51 @@
/*
* rt595-sspc-binance
*
* Written in 2010-2021 by Andy Green <andy@warmcat.com>
*
* This file is made available under the Creative Commons CC0 1.0
* Universal Public Domain Dedication.
*/
/* boilerplate for LWS_ONLY_SSPC Secure Streams
* LWS_SS_USE_SSPC should be defined by cmake
*/
#define lws_context lws_context_standalone
#undef LWS_SS_USE_SSPC
#define LWS_SS_USE_SSPC
#undef STANDALONE
#define STANDALONE
#include <libwebsockets.h>
typedef struct vcring {
uint8_t log_ring[4096];
unsigned int lrh, lrt;
} vcring_t;
extern vcring_t vcr_log, vcr_txp_out, vcr_txp_in;
long long
atoll(const char *s);
size_t
space_available(vcring_t *v);
int
append_vcring(vcring_t *v, const uint8_t *b, size_t l);
size_t
next_chonk(vcring_t *v, const uint8_t ** pp);
void
consume_chonk(vcring_t *v, size_t n);
extern lws_dll2_owner_t scheduler;
extern lws_transport_mux_t *tm;
/* our transport related apis */
extern const lws_transport_client_ops_t lws_sss_ops_client_serial;
void serial_handle_events(lws_transport_mux_t *tm);
/* our SS bindings */
extern const lws_ss_info_t ssi_binance_t, /* binance-ss.c */
ssi_get_t; /* get-ss.c */

View file

@ -0,0 +1,277 @@
/*
* rt595-sspc-binance
*
* Written in 2010-2021 by Andy Green <andy@warmcat.com>
*
* This file is made available under the Creative Commons CC0 1.0
* Universal Public Domain Dedication.
*
* These are the bindings for our system to the libwebsockets.a imports.
*/
#include "private.h"
#include <string.h>
#include <stdio.h>
static uint32_t ticks_high, last_tick_low;
/*
* wire up libwebsockets.a logs to native application logs, we just wire it up
* to the device console in our case.
*
* We add the lws loglevel colour scheme ourselves.
*/
int log_level = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE | LLL_INFO;
static const char * const colours[] = {
"[31;1m", /* LLL_ERR */
"[36;1m", /* LLL_WARN */
"[35;1m", /* LLL_NOTICE */
"[32;1m", /* LLL_INFO */
"[34;1m", /* LLL_DEBUG */
"[33;1m", /* LLL_PARSER */
"[33m", /* LLL_HEADER */
"[33m", /* LLL_EXT */
"[33m", /* LLL_CLIENT */
"[33;1m", /* LLL_LATENCY */
"[0;1m", /* LLL_USER */
"[31m", /* LLL_THREAD */
};
size_t
space_available(vcring_t *v)
{
if (v->lrt < v->lrh)
return (sizeof(v->log_ring) - v->lrh) + v->lrt;
if (v->lrt == v->lrh)
return sizeof(v->log_ring) - 1;
return (v->lrt - v->lrh) - 1;
}
int
append_vcring(vcring_t *v, const uint8_t *b, size_t l)
{
size_t r = sizeof(v->log_ring) - v->lrh;
if (v->lrt < v->lrh) {
/* ---t=====h--- */
if (r > l)
r = l;
memcpy(v->log_ring + v->lrh, b, r);
v->lrh += r;
if (v->lrh >= sizeof(v->log_ring))
v->lrh = 0;
b += r;
l -= r;
if (!l)
return 0;
}
/* ===h------t=== or ht--------- */
r = v->lrt - v->lrh;
if (!r) {
r = sizeof(v->log_ring) - 1;
v->lrt = v->lrh = 0;
}
if (r > l)
r = l;
memcpy(v->log_ring + v->lrh, b, r);
v->lrh += r;
if (v->lrh >= sizeof(v->log_ring))
v->lrh = 0;
__sync_synchronize();
return 0;
}
size_t
next_chonk(vcring_t *v, const uint8_t ** pp)
{
size_t c = v->lrh < v->lrt ? sizeof(v->log_ring) - v->lrt : v->lrh - v->lrt;
*pp = v->log_ring + v->lrt;
return c;
}
void
consume_chonk(vcring_t *v, size_t n)
{
v->lrt += n;
if (v->lrt >= sizeof(v->log_ring))
v->lrt = 0;
}
int
add_log_buf(const uint8_t *b, size_t l)
{
return append_vcring(&vcr_log, b, l);
}
void
__lws_logv(lws_log_cx_t *cx, lws_log_prepend_cx_t prep, void *obj,
int filter, const char * const _fun, const char *format, va_list ap)
{
int n, m = LWS_ARRAY_SIZE(colours) - 1;
char logbuf[200], *p = logbuf, *e = logbuf + sizeof(logbuf) - 7;
if (!(filter & log_level))
return;
n = 1 << (LWS_ARRAY_SIZE(colours) - 1);
while (n) {
if (filter & n)
break;
m--;
n >>= 1;
}
n = snprintf(p, lws_ptr_diff(e, p), "%lu: %c%s%s: ", (unsigned long)lws_now_usecs(), 27,
colours[m], _fun);
p += n;
if (prep && obj)
prep(cx, obj, &p, e);
n = vsnprintf(p, lws_ptr_diff(e, p), format, ap);
p += n;
if (p > e)
p = e;
if (p[-1] != '\n')
*p++ = '\n';
*p++ = '\r';
*p++ = 27;
*p++ = '[';
*p++ = '0';
*p++ = 'm';
add_log_buf(logbuf, lws_ptr_diff(p, logbuf));
}
static int
sul_compare(const lws_dll2_t *d, const lws_dll2_t *i)
{
lws_usec_t a = ((lws_sorted_usec_list_t *)d)->us;
lws_usec_t b = ((lws_sorted_usec_list_t *)i)->us;
/*
* Simply returning (a - b) in an int
* may lead to an integer overflow bug
*/
if (a > b)
return 1;
if (a < b)
return -1;
return 0;
}
void
lws_sul_schedule(struct lws_context_standalone *ctx, int tsi,
lws_sorted_usec_list_t *sul, sul_cb_t _cb, lws_usec_t _us)
{
if (_us == (lws_usec_t)LWS_SET_TIMER_USEC_CANCEL) {
lws_sul_cancel(sul);
return;
}
lws_dll2_remove(&sul->list);
sul->cb = _cb;
sul->us = lws_now_usecs() + _us;
lws_dll2_add_sorted(&sul->list, &scheduler, sul_compare);
}
void
lws_sul_cancel(lws_sorted_usec_list_t *sul)
{
lws_dll2_remove(&sul->list);
sul->us = 0;
}
lws_usec_t
lws_now_usecs(void)
{
uint32_t a = *((volatile uint32_t*)0xE0001004);
if (a < (uint32_t)last_tick_low)
ticks_high++;
last_tick_low = a;
return ((((uint64_t)ticks_high)<<32) | (uint64_t)a) / 198;
}
struct timeval {
uint32_t tv_sec; /* seconds */
uint32_t tv_usec; /* microseconds */
};
int gettimeofday(struct timeval *tv, void *tx)
{
lws_usec_t u = lws_now_usecs();
tv->tv_sec = u / 1000000;
tv->tv_usec = u - (tv->tv_sec * 1000000);
}
long long atoll(const char *s)
{
long long l = 0ll;
char minus = *s == '-';
if (minus)
s++;
while (*s) {
if (*s < '0' || *s > '9')
break;
l = (long long)(l * 10ll) + (*s) - '0';
s++;
}
if (minus)
return 0ll - l;
return l;
}
void __assert_func(const char *file, int line, const char *func, const char *failedExpr)
{
lwsl_err("ASSERT ERROR \" %s \": file \"%s\" Line \"%d\" function name \"%s\" \n", failedExpr, file ,
line, func);
for (;;)
{}
}
int getpid(void)
{
return 0;
}
struct lws_log_cx *
lwsl_context_get_cx(struct lws_context_standalone *cx)
{
return NULL;
}
void
lws_log_prepend_context(struct lws_log_cx *cx, void *obj, char **p, char *e)
{
}

View file

@ -0,0 +1,178 @@
/*
* rt595-sspc-binance
*
* Written in 2010-2021 by Andy Green <andy@warmcat.com>
*
* This file is made available under the Creative Commons CC0 1.0
* Universal Public Domain Dedication.
*
* The serial port based custom transport, and helpers used by lws_transport
*/
#include "private.h"
int need_pollout;
/* incoming parsed channel cbs */
static int
ltm_ch_payload(lws_transport_mux_ch_t *tmc, const uint8_t *buf, size_t len)
{
lwsl_notice("%s\n", __func__);
return 0;
}
static int
ltm_ch_opens_serial(lws_transport_mux_ch_t *tmc, int determination)
{
lws_transport_mux_t *tm = lws_container_of(tmc->list.owner,
lws_transport_mux_t, owner);
struct lws_sspc_handle *h = (struct lws_sspc_handle *)tmc->priv;
assert_is_tm(tm);
lwsl_sspc_err(h, "%d", determination);
if (tm->info.txp_cpath.ops_in->event_connect_disposition(h, determination))
return -1;
return 0;
}
static int
ltm_ch_closes(lws_transport_mux_ch_t *tmc)
{
lwsl_notice("%s\n", __func__);
return 0;
}
static void
ltm_txp_req_write(lws_transport_mux_t *tm)
{
tm->info.txp_cpath.ops_onw->req_write(tm->info.txp_cpath.priv_onw);
}
static int
ltm_txp_can_write(lws_transport_mux_ch_t *tmc)
{
assert_is_tmch(tmc);
return lws_txp_inside_sspc.event_can_write(
(struct lws_sspc_handle *)tmc->priv, 2048);
}
/*
* So that we can use the same mux framing parser for both sides, we pass into
* the parser an "ops struct" that gets called back to customize response to
* mux parser framing.
*/
static const lws_txp_mux_parse_cbs_t cbs = {
.payload = ltm_ch_payload,
.ch_opens = ltm_ch_opens_serial,
.ch_closes = ltm_ch_closes,
.txp_req_write = ltm_txp_req_write,
.txp_can_write = ltm_txp_can_write,
};
void
serial_handle_events(lws_transport_mux_t *tm)
{
const uint8_t *p;
uint8_t chonk[1200];
size_t n;
/* for "POLLOUT" */
if (need_pollout && vcr_txp_out.lrh == vcr_txp_out.lrt) {
size_t cl = sizeof(chonk);
need_pollout = 0;
if (lws_transport_mux_pending(tm, chonk, &cl, &cbs)) {
#if defined(_DEBUG)
lws_transport_path_client_dump(&tm->info.txp_cpath, "cpath");
#endif
tm->info.txp_cpath.ops_onw->_write(
tm->info.txp_cpath.priv_onw, chonk, cl);
return;
}
}
}
/*
* We get called while an individual SS is trying to connect to the proxy to
* be recognized as operational. It's the equivalent of trying to bring up the
* Unix Domain socket
*/
static int
txp_serial_retry_connect(lws_txp_path_client_t *path,
struct lws_sspc_handle *h)
{
lwsl_user("%s\n", __func__);
if (!path)
return 0;
if (path->ops_onw->event_connect_disposition(h,
path->mux->link_state != LWSTM_OPERATIONAL))
return -1;
return 0;
}
static void
txp_serial_req_write(lws_transport_priv_t priv)
{
need_pollout = 1;
}
static int
txp_serial_write(lws_transport_priv_t priv, uint8_t *buf, size_t len)
{
lwsl_notice("%s: writing %u\n", __func__, (unsigned int)len);
// lwsl_hexdump_level(LLL_WARN, buf, len);
append_vcring(&vcr_txp_out, buf, len);
return 0;
}
static void
txp_serial_close(lws_transport_priv_t priv)
{
#if 0
struct lws *wsi = (struct lws *)priv;
if (!wsi)
return;
lws_set_opaque_user_data(wsi, NULL);
lws_wsi_close(wsi, LWS_TO_KILL_ASYNC);
*priv = NULL;
#endif
}
static void
txp_serial_stream_up(lws_transport_priv_t priv)
{
// struct lws *wsi = (struct lws *)priv;
// lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
}
/*
* This is the lws_transport export for our custom serial transport
*/
const lws_transport_client_ops_t lws_sss_ops_client_serial = {
.name = "txpserial",
.event_retry_connect = txp_serial_retry_connect,
.req_write = txp_serial_req_write,
._write = txp_serial_write,
._close = txp_serial_close,
.event_stream_up = txp_serial_stream_up,
.flags = LWS_DSHFLAG_ENABLE_COALESCE,
.dsh_splitat = 0,
};

View file

@ -0,0 +1,157 @@
/*
* Copyright 2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _USB_DEVICE_CONFIG_H_
#define _USB_DEVICE_CONFIG_H_
/*******************************************************************************
* Definitions
******************************************************************************/
/*!
* @addtogroup usb_device_configuration
* @{
*/
/*!
* @name Hardware instance define
* @{
*/
/*! @brief KHCI instance count */
#define USB_DEVICE_CONFIG_KHCI (0U)
/*! @brief EHCI instance count */
#define USB_DEVICE_CONFIG_EHCI (0U)
/*! @brief LPC USB IP3511 FS instance count */
#define USB_DEVICE_CONFIG_LPCIP3511FS (0U)
/*! @brief LPC USB IP3511 HS instance count */
#define USB_DEVICE_CONFIG_LPCIP3511HS (1U)
/*! @brief Device instance count, the sum of KHCI and EHCI instance counts*/
#define USB_DEVICE_CONFIG_NUM \
(USB_DEVICE_CONFIG_KHCI + USB_DEVICE_CONFIG_EHCI + USB_DEVICE_CONFIG_LPCIP3511FS + USB_DEVICE_CONFIG_LPCIP3511HS)
/* @} */
/*!
* @name class instance define
* @{
*/
/*! @brief HID instance count */
#define USB_DEVICE_CONFIG_HID (0U)
/*! @brief CDC ACM instance count */
#define USB_DEVICE_CONFIG_CDC_ACM (2U)
/*! @brief MSC instance count */
#define USB_DEVICE_CONFIG_MSC (0U)
/*! @brief Audio instance count */
#define USB_DEVICE_CONFIG_AUDIO (0U)
/*! @brief PHDC instance count */
#define USB_DEVICE_CONFIG_PHDC (0U)
/*! @brief Video instance count */
#define USB_DEVICE_CONFIG_VIDEO (0U)
/*! @brief CCID instance count */
#define USB_DEVICE_CONFIG_CCID (0U)
/*! @brief Printer instance count */
#define USB_DEVICE_CONFIG_PRINTER (0U)
/*! @brief DFU instance count */
#define USB_DEVICE_CONFIG_DFU (0U)
/* @} */
/*! @brief Whether device is self power. 1U supported, 0U not supported */
#define USB_DEVICE_CONFIG_SELF_POWER (1U)
/*! @brief How many endpoints are supported in the stack. */
#define USB_DEVICE_CONFIG_ENDPOINTS (5U)
/*! @brief Whether the device task is enabled. */
#define USB_DEVICE_CONFIG_USE_TASK (0U)
/*! @brief How many the notification message are supported when the device task is enabled. */
#define USB_DEVICE_CONFIG_MAX_MESSAGES (8U)
/*! @brief Whether test mode enabled. */
#define USB_DEVICE_CONFIG_USB20_TEST_MODE (0U)
/*! @brief Whether device CV test is enabled. */
#define USB_DEVICE_CONFIG_CV_TEST (0U)
/*! @brief Whether device compliance test is enabled. If the macro is enabled,
the test mode and CV test macroes will be set.*/
#define USB_DEVICE_CONFIG_COMPLIANCE_TEST (0U)
#if ((defined(USB_DEVICE_CONFIG_COMPLIANCE_TEST)) && (USB_DEVICE_CONFIG_COMPLIANCE_TEST > 0U))
/*! @brief Undefine the macro USB_DEVICE_CONFIG_USB20_TEST_MODE. */
#undef USB_DEVICE_CONFIG_USB20_TEST_MODE
/*! @brief Undefine the macro USB_DEVICE_CONFIG_CV_TEST. */
#undef USB_DEVICE_CONFIG_CV_TEST
/*! @brief enable the test mode. */
#define USB_DEVICE_CONFIG_USB20_TEST_MODE (1U)
/*! @brief enable the CV test */
#define USB_DEVICE_CONFIG_CV_TEST (1U)
#endif
#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U))
/*! @brief The MAX buffer length for the KHCI DMA workaround.*/
#define USB_DEVICE_CONFIG_KHCI_DMA_ALIGN_BUFFER_LENGTH (64U)
/*! @brief Whether handle the USB KHCI bus error. */
#define USB_DEVICE_CONFIG_KHCI_ERROR_HANDLING (0U)
#endif
#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U))
/*! @brief How many the DTD are supported. */
#define USB_DEVICE_CONFIG_EHCI_MAX_DTD (16U)
/*! @brief Whether handle the USB EHCI bus error. */
#define USB_DEVICE_CONFIG_EHCI_ERROR_HANDLING (0U)
/*! @brief Whether the EHCI ID pin detect feature enabled. */
#define USB_DEVICE_CONFIG_EHCI_ID_PIN_DETECT (0U)
#endif
/*! @brief Whether the keep alive feature enabled. */
#define USB_DEVICE_CONFIG_KEEP_ALIVE_MODE (0U)
/*! @brief Whether the transfer buffer is cache-enabled or not. */
#ifndef USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE
#define USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE (0U)
#endif
/*! @brief Whether the low power mode is enabled or not. */
#define USB_DEVICE_CONFIG_LOW_POWER_MODE (0U)
#if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE)) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
/*! @brief Whether device remote wakeup supported. 1U supported, 0U not supported */
#define USB_DEVICE_CONFIG_REMOTE_WAKEUP (0U)
/*! @brief Whether LPM is supported. 1U supported, 0U not supported */
#define USB_DEVICE_CONFIG_LPM_L1 (0U)
#else
/*! @brief The device remote wakeup is unsupported. */
#define USB_DEVICE_CONFIG_REMOTE_WAKEUP (0U)
#endif
/*! @brief Whether the device detached feature is enabled or not. */
#define USB_DEVICE_CONFIG_DETACH_ENABLE (0U)
/* @} */
#endif /* _USB_DEVICE_CONFIG_H_ */

View file

@ -0,0 +1,814 @@
/*
* Copyright 2017 - 2019 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "usb_device_config.h"
#include "usb.h"
#include "usb_device.h"
#include "usb_device_class.h"
#include "usb_device_cdc_acm.h"
#include "usb_device_descriptor.h"
/*******************************************************************************
* Variables
******************************************************************************/
/* msc disk information */
/* Define endpoint for Vcom class */
/* cdc virtual com information */
/* Define endpoint for communication class */
usb_device_endpoint_struct_t g_cdcVcomCicEndpoints[USB_CDC_VCOM_CIC_ENDPOINT_COUNT] = {
{
USB_CDC_VCOM_CIC_INTERRUPT_IN_ENDPOINT | (USB_IN << 7U),
USB_ENDPOINT_INTERRUPT,
FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE,
FS_CDC_VCOM_INTERRUPT_IN_INTERVAL,
},
};
/* Define endpoint for data class */
usb_device_endpoint_struct_t g_cdcVcomDicEndpoints[USB_CDC_VCOM_DIC_ENDPOINT_COUNT] = {
{
USB_CDC_VCOM_DIC_BULK_IN_ENDPOINT | (USB_IN << 7U),
USB_ENDPOINT_BULK,
FS_CDC_VCOM_BULK_IN_PACKET_SIZE,
0U,
},
{
USB_CDC_VCOM_DIC_BULK_OUT_ENDPOINT | (USB_OUT << 7U),
USB_ENDPOINT_BULK,
FS_CDC_VCOM_BULK_OUT_PACKET_SIZE,
0U,
},
};
/* Define interface for communication class */
usb_device_interface_struct_t g_cdcVcomCicInterface[] = {{USB_CDC_VCOM_CIC_INTERFACE_ALTERNATE_0,
{
USB_CDC_VCOM_CIC_ENDPOINT_COUNT,
g_cdcVcomCicEndpoints,
},
NULL}};
/* Define interface for data class */
usb_device_interface_struct_t g_cdcVcomDicInterface[] = {{USB_CDC_VCOM_DIC_INTERFACE_ALTERNATE_0,
{
USB_CDC_VCOM_DIC_ENDPOINT_COUNT,
g_cdcVcomDicEndpoints,
},
NULL}};
/* Define interfaces for virtual com */
usb_device_interfaces_struct_t g_cdcVcomInterfaces[USB_CDC_VCOM_INTERFACE_COUNT] = {
{USB_CDC_VCOM_CIC_CLASS, USB_CDC_VCOM_CIC_SUBCLASS, USB_CDC_VCOM_CIC_PROTOCOL, USB_CDC_VCOM_CIC_INTERFACE_INDEX,
g_cdcVcomCicInterface, sizeof(g_cdcVcomCicInterface) / sizeof(usb_device_interface_struct_t)},
{USB_CDC_VCOM_DIC_CLASS, USB_CDC_VCOM_DIC_SUBCLASS, USB_CDC_VCOM_DIC_PROTOCOL, USB_CDC_VCOM_DIC_INTERFACE_INDEX,
g_cdcVcomDicInterface, sizeof(g_cdcVcomDicInterface) / sizeof(usb_device_interface_struct_t)},
};
/* Define configurations for virtual com */
usb_device_interface_list_t g_UsbDeviceCdcVcomInterfaceList[USB_DEVICE_CONFIGURATION_COUNT] = {
{
USB_CDC_VCOM_INTERFACE_COUNT,
g_cdcVcomInterfaces,
},
};
/* cdc virtual com 2 information */
/* Define endpoint for communication class */
usb_device_endpoint_struct_t g_cdcVcomCicEndpoints_2[USB_CDC_VCOM_CIC_ENDPOINT_COUNT_2] = {
{
USB_CDC_VCOM_CIC_INTERRUPT_IN_ENDPOINT_2 | (USB_IN << 7U),
USB_ENDPOINT_INTERRUPT,
FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE_2,
FS_CDC_VCOM_INTERRUPT_IN_INTERVAL_2,
},
};
/* Define endpoint for data class */
usb_device_endpoint_struct_t g_cdcVcomDicEndpoints_2[USB_CDC_VCOM_DIC_ENDPOINT_COUNT_2] = {
{
USB_CDC_VCOM_DIC_BULK_IN_ENDPOINT_2 | (USB_IN << 7U),
USB_ENDPOINT_BULK,
FS_CDC_VCOM_BULK_IN_PACKET_SIZE,
0U,
},
{
USB_CDC_VCOM_DIC_BULK_OUT_ENDPOINT_2 | (USB_OUT << 7U),
USB_ENDPOINT_BULK,
FS_CDC_VCOM_BULK_OUT_PACKET_SIZE,
0U,
},
};
/* Define interface for communication class */
usb_device_interface_struct_t g_cdcVcomCicInterface_2[] = {{USB_CDC_VCOM_CIC_INTERFACE_2_ALTERNATE_0,
{
USB_CDC_VCOM_CIC_ENDPOINT_COUNT_2,
g_cdcVcomCicEndpoints_2,
},
NULL}};
/* Define interface for data class */
usb_device_interface_struct_t g_cdcVcomDicInterface_2[] = {{USB_CDC_VCOM_DIC_INTERFACE_2_ALTERNATE_0,
{
USB_CDC_VCOM_DIC_ENDPOINT_COUNT_2,
g_cdcVcomDicEndpoints_2,
},
NULL}};
/* Define interfaces for virtual com */
usb_device_interfaces_struct_t g_cdcVcomInterfaces_2[USB_CDC_VCOM_INTERFACE_COUNT_2] = {
{USB_CDC_VCOM_CIC_CLASS, USB_CDC_VCOM_CIC_SUBCLASS, USB_CDC_VCOM_CIC_PROTOCOL, USB_CDC_VCOM_CIC_INTERFACE_INDEX_2,
g_cdcVcomCicInterface_2, sizeof(g_cdcVcomCicInterface_2) / sizeof(usb_device_interface_struct_t)},
{USB_CDC_VCOM_DIC_CLASS, USB_CDC_VCOM_DIC_SUBCLASS, USB_CDC_VCOM_DIC_PROTOCOL, USB_CDC_VCOM_DIC_INTERFACE_INDEX_2,
g_cdcVcomDicInterface_2, sizeof(g_cdcVcomDicInterface_2) / sizeof(usb_device_interface_struct_t)},
};
/* Define configurations for virtual com */
usb_device_interface_list_t g_UsbDeviceCdcVcomInterfaceList_2[USB_DEVICE_CONFIGURATION_COUNT] = {
{
USB_CDC_VCOM_INTERFACE_COUNT_2,
g_cdcVcomInterfaces_2,
},
};
/* Define class information for virtual com */
usb_device_class_struct_t g_UsbDeviceCdcVcomConfig[2] = {
{
g_UsbDeviceCdcVcomInterfaceList,
kUSB_DeviceClassTypeCdc,
USB_DEVICE_CONFIGURATION_COUNT,
},
{
g_UsbDeviceCdcVcomInterfaceList_2,
kUSB_DeviceClassTypeCdc,
USB_DEVICE_CONFIGURATION_COUNT,
},
};
/* Define device descriptor */
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
uint8_t g_UsbDeviceDescriptor[] = {
/* Size of this descriptor in bytes */
USB_DESCRIPTOR_LENGTH_DEVICE,
/* DEVICE Descriptor Type */
USB_DESCRIPTOR_TYPE_DEVICE,
/* USB Specification Release Number in Binary-Coded Decimal (i.e., 2.10 is 210H). */
USB_SHORT_GET_LOW(USB_DEVICE_SPECIFIC_BCD_VERSION),
USB_SHORT_GET_HIGH(USB_DEVICE_SPECIFIC_BCD_VERSION),
/* Class code (assigned by the USB-IF). */
USB_DEVICE_CLASS,
/* Subclass code (assigned by the USB-IF). */
USB_DEVICE_SUBCLASS,
/* Protocol code (assigned by the USB-IF). */
USB_DEVICE_PROTOCOL,
/* Maximum packet size for endpoint zero (only 8, 16, 32, or 64 are valid) */
USB_CONTROL_MAX_PACKET_SIZE,
USB_SHORT_GET_LOW(USB_DEVICE_VID),
USB_SHORT_GET_HIGH(USB_DEVICE_VID), /* Vendor ID (assigned by the USB-IF) */
USB_SHORT_GET_LOW(USB_DEVICE_PID),
USB_SHORT_GET_HIGH(USB_DEVICE_PID), /* Product ID (assigned by the manufacturer) */
/* Device release number in binary-coded decimal */
USB_SHORT_GET_LOW(USB_DEVICE_DEMO_BCD_VERSION),
USB_SHORT_GET_HIGH(USB_DEVICE_DEMO_BCD_VERSION),
/* Index of string descriptor describing manufacturer */
0x01,
/* Index of string descriptor describing product */
0x02,
/* Index of string descriptor describing the device's serial number */
0x03,
/* Number of possible configurations */
USB_DEVICE_CONFIGURATION_COUNT,
};
/* Define configuration descriptor */
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
uint8_t g_UsbDeviceConfigurationDescriptor[] = {
/* Configuration Descriptor Size*/
USB_DESCRIPTOR_LENGTH_CONFIGURE,
/* CONFIGURATION Descriptor Type */
USB_DESCRIPTOR_TYPE_CONFIGURE,
/* Total length of data returned for this configuration. */
USB_SHORT_GET_LOW(USB_DESCRIPTOR_LENGTH_CONFIGURE +
(USB_IAD_DESC_SIZE + USB_DESCRIPTOR_LENGTH_INTERFACE + USB_DESCRIPTOR_LENGTH_CDC_HEADER_FUNC +
USB_DESCRIPTOR_LENGTH_CDC_CALL_MANAG + USB_DESCRIPTOR_LENGTH_CDC_ABSTRACT +
USB_DESCRIPTOR_LENGTH_CDC_UNION_FUNC + USB_DESCRIPTOR_LENGTH_ENDPOINT +
USB_DESCRIPTOR_LENGTH_INTERFACE + USB_DESCRIPTOR_LENGTH_ENDPOINT +
USB_DESCRIPTOR_LENGTH_ENDPOINT) *
USB_DEVICE_CONFIG_CDC_ACM),
USB_SHORT_GET_HIGH(USB_DESCRIPTOR_LENGTH_CONFIGURE +
(USB_IAD_DESC_SIZE + USB_DESCRIPTOR_LENGTH_INTERFACE + USB_DESCRIPTOR_LENGTH_CDC_HEADER_FUNC +
USB_DESCRIPTOR_LENGTH_CDC_CALL_MANAG + USB_DESCRIPTOR_LENGTH_CDC_ABSTRACT +
USB_DESCRIPTOR_LENGTH_CDC_UNION_FUNC + USB_DESCRIPTOR_LENGTH_ENDPOINT +
USB_DESCRIPTOR_LENGTH_INTERFACE + USB_DESCRIPTOR_LENGTH_ENDPOINT +
USB_DESCRIPTOR_LENGTH_ENDPOINT) *
USB_DEVICE_CONFIG_CDC_ACM),
/* the two cdc interface have almost same interface attribute except for some number index difference etc, so we
could multiply by USB_DEVICE_CONFIG_CDC_ACM when calculate length*/
/* Number of interfaces supported by this configuration */
USB_INTERFACE_COUNT,
/* Value to use as an argument to the SetConfiguration() request to select this configuration */
USB_COMPOSITE_CONFIGURE_INDEX,
/* Index of string descriptor describing this configuration */
0,
/* Configuration characteristics D7: Reserved (set to one) D6: Self-powered D5: Remote Wakeup D4...0: Reserved
(reset to zero) */
(USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_D7_MASK) |
(USB_DEVICE_CONFIG_SELF_POWER << USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_SELF_POWERED_SHIFT) |
(USB_DEVICE_CONFIG_REMOTE_WAKEUP << USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_REMOTE_WAKEUP_SHIFT),
/* Maximum power consumption of the USB * device from the bus in this specific * configuration when the device is
fully * operational. Expressed in 2 mA units * (i.e., 50 = 100 mA). */
USB_DEVICE_MAX_POWER,
/* Interface Association Descriptor */
/* Size of this descriptor in bytes */
USB_IAD_DESC_SIZE,
/* INTERFACE_ASSOCIATION Descriptor Type */
USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION,
/* The first interface number associated with this function */
0x00,
/* The number of contiguous interfaces associated with this function */
0x02,
/* The function belongs to the Communication Device/Interface Class */
USB_CDC_VCOM_CIC_CLASS, USB_CDC_VCOM_CIC_SUBCLASS,
/* The function uses the No class specific protocol required Protocol */
0x00,
/* The Function string descriptor index */
0x02,
/* Interface Descriptor */
USB_DESCRIPTOR_LENGTH_INTERFACE, USB_DESCRIPTOR_TYPE_INTERFACE, USB_CDC_VCOM_CIC_INTERFACE_INDEX, USB_CDC_VCOM_CIC_INTERFACE_ALTERNATE_0,
USB_CDC_VCOM_CIC_ENDPOINT_COUNT, USB_CDC_VCOM_CIC_CLASS, USB_CDC_VCOM_CIC_SUBCLASS, USB_CDC_VCOM_CIC_PROTOCOL, 0x00,
/* CDC Class-Specific descriptor */
USB_DESCRIPTOR_LENGTH_CDC_HEADER_FUNC, /* Size of this descriptor in bytes */
USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE, /* CS_INTERFACE Descriptor Type */
USB_CDC_HEADER_FUNC_DESC, 0x10,
0x01, /* USB Class Definitions for Communications the Communication specification version 1.10 */
USB_DESCRIPTOR_LENGTH_CDC_CALL_MANAG, /* Size of this descriptor in bytes */
USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE, /* CS_INTERFACE Descriptor Type */
USB_CDC_CALL_MANAGEMENT_FUNC_DESC,
0x01, /*Bit 0: Whether device handle call management itself 1, Bit 1: Whether device can send/receive call
management information over a Data Class Interface 0 */
0x01, /* Indicates multiplexed commands are handled via data interface */
USB_DESCRIPTOR_LENGTH_CDC_ABSTRACT, /* Size of this descriptor in bytes */
USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE, /* CS_INTERFACE Descriptor Type */
USB_CDC_ABSTRACT_CONTROL_FUNC_DESC,
0x06, /* Bit 0: Whether device supports the request combination of Set_Comm_Feature, Clear_Comm_Feature, and
Get_Comm_Feature 0, Bit 1: Whether device supports the request combination of Set_Line_Coding,
Set_Control_Line_State, Get_Line_Coding, and the notification Serial_State 1, Bit ... */
USB_DESCRIPTOR_LENGTH_CDC_UNION_FUNC, /* Size of this descriptor in bytes */
USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE, /* CS_INTERFACE Descriptor Type */
USB_CDC_UNION_FUNC_DESC,
USB_CDC_VCOM_CIC_INTERFACE_INDEX, /* The interface number of the Communications or Data Class interface */
USB_CDC_VCOM_DIC_INTERFACE_INDEX, /* Interface number of subordinate interface in the Union */
/*Notification Endpoint descriptor */
USB_DESCRIPTOR_LENGTH_ENDPOINT, USB_DESCRIPTOR_TYPE_ENDPOINT,
USB_CDC_VCOM_CIC_INTERRUPT_IN_ENDPOINT | (USB_IN << 7U), USB_ENDPOINT_INTERRUPT,
USB_SHORT_GET_LOW(FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE), USB_SHORT_GET_HIGH(FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE),
FS_CDC_VCOM_INTERRUPT_IN_INTERVAL,
/* Data Interface Descriptor */
USB_DESCRIPTOR_LENGTH_INTERFACE, USB_DESCRIPTOR_TYPE_INTERFACE, USB_CDC_VCOM_DIC_INTERFACE_INDEX, USB_CDC_VCOM_DIC_INTERFACE_ALTERNATE_0,
USB_CDC_VCOM_DIC_ENDPOINT_COUNT, USB_CDC_VCOM_DIC_CLASS, USB_CDC_VCOM_DIC_SUBCLASS, USB_CDC_VCOM_DIC_PROTOCOL,
0x00, /* Interface Description String Index*/
/*Bulk IN Endpoint descriptor */
USB_DESCRIPTOR_LENGTH_ENDPOINT, USB_DESCRIPTOR_TYPE_ENDPOINT, USB_CDC_VCOM_DIC_BULK_IN_ENDPOINT | (USB_IN << 7U),
USB_ENDPOINT_BULK, USB_SHORT_GET_LOW(FS_CDC_VCOM_BULK_IN_PACKET_SIZE),
USB_SHORT_GET_HIGH(FS_CDC_VCOM_BULK_IN_PACKET_SIZE), 0x00, /* The polling interval value is every 0 Frames */
/*Bulk OUT Endpoint descriptor */
USB_DESCRIPTOR_LENGTH_ENDPOINT, USB_DESCRIPTOR_TYPE_ENDPOINT, USB_CDC_VCOM_DIC_BULK_OUT_ENDPOINT | (USB_OUT << 7U),
USB_ENDPOINT_BULK, USB_SHORT_GET_LOW(FS_CDC_VCOM_BULK_OUT_PACKET_SIZE),
USB_SHORT_GET_HIGH(FS_CDC_VCOM_BULK_OUT_PACKET_SIZE), 0x00, /* The polling interval value is every 0 Frames */
/*****VCOM_2 descriptor*****/
/* Interface Association Descriptor */
/* Size of this descriptor in bytes */
USB_IAD_DESC_SIZE,
/* INTERFACE_ASSOCIATION Descriptor Type */
USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION,
/* The first interface number associated with this function */
0x02,
/* The number of contiguous interfaces associated with this function */
0x02,
/* The function belongs to the Communication Device/Interface Class */
USB_CDC_VCOM_CIC_CLASS, USB_CDC_VCOM_CIC_SUBCLASS,
/* The function uses the No class specific protocol required Protocol */
0x00,
/* The Function string descriptor index */
0x02,
/* CDC Interface Descriptor */
USB_DESCRIPTOR_LENGTH_INTERFACE, USB_DESCRIPTOR_TYPE_INTERFACE, USB_CDC_VCOM_CIC_INTERFACE_INDEX_2, USB_CDC_VCOM_CIC_INTERFACE_2_ALTERNATE_0,
USB_CDC_VCOM_CIC_ENDPOINT_COUNT_2, USB_CDC_VCOM_CIC_CLASS, USB_CDC_VCOM_CIC_SUBCLASS, USB_CDC_VCOM_CIC_PROTOCOL,
0x00,
/* CDC Class-Specific descriptor */
USB_DESCRIPTOR_LENGTH_CDC_HEADER_FUNC, /* Size of this descriptor in bytes */
USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE, /* CS_INTERFACE Descriptor Type */
USB_CDC_HEADER_FUNC_DESC, 0x10,
0x01, /* USB Class Definitions for Communications the Communication specification version 1.10 */
USB_DESCRIPTOR_LENGTH_CDC_CALL_MANAG, /* Size of this descriptor in bytes */
USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE, /* CS_INTERFACE Descriptor Type */
USB_CDC_CALL_MANAGEMENT_FUNC_DESC,
0x01, /*Bit 0: Whether device handle call management itself 1, Bit 1: Whether device can send/receive call
management information over a Data Class Interface 0 */
0x01, /* Indicates multiplexed commands are handled via data interface */
USB_DESCRIPTOR_LENGTH_CDC_ABSTRACT, /* Size of this descriptor in bytes */
USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE, /* CS_INTERFACE Descriptor Type */
USB_CDC_ABSTRACT_CONTROL_FUNC_DESC,
0x06, /* Bit 0: Whether device supports the request combination of Set_Comm_Feature, Clear_Comm_Feature, and
Get_Comm_Feature 0, Bit 1: Whether device supports the request combination of Set_Line_Coding,
Set_Control_Line_State, Get_Line_Coding, and the notification Serial_State 1, Bit ... */
USB_DESCRIPTOR_LENGTH_CDC_UNION_FUNC, /* Size of this descriptor in bytes */
USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE, /* CS_INTERFACE Descriptor Type */
USB_CDC_UNION_FUNC_DESC,
USB_CDC_VCOM_CIC_INTERFACE_INDEX_2, /* The interface number of the Communications or Data Class interface */
USB_CDC_VCOM_DIC_INTERFACE_INDEX_2, /* Interface number of subordinate interface in the Union */
/*Notification Endpoint descriptor */
USB_DESCRIPTOR_LENGTH_ENDPOINT, USB_DESCRIPTOR_TYPE_ENDPOINT,
USB_CDC_VCOM_CIC_INTERRUPT_IN_ENDPOINT_2 | (USB_IN << 7U), USB_ENDPOINT_INTERRUPT,
USB_SHORT_GET_LOW(FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE_2),
USB_SHORT_GET_HIGH(FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE_2), FS_CDC_VCOM_INTERRUPT_IN_INTERVAL_2,
/* Data Interface Descriptor */
USB_DESCRIPTOR_LENGTH_INTERFACE, USB_DESCRIPTOR_TYPE_INTERFACE, USB_CDC_VCOM_DIC_INTERFACE_INDEX_2, USB_CDC_VCOM_DIC_INTERFACE_2_ALTERNATE_0,
USB_CDC_VCOM_DIC_ENDPOINT_COUNT_2, USB_CDC_VCOM_DIC_CLASS, USB_CDC_VCOM_DIC_SUBCLASS, USB_CDC_VCOM_DIC_PROTOCOL,
0x00, /* Interface Description String Index*/
/*Bulk IN Endpoint descriptor */
USB_DESCRIPTOR_LENGTH_ENDPOINT, USB_DESCRIPTOR_TYPE_ENDPOINT, USB_CDC_VCOM_DIC_BULK_IN_ENDPOINT_2 | (USB_IN << 7U),
USB_ENDPOINT_BULK, USB_SHORT_GET_LOW(FS_CDC_VCOM_BULK_IN_PACKET_SIZE_2),
USB_SHORT_GET_HIGH(FS_CDC_VCOM_BULK_IN_PACKET_SIZE_2), 0x00, /* The polling interval value is every 0 Frames */
/*Bulk OUT Endpoint descriptor */
USB_DESCRIPTOR_LENGTH_ENDPOINT, USB_DESCRIPTOR_TYPE_ENDPOINT,
USB_CDC_VCOM_DIC_BULK_OUT_ENDPOINT_2 | (USB_OUT << 7U), USB_ENDPOINT_BULK,
USB_SHORT_GET_LOW(FS_CDC_VCOM_BULK_OUT_PACKET_SIZE_2), USB_SHORT_GET_HIGH(FS_CDC_VCOM_BULK_OUT_PACKET_SIZE_2),
0x00, /* The polling interval value is every 0 Frames */
};
#if (defined(USB_DEVICE_CONFIG_CV_TEST) && (USB_DEVICE_CONFIG_CV_TEST > 0U))
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
uint8_t g_UsbDeviceQualifierDescriptor[USB_DESCRIPTOR_LENGTH_DEVICE_QUALITIER] = {
USB_DESCRIPTOR_LENGTH_DEVICE_QUALITIER, /* Size of this descriptor in bytes */
USB_DESCRIPTOR_TYPE_DEVICE_QUALITIER, /* DEVICE Descriptor Type */
USB_SHORT_GET_LOW(USB_DEVICE_SPECIFIC_BCD_VERSION),
USB_SHORT_GET_HIGH(USB_DEVICE_SPECIFIC_BCD_VERSION), /* USB Specification Release Number in
Binary-Coded Decimal (i.e., 2.10 is 210H). */
USB_DEVICE_CLASS, /* Class code (assigned by the USB-IF). */
USB_DEVICE_SUBCLASS, /* Subclass code (assigned by the USB-IF). */
USB_DEVICE_PROTOCOL, /* Protocol code (assigned by the USB-IF). */
USB_CONTROL_MAX_PACKET_SIZE, /* Maximum packet size for endpoint zero
(only 8, 16, 32, or 64 are valid) */
0x00U, /* Number of Other-speed Configurations */
0x00U, /* Reserved for future use, must be zero */
};
#endif
/* Define string descriptor */
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
uint8_t g_UsbDeviceString0[] = {
2U + 2U,
USB_DESCRIPTOR_TYPE_STRING,
0x09,
0x04,
};
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
uint8_t g_UsbDeviceString1[] = {
2U + 2U * 18U, USB_DESCRIPTOR_TYPE_STRING,
'N', 0x00U,
'X', 0x00U,
'P', 0x00U,
' ', 0x00U,
'S', 0x00U,
'E', 0x00U,
'M', 0x00U,
'I', 0x00U,
'C', 0x00U,
'O', 0x00U,
'N', 0x00U,
'D', 0x00U,
'U', 0x00U,
'C', 0x00U,
'T', 0x00U,
'O', 0x00U,
'R', 0x00U,
'S', 0x00U,
};
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
uint8_t g_UsbDeviceString2[] = {2U + 2U * 18U, USB_DESCRIPTOR_TYPE_STRING,
'U', 0,
'S', 0,
'B', 0,
' ', 0,
'C', 0,
'O', 0,
'M', 0,
'P', 0,
'O', 0,
'S', 0,
'I', 0,
'T', 0,
'E', 0,
' ', 0,
'D', 0,
'E', 0,
'M', 0,
'O', 0};
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
uint8_t g_UsbDeviceString3[] = {2U + 2U * 16U, USB_DESCRIPTOR_TYPE_STRING,
'0', 0x00U,
'1', 0x00U,
'2', 0x00U,
'3', 0x00U,
'4', 0x00U,
'5', 0x00U,
'6', 0x00U,
'7', 0x00U,
'8', 0x00U,
'9', 0x00U,
'A', 0x00U,
'B', 0x00U,
'C', 0x00U,
'D', 0x00U,
'E', 0x00U,
'F', 0x00U};
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
uint8_t g_UsbDeviceString4[] = {2U + 2U * 17U, USB_DESCRIPTOR_TYPE_STRING,
'M', 0,
'C', 0,
'U', 0,
' ', 0,
'C', 0,
'D', 0,
'C', 0,
' ', 0,
'C', 0,
'D', 0,
'C', 0,
'2', 0,
' ', 0,
'D', 0,
'E', 0,
'M', 0,
'O', 0};
/* Define string descriptor size */
uint32_t g_UsbDeviceStringDescriptorLength[USB_DEVICE_STRING_COUNT] = {
sizeof(g_UsbDeviceString0), sizeof(g_UsbDeviceString1), sizeof(g_UsbDeviceString2), sizeof(g_UsbDeviceString3),
sizeof(g_UsbDeviceString4)};
uint8_t *g_UsbDeviceStringDescriptorArray[USB_DEVICE_STRING_COUNT] = {
g_UsbDeviceString0, g_UsbDeviceString1, g_UsbDeviceString2, g_UsbDeviceString3, g_UsbDeviceString4};
usb_language_t g_UsbDeviceLanguage[USB_DEVICE_LANGUAGE_COUNT] = {{
g_UsbDeviceStringDescriptorArray,
g_UsbDeviceStringDescriptorLength,
(uint16_t)0x0409,
}};
usb_language_list_t g_UsbDeviceLanguageList = {
g_UsbDeviceString0,
sizeof(g_UsbDeviceString0),
g_UsbDeviceLanguage,
USB_DEVICE_LANGUAGE_COUNT,
};
/*******************************************************************************
* Code
******************************************************************************/
/*!
* @brief USB device get device descriptor function.
*
* This function gets the device descriptor of the USB device.
*
* @param handle The USB device handle.
* @param deviceDescriptor The pointer to the device descriptor structure.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceGetDeviceDescriptor(usb_device_handle handle,
usb_device_get_device_descriptor_struct_t *deviceDescriptor)
{
deviceDescriptor->buffer = g_UsbDeviceDescriptor;
deviceDescriptor->length = USB_DESCRIPTOR_LENGTH_DEVICE;
return kStatus_USB_Success;
}
#if (defined(USB_DEVICE_CONFIG_CV_TEST) && (USB_DEVICE_CONFIG_CV_TEST > 0U))
/* Get device qualifier descriptor request */
usb_status_t USB_DeviceGetDeviceQualifierDescriptor(
usb_device_handle handle, usb_device_get_device_qualifier_descriptor_struct_t *deviceQualifierDescriptor)
{
deviceQualifierDescriptor->buffer = g_UsbDeviceQualifierDescriptor;
deviceQualifierDescriptor->length = USB_DESCRIPTOR_LENGTH_DEVICE_QUALITIER;
return kStatus_USB_Success;
}
#endif
/*!
* @brief USB device get configuration descriptor function.
*
* This function gets the configuration descriptor of the USB device.
*
* @param handle The USB device handle.
* @param configurationDescriptor The pointer to the configuration descriptor structure.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceGetConfigurationDescriptor(
usb_device_handle handle, usb_device_get_configuration_descriptor_struct_t *configurationDescriptor)
{
if (USB_COMPOSITE_CONFIGURE_INDEX > configurationDescriptor->configuration)
{
configurationDescriptor->buffer = g_UsbDeviceConfigurationDescriptor;
configurationDescriptor->length = USB_DESCRIPTOR_LENGTH_CONFIGURATION_ALL;
return kStatus_USB_Success;
}
return kStatus_USB_InvalidRequest;
}
/*!
* @brief USB device get string descriptor function.
*
* This function gets the string descriptor of the USB device.
*
* @param handle The USB device handle.
* @param stringDescriptor Pointer to the string descriptor structure.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceGetStringDescriptor(usb_device_handle handle,
usb_device_get_string_descriptor_struct_t *stringDescriptor)
{
if (stringDescriptor->stringIndex == 0)
{
stringDescriptor->buffer = (uint8_t *)g_UsbDeviceLanguageList.languageString;
stringDescriptor->length = g_UsbDeviceLanguageList.stringLength;
}
else
{
uint8_t langId = 0;
uint8_t langIndex = USB_DEVICE_STRING_COUNT;
for (; langId < USB_DEVICE_LANGUAGE_COUNT; langId++)
{
if (stringDescriptor->languageId == g_UsbDeviceLanguageList.languageList[langId].languageId)
{
if (stringDescriptor->stringIndex < USB_DEVICE_STRING_COUNT)
{
langIndex = stringDescriptor->stringIndex;
}
break;
}
}
if (USB_DEVICE_STRING_COUNT == langIndex)
{
return kStatus_USB_InvalidRequest;
}
stringDescriptor->buffer = (uint8_t *)g_UsbDeviceLanguageList.languageList[langId].string[langIndex];
stringDescriptor->length = g_UsbDeviceLanguageList.languageList[langId].length[langIndex];
}
return kStatus_USB_Success;
}
/*!
* @brief USB device set speed function.
*
* This function sets the speed of the USB device.
*
* Due to the difference of HS and FS descriptors, the device descriptors and configurations need to be updated to match
* current speed.
* As the default, the device descriptors and configurations are configured by using FS parameters for both EHCI and
* KHCI.
* When the EHCI is enabled, the application needs to call this function to update device by using current speed.
* The updated information includes endpoint max packet size, endpoint interval, etc.
*
* @param handle The USB device handle.
* @param speed Speed type. USB_SPEED_HIGH/USB_SPEED_FULL/USB_SPEED_LOW.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceSetSpeed(usb_device_handle handle, uint8_t speed)
{
usb_descriptor_union_t *ptr1;
usb_descriptor_union_t *ptr2;
ptr1 = (usb_descriptor_union_t *)(&g_UsbDeviceConfigurationDescriptor[0]);
ptr2 = (usb_descriptor_union_t *)(&g_UsbDeviceConfigurationDescriptor[USB_DESCRIPTOR_LENGTH_CONFIGURATION_ALL - 1]);
while (ptr1 < ptr2)
{
if (ptr1->common.bDescriptorType == USB_DESCRIPTOR_TYPE_ENDPOINT)
{
if (USB_SPEED_HIGH == speed)
{
if ((USB_CDC_VCOM_CIC_INTERRUPT_IN_ENDPOINT ==
(ptr1->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)) &&
((ptr1->endpoint.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN))
{
ptr1->endpoint.bInterval = HS_CDC_VCOM_INTERRUPT_IN_INTERVAL;
USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(HS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE,
ptr1->endpoint.wMaxPacketSize);
}
else if ((USB_CDC_VCOM_DIC_BULK_IN_ENDPOINT ==
(ptr1->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)) &&
((ptr1->endpoint.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN))
{
USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(HS_CDC_VCOM_BULK_IN_PACKET_SIZE, ptr1->endpoint.wMaxPacketSize);
}
else if ((USB_CDC_VCOM_DIC_BULK_OUT_ENDPOINT ==
(ptr1->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)) &&
((ptr1->endpoint.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_OUT))
{
USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(HS_CDC_VCOM_BULK_OUT_PACKET_SIZE, ptr1->endpoint.wMaxPacketSize);
}
else if ((USB_CDC_VCOM_CIC_INTERRUPT_IN_ENDPOINT_2 ==
(ptr1->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)) &&
((ptr1->endpoint.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN))
{
ptr1->endpoint.bInterval = HS_CDC_VCOM_INTERRUPT_IN_INTERVAL_2;
USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(HS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE_2,
ptr1->endpoint.wMaxPacketSize);
}
else if ((USB_CDC_VCOM_DIC_BULK_IN_ENDPOINT_2 ==
(ptr1->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)) &&
((ptr1->endpoint.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN))
{
USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(HS_CDC_VCOM_BULK_IN_PACKET_SIZE_2,
ptr1->endpoint.wMaxPacketSize);
}
else if ((USB_CDC_VCOM_DIC_BULK_OUT_ENDPOINT_2 ==
(ptr1->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)) &&
((ptr1->endpoint.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_OUT))
{
USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(HS_CDC_VCOM_BULK_OUT_PACKET_SIZE_2,
ptr1->endpoint.wMaxPacketSize);
}
else
{
}
}
else
{
if ((USB_CDC_VCOM_CIC_INTERRUPT_IN_ENDPOINT ==
(ptr1->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)) &&
((ptr1->endpoint.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN))
{
ptr1->endpoint.bInterval = FS_CDC_VCOM_INTERRUPT_IN_INTERVAL;
USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE,
ptr1->endpoint.wMaxPacketSize);
}
else if ((USB_CDC_VCOM_DIC_BULK_IN_ENDPOINT ==
(ptr1->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)) &&
((ptr1->endpoint.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN))
{
USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(FS_CDC_VCOM_BULK_IN_PACKET_SIZE, ptr1->endpoint.wMaxPacketSize);
}
else if ((USB_CDC_VCOM_DIC_BULK_OUT_ENDPOINT ==
(ptr1->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)) &&
((ptr1->endpoint.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_OUT))
{
USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(FS_CDC_VCOM_BULK_OUT_PACKET_SIZE, ptr1->endpoint.wMaxPacketSize);
}
else if ((USB_CDC_VCOM_CIC_INTERRUPT_IN_ENDPOINT_2 ==
(ptr1->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)) &&
((ptr1->endpoint.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN))
{
ptr1->endpoint.bInterval = FS_CDC_VCOM_INTERRUPT_IN_INTERVAL_2;
USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE_2,
ptr1->endpoint.wMaxPacketSize);
}
else if ((USB_CDC_VCOM_DIC_BULK_IN_ENDPOINT_2 ==
(ptr1->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)) &&
((ptr1->endpoint.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN))
{
USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(FS_CDC_VCOM_BULK_IN_PACKET_SIZE_2,
ptr1->endpoint.wMaxPacketSize);
}
else if ((USB_CDC_VCOM_DIC_BULK_OUT_ENDPOINT_2 ==
(ptr1->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)) &&
((ptr1->endpoint.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_OUT))
{
USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(FS_CDC_VCOM_BULK_OUT_PACKET_SIZE_2,
ptr1->endpoint.wMaxPacketSize);
}
else
{
}
}
}
ptr1 = (usb_descriptor_union_t *)((uint8_t *)ptr1 + ptr1->common.bLength);
}
for (int i = 0; i < USB_CDC_VCOM_CIC_ENDPOINT_COUNT; i++)
{
if (USB_SPEED_HIGH == speed)
{
g_cdcVcomCicEndpoints[i].maxPacketSize = HS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE;
g_cdcVcomCicEndpoints[i].interval = HS_CDC_VCOM_INTERRUPT_IN_INTERVAL;
}
else
{
g_cdcVcomCicEndpoints[i].maxPacketSize = FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE;
g_cdcVcomCicEndpoints[i].interval = FS_CDC_VCOM_INTERRUPT_IN_INTERVAL;
}
}
for (int i = 0; i < USB_CDC_VCOM_DIC_ENDPOINT_COUNT; i++)
{
if (USB_SPEED_HIGH == speed)
{
if (g_cdcVcomDicEndpoints[i].endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK)
{
g_cdcVcomDicEndpoints[i].maxPacketSize = HS_CDC_VCOM_BULK_IN_PACKET_SIZE;
}
else
{
g_cdcVcomDicEndpoints[i].maxPacketSize = HS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
}
}
else
{
if (g_cdcVcomDicEndpoints[i].endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK)
{
g_cdcVcomDicEndpoints[i].maxPacketSize = FS_CDC_VCOM_BULK_IN_PACKET_SIZE;
}
else
{
g_cdcVcomDicEndpoints[i].maxPacketSize = FS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
}
}
}
for (int i = 0; i < USB_CDC_VCOM_CIC_ENDPOINT_COUNT_2; i++)
{
if (USB_SPEED_HIGH == speed)
{
g_cdcVcomCicEndpoints_2[i].maxPacketSize = HS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE_2;
g_cdcVcomCicEndpoints_2[i].interval = HS_CDC_VCOM_INTERRUPT_IN_INTERVAL_2;
}
else
{
g_cdcVcomCicEndpoints_2[i].maxPacketSize = FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE_2;
g_cdcVcomCicEndpoints_2[i].interval = FS_CDC_VCOM_INTERRUPT_IN_INTERVAL_2;
}
}
for (int i = 0; i < USB_CDC_VCOM_DIC_ENDPOINT_COUNT_2; i++)
{
if (USB_SPEED_HIGH == speed)
{
if (g_cdcVcomDicEndpoints_2[i].endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK)
{
g_cdcVcomDicEndpoints_2[i].maxPacketSize = HS_CDC_VCOM_BULK_IN_PACKET_SIZE_2;
}
else
{
g_cdcVcomDicEndpoints_2[i].maxPacketSize = HS_CDC_VCOM_BULK_OUT_PACKET_SIZE_2;
}
}
else
{
if (g_cdcVcomDicEndpoints_2[i].endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK)
{
g_cdcVcomDicEndpoints_2[i].maxPacketSize = FS_CDC_VCOM_BULK_IN_PACKET_SIZE_2;
}
else
{
g_cdcVcomDicEndpoints_2[i].maxPacketSize = FS_CDC_VCOM_BULK_OUT_PACKET_SIZE_2;
}
}
}
return kStatus_USB_Success;
}

View file

@ -0,0 +1,244 @@
/*
* Copyright 2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _USB_DEVICE_DESCRIPTOR_H_
#define _USB_DEVICE_DESCRIPTOR_H_ 1
/*******************************************************************************
* Definitions
******************************************************************************/
#define USB_DEVICE_SPECIFIC_BCD_VERSION (0x0200)
#define USB_DEVICE_DEMO_BCD_VERSION (0x0101U)
#define USB_DEVICE_VID (0x1FC9U)
#define USB_DEVICE_PID (0x00A3U)
/* Communication Class SubClass Codes */
#define USB_CDC_DIRECT_LINE_CONTROL_MODEL (0x01)
#define USB_CDC_ABSTRACT_CONTROL_MODEL (0x02)
#define USB_CDC_TELEPHONE_CONTROL_MODEL (0x03)
#define USB_CDC_MULTI_CHANNEL_CONTROL_MODEL (0x04)
#define USB_CDC_CAPI_CONTROL_MOPDEL (0x05)
#define USB_CDC_ETHERNET_NETWORKING_CONTROL_MODEL (0x06)
#define USB_CDC_ATM_NETWORKING_CONTROL_MODEL (0x07)
#define USB_CDC_WIRELESS_HANDSET_CONTROL_MODEL (0x08)
#define USB_CDC_DEVICE_MANAGEMENT (0x09)
#define USB_CDC_MOBILE_DIRECT_LINE_MODEL (0x0A)
#define USB_CDC_OBEX (0x0B)
#define USB_CDC_ETHERNET_EMULATION_MODEL (0x0C)
/* Communication Class Protocol Codes */
#define USB_CDC_NO_CLASS_SPECIFIC_PROTOCOL (0x00) /*also for Data Class Protocol Code */
#define USB_CDC_AT_250_PROTOCOL (0x01)
#define USB_CDC_AT_PCCA_101_PROTOCOL (0x02)
#define USB_CDC_AT_PCCA_101_ANNEX_O (0x03)
#define USB_CDC_AT_GSM_7_07 (0x04)
#define USB_CDC_AT_3GPP_27_007 (0x05)
#define USB_CDC_AT_TIA_CDMA (0x06)
#define USB_CDC_ETHERNET_EMULATION_PROTOCOL (0x07)
#define USB_CDC_EXTERNAL_PROTOCOL (0xFE)
#define USB_CDC_VENDOR_SPECIFIC (0xFF) /*also for Data Class Protocol Code */
/* Data Class Protocol Codes */
#define USB_CDC_PYHSICAL_INTERFACE_PROTOCOL (0x30)
#define USB_CDC_HDLC_PROTOCOL (0x31)
#define USB_CDC_TRANSPARENT_PROTOCOL (0x32)
#define USB_CDC_MANAGEMENT_PROTOCOL (0x50)
#define USB_CDC_DATA_LINK_Q931_PROTOCOL (0x51)
#define USB_CDC_DATA_LINK_Q921_PROTOCOL (0x52)
#define USB_CDC_DATA_COMPRESSION_V42BIS (0x90)
#define USB_CDC_EURO_ISDN_PROTOCOL (0x91)
#define USB_CDC_RATE_ADAPTION_ISDN_V24 (0x92)
#define USB_CDC_CAPI_COMMANDS (0x93)
#define USB_CDC_HOST_BASED_DRIVER (0xFD)
#define USB_CDC_UNIT_FUNCTIONAL (0xFE)
/* Descriptor SubType in Communications Class Functional Descriptors */
#define USB_CDC_HEADER_FUNC_DESC (0x00)
#define USB_CDC_CALL_MANAGEMENT_FUNC_DESC (0x01)
#define USB_CDC_ABSTRACT_CONTROL_FUNC_DESC (0x02)
#define USB_CDC_DIRECT_LINE_FUNC_DESC (0x03)
#define USB_CDC_TELEPHONE_RINGER_FUNC_DESC (0x04)
#define USB_CDC_TELEPHONE_REPORT_FUNC_DESC (0x05)
#define USB_CDC_UNION_FUNC_DESC (0x06)
#define USB_CDC_COUNTRY_SELECT_FUNC_DESC (0x07)
#define USB_CDC_TELEPHONE_MODES_FUNC_DESC (0x08)
#define USB_CDC_TERMINAL_FUNC_DESC (0x09)
#define USB_CDC_NETWORK_CHANNEL_FUNC_DESC (0x0A)
#define USB_CDC_PROTOCOL_UNIT_FUNC_DESC (0x0B)
#define USB_CDC_EXTENSION_UNIT_FUNC_DESC (0x0C)
#define USB_CDC_MULTI_CHANNEL_FUNC_DESC (0x0D)
#define USB_CDC_CAPI_CONTROL_FUNC_DESC (0x0E)
#define USB_CDC_ETHERNET_NETWORKING_FUNC_DESC (0x0F)
#define USB_CDC_ATM_NETWORKING_FUNC_DESC (0x10)
#define USB_CDC_WIRELESS_CONTROL_FUNC_DESC (0x11)
#define USB_CDC_MOBILE_DIRECT_LINE_FUNC_DESC (0x12)
#define USB_CDC_MDLM_DETAIL_FUNC_DESC (0x13)
#define USB_CDC_DEVICE_MANAGEMENT_FUNC_DESC (0x14)
#define USB_CDC_OBEX_FUNC_DESC (0x15)
#define USB_CDC_COMMAND_SET_FUNC_DESC (0x16)
#define USB_CDC_COMMAND_SET_DETAIL_FUNC_DESC (0x17)
#define USB_CDC_TELEPHONE_CONTROL_FUNC_DESC (0x18)
#define USB_CDC_OBEX_SERVICE_ID_FUNC_DESC (0x19)
/* usb descriptor length */
#define USB_DESCRIPTOR_LENGTH_CONFIGURATION_ALL (sizeof(g_UsbDeviceConfigurationDescriptor))
#define USB_CDC_VCOM_REPORT_DESCRIPTOR_LENGTH (33)
#define USB_IAD_DESC_SIZE (8)
#define USB_DESCRIPTOR_LENGTH_CDC_HEADER_FUNC (5)
#define USB_DESCRIPTOR_LENGTH_CDC_CALL_MANAG (5)
#define USB_DESCRIPTOR_LENGTH_CDC_ABSTRACT (4)
#define USB_DESCRIPTOR_LENGTH_CDC_UNION_FUNC (5)
#define USB_DEVICE_CONFIGURATION_COUNT (1)
#define USB_DEVICE_STRING_COUNT (5)
#define USB_DEVICE_LANGUAGE_COUNT (1)
#define USB_INTERFACE_COUNT (4)
#define USB_COMPOSITE_CONFIGURE_INDEX (1)
#define USB_MSC_DISK_CLASS (0x08)
/* scsi command set */
#define USB_MSC_DISK_SUBCLASS (0x06)
/* bulk only transport protocol */
#define USB_MSC_DISK_PROTOCOL (0x50)
/* Configuration, interface and endpoint. */
#define USB_CDC_VCOM_CIC_CLASS (0x02)
#define USB_CDC_VCOM_CIC_SUBCLASS (0x02)
#define USB_CDC_VCOM_CIC_PROTOCOL (0x00)
#define USB_CDC_VCOM_DIC_CLASS (0x0A)
#define USB_CDC_VCOM_DIC_SUBCLASS (0x00)
#define USB_CDC_VCOM_DIC_PROTOCOL (0x00)
#define USB_CDC_VCOM_INTERFACE_COUNT (2)
#define USB_CDC_VCOM_INTERFACE_COUNT_2 (2)
#define USB_CDC_VCOM_CIC_INTERFACE_INDEX (0)
#define USB_CDC_VCOM_DIC_INTERFACE_INDEX (1)
#define USB_CDC_VCOM_CIC_INTERFACE_INDEX_2 (2)
#define USB_CDC_VCOM_DIC_INTERFACE_INDEX_2 (3)
#define USB_CDC_VCOM_CIC_INTERFACE_ALTERNATE_COUNT (1)
#define USB_CDC_VCOM_DIC_INTERFACE_ALTERNATE_COUNT (1)
#define USB_CDC_VCOM_CIC_INTERFACE_ALTERNATE_0 (0)
#define USB_CDC_VCOM_DIC_INTERFACE_ALTERNATE_0 (0)
#define USB_CDC_VCOM_CIC_INTERFACE_2_ALTERNATE_COUNT (1)
#define USB_CDC_VCOM_DIC_INTERFACE_2_ALTERNATE_COUNT (1)
#define USB_CDC_VCOM_CIC_INTERFACE_2_ALTERNATE_0 (0)
#define USB_CDC_VCOM_DIC_INTERFACE_2_ALTERNATE_0 (0)
#define USB_CDC_VCOM_CIC_ENDPOINT_COUNT (1)
#define USB_CDC_VCOM_CIC_ENDPOINT_COUNT_2 (1)
#define USB_CDC_VCOM_CIC_INTERRUPT_IN_ENDPOINT (1)
#define USB_CDC_VCOM_CIC_INTERRUPT_IN_ENDPOINT_2 (2)
#define USB_CDC_VCOM_DIC_ENDPOINT_COUNT (2)
#define USB_CDC_VCOM_DIC_ENDPOINT_COUNT_2 (2)
#define USB_CDC_VCOM_DIC_BULK_IN_ENDPOINT (3)
#define USB_CDC_VCOM_DIC_BULK_OUT_ENDPOINT (3)
#define USB_CDC_VCOM_DIC_BULK_IN_ENDPOINT_2 (4)
#define USB_CDC_VCOM_DIC_BULK_OUT_ENDPOINT_2 (4)
/* Packet size. */
#define HS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE (16)
#define FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE (16)
#define HS_CDC_VCOM_INTERRUPT_IN_INTERVAL (0x07) /* 2^(7-1) = 8ms */
#define FS_CDC_VCOM_INTERRUPT_IN_INTERVAL (0x08)
/* Packet size. */
#define HS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE_2 (16)
#define FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE_2 (16)
#define HS_CDC_VCOM_INTERRUPT_IN_INTERVAL_2 (0x07) /* 2^(7-1) = 8ms */
#define FS_CDC_VCOM_INTERRUPT_IN_INTERVAL_2 (0x08)
#define HS_CDC_VCOM_BULK_IN_PACKET_SIZE (512)
#define FS_CDC_VCOM_BULK_IN_PACKET_SIZE (64)
#define HS_CDC_VCOM_BULK_OUT_PACKET_SIZE (512)
#define FS_CDC_VCOM_BULK_OUT_PACKET_SIZE (64)
#define HS_CDC_VCOM_BULK_IN_PACKET_SIZE_2 (512)
#define FS_CDC_VCOM_BULK_IN_PACKET_SIZE_2 (64)
#define HS_CDC_VCOM_BULK_OUT_PACKET_SIZE_2 (512)
#define FS_CDC_VCOM_BULK_OUT_PACKET_SIZE_2 (64)
/* String descriptor length. */
#define USB_DESCRIPTOR_LENGTH_STRING0 (sizeof(g_UsbDeviceString0))
#define USB_DESCRIPTOR_LENGTH_STRING1 (sizeof(g_UsbDeviceString1))
#define USB_DESCRIPTOR_LENGTH_STRING2 (sizeof(g_UsbDeviceString2))
#define USB_DESCRIPTOR_LENGTH_STRING3 (sizeof(g_UsbDeviceString3))
#define USB_DESCRIPTOR_LENGTH_STRING4 (sizeof(g_UsbDeviceString4))
#define USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE (0x24)
#define USB_DESCRIPTOR_TYPE_CDC_CS_ENDPOINT (0x25)
/* Class code. */
#define USB_DEVICE_CLASS (0xEF)
#define USB_DEVICE_SUBCLASS (0x02)
#define USB_DEVICE_PROTOCOL (0x01)
#define USB_DEVICE_MAX_POWER (0x32)
/*******************************************************************************
* API
******************************************************************************/
/*!
* @brief USB device set speed function.
*
* This function sets the speed of the USB device.
*
* Due to the difference of HS and FS descriptors, the device descriptors and configurations need to be updated to match
* current speed.
* As the default, the device descriptors and configurations are configured by using FS parameters for both EHCI and
* KHCI.
* When the EHCI is enabled, the application needs to call this function to update device by using current speed.
* The updated information includes endpoint max packet size, endpoint interval, etc.
*
* @param handle The USB device handle.
* @param speed Speed type. USB_SPEED_HIGH/USB_SPEED_FULL/USB_SPEED_LOW.
*
* @return A USB error code or kStatus_USB_Success.
*/
extern usb_status_t USB_DeviceSetSpeed(usb_device_handle handle, uint8_t speed);
#if (defined(USB_DEVICE_CONFIG_CV_TEST) && (USB_DEVICE_CONFIG_CV_TEST > 0U))
/* Get device qualifier descriptor request */
usb_status_t USB_DeviceGetDeviceQualifierDescriptor(
usb_device_handle handle, usb_device_get_device_qualifier_descriptor_struct_t *deviceQualifierDescriptor);
#endif
/*!
* @brief USB device get device descriptor function.
*
* This function gets the device descriptor of the USB device.
*
* @param handle The USB device handle.
* @param deviceDescriptor The pointer to the device descriptor structure.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceGetDeviceDescriptor(usb_device_handle handle,
usb_device_get_device_descriptor_struct_t *deviceDescriptor);
/*!
* @brief USB device get configuration descriptor function.
*
* This function gets the configuration descriptor of the USB device.
*
* @param handle The USB device handle.
* @param configurationDescriptor The pointer to the configuration descriptor structure.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceGetConfigurationDescriptor(
usb_device_handle handle, usb_device_get_configuration_descriptor_struct_t *configurationDescriptor);
/*!
* @brief USB device get string descriptor function.
*
* This function gets the string descriptor of the USB device.
*
* @param handle The USB device handle.
* @param stringDescriptor Pointer to the string descriptor structure.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceGetStringDescriptor(usb_device_handle handle,
usb_device_get_string_descriptor_struct_t *stringDescriptor);
#endif /* _USB_DEVICE_DESCRIPTOR_H_ */

View file

@ -0,0 +1,485 @@
/*
* Copyright 2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h>
#include <stdlib.h>
/*${standard_header_anchor}*/
#include "fsl_device_registers.h"
#include "clock_config.h"
#include "fsl_debug_console.h"
#include "board.h"
#include "usb_device_config.h"
#include "usb.h"
#include "usb_device.h"
#include "usb_device_class.h"
#include "usb_device_cdc_acm.h"
#include "usb_device_ch9.h"
#include "usb_device_descriptor.h"
#include "composite.h"
#include "private.h"
#include <string.h>
#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
#include "usb_phy.h"
#endif
lws_dll2_owner_t scheduler;
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
extern usb_device_endpoint_struct_t g_cdcVcomDicEndpoints[];
extern usb_device_endpoint_struct_t g_cdcVcomDicEndpoints_2[];
extern usb_device_endpoint_struct_t g_cdcVcomCicEndpoints[];
extern usb_device_endpoint_struct_t g_cdcVcomCicEndpoints_2[];
extern usb_device_class_struct_t g_UsbDeviceCdcVcomConfig[2];
/* Line coding of cdc device */
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
static uint8_t s_lineCoding[USB_DEVICE_CONFIG_CDC_ACM][LINE_CODING_SIZE] = {
{/* E.g. 0x00,0xC2,0x01,0x00 : 0x0001C200 is 115200 bits per second */
(LINE_CODING_DTERATE >> 0U) & 0x000000FFU, (LINE_CODING_DTERATE >> 8U) & 0x000000FFU,
(LINE_CODING_DTERATE >> 16U) & 0x000000FFU, (LINE_CODING_DTERATE >> 24U) & 0x000000FFU, LINE_CODING_CHARFORMAT,
LINE_CODING_PARITYTYPE, LINE_CODING_DATABITS},
{/* E.g. 0x00,0xC2,0x01,0x00 : 0x0001C200 is 115200 bits per second */
(LINE_CODING_DTERATE >> 0U) & 0x000000FFU, (LINE_CODING_DTERATE >> 8U) & 0x000000FFU,
(LINE_CODING_DTERATE >> 16U) & 0x000000FFU, (LINE_CODING_DTERATE >> 24U) & 0x000000FFU, LINE_CODING_CHARFORMAT,
LINE_CODING_PARITYTYPE, LINE_CODING_DATABITS},
};
/* Abstract state of cdc device */
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
static uint8_t s_abstractState[USB_DEVICE_CONFIG_CDC_ACM][COMM_FEATURE_DATA_SIZE] = {
{(STATUS_ABSTRACT_STATE >> 0U) & 0x00FFU, (STATUS_ABSTRACT_STATE >> 8U) & 0x00FFU},
{(STATUS_ABSTRACT_STATE >> 0U) & 0x00FFU, (STATUS_ABSTRACT_STATE >> 8U) & 0x00FFU},
};
/* Country code of cdc device */
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
static uint8_t s_countryCode[USB_DEVICE_CONFIG_CDC_ACM][COMM_FEATURE_DATA_SIZE] = {
{(COUNTRY_SETTING >> 0U) & 0x00FFU, (COUNTRY_SETTING >> 8U) & 0x00FFU},
{(COUNTRY_SETTING >> 0U) & 0x00FFU, (COUNTRY_SETTING >> 8U) & 0x00FFU},
};
/* CDC ACM information */
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
usb_cdc_acm_info_t s_usbCdcAcmInfo[USB_DEVICE_CONFIG_CDC_ACM] = {
{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0, 0, 0},
{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0, 0, 0},
};
/* Data buffer for receiving and sending*/
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
static uint8_t s_currRecvBuf[USB_DEVICE_CONFIG_CDC_ACM][DATA_BUFF_SIZE];
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
static uint8_t s_currSendBuf[USB_DEVICE_CONFIG_CDC_ACM][DATA_BUFF_SIZE];
volatile static uint32_t s_recvSize[USB_DEVICE_CONFIG_CDC_ACM] = {0};
volatile static uint32_t s_sendSize[USB_DEVICE_CONFIG_CDC_ACM] = {0};
volatile static usb_device_composite_struct_t *g_deviceComposite;
/*******************************************************************************
* Code
******************************************************************************/
/*!
* @brief CDC class specific callback function.
*last_tick_low
* This function handles the CDC class specific requests.
*
* @param handle The CDC ACM class handle.
* @param event The CDC ACM class event type.
* @param param The parameter of the class specific request.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceCdcVcomCallback(class_handle_t handle, uint32_t event, void *param)
{
uint32_t len;
uint8_t *uartBitmap;
usb_cdc_acm_info_t *acmInfo;
usb_device_cdc_acm_request_param_struct_t *acmReqParam;
usb_device_endpoint_callback_message_struct_t *epCbParam;
volatile usb_cdc_vcom_struct_t *vcomInstance;
usb_status_t error = kStatus_USB_InvalidRequest;
uint8_t i;
acmReqParam = (usb_device_cdc_acm_request_param_struct_t *)param;
epCbParam = (usb_device_endpoint_callback_message_struct_t *)param;
for (i = 0; i < USB_DEVICE_CONFIG_CDC_ACM; i++)
{
if (handle == g_deviceComposite->cdcVcom[i].cdcAcmHandle)
{
break;
}
}
if (i >= USB_DEVICE_CONFIG_CDC_ACM)
{
return error;
}
vcomInstance = &g_deviceComposite->cdcVcom[i];
acmInfo = vcomInstance->usbCdcAcmInfo;
switch (event)
{
case kUSB_DeviceCdcEventSendResponse:
{
if ((epCbParam->length != 0) && (!(epCbParam->length % vcomInstance->bulkInEndpointMaxPacketSize)))
{
/* If the last packet is the size of endpoint, then send also zero-ended packet,
** meaning that we want to inform the host that we do not have any additional
** data, so it can flush the output.
*/
error = USB_DeviceCdcAcmSend(handle, vcomInstance->bulkInEndpoint, NULL, 0);
}
else if ((1 == vcomInstance->attach) && (1 == vcomInstance->startTransactions))
{
if ((epCbParam->buffer != NULL) || ((epCbParam->buffer == NULL) && (epCbParam->length == 0)))
{
/* User: add your own code for send complete event */
/* Schedule buffer for next receive event */
error = USB_DeviceCdcAcmRecv(handle, vcomInstance->bulkOutEndpoint, vcomInstance->currRecvBuf,
vcomInstance->bulkOutEndpointMaxPacketSize);
}
}
else
{
}
}
break;
case kUSB_DeviceCdcEventRecvResponse:
{
if ((1 == vcomInstance->attach) && (1 == vcomInstance->startTransactions))
{
vcomInstance->recvSize = epCbParam->length;
if (!vcomInstance->recvSize)
{
/* Schedule buffer for next rechttps://community.nxp.com/t5/LPCXpresso-IDE/CDC-BulkIn-in-USB-CDC-Example/td-p/550945eive event */
error = USB_DeviceCdcAcmRecv(handle, vcomInstance->bulkOutEndpoint, vcomInstance->currRecvBuf,
vcomInstance->bulkOutEndpointMaxPacketSize);
}
}
}
break;
case kUSB_DeviceCdcEventSerialStateNotif:
((usb_device_cdc_acm_struct_t *)handle)->hasSentState = 0;
error = kStatus_USB_Success;
break;
case kUSB_DeviceCdcEventSendEncapsulatedCommand:
break;
case kUSB_DeviceCdcEventGetEncapsulatedResponse:
break;
case kUSB_DeviceCdcEventSetCommFeature:
if (USB_DEVICE_CDC_FEATURE_ABSTRACT_STATE == acmReqParam->setupValue)
{
if (1 == acmReqParam->isSetup)
{
*(acmReqParam->buffer) = vcomInstance->abstractState;
*(acmReqParam->length) = COMM_FEATURE_DATA_SIZE;
}
else
{
/* no action, data phase, s_abstractState has been assigned */
}
error = kStatus_USB_Success;
}
else if (USB_DEVICE_CDC_FEATURE_COUNTRY_SETTING == acmReqParam->setupValue)
{
if (1 == acmReqParam->isSetup)
{
*(acmReqParam->buffer) = vcomInstance->countryCode;
*(acmReqParam->length) = COMM_FEATURE_DATA_SIZE;
}
else
{
/* no action, data phase, s_countryCode has been assigned */
}
error = kStatus_USB_Success;
}
else
{
/* no action, return kStatus_USB_InvalidRequest */
}
break;
case kUSB_DeviceCdcEventGetCommFeature:
if (USB_DEVICE_CDC_FEATURE_ABSTRACT_STATE == acmReqParam->setupValue)
{
*(acmReqParam->buffer) = vcomInstance->abstractState;
*(acmReqParam->length) = COMM_FEATURE_DATA_SIZE;
error = kStatus_USB_Success;
}
else if (USB_DEVICE_CDC_FEATURE_COUNTRY_SETTING == acmReqParam->setupValue)
{
*(acmReqParam->buffer) = vcomInstance->countryCode;
*(acmReqParam->length) = COMM_FEATURE_DATA_SIZE;
error = kStatus_USB_Success;
}
else
{
/* no action, return kStatus_USB_InvalidRequest */
}
break;
case kUSB_DeviceCdcEventClearCommFeature:
break;
case kUSB_DeviceCdcEventGetLineCoding:
*(acmReqParam->buffer) = vcomInstance->lineCoding;
*(acmReqParam->length) = LINE_CODING_SIZE;
error = kStatus_USB_Success;
break;
case kUSB_DeviceCdcEventSetLineCoding:
{
if (1 == acmReqParam->isSetup)
{
*(acmReqParam->buffer) = vcomInstance->lineCoding;
*(acmReqParam->length) = LINE_CODING_SIZE;
}
else
{
/* no action, data phase, s_lineCoding has been assigned */
}
error = kStatus_USB_Success;
}
break;
case kUSB_DeviceCdcEventSetControlLineState:
{
error = kStatus_USB_Success;
vcomInstance->usbCdcAcmInfo->dteStatus = acmReqParam->setupValue;
/* activate/deactivate Tx carrier */
if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_CARRIER_ACTIVATION)
{
acmInfo->uartState |= USB_DEVICE_CDC_UART_STATE_TX_CARRIER;
}
else
{
acmInfo->uartState &= (uint16_t)~USB_DEVICE_CDC_UART_STATE_TX_CARRIER;
}
/* activate carrier and DTE. Com port of terminal tool running on PC is open now */
if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE)
{
acmInfo->uartState |= USB_DEVICE_CDC_UART_STATE_RX_CARRIER;
}
/* Com port of terminal tool running on PC is closed now */
else
{
acmInfo->uartState &= (uint16_t)~USB_DEVICE_CDC_UART_STATE_RX_CARRIER;
}
/* Indicates to DCE if DTE is present or not */
acmInfo->dtePresent = (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE) ? true : false;
/* Initialize the serial state buffer */
acmInfo->serialStateBuf[0] = NOTIF_REQUEST_TYPE; /* bmRequestType */
acmInfo->serialStateBuf[1] = USB_DEVICE_CDC_NOTIF_SERIAL_STATE; /* bNotification */
acmInfo->serialStateBuf[2] = 0x00; /* wValue */
acmInfo->serialStateBuf[3] = 0x00;
acmInfo->serialStateBuf[4] = 0x00; /* wIndex */
acmInfo->serialStateBuf[5] = 0x00;
acmInfo->serialStateBuf[6] = UART_BITMAP_SIZE; /* wLength */
acmInfo->serialStateBuf[7] = 0x00;
/* Notify to host the line state */
acmInfo->serialStateBuf[4] = acmReqParam->interfaceIndex;
/* Lower byte of UART BITMAP */
uartBitmap = (uint8_t *)&acmInfo->serialStateBuf[NOTIF_PACKET_SIZE + UART_BITMAP_SIZE - 2];
uartBitmap[0] = acmInfo->uartState & 0xFFu;
uartBitmap[1] = (acmInfo->uartState >> 8) & 0xFFu;
len = (uint32_t)(NOTIF_PACKET_SIZE + UART_BITMAP_SIZE);
if (0 == ((usb_device_cdc_acm_struct_t *)handle)->hasSentState)
{
error = USB_DeviceCdcAcmSend(handle, vcomInstance->interruptEndpoint, acmInfo->serialStateBuf, len);
if (kStatus_USB_Success != error)
{
usb_echo("kUSB_DeviceCdcEventSetControlLineState error!");
}
((usb_device_cdc_acm_struct_t *)handle)->hasSentState = 1;
}
/* Update status */
if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_CARRIER_ACTIVATION)
{
/* To do: CARRIER_ACTIVATED */
}
else
{
/* To do: CARRIER_DEACTIVATED */
}
if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE)
{
/* DTE_ACTIVATED */
if (1 == vcomInstance->attach)
{
vcomInstance->startTransactions = 1;
}
}
else
{
/* DTE_DEACTIVATED */
if (1 == vcomInstance->attach)
{
vcomInstance->startTransactions = 0;
}
}
}
break;
case kUSB_DeviceCdcEventSendBreak:
break;
default:
break;
}
return error;
}
vcring_t vcr_log, vcr_txp_out, vcr_txp_in;
extern usb_device_composite_struct_t g_composite;
/*!
* @brief Application task function.
*
* This function runs the task for application.
*
* @return None.
*/
void USB_DeviceCdcVcomTask(void)
{
usb_status_t error = kStatus_USB_Error;
volatile usb_cdc_vcom_struct_t *vci = &g_deviceComposite->cdcVcom[0];
const uint8_t *p;
size_t n;
/* emit logs on CDC 0 */
n = next_chonk(&vcr_log, &p);
if (vci->attach && vci->startTransactions && n) {
if (n > vci->bulkInEndpointMaxPacketSize)
n = vci->bulkInEndpointMaxPacketSize;
if (USB_DeviceCdcAcmSend(vci->cdcAcmHandle, vci->bulkInEndpoint, (uint8_t *)p, n) == kStatus_USB_Success)
consume_chonk(&vcr_log, n);
}
/* SS transport on CDC 1 */
vci++;
if (!vci->attach || !vci->startTransactions)
return;
if (vci->recvSize &&
USB_CANCELLED_TRANSFER_LENGTH != vci->recvSize) {
n = space_available(&vcr_txp_in);
// lwsl_warn("%s: len %u in", __func__, vci->recvSize);
// lwsl_hexdump_warn(vci->currRecvBuf, vci->recvSize);
n = tm->info.txp_cpath.ops_in->event_read(
tm->info.txp_cpath.priv_in, vci->currRecvBuf, vci->recvSize);
vci->recvSize = 0;
USB_DeviceSendRequest(g_composite.deviceHandle, vci->bulkOutEndpoint,0,0);
if (n) {
/*
* The SSS parser can identify the framing is broken,
* in that case the transport needs to re-link up
*/
tm->info.txp_cpath.ops_in->lost_coherence(
tm->info.txp_cpath.priv_in);
}
}
n = next_chonk(&vcr_txp_out, &p);
if (vci->attach && vci->startTransactions && n) {
if (n > vci->bulkInEndpointMaxPacketSize)
n = vci->bulkInEndpointMaxPacketSize;
if (USB_DeviceCdcAcmSend(vci->cdcAcmHandle, vci->bulkInEndpoint, (uint8_t *)p, n) == kStatus_USB_Success)
consume_chonk(&vcr_txp_out, n);
}
}
/*!
* @brief Virtual COM device set configuration function.
*
* This function sets configuration for CDC class.
*
* @param handle The CDC ACM class handle.
* @param configure The CDC ACM class configure index.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceCdcVcomSetConfigure(class_handle_t handle, uint8_t configure)
{
if (USB_COMPOSITE_CONFIGURE_INDEX == configure)
{
/*endpoint information for cdc 1*/
g_deviceComposite->cdcVcom[0].attach = 1;
g_deviceComposite->cdcVcom[0].interruptEndpoint = USB_CDC_VCOM_CIC_INTERRUPT_IN_ENDPOINT;
g_deviceComposite->cdcVcom[0].interruptEndpointMaxPacketSize = g_cdcVcomCicEndpoints[0].maxPacketSize;
g_deviceComposite->cdcVcom[0].bulkInEndpoint = USB_CDC_VCOM_DIC_BULK_IN_ENDPOINT;
g_deviceComposite->cdcVcom[0].bulkInEndpointMaxPacketSize = g_cdcVcomDicEndpoints[0].maxPacketSize;
g_deviceComposite->cdcVcom[0].bulkOutEndpoint = USB_CDC_VCOM_DIC_BULK_OUT_ENDPOINT;
g_deviceComposite->cdcVcom[0].bulkOutEndpointMaxPacketSize = g_cdcVcomDicEndpoints[1].maxPacketSize;
/* Schedule buffer for receive */
USB_DeviceCdcAcmRecv(g_deviceComposite->cdcVcom[0].cdcAcmHandle, g_deviceComposite->cdcVcom[0].bulkOutEndpoint,
s_currRecvBuf[0], g_deviceComposite->cdcVcom[0].bulkOutEndpointMaxPacketSize);
/*endpoint information for cdc 2*/
g_deviceComposite->cdcVcom[1].attach = 1;
g_deviceComposite->cdcVcom[1].interruptEndpoint = USB_CDC_VCOM_CIC_INTERRUPT_IN_ENDPOINT_2;
g_deviceComposite->cdcVcom[1].interruptEndpointMaxPacketSize = g_cdcVcomCicEndpoints_2[0].maxPacketSize;
g_deviceComposite->cdcVcom[1].bulkInEndpoint = USB_CDC_VCOM_DIC_BULK_IN_ENDPOINT_2;
g_deviceComposite->cdcVcom[1].bulkInEndpointMaxPacketSize = g_cdcVcomDicEndpoints_2[0].maxPacketSize;
g_deviceComposite->cdcVcom[1].bulkOutEndpoint = USB_CDC_VCOM_DIC_BULK_OUT_ENDPOINT_2;
g_deviceComposite->cdcVcom[1].bulkOutEndpointMaxPacketSize = g_cdcVcomDicEndpoints_2[1].maxPacketSize;
/* Schedule buffer for receive */
USB_DeviceCdcAcmRecv(g_deviceComposite->cdcVcom[1].cdcAcmHandle, g_deviceComposite->cdcVcom[1].bulkOutEndpoint,
s_currRecvBuf[1], g_deviceComposite->cdcVcom[1].bulkOutEndpointMaxPacketSize);
}
return kStatus_USB_Success;
}
/*!
* @brief Virtual COM device initialization function.
*
* This function initializes the device with the composite device class information.
*
* @param deviceComposite The pointer to the composite device structure.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceCdcVcomInit(usb_device_composite_struct_t *deviceComposite)
{
g_deviceComposite = deviceComposite;
for (uint8_t i = 0; i < USB_DEVICE_CONFIG_CDC_ACM; i++)
{
g_deviceComposite->cdcVcom[i].lineCoding = (uint8_t *)&s_lineCoding[i];
g_deviceComposite->cdcVcom[i].abstractState = (uint8_t *)&s_abstractState[i];
g_deviceComposite->cdcVcom[i].countryCode = (uint8_t *)&s_countryCode[i];
g_deviceComposite->cdcVcom[i].usbCdcAcmInfo = &s_usbCdcAcmInfo[i];
g_deviceComposite->cdcVcom[i].currRecvBuf = (uint8_t *)&s_currRecvBuf[i][0];
;
g_deviceComposite->cdcVcom[i].currSendBuf = (uint8_t *)&s_currSendBuf[i][0];
}
return kStatus_USB_Success;
}

View file

@ -0,0 +1,86 @@
/*
* Copyright 2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _USB_CDC_VCOM_H_
#define _USB_CDC_VCOM_H_ 1
/*******************************************************************************
* Definitions
******************************************************************************/
#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0)
#define CONTROLLER_ID kUSB_ControllerEhci0
#define DATA_BUFF_SIZE HS_CDC_VCOM_BULK_OUT_PACKET_SIZE
#endif
#if defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0)
#define CONTROLLER_ID kUSB_ControllerKhci0
#define DATA_BUFF_SIZE FS_CDC_VCOM_BULK_OUT_PACKET_SIZE
#endif
#if defined(USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)
#define CONTROLLER_ID kUSB_ControllerLpcIp3511Fs0
#define DATA_BUFF_SIZE FS_CDC_VCOM_BULK_OUT_PACKET_SIZE
#endif
#if defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)
#define CONTROLLER_ID kUSB_ControllerLpcIp3511Hs0
#define DATA_BUFF_SIZE HS_CDC_VCOM_BULK_OUT_PACKET_SIZE
#endif
#define USB_DEVICE_INTERRUPT_PRIORITY (3U)
/* Currently configured line coding */
#define LINE_CODING_SIZE (0x07)
#define LINE_CODING_DTERATE (115200)
#define LINE_CODING_CHARFORMAT (0x00)
#define LINE_CODING_PARITYTYPE (0x00)
#define LINE_CODING_DATABITS (0x08)
/* Communications feature */
#define COMM_FEATURE_DATA_SIZE (0x02)
#define STATUS_ABSTRACT_STATE (0x0000)
#define COUNTRY_SETTING (0x0000)
/* Notification of serial state */
#define NOTIF_PACKET_SIZE (0x08)
#define UART_BITMAP_SIZE (0x02)
#define NOTIF_REQUEST_TYPE (0xA1)
/* Define the information relates to abstract control model */
typedef struct _usb_cdc_acm_info
{
uint8_t serialStateBuf[NOTIF_PACKET_SIZE + UART_BITMAP_SIZE]; /* Serial state buffer of the CDC device to notify the
serial state to host. */
bool dtePresent; /* A flag to indicate whether DTE is present. */
uint16_t breakDuration; /* Length of time in milliseconds of the break signal */
uint8_t dteStatus; /* Status of data terminal equipment */
uint8_t currentInterface; /* Current interface index. */
uint16_t uartState; /* UART state of the CDC device. */
} usb_cdc_acm_info_t;
/* Define the types for application */
typedef struct _usb_cdc_vcom_struct
{
usb_device_handle deviceHandle; /* USB device handle. */
class_handle_t cdcAcmHandle; /* USB CDC ACM class handle. */
uint8_t *lineCoding; /* Line coding of cdc device */
uint8_t *abstractState; /* Abstract state of cdc device */
uint8_t *countryCode; /* Country code of cdc device */
usb_cdc_acm_info_t *usbCdcAcmInfo; /* CDC ACM information */
uint8_t *currRecvBuf; /*receive buffer*/
uint8_t *currSendBuf; /*send buffer*/
volatile uint32_t recvSize; /*the data length received from host*/
volatile uint32_t sendSize; /*the data length to send*/
uint16_t bulkOutEndpointMaxPacketSize; /*bulk out endpoint maxpacket size */
uint16_t bulkInEndpointMaxPacketSize; /*bulk in endpoint maxpacket size */
uint16_t interruptEndpointMaxPacketSize; /*interrupt endpoint maxpacket size */
uint8_t attach; /* A flag to indicate whether a usb device is attached. 1: attached, 0: not attached */
uint8_t speed; /* Speed of USB device. USB_SPEED_FULL/USB_SPEED_LOW/USB_SPEED_HIGH. */
uint8_t startTransactions; /* A flag to indicate whether a CDC device is ready to transmit and receive data. */
uint8_t currentConfiguration; /* Current configuration value. */
uint8_t currentInterfaceAlternateSetting[USB_CDC_VCOM_INTERFACE_COUNT]; /* Current alternate setting value for each
interface. */
uint8_t bulkInEndpoint; /*bulk in endpoint number*/
uint8_t bulkOutEndpoint; /*bulk out endpoint number*/
uint8_t interruptEndpoint; /*interrupt endpoint number*/
} usb_cdc_vcom_struct_t;
#endif /* _USB_CDC_VCOM_H_ */

View file

@ -0,0 +1,856 @@
//*****************************************************************************
// MIMXRT595S_cm33 startup code for use with MCUXpresso IDE
//
// Version : 180520
//*****************************************************************************
//
// Copyright 2016-2020 NXP
// All rights reserved.
//
// SPDX-License-Identifier: BSD-3-Clause
//*****************************************************************************
#if defined (DEBUG)
#pragma GCC push_options
#pragma GCC optimize ("Og")
#endif // (DEBUG)
#if defined (__cplusplus)
#ifdef __REDLIB__
#error Redlib does not support C++
#else
//*****************************************************************************
//
// The entry point for the C++ library startup
//
//*****************************************************************************
extern "C" {
extern void __libc_init_array(void);
}
#endif
#endif
#define WEAK __attribute__ ((weak))
#define WEAK_AV __attribute__ ((weak, section(".after_vectors")))
#define ALIAS(f) __attribute__ ((weak, alias (#f)))
//*****************************************************************************
#if defined (__cplusplus)
extern "C" {
#endif
//*****************************************************************************
// Variable to store CRP value in. Will be placed automatically
// by the linker when "Enable Code Read Protect" selected.
// See crp.h header for more information
//*****************************************************************************
//*****************************************************************************
// Declaration of external SystemInit function
//*****************************************************************************
#if defined (__USE_CMSIS)
extern void SystemInit(void);
#endif // (__USE_CMSIS)
//*****************************************************************************
// Forward declaration of the core exception handlers.
// When the application defines a handler (with the same name), this will
// automatically take precedence over these weak definitions.
// If your application is a C++ one, then any interrupt handlers defined
// in C++ files within in your main application will need to have C linkage
// rather than C++ linkage. To do this, make sure that you are using extern "C"
// { .... } around the interrupt handler within your main application code.
//*****************************************************************************
void ResetISR(void);
WEAK void NMI_Handler(void);
WEAK void HardFault_Handler(void);
WEAK void MemManage_Handler(void);
WEAK void BusFault_Handler(void);
WEAK void UsageFault_Handler(void);
WEAK void SecureFault_Handler(void);
WEAK void SVC_Handler(void);
WEAK void DebugMon_Handler(void);
WEAK void PendSV_Handler(void);
WEAK void SysTick_Handler(void);
WEAK void IntDefaultHandler(void);
//*****************************************************************************
// Forward declaration of the application IRQ handlers. When the application
// defines a handler (with the same name), this will automatically take
// precedence over weak definitions below
//*****************************************************************************
WEAK void WDT0_IRQHandler(void);
WEAK void DMA0_IRQHandler(void);
WEAK void GPIO_INTA_IRQHandler(void);
WEAK void GPIO_INTB_IRQHandler(void);
WEAK void PIN_INT0_IRQHandler(void);
WEAK void PIN_INT1_IRQHandler(void);
WEAK void PIN_INT2_IRQHandler(void);
WEAK void PIN_INT3_IRQHandler(void);
WEAK void UTICK0_IRQHandler(void);
WEAK void MRT0_IRQHandler(void);
WEAK void CTIMER0_IRQHandler(void);
WEAK void CTIMER1_IRQHandler(void);
WEAK void SCT0_IRQHandler(void);
WEAK void CTIMER3_IRQHandler(void);
WEAK void FLEXCOMM0_IRQHandler(void);
WEAK void FLEXCOMM1_IRQHandler(void);
WEAK void FLEXCOMM2_IRQHandler(void);
WEAK void FLEXCOMM3_IRQHandler(void);
WEAK void FLEXCOMM4_IRQHandler(void);
WEAK void FLEXCOMM5_IRQHandler(void);
WEAK void FLEXCOMM14_IRQHandler(void);
WEAK void FLEXCOMM15_IRQHandler(void);
WEAK void ADC0_IRQHandler(void);
WEAK void Reserved39_IRQHandler(void);
WEAK void ACMP_IRQHandler(void);
WEAK void DMIC0_IRQHandler(void);
WEAK void Reserved42_IRQHandler(void);
WEAK void HYPERVISOR_IRQHandler(void);
WEAK void SECURE_VIOLATION_IRQHandler(void);
WEAK void HWVAD0_IRQHandler(void);
WEAK void Reserved46_IRQHandler(void);
WEAK void RNG_IRQHandler(void);
WEAK void RTC_IRQHandler(void);
WEAK void DSP_TIE_EXPSTATE1_IRQHandler(void);
WEAK void MU_A_IRQHandler(void);
WEAK void PIN_INT4_IRQHandler(void);
WEAK void PIN_INT5_IRQHandler(void);
WEAK void PIN_INT6_IRQHandler(void);
WEAK void PIN_INT7_IRQHandler(void);
WEAK void CTIMER2_IRQHandler(void);
WEAK void CTIMER4_IRQHandler(void);
WEAK void OS_EVENT_IRQHandler(void);
WEAK void FLEXSPI0_FLEXSPI1_IRQHandler(void);
WEAK void FLEXCOMM6_IRQHandler(void);
WEAK void FLEXCOMM7_IRQHandler(void);
WEAK void USDHC0_IRQHandler(void);
WEAK void USDHC1_IRQHandler(void);
WEAK void SGPIO_INTA_IRQHandler(void);
WEAK void SGPIO_INTB_IRQHandler(void);
WEAK void I3C0_IRQHandler(void);
WEAK void USB0_IRQHandler(void);
WEAK void USB0_NEEDCLK_IRQHandler(void);
WEAK void WDT1_IRQHandler(void);
WEAK void USB_PHYDCD_IRQHandler(void);
WEAK void DMA1_IRQHandler(void);
WEAK void PUF_IRQHandler(void);
WEAK void POWERQUAD_IRQHandler(void);
WEAK void CASPER_IRQHandler(void);
WEAK void PMU_PMIC_IRQHandler(void);
WEAK void HASHCRYPT_IRQHandler(void);
WEAK void FLEXCOMM8_IRQHandler(void);
WEAK void FLEXCOMM9_IRQHandler(void);
WEAK void FLEXCOMM10_IRQHandler(void);
WEAK void FLEXCOMM11_IRQHandler(void);
WEAK void FLEXCOMM12_IRQHandler(void);
WEAK void FLEXCOMM13_IRQHandler(void);
WEAK void FLEXCOMM16_IRQHandler(void);
WEAK void I3C1_IRQHandler(void);
WEAK void FLEXIO_IRQHandler(void);
WEAK void LCDIF_IRQHandler(void);
WEAK void GPU_IRQHandler(void);
WEAK void MIPI_IRQHandler(void);
WEAK void Reserved88_IRQHandler(void);
WEAK void SDMA_IRQHandler(void);
//*****************************************************************************
// Forward declaration of the driver IRQ handlers. These are aliased
// to the IntDefaultHandler, which is a 'forever' loop. When the driver
// defines a handler (with the same name), this will automatically take
// precedence over these weak definitions
//*****************************************************************************
void WDT0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void DMA0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void GPIO_INTA_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void GPIO_INTB_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void PIN_INT0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void PIN_INT1_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void PIN_INT2_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void PIN_INT3_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void UTICK0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void MRT0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void CTIMER0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void CTIMER1_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void SCT0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void CTIMER3_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void FLEXCOMM0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void FLEXCOMM1_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void FLEXCOMM2_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void FLEXCOMM3_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void FLEXCOMM4_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void FLEXCOMM5_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void FLEXCOMM14_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void FLEXCOMM15_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void ADC0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void Reserved39_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void ACMP_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void DMIC0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void Reserved42_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void HYPERVISOR_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void SECURE_VIOLATION_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void HWVAD0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void Reserved46_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void RNG_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void RTC_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void DSP_TIE_EXPSTATE1_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void MU_A_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void PIN_INT4_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void PIN_INT5_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void PIN_INT6_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void PIN_INT7_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void CTIMER2_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void CTIMER4_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void OS_EVENT_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void FLEXSPI0_FLEXSPI1_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void FLEXCOMM6_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void FLEXCOMM7_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void USDHC0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void USDHC1_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void SGPIO_INTA_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void SGPIO_INTB_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void I3C0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void USB0_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void USB0_NEEDCLK_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void WDT1_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void USB_PHYDCD_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void DMA1_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void PUF_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void POWERQUAD_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void CASPER_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void PMU_PMIC_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void HASHCRYPT_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void FLEXCOMM8_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void FLEXCOMM9_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void FLEXCOMM10_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void FLEXCOMM11_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void FLEXCOMM12_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void FLEXCOMM13_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void FLEXCOMM16_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void I3C1_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void FLEXIO_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void LCDIF_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void GPU_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void MIPI_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void Reserved88_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
void SDMA_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
//*****************************************************************************
// The entry point for the application.
// __main() is the entry point for Redlib based applications
// main() is the entry point for Newlib based applications
//*****************************************************************************
#if defined (__REDLIB__)
extern void __main(void);
#endif
extern int main(void);
//*****************************************************************************
// External declaration for the pointer to the stack top from the Linker Script
//*****************************************************************************
extern void _vStackTop(void);
extern void _image_size(void);
//*****************************************************************************
// External declaration for the pointer to the stack base from the Linker Script
//*****************************************************************************
extern void _vStackBase(void);
//*****************************************************************************
// External declaration for image type and load address from Linker Script
//*****************************************************************************
WEAK extern void __imghdr_loadaddress();
WEAK extern void __imghdr_imagetype();
//*****************************************************************************
#if defined (__cplusplus)
} // extern "C"
#endif
//*****************************************************************************
// The vector table.
// This relies on the linker script to place at correct location in memory.
//*****************************************************************************
extern void (* const g_pfnVectors[])(void);
extern void * __Vectors __attribute__ ((alias ("g_pfnVectors")));
__attribute__ ((used, section(".isr_vector")))
void (* const g_pfnVectors[])(void) = {
// Core Level - CM33
&_vStackTop, // The initial stack pointer
ResetISR, // The reset handler
NMI_Handler, // The NMI handler
HardFault_Handler, // The hard fault handler
MemManage_Handler, // The MPU fault handler
BusFault_Handler, // The bus fault handler
UsageFault_Handler, // The usage fault handler
SecureFault_Handler, // The secure fault handler
#if (__ARM_FEATURE_CMSE & 0x2)
(void (*)())0x280000, // Image length
#else
(void (*)())((unsigned)_image_size), // Image length
#endif
__imghdr_imagetype, // Image type
0, // Reserved
SVC_Handler, // SVCall handler
DebugMon_Handler, // Debug monitor handler
(void (*)())g_pfnVectors, // Image load address
PendSV_Handler, // The PendSV handler
SysTick_Handler, // The SysTick handler
// Chip Level - MIMXRT595S_cm33
WDT0_IRQHandler, // 16: Watchdog timer interrupt
DMA0_IRQHandler, // 17: DMA interrupt
GPIO_INTA_IRQHandler, // 18: GPIO Interrupt A
GPIO_INTB_IRQHandler, // 19: GPIO Interrupt B
PIN_INT0_IRQHandler, // 20: General Purpose Input/Output interrupt 0
PIN_INT1_IRQHandler, // 21: General Purpose Input/Output interrupt 1
PIN_INT2_IRQHandler, // 22: General Purpose Input/Output interrupt 2
PIN_INT3_IRQHandler, // 23: General Purpose Input/Output interrupt 3
UTICK0_IRQHandler, // 24: Micro-tick Timer
MRT0_IRQHandler, // 25: Multi-Rate Timer
CTIMER0_IRQHandler, // 26: Standard counter/timer CTIMER0
CTIMER1_IRQHandler, // 27: Standard counter/timer CTIMER1
SCT0_IRQHandler, // 28: SCTimer/PWM
CTIMER3_IRQHandler, // 29: Standard counter/timer CTIMER3
FLEXCOMM0_IRQHandler, // 30: FlexComm interrupt
FLEXCOMM1_IRQHandler, // 31: FlexComm interrupt
FLEXCOMM2_IRQHandler, // 32: FlexComm interrupt
FLEXCOMM3_IRQHandler, // 33: FlexComm interrupt
FLEXCOMM4_IRQHandler, // 34: FlexComm interrupt
FLEXCOMM5_IRQHandler, // 35: FlexComm interrupt
FLEXCOMM14_IRQHandler, // 36: FlexComm interrupt. Standalone SPI
FLEXCOMM15_IRQHandler, // 37: FlexComm interrupt. Standalone I2C
ADC0_IRQHandler, // 38: Analog-to-Digital Converter interrupt
Reserved39_IRQHandler, // 39: Reserved interrupt
ACMP_IRQHandler, // 40: Analog comparator Interrupts
DMIC0_IRQHandler, // 41: Digital Microphone Interface interrupt
Reserved42_IRQHandler, // 42: Reserved interrupt
HYPERVISOR_IRQHandler, // 43: Hypervisor interrupt
SECURE_VIOLATION_IRQHandler, // 44: Secure violation interrupt
HWVAD0_IRQHandler, // 45: Hardware Voice Activity Detector interrupt
Reserved46_IRQHandler, // 46: Reserved interrupt
RNG_IRQHandler, // 47: Random Number Generator interrupt
RTC_IRQHandler, // 48: Real Time Clock Alarm interrupt OR Wakeup timer interrupt
DSP_TIE_EXPSTATE1_IRQHandler, // 49: DSP interrupt
MU_A_IRQHandler, // 50: Messaging Unit - Side A
PIN_INT4_IRQHandler, // 51: General Purpose Input/Output interrupt 4
PIN_INT5_IRQHandler, // 52: General Purpose Input/Output interrupt 5
PIN_INT6_IRQHandler, // 53: General Purpose Input/Output interrupt 6
PIN_INT7_IRQHandler, // 54: General Purpose Input/Output interrupt 7
CTIMER2_IRQHandler, // 55: Standard counter/timer CTIMER2
CTIMER4_IRQHandler, // 56: Standard counter/timer CTIMER4
OS_EVENT_IRQHandler, // 57: Event timer M33 Wakeup/interrupt
FLEXSPI0_FLEXSPI1_IRQHandler, // 58: FlexSPI0_IRQ OR FlexSPI1_IRQ
FLEXCOMM6_IRQHandler, // 59: FlexComm interrupt
FLEXCOMM7_IRQHandler, // 60: FlexComm interrupt
USDHC0_IRQHandler, // 61: USDHC interrupt
USDHC1_IRQHandler, // 62: USDHC interrupt
SGPIO_INTA_IRQHandler, // 63: Secure GPIO HS interrupt 0
SGPIO_INTB_IRQHandler, // 64: Secure GPIO HS interrupt 1
I3C0_IRQHandler, // 65: Improved Inter Integrated Circuit 0 interrupt
USB0_IRQHandler, // 66: USB device
USB0_NEEDCLK_IRQHandler, // 67: USB Activity Wake-up Interrupt
WDT1_IRQHandler, // 68: Watchdog timer 1 interrupt
USB_PHYDCD_IRQHandler, // 69: USBPHY DCD interrupt
DMA1_IRQHandler, // 70: DMA interrupt
PUF_IRQHandler, // 71: QuidKey interrupt
POWERQUAD_IRQHandler, // 72: Powerquad interrupt
CASPER_IRQHandler, // 73: Caspar interrupt
PMU_PMIC_IRQHandler, // 74: Power Management Control interrupt
HASHCRYPT_IRQHandler, // 75: SHA interrupt
FLEXCOMM8_IRQHandler, // 76: FlexComm interrupt
FLEXCOMM9_IRQHandler, // 77: FlexComm interrupt
FLEXCOMM10_IRQHandler, // 78: FlexComm interrupt
FLEXCOMM11_IRQHandler, // 79: FlexComm interrupt
FLEXCOMM12_IRQHandler, // 80: FlexComm interrupt
FLEXCOMM13_IRQHandler, // 81: FlexComm interrupt
FLEXCOMM16_IRQHandler, // 82: FlexComm interrupt
I3C1_IRQHandler, // 83: Improved Inter Integrated Circuit 1 interrupt
FLEXIO_IRQHandler, // 84: Flexible I/O interrupt
LCDIF_IRQHandler, // 85: Liquid Crystal Display interface interrupt
GPU_IRQHandler, // 86: Graphics Processor Unit interrupt
MIPI_IRQHandler, // 87: MIPI interrupt
Reserved88_IRQHandler, // 88: Reserved interrupt
SDMA_IRQHandler, // 89: Smart DMA Engine Controller interrupt
}; /* End of g_pfnVectors */
#if defined(ENABLE_RAM_VECTOR_TABLE)
extern void * __VECTOR_TABLE __attribute__ ((alias ("g_pfnVectors")));
void (* __VECTOR_RAM[sizeof(g_pfnVectors) / 4])(void) __attribute__((aligned(128)));
unsigned int __RAM_VECTOR_TABLE_SIZE_BYTES = sizeof(g_pfnVectors);
#endif
//*****************************************************************************
// Functions to carry out the initialization of RW and BSS data sections. These
// are written as separate functions rather than being inlined within the
// ResetISR() function in order to cope with MCUs with multiple banks of
// memory.
//*****************************************************************************
__attribute__ ((section(".after_vectors.init_data")))
void data_init(unsigned int romstart, unsigned int start, unsigned int len) {
unsigned int *pulDest = (unsigned int*) start;
unsigned int *pulSrc = (unsigned int*) romstart;
unsigned int loop;
for (loop = 0; loop < len; loop = loop + 4)
*pulDest++ = *pulSrc++;
}
__attribute__ ((section(".after_vectors.init_bss")))
void bss_init(unsigned int start, unsigned int len) {
unsigned int *pulDest = (unsigned int*) start;
unsigned int loop;
for (loop = 0; loop < len; loop = loop + 4)
*pulDest++ = 0;
}
//*****************************************************************************
// The following symbols are constructs generated by the linker, indicating
// the location of various points in the "Global Section Table". This table is
// created by the linker via the Code Red managed linker script mechanism. It
// contains the load address, execution address and length of each RW data
// section and the execution and length of each BSS (zero initialized) section.
//*****************************************************************************
extern unsigned int __data_section_table;
extern unsigned int __data_section_table_end;
extern unsigned int __bss_section_table;
extern unsigned int __bss_section_table_end;
//*****************************************************************************
// Reset entry point for your code.
// Sets up a simple runtime environment and initializes the C/C++
// library.
//*****************************************************************************
__attribute__ ((naked, section(".after_vectors.reset")))
void ResetISR(void) {
// Disable interrupts
__asm volatile ("cpsid i");
// Config VTOR & MSPLIM register
__asm volatile ("LDR R0, =0xE000ED08 \n"
"STR %0, [R0] \n"
"LDR R1, [%0] \n"
"MSR MSP, R1 \n"
"MSR MSPLIM, %1 \n"
:
: "r"(g_pfnVectors), "r"(_vStackBase)
: "r0", "r1");
#if defined (__USE_CMSIS)
// If __USE_CMSIS defined, then call CMSIS SystemInit code
SystemInit();
#endif // (__USE_CMSIS)
//
// Copy the data sections from flash to SRAM.
//
unsigned int LoadAddr, ExeAddr, SectionLen;
unsigned int *SectionTableAddr;
// Load base address of Global Section Table
SectionTableAddr = &__data_section_table;
// Copy the data sections from flash to SRAM.
while (SectionTableAddr < &__data_section_table_end) {
LoadAddr = *SectionTableAddr++;
ExeAddr = *SectionTableAddr++;
SectionLen = *SectionTableAddr++;
data_init(LoadAddr, ExeAddr, SectionLen);
}
// At this point, SectionTableAddr = &__bss_section_table;
// Zero fill the bss segment
while (SectionTableAddr < &__bss_section_table_end) {
ExeAddr = *SectionTableAddr++;
SectionLen = *SectionTableAddr++;
bss_init(ExeAddr, SectionLen);
}
#if defined (__cplusplus)
//
// Call C++ library initialisation
//
__libc_init_array();
#endif
// Reenable interrupts
__asm volatile ("cpsie i");
#if defined (__REDLIB__)
// Call the Redlib library, which in turn calls main()
__main();
#else
main();
#endif
//
// main() shouldn't return, but if it does, we'll just enter an infinite loop
//
while (1) {
;
}
}
//*****************************************************************************
// Default core exception handlers. Override the ones here by defining your own
// handler routines in your application code.
//*****************************************************************************
WEAK_AV void NMI_Handler(void)
{ while(1) {}
}
WEAK_AV void HardFault_Handler(void)
{ while(1) {}
}
WEAK_AV void MemManage_Handler(void)
{ while(1) {}
}
WEAK_AV void BusFault_Handler(void)
{ while(1) {}
}
WEAK_AV void UsageFault_Handler(void)
{ while(1) {}
}
WEAK_AV void SecureFault_Handler(void)
{ while(1) {}
}
WEAK_AV void SVC_Handler(void)
{ while(1) {}
}
WEAK_AV void DebugMon_Handler(void)
{ while(1) {}
}
WEAK_AV void PendSV_Handler(void)
{ while(1) {}
}
WEAK_AV void SysTick_Handler(void)
{ while(1) {}
}
//*****************************************************************************
// Processor ends up here if an unexpected interrupt occurs or a specific
// handler is not present in the application code.
//*****************************************************************************
WEAK_AV void IntDefaultHandler(void)
{ while(1) {}
}
//*****************************************************************************
// Default application exception handlers. Override the ones here by defining
// your own handler routines in your application code. These routines call
// driver exception handlers or IntDefaultHandler() if no driver exception
// handler is included.
//*****************************************************************************
WEAK void WDT0_IRQHandler(void)
{ WDT0_DriverIRQHandler();
}
WEAK void DMA0_IRQHandler(void)
{ DMA0_DriverIRQHandler();
}
WEAK void GPIO_INTA_IRQHandler(void)
{ GPIO_INTA_DriverIRQHandler();
}
WEAK void GPIO_INTB_IRQHandler(void)
{ GPIO_INTB_DriverIRQHandler();
}
WEAK void PIN_INT0_IRQHandler(void)
{ PIN_INT0_DriverIRQHandler();
}
WEAK void PIN_INT1_IRQHandler(void)
{ PIN_INT1_DriverIRQHandler();
}
WEAK void PIN_INT2_IRQHandler(void)
{ PIN_INT2_DriverIRQHandler();
}
WEAK void PIN_INT3_IRQHandler(void)
{ PIN_INT3_DriverIRQHandler();
}
WEAK void UTICK0_IRQHandler(void)
{ UTICK0_DriverIRQHandler();
}
WEAK void MRT0_IRQHandler(void)
{ MRT0_DriverIRQHandler();
}
WEAK void CTIMER0_IRQHandler(void)
{ CTIMER0_DriverIRQHandler();
}
WEAK void CTIMER1_IRQHandler(void)
{ CTIMER1_DriverIRQHandler();
}
WEAK void SCT0_IRQHandler(void)
{ SCT0_DriverIRQHandler();
}
WEAK void CTIMER3_IRQHandler(void)
{ CTIMER3_DriverIRQHandler();
}
WEAK void FLEXCOMM0_IRQHandler(void)
{ FLEXCOMM0_DriverIRQHandler();
}
WEAK void FLEXCOMM1_IRQHandler(void)
{ FLEXCOMM1_DriverIRQHandler();
}
WEAK void FLEXCOMM2_IRQHandler(void)
{ FLEXCOMM2_DriverIRQHandler();
}
WEAK void FLEXCOMM3_IRQHandler(void)
{ FLEXCOMM3_DriverIRQHandler();
}
WEAK void FLEXCOMM4_IRQHandler(void)
{ FLEXCOMM4_DriverIRQHandler();
}
WEAK void FLEXCOMM5_IRQHandler(void)
{ FLEXCOMM5_DriverIRQHandler();
}
WEAK void FLEXCOMM14_IRQHandler(void)
{ FLEXCOMM14_DriverIRQHandler();
}
WEAK void FLEXCOMM15_IRQHandler(void)
{ FLEXCOMM15_DriverIRQHandler();
}
WEAK void ADC0_IRQHandler(void)
{ ADC0_DriverIRQHandler();
}
WEAK void Reserved39_IRQHandler(void)
{ Reserved39_DriverIRQHandler();
}
WEAK void ACMP_IRQHandler(void)
{ ACMP_DriverIRQHandler();
}
WEAK void DMIC0_IRQHandler(void)
{ DMIC0_DriverIRQHandler();
}
WEAK void Reserved42_IRQHandler(void)
{ Reserved42_DriverIRQHandler();
}
WEAK void HYPERVISOR_IRQHandler(void)
{ HYPERVISOR_DriverIRQHandler();
}
WEAK void SECURE_VIOLATION_IRQHandler(void)
{ SECURE_VIOLATION_DriverIRQHandler();
}
WEAK void HWVAD0_IRQHandler(void)
{ HWVAD0_DriverIRQHandler();
}
WEAK void Reserved46_IRQHandler(void)
{ Reserved46_DriverIRQHandler();
}
WEAK void RNG_IRQHandler(void)
{ RNG_DriverIRQHandler();
}
WEAK void RTC_IRQHandler(void)
{ RTC_DriverIRQHandler();
}
WEAK void DSP_TIE_EXPSTATE1_IRQHandler(void)
{ DSP_TIE_EXPSTATE1_DriverIRQHandler();
}
WEAK void MU_A_IRQHandler(void)
{ MU_A_DriverIRQHandler();
}
WEAK void PIN_INT4_IRQHandler(void)
{ PIN_INT4_DriverIRQHandler();
}
WEAK void PIN_INT5_IRQHandler(void)
{ PIN_INT5_DriverIRQHandler();
}
WEAK void PIN_INT6_IRQHandler(void)
{ PIN_INT6_DriverIRQHandler();
}
WEAK void PIN_INT7_IRQHandler(void)
{ PIN_INT7_DriverIRQHandler();
}
WEAK void CTIMER2_IRQHandler(void)
{ CTIMER2_DriverIRQHandler();
}
WEAK void CTIMER4_IRQHandler(void)
{ CTIMER4_DriverIRQHandler();
}
WEAK void OS_EVENT_IRQHandler(void)
{ OS_EVENT_DriverIRQHandler();
}
WEAK void FLEXSPI0_FLEXSPI1_IRQHandler(void)
{ FLEXSPI0_FLEXSPI1_DriverIRQHandler();
}
WEAK void FLEXCOMM6_IRQHandler(void)
{ FLEXCOMM6_DriverIRQHandler();
}
WEAK void FLEXCOMM7_IRQHandler(void)
{ FLEXCOMM7_DriverIRQHandler();
}
WEAK void USDHC0_IRQHandler(void)
{ USDHC0_DriverIRQHandler();
}
WEAK void USDHC1_IRQHandler(void)
{ USDHC1_DriverIRQHandler();
}
WEAK void SGPIO_INTA_IRQHandler(void)
{ SGPIO_INTA_DriverIRQHandler();
}
WEAK void SGPIO_INTB_IRQHandler(void)
{ SGPIO_INTB_DriverIRQHandler();
}
WEAK void I3C0_IRQHandler(void)
{ I3C0_DriverIRQHandler();
}
WEAK void USB0_IRQHandler(void)
{ USB0_DriverIRQHandler();
}
WEAK void USB0_NEEDCLK_IRQHandler(void)
{ USB0_NEEDCLK_DriverIRQHandler();
}
WEAK void WDT1_IRQHandler(void)
{ WDT1_DriverIRQHandler();
}
WEAK void USB_PHYDCD_IRQHandler(void)
{ USB_PHYDCD_DriverIRQHandler();
}
WEAK void DMA1_IRQHandler(void)
{ DMA1_DriverIRQHandler();
}
WEAK void PUF_IRQHandler(void)
{ PUF_DriverIRQHandler();
}
WEAK void POWERQUAD_IRQHandler(void)
{ POWERQUAD_DriverIRQHandler();
}
WEAK void CASPER_IRQHandler(void)
{ CASPER_DriverIRQHandler();
}
WEAK void PMU_PMIC_IRQHandler(void)
{ PMU_PMIC_DriverIRQHandler();
}
WEAK void HASHCRYPT_IRQHandler(void)
{ HASHCRYPT_DriverIRQHandler();
}
WEAK void FLEXCOMM8_IRQHandler(void)
{ FLEXCOMM8_DriverIRQHandler();
}
WEAK void FLEXCOMM9_IRQHandler(void)
{ FLEXCOMM9_DriverIRQHandler();
}
WEAK void FLEXCOMM10_IRQHandler(void)
{ FLEXCOMM10_DriverIRQHandler();
}
WEAK void FLEXCOMM11_IRQHandler(void)
{ FLEXCOMM11_DriverIRQHandler();
}
WEAK void FLEXCOMM12_IRQHandler(void)
{ FLEXCOMM12_DriverIRQHandler();
}
WEAK void FLEXCOMM13_IRQHandler(void)
{ FLEXCOMM13_DriverIRQHandler();
}
WEAK void FLEXCOMM16_IRQHandler(void)
{ FLEXCOMM16_DriverIRQHandler();
}
WEAK void I3C1_IRQHandler(void)
{ I3C1_DriverIRQHandler();
}
WEAK void FLEXIO_IRQHandler(void)
{ FLEXIO_DriverIRQHandler();
}
WEAK void LCDIF_IRQHandler(void)
{ LCDIF_DriverIRQHandler();
}
WEAK void GPU_IRQHandler(void)
{ GPU_DriverIRQHandler();
}
WEAK void MIPI_IRQHandler(void)
{ MIPI_DriverIRQHandler();
}
WEAK void Reserved88_IRQHandler(void)
{ Reserved88_DriverIRQHandler();
}
WEAK void SDMA_IRQHandler(void)
{ SDMA_DriverIRQHandler();
}
//*****************************************************************************
#if defined (DEBUG)
#pragma GCC pop_options
#endif // (DEBUG)

View file

@ -0,0 +1,931 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016, 2019 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h>
#include <stdlib.h>
#include "usb_device_config.h"
#include "usb.h"
#include "usb_device.h"
#include "usb_device_class.h"
#if USB_DEVICE_CONFIG_CDC_ACM
#include "usb_device_cdc_acm.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define USB_CDC_ACM_ENTER_CRITICAL() \
OSA_SR_ALLOC(); \
OSA_ENTER_CRITICAL()
#define USB_CDC_ACM_EXIT_CRITICAL() OSA_EXIT_CRITICAL()
/*******************************************************************************
* Variables
******************************************************************************/
/* CDC ACM device instance */
USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_cdc_acm_struct_t
g_cdcAcmHandle[USB_DEVICE_CONFIG_CDC_ACM];
/*******************************************************************************
* Code
******************************************************************************/
/*!
* @brief Allocates the CDC ACM device handle.
*
* This function allocates the CDC ACM device handle.
*
* @param handle The class handle of the CDC ACM class.
* @return A USB error code or kStatus_USB_Success.
*/
static usb_status_t USB_DeviceCdcAcmAllocateHandle(usb_device_cdc_acm_struct_t **handle)
{
uint32_t count;
for (count = 0; count < (uint32_t)USB_DEVICE_CONFIG_CDC_ACM; count++)
{
if (NULL == g_cdcAcmHandle[count].handle)
{
*handle = &g_cdcAcmHandle[count];
return kStatus_USB_Success;
}
}
return kStatus_USB_Busy;
}
/*!
* @brief Frees the CDC ACM device handle.
*
* This function frees the CDC ACM device handle.
*
* @param handle The class handle of the CDC ACM class.
* @return A USB error code or kStatus_USB_Success.
*/
static usb_status_t USB_DeviceCdcAcmFreeHandle(usb_device_cdc_acm_struct_t *handle)
{
handle->handle = NULL;
handle->configStruct = NULL;
handle->configuration = 0;
handle->alternate = 0;
return kStatus_USB_Success;
}
/*!
* @brief Responds to the interrupt in endpoint event.
*
* This function responds to the interrupt in endpoint event.
*
* @param handle The device handle of the CDC ACM device.
* @param message The pointer to the message of the endpoint callback.
* @param callbackParam The pointer to the parameter of the callback.
* @return A USB error code or kStatus_USB_Success.
*/
static usb_status_t USB_DeviceCdcAcmInterruptIn(usb_device_handle handle,
usb_device_endpoint_callback_message_struct_t *message,
void *callbackParam)
{
usb_device_cdc_acm_struct_t *cdcAcmHandle;
usb_status_t error = kStatus_USB_Error;
cdcAcmHandle = (usb_device_cdc_acm_struct_t *)callbackParam;
if (NULL == cdcAcmHandle)
{
return kStatus_USB_InvalidHandle;
}
cdcAcmHandle->interruptIn.isBusy = 0U;
if ((NULL != cdcAcmHandle->configStruct) && (NULL != cdcAcmHandle->configStruct->classCallback))
{
/*classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
it is from the second parameter of classInit */
error = cdcAcmHandle->configStruct->classCallback((class_handle_t)cdcAcmHandle,
kUSB_DeviceCdcEventSerialStateNotif, message);
}
return error;
}
/*!
* @brief Responds to the bulk in endpoint event.
*
* This function responds to the bulk in endpoint event.
*
* @param handle The device handle of the CDC ACM device.
* @param message The pointer to the message of the endpoint callback.
* @param callbackParam The pointer to the parameter of the callback.
* @return A USB error code or kStatus_USB_Success.
*/
static usb_status_t USB_DeviceCdcAcmBulkIn(usb_device_handle handle,
usb_device_endpoint_callback_message_struct_t *message,
void *callbackParam)
{
usb_device_cdc_acm_struct_t *cdcAcmHandle;
usb_status_t status = kStatus_USB_Error;
cdcAcmHandle = (usb_device_cdc_acm_struct_t *)callbackParam;
if (NULL == cdcAcmHandle)
{
return kStatus_USB_InvalidHandle;
}
cdcAcmHandle->bulkIn.isBusy = 0;
if ((NULL != cdcAcmHandle->configStruct) && (NULL != cdcAcmHandle->configStruct->classCallback))
{
/*classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
it is from the second parameter of classInit */
status = cdcAcmHandle->configStruct->classCallback((class_handle_t)cdcAcmHandle,
kUSB_DeviceCdcEventSendResponse, message);
}
return status;
}
/*!
* @brief Responds to the bulk out endpoint event.
*
* This function responds to the bulk out endpoint event.
*
* @param handle The device handle of the CDC ACM device.
* @param message The pointer to the message of the endpoint callback.
* @param callbackParam The pointer to the parameter of the callback.
* @return A USB error code or kStatus_USB_Success.
*/
static usb_status_t USB_DeviceCdcAcmBulkOut(usb_device_handle handle,
usb_device_endpoint_callback_message_struct_t *message,
void *callbackParam)
{
usb_device_cdc_acm_struct_t *cdcAcmHandle;
usb_status_t status = kStatus_USB_Error;
cdcAcmHandle = (usb_device_cdc_acm_struct_t *)callbackParam;
if (NULL == cdcAcmHandle)
{
return kStatus_USB_InvalidHandle;
}
cdcAcmHandle->bulkOut.isBusy = 0U;
if ((NULL != cdcAcmHandle->configStruct) && (NULL != cdcAcmHandle->configStruct->classCallback))
{
/*classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
it is from the second parameter of classInit */
status = cdcAcmHandle->configStruct->classCallback((class_handle_t)cdcAcmHandle,
kUSB_DeviceCdcEventRecvResponse, message);
}
return status;
}
/*!
* @brief Initializes the endpoints in CDC ACM class.
*
* This function initializes the endpoints in CDC ACM class.
*
* @param cdcAcmHandle The class handle of the CDC ACM class.
* @return A USB error code or kStatus_USB_Success.
*/
static usb_status_t USB_DeviceCdcAcmEndpointsInit(usb_device_cdc_acm_struct_t *cdcAcmHandle)
{
usb_device_interface_list_t *interfaceList;
usb_device_interface_struct_t *interface = NULL;
usb_status_t error = kStatus_USB_Error;
uint32_t count;
uint32_t index;
if (NULL == cdcAcmHandle)
{
return error;
}
/* return error when configuration is invalid (0 or more than the configuration number) */
if ((cdcAcmHandle->configuration == 0U) ||
(cdcAcmHandle->configuration > cdcAcmHandle->configStruct->classInfomation->configurations))
{
return error;
}
interfaceList = &cdcAcmHandle->configStruct->classInfomation->interfaceList[cdcAcmHandle->configuration - 1U];
for (count = 0; count < interfaceList->count; count++)
{
if (USB_DEVICE_CONFIG_CDC_COMM_CLASS_CODE == interfaceList->interfaces[count].classCode)
{
for (index = 0; index < interfaceList->interfaces[count].count; index++)
{
if (interfaceList->interfaces[count].interface[index].alternateSetting == cdcAcmHandle->alternate)
{
interface = &interfaceList->interfaces[count].interface[index];
break;
}
}
cdcAcmHandle->interfaceNumber = interfaceList->interfaces[count].interfaceNumber;
break;
}
}
if (NULL == interface)
{
return error;
}
cdcAcmHandle->commInterfaceHandle = interface;
for (count = 0; count < interface->endpointList.count; count++)
{
usb_device_endpoint_init_struct_t epInitStruct;
usb_device_endpoint_callback_struct_t epCallback;
epInitStruct.zlt = 0;
epInitStruct.interval = interface->endpointList.endpoint[count].interval;
epInitStruct.endpointAddress = interface->endpointList.endpoint[count].endpointAddress;
epInitStruct.maxPacketSize = interface->endpointList.endpoint[count].maxPacketSize;
epInitStruct.transferType = interface->endpointList.endpoint[count].transferType;
if ((USB_IN == ((epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) &&
(USB_ENDPOINT_INTERRUPT == epInitStruct.transferType))
{
cdcAcmHandle->interruptIn.ep = (epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK);
cdcAcmHandle->interruptIn.isBusy = 0;
cdcAcmHandle->interruptIn.pipeDataBuffer = (uint8_t *)USB_INVALID_TRANSFER_BUFFER;
cdcAcmHandle->interruptIn.pipeStall = 0U;
cdcAcmHandle->interruptIn.pipeDataLen = 0U;
epCallback.callbackFn = USB_DeviceCdcAcmInterruptIn;
}
epCallback.callbackParam = cdcAcmHandle;
error = USB_DeviceInitEndpoint(cdcAcmHandle->handle, &epInitStruct, &epCallback);
if (kStatus_USB_Success != error)
{
return error;
}
}
for (count = 0; count < interfaceList->count; count++)
{
if (USB_DEVICE_CONFIG_CDC_DATA_CLASS_CODE == interfaceList->interfaces[count].classCode)
{
for (index = 0; index < interfaceList->interfaces[count].count; index++)
{
if (interfaceList->interfaces[count].interface[index].alternateSetting == cdcAcmHandle->alternate)
{
interface = &interfaceList->interfaces[count].interface[index];
break;
}
}
break;
}
}
cdcAcmHandle->dataInterfaceHandle = interface;
for (count = 0; count < interface->endpointList.count; count++)
{
usb_device_endpoint_init_struct_t epInitStruct;
usb_device_endpoint_callback_struct_t epCallback;
epInitStruct.zlt = 0;
epInitStruct.interval = interface->endpointList.endpoint[count].interval;
epInitStruct.endpointAddress = interface->endpointList.endpoint[count].endpointAddress;
epInitStruct.maxPacketSize = interface->endpointList.endpoint[count].maxPacketSize;
epInitStruct.transferType = interface->endpointList.endpoint[count].transferType;
if ((USB_IN == ((epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) &&
(USB_ENDPOINT_BULK == epInitStruct.transferType))
{
cdcAcmHandle->bulkIn.ep = (epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK);
cdcAcmHandle->bulkIn.isBusy = 0;
cdcAcmHandle->bulkIn.pipeDataBuffer = (uint8_t *)USB_INVALID_TRANSFER_BUFFER;
cdcAcmHandle->bulkIn.pipeStall = 0U;
cdcAcmHandle->bulkIn.pipeDataLen = 0U;
epCallback.callbackFn = USB_DeviceCdcAcmBulkIn;
}
else if ((USB_OUT == ((epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) &&
(USB_ENDPOINT_BULK == epInitStruct.transferType))
{
cdcAcmHandle->bulkOut.ep = (epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK);
cdcAcmHandle->bulkOut.isBusy = 0;
cdcAcmHandle->bulkOut.pipeDataBuffer = (uint8_t *)USB_INVALID_TRANSFER_BUFFER;
cdcAcmHandle->bulkOut.pipeStall = 0U;
cdcAcmHandle->bulkOut.pipeDataLen = 0U;
epCallback.callbackFn = USB_DeviceCdcAcmBulkOut;
}
else
{
/*no action*/
}
epCallback.callbackParam = cdcAcmHandle;
error = USB_DeviceInitEndpoint(cdcAcmHandle->handle, &epInitStruct, &epCallback);
}
return error;
}
/*!
* @brief De-initializes the endpoints in CDC ACM class.
*
* This function de-initializes the endpoints in CDC ACM class.
*
* @param cdcAcmHandle The class handle of the CDC ACM class.
* @return A USB error code or kStatus_USB_Success.
*/
static usb_status_t USB_DeviceCdcAcmEndpointsDeinit(usb_device_cdc_acm_struct_t *cdcAcmHandle)
{
usb_status_t status = kStatus_USB_Error;
uint32_t count;
if ((NULL == cdcAcmHandle->commInterfaceHandle) || (NULL == cdcAcmHandle->dataInterfaceHandle))
{
return status;
}
for (count = 0; count < cdcAcmHandle->commInterfaceHandle->endpointList.count; count++)
{
status = USB_DeviceDeinitEndpoint(
cdcAcmHandle->handle, cdcAcmHandle->commInterfaceHandle->endpointList.endpoint[count].endpointAddress);
}
for (count = 0; count < cdcAcmHandle->dataInterfaceHandle->endpointList.count; count++)
{
status = USB_DeviceDeinitEndpoint(
cdcAcmHandle->handle, cdcAcmHandle->dataInterfaceHandle->endpointList.endpoint[count].endpointAddress);
}
cdcAcmHandle->commInterfaceHandle = NULL;
cdcAcmHandle->dataInterfaceHandle = NULL;
return status;
}
/*!
* @brief Handles the CDC ACM class event.
*
* This function responses to various events including the common device events and the class specific events.
* For class specific events, it calls the class callback defined in the application to deal with the class specific
* event.
*
* @param handle The class handle of the CDC ACM class.
* @param event The event type.
* @param param The class handle of the CDC ACM class.
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceCdcAcmEvent(void *handle, uint32_t event, void *param)
{
usb_device_cdc_acm_struct_t *cdcAcmHandle;
usb_device_cdc_acm_request_param_struct_t reqParam;
usb_status_t error = kStatus_USB_Error;
uint32_t count;
uint16_t interfaceAlternate;
uint8_t *temp8;
uint8_t alternate;
usb_device_class_event_t eventCode = (usb_device_class_event_t)event;
if ((NULL == param) || (NULL == handle))
{
return kStatus_USB_InvalidHandle;
}
cdcAcmHandle = (usb_device_cdc_acm_struct_t *)handle;
switch (eventCode)
{
case kUSB_DeviceClassEventDeviceReset:
/* Bus reset, clear the configuration. */
cdcAcmHandle->configuration = 0;
error = kStatus_USB_Success;
break;
case kUSB_DeviceClassEventSetConfiguration:
temp8 = ((uint8_t *)param);
if (NULL == cdcAcmHandle->configStruct)
{
break;
}
if (*temp8 == cdcAcmHandle->configuration)
{
error = kStatus_USB_Success;
break;
}
error = USB_DeviceCdcAcmEndpointsDeinit(cdcAcmHandle);
cdcAcmHandle->configuration = *temp8;
cdcAcmHandle->alternate = 0U;
error = USB_DeviceCdcAcmEndpointsInit(cdcAcmHandle);
if (kStatus_USB_Success != error)
{
#if 0
(void)usb_echo("kUSB_DeviceClassEventSetConfiguration, USB_DeviceInitEndpoint fail\r\n");
#endif
}
break;
case kUSB_DeviceClassEventSetInterface:
if (NULL == cdcAcmHandle->configStruct)
{
break;
}
interfaceAlternate = *((uint16_t *)param);
alternate = (uint8_t)(interfaceAlternate & 0xFFU);
if (cdcAcmHandle->interfaceNumber != ((uint8_t)(interfaceAlternate >> 8U)))
{
break;
}
if (alternate == cdcAcmHandle->alternate)
{
error = kStatus_USB_Success;
break;
}
error = USB_DeviceCdcAcmEndpointsDeinit(cdcAcmHandle);
cdcAcmHandle->alternate = alternate;
error = USB_DeviceCdcAcmEndpointsInit(cdcAcmHandle);
if (kStatus_USB_Success != error)
{
#if 0
(void)usb_echo("kUSB_DeviceClassEventSetInterface, USB_DeviceInitEndpoint fail\r\n");
#endif
}
break;
case kUSB_DeviceClassEventSetEndpointHalt:
if ((NULL == cdcAcmHandle->configStruct) || (NULL == cdcAcmHandle->commInterfaceHandle) ||
(NULL == cdcAcmHandle->dataInterfaceHandle))
{
break;
}
temp8 = ((uint8_t *)param);
for (count = 0; count < cdcAcmHandle->commInterfaceHandle->endpointList.count; count++)
{
if (*temp8 == cdcAcmHandle->commInterfaceHandle->endpointList.endpoint[count].endpointAddress)
{
cdcAcmHandle->interruptIn.pipeStall = 1U;
error = USB_DeviceStallEndpoint(cdcAcmHandle->handle, *temp8);
}
}
for (count = 0; count < cdcAcmHandle->dataInterfaceHandle->endpointList.count; count++)
{
if (*temp8 == cdcAcmHandle->dataInterfaceHandle->endpointList.endpoint[count].endpointAddress)
{
if (USB_IN == (((*temp8) & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT))
{
cdcAcmHandle->bulkIn.pipeStall = 1U;
}
else
{
cdcAcmHandle->bulkOut.pipeStall = 1U;
}
error = USB_DeviceStallEndpoint(cdcAcmHandle->handle, *temp8);
}
}
break;
case kUSB_DeviceClassEventClearEndpointHalt:
if ((NULL == cdcAcmHandle->configStruct) || (NULL == cdcAcmHandle->commInterfaceHandle) ||
(NULL == cdcAcmHandle->dataInterfaceHandle))
{
break;
}
temp8 = ((uint8_t *)param);
for (count = 0; count < cdcAcmHandle->commInterfaceHandle->endpointList.count; count++)
{
if (*temp8 == cdcAcmHandle->commInterfaceHandle->endpointList.endpoint[count].endpointAddress)
{
error = USB_DeviceUnstallEndpoint(cdcAcmHandle->handle, *temp8);
if (USB_IN == (((*temp8) & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT))
{
if (0U != cdcAcmHandle->interruptIn.pipeStall)
{
cdcAcmHandle->interruptIn.pipeStall = 0U;
if ((uint8_t *)USB_INVALID_TRANSFER_BUFFER != cdcAcmHandle->interruptIn.pipeDataBuffer)
{
error = USB_DeviceSendRequest(cdcAcmHandle->handle, (cdcAcmHandle->interruptIn.ep),
cdcAcmHandle->interruptIn.pipeDataBuffer,
cdcAcmHandle->interruptIn.pipeDataLen);
if (kStatus_USB_Success != error)
{
usb_device_endpoint_callback_message_struct_t endpointCallbackMessage;
endpointCallbackMessage.buffer = cdcAcmHandle->interruptIn.pipeDataBuffer;
endpointCallbackMessage.length = cdcAcmHandle->interruptIn.pipeDataLen;
endpointCallbackMessage.isSetup = 0U;
(void)USB_DeviceCdcAcmBulkIn(cdcAcmHandle->handle, (void *)&endpointCallbackMessage,
handle);
}
cdcAcmHandle->interruptIn.pipeDataBuffer = (uint8_t *)USB_INVALID_TRANSFER_BUFFER;
cdcAcmHandle->interruptIn.pipeDataLen = 0U;
}
}
}
}
}
for (count = 0; count < cdcAcmHandle->dataInterfaceHandle->endpointList.count; count++)
{
if (*temp8 == cdcAcmHandle->dataInterfaceHandle->endpointList.endpoint[count].endpointAddress)
{
error = USB_DeviceUnstallEndpoint(cdcAcmHandle->handle, *temp8);
if (USB_IN == (((*temp8) & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT))
{
if (0U != cdcAcmHandle->bulkIn.pipeStall)
{
cdcAcmHandle->bulkIn.pipeStall = 0U;
if ((uint8_t *)USB_INVALID_TRANSFER_BUFFER != cdcAcmHandle->bulkIn.pipeDataBuffer)
{
error = USB_DeviceSendRequest(cdcAcmHandle->handle, (cdcAcmHandle->bulkIn.ep),
cdcAcmHandle->bulkIn.pipeDataBuffer,
cdcAcmHandle->bulkIn.pipeDataLen);
if (kStatus_USB_Success != error)
{
usb_device_endpoint_callback_message_struct_t endpointCallbackMessage;
endpointCallbackMessage.buffer = cdcAcmHandle->bulkIn.pipeDataBuffer;
endpointCallbackMessage.length = cdcAcmHandle->bulkIn.pipeDataLen;
endpointCallbackMessage.isSetup = 0U;
(void)USB_DeviceCdcAcmBulkIn(cdcAcmHandle->handle, (void *)&endpointCallbackMessage,
handle);
}
cdcAcmHandle->bulkIn.pipeDataBuffer = (uint8_t *)USB_INVALID_TRANSFER_BUFFER;
cdcAcmHandle->bulkIn.pipeDataLen = 0U;
}
}
}
else
{
if (0U != cdcAcmHandle->bulkOut.pipeStall)
{
cdcAcmHandle->bulkOut.pipeStall = 0U;
if ((uint8_t *)USB_INVALID_TRANSFER_BUFFER != cdcAcmHandle->bulkOut.pipeDataBuffer)
{
error = USB_DeviceRecvRequest(cdcAcmHandle->handle, (cdcAcmHandle->bulkOut.ep),
cdcAcmHandle->bulkOut.pipeDataBuffer,
cdcAcmHandle->bulkOut.pipeDataLen);
if (kStatus_USB_Success != error)
{
usb_device_endpoint_callback_message_struct_t endpointCallbackMessage;
endpointCallbackMessage.buffer = cdcAcmHandle->bulkOut.pipeDataBuffer;
endpointCallbackMessage.length = cdcAcmHandle->bulkOut.pipeDataLen;
endpointCallbackMessage.isSetup = 0U;
(void)USB_DeviceCdcAcmBulkOut(cdcAcmHandle->handle,
(void *)&endpointCallbackMessage, handle);
}
cdcAcmHandle->bulkOut.pipeDataBuffer = (uint8_t *)USB_INVALID_TRANSFER_BUFFER;
cdcAcmHandle->bulkOut.pipeDataLen = 0U;
}
}
}
}
}
break;
case kUSB_DeviceClassEventClassRequest:
{
usb_device_control_request_struct_t *controlRequest = (usb_device_control_request_struct_t *)param;
if ((controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) !=
USB_REQUEST_TYPE_RECIPIENT_INTERFACE)
{
break;
}
if ((controlRequest->setup->wIndex & 0xFFU) != cdcAcmHandle->interfaceNumber)
{
break;
}
error = kStatus_USB_InvalidRequest;
/* Standard CDC request */
reqParam.buffer = &(controlRequest->buffer);
reqParam.length = &(controlRequest->length);
reqParam.interfaceIndex = controlRequest->setup->wIndex;
reqParam.setupValue = controlRequest->setup->wValue;
reqParam.isSetup = controlRequest->isSetup;
switch (controlRequest->setup->bRequest)
{
case USB_DEVICE_CDC_REQUEST_SEND_ENCAPSULATED_COMMAND:
if (((controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) ==
USB_REQUEST_TYPE_DIR_OUT) &&
(controlRequest->setup->wLength != 0U))
{
/* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
it is from the second parameter of classInit */
error = cdcAcmHandle->configStruct->classCallback(
(class_handle_t)cdcAcmHandle, kUSB_DeviceCdcEventSendEncapsulatedCommand, &reqParam);
}
break;
case USB_DEVICE_CDC_REQUEST_GET_ENCAPSULATED_RESPONSE:
if (((controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) ==
USB_REQUEST_TYPE_DIR_IN) &&
(controlRequest->setup->wLength != 0U))
{
/* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
it is from the second parameter of classInit */
error = cdcAcmHandle->configStruct->classCallback(
(class_handle_t)cdcAcmHandle, kUSB_DeviceCdcEventGetEncapsulatedResponse, &reqParam);
}
break;
case USB_DEVICE_CDC_REQUEST_SET_COMM_FEATURE:
if (((controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) ==
USB_REQUEST_TYPE_DIR_OUT) &&
(controlRequest->setup->wLength != 0U))
{
/* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
it is from the second parameter of classInit */
error = cdcAcmHandle->configStruct->classCallback((class_handle_t)cdcAcmHandle,
kUSB_DeviceCdcEventSetCommFeature, &reqParam);
}
break;
case USB_DEVICE_CDC_REQUEST_GET_COMM_FEATURE:
if (((controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) ==
USB_REQUEST_TYPE_DIR_IN) &&
(controlRequest->setup->wLength != 0U))
{
/* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
it is from the second parameter of classInit */
error = cdcAcmHandle->configStruct->classCallback((class_handle_t)cdcAcmHandle,
kUSB_DeviceCdcEventGetCommFeature, &reqParam);
}
break;
case USB_DEVICE_CDC_REQUEST_CLEAR_COMM_FEATURE:
if (((controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) ==
USB_REQUEST_TYPE_DIR_OUT) &&
(controlRequest->setup->wLength == 0U))
{
/* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
it is from the second parameter of classInit */
error = cdcAcmHandle->configStruct->classCallback(
(class_handle_t)cdcAcmHandle, kUSB_DeviceCdcEventClearCommFeature, &reqParam);
}
break;
case USB_DEVICE_CDC_REQUEST_GET_LINE_CODING:
if (((controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) ==
USB_REQUEST_TYPE_DIR_IN) &&
(controlRequest->setup->wLength != 0U))
{
/* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
it is from the second parameter of classInit */
error = cdcAcmHandle->configStruct->classCallback((class_handle_t)cdcAcmHandle,
kUSB_DeviceCdcEventGetLineCoding, &reqParam);
}
break;
case USB_DEVICE_CDC_REQUEST_SET_LINE_CODING:
if (((controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) ==
USB_REQUEST_TYPE_DIR_OUT) &&
(controlRequest->setup->wLength != 0U))
{
/* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
it is from the second parameter of classInit */
error = cdcAcmHandle->configStruct->classCallback((class_handle_t)cdcAcmHandle,
kUSB_DeviceCdcEventSetLineCoding, &reqParam);
}
break;
case USB_DEVICE_CDC_REQUEST_SET_CONTROL_LINE_STATE:
if (((controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) ==
USB_REQUEST_TYPE_DIR_OUT) &&
(controlRequest->setup->wLength == 0U))
{
/* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
it is from the second parameter of classInit */
error = cdcAcmHandle->configStruct->classCallback(
(class_handle_t)cdcAcmHandle, kUSB_DeviceCdcEventSetControlLineState, &reqParam);
}
break;
case USB_DEVICE_CDC_REQUEST_SEND_BREAK:
if (((controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) ==
USB_REQUEST_TYPE_DIR_OUT) &&
(controlRequest->setup->wLength == 0U))
{
/* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
it is from the second parameter of classInit */
error = cdcAcmHandle->configStruct->classCallback((class_handle_t)cdcAcmHandle,
kUSB_DeviceCdcEventSendBreak, &reqParam);
}
break;
default:
/* no action, return kStatus_USB_InvalidRequest */
break;
}
}
break;
default:
/*no action*/
break;
}
return error;
}
/*!
* @brief Initializes the USB CDC ACM class.
*
* This function obtains a usb device handle according to the controller id, initializes the CDC ACM class
* with the class configure parameters and creates the mutex for each pipe.
*
* @param controllerId The id of the controller. The value can be choosen from kUSB_ControllerKhci0,
* kUSB_ControllerKhci1, kUSB_ControllerEhci0 or kUSB_ControllerEhci1.
* @param config The user configuration structure of type usb_device_class_config_struct_t. The user
* populates the members of this structure and passes the pointer of this structure
* into this function.
* @param handle It is out parameter. The class handle of the CDC ACM class.
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceCdcAcmInit(uint8_t controllerId,
usb_device_class_config_struct_t *config,
class_handle_t *handle)
{
usb_device_cdc_acm_struct_t *cdcAcmHandle;
usb_status_t error;
error = USB_DeviceCdcAcmAllocateHandle(&cdcAcmHandle);
if (kStatus_USB_Success != error)
{
return error;
}
error = USB_DeviceClassGetDeviceHandle(controllerId, &cdcAcmHandle->handle);
if (kStatus_USB_Success != error)
{
return error;
}
if (NULL == cdcAcmHandle->handle)
{
return kStatus_USB_InvalidHandle;
}
cdcAcmHandle->configStruct = config;
cdcAcmHandle->configuration = 0;
cdcAcmHandle->alternate = 0xFF;
cdcAcmHandle->bulkIn.mutex = (osa_mutex_handle_t)&cdcAcmHandle->bulkIn.mutexBuffer[0];
if (KOSA_StatusSuccess != OSA_MutexCreate((cdcAcmHandle->bulkIn.mutex)))
{
#if 0
(void)usb_echo("mutex create error!");
#endif
}
cdcAcmHandle->bulkOut.mutex = (osa_mutex_handle_t)&cdcAcmHandle->bulkOut.mutexBuffer[0];
if (KOSA_StatusSuccess != OSA_MutexCreate((cdcAcmHandle->bulkOut.mutex)))
{
#if 0
(void)usb_echo("mutex create error!");
#endif
}
cdcAcmHandle->interruptIn.mutex = (osa_mutex_handle_t)&cdcAcmHandle->interruptIn.mutexBuffer[0];
if (KOSA_StatusSuccess != OSA_MutexCreate((cdcAcmHandle->interruptIn.mutex)))
{
#if 0
(void)usb_echo("mutex create error!");
#endif
}
*handle = (class_handle_t)cdcAcmHandle;
return error;
}
/*!
* @brief De-Initializes the USB CDC ACM class.
*
* This function destroys the mutex for each pipe, deinit each endpoint of the CDC ACM class and free
* the CDC ACM class handle.
*
* @param handle The class handle of the CDC ACM class.
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceCdcAcmDeinit(class_handle_t handle)
{
usb_device_cdc_acm_struct_t *cdcAcmHandle;
usb_status_t error;
cdcAcmHandle = (usb_device_cdc_acm_struct_t *)handle;
if (NULL == cdcAcmHandle)
{
return kStatus_USB_InvalidHandle;
}
if (KOSA_StatusSuccess != OSA_MutexDestroy((cdcAcmHandle->bulkIn.mutex)))
{
#if 0
(void)usb_echo("mutex destroy error!");
#endif
}
if (KOSA_StatusSuccess != OSA_MutexDestroy((cdcAcmHandle->bulkOut.mutex)))
{
#if 0
(void)usb_echo("mutex destroy error!");
#endif
}
if (KOSA_StatusSuccess != OSA_MutexDestroy((cdcAcmHandle->interruptIn.mutex)))
{
#if 0
(void)usb_echo("mutex destroy error!");
#endif
}
error = USB_DeviceCdcAcmEndpointsDeinit(cdcAcmHandle);
(void)USB_DeviceCdcAcmFreeHandle(cdcAcmHandle);
return error;
}
/*!
* @brief Prime the endpoint to send packet to host.
*
* This function checks whether the endpoint is sending packet, then it primes the endpoint
* with the buffer address and the buffer length if the pipe is not busy. Otherwise, it ignores this transfer by
* returning an error code.
*
* @param handle The class handle of the CDC ACM class.
* @param ep The endpoint number of the transfer.
* @param buffer The pointer to the buffer to be transferred.
* @param length The length of the buffer to be transferred.
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceCdcAcmSend(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length)
{
usb_device_cdc_acm_struct_t *cdcAcmHandle;
usb_status_t status = kStatus_USB_Error;
usb_device_cdc_acm_pipe_t *cdcAcmPipe = NULL;
if (NULL == handle)
{
return kStatus_USB_InvalidHandle;
}
cdcAcmHandle = (usb_device_cdc_acm_struct_t *)handle;
if (cdcAcmHandle->bulkIn.ep == ep)
{
cdcAcmPipe = &(cdcAcmHandle->bulkIn);
}
else if (cdcAcmHandle->interruptIn.ep == ep)
{
cdcAcmPipe = &(cdcAcmHandle->interruptIn);
}
else
{
/*no action*/
}
if (NULL != cdcAcmPipe)
{
if (1U == cdcAcmPipe->isBusy)
{
return kStatus_USB_Busy;
}
cdcAcmPipe->isBusy = 1U;
if (0u != cdcAcmPipe->pipeStall)
{
cdcAcmPipe->pipeDataBuffer = buffer;
cdcAcmPipe->pipeDataLen = length;
return kStatus_USB_Success;
}
status = USB_DeviceSendRequest(cdcAcmHandle->handle, ep, buffer, length);
if (kStatus_USB_Success != status)
{
cdcAcmPipe->isBusy = 0U;
}
}
return status;
}
/*!
* @brief Prime the endpoint to receive packet from host.
*
* This function checks whether the endpoint is receiving packet, then it primes the endpoint
* with the buffer address and the buffer length if the pipe is not busy. Otherwise, it ignores this transfer by
* returning an error code.
*
* @param handle The class handle of the CDC ACM class.
* @param ep The endpoint number of the transfer.
* @param buffer The pointer to the buffer to be transferred.
* @param length The length of the buffer to be transferred.
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceCdcAcmRecv(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length)
{
usb_device_cdc_acm_struct_t *cdcAcmHandle;
usb_status_t status;
if (NULL == handle)
{
return kStatus_USB_InvalidHandle;
}
cdcAcmHandle = (usb_device_cdc_acm_struct_t *)handle;
if (1U == cdcAcmHandle->bulkOut.isBusy)
{
return kStatus_USB_Busy;
}
cdcAcmHandle->bulkOut.isBusy = 1U;
if (0U != cdcAcmHandle->bulkOut.pipeStall)
{
cdcAcmHandle->bulkOut.pipeDataBuffer = buffer;
cdcAcmHandle->bulkOut.pipeDataLen = length;
return kStatus_USB_Success;
}
status = USB_DeviceRecvRequest(cdcAcmHandle->handle, ep, buffer, length);
if (kStatus_USB_Success != status)
{
cdcAcmHandle->bulkOut.isBusy = 0U;
}
return status;
}
#endif /* USB_DEVICE_CONFIG_CDC_ACM */

View file

@ -0,0 +1,270 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016,2019 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _USB_DEVICE_CDC_ACM_H_
#define _USB_DEVICE_CDC_ACM_H_
/*!
* @addtogroup cdc_acm
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
#define USB_DEVICE_CONFIG_CDC_ACM_MAX_INSTANCE (1U) /*!< The maximum number of CDC device instance. */
#define USB_DEVICE_CONFIG_CDC_COMM_CLASS_CODE (0x02U) /*!< The CDC communication class code. */
#define USB_DEVICE_CONFIG_CDC_DATA_CLASS_CODE (0x0AU) /*!< The CDC data class code. */
#define USB_DEVICE_CDC_REQUEST_SEND_ENCAPSULATED_COMMAND \
(0x00) /*!< The CDC class request code for SEND_ENCAPSULATED_COMMAND. */
#define USB_DEVICE_CDC_REQUEST_GET_ENCAPSULATED_RESPONSE \
(0x01) /*!< The CDC class request code for GET_ENCAPSULATED_RESPONSE. */
#define USB_DEVICE_CDC_REQUEST_SET_COMM_FEATURE (0x02) /*!< The CDC class request code for SET_COMM_FEATURE. */
#define USB_DEVICE_CDC_REQUEST_GET_COMM_FEATURE (0x03) /*!< The CDC class request code for GET_COMM_FEATURE. */
#define USB_DEVICE_CDC_REQUEST_CLEAR_COMM_FEATURE (0x04) /*!< The CDC class request code for CLEAR_COMM_FEATURE. */
#define USB_DEVICE_CDC_REQUEST_SET_AUX_LINE_STATE (0x10) /*!< The CDC class request code for SET_AUX_LINE_STATE. */
#define USB_DEVICE_CDC_REQUEST_SET_HOOK_STATE (0x11) /*!< The CDC class request code for SET_HOOK_STATE. */
#define USB_DEVICE_CDC_REQUEST_PULSE_SETUP (0x12) /*!< The CDC class request code for PULSE_SETUP. */
#define USB_DEVICE_CDC_REQUEST_SEND_PULSE (0x13) /*!< The CDC class request code for SEND_PULSE. */
#define USB_DEVICE_CDC_REQUEST_SET_PULSE_TIME (0x14) /*!< The CDC class request code for SET_PULSE_TIME. */
#define USB_DEVICE_CDC_REQUEST_RING_AUX_JACK (0x15) /*!< The CDC class request code for RING_AUX_JACK. */
#define USB_DEVICE_CDC_REQUEST_SET_LINE_CODING (0x20) /*!< The CDC class request code for SET_LINE_CODING. */
#define USB_DEVICE_CDC_REQUEST_GET_LINE_CODING (0x21) /*!< The CDC class request code for GET_LINE_CODING. */
#define USB_DEVICE_CDC_REQUEST_SET_CONTROL_LINE_STATE \
(0x22) /*!< The CDC class request code for SET_CONTROL_LINE_STATE. */
#define USB_DEVICE_CDC_REQUEST_SEND_BREAK (0x23) /*!< The CDC class request code for SEND_BREAK. */
#define USB_DEVICE_CDC_REQUEST_SET_RINGER_PARAMS (0x30) /*!< The CDC class request code for SET_RINGER_PARAMS. */
#define USB_DEVICE_CDC_REQUEST_GET_RINGER_PARAMS (0x31) /*!< The CDC class request code for GET_RINGER_PARAMS. */
#define USB_DEVICE_CDC_REQUEST_SET_OPERATION_PARAM (0x32) /*!< The CDC class request code for SET_OPERATION_PARAM. */
#define USB_DEVICE_CDC_REQUEST_GET_OPERATION_PARAM (0x33) /*!< The CDC class request code for GET_OPERATION_PARAM. */
#define USB_DEVICE_CDC_REQUEST_SET_LINE_PARAMS (0x34) /*!< The CDC class request code for SET_LINE_PARAMS. */
#define USB_DEVICE_CDC_REQUEST_GET_LINE_PARAMS (0x35) /*!< The CDC class request code for GET_LINE_PARAMS. */
#define USB_DEVICE_CDC_REQUEST_DIAL_DIGITS (0x36) /*!< The CDC class request code for DIAL_DIGITS. */
#define USB_DEVICE_CDC_REQUEST_SET_UNIT_PARAMETER (0x37) /*!< The CDC class request code for SET_UNIT_PARAMETER. */
#define USB_DEVICE_CDC_REQUEST_GET_UNIT_PARAMETER (0x38) /*!< The CDC class request code for GET_UNIT_PARAMETER. */
#define USB_DEVICE_CDC_REQUEST_CLEAR_UNIT_PARAMETER \
(0x39) /*!< The CDC class request code for CLEAR_UNIT_PARAMETER. */
#define USB_DEVICE_CDC_REQUEST_SET_ETHERNET_MULTICAST_FILTERS \
(0x40) /*!< The CDC class request code for SET_ETHERNET_MULTICAST_FILTERS. */
#define USB_DEVICE_CDC_REQUEST_SET_ETHERNET_POW_PATTER_FILTER \
(0x41) /*!< The CDC class request code for SET_ETHERNET_POW_PATTER_FILTER. */
#define USB_DEVICE_CDC_REQUEST_GET_ETHERNET_POW_PATTER_FILTER \
(0x42) /*!< The CDC class request code for GET_ETHERNET_POW_PATTER_FILTER. */
#define USB_DEVICE_CDC_REQUEST_SET_ETHERNET_PACKET_FILTER \
(0x43) /*!< The CDC class request code for SET_ETHERNET_PACKET_FILTER. */
#define USB_DEVICE_CDC_REQUEST_GET_ETHERNET_STATISTIC \
(0x44) /*!< The CDC class request code for GET_ETHERNET_STATISTIC. */
#define USB_DEVICE_CDC_REQUEST_SET_ATM_DATA_FORMAT (0x50) /*!< The CDC class request code for SET_ATM_DATA_FORMAT. */
#define USB_DEVICE_CDC_REQUEST_GET_ATM_DEVICE_STATISTICS \
(0x51) /*!< The CDC class request code for GET_ATM_DEVICE_STATISTICS. */
#define USB_DEVICE_CDC_REQUEST_SET_ATM_DEFAULT_VC (0x52) /*!< The CDC class request code for SET_ATM_DEFAULT_VC. */
#define USB_DEVICE_CDC_REQUEST_GET_ATM_VC_STATISTICS \
(0x53) /*!< The CDC class request code for GET_ATM_VC_STATISTICS. */
#define USB_DEVICE_CDC_REQUEST_MDLM_SPECIFIC_REQUESTS_MASK \
(0x7F) /*!< The CDC class request code for MDLM_SPECIFIC_REQUESTS_MASK. */
#define USB_DEVICE_CDC_NOTIF_NETWORK_CONNECTION (0x00) /*!< The CDC class notify code for NETWORK_CONNECTION. */
#define USB_DEVICE_CDC_NOTIF_RESPONSE_AVAIL (0x01) /*!< The CDC class notify code for RESPONSE_AVAIL. */
#define USB_DEVICE_CDC_NOTIF_AUX_JACK_HOOK_STATE (0x08) /*!< The CDC class notify code for AUX_JACK_HOOK_STATE. */
#define USB_DEVICE_CDC_NOTIF_RING_DETECT (0x09) /*!< The CDC class notify code for RING_DETECT. */
#define USB_DEVICE_CDC_NOTIF_SERIAL_STATE (0x20) /*!< The CDC class notify code for SERIAL_STATE. */
#define USB_DEVICE_CDC_NOTIF_CALL_STATE_CHANGE (0x28) /*!< The CDC class notify code for CALL_STATE_CHANGE. */
#define USB_DEVICE_CDC_NOTIF_LINE_STATE_CHANGE (0x29) /*!< The CDC class notify code for LINE_STATE_CHANGE. */
#define USB_DEVICE_CDC_NOTIF_CONNECTION_SPEED_CHANGE \
(0x2A) /*!< The CDC class notify code for CONNECTION_SPEED_CHANGE. */
#define USB_DEVICE_CDC_FEATURE_ABSTRACT_STATE (0x01) /*!< The CDC class feature select code for ABSTRACT_STATE. */
#define USB_DEVICE_CDC_FEATURE_COUNTRY_SETTING (0x02) /*!< The CDC class feature select code for COUNTRY_SETTING. */
#define USB_DEVICE_CDC_CONTROL_SIG_BITMAP_CARRIER_ACTIVATION \
(0x02) /*!< The CDC class control signal bitmap value for CARRIER_ACTIVATION. */
#define USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE \
(0x01) /*!< The CDC class control signal bitmap value for DTE_PRESENCE. */
#define USB_DEVICE_CDC_UART_STATE_RX_CARRIER (0x01) /*!< The UART state bitmap value of RX_CARRIER. */
#define USB_DEVICE_CDC_UART_STATE_TX_CARRIER (0x02) /*!< The UART state bitmap value of TX_CARRIER. */
#define USB_DEVICE_CDC_UART_STATE_BREAK (0x04) /*!< The UART state bitmap value of BREAK. */
#define USB_DEVICE_CDC_UART_STATE_RING_SIGNAL (0x08) /*!< The UART state bitmap value of RING_SIGNAL. */
#define USB_DEVICE_CDC_UART_STATE_FRAMING (0x10) /*!< The UART state bitmap value of FRAMING. */
#define USB_DEVICE_CDC_UART_STATE_PARITY (0x20) /*!< The UART state bitmap value of PARITY. */
#define USB_DEVICE_CDC_UART_STATE_OVERRUN (0x40) /*!< The UART state bitmap value of OVERRUN. */
/*! @brief Definition of CDC class event. */
typedef enum _usb_device_cdc_acm_event
{
kUSB_DeviceCdcEventSendResponse = 0x01, /*!< This event indicates the bulk send transfer is complete or cancelled etc. */
kUSB_DeviceCdcEventRecvResponse, /*!< This event indicates the bulk receive transfer is complete or cancelled etc.. */
kUSB_DeviceCdcEventSerialStateNotif, /*!< This event indicates the serial state has been sent to the host. */
kUSB_DeviceCdcEventSendEncapsulatedCommand, /*!< This event indicates the device received the
SEND_ENCAPSULATED_COMMAND request. */
kUSB_DeviceCdcEventGetEncapsulatedResponse, /*!< This event indicates the device received the
GET_ENCAPSULATED_RESPONSE request. */
kUSB_DeviceCdcEventSetCommFeature, /*!< This event indicates the device received the SET_COMM_FEATURE request. */
kUSB_DeviceCdcEventGetCommFeature, /*!< This event indicates the device received the GET_COMM_FEATURE request. */
kUSB_DeviceCdcEventClearCommFeature, /*!< This event indicates the device received the CLEAR_COMM_FEATURE request.
*/
kUSB_DeviceCdcEventGetLineCoding, /*!< This event indicates the device received the GET_LINE_CODING request. */
kUSB_DeviceCdcEventSetLineCoding, /*!< This event indicates the device received the SET_LINE_CODING request. */
kUSB_DeviceCdcEventSetControlLineState, /*!< This event indicates the device received the SET_CONTRL_LINE_STATE
request. */
kUSB_DeviceCdcEventSendBreak /*!< This event indicates the device received the SEND_BREAK request. */
} usb_device_cdc_acm_event_t;
/*! @brief Definition of parameters for CDC ACM request. */
typedef struct _usb_device_cdc_acm_request_param_struct
{
uint8_t **buffer; /*!< The pointer to the address of the buffer for CDC class request. */
uint32_t *length; /*!< The pointer to the length of the buffer for CDC class request. */
uint16_t interfaceIndex; /*!< The interface index of the setup packet. */
uint16_t setupValue; /*!< The wValue field of the setup packet. */
uint8_t isSetup; /*!< The flag indicates if it is a setup packet, 1: yes, 0: no. */
} usb_device_cdc_acm_request_param_struct_t;
/*! @brief Definition of pipe structure. */
typedef struct _usb_device_cdc_acm_pipe
{
osa_mutex_handle_t mutex; /*!< The mutex of the pipe. */
uint32_t mutexBuffer[(OSA_MUTEX_HANDLE_SIZE + 3)/4];
uint8_t *pipeDataBuffer; /*!< pipe data buffer backup when stall */
uint32_t pipeDataLen; /*!< pipe data length backup when stall */
uint8_t pipeStall; /*!< pipe is stall */
uint8_t ep; /*!< The endpoint number of the pipe. */
uint8_t isBusy; /*!< 1: The pipe is transferring packet, 0: The pipe is idle. */
} usb_device_cdc_acm_pipe_t;
/*! @brief Definition of structure for CDC ACM device. */
typedef struct _usb_device_cdc_acm_struct
{
usb_device_handle handle; /*!< The handle of the USB device. */
usb_device_class_config_struct_t *configStruct; /*!< The class configure structure. */
usb_device_interface_struct_t *commInterfaceHandle; /*!< The CDC communication interface handle. */
usb_device_interface_struct_t *dataInterfaceHandle; /*!< The CDC data interface handle. */
usb_device_cdc_acm_pipe_t bulkIn; /*!< The bulk in pipe for sending packet to host. */
usb_device_cdc_acm_pipe_t bulkOut; /*!< The bulk out pipe for receiving packet from host. */
usb_device_cdc_acm_pipe_t interruptIn; /*!< The interrupt in pipe for notifying the device state to host. */
uint8_t configuration; /*!< The current configuration value. */
uint8_t interfaceNumber; /*!< The current interface number. */
uint8_t alternate; /*!< The alternate setting value of the interface. */
uint8_t hasSentState; /*!< 1: The device has primed the state in interrupt pipe, 0: Not primed the state. */
} usb_device_cdc_acm_struct_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name USB CDC ACM Class Driver
* @{
*/
/*!
* @brief Initializes the USB CDC ACM class.
*
* This function obtains a USB device handle according to the controller ID, initializes the CDC ACM class
* with the class configure parameters and creates the mutex for each pipe.
*
* @param controllerId The ID of the controller. The value can be chosen from the kUSB_ControllerKhci0,
* kUSB_ControllerKhci1, kUSB_ControllerEhci0, or kUSB_ControllerEhci1.
* @param config The user configuration structure of type usb_device_class_config_struct_t. The user
* populates the members of this structure and passes the pointer of this structure
* into this function.
* @param handle It is out parameter. The class handle of the CDC ACM class.
* @return A USB error code or kStatus_USB_Success.
* @retval kStatus_USB_Success The CDC ACM class is initialized successfully.
* @retval kStatus_USB_Busy No CDC ACM device handle available for allocation.
* @retval kStatus_USB_InvalidHandle The CDC ACM device handle allocation failure.
* @retval kStatus_USB_InvalidParameter The USB device handle allocation failure.
*/
extern usb_status_t USB_DeviceCdcAcmInit(uint8_t controllerId,
usb_device_class_config_struct_t *config,
class_handle_t *handle);
/*!
* @brief Deinitializes the USB CDC ACM class.
*
* This function destroys the mutex for each pipe, deinitializes each endpoint of the CDC ACM class and frees
* the CDC ACM class handle.
*
* @param handle The class handle of the CDC ACM class.
* @return A USB error code or kStatus_USB_Success.
* @retval kStatus_USB_Success The CDC ACM class is de-initialized successfully.
* @retval kStatus_USB_Error The endpoint deinitialization failure.
* @retval kStatus_USB_InvalidHandle The CDC ACM device handle or the CDC ACM class handle is invalid.
* @retval kStatus_USB_InvalidParameter The endpoint number of the CDC ACM class handle is invalid.
*/
extern usb_status_t USB_DeviceCdcAcmDeinit(class_handle_t handle);
/*!
* @brief Handles the CDC ACM class event.
*
* This function responds to various events including the common device events and the class-specific events.
* For class-specific events, it calls the class callback defined in the application to deal with the class-specific
* event.
*
* @param handle The class handle of the CDC ACM class.
* @param event The event type.
* @param param The class handle of the CDC ACM class.
* @return A USB error code or kStatus_USB_Success.
* @retval kStatus_USB_Success The CDC ACM class is de-initialized successfully.
* @retval kStatus_USB_Error The configure structure of the CDC ACM class handle is invalid.
* @retval kStatus_USB_InvalidHandle The CDC ACM device handle or the CDC ACM class handle is invalid.
* @retval kStatus_USB_InvalidParameter The endpoint number of the CDC ACM class handle is invalid.
* @retval Others The error code returned by class callback in application.
*/
extern usb_status_t USB_DeviceCdcAcmEvent(void *handle, uint32_t event, void *param);
/*!
* @brief Primes the endpoint to send packet to host.
*
* This function checks whether the endpoint is sending packet, then it primes the endpoint
* with the buffer address and the buffer length if the pipe is not busy. Otherwise, it ignores this transfer by
* returning an error code.
*
* @param handle The class handle of the CDC ACM class.
* @param ep The endpoint number of the transfer.
* @param buffer The pointer to the buffer to be transferred.
* @param length The length of the buffer to be transferred.
* @return A USB error code or kStatus_USB_Success.
* @retval kStatus_USB_Success Prime to send packet successfully.
* @retval kStatus_USB_Busy The endpoint is busy in transferring.
* @retval kStatus_USB_InvalidHandle The CDC ACM device handle or the CDC ACM class handle is invalid.
* @retval kStatus_USB_ControllerNotFound The controller interface is invalid.
*
* @note The function can only be called in the same context.
*/
extern usb_status_t USB_DeviceCdcAcmSend(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length);
/*!
* @brief Primes the endpoint to receive packet from host.
*
* This function checks whether the endpoint is receiving packet, then it primes the endpoint
* with the buffer address and the buffer length if the pipe is not busy. Otherwise, it ignores this transfer by
* returning an error code.
*
* @param handle The class handle of the CDC ACM class.
* @param ep The endpoint number of the transfer.
* @param buffer The pointer to the buffer to be transferred.
* @param length The length of the buffer to be transferred.
* @return A USB error code or kStatus_USB_Success.
* @retval kStatus_USB_Success Prime to receive packet successfully.
* @retval kStatus_USB_Busy The endpoint is busy in transferring.
* @retval kStatus_USB_InvalidHandle The CDC ACM device handle or the CDC ACM class handle is invalid.
* @retval kStatus_USB_ControllerNotFound The controller interface is invalid.
*
* @note The function can only be called in the same context.
*/
extern usb_status_t USB_DeviceCdcAcmRecv(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length);
/*! @}*/
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* _USB_DEVICE_CDC_ACM_H_ */

View file

@ -0,0 +1,595 @@
/*
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
* Copyright 2016, 2019 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "usb_device_config.h"
#include "usb.h"
#include "usb_device.h"
#include "usb_device_ch9.h"
#include "usb_device_class.h"
#if ((defined(USB_DEVICE_CONFIG_NUM)) && (USB_DEVICE_CONFIG_NUM > 0U))
/* Include the class drivers according to the usb_device_config.h. */
#if ((defined(USB_DEVICE_CONFIG_HID)) && (USB_DEVICE_CONFIG_HID > 0U))
#include "usb_device_hid.h"
#endif
#if ((defined(USB_DEVICE_CONFIG_CDC_ACM)) && (USB_DEVICE_CONFIG_CDC_ACM > 0U))
#include "usb_device_cdc_acm.h"
#endif
#if ((defined(USB_DEVICE_CONFIG_MSC)) && (USB_DEVICE_CONFIG_MSC > 0U))
#include "usb_device_msc.h"
#endif
#if ((defined(USB_DEVICE_CONFIG_MTP)) && (USB_DEVICE_CONFIG_MTP > 0U))
#include "usb_device_mtp.h"
#endif
#if ((defined(USB_DEVICE_CONFIG_AUDIO)) && (USB_DEVICE_CONFIG_AUDIO > 0U))
#include "usb_device_audio.h"
#endif
#if ((defined(USB_DEVICE_CONFIG_PHDC)) && (USB_DEVICE_CONFIG_PHDC > 0U))
#include "usb_device_phdc.h"
#endif
#if ((defined(USB_DEVICE_CONFIG_VIDEO)) && (USB_DEVICE_CONFIG_VIDEO > 0U))
#include "usb_device_video.h"
#endif
#if ((defined(USB_DEVICE_CONFIG_PRINTER)) && (USB_DEVICE_CONFIG_PRINTER > 0U))
#include "usb_device_printer.h"
#endif
#if ((defined(USB_DEVICE_CONFIG_DFU)) && (USB_DEVICE_CONFIG_DFU > 0U))
#include "usb_device_dfu.h"
#endif
#if ((defined(USB_DEVICE_CONFIG_CCID)) && (USB_DEVICE_CONFIG_CCID > 0U))
#include "usb_device_ccid.h"
#endif
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* Prototypes
******************************************************************************/
static usb_status_t USB_DeviceClassAllocateHandle(uint8_t controllerId, usb_device_common_class_struct_t **handle);
static usb_status_t USB_DeviceClassFreeHandle(uint8_t controllerId);
static usb_status_t USB_DeviceClassGetHandleByControllerId(uint8_t controllerId,
usb_device_common_class_struct_t **handle);
static usb_status_t USB_DeviceClassGetHandleByDeviceHandle(usb_device_handle deviceHandle,
usb_device_common_class_struct_t **handle);
/*******************************************************************************
* Variables
******************************************************************************/
/* The device class driver list. */
static const usb_device_class_map_t s_UsbDeviceClassInterfaceMap[] = {
#if ((defined(USB_DEVICE_CONFIG_HID)) && (USB_DEVICE_CONFIG_HID > 0U))
{USB_DeviceHidInit, USB_DeviceHidDeinit, USB_DeviceHidEvent, kUSB_DeviceClassTypeHid},
#endif
#if ((defined(USB_DEVICE_CONFIG_CDC_ACM)) && (USB_DEVICE_CONFIG_CDC_ACM > 0U))
{USB_DeviceCdcAcmInit, USB_DeviceCdcAcmDeinit, USB_DeviceCdcAcmEvent, kUSB_DeviceClassTypeCdc},
#endif
#if ((defined(USB_DEVICE_CONFIG_MSC)) && (USB_DEVICE_CONFIG_MSC > 0U))
{USB_DeviceMscInit, USB_DeviceMscDeinit, USB_DeviceMscEvent, kUSB_DeviceClassTypeMsc},
#endif
#if ((defined(USB_DEVICE_CONFIG_MTP)) && (USB_DEVICE_CONFIG_MTP > 0U))
{USB_DeviceMtpInit, USB_DeviceMtpDeinit, USB_DeviceMtpEvent, kUSB_DeviceClassTypeMtp},
#endif
#if ((defined USB_DEVICE_CONFIG_AUDIO) && (USB_DEVICE_CONFIG_AUDIO > 0U))
{USB_DeviceAudioInit, USB_DeviceAudioDeinit, USB_DeviceAudioEvent, kUSB_DeviceClassTypeAudio},
#endif
#if ((defined USB_DEVICE_CONFIG_PHDC) && (USB_DEVICE_CONFIG_PHDC > 0U))
{USB_DevicePhdcInit, USB_DevicePhdcDeinit, USB_DevicePhdcEvent, kUSB_DeviceClassTypePhdc},
#endif
#if ((defined USB_DEVICE_CONFIG_VIDEO) && (USB_DEVICE_CONFIG_VIDEO > 0U))
{USB_DeviceVideoInit, USB_DeviceVideoDeinit, USB_DeviceVideoEvent, kUSB_DeviceClassTypeVideo},
#endif
#if ((defined USB_DEVICE_CONFIG_PRINTER) && (USB_DEVICE_CONFIG_PRINTER > 0U))
{USB_DevicePrinterInit, USB_DevicePrinterDeinit, USB_DevicePrinterEvent, kUSB_DeviceClassTypePrinter},
#endif
#if ((defined USB_DEVICE_CONFIG_DFU) && (USB_DEVICE_CONFIG_DFU > 0U))
{USB_DeviceDfuInit, USB_DeviceDfuDeinit, USB_DeviceDfuEvent, kUSB_DeviceClassTypeDfu},
#endif
#if ((defined USB_DEVICE_CONFIG_CCID) && (USB_DEVICE_CONFIG_CCID > 0U))
{USB_DeviceCcidInit, USB_DeviceCcidDeinit, USB_DeviceCcidEvent, kUSB_DeviceClassTypeCcid},
#endif
/* please make sure the following member is in the end of s_UsbDeviceClassInterfaceMap*/
{(usb_device_class_init_call_t)NULL, (usb_device_class_deinit_call_t)NULL, (usb_device_class_event_callback_t)NULL,
(usb_device_class_type_t)0},
};
USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_common_class_struct_t
s_UsbDeviceCommonClassStruct[USB_DEVICE_CONFIG_NUM];
USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static uint8_t
s_UsbDeviceSetupBuffer[USB_DEVICE_CONFIG_NUM][USB_DATA_ALIGN_SIZE_MULTIPLE(USB_SETUP_PACKET_SIZE)];
/*******************************************************************************
* Code
******************************************************************************/
/*!
* @brief Allocate a device common class handle.
*
* This function allocates a a device common class handle.
*
* @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
* @param handle It is out parameter, is used to return pointer of the device common class handle to the
* caller.
*
* @retval kStatus_USB_Success Get a device handle successfully.
* @retval kStatus_USB_Busy Cannot allocate a common class handle.
* @retval kStatus_USB_Error The common class has been initialized.
*/
static usb_status_t USB_DeviceClassAllocateHandle(uint8_t controllerId, usb_device_common_class_struct_t **handle)
{
uint32_t count;
OSA_SR_ALLOC();
OSA_ENTER_CRITICAL();
/* Check the controller is initialized or not. */
for (count = 0U; count < USB_DEVICE_CONFIG_NUM; count++)
{
if ((NULL != s_UsbDeviceCommonClassStruct[count].handle) &&
(controllerId == s_UsbDeviceCommonClassStruct[count].controllerId))
{
OSA_EXIT_CRITICAL();
return kStatus_USB_Error;
}
}
/* Get a free common class handle. */
for (count = 0U; count < USB_DEVICE_CONFIG_NUM; count++)
{
if (NULL == s_UsbDeviceCommonClassStruct[count].handle)
{
s_UsbDeviceCommonClassStruct[count].controllerId = controllerId;
s_UsbDeviceCommonClassStruct[count].setupBuffer = s_UsbDeviceSetupBuffer[count];
*handle = &s_UsbDeviceCommonClassStruct[count];
OSA_EXIT_CRITICAL();
return kStatus_USB_Success;
}
}
OSA_EXIT_CRITICAL();
return kStatus_USB_Busy;
}
/*!
* @brief Free a device common class handle.
*
* This function frees a device common class handle.
*
* @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
*
* @retval kStatus_USB_Success Free device handle successfully.
* @retval kStatus_USB_InvalidParameter The common class can not be found.
*/
static usb_status_t USB_DeviceClassFreeHandle(uint8_t controllerId)
{
uint32_t count = 0U;
OSA_SR_ALLOC();
OSA_ENTER_CRITICAL();
for (; count < USB_DEVICE_CONFIG_NUM; count++)
{
if ((NULL != s_UsbDeviceCommonClassStruct[count].handle) &&
(controllerId == s_UsbDeviceCommonClassStruct[count].controllerId))
{
s_UsbDeviceCommonClassStruct[count].handle = NULL;
s_UsbDeviceCommonClassStruct[count].configList = (usb_device_class_config_list_struct_t *)NULL;
s_UsbDeviceCommonClassStruct[count].controllerId = 0U;
OSA_EXIT_CRITICAL();
return kStatus_USB_Success;
}
}
OSA_EXIT_CRITICAL();
return kStatus_USB_InvalidParameter;
}
/*!
* @brief Get the device common class handle according to the controller id.
*
* This function gets the device common class handle according to the controller id.
*
* @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
* @param handle It is out parameter, is used to return pointer of the device common class handle to the
* caller.
*
* @retval kStatus_USB_Success Free device handle successfully.
* @retval kStatus_USB_InvalidParameter The common class can not be found.
*/
static usb_status_t USB_DeviceClassGetHandleByControllerId(uint8_t controllerId,
usb_device_common_class_struct_t **handle)
{
uint32_t count = 0U;
OSA_SR_ALLOC();
OSA_ENTER_CRITICAL();
for (; count < USB_DEVICE_CONFIG_NUM; count++)
{
if ((NULL != s_UsbDeviceCommonClassStruct[count].handle) &&
(controllerId == s_UsbDeviceCommonClassStruct[count].controllerId))
{
*handle = &s_UsbDeviceCommonClassStruct[count];
OSA_EXIT_CRITICAL();
return kStatus_USB_Success;
}
}
OSA_EXIT_CRITICAL();
return kStatus_USB_InvalidParameter;
}
/*!
* @brief Get the device common class handle according to the device handle.
*
* This function gets the device common class handle according to the device handle.
*
* @param deviceHandle The device handle, got from the USB_DeviceInit.
* @param handle It is out parameter, is used to return pointer of the device common class handle to the
* caller.
*
* @retval kStatus_USB_Success Free device handle successfully.
* @retval kStatus_USB_InvalidParameter The common class can not be found.
*/
static usb_status_t USB_DeviceClassGetHandleByDeviceHandle(usb_device_handle deviceHandle,
usb_device_common_class_struct_t **handle)
{
uint32_t count = 0U;
OSA_SR_ALLOC();
OSA_ENTER_CRITICAL();
for (; count < USB_DEVICE_CONFIG_NUM; count++)
{
if (deviceHandle == s_UsbDeviceCommonClassStruct[count].handle)
{
*handle = &s_UsbDeviceCommonClassStruct[count];
OSA_EXIT_CRITICAL();
return kStatus_USB_Success;
}
}
OSA_EXIT_CRITICAL();
return kStatus_USB_InvalidParameter;
}
/*!
* @brief Get the device handle according to the controller id.
*
* This function gets the device handle according to the controller id.
*
* @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
* @param handle It is out parameter, is used to return pointer of the device handle to the caller.
*
* @retval kStatus_USB_Success Free device handle successfully.
* @retval kStatus_USB_InvalidParameter The device handle not be found.
*/
usb_status_t USB_DeviceClassGetDeviceHandle(uint8_t controllerId, usb_device_handle *handle)
{
uint32_t count = 0U;
OSA_SR_ALLOC();
OSA_ENTER_CRITICAL();
for (; count < USB_DEVICE_CONFIG_NUM; count++)
{
if ((NULL != s_UsbDeviceCommonClassStruct[count].handle) &&
(controllerId == s_UsbDeviceCommonClassStruct[count].controllerId))
{
*handle = s_UsbDeviceCommonClassStruct[count].handle;
OSA_EXIT_CRITICAL();
return kStatus_USB_Success;
}
}
OSA_EXIT_CRITICAL();
return kStatus_USB_InvalidParameter;
}
/*!
* @brief Handle the event passed to the class drivers.
*
* This function handles the event passed to the class drivers.
*
* @param handle The device handle, got from the USB_DeviceInit.
* @param event The event codes. Please refer to the enumeration usb_device_class_event_t.
* @param param The param type is determined by the event code.
*
* @return A USB error code or kStatus_USB_Success.
* @retval kStatus_USB_Success A valid request has been handled.
* @retval kStatus_USB_InvalidParameter The device handle not be found.
* @retval kStatus_USB_InvalidRequest The request is invalid, and the control pipe will be stalled by the caller.
*/
usb_status_t USB_DeviceClassEvent(usb_device_handle handle, usb_device_class_event_t event, void *param)
{
usb_device_common_class_struct_t *classHandle;
uint8_t mapIndex;
uint8_t classIndex;
usb_status_t errorReturn;
usb_status_t status = kStatus_USB_Error;
if (NULL == param)
{
return kStatus_USB_InvalidParameter;
}
/* Get the common class handle according to the device handle. */
errorReturn = USB_DeviceClassGetHandleByDeviceHandle(handle, &classHandle);
if (kStatus_USB_Success != errorReturn)
{
return kStatus_USB_InvalidParameter;
}
for (classIndex = 0U; classIndex < classHandle->configList->count; classIndex++)
{
for (mapIndex = 0U; mapIndex < (ARRAY_SIZE(s_UsbDeviceClassInterfaceMap) - 1U); mapIndex++)
{
if (s_UsbDeviceClassInterfaceMap[mapIndex].type ==
classHandle->configList->config[classIndex].classInfomation->type)
{
/* Call class event callback of supported class */
errorReturn = s_UsbDeviceClassInterfaceMap[mapIndex].classEventCallback(
(void *)classHandle->configList->config[classIndex].classHandle, event, param);
/* Return the error code kStatus_USB_InvalidRequest immediately, when a class returns
* kStatus_USB_InvalidRequest. */
if (kStatus_USB_InvalidRequest == errorReturn)
{
return kStatus_USB_InvalidRequest;
}
/* For composite device, it should return kStatus_USB_Success once a valid request has been handled */
if (kStatus_USB_Success == errorReturn)
{
status = kStatus_USB_Success;
}
break;
}
}
}
return status;
}
/*!
* @brief Handle the common class callback.
*
* This function handles the common class callback.
*
* @param handle The device handle, got from the USB_DeviceInit.
* @param event The event codes. Please refer to the enumeration usb_device_event_t.
* @param param The param type is determined by the event code.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceClassCallback(usb_device_handle handle, uint32_t event, void *param)
{
usb_device_common_class_struct_t *classHandle;
usb_status_t status;
/* Get the common class handle according to the device handle. */
status = USB_DeviceClassGetHandleByDeviceHandle(handle, &classHandle);
if (kStatus_USB_Success != status)
{
return status;
}
if ((uint32_t)kUSB_DeviceEventBusReset == event)
{
/* Initialize the control pipes */
(void)USB_DeviceControlPipeInit(handle, classHandle);
/* Notify the classes the USB bus reset signal detected. */
(void)USB_DeviceClassEvent(handle, kUSB_DeviceClassEventDeviceReset, classHandle);
}
/* Call the application device callback function. deviceCallback is from the second parameter of
USB_DeviceClassInit */
status = classHandle->configList->deviceCallback(handle, event, param);
return status;
}
/*!
* @brief Initialize the common class and the supported classes.
*
* This function is used to initialize the common class and the supported classes.
*
* @param[in] controllerId The controller id of the USB IP. Please refer to the enumeration #usb_controller_index_t.
* @param[in] configList The class configurations. The pointer must point to the global variable.
* Please refer to the structure #usb_device_class_config_list_struct_t.
* @param[out] handle It is out parameter, is used to return pointer of the device handle to the caller.
* The value of parameter is a pointer points the device handle, and this design is used to
* make simple device align with composite device. For composite device, there are many
* kinds of class handle, but there is only one device handle. So the handle points to
* a device instead of a class. And the class handle can be got from the
* #usb_device_class_config_struct_t::classHandle after the function successfully.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceClassInit(
uint8_t controllerId, /*!< [IN] Controller ID */
usb_device_class_config_list_struct_t *configList, /*!< [IN] Pointer to class configuration list */
usb_device_handle *handle /*!< [OUT] Pointer to the device handle */
)
{
usb_device_common_class_struct_t *classHandle;
usb_status_t error;
uint8_t mapIndex;
uint8_t classIndex;
if ((NULL == handle) || (NULL == configList) || ((usb_device_callback_t)NULL == configList->deviceCallback))
{
return kStatus_USB_InvalidParameter;
}
/* Allocate a common class driver handle. */
error = USB_DeviceClassAllocateHandle(controllerId, &classHandle);
if (kStatus_USB_Success != error)
{
return error;
}
/* Save the configuration list */
classHandle->configList = configList;
/* Initialize the device stack. */
error = USB_DeviceInit(controllerId, USB_DeviceClassCallback, &classHandle->handle);
if (kStatus_USB_Success != error)
{
(void)USB_DeviceDeinit(classHandle->handle);
(void)USB_DeviceClassFreeHandle(controllerId);
return error;
}
/* Initialize the all supported classes according to the configuration list. */
for (classIndex = 0U; classIndex < classHandle->configList->count; classIndex++)
{
for (mapIndex = 0U; mapIndex < (sizeof(s_UsbDeviceClassInterfaceMap) / sizeof(usb_device_class_map_t));
mapIndex++)
{
if (classHandle->configList->config[classIndex].classInfomation->type ==
s_UsbDeviceClassInterfaceMap[mapIndex].type)
{
(void)s_UsbDeviceClassInterfaceMap[mapIndex].classInit(
controllerId, &classHandle->configList->config[classIndex],
&classHandle->configList->config[classIndex].classHandle);
}
}
}
*handle = classHandle->handle;
return error;
}
/*!
* @brief De-initialize the common class and the supported classes.
*
* This function is used to de-initialize the common class and the supported classes.
*
* @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceClassDeinit(uint8_t controllerId /*!< [IN] Controller ID */
)
{
usb_device_common_class_struct_t *classHandle;
usb_status_t error;
uint8_t mapIndex;
uint8_t classIndex;
/* Get the common class handle according to the controller id. */
error = USB_DeviceClassGetHandleByControllerId(controllerId, &classHandle);
if (kStatus_USB_Success != error)
{
return error;
}
/* De-initialize the all supported classes according to the configuration list. */
for (classIndex = 0U; classIndex < classHandle->configList->count; classIndex++)
{
for (mapIndex = 0U; mapIndex < (sizeof(s_UsbDeviceClassInterfaceMap) / sizeof(usb_device_class_map_t));
mapIndex++)
{
if (classHandle->configList->config[classIndex].classInfomation->type ==
s_UsbDeviceClassInterfaceMap[mapIndex].type)
{
(void)s_UsbDeviceClassInterfaceMap[mapIndex].classDeinit(
classHandle->configList->config[classIndex].classHandle);
}
}
}
/* De-initialize the USB device stack. */
error = USB_DeviceDeinit(classHandle->handle);
if (kStatus_USB_Success == error)
{
/* Free the common class handle. */
(void)USB_DeviceClassFreeHandle(controllerId);
}
return error;
}
/*!
* @brief Get the USB bus speed.
*
* This function is used to get the USB bus speed.
*
* @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
* @param speed It is an OUT parameter, return current speed of the controller.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceClassGetSpeed(uint8_t controllerId, /*!< [IN] Controller ID */
uint8_t *speed /*!< [OUT] Current speed */
)
{
usb_device_common_class_struct_t *classHandle;
usb_status_t error;
/* Get the common class handle according to the controller id. */
error = USB_DeviceClassGetHandleByControllerId(controllerId, &classHandle);
if (kStatus_USB_Success != error)
{
return error;
}
/* Get the current speed. */
error = USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusSpeed, speed);
return error;
}
#if defined(USB_DEVICE_CONFIG_GET_SOF_COUNT) && (USB_DEVICE_CONFIG_GET_SOF_COUNT > 0U)
/*!
* @brief Get the USB SOF count.
*
* This function is used to get the USB SOF count.
*
* @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
* @param currentFrameCount It is an OUT parameter, return current sof count of the controller.
* HS: micro frame count, FS: frame count
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceClassGetCurrentFrameCount(uint8_t controllerId, /*!< [IN] Controller ID */
uint32_t *currentFrameCount /*!< [OUT] Current frame count */
)
{
usb_device_common_class_struct_t *classHandle;
usb_status_t error;
/* Get the common class handle according to the controller id. */
error = USB_DeviceClassGetHandleByControllerId(controllerId, &classHandle);
if (kStatus_USB_Success != error)
{
return error;
}
/* Get the current frame count. */
error = USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusGetCurrentFrameCount, currentFrameCount);
return error;
}
#endif /* USB_DEVICE_CONFIG_GET_SOF_COUNT */
#endif /* USB_DEVICE_CONFIG_NUM */

View file

@ -0,0 +1,439 @@
/*
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __USB_DEVICE_CLASS_H__
#define __USB_DEVICE_CLASS_H__
/*!
* @addtogroup usb_device_class_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief Macro to define class handle */
typedef void *class_handle_t;
/*! @brief Available class types. */
typedef enum _usb_usb_device_class_type
{
kUSB_DeviceClassTypeHid = 1U,
kUSB_DeviceClassTypeCdc,
kUSB_DeviceClassTypeMsc,
kUSB_DeviceClassTypeMtp,
kUSB_DeviceClassTypeAudio,
kUSB_DeviceClassTypePhdc,
kUSB_DeviceClassTypeVideo,
kUSB_DeviceClassTypePrinter,
kUSB_DeviceClassTypeDfu,
kUSB_DeviceClassTypeCcid,
} usb_device_class_type_t;
/*! @brief Available common class events. */
typedef enum _usb_device_class_event
{
kUSB_DeviceClassEventClassRequest = 1U,
kUSB_DeviceClassEventDeviceReset,
kUSB_DeviceClassEventSetConfiguration,
kUSB_DeviceClassEventSetInterface,
kUSB_DeviceClassEventSetEndpointHalt,
kUSB_DeviceClassEventClearEndpointHalt,
} usb_device_class_event_t;
/*!
* @brief Obtains the endpoint data structure.
*
* Define the endpoint data structure.
*
*/
typedef struct _usb_device_endpoint_struct
{
uint8_t endpointAddress; /*!< Endpoint address*/
uint8_t transferType; /*!< Endpoint transfer type*/
uint16_t maxPacketSize; /*!< Endpoint maximum packet size */
uint8_t interval; /*!< Endpoint interval*/
} usb_device_endpoint_struct_t;
/*!
* @brief Obtains the endpoint group.
*
* Structure representing endpoints and the number of endpoints that the user wants.
*
*/
typedef struct _usb_device_endpoint_list
{
uint8_t count; /*!< How many endpoints in current interface*/
usb_device_endpoint_struct_t *endpoint; /*!< Endpoint structure list*/
} usb_device_endpoint_list_t;
/*!
* @brief Obtains the interface list data structure.
*
* Structure representing an interface.
*
*/
typedef struct _usb_device_interface_struct
{
uint8_t alternateSetting; /*!< Alternate setting number*/
usb_device_endpoint_list_t endpointList; /*!< Endpoints of the interface*/
void *classSpecific; /*!< Class specific structure handle*/
} usb_device_interface_struct_t;
/*!
* @brief Obtains the interface data structure.
*
* Structure representing interface.
*
*/
typedef struct _usb_device_interfaces_struct
{
uint8_t classCode; /*!< Class code of the interface*/
uint8_t subclassCode; /*!< Subclass code of the interface*/
uint8_t protocolCode; /*!< Protocol code of the interface*/
uint8_t interfaceNumber; /*!< Interface number*/
usb_device_interface_struct_t *interface; /*!< Interface structure list*/
uint8_t count; /*!< Number of interfaces in the current interface*/
} usb_device_interfaces_struct_t;
/*!
* @brief Obtains the interface group.
*
* Structure representing how many interfaces in one class type.
*
*/
typedef struct _usb_device_interface_list
{
uint8_t count; /*!< Number of interfaces of the class*/
usb_device_interfaces_struct_t *interfaces; /*!< All interfaces*/
} usb_device_interface_list_t;
/*!
* @brief Obtains the class data structure.
*
* Structure representing how many configurations in one class type.
*
*/
typedef struct _usb_device_class_struct
{
usb_device_interface_list_t *interfaceList; /*!< Interfaces of the class*/
usb_device_class_type_t type; /*!< Class type*/
uint8_t configurations; /*!< Number of configurations of the class*/
} usb_device_class_struct_t;
/*callback function pointer structure for application to provide class parameters*/
typedef usb_status_t (*usb_device_class_callback_t)(class_handle_t classHandle,
uint32_t callbackEvent,
void *eventParam);
/*!
* @brief Obtains the device class information structure.
*
* Structure representing the device class information. This structure only can be stored in RAM space.
*
*/
typedef struct _usb_device_class_config_struct
{
usb_device_class_callback_t classCallback; /*!< Class callback function to handle the device status-related event
for the specified type of class*/
class_handle_t classHandle; /*!< The class handle of the class, filled by the common driver.*/
usb_device_class_struct_t *classInfomation; /*!< Detailed information of the class*/
} usb_device_class_config_struct_t;
/*!
* @brief Obtains the device class configuration structure.
*
* Structure representing the device class configuration information.
*
*/
typedef struct _usb_device_class_config_list_struct
{
usb_device_class_config_struct_t *config; /*!< Array of class configuration structures */
usb_device_callback_t deviceCallback; /*!< Device callback function */
uint8_t count; /*!< Number of class supported */
} usb_device_class_config_list_struct_t;
/*!
* @brief Obtains the control request structure.
*
* This structure is used to pass the control request information.
* The structure is used in following two cases.
* 1. Case one, the host wants to send data to the device in the control data stage: @n
* a. If a setup packet is received, the structure is used to pass the setup packet data and wants to get the
* buffer to receive data sent from the host.
* The field isSetup is 1.
* The length is the requested buffer length.
* The buffer is filled by the class or application by using the valid buffer address.
* The setup is the setup packet address.
* b. If the data received is sent by the host, the structure is used to pass the data buffer address and the
* data
* length sent by the host.
* In this way, the field isSetup is 0.
* The buffer is the address of the data sent from the host.
* The length is the received data length.
* The setup is the setup packet address. @n
* 2. Case two, the host wants to get data from the device in control data stage: @n
* If the setup packet is received, the structure is used to pass the setup packet data and wants to get the
* data buffer address to send data to the host.
* The field isSetup is 1.
* The length is the requested data length.
* The buffer is filled by the class or application by using the valid buffer address.
* The setup is the setup packet address.
*
*/
typedef struct _usb_device_control_request_struct
{
usb_setup_struct_t *setup; /*!< The pointer of the setup packet data. */
uint8_t *buffer; /*!< Pass the buffer address. */
uint32_t length; /*!< Pass the buffer length or requested length. */
uint8_t isSetup; /*!< Indicates whether a setup packet is received. */
} usb_device_control_request_struct_t;
/*! @brief Obtains the control get descriptor request common structure. */
typedef struct _usb_device_get_descriptor_common_struct
{
uint8_t *buffer; /*!< Pass the buffer address. */
uint32_t length; /*!< Pass the buffer length. */
} usb_device_get_descriptor_common_struct_t;
/*! @brief Obtains the control get device descriptor request structure. */
typedef struct _usb_device_get_device_descriptor_struct
{
uint8_t *buffer; /*!< Pass the buffer address. */
uint32_t length; /*!< Pass the buffer length. */
} usb_device_get_device_descriptor_struct_t;
/*! @brief Obtains the control get device qualifier descriptor request structure. */
typedef struct _usb_device_get_device_qualifier_descriptor_struct
{
uint8_t *buffer; /*!< Pass the buffer address. */
uint32_t length; /*!< Pass the buffer length. */
} usb_device_get_device_qualifier_descriptor_struct_t;
/*! @brief Obtains the control get configuration descriptor request structure. */
typedef struct _usb_device_get_configuration_descriptor_struct
{
uint8_t *buffer; /*!< Pass the buffer address. */
uint32_t length; /*!< Pass the buffer length. */
uint8_t configuration; /*!< The configuration number. */
} usb_device_get_configuration_descriptor_struct_t;
/*! @brief Obtains the control get bos descriptor request structure. */
typedef struct _usb_device_get_bos_descriptor_struct
{
uint8_t *buffer; /*!< Pass the buffer address. */
uint32_t length; /*!< Pass the buffer length. */
} usb_device_get_bos_descriptor_struct_t;
/*! @brief Obtains the control get string descriptor request structure. */
typedef struct _usb_device_get_string_descriptor_struct
{
uint8_t *buffer; /*!< Pass the buffer address. */
uint32_t length; /*!< Pass the buffer length. */
uint16_t languageId; /*!< Language ID. */
uint8_t stringIndex; /*!< String index. */
} usb_device_get_string_descriptor_struct_t;
/*! @brief Obtains the control get HID descriptor request structure. */
typedef struct _usb_device_get_hid_descriptor_struct
{
uint8_t *buffer; /*!< Pass the buffer address. */
uint32_t length; /*!< Pass the buffer length. */
uint8_t interfaceNumber; /*!< The interface number. */
} usb_device_get_hid_descriptor_struct_t;
/*! @brief Obtains the control get HID report descriptor request structure. */
typedef struct _usb_device_get_hid_report_descriptor_struct
{
uint8_t *buffer; /*!< Pass the buffer address. */
uint32_t length; /*!< Pass the buffer length. */
uint8_t interfaceNumber; /*!< The interface number. */
} usb_device_get_hid_report_descriptor_struct_t;
/*! @brief Obtains the control get HID physical descriptor request structure. */
typedef struct _usb_device_get_hid_physical_descriptor_struct
{
uint8_t *buffer; /*!< Pass the buffer address. */
uint32_t length; /*!< Pass the buffer length. */
uint8_t index; /*!< Physical index */
uint8_t interfaceNumber; /*!< The interface number. */
} usb_device_get_hid_physical_descriptor_struct_t;
/*! @brief Obtains the control get descriptor request common union. */
typedef union _usb_device_get_descriptor_common_union
{
usb_device_get_descriptor_common_struct_t commonDescriptor; /*!< Common structure. */
usb_device_get_device_descriptor_struct_t deviceDescriptor; /*!< The structure to get device descriptor. */
usb_device_get_device_qualifier_descriptor_struct_t
deviceQualifierDescriptor; /*!< The structure to get device qualifier descriptor. */
usb_device_get_configuration_descriptor_struct_t
configurationDescriptor; /*!< The structure to get configuration descriptor. */
usb_device_get_string_descriptor_struct_t stringDescriptor; /*!< The structure to get string descriptor. */
usb_device_get_hid_descriptor_struct_t hidDescriptor; /*!< The structure to get HID descriptor. */
usb_device_get_hid_report_descriptor_struct_t
hidReportDescriptor; /*!< The structure to get HID report descriptor. */
usb_device_get_hid_physical_descriptor_struct_t
hidPhysicalDescriptor; /*!< The structure to get HID physical descriptor. */
} usb_device_get_descriptor_common_union_t;
/*! @brief Define function type for class device instance initialization */
typedef usb_status_t (*usb_device_class_init_call_t)(uint8_t controllerId,
usb_device_class_config_struct_t *classConfig,
class_handle_t *classHandle);
/*! @brief Define function type for class device instance deinitialization, internal */
typedef usb_status_t (*usb_device_class_deinit_call_t)(class_handle_t handle);
/*! @brief Define function type for class device instance Event change */
typedef usb_status_t (*usb_device_class_event_callback_t)(void *classHandle, uint32_t event, void *param);
/*! @brief Define class driver interface structure. */
typedef struct _usb_device_class_map
{
usb_device_class_init_call_t classInit; /*!< Class driver initialization- entry of the class driver */
usb_device_class_deinit_call_t classDeinit; /*!< Class driver de-initialization*/
usb_device_class_event_callback_t classEventCallback; /*!< Class driver event callback*/
usb_device_class_type_t type; /*!< Class type*/
} usb_device_class_map_t;
/*! @brief Structure holding common class state information */
typedef struct _usb_device_common_class_struct
{
usb_device_handle handle; /*!< USB device handle*/
usb_device_class_config_list_struct_t *configList; /*!< USB device configure list*/
uint8_t *setupBuffer; /*!< Setup packet data buffer*/
uint16_t standardTranscationBuffer; /*!<
* This variable is used in:
* get status request
* get configuration request
* get interface request
* set interface request
* get sync frame request
*/
uint8_t controllerId; /*!< Controller ID*/
} usb_device_common_class_struct_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @brief Initializes the common class and the supported classes.
*
* This function is used to initialize the common class and the supported classes.
*
* @param[in] controllerId The controller ID of the USB IP. See the enumeration #usb_controller_index_t.
* @param[in] configList The class configurations. The pointer must point to the global variable.
* See the structure #usb_device_class_config_list_struct_t.
* @param[out] handle A parameter used to return pointer of the device handle to the caller.
* The value of the parameter is a pointer to the device handle. This design is used to
* make a simple device align with the composite device. For the composite device, there are
* many
* kinds of class handles. However, there is only one device handle. Therefore, the handle
* points to
* a device instead of a class. The class handle can be received from the
* #usb_device_class_config_struct_t::classHandle after the function successfully.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceClassInit(uint8_t controllerId,
usb_device_class_config_list_struct_t *configList,
usb_device_handle *handle);
/*!
* @brief Deinitializes the common class and the supported classes.
*
* This function is used to deinitialize the common class and the supported classes.
*
* @param[in] controllerId The controller ID of the USB IP. See the enumeration #usb_controller_index_t.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceClassDeinit(uint8_t controllerId);
/*!
* @brief Gets the USB bus speed.
*
* This function is used to get the USB bus speed.
*
* @param[in] controllerId The controller ID of the USB IP. See the enumeration #usb_controller_index_t.
* @param[out] speed It is an OUT parameter, which returns the current speed of the controller.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceClassGetSpeed(uint8_t controllerId, uint8_t *speed);
/*!
* @brief Handles the event passed to the class drivers.
*
* This function handles the event passed to the class drivers.
*
* @param[in] handle The device handle received from the #USB_DeviceInit.
* @param[in] event The event codes. See the enumeration #usb_device_class_event_t.
* @param[in,out] param The parameter type is determined by the event code.
*
* @return A USB error code or kStatus_USB_Success.
* @retval kStatus_USB_Success A valid request has been handled.
* @retval kStatus_USB_InvalidParameter The device handle not be found.
* @retval kStatus_USB_InvalidRequest The request is invalid, and the control pipe is stalled by the caller.
*/
usb_status_t USB_DeviceClassEvent(usb_device_handle handle, usb_device_class_event_t event, void *param);
/*!
* @brief Handles the common class callback.
*
* This function handles the common class callback.
*
* @param[in] handle The device handle received from the #USB_DeviceInit.
* @param[in] event The event codes. See the enumeration #usb_device_event_t.
* @param[in,out] param The parameter type is determined by the event code.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceClassCallback(usb_device_handle handle, uint32_t event, void *param);
/*!
* @brief Gets the device handle according to the controller ID.
*
* This function gets the device handle according to the controller ID.
*
* @param[in] controllerId The controller ID of the USB IP. See the enumeration #usb_controller_index_t.
* @param[out] handle An out parameter used to return the pointer of the device handle to the caller.
*
* @retval kStatus_USB_Success Get device handle successfully.
* @retval kStatus_USB_InvalidParameter The device handle can't be found.
*/
usb_status_t USB_DeviceClassGetDeviceHandle(uint8_t controllerId, usb_device_handle *handle);
#if defined(USB_DEVICE_CONFIG_GET_SOF_COUNT) && (USB_DEVICE_CONFIG_GET_SOF_COUNT > 0U)
/*!
* @brief Get the USB SOF count.
*
* This function is used to get the USB SOF count.
*
* @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
* @param currentFrameCount It is an OUT parameter, return current sof count of the controller.
* HS: micro frame count, FS: frame count
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceClassGetCurrentFrameCount(uint8_t controllerId, /*!< [IN] Controller ID */
uint32_t *currentFrameCount /*!< [OUT] Current frame count */
);
#endif
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* __USB_DEVICE_CLASS_H__ */

View file

@ -0,0 +1,660 @@
/*
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __USB_DEVICE_H__
#define __USB_DEVICE_H__
#include "usb.h"
/*!
* @addtogroup usb_device_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief Defines Get/Set status Types */
typedef enum _usb_device_status
{
kUSB_DeviceStatusTestMode = 1U, /*!< Test mode */
kUSB_DeviceStatusSpeed, /*!< Current speed */
kUSB_DeviceStatusOtg, /*!< OTG status */
kUSB_DeviceStatusDevice, /*!< Device status */
kUSB_DeviceStatusEndpoint, /*!< Endpoint state usb_device_endpoint_status_t */
kUSB_DeviceStatusDeviceState, /*!< Device state */
kUSB_DeviceStatusAddress, /*!< Device address */
kUSB_DeviceStatusSynchFrame, /*!< Current frame */
kUSB_DeviceStatusBus, /*!< Bus status */
kUSB_DeviceStatusBusSuspend, /*!< Bus suspend */
kUSB_DeviceStatusBusSleep, /*!< Bus suspend */
kUSB_DeviceStatusBusResume, /*!< Bus resume */
kUSB_DeviceStatusRemoteWakeup, /*!< Remote wakeup state */
kUSB_DeviceStatusBusSleepResume, /*!< Bus resume */
#if defined(USB_DEVICE_CONFIG_GET_SOF_COUNT) && (USB_DEVICE_CONFIG_GET_SOF_COUNT > 0U)
kUSB_DeviceStatusGetCurrentFrameCount, /*!< Get current frame count */
#endif
} usb_device_status_t;
/*! @brief Defines USB 2.0 device state */
typedef enum _usb_device_state
{
kUSB_DeviceStateConfigured = 0U, /*!< Device state, Configured*/
kUSB_DeviceStateAddress, /*!< Device state, Address*/
kUSB_DeviceStateDefault, /*!< Device state, Default*/
kUSB_DeviceStateAddressing, /*!< Device state, Address setting*/
kUSB_DeviceStateTestMode, /*!< Device state, Test mode*/
} usb_device_state_t;
/*! @brief Defines endpoint state */
typedef enum _usb_endpoint_status
{
kUSB_DeviceEndpointStateIdle = 0U, /*!< Endpoint state, idle*/
kUSB_DeviceEndpointStateStalled, /*!< Endpoint state, stalled*/
} usb_device_endpoint_status_t;
/*! @brief Control endpoint index */
#define USB_CONTROL_ENDPOINT (0U)
/*! @brief Control endpoint maxPacketSize */
#define USB_CONTROL_MAX_PACKET_SIZE (64U)
#if (USB_DEVICE_CONFIG_EHCI && (USB_CONTROL_MAX_PACKET_SIZE != (64U)))
#error For high speed, USB_CONTROL_MAX_PACKET_SIZE must be 64!!!
#endif
/*! @brief The setup packet size of USB control transfer. */
#define USB_SETUP_PACKET_SIZE (8U)
/*! @brief USB endpoint mask */
#define USB_ENDPOINT_NUMBER_MASK (0x0FU)
/*! @brief uninitialized value */
#define USB_UNINITIALIZED_VAL_32 (0xFFFFFFFFU)
/*! @brief the endpoint callback length of cancelled transfer */
#define USB_CANCELLED_TRANSFER_LENGTH (0xFFFFFFFFU)
/*! @brief invalid tranfer buffer addresss */
#define USB_INVALID_TRANSFER_BUFFER (0xFFFFFFFEU)
#if defined(USB_DEVICE_CONFIG_GET_SOF_COUNT) && (USB_DEVICE_CONFIG_GET_SOF_COUNT > 0U)
/* USB device IP3511 max frame count */
#define USB_DEVICE_IP3511_MAX_FRAME_COUNT (0x000007FFU)
/* USB device EHCI max frame count */
#define USB_DEVICE_EHCI_MAX_FRAME_COUNT (0x00003FFFU)
/* USB device EHCI max frame count */
#define USB_DEVICE_KHCI_MAX_FRAME_COUNT (0x000007FFU)
/*! @brief usb device controller max frame count */
#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U))
#define USB_DEVICE_MAX_FRAME_COUNT (USB_DEVICE_KHCI_MAX_FRAME_COUNT)
#elif (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \
((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)))
#define USB_DEVICE_MAX_FRAME_COUNT (USB_DEVICE_IP3511_MAX_FRAME_COUNT)
#elif ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U))
#define USB_DEVICE_MAX_FRAME_COUNT (USB_DEVICE_EHCI_MAX_FRAME_COUNT)
#endif
#endif
/*! @brief Available common EVENT types in device callback */
typedef enum _usb_device_event
{
kUSB_DeviceEventBusReset = 1U, /*!< USB bus reset signal detected */
kUSB_DeviceEventSuspend, /*!< USB bus suspend signal detected */
kUSB_DeviceEventResume, /*!< USB bus resume signal detected. The resume signal is driven by itself or a host */
kUSB_DeviceEventSleeped, /*!< USB bus LPM suspend signal detected */
kUSB_DeviceEventLPMResume, /*!< USB bus LPM resume signal detected. The resume signal is driven by itself or a host
*/
kUSB_DeviceEventError, /*!< An error is happened in the bus. */
kUSB_DeviceEventDetach, /*!< USB device is disconnected from a host. */
kUSB_DeviceEventAttach, /*!< USB device is connected to a host. */
kUSB_DeviceEventSetConfiguration, /*!< Set configuration. */
kUSB_DeviceEventSetInterface, /*!< Set interface. */
kUSB_DeviceEventGetDeviceDescriptor, /*!< Get device descriptor. */
kUSB_DeviceEventGetConfigurationDescriptor, /*!< Get configuration descriptor. */
kUSB_DeviceEventGetStringDescriptor, /*!< Get string descriptor. */
kUSB_DeviceEventGetHidDescriptor, /*!< Get HID descriptor. */
kUSB_DeviceEventGetHidReportDescriptor, /*!< Get HID report descriptor. */
kUSB_DeviceEventGetHidPhysicalDescriptor, /*!< Get HID physical descriptor. */
kUSB_DeviceEventGetBOSDescriptor, /*!< Get configuration descriptor. */
kUSB_DeviceEventGetDeviceQualifierDescriptor, /*!< Get device qualifier descriptor. */
kUSB_DeviceEventVendorRequest, /*!< Vendor request. */
kUSB_DeviceEventSetRemoteWakeup, /*!< Enable or disable remote wakeup function. */
kUSB_DeviceEventGetConfiguration, /*!< Get current configuration index */
kUSB_DeviceEventGetInterface, /*!< Get current interface alternate setting value */
kUSB_DeviceEventSetBHNPEnable,
#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U))
kUSB_DeviceEventDcdDetectionfinished, /*!< The DCD detection finished */
#endif
} usb_device_event_t;
/*! @brief Endpoint callback message structure */
typedef struct _usb_device_endpoint_callback_message_struct
{
uint8_t *buffer; /*!< Transferred buffer */
uint32_t length; /*!< Transferred data length */
uint8_t isSetup; /*!< Is in a setup phase */
} usb_device_endpoint_callback_message_struct_t;
/*!
* @brief Endpoint callback function typedef.
*
* This callback function is used to notify the upper layer what the transfer result is.
* This callback pointer is passed when a specified endpoint is initialized by calling API #USB_DeviceInitEndpoint.
*
* @param handle The device handle. It equals to the value returned from #USB_DeviceInit.
* @param message The result of a transfer, which includes transfer buffer, transfer length, and whether is in a
* setup phase.
* phase for control pipe.
* @param callbackParam The parameter for this callback. It is same with
* usb_device_endpoint_callback_struct_t::callbackParam.
*
* @return A USB error code or kStatus_USB_Success.
*/
typedef usb_status_t (*usb_device_endpoint_callback_t)(usb_device_handle handle,
usb_device_endpoint_callback_message_struct_t *message,
void *callbackParam);
/*!
* @brief Device callback function typedef.
*
* This callback function is used to notify the upper layer that the device status has changed.
* This callback pointer is passed by calling API #USB_DeviceInit.
*
* @param handle The device handle. It equals the value returned from #USB_DeviceInit.
* @param callbackEvent The callback event type. See enumeration #usb_device_event_t.
* @param eventParam The event parameter for this callback. The parameter type is determined by the callback event.
*
* @return A USB error code or kStatus_USB_Success.
*/
typedef usb_status_t (*usb_device_callback_t)(usb_device_handle handle, uint32_t callbackEvent, void *eventParam);
/*! @brief Endpoint callback structure */
typedef struct _usb_device_endpoint_callback_struct
{
usb_device_endpoint_callback_t callbackFn; /*!< Endpoint callback function*/
void *callbackParam; /*!< Parameter for callback function*/
uint8_t isBusy;
} usb_device_endpoint_callback_struct_t;
/*! @brief Endpoint initialization structure */
typedef struct _usb_device_endpoint_init_struct
{
uint16_t maxPacketSize; /*!< Endpoint maximum packet size */
uint8_t endpointAddress; /*!< Endpoint address*/
uint8_t transferType; /*!< Endpoint transfer type*/
uint8_t zlt; /*!< ZLT flag*/
uint8_t interval; /*!< Endpoint interval*/
} usb_device_endpoint_init_struct_t;
/*! @brief Endpoint status structure */
typedef struct _usb_device_endpoint_status_struct
{
uint8_t endpointAddress; /*!< Endpoint address */
uint16_t endpointStatus; /*!< Endpoint status : idle or stalled */
} usb_device_endpoint_status_struct_t;
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus*/
/*!
* @name USB device APIs
* @{
*/
/*******************************************************************************
* API
******************************************************************************/
/*!
* @brief Initializes the USB device stack.
*
* This function initializes the USB device module specified by the controllerId.
*
* @param[in] controllerId The controller ID of the USB IP. See the enumeration #usb_controller_index_t.
* @param[in] deviceCallback Function pointer of the device callback.
* @param[out] handle It is an out parameter used to return the pointer of the device handle to the caller.
*
* @retval kStatus_USB_Success The device is initialized successfully.
* @retval kStatus_USB_InvalidHandle The handle is a NULL pointer.
* @retval kStatus_USB_Busy Cannot allocate a device handle.
* @retval kStatus_USB_ControllerNotFound Cannot find the controller according to the controller id.
* @retval kStatus_USB_InvalidControllerInterface The controller driver interfaces is invalid. There is an empty
* interface entity.
* @retval kStatus_USB_Error The macro USB_DEVICE_CONFIG_ENDPOINTS is more than the IP's endpoint number.
* Or, the device has been initialized.
* Or, the mutex or message queue is created failed.
*/
extern usb_status_t USB_DeviceInit(uint8_t controllerId,
usb_device_callback_t deviceCallback,
usb_device_handle *handle);
/*!
* @brief Enables the device functionality.
*
* The function enables the device functionality, so that the device can be recognized by the host when the device
* detects that it has been connected to a host.
*
* @param[in] handle The device handle got from #USB_DeviceInit.
*
* @retval kStatus_USB_Success The device is run successfully.
* @retval kStatus_USB_ControllerNotFound Cannot find the controller.
* @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid.
*
*/
extern usb_status_t USB_DeviceRun(usb_device_handle handle);
/*!
* @brief Disables the device functionality.
*
* The function disables the device functionality. After this function called, even if the device is detached to the
* host,
* it can't work.
*
* @param[in] handle The device handle received from #USB_DeviceInit.
*
* @retval kStatus_USB_Success The device is stopped successfully.
* @retval kStatus_USB_ControllerNotFound Cannot find the controller.
* @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer or the controller handle is invalid.
*/
extern usb_status_t USB_DeviceStop(usb_device_handle handle);
/*!
* @brief De-initializes the device controller.
*
* The function de-initializes the device controller specified by the handle.
*
* @param[in] handle The device handle got from #USB_DeviceInit.
*
* @retval kStatus_USB_Success The device is stopped successfully.
* @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer or the controller handle is invalid.
*/
extern usb_status_t USB_DeviceDeinit(usb_device_handle handle);
/*!
* @brief Sends data through a specified endpoint.
*
* The function is used to send data through a specified endpoint.
*
* @param[in] handle The device handle got from #USB_DeviceInit.
* @param[in] endpointAddress Endpoint index.
* @param[in] buffer The memory address to hold the data need to be sent. The function is not reentrant.
* @param[in] length The data length need to be sent.
*
* @retval kStatus_USB_Success The send request is sent successfully.
* @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
* @retval kStatus_USB_Busy Cannot allocate DTDS for current transfer in EHCI driver.
* @retval kStatus_USB_ControllerNotFound Cannot find the controller.
* @retval kStatus_USB_Error The device is doing reset.
*
* @note The return value indicates whether the sending request is successful or not. The transfer done is notified by
* the
* corresponding callback function.
* Currently, only one transfer request can be supported for one specific endpoint.
* If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application
* should implement a queue on the application level.
* The subsequent transfer can begin only when the previous transfer is done (get notification through the endpoint
* callback).
*/
extern usb_status_t USB_DeviceSendRequest(usb_device_handle handle,
uint8_t endpointAddress,
uint8_t *buffer,
uint32_t length);
/*!
* @brief Receives data through a specified endpoint.
*
* The function is used to receive data through a specified endpoint. The function is not reentrant.
*
* @param[in] handle The device handle got from #USB_DeviceInit.
* @param[in] endpointAddress Endpoint index.
* @param[in] buffer The memory address to save the received data.
* @param[in] length The data length want to be received.
*
* @retval kStatus_USB_Success The receive request is sent successfully.
* @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
* @retval kStatus_USB_Busy Cannot allocate DTDS for current transfer in EHCI driver.
* @retval kStatus_USB_ControllerNotFound Cannot find the controller.
* @retval kStatus_USB_Error The device is doing reset.
*
* @note The return value indicates whether the receiving request is successful or not. The transfer done is notified by
* the
* corresponding callback function.
* Currently, only one transfer request can be supported for one specific endpoint.
* If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application
* should implement a queue on the application level.
* The subsequent transfer can begin only when the previous transfer is done (get notification through the endpoint
* callback).
*/
extern usb_status_t USB_DeviceRecvRequest(usb_device_handle handle,
uint8_t endpointAddress,
uint8_t *buffer,
uint32_t length);
/*!
* @brief Cancels the pending transfer in a specified endpoint.
*
* The function is used to cancel the pending transfer in a specified endpoint.
*
* @param[in] handle The device handle got from #USB_DeviceInit.
* @param[in] endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, and 0U - OUT.
*
* @retval kStatus_USB_Success The transfer is cancelled.
* @retval kStatus_USB_InvalidHandle The handle is a NULL pointer or the controller handle is invalid.
* @retval kStatus_USB_ControllerNotFound Cannot find the controller.
*/
extern usb_status_t USB_DeviceCancel(usb_device_handle handle, uint8_t endpointAddress);
/*!
* @brief Initializes a specified endpoint.
*
* The function is used to initialize a specified endpoint. The corresponding endpoint callback is also initialized.
*
* @param[in] handle The device handle received from #USB_DeviceInit.
* @param[in] epInit Endpoint initialization structure. See the structure usb_device_endpoint_init_struct_t.
* @param[in] epCallback Endpoint callback structure. See the structure
* usb_device_endpoint_callback_struct_t.
*
* @retval kStatus_USB_Success The endpoint is initialized successfully.
* @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
* @retval kStatus_USB_InvalidParameter The epInit or epCallback is NULL pointer. Or the endpoint number is
* more than USB_DEVICE_CONFIG_ENDPOINTS.
* @retval kStatus_USB_Busy The endpoint is busy in EHCI driver.
* @retval kStatus_USB_ControllerNotFound Cannot find the controller.
*/
extern usb_status_t USB_DeviceInitEndpoint(usb_device_handle handle,
usb_device_endpoint_init_struct_t *epInit,
usb_device_endpoint_callback_struct_t *epCallback);
/*!
* @brief Deinitializes a specified endpoint.
*
* The function is used to deinitializes a specified endpoint.
*
* @param[in] handle The device handle got from #USB_DeviceInit.
* @param[in] endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, and 0U - OUT.
*
* @retval kStatus_USB_Success The endpoint is de-initialized successfully.
* @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
* @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS.
* @retval kStatus_USB_Busy The endpoint is busy in EHCI driver.
* @retval kStatus_USB_ControllerNotFound Cannot find the controller.
*/
extern usb_status_t USB_DeviceDeinitEndpoint(usb_device_handle handle, uint8_t endpointAddress);
/*!
* @brief Stalls a specified endpoint.
*
* The function is used to stall a specified endpoint.
*
* @param[in] handle The device handle received from #USB_DeviceInit.
* @param[in] endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, and 0U - OUT.
*
* @retval kStatus_USB_Success The endpoint is stalled successfully.
* @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
* @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS.
* @retval kStatus_USB_ControllerNotFound Cannot find the controller.
*/
extern usb_status_t USB_DeviceStallEndpoint(usb_device_handle handle, uint8_t endpointAddress);
/*!
* @brief Un-stall a specified endpoint.
*
* The function is used to unstall a specified endpoint.
*
* @param[in] handle The device handle received from #USB_DeviceInit.
* @param[in] endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, and 0U - OUT.
*
* @retval kStatus_USB_Success The endpoint is un-stalled successfully.
* @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
* @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS.
* @retval kStatus_USB_ControllerNotFound Cannot find the controller.
*/
extern usb_status_t USB_DeviceUnstallEndpoint(usb_device_handle handle, uint8_t endpointAddress);
/*!
* @brief Gets the status of the selected item.
*
* The function is used to get the status of the selected item.
*
* @param[in] handle The device handle got from #USB_DeviceInit.
* @param[in] type The selected item. See the structure #usb_device_status_t.
* @param[out] param The parameter type is determined by the selected item.
*
* @retval kStatus_USB_Success Get status successfully.
* @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
* @retval kStatus_USB_InvalidParameter The parameter is NULL pointer.
* @retval kStatus_USB_ControllerNotFound Cannot find the controller.
* @retval kStatus_USB_Error Unsupported type.
*/
extern usb_status_t USB_DeviceGetStatus(usb_device_handle handle, usb_device_status_t type, void *param);
/*!
* @brief Sets the status of the selected item.
*
* The function is used to set the status of the selected item.
*
* @param[in] handle The device handle got from #USB_DeviceInit.
* @param[in] type The selected item. See the structure #usb_device_status_t.
* @param[in] param The parameter type is determined by the selected item.
*
* @retval kStatus_USB_Success Set status successfully.
* @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
* @retval kStatus_USB_ControllerNotFound Cannot find the controller.
* @retval kStatus_USB_Error Unsupported type or the parameter is NULL pointer.
*/
extern usb_status_t USB_DeviceSetStatus(usb_device_handle handle, usb_device_status_t type, void *param);
#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U))
/*!
* @brief Enable the device dcd module.
*
* The function enable the device dcd module.
*
* @param[in] handle The device handle got from #USB_DeviceInit.
*
* @retval kStatus_USB_Success The device could run.
* @retval kStatus_USB_ControllerNotFound Cannot find the controller.
* @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid.
*
*/
extern usb_status_t USB_DeviceDcdEnable(usb_device_handle handle);
/*!
* @brief Disable the device dcd module.
*
* The function disable the device dcd module.
*
* @param[in] handle The device handle got from #USB_DeviceInit.
*
* @retval kStatus_USB_Success The dcd is reset and stopped.
* @retval kStatus_USB_ControllerNotFound Cannot find the controller.
* @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer or the controller handle is invalid.
*
*/
extern usb_status_t USB_DeviceDcdDisable(usb_device_handle handle);
#endif
#if ((defined(USB_DEVICE_CONFIG_USE_TASK)) && (USB_DEVICE_CONFIG_USE_TASK > 0U))
/*!
* @brief Device task function.
*
* The function is used to handle the controller message.
* This function should not be called in the application directly.
*
* @param[in] deviceHandle The device handle got from #USB_DeviceInit.
*/
extern void USB_DeviceTaskFunction(void *deviceHandle);
#endif
#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U))
#if ((defined(USB_DEVICE_CONFIG_USE_TASK)) && (USB_DEVICE_CONFIG_USE_TASK > 0U))
/*!
* @brief Device KHCI task function.
*
* The function is used to handle the KHCI controller message.
* In the bare metal environment, this function should be called periodically in the main function.
* In the RTOS environment, this function should be used as a function entry to create a task.
*
* @param[in] deviceHandle The device handle got from #USB_DeviceInit.
*/
#define USB_DeviceKhciTaskFunction(deviceHandle) USB_DeviceTaskFunction(deviceHandle)
#endif
#endif
#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U))
#if ((defined(USB_DEVICE_CONFIG_USE_TASK)) && (USB_DEVICE_CONFIG_USE_TASK > 0U))
/*!
* @brief Device EHCI task function.
*
* The function is used to handle the EHCI controller message.
* In the bare metal environment, this function should be called periodically in the main function.
* In the RTOS environment, this function should be used as a function entry to create a task.
*
* @param[in] deviceHandle The device handle got from #USB_DeviceInit.
*/
#define USB_DeviceEhciTaskFunction(deviceHandle) USB_DeviceTaskFunction(deviceHandle)
#endif
#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U))
#if (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))
/*!
* @brief Device ehci DCD ISR function.
*
* The function is the ehci DCD interrupt service routine.
*
* @param[in] deviceHandle The device handle got from #USB_DeviceInit.
*/
extern void USB_DeviceEhciIsrHSDCDFunction(void *deviceHandle);
#endif
#endif
#endif
#if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \
((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)))
#if ((defined(USB_DEVICE_CONFIG_USE_TASK)) && (USB_DEVICE_CONFIG_USE_TASK > 0U))
/*!
* @brief Device LPC ip3511 controller task function.
*
* The function is used to handle the LPC ip3511 controller message.
* In the bare metal environment, this function should be called periodically in the main function.
* In the RTOS environment, this function should be used as a function entry to create a task.
*
* @param[in] deviceHandle The device handle got from #USB_DeviceInit.
*/
#define USB_DeviceLpcIp3511TaskFunction(deviceHandle) USB_DeviceTaskFunction(deviceHandle)
#endif
#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U))
#if (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))
/*!
* @brief Device IP3511 DCD ISR function.
*
* The function is the IP3511 DCD interrupt service routine.
*
* @param[in] deviceHandle The device handle got from #USB_DeviceInit.
*/
extern void USB_DeviceLpcIp3511IsrDCDFunction(void *deviceHandle);
#endif
#endif
#endif
#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U))
/*!
* @brief Device KHCI ISR function.
*
* The function is the KHCI interrupt service routine.
*
* @param[in] deviceHandle The device handle got from #USB_DeviceInit.
*/
extern void USB_DeviceKhciIsrFunction(void *deviceHandle);
#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U))
#if (defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U))
#if 0U /* it is not implemented yet */
/*!
* @brief Device KHCI DCD ISR function.
*
* The function is the KHCI DCD interrupt service routine.
*
* @param[in] deviceHandle The device handle got from #USB_DeviceInit.
*/
extern void USB_DeviceDcdIsrFunction(void *deviceHandle);
#endif
#endif
#endif
#endif
#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U))
/*!
* @brief Device EHCI ISR function.
*
* The function is the EHCI interrupt service routine.
*
* @param[in] deviceHandle The device handle got from #USB_DeviceInit.
*/
extern void USB_DeviceEhciIsrFunction(void *deviceHandle);
#endif
#if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \
((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)))
/*!
* @brief Device LPC USB ISR function.
*
* The function is the LPC USB interrupt service routine.
*
* @param[in] deviceHandle The device handle got from #USB_DeviceInit.
*/
extern void USB_DeviceLpcIp3511IsrFunction(void *deviceHandle);
#endif
#if (((defined(USB_DEVICE_CONFIG_DWC3)) && (USB_DEVICE_CONFIG_DWC3 > 0U)) || \
((defined(USB_DEVICE_CONFIG_DWC3)) && (USB_DEVICE_CONFIG_DWC3 > 0U)))
/*!
* @brief Device USB DWC3 ISR function.
*
* The function is the USB interrupt service routine.
*
* @param[in] deviceHandle The device handle got from #USB_DeviceInit.
*/
extern void USB_DeviceDwc3IsrFunction(void *deviceHandle);
#endif
/*!
* @brief Gets the device stack version function.
*
* The function is used to get the device stack version.
*
* @param[out] version The version structure pointer to keep the device stack version.
*
*/
extern void USB_DeviceGetVersion(uint32_t *version);
#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) || \
(((defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \
(defined(FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U))))
/*!
* @brief Update the hardware tick.
*
* The function is used to update the hardware tick.
*
* @param[in] handle The device handle got from #USB_DeviceInit.
* @param[in] tick Current hardware tick(uint is ms).
*
*/
extern usb_status_t USB_DeviceUpdateHwTick(usb_device_handle handle, uint64_t tick);
#endif
/*! @}*/
#if defined(__cplusplus)
}
#endif /* __cplusplus*/
/*! @}*/
#endif /* __USB_DEVICE_H__ */

View file

@ -0,0 +1,318 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __USB_DEVICE_LPC3511IP_H__
#define __USB_DEVICE_LPC3511IP_H__
#include "fsl_device_registers.h"
/*!
* @addtogroup usb_device_controller_lpcip3511_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/* For bulk out endpoint in high speed mode, use long length data transfer to decrease the Ping packet count to increase
* bulk bandwidth */
/* The bigger this macro's value is, the higher bandwidth bulk out endpoint has. However, you need to set a reasonable
* value for this macro based on RAM size of Soc. If this macro's value is too big, link may be failed. */
/* Note that please set this value as integral multiple of 512U. When using USB RAM, you also can decrease the
* USB_DEVICE_IP3511_USB_RAM_IN_USE_SIZE within a reasonable range to use more USB RAM */
#if (((defined(USB_DEVICE_CONFIG_MSC)) && (USB_DEVICE_CONFIG_MSC > 0U)) && \
((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)))
#define USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX (0U)
#endif
/* During enumeration for high speed, IP3511HS responds NYET to the host(HUAWEI smartphone P20, Kirin 970 platform) for
OUT transaction in the status stage of control transfer. \ The host can not handle NYET respond in this case. Then
this leads to enumeration failure. This workaround is used to fix this issue, which force the prime length is 65
bytes. This workaround is disabled by default */
#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))
#define USB_DEVICE_IP3511HS_CONTROL_OUT_NYET_WORKAROUND (0U)
#endif
/*! @brief Prime all the double endpoint buffer at the same time, if the transfer length is larger than max packet size.
*/
#define USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE (1U)
#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))
#define USB_LPC3511IP_Type USBHSD_Type
#define USB_DEVICE_IP3511_ENDPOINTS_NUM FSL_FEATURE_USBHSD_EP_NUM
#define USB_DEVICE_IP3511_USB_RAM_SIZE FSL_FEATURE_USBHSD_USB_RAM
#else
#define USB_LPC3511IP_Type USB_Type
#define USB_DEVICE_IP3511_ENDPOINTS_NUM FSL_FEATURE_USB_EP_NUM
#if ((defined(FSL_FEATURE_USB_USB_RAM)) && (FSL_FEATURE_USB_USB_RAM > 0U))
#define USB_DEVICE_IP3511_USB_RAM_SIZE FSL_FEATURE_USB_USB_RAM
#endif
#endif
/*! @brief Use the macro to represent the USB RAM that has been used. The remaining USB RAM will be used by the
controller driver. If application needs to allocate variables into the USB RAM, please increase the macro or link
may fail. Likewise, if requiring to assign more USB RAM to the controller driver, please decrease the macro.
When USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX is used, USB_DEVICE_IP3511_USB_RAM_IN_USE_SIZE can be
decreased within a reasonable range to use more USB RAM. */
#define USB_DEVICE_IP3511_USB_RAM_IN_USE_SIZE (3U * 1024U)
/*! @brief The reserved buffer size, the buffer is for the memory copy if the application transfer buffer is
((not 64 bytes alignment) || (not in the USB RAM) || (HS && OUT && not multiple of the maximum packet size)) */
#if ((defined(USB_DEVICE_IP3511_USB_RAM_SIZE)) && (USB_DEVICE_IP3511_USB_RAM_SIZE > 0U))
#define USB_DEVICE_IP3511_ENDPOINT_RESERVED_BUFFER_SIZE \
((uint32_t)USB_DEVICE_IP3511_USB_RAM_SIZE - USB_DEVICE_IP3511_USB_RAM_IN_USE_SIZE)
#else
#if ((defined(USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX)) && \
(USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX > 0U))
/* if use USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX (>0U), need to increase the reserved buffer size */
#define USB_DEVICE_IP3511_ENDPOINT_RESERVED_BUFFER_SIZE \
((5U * 1024U) + (USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX / 512U) * 512U)
#else
#define USB_DEVICE_IP3511_ENDPOINT_RESERVED_BUFFER_SIZE (5U * 1024U)
#endif
#endif
/*! @brief Use one bit to represent one reserved 64 bytes to allocate the buffer by uint of 64 bytes. */
#define USB_DEVICE_IP3511_BITS_FOR_RESERVED_BUFFER ((USB_DEVICE_IP3511_ENDPOINT_RESERVED_BUFFER_SIZE + 63U) / 64U)
/*! @brief How many IPs support the reserved buffer */
#define USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY (USB_DEVICE_CONFIG_LPCIP3511FS + USB_DEVICE_CONFIG_LPCIP3511HS)
/* for out endpoint,only use buffer toggle, disable prime double buffer at the same time*/
/*host send data less than maxpacket size and in endpoint prime length more more than maxpacketsize, there will be state
* mismtach*/
#if USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE
#define USB_DEVICE_IP3511_DISABLE_OUT_DOUBLE_BUFFER (1U)
#else
#define USB_DEVICE_IP3511_DISABLE_OUT_DOUBLE_BUFFER (0U)
#endif
#define USB_DEVICE_IP3511HS_LPM_ADPPROBE_ATTACH_DEBOUNCE_COUNT (3)
/* if FSL_FEATURE_USBHSD_HAS_EXIT_HS_ISSUE is true:
* Enable this macro to exit HS mode automatically if the user case is:
* host and device keep cable connected, and host turn off vbus to simulate detachment.
* If user disconnects the cable, there is no issue and don't need enable this macro.
* There is one delay in the isr if enable this macro.
*/
#define USB_DEVICE_IP3511HS_FORCE_EXIT_HS_MODE_ENABLE (0u)
/*! @brief Endpoint state structure */
typedef struct _usb_device_lpc3511ip_endpoint_state_struct
{
uint8_t *transferBuffer; /*!< Address of buffer containing the data to be transmitted */
uint32_t transferLength; /*!< Length of data to transmit. */
uint32_t transferDone; /*!< The data length has been transferred*/
uint32_t transferPrimedLength; /*!< it may larger than transferLength, because the primed length may larger than the
transaction length. */
uint8_t *epPacketBuffer; /*!< The max packet buffer for copying*/
union
{
uint32_t state; /*!< The state of the endpoint */
struct
{
uint32_t maxPacketSize : 11U; /*!< The maximum packet size of the endpoint */
uint32_t stalled : 1U; /*!< The endpoint is stalled or not */
uint32_t transferring : 1U; /*!< The endpoint is transferring */
uint32_t zlt : 1U; /*!< zlt flag */
uint32_t stallPrimed : 1U;
uint32_t epPacketCopyed : 1U; /*!< whether use the copy buffer */
uint32_t epControlDefault : 5u; /*!< The EP command/status 26~30 bits */
uint32_t doubleBufferBusy : 2U; /*!< How many buffers are primed, for control endpoint it is not used */
uint32_t producerOdd : 1U; /*!< When priming one transaction, prime to this endpoint buffer */
uint32_t consumerOdd : 1U; /*!< When transaction is done, read result from this endpoint buffer */
uint32_t endpointType : 2U;
#if (defined(USB_DEVICE_CONFIG_ROOT2_TEST) && (USB_DEVICE_CONFIG_ROOT2_TEST > 0U))
uint32_t isOpened : 1U; /*!< whether the endpoint is initialized */
uint32_t reserved1 : 4U;
#else
uint32_t reserved1 : 5U;
#endif
} stateBitField;
} stateUnion;
union
{
uint16_t epBufferStatus;
/* If double buff is disable, only epBufferStatusUnion[0] is used;
For control endpoint, only epBufferStatusUnion[0] is used. */
struct
{
uint16_t transactionLength : 15U;
uint16_t epPacketCopyed : 1U;
} epBufferStatusField;
} epBufferStatusUnion[2];
} usb_device_lpc3511ip_endpoint_state_struct_t;
/*! @brief LPC USB controller (IP3511) state structure */
typedef struct _usb_device_lpc3511ip_state_struct
{
/*!< control data buffer, must align with 64 */
uint8_t *controlData;
/*!< 8 bytes' setup data, must align with 64 */
uint8_t *setupData;
/*!< 4 bytes for zero length transaction, must align with 64 */
uint8_t *zeroTransactionData;
/* Endpoint state structures */
usb_device_lpc3511ip_endpoint_state_struct_t endpointState[(USB_DEVICE_IP3511_ENDPOINTS_NUM * 2)];
usb_device_handle deviceHandle; /*!< (4 bytes) Device handle used to identify the device object belongs to */
USB_LPC3511IP_Type *registerBase; /*!< (4 bytes) ip base address */
volatile uint32_t *epCommandStatusList; /* endpoint list */
#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \
(defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))
void *dcdHandle; /*!< Dcd handle used to identify the device object belongs to */
#endif
uint8_t controllerId; /*!< Controller ID */
uint8_t isResetting; /*!< Is doing device reset or not */
uint8_t deviceSpeed; /*!< some controller support the HS */
#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))
uint8_t controllerSpeed;
#endif
#if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE))
uint8_t deviceState; /*!< Is device attached,1 attached,0 detached */
#endif
#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
#if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U))
uint8_t lpmRemoteWakeUp;
#endif
#endif
#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))
#if (defined(FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK) && \
(FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK))
uint8_t hsInterruptIssue;
#endif
#endif
} usb_device_lpc3511ip_state_struct_t;
/*!
* @name USB device controller (IP3511) functions
* @{
*/
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @brief Initializes the USB device controller instance.
*
* This function initializes the USB device controller module specified by the controllerId.
*
* @param[in] controllerId The controller ID of the USB IP. See the enumeration type usb_controller_index_t.
* @param[in] handle Pointer of the device handle used to identify the device object belongs to.
* @param[out] controllerHandle An out parameter used to return the pointer of the device controller handle to the
* caller.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceLpc3511IpInit(uint8_t controllerId,
usb_device_handle handle,
usb_device_controller_handle *controllerHandle);
/*!
* @brief Deinitializes the USB device controller instance.
*
* This function deinitializes the USB device controller module.
*
* @param[in] controllerHandle Pointer of the device controller handle.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceLpc3511IpDeinit(usb_device_controller_handle controllerHandle);
/*!
* @brief Sends data through a specified endpoint.
*
* This function sends data through a specified endpoint.
*
* @param[in] controllerHandle Pointer of the device controller handle.
* @param[in] endpointAddress Endpoint index.
* @param[in] buffer The memory address to hold the data need to be sent.
* @param[in] length The data length need to be sent.
*
* @return A USB error code or kStatus_USB_Success.
*
* @note The return value indicates whether the sending request is successful or not. The transfer completion is
* notified by the
* corresponding callback function.
* Currently, only one transfer request can be supported for a specific endpoint.
* If there is a specific requirement to support multiple transfer requests for a specific endpoint, the application
* should implement a queue in the application level.
* The subsequent transfer can begin only when the previous transfer is done (a notification is obtained through the
* endpoint
* callback).
*/
usb_status_t USB_DeviceLpc3511IpSend(usb_device_controller_handle controllerHandle,
uint8_t endpointAddress,
uint8_t *buffer,
uint32_t length);
/*!
* @brief Receives data through a specified endpoint.
*
* This function receives data through a specified endpoint.
*
* @param[in] controllerHandle Pointer of the device controller handle.
* @param[in] endpointAddress Endpoint index.
* @param[in] buffer The memory address to save the received data.
* @param[in] length The data length to be received.
*
* @return A USB error code or kStatus_USB_Success.
*
* @note The return value indicates whether the receiving request is successful or not. The transfer completion is
* notified by the
* corresponding callback function.
* Currently, only one transfer request can be supported for a specific endpoint.
* If there is a specific requirement to support multiple transfer requests for a specific endpoint, the application
* should implement a queue in the application level.
* The subsequent transfer can begin only when the previous transfer is done (a notification is obtained through the
* endpoint
* callback).
*/
usb_status_t USB_DeviceLpc3511IpRecv(usb_device_controller_handle controllerHandle,
uint8_t endpointAddress,
uint8_t *buffer,
uint32_t length);
/*!
* @brief Cancels the pending transfer in a specified endpoint.
*
* The function is used to cancel the pending transfer in a specified endpoint.
*
* @param[in] controllerHandle ointer of the device controller handle.
* @param[in] ep Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceLpc3511IpCancel(usb_device_controller_handle controllerHandle, uint8_t ep);
/*!
* @brief Controls the status of the selected item.
*
* The function is used to control the status of the selected item.
*
* @param[in] controllerHandle Pointer of the device controller handle.
* @param[in] type The selected item. Please refer to enumeration type usb_device_control_type_t.
* @param[in,out] param The parameter type is determined by the selected item.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceLpc3511IpControl(usb_device_controller_handle controllerHandle,
usb_device_control_type_t type,
void *param);
/*! @} */
#if defined(__cplusplus)
}
#endif
/*! @} */
#endif /* __USB_DEVICE_LPC3511IP_H__ */

View file

@ -0,0 +1,79 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __USB_DEVICE_CH9_H__
#define __USB_DEVICE_CH9_H__
/*******************************************************************************
* Definitions
******************************************************************************/
/*!
* @addtogroup usb_device_ch9
* @{
*/
/*! @brief Defines USB device status size when the host request to get device status */
#define USB_DEVICE_STATUS_SIZE (0x02U)
/*! @brief Defines USB device interface status size when the host request to get interface status */
#define USB_INTERFACE_STATUS_SIZE (0x02U)
/*! @brief Defines USB device endpoint status size when the host request to get endpoint status */
#define USB_ENDPOINT_STATUS_SIZE (0x02U)
/*! @brief Defines USB device configuration size when the host request to get current configuration */
#define USB_CONFIGURE_SIZE (0X01U)
/*! @brief Defines USB device interface alternate setting size when the host request to get interface alternate setting
*/
#define USB_INTERFACE_SIZE (0X01U)
/*! @brief Defines USB device status mask */
#define USB_GET_STATUS_DEVICE_MASK (0x03U)
/*! @brief Defines USB device interface status mask */
#define USB_GET_STATUS_INTERFACE_MASK (0x03U)
/*! @brief Defines USB device endpoint status mask */
#define USB_GET_STATUS_ENDPOINT_MASK (0x03U)
/*! @brief Control read and write sequence */
typedef enum _usb_device_control_read_write_sequence
{
kUSB_DeviceControlPipeSetupStage = 0U, /*!< Setup stage */
kUSB_DeviceControlPipeDataStage, /*!< Data stage */
kUSB_DeviceControlPipeStatusStage, /*!< status stage */
} usb_device_control_read_write_sequence_t;
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* API
******************************************************************************/
/*!
* @brief Initializes the control pipes.
*
* The function is used to initialize the control pipes. This function should be called when event
* kUSB_DeviceEventBusReset is received.
*
* @param[in] handle The device handle.
* @param[in] param The event parameter.
*
* @return A USB error code or kStatus_USB_Success.
*/
extern usb_status_t USB_DeviceControlPipeInit(usb_device_handle handle, void *param);
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* __USB_DEVICE_CH9_H__ */

Some files were not shown because too many files have changed in this diff Show more