Merge pull request #14663 from arduino/whd_patch_portenta

Portenta: Add support to generic COMPONENT_WHD
pull/14847/head
Martin Kojtal 2021-07-08 15:54:20 +02:00 committed by GitHub
commit 0e52d4946c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 31060 additions and 1 deletions

View File

@ -1,6 +1,8 @@
# Copyright (c) 2020 ARM Limited. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
add_subdirectory(COMPONENT_WHD EXCLUDE_FROM_ALL)
add_library(mbed-portenta-h7-m4 INTERFACE)
target_sources(mbed-portenta-h7-m4

View File

@ -0,0 +1,34 @@
# Copyright (c) 2020-2021 ARM Limited. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
add_library(mbed-portenta-whd-4343w-fw INTERFACE)
target_include_directories(mbed-portenta-whd-4343w-fw
INTERFACE
resources/firmware/COMPONENT_4343W_FS
)
target_sources(mbed-portenta-whd-4343w-fw
INTERFACE
resources/firmware/COMPONENT_4343W_FS/4343WA1_bin.c
resources/firmware/COMPONENT_4343W_FS/4343WA1_clm_blob.c
)
add_library(mbed-portenta-whd-4343w-nvram INTERFACE)
target_include_directories(mbed-portenta-whd-4343w-nvram INTERFACE resources/nvram)
add_library(mbed-portenta-whd INTERFACE)
target_include_directories(mbed-portenta-whd
INTERFACE
.
port
interface
)
target_sources(mbed-portenta-whd
INTERFACE
port/cyhal.c
port/cyhalgpio.cpp
port/cyhalsdio.c
port/wiced_filesystem.cpp
interface/cyabs_rtos_rtxv5.c
)

View File

@ -0,0 +1,9 @@
/*
* This file is used to set the MAC address in NVRAM.
* The MAC address of the Wi-Fi device may be configured in OTP and/or in NVRAM.
* If both OTP and NVRAM contains the MAC address then OTP programmed MAC address will be used.
* PSOC boards are usually programmed with OTP MAC address.
* MAC address is printed during WHD power up
*/
#define NVRAM_GENERATED_MAC_ADDRESS "macaddr=00:A0:50:6f:b2:ea"

View File

@ -0,0 +1,228 @@
/***************************************************************************//**
* \file cy_result.h
*
* \brief
* Basic function result handling. Defines a simple type for conveying
* information about whether something succeeded or details about any issues
* that were detected.
*
********************************************************************************
* \copyright
* Copyright 2018-2020 Cypress Semiconductor Corporation
* 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
*
* 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.
*******************************************************************************/
/**
* \addtogroup group_result Result Type
* \ingroup group_abstraction
* \{
* \anchor anchor_general_description
* \brief Defines a type and related utilities for function result handling.
*
* The @ref cy_rslt_t type is a structured bitfield which encodes information
* about result type, the originating module, and a code for the specific
* error (or warning etc). In order to extract these individual fields from
* a @ref cy_rslt_t value, the utility macros @ref CY_RSLT_GET_TYPE, @ref CY_RSLT_GET_MODULE,
* and @ref CY_RSLT_GET_CODE are provided. For example:
* \code
* cy_rslt_t result = cy_hal_do_operation(arg);
* // Will be CY_RSLT_TYPE_INFO, CY_RSLT_TYPE_WARNING, CY_RSLT_TYPE_ERROR, or CY_RSLT_TYPE_FATAL
* uint8_t type = CY_RSLT_GET_TYPE(result)
* // See the "Modules" section for possible values
* uint16_t module_id = CY_RSLT_GET_MODULE(result);
* // Specific error codes are defined by each module
* uint16_t error_code = CY_RSLT_GET_CODE(result);
* \endcode
*/
#if !defined(CY_RESULT_H)
#define CY_RESULT_H
#include <stdint.h>
#if defined(__cplusplus)
extern "C" {
#endif
/**
* @brief Provides the result of an operation as a structured bitfield.
*
* See the \ref anchor_general_description "General Description"
* for more details on structure and usage.
*/
typedef uint32_t cy_rslt_t;
/** @ref cy_rslt_t return value indicating success */
#define CY_RSLT_SUCCESS ((cy_rslt_t)0x00000000U)
/** \cond INTERNAL */
/** Mask for the bit at position "x" */
#define CY_BIT_MASK(x) ((1UL << (x)) - 1U)
/** Bit position of the result type */
#define CY_RSLT_TYPE_POSITION (16U)
/** Bit width of the result type */
#define CY_RSLT_TYPE_WIDTH (2U)
/** Bit position of the module identifier */
#define CY_RSLT_MODULE_POSITION (18U)
/** Bit width of the module identifier */
#define CY_RSLT_MODULE_WIDTH (14U)
/** Bit position of the result code */
#define CY_RSLT_CODE_POSITION (0U)
/** Bit width of the result code */
#define CY_RSLT_CODE_WIDTH (16U)
/** Mask for the result type */
#define CY_RSLT_TYPE_MASK CY_BIT_MASK(CY_RSLT_TYPE_WIDTH)
/** Mask for the module identifier */
#define CY_RSLT_MODULE_MASK CY_BIT_MASK(CY_RSLT_MODULE_WIDTH)
/** Mask for the result code */
#define CY_RSLT_CODE_MASK CY_BIT_MASK(CY_RSLT_CODE_WIDTH)
/** \endcond */
/**
* \{
* @name Fields
* Utility macros for constructing result values and extracting individual fields from existing results.
*/
/**
* @brief Get the value of the result type field
* @param x the @ref cy_rslt_t value from which to extract the result type
*/
#define CY_RSLT_GET_TYPE(x) (((x) >> CY_RSLT_TYPE_POSITION) & CY_RSLT_TYPE_MASK)
/**
* @brief Get the value of the module identifier field
* @param x the @ref cy_rslt_t value from which to extract the module id
*/
#define CY_RSLT_GET_MODULE(x) (((x) >> CY_RSLT_MODULE_POSITION) & CY_RSLT_MODULE_MASK)
/**
* @brief Get the value of the result code field
* @param x the @ref cy_rslt_t value from which to extract the result code
*/
#define CY_RSLT_GET_CODE(x) (((x) >> CY_RSLT_CODE_POSITION) & CY_RSLT_CODE_MASK)
/**
* @brief Create a new @ref cy_rslt_t value that encodes the specified type, module, and result code.
* @param type one of @ref CY_RSLT_TYPE_INFO, @ref CY_RSLT_TYPE_WARNING,
* @ref CY_RSLT_TYPE_ERROR, @ref CY_RSLT_TYPE_FATAL
* @param module Identifies the module where this result originated; see @ref anchor_modules "Modules".
* @param code a module-defined identifier to identify the specific situation that
* this result describes.
*/
#define CY_RSLT_CREATE(type, module, code) \
((((module) & CY_RSLT_MODULE_MASK) << CY_RSLT_MODULE_POSITION) | \
(((code) & CY_RSLT_CODE_MASK) << CY_RSLT_CODE_POSITION) | \
(((type) & CY_RSLT_TYPE_MASK) << CY_RSLT_TYPE_POSITION))
/** \} fields */
/**
* \{
* @name Result Types
* Defines codes to identify the type of result.
*/
/** @brief The result code is informational-only */
#define CY_RSLT_TYPE_INFO (0U)
/** @brief The result code is warning of a problem but will proceed */
#define CY_RSLT_TYPE_WARNING (1U)
/** @brief The result code is an error */
#define CY_RSLT_TYPE_ERROR (2U)
/** @brief The result code is a fatal error */
#define CY_RSLT_TYPE_FATAL (3U)
/** \} severity */
/**
* \{
* @name Modules
* @anchor anchor_modules
* Defines codes to identify the module from which an error originated.
* For some large libraries, a range of module codes is defined here;
* see the library documentation for values corresponding to individual modules.
* Valid range is 0x0000-0x4000.
*/
/**** DRIVER Module codes: 0x0000 - 0x00FF ****/
/** Base module identifier for peripheral driver library drivers (0x0000 - 0x007F) */
#define CY_RSLT_MODULE_DRIVERS_PDL_BASE (0x0000U)
/** Base module identifier for wireless host driver library modules (0x0080 - 0x00FF) */
#define CY_RSLT_MODULE_DRIVERS_WHD_BASE (0x0080U)
/** Deprecated. Use \ref CY_RSLT_MODULE_ABSTRACTION_HAL */
#define CY_RSLT_MODULE_ABSTRACTION_HAL_BASE (0x0100U)
/** Module identifier for the Hardware Abstraction Layer */
#define CY_RSLT_MODULE_ABSTRACTION_HAL (0x0100U)
/** Module identifier for board support package */
#define CY_RSLT_MODULE_ABSTRACTION_BSP (0x0180U)
/** Module identifier for file system abstraction */
#define CY_RSLT_MODULE_ABSTRACTION_FS (0x0181U)
/** Module identifier for resource abstraction */
#define CY_RSLT_MODULE_ABSTRACTION_RESOURCE (0x0182U)
/** Module identifier for rtos abstraction */
#define CY_RSLT_MODULE_ABSTRACTION_OS (0x0183U)
/** Base identifier for environment abstraction modules (0x0184 - 0x01FF) */
#define CY_RSLT_MODULE_ABSTRACTION_ENV (0x0184U)
/** Base module identifier for Board Libraries (0x01A0 - 0x01BF) */
#define CY_RSLT_MODULE_BOARD_LIB_BASE (0x01A0U)
/** Module identifier for the Retarget IO Board Library */
#define CY_RSLT_MODULE_BOARD_LIB_RETARGET_IO (0x1A0U)
/** Module identifier for the RGB LED Board Library */
#define CY_RSLT_MODULE_BOARD_LIB_RGB_LED (0x01A1U)
/** Module identifier for the Serial Flash Board Library */
#define CY_RSLT_MODULE_BOARD_LIB_SERIAL_FLASH (0x01A2U)
/** Module identifier for the WiFi Host Driver + Board Support Integration Library */
#define CY_RSLT_MODULE_BOARD_LIB_WHD_INTEGRATION (0x01A3U)
/** Base module identifier for Shield Board Libraries (0x01B8 - 0x01BF) */
#define CY_RSLT_MODULE_BOARD_SHIELD_BASE (0x01B8U)
/** Module identifier for Shield Board CY8CKIT-028-EPD */
#define CY_RSLT_MODULE_BOARD_SHIELD_028_EPD (0x01B8U)
/** Module identifier for Shield Board CY8CKIT-028-TFT */
#define CY_RSLT_MODULE_BOARD_SHIELD_028_TFT (0x01B9U)
/** Module identifier for Shield Board CY8CKIT-032 */
#define CY_RSLT_MODULE_BOARD_SHIELD_032 (0x01BAU)
/** Base module identifier for Board Hardware Libraries (0x01C0 - 0x01FF) */
#define CY_RSLT_MODULE_BOARD_HARDWARE_BASE (0x01C0U)
/** Module identifier for the BMI160 Motion Sensor Library */
#define CY_RSLT_MODULE_BOARD_HARDWARE_BMI160 (0x01C0U)
/** Module identifier for the E2271CS021 E-Ink Controller Library */
#define CY_RSLT_MODULE_BOARD_HARDWARE_E2271CS021 (0x01C1U)
/** Module identifier for the NTC GPIO Thermistor Library */
#define CY_RSLT_MODULE_BOARD_HARDWARE_THERMISTOR (0x01C2U)
/** Module identifier for the SSD1306 OLED Controller Library */
#define CY_RSLT_MODULE_BOARD_HARDWARE_SSD1306 (0x01C3U)
/** Module identifier for the ST7789V TFT Controller Library */
#define CY_RSLT_MODULE_BOARD_HARDWARE_ST7789V (0x01C4U)
/** Module identifier for the Light Sensor Library */
#define CY_RSLT_MODULE_BOARD_HARDWARE_LIGHT_SENSOR (0x01C5U)
/** Module identifier for the AK4954A Audio Codec Library */
#define CY_RSLT_MODULE_BOARD_HARDWARE_AK4954A (0x01C6U)
/** Base module identifier for Middleware Libraries (0x0200 - 0x02FF) */
#define CY_RSLT_MODULE_MIDDLEWARE_BASE (0x0200U)
/** \} modules */
#ifdef __cplusplus
}
#endif
#endif /* CY_RESULT_H */
/** \} group_result */

View File

@ -0,0 +1,711 @@
/***************************************************************************//**
* \file cyabs_rtos.h
*
* \brief
* Defines the Cypress RTOS Interface. Provides prototypes for functions that
* allow Cypress libraries to use RTOS resources such as threads, mutexes &
* timing functions in an abstract way. The APIs are implemented in the Port
* Layer RTOS interface which is specific to the RTOS in use.
*
********************************************************************************
* \copyright
* Copyright 2018-2020 Cypress Semiconductor Corporation
* 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
*
* 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 INCLUDED_CY_RTOS_INTERFACE_H_
#define INCLUDED_CY_RTOS_INTERFACE_H_
#include "cyabs_rtos_impl.h"
#include "cy_result.h"
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
/**
* \defgroup group_abstraction_rtos_common Common
* General types and defines for working with the RTOS abstraction layer.
* \defgroup group_abstraction_rtos_mutex Mutex
* APIs for acquiring and working with Mutexes.
* \defgroup group_abstraction_rtos_queue Queue
* APIs for creating and working with Queues.
* \defgroup group_abstraction_rtos_semaphore Semaphore
* APIs for acquiring and working with Semaphores.
* \defgroup group_abstraction_rtos_threads Threads
* APIs for creating and working with Threads.
* \defgroup group_abstraction_rtos_time Time
* APIs for getting the current time and waiting.
* \defgroup group_abstraction_rtos_timer Timer
* APIs for creating and working with Timers.
*/
#ifdef __cplusplus
extern "C"
{
#endif
/*********************************************** CONSTANTS **********************************************/
/**
* \ingroup group_abstraction_rtos_common
* \{
*/
#if defined(DOXYGEN)
//#include "Template/cyabs_rtos_impl.h"
/** Return value indicating success */
#define CY_RSLT_SUCCESS ((cy_rslt_t)0x00000000U)
#endif
/** Used with RTOS calls that require a timeout. This implies the call will never timeout. */
#define CY_RTOS_NEVER_TIMEOUT ( (uint32_t)0xffffffffUL )
//
// Note on error strategy. If the error is a normal part of operation (timeouts, full queues, empty
// queues), the these errors are listed here and the abstraction layer implementation must map from the
// underlying errors to these. If the errors are special cases, the the error \ref CY_RTOS_GENERAL_ERROR
// will be returned and \ref cy_rtos_last_error() can be used to retrieve the RTOS specific error message.
//
/** Requested operation did not complete in the specified time */
#define CY_RTOS_TIMEOUT CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_OS, 0)
/** The RTOS could not allocate memory for the specified operation */
#define CY_RTOS_NO_MEMORY CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_OS, 1)
/** An error occured in the RTOS */
#define CY_RTOS_GENERAL_ERROR CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_OS, 2)
/** A bad argument was passed into the APIs */
#define CY_RTOS_BAD_PARAM CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_OS, 5)
/** A memory alignment issue was detected. Ensure memory provided is aligned per \ref CY_RTOS_ALIGNMENT_MASK */
#define CY_RTOS_ALIGNMENT_ERROR CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_OS, 6)
/** \} group_abstraction_rtos_common */
/**
* \ingroup group_abstraction_rtos_queue
* \{
*/
/** The Queue is already full and can't accept any more items at this time */
#define CY_RTOS_QUEUE_FULL CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_OS, 3)
/** The Queue is empty and has nothing to remove */
#define CY_RTOS_QUEUE_EMPTY CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_OS, 4)
/** \} group_abstraction_rtos_queue */
/*********************************************** TYPES **********************************************/
/**
* The state a thread can be in
*
* \ingroup group_abstraction_rtos_threads
*/
typedef enum cy_thread_state
{
CY_THREAD_STATE_INACTIVE, /**< thread has not started or was terminated but not yet joined */
CY_THREAD_STATE_READY, /**< thread can run, but is not currently */
CY_THREAD_STATE_RUNNING, /**< thread is currently running */
CY_THREAD_STATE_BLOCKED, /**< thread is blocked waiting for something */
CY_THREAD_STATE_TERMINATED, /**< thread has terminated but not freed */
CY_THREAD_STATE_UNKNOWN, /**< thread is in an unknown state */
} cy_thread_state_t;
/**
* The type of timer
*
* \ingroup group_abstraction_rtos_timer
*/
typedef enum cy_timer_trigger_type
{
CY_TIMER_TYPE_PERIODIC, /**< called periodically until stopped */
CY_TIMER_TYPE_ONCE, /**< called once only */
cy_timer_type_periodic = CY_TIMER_TYPE_PERIODIC, /**< \deprecated replaced by \ref CY_TIMER_TYPE_PERIODIC */
cy_timer_type_once = CY_TIMER_TYPE_ONCE, /**< \deprecated replaced by \ref CY_TIMER_TYPE_ONCE */
} cy_timer_trigger_type_t;
/**
* The type of a function that is the entry point for a thread
*
* @param[in] arg the argument passed from the thread create call to the entry function
*
* \ingroup group_abstraction_rtos_threads
*/
typedef void (*cy_thread_entry_fn_t)(cy_thread_arg_t arg);
/**
* The callback function to be called by a timer
*
* \ingroup group_abstraction_rtos_timer
*/
typedef void (*cy_timer_callback_t)(cy_timer_callback_arg_t arg);
/**
* Return the last error from the RTOS.
*
* The functions in the RTOS abstraction layer adhere to the Cypress return
* results calling convention. The underlying RTOS implementations will not but rather
* will have their own error code conventions. This function is provided as a service
* to the developer, mostly for debugging, and returns the underlying RTOS error code
* from the last RTOS abstraction layer that returned \ref CY_RTOS_GENERAL_ERROR.
*
* @return RTOS specific error code.
*
* \ingroup group_abstraction_rtos_common
*/
cy_rtos_error_t cy_rtos_last_error();
/*********************************************** Threads **********************************************/
/**
* \ingroup group_abstraction_rtos_threads
* \{
*/
/** Create a thread with specific thread argument.
*
* This function is called to startup a new thread. If the thread can exit, it must call
* \ref cy_rtos_exit_thread() just before doing so. All created threads that can terminate, either
* by themselves or forcefully by another thread MUST have \ref cy_rtos_join_thread() called on them
* by another thread in order to cleanup any resources that might have been allocated for them.
*
* @param[out] thread Pointer to a variable which will receive the new thread handle
* @param[in] entry_function Function pointer which points to the main function for the new thread
* @param[in] name String thread name used for a debugger
* @param[in] stack The buffer to use for the thread stack. This must be aligned to
* \ref CY_RTOS_ALIGNMENT_MASK with a size of at least \ref CY_RTOS_MIN_STACK_SIZE.
* If stack is null, cy_rtos_create_thread will allocate a stack from the heap.
* @param[in] stack_size The size of the thread stack in bytes
* @param[in] priority The priority of the thread. Values are operating system specific, but some
* common priority levels are defined:
* CY_THREAD_PRIORITY_LOW
* CY_THREAD_PRIORITY_NORMAL
* CY_THREAD_PRIORITY_HIGH
* @param[in] arg The argument to pass to the new thread
*
* @return The status of thread create request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_create_thread(cy_thread_t *thread, cy_thread_entry_fn_t entry_function,
const char *name, void *stack, uint32_t stack_size, cy_thread_priority_t priority, cy_thread_arg_t arg);
/** Exit the current thread.
*
* This function is called just before a thread exits. In some cases it is sufficient
* for a thread to just return to exit, but in other cases, the RTOS must be explicitly
* signaled. In cases where a return is sufficient, this should be a null funcition.
* where the RTOS must be signaled, this function should perform that In cases operation.
* In code using RTOS services, this function should be placed at any at any location
* where the main thread function will return, exiting the thread. Threads that can
* exit must still be joined (\ref cy_rtos_join_thread) to ensure their resources are
* fully cleaned up.
*
* @return The status of thread exit request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_exit_thread();
/** Terminates another thread.
*
* This function is called to terminate another thread and reap the resources claimed
* by the thread. This should be called both when forcibly terminating another thread
* as well as any time a thread can exit on its own. For some RTOS implementations
* this is not required as the thread resources are claimed as soon as it exits. In
* other cases, this must be called to reclaim resources. Threads that are terminated
* must still be joined (\ref cy_rtos_join_thread) to ensure their resources are fully
* cleaned up.
*
* @param[in] thread Handle of the thread to terminate
*
* @returns The status of the thread terminate. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_terminate_thread(cy_thread_t *thread);
/** Waits for a thread to complete.
*
* This must be called on any thread that can complete to ensure that any resources that
* were allocated for it are cleaned up.
*
* @param[in] thread Handle of the thread to wait for
*
* @returns The status of thread join request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_join_thread(cy_thread_t *thread);
/** Checks if the thread is running
*
* This function is called to determine if a thread is actively running or not. For information on
* the thread state, use the \ref cy_rtos_get_thread_state() function.
*
* @param[in] thread Handle of the terminated thread to delete
* @param[out] running Returns true if the thread is running, otherwise false
*
* @returns The status of the thread running check. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_is_thread_running(cy_thread_t *thread, bool *running);
/** Gets the state the thread is currently in
*
* This function is called to determine if a thread is running/blocked/inactive/ready etc.
*
* @param[in] thread Handle of the terminated thread to delete
* @param[out] state Returns the state the thread is currently in
*
* @returns The status of the thread state check. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_get_thread_state(cy_thread_t *thread, cy_thread_state_t *state);
/** Get current thread handle
*
* Returns the unique thread handle of the current running thread.
*
* @param[out] thread Handle of the current running thread
*
* @returns The status of thread join request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_get_thread_handle(cy_thread_t *thread);
/** \} group_abstraction_rtos_threads */
/*********************************************** Mutexes **********************************************/
/**
* \ingroup group_abstraction_rtos_mutex
* \{
*/
/** Create a recursive mutex.
*
* Creates a binary mutex which can be used to synchronize between threads
* and between threads and ISRs. Created mutexes are recursive and support priority inheritance.
*
* This function has been replaced by \ref cy_rtos_init_mutex2 which allow for specifying
* whether or not the mutex supports recursion or not.
*
* @param[out] mutex Pointer to the mutex handle to be initialized
*
* @return The status of mutex creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR]
*/
#define cy_rtos_init_mutex(mutex) cy_rtos_init_mutex2(mutex, true)
/** Create a mutex which can support recursion or not.
*
* Creates a binary mutex which can be used to synchronize between threads and between threads and
* ISRs. Created mutexes can support priority inheritance if recursive.
*
* \note Not all RTOS implementations support non-recursive mutexes. In this case a recursive
* mutex will be created.
*
* @param[out] mutex Pointer to the mutex handle to be initialized
* @param[in] recursive Should the created mutex support recursion or not
*
* @return The status of mutex creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_init_mutex2(cy_mutex_t *mutex, bool recursive);
/** Get a mutex.
*
* If the mutex is available, it is acquired and this function returned.
* If the mutex is not available, the thread waits until the mutex is available
* or until the timeout occurs.
*
* @note This function must not be called from an interrupt context as it may block.
*
* @param[in] mutex Pointer to the mutex handle
* @param[in] timeout_ms Maximum number of milliseconds to wait while attempting to get
* the mutex. Use the \ref CY_RTOS_NEVER_TIMEOUT constant to wait forever.
* Must be zero if in_isr is true.
*
* @return The status of the get mutex. Returns timeout if mutex was not acquired
* before timeout_ms period. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_TIMEOUT, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_get_mutex(cy_mutex_t *mutex, cy_time_t timeout_ms);
/** Set a mutex.
*
* The mutex is released allowing any other threads waiting on the mutex to
* obtain the semaphore.
*
* @param[in] mutex Pointer to the mutex handle
*
* @return The status of the set mutex request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
*
*/
cy_rslt_t cy_rtos_set_mutex(cy_mutex_t *mutex);
/** Deletes a mutex.
*
* This function frees the resources associated with a sempahore.
*
* @param[in] mutex Pointer to the mutex handle
*
* @return The status to the delete request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_deinit_mutex(cy_mutex_t *mutex);
/** \} group_abstraction_rtos_mutex */
/*********************************************** Semaphores **********************************************/
/**
* \ingroup group_abstraction_rtos_semaphore
* \{
*/
/**
* Create a semaphore
*
* This is basically a counting semaphore.
*
* @param[in,out] semaphore Pointer to the semaphore handle to be initialized
* @param[in] maxcount The maximum count for this semaphore
* @param[in] initcount The initial count for this semaphore
*
* @return The status of the semaphore creation. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_init_semaphore(cy_semaphore_t *semaphore, uint32_t maxcount, uint32_t initcount);
/**
* Get/Acquire a semaphore
*
* If the semaphore count is zero, waits until the semaphore count is greater than zero.
* Once the semaphore count is greater than zero, this function decrements
* the count and return. It may also return if the timeout is exceeded.
*
* @param[in] semaphore Pointer to the semaphore handle
* @param[in] timeout_ms Maximum number of milliseconds to wait while attempting to get
* the semaphore. Use the \ref CY_RTOS_NEVER_TIMEOUT constant to wait forever. Must
* be zero is in_isr is true
* @param[in] in_isr true if we are trying to get the semaphore from with an ISR
* @return The status of get semaphore operation [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_TIMEOUT, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_get_semaphore(cy_semaphore_t *semaphore, cy_time_t timeout_ms, bool in_isr);
/**
* Set/Release a semaphore
*
* Increments the semaphore count, up to the maximum count for this semaphore.
*
* @param[in] semaphore Pointer to the semaphore handle
* @param[in] in_isr Value of true indicates calling from interrupt context
* Value of false indicates calling from normal thread context
* @return The status of set semaphore operation [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_set_semaphore(cy_semaphore_t *semaphore, bool in_isr);
/**
* Get the count of a semaphore.
*
* Gets the number of available tokens on the semaphore.
*
* @param[in] semaphore Pointer to the semaphore handle
* @param[out] count Pointer to the return count
* @return The status of get semaphore count operation [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_get_count_semaphore(cy_semaphore_t *semaphore, size_t *count);
/**
* Deletes a semaphore
*
* This function frees the resources associated with a semaphore.
*
* @param[in] semaphore Pointer to the semaphore handle
*
* @return The status of semaphore deletion [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_deinit_semaphore(cy_semaphore_t *semaphore);
/** \} group_abstraction_rtos_semaphore */
/*********************************************** Events **********************************************/
/**
* \ingroup group_abstraction_rtos_event
* \{
*/
/** Create an event.
*
* This is an event which can be used to signal a set of threads
* with a 32 bit data element.
*
* @param[in,out] event Pointer to the event handle to be initialized
*
* @return The status of the event initialization request.
* [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_init_event(cy_event_t *event);
/** Set the event flag bits.
*
* This is an event which can be used to signal a set of threads
* with a 32 bit data element. Any threads waiting on this event are released
*
* @param[in] event Pointer to the event handle
* @param[in] bits The value of the 32 bit flags
* @param[in] in_isr If true, this is called from an ISR, otherwise from a thread
*
* @return The status of the set request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_setbits_event(cy_event_t *event, uint32_t bits, bool in_isr) ;
/**
* Clear the event flag bits
*
* This function clears bits in the event.
*
* @param[in] event Pointer to the event handle
* @param[in] bits Any bits set in this value, will be cleared in the event.
* @param[in] in_isr if true, this is called from an ISR, otherwise from a thread
*
* @return The status of the clear flags request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_clearbits_event(cy_event_t *event, uint32_t bits, bool in_isr) ;
/** Get the event bits.
*
* Returns the current bits for the event.
*
* @param[in] event Pointer to the event handle
* @param[out] bits pointer to receive the value of the event flags
*
* @return The status of the get request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_getbits_event(cy_event_t *event, uint32_t *bits);
/** Wait for the event and return bits.
*
* Waits for the event to be set and then returns the bits associated
* with the event, or waits for the given timeout period.
* @note This function returns if any bit in the set is set.
*
* @param[in] event Pointer to the event handle
* @param[in,out] bits pointer to receive the value of the event flags
* @param[in] clear if true, clear any bits set that cause the wait to return
* if false, do not clear bits
* @param[in] all if true, all bits in the initial bits value must be set to return
* if false, any one bit in the initial bits value must be set to return
* @param[in] timeout The amount of time to wait in milliseconds
*
* @return The status of the wait for event request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_waitbits_event(cy_event_t *event, uint32_t *bits, bool clear, bool all, cy_time_t timeout);
/** Deinitialize a event.
*
* This function frees the resources associated with an event.
*
* @param[in] event Pointer to the event handle
*
* @return The status of the deletion request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_deinit_event(cy_event_t *event);
/** \} group_abstraction_rtos_event */
/*********************************************** Queues **********************************************/
/**
* \ingroup group_abstraction_rtos_queue
* \{
*/
/** Create a queue.
*
* This is a queue of data where entries are placed on the back of the queue
* and removed from the front of the queue.
*
* @param[out] queue Pointer to the queue handle
* @param[in] length The maximum length of the queue in items
* @param[in] itemsize The size of each item in the queue.
*
* @return The status of the creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_init_queue(cy_queue_t *queue, size_t length, size_t itemsize);
/** Put an item in a queue.
*
* This function puts an item in the queue. The item is copied
* into the queue using a memory copy and the data pointed to by item_ptr
* is no longer referenced once the call returns.
*
* @note If in_isr is true, timeout_ms must be zero.
*
* @param[in] queue Pointer to the queue handle
* @param[in] item_ptr Pointer to the item to place in the queue
* @param[in] timeout_ms The time to wait to place the item in the queue
* @param[in] in_isr If true this is being called from within and ISR
*
* @return The status of the creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR, \ref CY_RTOS_QUEUE_FULL]
*/
cy_rslt_t cy_rtos_put_queue(cy_queue_t *queue, const void *item_ptr, cy_time_t timeout_ms, bool in_isr);
/** Gets an item in a queue.
*
* This function gets an item from the queue. The item is copied
* out of the queue into the memory provide by item_ptr. This space must be
* large enough to hold a queue entry as defined when the queue was initialized.
*
* @note If in_isr is true, timeout_ms must be zero.
*
* @param[in] queue Pointer to the queue handle
* @param[in] item_ptr Pointer to the memory for the item from the queue
* @param[in] timeout_ms The time to wait to get an item from the queue
* @param[in] in_isr If true this is being called from within an ISR
*
* @return The status of the creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR, \ref CY_RTOS_QUEUE_EMPTY]
*/
cy_rslt_t cy_rtos_get_queue(cy_queue_t *queue, void *item_ptr, cy_time_t timeout_ms, bool in_isr);
/** Return the number of items in the queue.
*
* This function returns the number of items currently in the queue.
*
* @param[in] queue Pointer to the queue handle
* @param[out] num_waiting Pointer to the return count
*
* @return The status of the creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_count_queue(cy_queue_t *queue, size_t *num_waiting);
/** Return the amount of empty space in the queue.
*
* This function returns the amount of empty space in the
* queue. For instance, if the queue was created with 10 entries max and there
* are currently 2 entries in the queue, this will return 8.
*
* @param[in] queue Pointer to the queue handle
* @param[out] num_spaces Pointer to the return count.
*
* @return The status of the creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_space_queue(cy_queue_t *queue, size_t *num_spaces);
/** Reset the queue.
*
* This function sets the queue to empty.
*
* @param[in] queue pointer to the queue handle
*
* @return The status of the creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_reset_queue(cy_queue_t *queue);
/** Deinitialize the queue handle.
*
* This function de-initializes the queue and returns all
* resources used by the queue.
*
* @param[in] queue Pointer to the queue handle
*
* @return The status of the creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_deinit_queue(cy_queue_t *queue);
/** \} group_abstraction_rtos_queue */
/*********************************************** Timers **********************************************/
/**
* \ingroup group_abstraction_rtos_timer
* \{
*/
/** Create a new timer.
*
* This function initializes a timer object.
* @note The timer is not active until start is called.
* @note The callback may be (likely will be) called from a different thread.
*
* @param[out] timer Pointer to the timer handle to initialize
* @param[in] type Type of timer (periodic or once)
* @param[in] fun The function
* @param[in] arg Argument to pass along to the callback function
*
* @return The status of the creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_init_timer(cy_timer_t *timer, cy_timer_trigger_type_t type,
cy_timer_callback_t fun, cy_timer_callback_arg_t arg);
/** Start a timer.
*
* @param[in] timer Pointer to the timer handle
* @param[in] num_ms The number of milliseconds to wait before the timer fires
*
* @return The status of the creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_start_timer(cy_timer_t *timer, cy_time_t num_ms);
/** Stop a timer.
*
* @param[in] timer Pointer to the timer handle
*
* @return The status of the creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_stop_timer(cy_timer_t *timer);
/** Returns state of a timer.
*
* @param[in] timer Pointer to the timer handle
* @param[out] state Return value for state, true if running, false otherwise
*
* @return The status of the creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_is_running_timer(cy_timer_t *timer, bool *state);
/** Deinit the timer.
*
* This function deinitializes the timer and frees all consumed resources.
*
* @param[in] timer Pointer to the timer handle
*
* @return The status of the creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_deinit_timer(cy_timer_t *timer);
/** \} group_abstraction_rtos_timer */
/*********************************************** Time **********************************************/
/**
* \ingroup group_abstraction_rtos_time
* \{
*/
/** Gets time in milliseconds since RTOS start.
*
* @note Since this is only 32 bits, it will roll over every 49 days, 17 hours, 2 mins, 47.296 seconds
*
* @param[out] tval Pointer to the struct to populate with the RTOS time
*
* @returns Time in milliseconds since the RTOS started.
*/
cy_rslt_t cy_rtos_get_time(cy_time_t *tval);
/** Delay for a number of milliseconds.
*
* Processing of this function depends on the minimum sleep
* time resolution of the RTOS. The current thread should sleep for
* the longest period possible which is less than the delay required,
* then makes up the difference with a tight loop.
*
* @param[in] num_ms The number of milliseconds to delay for
*
* @return The status of the creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
*/
cy_rslt_t cy_rtos_delay_milliseconds(cy_time_t num_ms);
/** \} group_abstraction_rtos_time */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* ifndef INCLUDED_CY_RTOS_INTERFACE_H_ */

View File

@ -0,0 +1,77 @@
/***************************************************************************//**
* \file cyabs_rtos_impl.h
*
* \brief
* Internal definitions for RTOS abstraction layer
*
********************************************************************************
* \copyright
* Copyright 2019-2020 Cypress Semiconductor Corporation
* 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
*
* 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 INCLUDED_CYABS_RTOS_IMPL_H_
#define INCLUDED_CYABS_RTOS_IMPL_H_
#include "cmsis_os2.h"
#include "rtx_os.h"
#ifdef __cplusplus
extern "C"
{
#endif
/******************************************************
* Constants
******************************************************/
#define CY_RTOS_MIN_STACK_SIZE 300 /** Minimum stack size in bytes */
#define CY_RTOS_ALIGNMENT 0x00000008UL /** Minimum alignment for RTOS objects */
#define CY_RTOS_ALIGNMENT_MASK 0x00000007UL /** Mask for checking the alignment of created RTOS objects */
/******************************************************
* Type Definitions
******************************************************/
/* RTOS thread priority */
typedef enum
{
CY_RTOS_PRIORITY_MIN = osPriorityNone,
CY_RTOS_PRIORITY_LOW = osPriorityLow,
CY_RTOS_PRIORITY_BELOWNORMAL = osPriorityBelowNormal,
CY_RTOS_PRIORITY_NORMAL = osPriorityNormal,
CY_RTOS_PRIORITY_ABOVENORMAL = osPriorityAboveNormal,
CY_RTOS_PRIORITY_HIGH = osPriorityHigh,
CY_RTOS_PRIORITY_REALTIME = osPriorityRealtime,
CY_RTOS_PRIORITY_MAX = osPriorityRealtime7
} cy_thread_priority_t ;
typedef osThreadId_t cy_thread_t; /** CMSIS definition of a thread handle */
typedef void * cy_thread_arg_t; /** Argument passed to the entry function of a thread */
typedef osMutexId_t cy_mutex_t; /** CMSIS definition of a mutex */
typedef osSemaphoreId_t cy_semaphore_t; /** CMSIS definition of a semaphore */
typedef osEventFlagsId_t cy_event_t; /** CMSIS definition of an event */
typedef osMessageQueueId_t cy_queue_t; /** CMSIS definition of a message queue */
typedef osTimerId_t cy_timer_t; /** CMSIS definition of a timer */
typedef void * cy_timer_callback_arg_t; /** Argument passed to the timer callback function */
typedef uint32_t cy_time_t; /** Time in milliseconds */
typedef osStatus_t cy_rtos_error_t; /** CMSIS definition of a error status */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* ifndef INCLUDED_CYABS_RTOS_IMPL_H_ */

View File

@ -0,0 +1,863 @@
/***************************************************************************//**
* \file cyabs_rtos.c
*
* \brief
* Implementation for CMSIS RTOS v2 abstraction
*
********************************************************************************
* \copyright
* Copyright 2018-2020 Cypress Semiconductor Corporation
* 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
*
* 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.
*******************************************************************************/
#include <stdlib.h>
#include <cy_utils.h>
#include <cyabs_rtos.h>
#if defined(__cplusplus)
extern "C" {
#endif
/******************************************************
* Error Converter
******************************************************/
/* Last received error status */
static cy_rtos_error_t dbgErr;
cy_rtos_error_t cy_rtos_last_error() { return dbgErr; }
/* Converts internal error type to external error type */
static cy_rslt_t error_converter(cy_rtos_error_t internalError)
{
cy_rslt_t value;
switch (internalError)
{
case osOK:
value = CY_RSLT_SUCCESS;
break;
case osErrorTimeout:
value = CY_RTOS_TIMEOUT;
break;
case osErrorParameter:
value = CY_RTOS_BAD_PARAM;
break;
case osErrorNoMemory:
value = CY_RTOS_NO_MEMORY;
break;
case osError:
case osErrorResource:
case osErrorISR:
default:
value = CY_RTOS_GENERAL_ERROR;
break;
}
/* Update the last known error status */
dbgErr = internalError;
return value;
}
/******************************************************
* Threads
******************************************************/
cy_rslt_t cy_rtos_create_thread(cy_thread_t *thread, cy_thread_entry_fn_t entry_function,
const char *name, void *stack, uint32_t stack_size, cy_thread_priority_t priority, cy_thread_arg_t arg)
{
cy_rslt_t status = CY_RSLT_SUCCESS;
osThreadAttr_t attr;
if (thread == NULL || stack_size < CY_RTOS_MIN_STACK_SIZE)
status = CY_RTOS_BAD_PARAM;
else if (stack != NULL && (0 != (((uint32_t)stack) & CY_RTOS_ALIGNMENT_MASK)))
status = CY_RTOS_ALIGNMENT_ERROR;
else
{
attr.name = name;
attr.attr_bits = osThreadJoinable;
attr.cb_size = osRtxThreadCbSize;
attr.stack_size = stack_size;
attr.priority = (osPriority_t)priority;
attr.tz_module = 0;
attr.reserved = 0;
/* Allocate stack if NULL was passed */
if ((uint32_t *)stack == NULL)
{
/* Note: 1 malloc so that it can be freed with 1 call when terminating */
uint32_t cb_mem_pad = (~osRtxThreadCbSize + 1) & CY_RTOS_ALIGNMENT_MASK;
attr.cb_mem = malloc(osRtxThreadCbSize + cb_mem_pad + stack_size);
if (attr.cb_mem != NULL)
attr.stack_mem = (uint32_t *)((uint32_t)attr.cb_mem + osRtxThreadCbSize + cb_mem_pad);
}
else
{
attr.cb_mem = malloc(osRtxThreadCbSize);
attr.stack_mem = stack;
}
if (attr.cb_mem == NULL)
status = CY_RTOS_NO_MEMORY;
else
{
CY_ASSERT(((uint32_t)attr.cb_mem & CY_RTOS_ALIGNMENT_MASK) == 0UL);
CY_ASSERT(((uint32_t)attr.stack_mem & CY_RTOS_ALIGNMENT_MASK) == 0UL);
*thread = osThreadNew((osThreadFunc_t)entry_function, arg, &attr);
CY_ASSERT((*thread == attr.cb_mem) || (*thread == NULL));
status = (*thread == NULL) ? CY_RTOS_GENERAL_ERROR : CY_RSLT_SUCCESS;
}
}
return status;
}
cy_rslt_t cy_rtos_exit_thread()
{
/* This does not have a return statement because the osThreadExit() function
* does not return so the return statement would be unreachable and causes a
* warning for IAR compiler.
*/
osThreadExit();
}
cy_rslt_t cy_rtos_terminate_thread(cy_thread_t *thread)
{
cy_rslt_t status;
cy_rtos_error_t statusInternal;
if (thread == NULL)
status = CY_RTOS_BAD_PARAM;
else
{
statusInternal = osThreadTerminate(*thread);
status = error_converter(statusInternal);
}
return status;
}
cy_rslt_t cy_rtos_is_thread_running(cy_thread_t *thread, bool *running)
{
cy_rslt_t status = CY_RSLT_SUCCESS;
if ((thread == NULL) || (running == NULL))
status = CY_RTOS_BAD_PARAM;
else
{
*running = (osThreadGetState(*thread) == osThreadRunning) ? true : false;
}
return status;
}
cy_rslt_t cy_rtos_get_thread_state(cy_thread_t *thread, cy_thread_state_t *state)
{
cy_rslt_t status = CY_RSLT_SUCCESS;
if ((thread == NULL) || (state == NULL))
status = CY_RTOS_BAD_PARAM;
else
{
switch (osThreadGetState(*thread))
{
case osThreadInactive:
*state = CY_THREAD_STATE_INACTIVE;
break;
case osThreadReady:
*state = CY_THREAD_STATE_READY;
break;
case osThreadRunning:
*state = CY_THREAD_STATE_RUNNING;
break;
case osThreadBlocked:
*state = CY_THREAD_STATE_BLOCKED;
break;
case osThreadTerminated:
*state = CY_THREAD_STATE_TERMINATED;
break;
case osThreadError:
case osThreadReserved:
default:
*state = CY_THREAD_STATE_UNKNOWN;
break;
}
}
return status;
}
cy_rslt_t cy_rtos_join_thread(cy_thread_t *thread)
{
cy_rslt_t status;
cy_rtos_error_t statusInternal;
if (thread == NULL)
status = CY_RTOS_BAD_PARAM;
else
{
statusInternal = osThreadJoin(*thread);
status = error_converter(statusInternal);
if (status == CY_RSLT_SUCCESS)
{
free(*thread);
*thread = NULL;
}
}
return status;
}
cy_rslt_t cy_rtos_get_thread_handle(cy_thread_t *thread)
{
cy_rslt_t status = CY_RSLT_SUCCESS;
if (thread == NULL)
status = CY_RTOS_BAD_PARAM;
else
*thread = osThreadGetId();
return status;
}
/******************************************************
* Mutexes
******************************************************/
cy_rslt_t cy_rtos_init_mutex2(cy_mutex_t *mutex, bool recursive)
{
cy_rslt_t status;
osMutexAttr_t attr;
if (mutex == NULL)
status = CY_RTOS_BAD_PARAM;
else
{
attr.name = NULL;
attr.attr_bits = osMutexPrioInherit;
if (recursive)
{
attr.attr_bits |= osMutexRecursive;
}
attr.cb_mem = malloc(osRtxMutexCbSize);
attr.cb_size = osRtxMutexCbSize;
if (attr.cb_mem == NULL)
status = CY_RTOS_NO_MEMORY;
else
{
CY_ASSERT(((uint32_t)attr.cb_mem & CY_RTOS_ALIGNMENT_MASK) == 0UL);
*mutex = osMutexNew(&attr);
CY_ASSERT((*mutex == attr.cb_mem) || (*mutex == NULL));
status = (*mutex == NULL) ? CY_RTOS_GENERAL_ERROR : CY_RSLT_SUCCESS;
}
}
return status;
}
cy_rslt_t cy_rtos_get_mutex(cy_mutex_t *mutex, cy_time_t timeout_ms)
{
cy_rslt_t status;
cy_rtos_error_t statusInternal;
if (mutex == NULL)
status = CY_RTOS_BAD_PARAM;
else
{
statusInternal = osMutexAcquire(*mutex, timeout_ms);
status = error_converter(statusInternal);
}
return status;
}
cy_rslt_t cy_rtos_set_mutex(cy_mutex_t *mutex)
{
cy_rslt_t status;
cy_rtos_error_t statusInternal;
if (mutex == NULL)
status = CY_RTOS_BAD_PARAM;
else
{
statusInternal = osMutexRelease(*mutex);
status = error_converter(statusInternal);
}
return status;
}
cy_rslt_t cy_rtos_deinit_mutex(cy_mutex_t *mutex)
{
cy_rslt_t status;
cy_rtos_error_t statusInternal;
if (mutex == NULL)
status = CY_RTOS_BAD_PARAM;
else
{
statusInternal = osMutexDelete(*mutex);
status = error_converter(statusInternal);
if (status == CY_RSLT_SUCCESS)
{
free(*mutex);
*mutex = NULL;
}
}
return status;
}
/******************************************************
* Semaphores
******************************************************/
cy_rslt_t cy_rtos_init_semaphore(cy_semaphore_t *semaphore, uint32_t maxcount, uint32_t initcount)
{
cy_rslt_t status;
osSemaphoreAttr_t attr;
if (semaphore == NULL)
status = CY_RTOS_BAD_PARAM;
else
{
attr.name = NULL;
attr.attr_bits = 0U;
attr.cb_mem = malloc(osRtxSemaphoreCbSize);
attr.cb_size = osRtxSemaphoreCbSize;
if (attr.cb_mem == NULL)
status = CY_RTOS_NO_MEMORY;
else
{
CY_ASSERT(((uint32_t)attr.cb_mem & CY_RTOS_ALIGNMENT_MASK) == 0UL);
*semaphore = osSemaphoreNew(maxcount, initcount, &attr);
CY_ASSERT((*semaphore == attr.cb_mem) || (*semaphore == NULL));
status = (*semaphore == NULL) ? CY_RTOS_GENERAL_ERROR : CY_RSLT_SUCCESS;
}
}
return status;
}
cy_rslt_t cy_rtos_get_semaphore(cy_semaphore_t *semaphore, cy_time_t timeout_ms, bool in_isr)
{
cy_rslt_t status = CY_RSLT_SUCCESS;
cy_rtos_error_t statusInternal;
if (semaphore == NULL)
status = CY_RTOS_BAD_PARAM;
else
{
/* Not allowed to be called in ISR if timeout != 0 */
if ((!in_isr) || (in_isr && (timeout_ms == 0U)))
statusInternal = osSemaphoreAcquire(*semaphore, timeout_ms);
else
statusInternal = osErrorISR;
status = error_converter(statusInternal);
}
return status;
}
cy_rslt_t cy_rtos_set_semaphore(cy_semaphore_t *semaphore, bool in_isr)
{
cy_rslt_t status = CY_RSLT_SUCCESS;
cy_rtos_error_t statusInternal;
(void)in_isr; // Unused parameter in this implementation
if (semaphore == NULL)
status = CY_RTOS_BAD_PARAM;
else
{
statusInternal = osSemaphoreRelease(*semaphore);
status = error_converter(statusInternal);
}
return status;
}
cy_rslt_t cy_rtos_get_count_semaphore(cy_semaphore_t *semaphore, size_t *count)
{
cy_rslt_t status;
if (semaphore == NULL || count == NULL)
status = CY_RTOS_BAD_PARAM;
else
{
*count = osSemaphoreGetCount(*semaphore);
status = CY_RSLT_SUCCESS;
}
return status;
}
cy_rslt_t cy_rtos_deinit_semaphore(cy_semaphore_t *semaphore)
{
cy_rslt_t status;
cy_rtos_error_t statusInternal;
if (semaphore == NULL)
status = CY_RTOS_BAD_PARAM;
else
{
statusInternal = osSemaphoreDelete(*semaphore);
status = error_converter(statusInternal);
if (status == CY_RSLT_SUCCESS)
{
free(*semaphore);
*semaphore = NULL;
}
}
return status;
}
/******************************************************
* Events
******************************************************/
#define CY_RTOS_EVENT_ERRORFLAG 0x80000000UL
#define CY_RTOS_EVENT_FLAGS 0x7FFFFFFFUL
cy_rslt_t cy_rtos_init_event(cy_event_t *event)
{
cy_rslt_t status;
osEventFlagsAttr_t attr;
if (event == NULL)
status = CY_RTOS_BAD_PARAM;
else
{
attr.name = NULL;
attr.attr_bits = 0U;
attr.cb_mem = malloc(osRtxEventFlagsCbSize);
attr.cb_size = osRtxEventFlagsCbSize;
if (attr.cb_mem == NULL)
status = CY_RTOS_NO_MEMORY;
else
{
CY_ASSERT(((uint32_t)attr.cb_mem & CY_RTOS_ALIGNMENT_MASK) == 0UL);
*event = osEventFlagsNew(&attr);
CY_ASSERT((*event == attr.cb_mem) || (*event == NULL));
status = (*event == NULL) ? CY_RTOS_GENERAL_ERROR : CY_RSLT_SUCCESS;
}
}
return status;
}
cy_rslt_t cy_rtos_setbits_event(cy_event_t *event, uint32_t bits, bool in_isr)
{
cy_rslt_t status = CY_RSLT_SUCCESS;
cy_rtos_error_t statusInternal;
(void)in_isr; // Unused parameter in this implementation
if (event == NULL)
status = CY_RTOS_BAD_PARAM;
else
{
statusInternal = (osStatus_t)osEventFlagsSet(*event, bits);
if ((statusInternal & CY_RTOS_EVENT_ERRORFLAG) != 0UL)
status = error_converter(statusInternal);
}
return status;
}
cy_rslt_t cy_rtos_clearbits_event(cy_event_t *event, uint32_t bits, bool in_isr)
{
cy_rslt_t status = CY_RSLT_SUCCESS;
cy_rtos_error_t statusInternal;
(void)in_isr; // Unused parameter in this implementation
if (event == NULL)
status = CY_RTOS_BAD_PARAM;
else
{
statusInternal = (osStatus_t)osEventFlagsClear(*event, bits);
if ((statusInternal & CY_RTOS_EVENT_ERRORFLAG) != 0UL)
status = error_converter(statusInternal);
}
return status;
}
cy_rslt_t cy_rtos_getbits_event(cy_event_t *event, uint32_t *bits)
{
cy_rslt_t status = CY_RSLT_SUCCESS;
if ((event == NULL) || (bits == NULL))
status = CY_RTOS_BAD_PARAM;
else
*bits = osEventFlagsGet(*event);
return status;
}
cy_rslt_t cy_rtos_waitbits_event(cy_event_t *event, uint32_t *bits, bool clear, bool all, cy_time_t timeout)
{
cy_rslt_t status = CY_RSLT_SUCCESS;
cy_rtos_error_t statusInternal;
uint32_t flagOption;
if ((event == NULL) || (bits == NULL))
status = CY_RTOS_BAD_PARAM;
else
{
flagOption = (all) ? osFlagsWaitAll : osFlagsWaitAny;
if (!clear)
flagOption |= osFlagsNoClear;
statusInternal = (osStatus_t)osEventFlagsWait(*event, *bits, flagOption, timeout);
if ((statusInternal & CY_RTOS_EVENT_ERRORFLAG) == 0UL)
*bits = statusInternal;
else
status = error_converter(statusInternal);
}
return status;
}
cy_rslt_t cy_rtos_deinit_event(cy_event_t *event)
{
cy_rslt_t status;
cy_rtos_error_t statusInternal;
if (event == NULL)
status = CY_RTOS_BAD_PARAM;
else
{
statusInternal = osEventFlagsDelete(*event);
status = error_converter(statusInternal);
if (status == CY_RSLT_SUCCESS)
{
free(*event);
*event = NULL;
}
}
return status;
}
/******************************************************
* Queues
******************************************************/
cy_rslt_t cy_rtos_init_queue(cy_queue_t *queue, size_t length, size_t itemsize)
{
cy_rslt_t status;
osMessageQueueAttr_t attr;
if (queue == NULL)
status = CY_RTOS_BAD_PARAM;
else
{
attr.name = NULL;
attr.attr_bits = 0U;
attr.cb_size = osRtxMessageQueueCbSize;
uint32_t blockSize = ((itemsize + 3U) & ~3UL) + sizeof(osRtxMessage_t);
attr.mq_size = blockSize * length;
/* Note: 1 malloc for both so that they can be freed with 1 call */
uint32_t cb_mem_pad = (8 - (osRtxMessageQueueCbSize & 0x07)) & 0x07;
attr.cb_mem = malloc(osRtxMessageQueueCbSize + cb_mem_pad + attr.mq_size);
if (attr.cb_mem != NULL)
attr.mq_mem = (uint32_t *)((uint32_t)attr.cb_mem + osRtxMessageQueueCbSize + cb_mem_pad);
if (attr.cb_mem == NULL)
status = CY_RTOS_NO_MEMORY;
else
{
CY_ASSERT(((uint32_t)attr.cb_mem & CY_RTOS_ALIGNMENT_MASK) == 0UL);
CY_ASSERT(((uint32_t)attr.mq_mem & CY_RTOS_ALIGNMENT_MASK) == 0UL);
*queue = osMessageQueueNew(length, itemsize, &attr);
CY_ASSERT((*queue == attr.cb_mem) || (*queue == NULL));
status = (*queue == NULL) ? CY_RTOS_GENERAL_ERROR : CY_RSLT_SUCCESS;
}
}
return status;
}
cy_rslt_t cy_rtos_put_queue(cy_queue_t *queue, const void *item_ptr, cy_time_t timeout_ms, bool in_isr)
{
cy_rslt_t status;
cy_rtos_error_t statusInternal;
if ((queue == NULL) || (item_ptr == NULL))
status = CY_RTOS_BAD_PARAM;
else
{
/* Not allowed to be called in ISR if timeout != 0 */
if ((!in_isr) || (in_isr && (timeout_ms == 0U)))
statusInternal = osMessageQueuePut(*queue, (uint8_t *)item_ptr, 0u, timeout_ms);
else
statusInternal = osErrorISR;
status = error_converter(statusInternal);
}
return status;
}
cy_rslt_t cy_rtos_get_queue(cy_queue_t *queue, void *item_ptr, cy_time_t timeout_ms, bool in_isr)
{
cy_rslt_t status;
cy_rtos_error_t statusInternal;
if ((queue == NULL) || (item_ptr == NULL))
status = CY_RTOS_BAD_PARAM;
else
{
/* Not allowed to be called in ISR if timeout != 0 */
if ((!in_isr) || (in_isr && (timeout_ms == 0U)))
statusInternal = osMessageQueueGet(*queue, (uint8_t *)item_ptr, 0u, timeout_ms);
else
statusInternal = osErrorISR;
status = error_converter(statusInternal);
}
return status;
}
cy_rslt_t cy_rtos_count_queue(cy_queue_t *queue, size_t *num_waiting)
{
cy_rslt_t status = CY_RSLT_SUCCESS;
if ((queue == NULL) || (num_waiting == NULL))
status = CY_RTOS_BAD_PARAM;
else
*num_waiting = osMessageQueueGetCount(*queue);
return status;
}
cy_rslt_t cy_rtos_space_queue(cy_queue_t *queue, size_t *num_spaces)
{
cy_rslt_t status = CY_RSLT_SUCCESS;
if ((queue == NULL) || (num_spaces == NULL))
status = CY_RTOS_BAD_PARAM;
else
*num_spaces = osMessageQueueGetSpace(*queue);
return status;
}
cy_rslt_t cy_rtos_reset_queue(cy_queue_t *queue)
{
cy_rslt_t status;
cy_rtos_error_t statusInternal;
if (queue == NULL)
status = CY_RTOS_BAD_PARAM;
else
{
statusInternal = osMessageQueueReset(*queue);
status = error_converter(statusInternal);
}
return status;
}
cy_rslt_t cy_rtos_deinit_queue(cy_queue_t *queue)
{
cy_rslt_t status;
cy_rtos_error_t statusInternal;
if (queue == NULL)
status = CY_RTOS_BAD_PARAM;
else
{
statusInternal = osMessageQueueDelete(*queue);
status = error_converter(statusInternal);
if (status == CY_RSLT_SUCCESS)
{
free(*queue);
*queue = NULL;
}
}
return status;
}
/******************************************************
* Timers
******************************************************/
cy_rslt_t cy_rtos_init_timer(cy_timer_t *timer, cy_timer_trigger_type_t type,
cy_timer_callback_t fun, cy_timer_callback_arg_t arg)
{
cy_rslt_t status;
osTimerAttr_t attr;
if (timer == NULL)
status = CY_RTOS_BAD_PARAM;
else
{
attr.name = NULL;
attr.attr_bits = 0U;
attr.cb_mem = malloc(osRtxTimerCbSize);
attr.cb_size = osRtxTimerCbSize;
if (attr.cb_mem == NULL)
status = CY_RTOS_NO_MEMORY;
else
{
osTimerType_t osTriggerType = (CY_TIMER_TYPE_PERIODIC == type)
? osTimerPeriodic
: osTimerOnce;
CY_ASSERT(((uint32_t)attr.cb_mem & CY_RTOS_ALIGNMENT_MASK) == 0UL);
*timer = osTimerNew( (osTimerFunc_t)fun, osTriggerType, (void *)arg, &attr );
CY_ASSERT((*timer == attr.cb_mem) || (*timer == NULL));
status = (*timer == NULL) ? CY_RTOS_GENERAL_ERROR : CY_RSLT_SUCCESS;
}
}
return status;
}
cy_rslt_t cy_rtos_start_timer(cy_timer_t *timer, cy_time_t num_ms)
{
cy_rslt_t status;
cy_rtos_error_t statusInternal;
if (timer == NULL)
status = CY_RTOS_BAD_PARAM;
else
{
/* Get Number of ticks per second */
uint32_t tick_freq = osKernelGetTickFreq();
/* Convert ticks count to time in milliseconds */
if (tick_freq != 0)
{
uint32_t ticks = ((num_ms * tick_freq) / 1000);
statusInternal = osTimerStart(*timer, ticks);
status = error_converter(statusInternal);
}
else
status = CY_RTOS_GENERAL_ERROR;
}
return status;
}
cy_rslt_t cy_rtos_stop_timer(cy_timer_t *timer)
{
cy_rslt_t status;
cy_rtos_error_t statusInternal;
if (timer == NULL)
status = CY_RTOS_BAD_PARAM;
else
{
statusInternal = osTimerStop(*timer);
status = error_converter(statusInternal);
}
return status;
}
cy_rslt_t cy_rtos_is_running_timer(cy_timer_t *timer, bool *state)
{
cy_rslt_t status = CY_RSLT_SUCCESS;
if ((timer == NULL) || (state == NULL))
status = CY_RTOS_BAD_PARAM;
else
*state = osTimerIsRunning(*timer);
return status;
}
cy_rslt_t cy_rtos_deinit_timer(cy_timer_t *timer)
{
cy_rslt_t status;
cy_rtos_error_t statusInternal;
if (timer == NULL)
status = CY_RTOS_BAD_PARAM;
else
{
statusInternal = osTimerDelete(*timer);
status = error_converter(statusInternal);
if (status == CY_RSLT_SUCCESS)
{
free(*timer);
*timer = NULL;
}
}
return status;
}
/******************************************************
* Time
******************************************************/
cy_rslt_t cy_rtos_get_time(cy_time_t *tval)
{
cy_rslt_t status = CY_RSLT_SUCCESS;
uint32_t tick_freq;
if (tval == NULL)
status = CY_RTOS_BAD_PARAM;
else
{
/* Get Number of ticks per second */
tick_freq = osKernelGetTickFreq();
/* Convert ticks count to time in milliseconds */
if (tick_freq != 0)
*tval = (cy_time_t)((osKernelGetTickCount() * 1000LL) / tick_freq);
else
status = CY_RTOS_GENERAL_ERROR;
}
return status;
}
cy_rslt_t cy_rtos_delay_milliseconds(cy_time_t num_ms)
{
cy_rslt_t status;
cy_rtos_error_t statusInternal;
statusInternal = osDelay(num_ms);
status = error_converter(statusInternal);
return status;
}
#if defined(__cplusplus)
}
#endif

View File

@ -0,0 +1,247 @@
/***************************************************************************//**
* \file cyhal_gpio.h
*
* \brief
* Provides a high level interface for interacting with the GPIO on Cypress devices.
* This interface abstracts out the chip specific details. If any chip specific
* functionality is necessary, or performance is critical the low level functions
* can be used directly.
*
********************************************************************************
* \copyright
* Copyright 2018-2020 Cypress Semiconductor Corporation
* 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
*
* 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.
*******************************************************************************/
/**
* \addtogroup group_hal_gpio GPIO (General Purpose Input Output)
* \ingroup group_hal
* \{
* High level interface for configuring and interacting with general purpose input/outputs (GPIO).
*
* The GPIO driver provides functions to configure and initialize GPIO, and to read and write data to the pin.
* The driver also supports interrupt generation on GPIO signals with rising, falling or both edges.
*
* \note The APIs in this driver need not be used if a GPIO is to be used as an input or output of peripherals like I2C or PWM.
* The respective peripheral's driver will utilize the GPIO interface to configure and initialize its GPIO pins.
*
* \section subsection_gpio_features Features
* * Configurable GPIO pin direction - \ref cyhal_gpio_direction_t
* * Configurable GPIO pin drive modes - \ref cyhal_gpio_drive_mode_t
* * Configurable analog and digital characteristics
* * Configurable edge-triggered interrupts and callback assignment on GPIO events - \ref cyhal_gpio_event_t
*
* \section subsection_gpio_quickstart Quick Start
* \ref cyhal_gpio_init can be used for a simple GPIO initialization by providing the pin number (<b>pin</b>), pin direction (<b>direction</b>),
* pin drive mode (<b>drive_mode</b>) and the initial value on the pin (<b>init_val</b>).
*
* \section subsection_gpio_sample_snippets Code Snippets
*
* \subsection subsection_gpio_snippet_1 Snippet 1: Reading value from GPIO
* The following snippet initializes GPIO pin \ref P0_0 as an input with high impedance digital drive mode and initial value = <b>false</b> (low). A value is read
* from the pin and stored to a uint8_t variable (<b>read_val</b>).
* \snippet gpio.c snippet_cyhal_gpio_read
* \subsection subsection_gpio_snippet_2 Snippet 2: Writing value to a GPIO
* The following snippet initializes GPIO pin \ref P0_0 as an output pin with strong drive mode and initial value = <b>false</b> (low).
* A value = <b>true</b> (high) is written to the output driver.
* \snippet gpio.c snippet_cyhal_gpio_write
* \subsection subsection_gpio_snippet_3 Snippet 3: Reconfiguring a GPIO
* The following snippet shows how to reconfigure a GPIO pin during run-time using the firmware. The GPIO pin \ref P0_0
* is first initialized as an output pin with strong drive mode. The pin is then reconfigured as an input with high impedance digital drive mode.
* \note \ref cyhal_gpio_configure only changes the <b>direction</b> and the <b>drive_mode</b>
* of the pin. Previously set pin value is retained.
*
* \snippet gpio.c snippet_cyhal_gpio_reconfigure
* \subsection subsection_gpio_snippet_4 Snippet 4: Interrupts on GPIO events
* GPIO events can be mapped to an interrupt and assigned to a callback function. The callback function needs to be first registered and
* then the event needs to be enabled.
** The following snippet initializes GPIO pin \ref P0_0 as an input pin. It registers a callback function and enables detection
* of a falling edge event to trigger the callback.
* \note If no argument needs to be passed to the callback function then a NULL can be passed during registering. <br>
*
* \snippet gpio.c snippet_cyhal_gpio_interrupt
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include "cy_result.h"
#include "cyhal_hw_types.h"
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
/*******************************************************************************
* Defines
*******************************************************************************/
/** Integer representation of no connect pin (required to exist in all BSPs) */
#define CYHAL_NC_PIN_VALUE (NC)
/*******************************************************************************
* Enumerations
*******************************************************************************/
/** Pin events */
typedef enum {
CYHAL_GPIO_IRQ_NONE = 0, /**< No interrupt */
CYHAL_GPIO_IRQ_RISE = 1 << 0, /**< Interrupt on rising edge */
CYHAL_GPIO_IRQ_FALL = 1 << 1, /**< Interrupt on falling edge */
CYHAL_GPIO_IRQ_BOTH = (CYHAL_GPIO_IRQ_RISE | CYHAL_GPIO_IRQ_FALL), /**< Interrupt on both rising and falling edges */
} cyhal_gpio_event_t;
/** Pin direction */
typedef enum {
CYHAL_GPIO_DIR_INPUT, /**< Input pin */
CYHAL_GPIO_DIR_OUTPUT, /**< Output pin */
CYHAL_GPIO_DIR_BIDIRECTIONAL, /**< Input and output pin */
} cyhal_gpio_direction_t;
/** Pin drive mode */
/** \note When the <b> drive_mode </b> of the <b> pin </b> is set to <b> CYHAL_GPIO_DRIVE_PULL_NONE </b>,
* it is set to <b> CYHAL_GPIO_DRIVE_STRONG </b> if the <b> direction </b>
* of the <b> pin </b> is <b> CYHAL_GPIO_DIR_OUTPUT </b> or <b> CYHAL_GPIO_DIR_BIDIRECTIONAL</b>.
* If not, the <b> drive_mode </b> of the <b> pin </b> is set to <b> CYHAL_GPIO_DRIVE_NONE</b>.
*/
typedef enum {
CYHAL_GPIO_DRIVE_NONE, /**< Digital Hi-Z. Input only. Input init value(s): 0 or 1 */
CYHAL_GPIO_DRIVE_ANALOG, /**< Analog Hi-Z. Use only for analog purpose */
CYHAL_GPIO_DRIVE_PULLUP, /**< Pull-up resistor. Input and output. Input init value(s): 1, output value(s): 0 */
CYHAL_GPIO_DRIVE_PULLDOWN, /**< Pull-down resistor. Input and output. Input init value(s): 0, output value(s): 1 */
CYHAL_GPIO_DRIVE_OPENDRAINDRIVESLOW, /**< Open-drain, Drives Low. Input and output. Input init value(s): 1, output value(s): 0 */
CYHAL_GPIO_DRIVE_OPENDRAINDRIVESHIGH, /**< Open-drain, Drives High. Input and output. Input init value(s): 0, output value(s): 1 */
CYHAL_GPIO_DRIVE_STRONG, /**< Strong output. Output only. Output init value(s): 0 or 1 */
CYHAL_GPIO_DRIVE_PULLUPDOWN, /**< Pull-up and pull-down resistors. Input and output. Input init value(s): 0 or 1, output value(s): 0 or 1 */
CYHAL_GPIO_DRIVE_PULL_NONE, /**< No Pull-up or pull-down resistors. Input and output. Input init value(s): 0 or 1, output value(s): 0 or 1 */
} cyhal_gpio_drive_mode_t;
/** GPIO callback function type */
typedef void (*cyhal_gpio_event_callback_t)(void *callback_arg, cyhal_gpio_event_t event);
/*******************************************************************************
* Functions
*******************************************************************************/
/** Initialize the GPIO pin <br>
* See \ref subsection_gpio_snippet_1.
*
* @param[in] pin The GPIO pin to initialize
* @param[in] direction The pin direction
* @param[in] drive_mode The pin drive mode
* @param[in] init_val Initial value on the pin
*
* @return The status of the init request
*
* Guidance for using gpio drive modes ( \ref cyhal_gpio_drive_mode_t for details).
* For default use drive modes:
* Input GPIO direction - \ref CYHAL_GPIO_DRIVE_NONE
* Output GPIO direction - \ref CYHAL_GPIO_DRIVE_STRONG
* Bidirectional GPIO - \ref CYHAL_GPIO_DRIVE_PULLUPDOWN
* \warning Don't use \ref CYHAL_GPIO_DRIVE_STRONG for input GPIO direction. It may cause an overcurrent issue.
*/
cy_rslt_t cyhal_gpio_init(cyhal_gpio_t pin, cyhal_gpio_direction_t direction, cyhal_gpio_drive_mode_t drive_mode, bool init_val);
/** Uninitialize the gpio peripheral and the cyhal_gpio_t object
*
* @param[in] pin Pin number
*/
void cyhal_gpio_free(cyhal_gpio_t pin);
/** Configure the GPIO pin <br>
* See \ref subsection_gpio_snippet_3.
*
* @param[in] pin The GPIO pin
* @param[in] direction The pin direction
* @param[in] drive_mode The pin drive mode
*
* @return The status of the configure request
*/
cy_rslt_t cyhal_gpio_configure(cyhal_gpio_t pin, cyhal_gpio_direction_t direction, cyhal_gpio_drive_mode_t drive_mode);
/** Set the output value for the pin. This only works for output & in_out pins. <br>
* See \ref subsection_gpio_snippet_2.
*
* @param[in] pin The GPIO object
* @param[in] value The value to be set (high = true, low = false)
*/
void cyhal_gpio_write(cyhal_gpio_t pin, bool value);
/** Read the input value. This only works for \ref CYHAL_GPIO_DIR_INPUT & \ref CYHAL_GPIO_DIR_BIDIRECTIONAL pins. <br>
* See \ref subsection_gpio_snippet_1.
*
* @param[in] pin The GPIO object
* @return The value of the IO (true = high, false = low)
*/
bool cyhal_gpio_read(cyhal_gpio_t pin);
/** Toggle the output value <br>
* See \ref subsection_gpio_snippet_4.
* @param[in] pin The GPIO object
*/
void cyhal_gpio_toggle(cyhal_gpio_t pin);
/** Register/clear a callback handler for pin events <br>
*
* This function will be called when one of the events enabled by \ref cyhal_gpio_enable_event occurs.
*
* See \ref subsection_gpio_snippet_4.
*
* @param[in] pin The pin number
* @param[in] callback The function to call when the specified event happens. Pass NULL to unregister the handler.
* @param[in] callback_arg Generic argument that will be provided to the callback when called, can be NULL
*/
void cyhal_gpio_register_callback(cyhal_gpio_t pin, cyhal_gpio_event_callback_t callback, void *callback_arg);
/** Enable or Disable the specified GPIO event <br>
*
* When an enabled event occurs, the function specified by \ref cyhal_gpio_register_callback will be called.
*
* See \ref subsection_gpio_snippet_4.
*
* @param[in] pin The GPIO object
* @param[in] event The GPIO event
* @param[in] intr_priority The priority for NVIC interrupt events
* @param[in] enable True to turn on interrupts, False to turn off
*/
void cyhal_gpio_enable_event(cyhal_gpio_t pin, cyhal_gpio_event_t event, uint8_t intr_priority, bool enable);
/*******************************************************************************
* Backward compatibility macro. The following code is DEPRECATED and must
* not be used in new projects
*******************************************************************************/
/** \cond INTERNAL */
#define cyhal_gpio_register_irq(pin, priority, handler, handler_arg) cyhal_gpio_register_callback(pin, handler, handler_arg)
#define cyhal_gpio_irq_enable(pin, event, enable) cyhal_gpio_enable_event(pin, event, CYHAL_ISR_PRIORITY_DEFAULT, enable)
typedef cyhal_gpio_event_t cyhal_gpio_irq_event_t;
/** \endcond */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#ifdef CYHAL_GPIO_IMPL_HEADER
#include CYHAL_GPIO_IMPL_HEADER
#endif /* CYHAL_GPIO_IMPL_HEADER */
/** \} group_hal_gpio */

View File

@ -0,0 +1,366 @@
/***************************************************************************//**
* \file cyhal_sdio.h
*
* \brief
* Provides a high level interface for interacting with the Cypress SDIO interface.
* This interface abstracts out the chip specific details. If any chip specific
* functionality is necessary, or performance is critical the low level functions
* can be used directly.
*
********************************************************************************
* \copyright
* Copyright 2018-2020 Cypress Semiconductor Corporation
* 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
*
* 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.
*******************************************************************************/
/**
* \addtogroup group_hal_sdio SDIO (Secure Digital Input Output)
* \ingroup group_hal
* \{
* High level interface to the Secure Digital Input Output (SDIO).
*
* This driver allows commands to be sent over the SDIO bus; the supported commands
* can be found in \ref cyhal_sdio_command_t. Bulk data transfer is also supported
* via cyhal_sdio_bulk_transfer().
*
* The SDIO protocol is an extension of the SD
* interface for general I/O functions. Refer to the SD Specifications Part 1 SDIO
* Specifications Version 4.10 for more information on the SDIO protocol and specifications.
*
*
* \section subsection_sdio_features Features
* * Supports 4-bit interface
* * Supports Ultra High Speed (UHS-I) mode
* * Supports Default Speed (DS), High Speed (HS), SDR12, SDR25 and SDR50 speed modes
* * Supports SDIO card interrupts in both 1-bit and 4-bit modes
* * Supports Standard capacity (SDSC), High capacity (SDHC) and Extended capacity (SDXC) memory
*
* \section subsection_sdio_quickstart Quick Start
*
* \ref cyhal_sdio_init initializes the SDIO peripheral and passes a pointer to the SDIO block through the **obj** object of type \ref cyhal_sdio_t.
*
* \section subsection_sdio_code_snippets Code Snippets
*
* \subsection subsection_sdio_use_case_1 Snippet1: Simple SDIO Initialization example
* The following snippet shows how to initialize the SDIO interface with a pre-defined configuration
*
* \snippet sdio.c snippet_cyhal_sdio_simple_init
*
* \subsection subsection_sdio_use_case_2 Snippet2: Configure Interrupt
* The following snippet shows how to configure an interrupt and handle specific events. Refer \ref cyhal_sdio_event_t for different types of events.
*
* \snippet sdio.c snippet_cyhal_sdio_interrupt_callback
*
* \subsection subsection_sdio_use_case_3 Snippet3: Sending Commands
* The following snippet shows how to send a particular command. Some steps of the card initialization have been provided for reference. Refer \ref cyhal_sdio_command_t for different commands.
*
* \snippet sdio.c snippet_cyhal_sdio_send_command
*
* \subsection subsection_sdio_use_case_4 Snippet4: Bulk Data Transfer
* The following snippet shows how to start a bulk data transfer.
*
* \snippet sdio.c snippet_cyhal_sdio_bulk_transfer
*
* \subsection subsection_sdio_use_case_5 Snippet5: Async Data Transfer
*
* The following snippet shows how to start an async data transfer.
* \snippet sdio.c snippet_cyhal_sdio_async_transfer
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include "cy_result.h"
#include "cyhal_hw_types.h"
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* Defines
*******************************************************************************/
#define CYHAL_SDIO_RET_NO_ERRORS (0x00) /**< No error*/
#define CYHAL_SDIO_RET_NO_SP_ERRORS (0x01) /**< Non-specific error code*/
#define CYHAL_SDIO_RET_CMD_CRC_ERROR (0x02) /**< There was a CRC error on the Command/Response*/
#define CYHAL_SDIO_RET_CMD_IDX_ERROR (0x04) /**< The index for the command didn't match*/
#define CYHAL_SDIO_RET_CMD_EB_ERROR (0x08) /**< There was an end bit error on the command*/
#define CYHAL_SDIO_RET_DAT_CRC_ERROR (0x10) /**< There was a data CRC Error*/
#define CYHAL_SDIO_RET_CMD_TIMEOUT (0x20) /**< The command didn't finish before the timeout period was over*/
#define CYHAL_SDIO_RET_DAT_TIMEOUT (0x40) /**< The data didn't finish before the timeout period was over*/
#define CYHAL_SDIO_RET_RESP_FLAG_ERROR (0x80) /**< There was an error in the resposne flag for command 53*/
#define CYHAL_SDIO_CLOCK_ERROR (0x100) /**< Failed to initial clock for SDIO */
#define CYHAL_SDIO_BAD_ARGUMENT (0x200) /**< Bad argument passed for SDIO */
#define CYHAL_SDIO_SEMA_NOT_INITED (0x400) /**< Semaphore is not initiated */
#define CYHAL_SDIO_FUNC_NOT_SUPPORTED (0x800) /**< Function is not supported */
#define CYHAL_SDIO_CANCELED (0x1000) /**< Operation canceled */
#define CYHAL_SDIO_PM_PENDING_ERROR (0x2000) /**< Transfer cannot be initiated after power mode transition allowed.*/
/* HAL return value defines */
/** \addtogroup group_hal_results_sdio SDIO HAL Results
* SDIO specific return codes
* \ingroup group_hal_results
* \{ *//**
*/
/** Incorrect parameter value define */
#define CYHAL_SDIO_RSLT_ERR_BAD_PARAM \
(CYHAL_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SDIO, CYHAL_SDIO_BAD_ARGUMENT))
/** Clock initialization error define */
#define CYHAL_SDIO_RSLT_ERR_CLOCK \
(CYHAL_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SDIO, CYHAL_SDIO_CLOCK_ERROR))
/** Semaphore not initiated error define */
#define CYHAL_SDIO_RSLT_ERR_SEMA_NOT_INITED \
(CYHAL_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SDIO, CYHAL_SDIO_SEMA_NOT_INITED))
/** Error define based on SDIO lower function return value */
#define CYHAL_SDIO_RSLT_ERR_FUNC_RET(retVal) \
(CYHAL_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SDIO, ((uint16_t)retVal)))
/** Define to indicate canceled operation */
#define CYHAL_SDIO_RSLT_CANCELED \
(CYHAL_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SDIO, CYHAL_SDIO_CANCELED))
/** Transfers are not allowed after the SDIO block has allowed power mode transition. */
#define CYHAL_SDIO_RSLT_ERR_PM_PENDING \
(CYHAL_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SDIO, CYHAL_SDIO_PM_PENDING_ERROR))
/**
* \}
*/
/*******************************************************************************
* Enumerations
*******************************************************************************/
/** Commands that can be issued */
typedef enum
{
CYHAL_SDIO_CMD_GO_IDLE_STATE = 0, //!< Go to idle state
CYHAL_SDIO_CMD_SEND_RELATIVE_ADDR = 3, //!< Send a relative address
CYHAL_SDIO_CMD_IO_SEND_OP_COND = 5, //!< Send an OP IO
CYHAL_SDIO_CMD_SELECT_CARD = 7, //!< Send a card select
CYHAL_SDIO_CMD_GO_INACTIVE_STATE = 15, //!< Go to inactive state
CYHAL_SDIO_CMD_IO_RW_DIRECT = 52, //!< Perform a direct read/write
CYHAL_SDIO_CMD_IO_RW_EXTENDED = 53, //!< Perform an extended read/write
} cyhal_sdio_command_t;
/** Types of transfer that can be performed */
typedef enum
{
CYHAL_READ, //!< Read from the card
CYHAL_WRITE //!< Write to the card
} cyhal_transfer_t;
/** Types of events that could be asserted by SDIO */
typedef enum {
/* Interrupt-based thread events */
CYHAL_SDIO_CMD_COMPLETE = 0x00001, //!< Command Complete
CYHAL_SDIO_XFER_COMPLETE = 0x00002, //!< Host read/write transfer is complete
CYHAL_SDIO_BGAP_EVENT = 0x00004, //!< This bit is set when both read/write transaction is stopped
CYHAL_SDIO_DMA_INTERRUPT = 0x00008, //!< Host controller detects an SDMA Buffer Boundary during transfer
CYHAL_SDIO_BUF_WR_READY = 0x00010, //!< This bit is set if the Buffer Write Enable changes from 0 to 1
CYHAL_SDIO_BUF_RD_READY = 0x00020, //!< This bit is set if the Buffer Read Enable changes from 0 to 1
CYHAL_SDIO_CARD_INSERTION = 0x00040, //!< This bit is set if the Card Inserted in the Present State
CYHAL_SDIO_CARD_REMOVAL = 0x00080, //!< This bit is set if the Card Inserted in the Present State
CYHAL_SDIO_CARD_INTERRUPT = 0x00100, //!< The synchronized value of the DAT[1] interrupt input for SD mode
CYHAL_SDIO_INT_A = 0x00200, //!< Reserved: set to 0
CYHAL_SDIO_INT_B = 0x00400, //!< Reserved: set to 0
CYHAL_SDIO_INT_C = 0x00800, //!< Reserved: set to 0
CYHAL_SDIO_RE_TUNE_EVENT = 0x01000, //!< Reserved: set to 0
CYHAL_SDIO_FX_EVENT = 0x02000, //!< This status is set when R[14] of response register is set to 1
CYHAL_SDIO_CQE_EVENT = 0x04000, //!< This status is set if Command Queuing/Crypto event has occurred
CYHAL_SDIO_ERR_INTERRUPT = 0x08000, //!< If any of the bits in the Error Interrupt Status register are set
/* Non-interrupt-based thread events */
CYHAL_SDIO_GOING_DOWN = 0x10000, //!< The interface is going away (eg: powering down for some period of time)
CYHAL_SDIO_COMING_UP = 0x20000, //!< The interface is back up (eg: came back from a low power state)
CYHAL_SDIO_ALL_INTERRUPTS = 0x0E1FF, //!< Is used to enable/disable all interrupts events
} cyhal_sdio_event_t;
/*******************************************************************************
* Data Structures
*******************************************************************************/
/** @brief SDIO controller initial configuration */
typedef struct
{
uint32_t frequencyhal_hz; //!< Clock frequency, in hertz
uint16_t block_size; //!< Block size
} cyhal_sdio_cfg_t;
/** Callback for SDIO events */
typedef void (*cyhal_sdio_event_callback_t)(void *callback_arg, cyhal_sdio_event_t event);
/*******************************************************************************
* Data Structures
*******************************************************************************/
/** Initialize the SDIO peripheral
*
* @param[out] obj Pointer to an SDIO object.
* The caller must allocate the memory for this object but the init
* function will initialize its contents.
* @param[out] clk The pin connected to the clk signal
* @param[in] cmd The pin connected to the command signal
* @param[in] data0 The pin connected to the data0 signal
* @param[in] data1 The pin connected to the data1 signal
* @param[in] data2 The pin connected to the data2 signal
* @param[in] data3 The pin connected to the data3 signal
* @return The status of the init request
*
* Returns \ref CY_RSLT_SUCCESS on successful operation. Refer \ref subsection_sdio_use_case_1 for more information.
*/
cy_rslt_t cyhal_sdio_init(cyhal_sdio_t *obj, cyhal_gpio_t cmd, cyhal_gpio_t clk, cyhal_gpio_t data0, cyhal_gpio_t data1, cyhal_gpio_t data2, cyhal_gpio_t data3);
/** Release the SDIO block.
*
* @param[in,out] obj The SDIO object
*/
void cyhal_sdio_free(cyhal_sdio_t *obj);
/** Configure the SDIO block with required parameters. Refer \ref cyhal_sdio_cfg_t for more information.
*
* @param[in,out] obj The SDIO object
* @param[in] config The SDIO configuration to apply
* @return The status of the configure request.
*
* Returns \ref CY_RSLT_SUCCESS on successful operation.
*/
cy_rslt_t cyhal_sdio_configure(cyhal_sdio_t *obj, const cyhal_sdio_cfg_t *config);
/** Sends command to the SDIO device. See \ref cyhal_sdio_command_t for list of available commands.
*
* This will block until the command is completed.
*
* @param[in,out] obj The SDIO object
* @param[in] direction The direction of transfer (read/write)
* @param[in] command The command to send to the SDIO device
* @param[in] argument The argument to the command
* @param[out] response The response from the SDIO device
* @return The status of the command transfer.
*
* Returns \ref CY_RSLT_SUCCESS on successful operation. Refer \ref subsection_sdio_use_case_3 for more information.
*/
cy_rslt_t cyhal_sdio_send_cmd(const cyhal_sdio_t *obj, cyhal_transfer_t direction, cyhal_sdio_command_t command, uint32_t argument, uint32_t* response);
/** Performs a bulk data transfer. Sends \ref CYHAL_SDIO_CMD_IO_RW_EXTENDED command (CMD=53) which allows writing and reading of a large number of I/O registers with a single command.
*
* This will block until the transfer is completed.
*
* @param[in,out] obj The SDIO object
* @param[in] direction The direction of transfer (read/write)
* @param[in] argument The argument to the command
* @param[in] data The data to send to the SDIO device. A bulk transfer is done in block
* size (default: 64 bytes) chunks for better performance. Therefore,
* the size of the data buffer passed into this function must be at least
* `length` bytes and a multiple of the block size. For example, when
* requesting to read 100 bytes of data with a block size 64 bytes, the
* data buffer needs to be at least 128 bytes. The first 100 bytes of data
* in the buffer will be the requested data.
* @param[in] length The number of bytes to send
* @param[out] response The response from the SDIO device
* @return The status of the bulk transfer operation.
*
* Returns \ref CY_RSLT_SUCCESS on successful operation. Refer \ref subsection_sdio_use_case_4 for more information.
*/
cy_rslt_t cyhal_sdio_bulk_transfer(cyhal_sdio_t *obj, cyhal_transfer_t direction, uint32_t argument, const uint32_t* data, uint16_t length, uint32_t* response);
/** Performs a bulk asynchronous data transfer by issuing the \ref CYHAL_SDIO_CMD_IO_RW_EXTENDED command(CMD=53) to the SDIO block.
* After exiting this function the \ref CYHAL_SDIO_CMD_COMPLETE and \ref CYHAL_SDIO_XFER_COMPLETE events are not asserted.
*
* To complete the asynchronous transfer, call \ref cyhal_sdio_is_busy()
* until it returns false.
* The \ref CYHAL_SDIO_CMD_COMPLETE and \ref CYHAL_SDIO_XFER_COMPLETE events are enabled
* after the asynchronous transfer is complete and in the condition they were
* enabled in before the transfer operation started. Handle these events in the interrupt callback.
*
* When the transfer is complete, the \ref CYHAL_SDIO_XFER_COMPLETE event will be raised.
* See \ref cyhal_sdio_register_callback and \ref cyhal_sdio_enable_event.
*
* @param[in,out] obj The SDIO object
* @param[in] direction The direction of transfer (read/write)
* @param[in] argument The argument to the command
* @param[in] data The data to send to the SDIO device
* @param[in] length The number of bytes to send
* @return The status of the async tranfer operation.
*
* Returns \ref CY_RSLT_SUCCESS on successful operation. Refer \ref subsection_sdio_use_case_5 for more information.
*/
cy_rslt_t cyhal_sdio_transfer_async(cyhal_sdio_t *obj, cyhal_transfer_t direction, uint32_t argument, const uint32_t* data, uint16_t length);
/** Checks if the specified SDIO is in use
*
* @param[in] obj The SDIO peripheral to check
* @return true if SDIO is in use. false, otherwise.
*/
bool cyhal_sdio_is_busy(const cyhal_sdio_t *obj);
/** Abort an SDIO transfer
*
* @param[in] obj The SDIO peripheral to stop
* @return The status of the abort_async request.
*
* Returns \ref CY_RSLT_SUCCESS on successful operation.
*/
cy_rslt_t cyhal_sdio_abort_async(const cyhal_sdio_t *obj);
/** Register an SDIO event callback to be invoked when the event is triggered.
*
* This function will be called when one of the events enabled by \ref cyhal_sdio_enable_event occurs.
*
* @param[in] obj The SDIO object
* @param[in] callback The callback function which will be invoked when the event triggers
* @param[in] callback_arg Generic argument that will be provided to the callback when executed
*
* Refer \ref subsection_sdio_use_case_2 for more implementation.
*/
void cyhal_sdio_register_callback(cyhal_sdio_t *obj, cyhal_sdio_event_callback_t callback, void *callback_arg);
/** Enables callbacks to be triggered for specified SDIO events. Refer \ref cyhal_sdio_event_t for all events.
*
* @param[in] obj The SDIO object
* @param[in] event The SDIO event type
* @param[in] intr_priority The priority for NVIC interrupt events
* @param[in] enable Set to true to enable events, or false to disable them
*
* Refer \ref subsection_sdio_use_case_2 for more information.
*/
void cyhal_sdio_enable_event(cyhal_sdio_t *obj, cyhal_sdio_event_t event, uint8_t intr_priority, bool enable);
/*******************************************************************************
* Backward compatibility macro. The following code is DEPRECATED and must
* not be used in new projects
*******************************************************************************/
/** \cond INTERNAL */
#define cyhal_sdio_register_irq cyhal_sdio_register_callback
#define cyhal_sdio_irq_enable(obj, event, enable) cyhal_sdio_enable_event(obj, event, CYHAL_ISR_PRIORITY_DEFAULT, enable)
typedef cyhal_sdio_event_t cyhal_sdio_irq_event_t;
typedef cyhal_sdio_event_callback_t cyhal_sdio_irq_handler_t;
/** \endcond */
#if defined(__cplusplus)
}
#endif
#ifdef CYHAL_SDIO_IMPL_HEADER
#include CYHAL_SDIO_IMPL_HEADER
#endif /* CYHAL_SDIO_IMPL_HEADER */
/** \} group_hal_sdio */

View File

@ -0,0 +1,383 @@
/***************************************************************************//**
* \file cyhal_spi.h
*
* \brief
* Provides a high level interface for interacting with the Cypress SPI.
* This interface abstracts out the chip specific details. If any chip specific
* functionality is necessary, or performance is critical the low level functions
* can be used directly.
*
********************************************************************************
* \copyright
* Copyright 2018-2020 Cypress Semiconductor Corporation
* 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
*
* 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.
*******************************************************************************/
/**
* \addtogroup group_hal_spi SPI (Serial Peripheral Interface)
* \ingroup group_hal
* \{
* High level interface for interacting with the Serial Peripheral Interface (SPI).
*
* The SPI protocol is a synchronous serial interface protocol. Devices operate
* in either master or slave mode. The master initiates the data transfer.
*
* Motorola SPI modes 0, 1, 2, and 3 are supported, with either MSB or LSB first.
* The operating mode and data frame size can be configured via \ref cyhal_spi_cfg_t.
*
* \section section_spi_features Features
* * Supports master and slave functionality.
* * Supports Motorola modes - 0, 1, 2 and 3 - \ref cyhal_spi_mode_t
* * MSb or LSb first shift direction - \ref cyhal_spi_mode_t
* * Master supports up to four slave select lines
* * Supports data frame size of 8 or 16 bits
* * Configurable interrupt and callback assignment on SPI events:
* Data transfer to FIFO complete, Transfer complete and Transmission error - \ref cyhal_spi_event_t
* * Supports changing baud rate of the transaction in run time.
* * Provides functions to send/receive a single byte or block of data.
*
* \section section_spi_quickstart Quick Start
*
* Initialise a SPI master or slave interface using \ref cyhal_spi_init() and provide the SPI pins (<b>mosi</b>, <b>miso</b>, <b>sclk</b>, <b>ssel</b>),
* number of bits per frame (<b>data_bits</b>) and SPI Motorola <b>mode</b>. The data rate can be set using \ref cyhal_spi_set_frequency(). <br>
* See \ref section_spi_snippets for code snippets to send or receive the data.
*
* \section section_spi_snippets Code snippets
*
* \subsection subsection_spi_snippet_1 Snippet 1: SPI Master - Single byte transfer operation (Read and Write)
* The following code snippet initializes an SPI Master interface using the \ref cyhal_spi_init(). The data rate of transfer is set using \ref cyhal_spi_set_frequency().
* The code snippet shows how to transfer a single byte of data using \ref cyhal_spi_send() and \ref cyhal_spi_recv().
* \snippet spi.c snippet_cyhal_spi_master_byte_operation
*
* \subsection subsection_spi_snippet_2 Snippet 2: SPI Slave - Single byte transfer operation (Read and Write)
* The following code snippet initializes an SPI Slave interface using the \ref cyhal_spi_init(). The data rate of transfer is set using \ref cyhal_spi_set_frequency.
* The code snippet shows how to transfer a single byte of data using \ref cyhal_spi_send() and \ref cyhal_spi_recv.
* \snippet spi.c snippet_cyhal_spi_slave_byte_operation
*
* \subsection subsection_spi_snippet_3 Snippet 3: SPI Block Data transfer
* The following snippet sends and receives an array of data in a single SPI transaction using \ref cyhal_spi_transfer(). The example
* uses SPI master to transmit 5 bytes of data and receive 5 bytes of data in a single transaction.
* \snippet spi.c snippet_cyhal_spi_block_data_transfer
*
* \subsection subsection_spi_snippet_4 Snippet 4: Interrupts on SPI events
* SPI interrupt events ( \ref cyhal_spi_event_t) can be mapped to an interrupt and assigned to a callback function.
* The callback function needs to be first registered and then the event needs to be enabled.
* The following snippet initialises a SPI master to perform a block transfer using \ref cyhal_spi_transfer_async(). This is a non-blocking function.
* A callback function is registered using \ref cyhal_spi_register_callback to notify whenever the SPI transfer is complete.
* \snippet spi.c snippet_cyhal_spi_interrupt_callback_events
* \section subsection_spi_moreinfor More Information
*
* * <a href="https://github.com/cypresssemiconductorco/mtb-example-psoc6-spi-master"><b>mtb-example-psoc6-spi-master</b></a>: This example project demonstrates
* use of SPI (HAL) resource in PSoC® 6 MCU in Master mode to write data to an SPI slave.
*
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include "cy_result.h"
#include "cyhal_hw_types.h"
#if defined(__cplusplus)
extern "C" {
#endif
/** \addtogroup group_hal_results_spi SPI HAL Results
* SPI specific return codes
* \ingroup group_hal_results
* \{ *//**
*/
/** Bad argument */
#define CYHAL_SPI_RSLT_BAD_ARGUMENT \
(CYHAL_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SPI, 0))
/** Failed to initialize SPI clock */
#define CYHAL_SPI_RSLT_CLOCK_ERROR \
(CYHAL_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SPI, 1))
/** Failed to Transfer SPI data */
#define CYHAL_SPI_RSLT_TRANSFER_ERROR \
(CYHAL_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SPI, 2))
/** Provided clock is not supported by SPI */
#define CYHAL_SPI_RSLT_CLOCK_NOT_SUPPORTED \
(CYHAL_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SPI, 3))
/** Provided PIN configuration is not supported by SPI */
#define CYHAL_SPI_RSLT_PIN_CONFIG_NOT_SUPPORTED \
(CYHAL_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SPI, 5))
/** Provided PIN configuration is not supported by SPI */
#define CYHAL_SPI_RSLT_INVALID_PIN_API_NOT_SUPPORTED \
(CYHAL_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SPI, 6))
/** The requested resource type is invalid */
#define CYHAL_SPI_RSLT_ERR_INVALID_PIN \
(CYHAL_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SPI, 7))
/** Cannot configure SSEL signal */
#define CYHAL_SPI_RSLT_ERR_CANNOT_CONFIG_SSEL \
(CYHAL_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SPI, 8))
/** Cannot switch SSEL - device is busy or incorrect pin provided */
#define CYHAL_SPI_RSLT_ERR_CANNOT_SWITCH_SSEL \
(CYHAL_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SPI, 9))
/**
* \}
*/
/** Compatibility define for cyhal_spi_set_frequency. */
#define cyhal_spi_frequency cyhal_spi_set_frequency
/** SPI interrupt triggers */
typedef enum {
/** All transfer data has been moved into data FIFO */
CYHAL_SPI_IRQ_DATA_IN_FIFO = 1 << 1,
/** Transfer complete. */
CYHAL_SPI_IRQ_DONE = 1 << 2,
/** An error occurred while transferring data */
CYHAL_SPI_IRQ_ERROR = 1 << 3,
} cyhal_spi_event_t;
/** SPI Slave Select polarity */
typedef enum {
/** SSEL signal is active low */
CYHAL_SPI_SSEL_ACTIVE_LOW = 0,
/** SSEL signal is active high */
CYHAL_SPI_SSEL_ACTIVE_HIGH = 1,
} cyhal_spi_ssel_polarity_t;
/** Handler for SPI interrupts */
typedef void (*cyhal_spi_event_callback_t)(void *callback_arg, cyhal_spi_event_t event);
/** Flag for SPI \ref cyhal_spi_mode_t values indicating that the LSB is sent first. */
#define CYHAL_SPI_MODE_FLAG_LSB (0x01u)
/** Flag for SPI \ref cyhal_spi_mode_t values indicating that the CPHA=1. */
#define CYHAL_SPI_MODE_FLAG_CPHA (0x02u)
/** Flag for SPI \ref cyhal_spi_mode_t values indicating that the CPOL=1. */
#define CYHAL_SPI_MODE_FLAG_CPOL (0x04u)
/** Creates a \ref cyhal_spi_mode_t value given the cpol, cpha, lsb values. */
#define CYHAL_SPI_MODE(cpol, cpha, lsb) (((cpol > 0) ? CYHAL_SPI_MODE_FLAG_CPOL : 0) | \
((cpha > 0) ? CYHAL_SPI_MODE_FLAG_CPHA : 0) | \
(( lsb > 0) ? CYHAL_SPI_MODE_FLAG_LSB : 0))
/** SPI operating modes */
typedef enum
{
/** Standard motorola SPI CPOL=0, CPHA=0 with MSB first operation */
CYHAL_SPI_MODE_00_MSB = CYHAL_SPI_MODE(0, 0, 0),
/** Standard motorola SPI CPOL=0, CPHA=0 with LSB first operation */
CYHAL_SPI_MODE_00_LSB = CYHAL_SPI_MODE(0, 0, 1),
/** Standard motorola SPI CPOL=0, CPHA=1 with MSB first operation */
CYHAL_SPI_MODE_01_MSB = CYHAL_SPI_MODE(0, 1, 0),
/** Standard motorola SPI CPOL=0, CPHA=1 with LSB first operation */
CYHAL_SPI_MODE_01_LSB = CYHAL_SPI_MODE(0, 1, 1),
/** Standard motorola SPI CPOL=1, CPHA=0 with MSB first operation */
CYHAL_SPI_MODE_10_MSB = CYHAL_SPI_MODE(1, 0, 0),
/** Standard motorola SPI CPOL=1, CPHA=0 with LSB first operation */
CYHAL_SPI_MODE_10_LSB = CYHAL_SPI_MODE(1, 0, 1),
/** Standard motorola SPI CPOL=1, CPHA=1 with MSB first operation */
CYHAL_SPI_MODE_11_MSB = CYHAL_SPI_MODE(1, 1, 0),
/** Standard motorola SPI CPOL=1, CPHA=1 with LSB first operation */
CYHAL_SPI_MODE_11_LSB = CYHAL_SPI_MODE(1, 1, 1),
} cyhal_spi_mode_t;
/** @brief Initial SPI configuration. */
typedef struct
{
cyhal_spi_mode_t mode; //!< The operating mode
uint8_t data_bits; //!< The number of bits per transfer
bool is_slave; //!< Whether the peripheral is operating as slave or master
} cyhal_spi_cfg_t;
/** Initialize the SPI peripheral
*
* Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral
* @param[out] obj Pointer to a SPI object. The caller must allocate the memory
* for this object but the init function will initialize its contents.
* @param[in] mosi The pin to use for MOSI
* @note At least MOSI or MISO pin should be non-NC
* @param[in] miso The pin to use for MISO
* @note At least MOSI or MISO pin should be non-NC
* @param[in] sclk The pin to use for SCLK
* @note This pin cannot be NC
* @param[in] ssel The pin to use for SSEL
* @note Provided pin will be configured for \ref CYHAL_SPI_SSEL_ACTIVE_LOW polarity and set as active. This can be changed
* (as well as additional ssel pins can be added) by \ref cyhal_spi_slave_select_config and \ref cyhal_spi_select_active_ssel
* functions. This pin can be NC.
* @param[in] clk The clock to use can be shared, if not provided a new clock will be allocated
* @param[in] bits The number of bits per frame
* @note bits should be 8 or 16
* @param[in] mode The SPI mode (clock polarity, phase, and shift direction)
* @param[in] is_slave false for master mode or true for slave mode operation
* @return The status of the init request
*/
cy_rslt_t cyhal_spi_init(cyhal_spi_t *obj, cyhal_gpio_t mosi, cyhal_gpio_t miso, cyhal_gpio_t sclk, cyhal_gpio_t ssel,
const cyhal_clock_t *clk, uint8_t bits, cyhal_spi_mode_t mode, bool is_slave);
/** Release a SPI object
*
* Return the peripheral, pins and clock owned by the SPI object to their reset state
* @param[in,out] obj The SPI object to deinitialize
*/
void cyhal_spi_free(cyhal_spi_t *obj);
/** Set the SPI baud rate
*
* Actual frequency may differ from the desired frequency due to available dividers and bus clock
* Configures the SPI peripheral's baud rate
* @param[in,out] obj The SPI object to configure
* @param[in] hz The baud rate in Hz
* @return The status of the set_frequency request
*/
cy_rslt_t cyhal_spi_set_frequency(cyhal_spi_t *obj, uint32_t hz);
/** Configures provided ssel pin to work as SPI slave select with specified polarity.
*
* Multiple pins can be configured as SPI slave select pins. Please refer to device datasheet for details. Switching
* between configured slave select pins is done by \ref cyhal_spi_select_active_ssel function.
* Unless modified with this function, the SSEL pin provided as part of \ref cyhal_spi_init is the default.
* @param[in] obj The SPI object to add slave select for
* @param[in] ssel Slave select pin to be added
* @param[in] polarity Polarity of slave select
* @return The status of ssel pin configuration
*/
cy_rslt_t cyhal_spi_slave_select_config(cyhal_spi_t *obj, cyhal_gpio_t ssel, cyhal_spi_ssel_polarity_t polarity);
/** Selects an active slave select line from one of available.
*
* This function is applicable for the master and slave.
* SSEL pin should be configured by \ref cyhal_spi_slave_select_config or \ref cyhal_spi_init functions prior
* to selecting it as active. The active slave select line will automatically be toggled as part of any transfer.
* @param[in] obj The SPI object for switching
* @param[in] ssel Slave select pin to be set as active
* @return CY_RSLT_SUCCESS if slave select was switched successfully, otherwise - CYHAL_SPI_RSLT_ERR_CANNOT_SWITCH_SSEL
*/
cy_rslt_t cyhal_spi_select_active_ssel(cyhal_spi_t *obj, cyhal_gpio_t ssel);
/** Synchronously get a received value out of the SPI receive buffer
*
* In Master mode - transmits fill-in value and read the data from RxFifo
* In Slave mode - Blocks until a value is available
*
* @param[in] obj The SPI peripheral to read
* @param[in] value The value received
* @return The status of the read request
* @note
* - In Master mode, MISO pin required to be non-NC for this API to operate
* - In Slave mode, MOSI pin required to be non-NC for this API to operate
*/
cy_rslt_t cyhal_spi_recv(cyhal_spi_t *obj, uint32_t* value);
/** Synchronously send a byte out
*
* In Master mode transmits value to slave and read/drop a value from the RxFifo.
* In Slave mode writes a value to TxFifo
*
* @param[in] obj The SPI peripheral to use for sending
* @param[in] value The value to send
* @return The status of the write request
* @note
* - In Master mode, MOSI pin required to be non-NC for this API to operate
* - In Slave mode, MISO pin required to be non-NC for this API to operate
*/
cy_rslt_t cyhal_spi_send(cyhal_spi_t *obj, uint32_t value);
/** Synchronously Write a block out and receive a value
*
* The total number of bytes sent and received will be the maximum of tx_length
* and rx_length. The bytes written will be padded (at the end) with the value
* given by write_fill.
*
* This function will block for the duration of the transfer. \ref cyhal_spi_transfer_async
* can be used for non-blocking transfers.
*
* @param[in] obj The SPI peripheral to use for sending
* @param[in] tx Pointer to the byte-array of data to write to the device
* @param[in,out] tx_length Number of bytes to write, updated with the number actually written
* @param[out] rx Pointer to the byte-array of data to read from the device
* @param[in,out] rx_length Number of bytes to read, updated with the number actually read
* @param[in] write_fill Default data transmitted while performing a read
* @return The status of the transfer request
* @note Both MOSI and MISO pins required to be non-NC for this API to operate
*/
cy_rslt_t cyhal_spi_transfer(cyhal_spi_t *obj, const uint8_t *tx, size_t tx_length, uint8_t *rx, size_t rx_length, uint8_t write_fill);
/** Start an asynchronous SPI transfer.
*
* This will transfer `rx_length` bytes into the buffer pointed to by `rx`, while simultaneously transfering
* `tx_length` bytes of data from the buffer pointed to by `tx`, both in the background.
* When the transfer is complete, the @ref CYHAL_SPI_IRQ_DONE event will be raised.
* See @ref cyhal_spi_register_callback and @ref cyhal_spi_enable_event.
* \note For blocking transfers cyhal_spi_transfer can be used.
*
* @param[in] obj The SPI object that holds the transfer information
* @param[in] tx The transmit buffer
* @param[in,out] tx_length The number of bytes to transmit
* @param[out] rx The receive buffer
* @param[in,out] rx_length The number of bytes to receive
* @return The status of the transfer_async request
* @note Both MOSI and MISO pins required to be non-NC for this API to operate
*/
cy_rslt_t cyhal_spi_transfer_async(cyhal_spi_t *obj, const uint8_t *tx, size_t tx_length, uint8_t *rx, size_t rx_length);
/** Checks if the specified SPI peripheral is in use
*
* @param[in] obj The SPI peripheral to check
* @return Indication of whether the SPI is still transmitting
*/
bool cyhal_spi_is_busy(cyhal_spi_t *obj);
/** Abort an SPI transfer
*
* @param[in] obj The SPI peripheral to stop
* @return The status of the abort_async request
*/
cy_rslt_t cyhal_spi_abort_async(cyhal_spi_t *obj);
/** Register a SPI callback handler
*
* This function will be called when one of the events enabled by \ref cyhal_spi_enable_event occurs.
*
* @param[in] obj The SPI object
* @param[in] callback The callback handler which will be invoked when the interrupt fires
* @param[in] callback_arg Generic argument that will be provided to the callback when called
*/
void cyhal_spi_register_callback(cyhal_spi_t *obj, cyhal_spi_event_callback_t callback, void *callback_arg);
/** Configure SPI interrupt. This function is used for word-approach
*
* When an enabled event occurs, the function specified by \ref cyhal_spi_register_callback will be called.
*
* @param[in] obj The SPI object
* @param[in] event The SPI event type
* @param[in] intr_priority The priority for NVIC interrupt events
* @param[in] enable True to turn on interrupts, False to turn off
*/
void cyhal_spi_enable_event(cyhal_spi_t *obj, cyhal_spi_event_t event, uint8_t intr_priority, bool enable);
/*******************************************************************************
* Backward compatibility macro. The following code is DEPRECATED and must
* not be used in new projects
*******************************************************************************/
/** \cond INTERNAL */
typedef cyhal_spi_event_t cyhal_spi_irq_event_t;
/** \endcond */
#if defined(__cplusplus)
}
#endif
#ifdef CYHAL_SPI_IMPL_HEADER
#include CYHAL_SPI_IMPL_HEADER
#endif /* CYHAL_SPI_IMPL_HEADER */
/** \} group_hal_spi */

View File

@ -0,0 +1,63 @@
/*
* Copyright 2020 Arduino SA
* 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
*
* 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.
*/
/** @file
* Provides cyhal porting to generic mbed APIs
*/
#include "cyhal.h"
#include "mbed_thread.h"
#include "mbed_wait_api.h"
static cyhal_sdio_t sdio_obj;
/* Edit Pin configuration */
const pinconfig_t PinConfig[] = {
[CYBSP_WIFI_WL_REG_ON] = WIFI_WL_REG_ON,
#ifdef CYBSP_WIFI_32K_CLK
[CYBSP_WIFI_32K_CLK] = WIFI_32K_CLK,
#endif /* CYBSP_WIFI_32K_CLK */
[CYBSP_LED1 ] = BSP_LED1,
[CYBSP_LED2 ] = BSP_LED2,
[CYBSP_WIFI_SDIO_CMD] = WIFI_SDIO_CMD,
[CYBSP_WIFI_SDIO_CLK] = WIFI_SDIO_CLK,
[CYBSP_WIFI_SDIO_D0 ] = WIFI_SDIO_D0,
[CYBSP_WIFI_SDIO_D1 ] = WIFI_SDIO_D1,
[CYBSP_WIFI_SDIO_D2 ] = WIFI_SDIO_D2,
[CYBSP_WIFI_SDIO_D3 ] = WIFI_SDIO_D3,
[CYBSP_SDIO_OOB_IRQ ] = WIFI_SDIO_OOB_IRQ //VIKR
};
void Cy_SysLib_Delay(uint32_t milliseconds)
{
thread_sleep_for(milliseconds);
}
void Cy_SysLib_DelayUs(uint16_t microseconds)
{
wait_us(microseconds);
}
void cyhal_system_delay_ms(uint32_t milliseconds)
{
Cy_SysLib_Delay(milliseconds);
}
cyhal_sdio_t *cybsp_get_wifi_sdio_obj(void)
{
return &sdio_obj;
}

View File

@ -0,0 +1,592 @@
/***************************************************************************//**
* \file cy_syslib.h
* \version 2.40.1
*
* Provides an API declaration of the SysLib driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2019 Cypress Semiconductor Corporation
* 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
*
* 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.
*******************************************************************************/
/**
* \addtogroup group_syslib
* \{
* The system libraries provide APIs that can be called in the user application
* to handle the timing, logical checking or register.
*
* The functions and other declarations used in this driver are in cy_syslib.h.
* You can include cy_pdl.h (ModusToolbox only) to get access to all functions
* and declarations in the PDL.
*
* The SysLib driver contains a set of different system functions. These functions
* can be called in the application routine. Major features of the system library:
* * Delay functions
* * The register Read/Write macro
* * Assert and Halt
* * Assert Classes and Levels
* * A software reset
* * Reading the reset cause
* * An API to invalidate the flash cache and buffer
* * Data manipulation macro
* * A variable type definition from MISRA-C which specifies signedness
* * Cross compiler compatible attributes
* * Getting a silicon-unique ID API
* * Setting wait states API
* * Resetting the backup domain API
* * APIs to serve Fault handler
*
* \section group_syslib_configuration Configuration Considerations
* <b> Assertion Usage </b> <br />
* Use the CY_ASSERT() macro to check expressions that must be true as long as the
* program is running correctly. It is a convenient way to insert sanity checks.
* The CY_ASSERT() macro is defined in the cy_syslib.h file which is part of
* the PDL library. The behavior of the macro is as follows: if the expression
* passed to the macro is false, output an error message that includes the file
* name and line number, and then halts the CPU. \n
* In case of fault, the CY_ASSERT() macro calls the Cy_SysLib_AssertFailed() function.
* This is a weakly linked function. The default implementation stores the file
* name and line number of the ASSERT into global variables, cy_assertFileName
* and cy_assertLine . It then calls the Cy_SysLib_Halt() function.
* \note Firmware can redefine the Cy_SysLib_AssertFailed() function for custom processing.
*
* The PDL source code uses this assert mechanism extensively. It is recommended
* that you enable asserts when debugging firmware. \n
* <b> Assertion Classes and Levels </b> <br />
* The PDL defines three assert classes, which correspond to different kinds
* of parameters. There is a corresponding assert "level" for each class.
* <table class="doxtable">
* <tr><th>Class Macro</th><th>Level Macro</th><th>Type of check</th></tr>
* <tr>
* <td>CY_ASSERT_CLASS_1</td>
* <td>CY_ASSERT_L1</td>
* <td>A parameter that could change between different PSoC devices
* (e.g. the number of clock paths)</td>
* </tr>
* <tr>
* <td>CY_ASSERT_CLASS_2</td>
* <td>CY_ASSERT_L2</td>
* <td>A parameter that has fixed limits such as a counter period</td>
* </tr>
* <tr>
* <td>CY_ASSERT_CLASS_3</td>
* <td>CY_ASSERT_L3</td>
* <td>A parameter that is an enum constant</td>
* </tr>
* </table>
* Firmware defines which ASSERT class is enabled by defining CY_ASSERT_LEVEL.
* This is a compiler command line argument, similar to how the DEBUG / NDEBUG
* macro is passed. \n
* Enabling any class also enables any lower-numbered class.
* CY_ASSERT_CLASS_3 is the default level, and it enables asserts for all three
* classes. The following example shows the command-line option to enable all
* the assert levels:
* \code -D CY_ASSERT_LEVEL=CY_ASSERT_CLASS_3 \endcode
* \note The use of special characters, such as spaces, parenthesis, etc. must
* be protected with quotes.
*
* After CY_ASSERT_LEVEL is defined, firmware can use
* one of the three level macros to make an assertion. For example, if the
* parameter can vary between devices, firmware uses the L1 macro.
* \code CY_ASSERT_L1(clkPath < SRSS_NUM_CLKPATH); \endcode
* If the parameter has bounds, firmware uses L2.
* \code CY_ASSERT_L2(trim <= CY_CTB_TRIM_VALUE_MAX); \endcode
* If the parameter is an enum, firmware uses L3.
* \code CY_ASSERT_L3(config->LossAction <= CY_SYSCLK_CSV_ERROR_FAULT_RESET); \endcode
* Each check uses the appropriate level macro for the kind of parameter being checked.
* If a particular assert class/level is not enabled, then the assert does nothing.
*
* \section group_syslib_more_information More Information
* Refer to the technical reference manual (TRM).
*
* \section group_syslib_MISRA MISRA-C Compliance
* <table class="doxtable">
* <tr>
* <th>MISRA Rule</th>
* <th>Rule Class (Required/Advisory)</th>
* <th>Rule Description</th>
* <th>Description of Deviation(s)</th>
* </tr>
* <tr>
* <td>1.2</td>
* <td>R</td>
* <td>No reliance shall be placed on undefined or unspecified behaviour.</td>
* <td>This specific behavior is explicitly covered in rule 20.1.</td>
* </tr>
* <tr>
* <td>2.1</td>
* <td>R</td>
* <td>This function contains a mixture of in-line assembler statements and C statements.</td>
* <td>This si required by design of the Cy_SysLib_Halt function.</td>
* </tr>
* <tr>
* <td>18.4</td>
* <td>R</td>
* <td>Unions shall not be used.</td>
* <td>The unions are used for CFSR, HFSR and SHCSR Fault Status Registers
* content access as a word in code and as a structure during debug.</td>
* </tr>
* <tr>
* <td>19.13</td>
* <td>A</td>
* <td>The # and ## operators should not be used.</td>
* <td>The ## preprocessor operator is used in macros to form the field mask.</td>
* </tr>
* <tr>
* <td>20.1</td>
* <td>R</td>
* <td>Reserved identifiers, macros and functions in the standard library, shall not be
* defined, redefined or undefined.</td>
* <td>The driver defines the macros with leading underscores
* (_CLR_SET_FLD/_BOOL2FLD/_FLD2BOOL) and therefore generates this MISRA violation.</td>
* </tr>
* </table>
*
* \section group_syslib_changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>2.40.1</td>
* <td>Correct the CY_RAMFUNC_BEGIN macro for the IAR compiler.</td>
* <td>Removed the IAR compiler warning.</td>
* </tr>
* <tr>
* <td>2.40</td>
* <td>Added new macros CY_SYSLIB_DIV_ROUND and CY_SYSLIB_DIV_ROUNDUP to easy perform integer division with rounding.</td>
* <td>Improve PDL code base.</td>
* </tr>
* <tr>
* <td rowspan="3">2.30</td>
* <td>Updated implementation of the Cy_SysLib_AsmInfiniteLoop() function to be compatible with ARMC6.</td>
* <td>Provided support for the ARM Compiler 6.</td>
* </tr>
* <tr>
* <td>Minor documentation edits.</td>
* <td>Documentation update and clarification.</td>
* </tr>
* <tr>
* <td>Added new macros CY_RAMFUNC_BEGIN and CY_RAMFUNC_END for convenient placement function in RAM for all supported compilers.</td>
* <td>Improve user experience.</td>
* </tr>
* <tr>
* <td rowspan="2">2.20</td>
* <td>Updated implementation of the \ref Cy_SysLib_AssertFailed() function to be available in Release and Debug modes.</td>
* <td>Provided support for the PDL static library in Release mode.</td>
* </tr>
* <tr>
* <td>Minor documentation edits.</td>
* <td>Documentation update and clarification.</td>
* </tr>
* <tr>
* <td rowspan="4">2.10</td>
* <td>Flattened the organization of the driver source code into the single source directory and the single include directory.</td>
* <td>Driver library directory-structure simplification.</td>
* </tr>
* <tr>
* <td>Added the following macros: \ref CY_REG32_CLR_SET, \ref _CLR_SET_FLD16U, \ref CY_REG16_CLR_SET, \ref _CLR_SET_FLD8U, \ref CY_REG8_CLR_SET</td>
* <td>Register access simplification.</td>
* </tr>
* <tr>
* <td>Removed the Cy_SysLib_GetNumHfclkResetCause API function.</td>
* <td>This feature is not supported by SRSS_ver1.</td>
* </tr>
* <tr>
* <td>Added register access layer. Use register access macros instead
* of direct register access using dereferenced pointers.</td>
* <td>Makes register access device-independent, so that the PDL does
* not need to be recompiled for each supported part number.</td>
* </tr>
* <tr>
* <td>2.0.1</td>
* <td>Minor documentation edits</td>
* <td>Documentation update and clarification</td>
* </tr>
* <tr>
* <td rowspan="4"> 2.0</td>
* <td>
* Added Cy_SysLib_ResetBackupDomain() API implementation. \n
* Added CY_NOINLINE attribute implementation. \n
* Added DIE_YEAR field to 64-bit unique ID return value of Cy_SysLib_GetUniqueId() API. \n
* Added storing of SCB->HFSR, SCB->SHCSR registers and SCB->MMFAR, SCB->BFAR addresses to Fault Handler debug structure. \n
* Optimized Cy_SysLib_SetWaitStates() API implementation.
* </td>
* <td>Improvements made based on usability feedback.</td>
* </tr>
* <tr>
* <td>Added Assertion Classes and Levels.</td>
* <td>For error checking, parameter validation and status returns in the PDL API.</td>
* </tr>
* <tr>
* <td>Applied CY_NOINIT attribute to cy_assertFileName, cy_assertLine, and cy_faultFrame global variables.</td>
* <td>To store debug information into a non-zero init area for future analysis.</td>
* </tr>
* <tr>
* <td>Removed CY_WEAK attribute implementation.</td>
* <td>CMSIS __WEAK attribute should be used instead.</td>
* </tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_syslib_macros Macros
* \defgroup group_syslib_functions Functions
* \defgroup group_syslib_data_structures Data Structures
* \defgroup group_syslib_enumerated_types Enumerated Types
*
*/
#if !defined(CY_SYSLIB_H)
#define CY_SYSLIB_H
#include <stdint.h>
#include <stdbool.h>
/*******************************************************************************
* Data manipulation defines
*******************************************************************************/
/** Get the lower 8 bits of a 16-bit value. */
#define CY_LO8(x) ((uint8_t) ((x) & 0xFFU))
/** Get the upper 8 bits of a 16-bit value. */
#define CY_HI8(x) ((uint8_t) ((uint16_t)(x) >> 8U))
/** Get the lower 16 bits of a 32-bit value. */
#define CY_LO16(x) ((uint16_t) ((x) & 0xFFFFU))
/** Get the upper 16 bits of a 32-bit value. */
#define CY_HI16(x) ((uint16_t) ((uint32_t)(x) >> 16U))
/** Swap the byte ordering of a 16-bit value */
#define CY_SWAP_ENDIAN16(x) ((uint16_t)(((x) << 8U) | (((x) >> 8U) & 0x00FFU)))
/** Swap the byte ordering of a 32-bit value */
#define CY_SWAP_ENDIAN32(x) ((uint32_t)((((x) >> 24U) & 0x000000FFU) | (((x) & 0x00FF0000U) >> 8U) | \
(((x) & 0x0000FF00U) << 8U) | ((x) << 24U)))
/** Swap the byte ordering of a 64-bit value */
#define CY_SWAP_ENDIAN64(x) ((uint64_t) (((uint64_t) CY_SWAP_ENDIAN32((uint32_t)(x)) << 32U) | \
CY_SWAP_ENDIAN32((uint32_t)((x) >> 32U))))
/* MISRA rule 6.3 recommends using specific-length typedef for the basic
* numerical types of signed and unsigned variants of char, float, and double.
*/
typedef char char_t; /**< Specific-length typedef for the basic numerical types of char */
typedef float float32_t; /**< Specific-length typedef for the basic numerical types of float */
typedef double float64_t; /**< Specific-length typedef for the basic numerical types of double */
/*******************************************************************************
* Macro Name: CY_GET_REG8(addr)
****************************************************************************//**
*
* Reads the 8-bit value from the specified address. This function can't be
* used to access the Core register, otherwise a fault occurs.
*
* \param addr The register address.
*
* \return The read value.
*
*******************************************************************************/
#define CY_GET_REG8(addr) (*((const volatile uint8_t *)(addr)))
/*******************************************************************************
* Macro Name: CY_SET_REG8(addr, value)
****************************************************************************//**
*
* Writes an 8-bit value to the specified address. This function can't be
* used to access the Core register, otherwise a fault occurs.
*
* \param addr The register address.
*
* \param value The value to write.
*
*******************************************************************************/
#define CY_SET_REG8(addr, value) (*((volatile uint8_t *)(addr)) = (uint8_t)(value))
/*******************************************************************************
* Macro Name: CY_GET_REG16(addr)
****************************************************************************//**
*
* Reads the 16-bit value from the specified address.
*
* \param addr The register address.
*
* \return The read value.
*
*******************************************************************************/
#define CY_GET_REG16(addr) (*((const volatile uint16_t *)(addr)))
/*******************************************************************************
* Macro Name: CY_SET_REG16(addr, value)
****************************************************************************//**
*
* Writes the 16-bit value to the specified address.
*
* \param addr The register address.
*
* \param value The value to write.
*
*******************************************************************************/
#define CY_SET_REG16(addr, value) (*((volatile uint16_t *)(addr)) = (uint16_t)(value))
/*******************************************************************************
* Macro Name: CY_GET_REG24(addr)
****************************************************************************//**
*
* Reads the 24-bit value from the specified address.
*
* \param addr The register address.
*
* \return The read value.
*
*******************************************************************************/
#define CY_GET_REG24(addr) (((uint32_t) (*((const volatile uint8_t *)(addr)))) | \
(((uint32_t) (*((const volatile uint8_t *)(addr) + 1))) << 8U) | \
(((uint32_t) (*((const volatile uint8_t *)(addr) + 2))) << 16U))
/*******************************************************************************
* Macro Name: CY_SET_REG24(addr, value)
****************************************************************************//**
*
* Writes the 24-bit value to the specified address.
*
* \param addr The register address.
*
* \param value The value to write.
*
*******************************************************************************/
#define CY_SET_REG24(addr, value) do \
{ \
(*((volatile uint8_t *) (addr))) = (uint8_t)(value); \
(*((volatile uint8_t *) (addr) + 1)) = (uint8_t)((value) >> 8U); \
(*((volatile uint8_t *) (addr) + 2)) = (uint8_t)((value) >> 16U); \
} \
while(0)
/*******************************************************************************
* Macro Name: CY_GET_REG32(addr)
****************************************************************************//**
*
* Reads the 32-bit value from the specified register. The address is the little
* endian order (LSB in lowest address).
*
* \param addr The register address.
*
* \return The read value.
*
*******************************************************************************/
#define CY_GET_REG32(addr) (*((const volatile uint32_t *)(addr)))
/*******************************************************************************
* Macro Name: CY_SET_REG32(addr, value)
****************************************************************************//**
*
* Writes the 32-bit value to the specified register. The address is the little
* endian order (LSB in lowest address).
*
* \param addr The register address.
*
* \param value The value to write.
*
*******************************************************************************/
#define CY_SET_REG32(addr, value) (*((volatile uint32_t *)(addr)) = (uint32_t)(value))
/*******************************************************************************
* Macro Name: _CLR_SET_FLD32U
****************************************************************************//**
*
* The macro for setting a register with a name field and value for providing
* get-clear-modify-write operations.
* Returns a resulting value to be assigned to the register.
*
*******************************************************************************/
#define _CLR_SET_FLD32U(reg, field, value) (((reg) & ((uint32_t)(~(field ## _Msk)))) | (_VAL2FLD(field, value)))
/*******************************************************************************
* Macro Name: CY_REG32_CLR_SET
****************************************************************************//**
*
* Uses _CLR_SET_FLD32U macro for providing get-clear-modify-write
* operations with a name field and value and writes a resulting value
* to the 32-bit register.
*
*******************************************************************************/
#define CY_REG32_CLR_SET(reg, field, value) ((reg) = _CLR_SET_FLD32U((reg), field, (value)))
/*******************************************************************************
* Macro Name: _CLR_SET_FLD16U
****************************************************************************//**
*
* The macro for setting a 16-bit register with a name field and value for providing
* get-clear-modify-write operations.
* Returns a resulting value to be assigned to the 16-bit register.
*
*******************************************************************************/
#define _CLR_SET_FLD16U(reg, field, value) ((uint16_t)(((reg) & ((uint16_t)(~(field ## _Msk)))) | \
((uint16_t)_VAL2FLD(field, value))))
/*******************************************************************************
* Macro Name: CY_REG16_CLR_SET
****************************************************************************//**
*
* Uses _CLR_SET_FLD16U macro for providing get-clear-modify-write
* operations with a name field and value and writes a resulting value
* to the 16-bit register.
*
*******************************************************************************/
#define CY_REG16_CLR_SET(reg, field, value) ((reg) = _CLR_SET_FLD16U((reg), field, (value)))
/*******************************************************************************
* Macro Name: _CLR_SET_FLD8U
****************************************************************************//**
*
* The macro for setting a 8-bit register with a name field and value for providing
* get-clear-modify-write operations.
* Returns a resulting value to be assigned to the 8-bit register.
*
*******************************************************************************/
#define _CLR_SET_FLD8U(reg, field, value) ((uint8_t)(((reg) & ((uint8_t)(~(field ## _Msk)))) | \
((uint8_t)_VAL2FLD(field, value))))
/*******************************************************************************
* Macro Name: CY_REG8_CLR_SET
****************************************************************************//**
*
* Uses _CLR_SET_FLD8U macro for providing get-clear-modify-write
* operations with a name field and value and writes a resulting value
* to the 8-bit register.
*
*******************************************************************************/
#define CY_REG8_CLR_SET(reg, field, value) ((reg) = _CLR_SET_FLD8U((reg), field, (value)))
/*******************************************************************************
* Macro Name: _BOOL2FLD
****************************************************************************//**
*
* Returns a field mask if the value is not false.
* Returns 0, if the value is false.
*
*******************************************************************************/
#define _BOOL2FLD(field, value) (((value) != false) ? (field ## _Msk) : 0UL)
/*******************************************************************************
* Macro Name: _FLD2BOOL
****************************************************************************//**
*
* Returns true, if the value includes the field mask.
* Returns false, if the value doesn't include the field mask.
*
*******************************************************************************/
#define _FLD2BOOL(field, value) (((value) & (field ## _Msk)) != 0UL)
/*******************************************************************************
* Macro Name: CY_SYSLIB_DIV_ROUND
****************************************************************************//**
*
* Calculates a / b with rounding to the nearest integer,
* a and b must have the same sign.
*
*******************************************************************************/
#define CY_SYSLIB_DIV_ROUND(a, b) (((a) + ((b) / 2U)) / (b))
/*******************************************************************************
* Macro Name: CY_SYSLIB_DIV_ROUNDUP
****************************************************************************//**
*
* Calculates a / b with rounding up if remainder != 0,
* both a and b must be positive.
*
*******************************************************************************/
#define CY_SYSLIB_DIV_ROUNDUP(a, b) ((((a) - 1U) / (b)) + 1U)
typedef uint32_t cy_status;
/** The ARM 32-bit status value for backward compatibility with the UDB components. Do not use it in your code. */
typedef uint32_t cystatus;
typedef uint8_t uint8; /**< Alias to uint8_t for backward compatibility */
typedef uint16_t uint16; /**< Alias to uint16_t for backward compatibility */
typedef uint32_t uint32; /**< Alias to uint32_t for backward compatibility */
typedef int8_t int8; /**< Alias to int8_t for backward compatibility */
typedef int16_t int16; /**< Alias to int16_t for backward compatibility */
typedef int32_t int32; /**< Alias to int32_t for backward compatibility */
typedef float float32; /**< Alias to float for backward compatibility */
typedef double float64; /**< Alias to double for backward compatibility */
typedef int64_t int64; /**< Alias to int64_t for backward compatibility */
typedef uint64_t uint64; /**< Alias to uint64_t for backward compatibility */
/* Signed or unsigned depending on the compiler selection */
typedef char char8; /**< Alias to char for backward compatibility */
typedef volatile uint8_t reg8; /**< Alias to uint8_t for backward compatibility */
typedef volatile uint16_t reg16; /**< Alias to uint16_t for backward compatibility */
typedef volatile uint32_t reg32; /**< Alias to uint32_t for backward compatibility */
/** The ARM 32-bit Return error / status code for backward compatibility.
* Do not use them in your code.
*/
#define CY_RET_SUCCESS (0x00U) /* Successful */
#define CY_RET_BAD_PARAM (0x01U) /* One or more invalid parameters */
#define CY_RET_INVALID_OBJECT (0x02U) /* An invalid object specified */
#define CY_RET_MEMORY (0x03U) /* A memory-related failure */
#define CY_RET_LOCKED (0x04U) /* A resource lock failure */
#define CY_RET_EMPTY (0x05U) /* No more objects available */
#define CY_RET_BAD_DATA (0x06U) /* Bad data received (CRC or other error check) */
#define CY_RET_STARTED (0x07U) /* Operation started, but not necessarily completed yet */
#define CY_RET_FINISHED (0x08U) /* Operation is completed */
#define CY_RET_CANCELED (0x09U) /* Operation is canceled */
#define CY_RET_TIMEOUT (0x10U) /* Operation timed out */
#define CY_RET_INVALID_STATE (0x11U) /* Operation is not setup or is in an improper state */
#define CY_RET_UNKNOWN ((cy_status) 0xFFFFFFFFU) /* Unknown failure */
/** ARM 32-bit Return error / status codes for backward compatibility with the UDB components.
* Do not use them in your code.
*/
#define CYRET_SUCCESS (0x00U) /* Successful */
#define CYRET_BAD_PARAM (0x01U) /* One or more invalid parameters */
#define CYRET_INVALID_OBJECT (0x02U) /* An invalid object specified */
#define CYRET_MEMORY (0x03U) /* A memory-related failure */
#define CYRET_LOCKED (0x04U) /* A resource lock failure */
#define CYRET_EMPTY (0x05U) /* No more objects available */
#define CYRET_BAD_DATA (0x06U) /* Bad data received (CRC or other error check) */
#define CYRET_STARTED (0x07U) /* Operation started, but not necessarily completed yet */
#define CYRET_FINISHED (0x08U) /* Operation is completed */
#define CYRET_CANCELED (0x09U) /* Operation is canceled */
#define CYRET_TIMEOUT (0x10U) /* Operation timed out */
#define CYRET_INVALID_STATE (0x11U) /* Operation is not setup or is in an improper state */
#define CYRET_UNKNOWN ((cystatus) 0xFFFFFFFFU) /* Unknown failure */
/** \} group_syslib_functions */
#endif /* CY_SYSLIB_H */
/** \} group_syslib */
/* [] END OF FILE */

View File

@ -0,0 +1,81 @@
/***************************************************************************//**
* \file cy_utils.h
*
* \brief
* Basic utility macros and functions.
*
********************************************************************************
* \copyright
* Copyright 2018-2019 Cypress Semiconductor Corporation
* 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
*
* 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.
*******************************************************************************/
/**
* \addtogroup group_utils Utilities
* \ingroup group_abstraction
* \{
* Basic utility macros and functions.
*
* \defgroup group_utils_macros Macros
*/
#pragma once
#include "stdint.h"
#if defined(__cplusplus)
extern "C" {
#endif
/**
* \addtogroup group_utils_macros
* \{
*/
/** Simple macro to supress the unused parameter warning by casting to void. */
#define CY_UNUSED_PARAMETER(x) ( (void)(x) )
/** Halt the processor in the debug state
* @return
*/
static inline uint32_t CY_HALT()
{
__asm(" bkpt 1");
return 0;
}
#ifdef CY_ASSERT
#undef CY_ASSERT
#endif /* ifdef(CY_ASSERT) */
/** Utility macro when neither NDEBUG or CY_NO_ASSERT is not declared to check a condition and, if false, trigger a breakpoint */
#if defined(NDEBUG) || defined(CY_NO_ASSERT)
#define CY_ASSERT(x) CY_UNUSED_PARAMETER(x)
#else
#define CY_ASSERT(x) do { \
if(!(x)) \
{ \
CY_HALT(); \
} \
} while(0)
#endif /* defined(NDEBUG) */
/** \} group_utils_macros */
#ifdef __cplusplus
}
#endif
/** \} group_utils */

View File

@ -0,0 +1,50 @@
/***************************************************************************//**
* \file cybsp.h
*
* \brief
* Basic API for setting up boards containing a Cypress MCU.
*
********************************************************************************
* \copyright
* Copyright 2018-2020 Cypress Semiconductor Corporation
* 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
*
* 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.
*******************************************************************************/
#pragma once
#include "cy_result.h"
#include "cyhal_sdio.h"
#if defined(__cplusplus)
extern "C" {
#endif
/**
* \addtogroup group_bsp_functions Functions
* \{
*/
/**
* \brief Get the initialized sdio object used for communicating with the WiFi Chip.
* \note This function should only be called after cybsp_init();
* \returns The initialized sdio object.
*/
cyhal_sdio_t* cybsp_get_wifi_sdio_obj(void);
/** \} group_bsp_functions */
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -0,0 +1,20 @@
/*
* Copyright 2020 Arduino SA
* 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
*
* 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.
*/
/** @file
* Empty file to be compliant with Cypress COMPONENT_WHD
*/

View File

@ -0,0 +1,52 @@
/*
* Copyright 2020 Arduino SA
* 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
*
* 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.
*/
/** @file
* Provides cyhal porting to generic mbed APIs
*/
#include "whd_config.h"
#include "cyhal_hw_types.h"
#include "cyhal_gpio.h"
#include "cyhal_sdio.h"
#if defined(__cplusplus)
extern "C" {
#endif
typedef enum
{
CYBSP_WIFI_WL_REG_ON,
CYBSP_WIFI_32K_CLK,
CYBSP_LED1,
CYBSP_LED2,
CYBSP_WIFI_SDIO_CMD,
CYBSP_WIFI_SDIO_CLK,
CYBSP_WIFI_SDIO_D0,
CYBSP_WIFI_SDIO_D1,
CYBSP_WIFI_SDIO_D2,
CYBSP_WIFI_SDIO_D3,
CYBSP_SDIO_OOB_IRQ,
CYBSP_WIFI_MAX,
} wwd_sdio_pin_t;
void cyhal_system_delay_ms(uint32_t milliseconds);
cy_rslt_t sdio_enable_high_speed(void);
#if defined(__cplusplus)
}
#endif

View File

@ -0,0 +1,104 @@
/*
* Copyright 2020 Arduino SA
* 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
*
* 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.
*/
/** @file
* Provides the porting layer for STM32 GPIOs on WHD driver
*/
#include <stdio.h>
#include "cyhal.h"
#include "cybsp.h"
#include "mbed.h"
#include "wiced_filesystem.h"
extern pinconfig_t PinConfig[];
/*******************************************************************************
* Internal
*******************************************************************************/
static mbed::InterruptIn *oob_irq;
static cyhal_gpio_event_t oob_event = CYHAL_GPIO_IRQ_FALL;
static cyhal_gpio_event_callback_t oob_handler;
static void *oob_handler_arg;
/*******************************************************************************
* Internal Interrrupt Service Routine
*******************************************************************************/
static void cb()
{
oob_handler(oob_handler_arg, oob_event);
}
/*******************************************************************************
* HAL Implementation
*******************************************************************************/
cy_rslt_t cyhal_gpio_init(cyhal_gpio_t pin, cyhal_gpio_direction_t direction, cyhal_gpio_drive_mode_t drvMode, bool initVal)
{
cy_rslt_t ret = CY_RSLT_SUCCESS;
// Workaround to enable GPIOJ clock
if (pin == CYBSP_WIFI_WL_REG_ON) {
__HAL_RCC_GPIOJ_CLK_ENABLE();
// Ensure FS and BlockDevice are initialized on time if needed
wiced_filesystem_init();
}
// Ignore the parameter and take the pin config directly from a static array defintions
HAL_GPIO_Init(PinConfig[pin].port, &PinConfig[pin].config);
if (direction == CYHAL_GPIO_DIR_OUTPUT) {
HAL_GPIO_WritePin(PinConfig[pin].port, PinConfig[pin].config.Pin, (initVal) ? GPIO_PIN_SET : GPIO_PIN_RESET);
}
// Workaround to initialize sdio interface without cypress bsp init
if (pin == CYBSP_WIFI_WL_REG_ON) {
cyhal_sdio_t *sdio_p = cybsp_get_wifi_sdio_obj();
ret = cyhal_sdio_init(sdio_p, CYBSP_WIFI_SDIO_CMD, CYBSP_WIFI_SDIO_CLK, CYBSP_WIFI_SDIO_D0, CYBSP_WIFI_SDIO_D1, CYBSP_WIFI_SDIO_D2, CYBSP_WIFI_SDIO_D3);
}
return ret;
}
void cyhal_gpio_write(cyhal_gpio_t pin, bool value)
{
HAL_GPIO_WritePin(PinConfig[pin].port, PinConfig[pin].config.Pin, (value) ? GPIO_PIN_SET : GPIO_PIN_RESET);
}
void cyhal_gpio_register_callback(cyhal_gpio_t pin, cyhal_gpio_event_callback_t handler, void *handler_arg)
{
if (handler && handler_arg && (oob_irq == NULL)) {
oob_irq = new mbed::InterruptIn(PJ_5);
oob_handler = handler;
oob_handler_arg = handler_arg;
}
}
void cyhal_gpio_enable_event(cyhal_gpio_t pin, cyhal_gpio_event_t event, uint8_t intr_priority, bool enable)
{
oob_event = event;
if (enable) {
if (event == CYHAL_GPIO_IRQ_RISE) {
oob_irq->rise(cb);
}
if (event == CYHAL_GPIO_IRQ_FALL) {
oob_irq->fall(cb);
}
} else if (oob_irq != NULL) {
delete oob_irq;
}
}
void cyhal_gpio_free(cyhal_gpio_t pin)
{
// Do nothing
}

View File

@ -0,0 +1,123 @@
/***************************************************************************//**
* \file cyhal_hw_types_template.h
*
* \brief
* Provides a template for configuration resources used by the HAL. Items
* here need to be implemented for each HAL port. It is up to the environment
* being ported into what the actual types are. There are some suggestions below
* but these are not required. All that is required is that the type is defined;
* it does not matter to the HAL what type is actually chosen for the
* implementation
* All TODOs and references to 'PORT' need to be replaced by with meaningful
* values for the device being supported.
*
********************************************************************************
* \copyright
* Copyright 2018-2019 Cypress Semiconductor Corporation
* 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
*
* 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.
*******************************************************************************/
/**
* \addtogroup group_hal_hw_types PORT Hardware Types
* \ingroup group_hal_PORT
* \{
* Struct definitions for configuration resources in the PORT.
*
* \defgroup group_hal_hw_types_data_structures Data Structures
*/
#pragma once
#include <stdbool.h>
#include "stm32h7xx_hal.h"
#include "PinNames.h"
/*
#include "TODO: Port specific header file"
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef CYHAL_ISR_PRIORITY_DEFAULT
/** Priority that is applied by default to all drivers when initalized. Priorities can be
* overridden on each driver as part of enabling events.
*/
#define CYHAL_ISR_PRIORITY_DEFAULT (7)
#endif
/**
* \addtogroup group_hal_hw_types_data_structures
* \{
*/
typedef int32_t cyhal_gpio_t;
/** GPIO object */
typedef struct
{
GPIO_TypeDef *port;
GPIO_InitTypeDef config;
} pinconfig_t;
/** Clock divider object */
typedef struct
{
/* TODO: replace with port specific items */
void *div_type;
} cyhal_clock_divider_t;
/** Clock object */
typedef struct
{
//For backwards compatibility with cyhal_clock_divider_t only. Do not use going forward.
int div_type; /*!< Deprecated */
uint8_t div_num; /*!< Deprecated */
//End BWC items
int block;
uint8_t channel;
bool reserved;
} cyhal_clock_t;
/** SDIO object */
typedef void* *cyhal_sdio_t;
/** SPI object */
typedef struct
{
/* TODO: replace with port specific items */
void *empty;
} cyhal_spi_t;
#include "whd_debug.h"
#if defined(WPRINT_ENABLE_WHD_ERROR) || defined(WPRINT_ENABLE_WHD_INFO) || defined(WPRINT_ENABLE_WHD_DEBUG)
/** \} group_hal_hw_types_data_structures */
#define PRINTF(...) do { \
(void) printf(__VA_ARGS__); \
} while (0)
#else
#define PRINTF(...)
#endif
#include "whd_config.h"
#if defined(__cplusplus)
}
#endif /* __cplusplus */
/** \} group_hal_hw_types */

View File

@ -0,0 +1,483 @@
/*
* Copyright 2020 Cypress Semiconductor Corporation
* 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
*
* 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.
*/
/** @file
* Provides the porting layer for STM32 SDIO on WHD driver
*/
#include <stdio.h>
#include <string.h>
#include "whd_thread.h"
#include "bus_protocols/whd_bus_sdio_protocol.h"
#include "cyabs_rtos.h"
#include "cyhal_sdio.h"
#define SDIO_RESPONSE_SHORT SDMMC_RESPONSE_SHORT
#define SDIO_WAIT_NO SDMMC_WAIT_NO
#define SDIO_CPSM_ENABLE SDMMC_CPSM_ENABLE
#define SDIO_CMDTRANS SDMMC_CMD_CMDTRANS
#define SDIO_FLAG_CMDACT (SDMMC_STA_CPSMACT | SDMMC_STA_DPSMACT)
#define SDIO_TRANSFER_DIR_TO_SDIO SDMMC_TRANSFER_DIR_TO_SDMMC
#define SDIO_TRANSFER_DIR_TO_CARD SDMMC_TRANSFER_DIR_TO_CARD
#define SDIO_TRANSFER_MODE_BLOCK SDMMC_TRANSFER_MODE_BLOCK
#define SDIO_DPSM_ENABLE SDMMC_DPSM_ENABLE
#define SDIO_DPSM_DISABLE SDMMC_DPSM_DISABLE
#define SDIO_DCTRL_SDIOEN SDMMC_DCTRL_SDIOEN /* 1 << 11 */
#define SDIO_DCTRL_DTMODE_1 SDMMC_DCTRL_DTMODE_1 /* 1<<3 */
#define SDIO_STA_DTIMEOUT SDMMC_STA_DTIMEOUT
#define SDIO_STA_CTIMEOUT SDMMC_STA_CTIMEOUT
#define SDIO_STA_CCRCFAIL SDMMC_STA_CCRCFAIL
#define SDIO_STA_DCRCFAIL SDMMC_STA_DCRCFAIL
#define SDIO_STA_TXUNDERR SDMMC_STA_TXUNDERR
#define SDIO_STA_RXOVERR SDMMC_STA_RXOVERR
#define SDIO_STA_TXACT SDMMC_STA_CPSMACT
#define SDIO_STA_RXACT SDMMC_STA_DPSMACT
#define SDIO_STA_CMDREND SDMMC_STA_CMDREND
#define SDIO_STA_CMDSENT SDMMC_STA_CMDSENT
#define SDIO_CMD_CMDTRANS SDMMC_CMD_CMDTRANS
#define SDIO SDMMC1
#define COMMAND_FINISHED_CMD52_TIMEOUT_LOOPS (100000)
#define BUS_LEVEL_MAX_RETRIES 10
#define SDIO_CMD_5 5
#define SDIO_CMD_53 53
#define SDIO_STA_STBITERR ((uint32_t)0x00000200) /*!<Start bit not detected on all data signals in wide bus mode */
#define SDIO_ERROR_MASK ( SDMMC_STA_CCRCFAIL | SDMMC_STA_DCRCFAIL | SDMMC_STA_CTIMEOUT | SDMMC_STA_DTIMEOUT | SDMMC_STA_TXUNDERR | SDMMC_STA_RXOVERR )
#define LINK_MTU 1024
#define MAX(a,b) (a>b)?a:b
extern pinconfig_t PinConfig[];
extern SD_HandleTypeDef hsd;
/* for debug prints only */
//static int num = 0;
static uint32_t dctrl;
static whd_driver_t whd_handler;
static cyhal_sdio_irq_handler_t sdio_irq_handler;
static uint8_t temp_dma_buffer[2048] __attribute__((aligned(8)));
static uint8_t *user_data;
static uint32_t user_data_size;
static uint8_t *dma_data_source;
static uint32_t dma_transfer_size;
static cyhal_transfer_t current_transfer_direction;
static cy_semaphore_t sdio_transfer_finished_semaphore;
static volatile uint32_t sdio_transfer_failed = 0;
static volatile uint32_t irqstatus = 0;
static int current_command = 0;
static cy_rslt_t sdio_enable_high_speed(void)
{
SDMMC_InitTypeDef sdio_init_structure;
sdio_init_structure.ClockDiv = SDMMC_HSpeed_CLK_DIV;
sdio_init_structure.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
sdio_init_structure.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
sdio_init_structure.BusWide = SDMMC_BUS_WIDE_4B;
sdio_init_structure.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_ENABLE;
SDMMC_Init(SDMMC1, sdio_init_structure);
return CY_RSLT_SUCCESS;
}
static uint32_t find_optimal_block_size(uint32_t data_size)
{
if (data_size > (uint32_t) 256) {
return 512;
}
if (data_size > (uint32_t) 128) {
return 256;
}
if (data_size > (uint32_t) 64) {
return 128;
}
if (data_size > (uint32_t) 32) {
return 64;
}
if (data_size > (uint32_t) 16) {
return 32;
}
if (data_size > (uint32_t) 8) {
return 16;
}
if (data_size > (uint32_t) 4) {
return 8;
}
if (data_size > (uint32_t) 2) {
return 4;
}
return 4;
}
static uint32_t sdio_get_blocksize(uint32_t blocksize)
{
uint32_t n = 0;
blocksize >>= 1;
while (blocksize) {
n++;
blocksize >>= 1;
}
n <<= 4;
return n;
}
static void sdio_prepare_data_transfer(cyhal_transfer_t direction, uint32_t block_size, uint8_t *data, uint16_t data_size)
{
/* Setup a single transfer using the temp buffer */
user_data = data;
user_data_size = data_size;
dma_transfer_size = (uint32_t)(((data_size + (uint16_t) block_size - 1) / (uint16_t) block_size) * (uint16_t) block_size);
if (direction == CYHAL_WRITE) {
#if !(defined(DUAL_CORE) && defined(CORE_CM4))
SCB_CleanDCache_by_Addr((uint32_t *)dma_data_source, data_size + 32);
#endif
memcpy(temp_dma_buffer, data, data_size);
dma_data_source = temp_dma_buffer;
} else {
dma_data_source = (uint8_t *)temp_dma_buffer;
//VIKR
//memset(dma_data_source,0x12,data_size);
#if !(defined(DUAL_CORE) && defined(CORE_CM4))
/* Cache-Invalidate the output from DMA */
SCB_CleanDCache_by_Addr((uint32_t *)dma_data_source, data_size + 32);
#endif
}
SDIO->DTIMER = (uint32_t) 0xFFFFFFFF;
SDIO->DLEN = dma_transfer_size;
dctrl = sdio_get_blocksize(block_size) | ((direction == CYHAL_READ) ? SDIO_TRANSFER_DIR_TO_SDIO : SDIO_TRANSFER_DIR_TO_CARD) | SDIO_TRANSFER_MODE_BLOCK | SDIO_DPSM_DISABLE | SDIO_DCTRL_SDIOEN;
SDIO->DCTRL = dctrl;
SDMMC1->IDMACTRL = SDMMC_ENABLE_IDMA_SINGLE_BUFF;
SDMMC1->IDMABASE0 = (uint32_t) dma_data_source;
}
static void sdio_enable_bus_irq(void)
{
SDMMC1->MASK = SDMMC_IT_RXOVERR | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND | SDMMC_IT_CMDREND | SDMMC_IT_CMDSENT;
}
void SDMMC1_IRQHandler(void)
{
uint32_t intstatus = SDIO->STA;
irqstatus = intstatus;
//VIKR | SDIO_STA_STBITERR )
if ((intstatus & (SDIO_STA_CCRCFAIL | SDIO_STA_DCRCFAIL | SDIO_STA_TXUNDERR | SDIO_STA_RXOVERR)) != 0) {
WPRINT_WHD_DEBUG(("sdio error flagged\n"));
sdio_transfer_failed = intstatus;
SDIO->ICR = (uint32_t) 0xffffffff;
cy_rtos_set_semaphore(&sdio_transfer_finished_semaphore, WHD_TRUE);
} else {
if ((intstatus & (SDMMC_STA_CMDREND | SDMMC_STA_CMDSENT)) != 0) {
if ((SDMMC1->RESP1 & 0x800) != 0) {
sdio_transfer_failed = irqstatus;
cy_rtos_set_semaphore(&sdio_transfer_finished_semaphore, WHD_TRUE);
}
/* Clear all command/response interrupts */
SDMMC1->ICR = (SDMMC_STA_CMDREND | SDMMC_STA_CMDSENT);
}
/* Check whether the external interrupt was triggered */
if (intstatus & SDMMC_STA_SDIOIT) {
/* Clear the interrupt */
SDMMC1->ICR = SDMMC_STA_SDIOIT;
/* Inform WICED WWD thread */
sdio_irq_handler(whd_handler, CYHAL_SDIO_CARD_INTERRUPT);
}
if (intstatus & SDMMC_STA_DATAEND) {
SDMMC1->ICR = SDMMC_STA_DATAEND;
SDMMC1->DLEN = 0;
SDMMC1->DCTRL = SDMMC_DCTRL_SDIOEN;
SDMMC1->IDMACTRL = SDMMC_DISABLE_IDMA;
SDMMC1->CMD = 0;
cy_rtos_set_semaphore(&sdio_transfer_finished_semaphore, WHD_TRUE);
}
}
}
//void sdio_dma_irq(void)
//{
// /* Clear interrupt */
// DMA2->LIFCR = (uint32_t)(0x3F << 22);
// cy_rtos_set_semaphore(&sdio_transfer_finished_semaphore, WHD_TRUE);
//}
cy_rslt_t cyhal_sdio_init(cyhal_sdio_t *obj, cyhal_gpio_t cmd, cyhal_gpio_t clk, cyhal_gpio_t data0, cyhal_gpio_t data1, cyhal_gpio_t data2, cyhal_gpio_t data3)
{
cy_rslt_t ret = CY_RSLT_SUCCESS;
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_SDMMC1_CLK_ENABLE();
HAL_GPIO_Init(PinConfig[cmd].port, &PinConfig[cmd].config);
HAL_GPIO_Init(PinConfig[clk].port, &PinConfig[clk].config);
HAL_GPIO_Init(PinConfig[data0].port, &PinConfig[data0].config);
HAL_GPIO_Init(PinConfig[data1].port, &PinConfig[data1].config);
HAL_GPIO_Init(PinConfig[data2].port, &PinConfig[data2].config);
HAL_GPIO_Init(PinConfig[data3].port, &PinConfig[data3].config);
/* Reset SDIO Block */
SDMMC_PowerState_OFF(SDMMC1);
__HAL_RCC_SDMMC1_FORCE_RESET();
__HAL_RCC_SDMMC1_RELEASE_RESET();
/* Enable the SDIO Clock */
__HAL_RCC_SDMMC1_CLK_ENABLE();
#if !(defined(DUAL_CORE) && defined(CORE_CM4))
/* Disable DCache for STM32H7 family */
SCB_CleanDCache();
SCB_DisableDCache();
#endif
WPRINT_WHD_DEBUG(("in init: %p\n", sdio_transfer_finished_semaphore));
// Lower speed configuration
SDMMC_InitTypeDef sdio_init_structure;
sdio_init_structure.ClockDiv = SDMMC_INIT_CLK_DIV;
sdio_init_structure.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
sdio_init_structure.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
sdio_init_structure.BusWide = SDMMC_BUS_WIDE_1B;
sdio_init_structure.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
ret = SDMMC_Init(SDMMC1, sdio_init_structure);
ret |= SDMMC_PowerState_ON(SDMMC1);
ret |= SDMMC_SetSDMMCReadWaitMode(SDMMC1, SDMMC_READ_WAIT_MODE_CLK);
if (ret) {
return ret;
}
/* Clear all SDIO interrupts */
SDMMC1->ICR = (uint32_t) 0xffffffff;
/* Turn on SDIO IRQ */
/* Must be lower priority than the value of configMAX_SYSCALL_INTERRUPT_PRIORITY */
/* otherwise FreeRTOS will not be able to mask the interrupt */
/* keep in mind that ARMCM7 interrupt priority logic is inverted, the highest value */
/* is the lowest priority */
HAL_NVIC_EnableIRQ((IRQn_Type) SDMMC1_IRQn);
HAL_NVIC_SetPriority(SDMMC1_IRQn, 5, 0);
WPRINT_WHD_DEBUG(("after enable sdio: %p\n", sdio_transfer_finished_semaphore));
if (cy_rtos_init_semaphore(&sdio_transfer_finished_semaphore, 1, 0) != WHD_SUCCESS) {
cy_rtos_deinit_semaphore(&sdio_transfer_finished_semaphore);
return -1;
}
WPRINT_WHD_DEBUG(("cy_rtos_init_semaphore: %p\n", sdio_transfer_finished_semaphore));
return ret;
}
void cyhal_sdio_free(cyhal_sdio_t *obj)
{
//TODO
}
cy_rslt_t cyhal_sdio_configure(cyhal_sdio_t *obj, const cyhal_sdio_cfg_t *config)
{
return sdio_enable_high_speed();
}
cy_rslt_t cyhal_sdio_send_cmd(const cyhal_sdio_t *obj, cyhal_transfer_t direction, cyhal_sdio_command_t command, uint32_t argument, uint32_t *response)
{
uint32_t loop_count = 0;
cy_rslt_t result;
uint16_t attempts = 0;
uint32_t temp_sta;
if (response != NULL) {
*response = 0;
}
current_command = 0;
restart:
SDIO->ICR = (uint32_t) 0xFFFFFFFF;
++attempts;
/* Check if we've tried too many times */
if (attempts >= (uint16_t) BUS_LEVEL_MAX_RETRIES) {
/* WWD_SDIO_RETRIES_EXCEEDED */
result = -1;
goto exit;
}
/* Send the command */
SDIO->ARG = argument;
SDIO->CMD = (uint32_t)(command | SDIO_RESPONSE_SHORT | SDIO_WAIT_NO | SDIO_CPSM_ENABLE);
loop_count = (uint32_t) COMMAND_FINISHED_CMD52_TIMEOUT_LOOPS;
do {
temp_sta = SDIO->STA;
loop_count--;
if (loop_count == 0 /*|| ((response != NULL) && ((temp_sta & SDIO_ERROR_MASK) != 0))*/) {
WPRINT_WHD_DEBUG(("Restart single access loop count %ld stat %lx\n", loop_count, temp_sta));
HAL_Delay(10U);
goto restart;
}
} while ((temp_sta & SDIO_FLAG_CMDACT) != 0);
if (response != NULL) {
*response = SDIO->RESP1;
}
result = CY_RSLT_SUCCESS;
exit:
if (result) {
WPRINT_WHD_ERROR(("SDIO->POWER %lx \n", SDIO->POWER));
WPRINT_WHD_ERROR(("SDIO->CLKCR %lx \n", SDIO->CLKCR));
WPRINT_WHD_ERROR(("result %lx \n", result));
WPRINT_WHD_ERROR(("cyhal_sdio_send_cmd %s\n", (result == 0) ? "Passed" : "Failed"));
while (1);
}
SDMMC1->CMD = 0;
//WPRINT_WHD_DEBUG(("%d %s cmd 0x%x arg 0x%x resp 0x%x\n",num++,(direction!=CYHAL_READ)?"Write":"Read",command,argument,(response)?*response:0));
return result;
}
cy_rslt_t cyhal_sdio_bulk_transfer(cyhal_sdio_t *obj, cyhal_transfer_t direction, uint32_t argument, const uint32_t *data, uint16_t length, uint32_t *response)
{
cy_rslt_t result;
uint16_t attempts = 0;
uint32_t block_size = 64;
sdio_cmd_argument_t arg;
uint32_t cmd;
current_command = SDIO_CMD_53;
current_transfer_direction = direction;
arg.value = argument;
sdio_enable_bus_irq();
if (response != NULL) {
*response = 0;
}
restart:
sdio_transfer_failed = 0;
SDMMC1->ICR = (uint32_t) 0xFFFFFFFF;
++attempts;
/* Check if we've tried too many times */
if (attempts >= (uint16_t) BUS_LEVEL_MAX_RETRIES) {
/* WWD_SDIO_RETRIES_EXCEEDED */
WPRINT_WHD_ERROR(("Too much attempt\n"));
result = -1;
goto exit;
}
/* Dodgy STM32 hack to set the CMD53 byte mode size to be the same as the block size */
if (arg.cmd53.block_mode == 0) {
block_size = find_optimal_block_size(arg.cmd53.count);
if (block_size < SDIO_512B_BLOCK) {
arg.cmd53.count = block_size;
} else {
arg.cmd53.count = 0;
}
argument = arg.value;
}
SDMMC1->CMD |= SDMMC_CMD_CMDTRANS;
/* Prepare the SDIO for a data transfer */
sdio_prepare_data_transfer(direction, block_size, (uint8_t *) data, (uint32_t) length);
/* Send the command */
//WPRINT_WHD_DEBUG(("%d bs=%d argument=%x\n",num++,block_size,argument));
SDMMC1->ARG = argument;
cmd = (uint32_t)(SDIO_CMD_53 | SDMMC_RESPONSE_SHORT | SDMMC_WAIT_NO | SDMMC_CPSM_ENABLE | SDMMC_CMD_CMDTRANS);
SDMMC1->CMD = cmd;
/* Wait for the whole transfer to complete */
//WPRINT_WHD_DEBUG(("cy_rtos_get_semaphore: %d\n", sdio_transfer_finished_semaphore));
result = cy_rtos_get_semaphore(&sdio_transfer_finished_semaphore, 50, WHD_FALSE);
if (result != CY_RSLT_SUCCESS) {
WPRINT_WHD_ERROR(("failed getting semaphore\n"));
goto exit;
}
if (sdio_transfer_failed) {
WPRINT_WHD_DEBUG(("try again sdio_transfer_failed %"PRIu32" irq %"PRIu32"\n", sdio_transfer_failed, irqstatus));
goto restart;
}
/* Check if there were any SDIO errors */
if ((SDIO->STA & (SDIO_STA_DTIMEOUT | SDIO_STA_CTIMEOUT)) != 0) {
WPRINT_WHD_DEBUG(("sdio errors SDIO_STA_DTIMEOUT | SDIO_STA_CTIMEOUT\n"));
goto restart;
} else if (((SDIO->STA & (SDIO_STA_CCRCFAIL | SDIO_STA_DCRCFAIL | SDIO_STA_TXUNDERR | SDIO_STA_RXOVERR)) != 0)) {
WPRINT_WHD_DEBUG(("sdio errors SDIO_STA_CCRCFAIL | SDIO_STA_DCRCFAIL | SDIO_STA_TXUNDERR | SDIO_STA_RXOVER \n"));
goto restart;
}
if (direction == CYHAL_READ) {
memcpy(user_data, dma_data_source, (size_t) user_data_size);
}
if (response != NULL) {
*response = SDIO->RESP1;
}
result = CY_RSLT_SUCCESS;
exit:
SDMMC1->CMD = 0;
//WPRINT_WHD_DEBUG(("%d %s cmd 53 argument %lx datasize %d blocknumber 0x%x cmdis %lx %lu dctrl = %x\n", num++, (direction != CYHAL_READ) ? "Write" : "Read", argument, length, arg.cmd53.count, cmd, cmd, dctrl));
return result;
}
cy_rslt_t cyhal_sdio_transfer_async(cyhal_sdio_t *obj, cyhal_transfer_t direction, uint32_t argument, const uint32_t *data, uint16_t length)
{
//TODO
return CYHAL_SDIO_RET_NO_SP_ERRORS;
}
bool cyhal_sdio_is_busy(const cyhal_sdio_t *obj)
{
return false;
}
cy_rslt_t cyhal_sdio_abort_async(const cyhal_sdio_t *obj)
{
//TODO
return CYHAL_SDIO_RET_NO_SP_ERRORS;
}
void cyhal_sdio_register_callback(cyhal_sdio_t *obj, cyhal_sdio_irq_handler_t handler, void *handler_arg)
{
whd_handler = (whd_driver_t)handler_arg;
sdio_irq_handler = handler;
}
void cyhal_sdio_enable_event(cyhal_sdio_t *obj, cyhal_sdio_irq_event_t event, uint8_t intr_priority, bool enable)
{
//TODO
}

View File

@ -0,0 +1,29 @@
/*
* Copyright 2020 Arduino SA
* 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
*
* 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.
*/
/** @file
* Provides stubs for the WHD driver needed by ARMClang
*/
#include <stdio.h>
#include <string.h>
#include "cyhal_spi.h"
cy_rslt_t cyhal_spi_transfer(cyhal_spi_t *obj, const uint8_t *tx, size_t tx_length, uint8_t *rx, size_t rx_length, uint8_t write_fill)
{
// Do nothing
}

View File

@ -0,0 +1,20 @@
/*
* Copyright 2020 Arduino SA
* 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
*
* 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.
*/
/** @file
* Empty file to be compliant with Cypress COMPONENT_WHD
*/

View File

@ -0,0 +1,49 @@
/*
* Copyright 2020 Arduino SA
* 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
*
* 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.
*/
/** @file
* Provides wiced fs porting to generic mbed APIs
*/
#pragma once
#include "whd_config.h"
#include "BlockDevice.h"
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************
* Type Definitions
******************************************************/
/**
* Mount the physical device
*
* This assumes that the device is ready to read/write immediately.
*
* @param[in] device - physical media to init
* @param[out] fs_handle_out - Receives the filesystem handle.
*
* @return WICED_SUCCESS on success
*/
wiced_result_t wiced_filesystem_mount(mbed::BlockDevice *device, wiced_filesystem_handle_type_t fs_type, wiced_filesystem_t *fs_handle_out, const char *mounted_name);
#ifdef __cplusplus
} /*extern "C" */
#endif

View File

@ -0,0 +1,214 @@
/*
* Copyright 2020 Arduino SA
* 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
*
* 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.
*/
/** @file
* Provides wiced fs porting to generic mbed APIs
*/
#include <stddef.h>
#include <stdio.h>
#include <stdbool.h>
#include <string>
#include "sockets.h"
#include "resources.h"
#include "wiced_filesystem.h"
#include "wiced_bd.h"
#include "QSPIFBlockDevice.h"
#include "MBRBlockDevice.h"
#include "FATFileSystem.h"
#define WIFI_DEFAULT_FIRMWARE_PATH "/wlan/4343WA1.BIN"
#define WIFI_DEFAULT_MOUNT_NAME "wlan"
#define WIFI_DEFAULT_PARTITION 1
#define WIFI_DEFAULT_FS 0
QSPIFBlockDevice *qspi_bd = NULL;
MBRBlockDevice *mbr_bd = NULL;
FATFileSystem *wifi_fs = NULL;
wiced_filesystem_t resource_fs_handle;
MBED_WEAK void wiced_filesystem_mount_error(void)
{
WPRINT_WHD_ERROR(("Failed to mount the filesystem containing the WiFi firmware.\n\r"));
whd_print_logbuffer();
while (1) {}
}
MBED_WEAK void wiced_filesystem_firmware_error(void)
{
WPRINT_WHD_ERROR(("Please run the \"PortentaWiFiFirmwareUpdater\" sketch once to install the WiFi firmware.\n\r"));
whd_print_logbuffer();
while (1) {}
}
MBED_WEAK wiced_result_t whd_firmware_check_hook(const char *mounted_name, int mount_err)
{
DIR *dir;
struct dirent *ent;
std::string dir_name(mounted_name);
if (mount_err) {
wiced_filesystem_mount_error();
} else {
if ((dir = opendir(mounted_name)) != NULL) {
// print all the files and directories within directory
while ((ent = readdir(dir)) != NULL) {
std::string fullname = "/" + dir_name + "/" + std::string(ent->d_name);
if (fullname == WIFI_DEFAULT_FIRMWARE_PATH) {
closedir(dir);
return WICED_SUCCESS;
}
}
closedir(dir);
}
wiced_filesystem_firmware_error();
}
return WICED_ERROR;
}
static wiced_result_t whd_default_firmware_restore(void)
{
#if MBED_CONF_APP_WIFI_FIRMWARE_RESTORE
size_t ret;
FILE *fp;
//This should only happen the firs time or if the partition table has been overwritten i.e QSPI tests
WPRINT_WHD_DEBUG(("MBRBlockDevice init failed, repatitioning\n\r"));
if (mbr_bd->partition(qspi_bd, 1, 0x0B, 0, 1024 * 1024) != BD_ERROR_OK) {
return WICED_ERROR;
}
WPRINT_WHD_DEBUG(("MBRBockDevice repatitioning OK, reinit\n\r"));
if (mbr_bd->init() != BD_ERROR_OK) {
return WICED_ERROR;
}
WPRINT_WHD_DEBUG(("MBRBockDevice init OK\n\r"));
wifi_fs = new FATFileSystem(WIFI_DEFAULT_MOUNT_NAME);
if (wifi_fs->reformat(mbr_bd) != 0) {
return WICED_ERROR;
}
WPRINT_WHD_DEBUG(("FATFileSystem reformat and mount OK\n\r"));
fp = fopen(WIFI_DEFAULT_FIRMWARE_PATH, "wb");
if (fp == NULL) {
return WICED_ERROR;
}
ret = fwrite(wifi_firmware_image_data, wifi_firmware_image.size, 1, fp);
if (ret != wifi_firmware_image.size) {
return WICED_ERROR;
}
fclose(fp);
if (mbr_bd->sync() != 0) {
return WICED_ERROR;
}
WPRINT_WHD_DEBUG(("Sync BlockDevice OK\n\r"));
if (wifi_fs->unmount() != 0) {
return WICED_ERROR;
}
WPRINT_WHD_DEBUG(("Unmount FS\n\r"));
wifi_fs = NULL;
#endif
return WICED_SUCCESS;
}
wiced_result_t wiced_filesystem_init(void)
{
if (mbr_bd == NULL && wifi_fs == NULL) {
WPRINT_WHD_DEBUG(("Initialize FileSystem with Mbed default settings\n\r"));
qspi_bd = new QSPIFBlockDevice(PD_11, PD_12, PF_7, PD_13, PF_10, PG_6, QSPIF_POLARITY_MODE_1, 40000000);
if (qspi_bd->init() == BD_ERROR_OK) {
mbr_bd = new MBRBlockDevice(qspi_bd, WIFI_DEFAULT_PARTITION);
if (mbr_bd->init() == BD_ERROR_OK) {
return WICED_SUCCESS;
} else {
return whd_default_firmware_restore();
}
}
return WICED_ERROR;
} else {
WPRINT_WHD_DEBUG(("FileSystem initialized with user settings\n\r"));
return WICED_SUCCESS;
}
}
wiced_result_t wiced_filesystem_mount(BlockDevice *device, wiced_filesystem_handle_type_t fs_type, wiced_filesystem_t *fs_handle_out, const char *mounted_name)
{
wifi_fs = new FATFileSystem(mounted_name);
int err = wifi_fs->mount(device);
whd_firmware_check_hook(mounted_name, err);
if (!err) {
//fs_handle_out = wifi_fs
return WICED_SUCCESS;
}
return WICED_ERROR;
}
wiced_result_t wiced_filesystem_file_open(wiced_filesystem_t *fs_handle, wiced_file_t *file_handle_out, const char *filename, wiced_filesystem_open_mode_t mode)
{
/* This is called by mbed test system */
//if (mbr_bd == NULL && wifi_fs == NULL) {
// wiced_filesystem_init();
//}
//This can be called from user sketch to provide custom block device and mount point before WiFi.beginAP or WiFi.begin
if (wifi_fs == NULL) {
wiced_filesystem_mount(mbr_bd, WIFI_DEFAULT_FS, fs_handle, WIFI_DEFAULT_MOUNT_NAME);
}
if (wifi_fs == NULL) {
return WICED_ERROR;
}
*file_handle_out = open(filename, mode);
if (*file_handle_out == -1) {
return WICED_ERROR;
}
return WICED_SUCCESS;
}
wiced_result_t wiced_filesystem_file_seek(wiced_file_t *file_handle, int64_t offset, wiced_filesystem_seek_type_t whence)
{
if (*file_handle == -1) {
return WICED_ERROR;
}
lseek(*file_handle, offset, whence);
return WICED_SUCCESS;
}
wiced_result_t wiced_filesystem_file_read(wiced_file_t *file_handle, void *data, uint64_t bytes_to_read, uint64_t *returned_bytes_count)
{
if (*file_handle == -1) {
return WICED_ERROR;
}
*returned_bytes_count = read(*file_handle, data, bytes_to_read);
return WICED_SUCCESS;
}
wiced_result_t wiced_filesystem_file_close(wiced_file_t *file_handle)
{
if (*file_handle == -1) {
return WICED_ERROR;
}
close(*file_handle);
return WICED_SUCCESS;
}

View File

@ -0,0 +1,139 @@
/*
* Copyright 2020 Arduino SA
* 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
*
* 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.
*/
/** @file
* Provides wiced fs porting to generic mbed APIs
*/
#pragma once
#include "whd_config.h"
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************
* Enumerations
******************************************************/
typedef enum {
WICED_FILESYSTEM_OPEN_FOR_READ, /** Specifies read access to the object. Data can be read from the file - equivalent to "r" or "rb" */
WICED_FILESYSTEM_OPEN_FOR_WRITE, /** Specifies read/write access to the object. Data can be written to the file - equivalent to "r+" or "rb+" or "r+b" */
WICED_FILESYSTEM_OPEN_WRITE_CREATE, /** Opens for read/write access, creates it if it doesn't exist */
WICED_FILESYSTEM_OPEN_ZERO_LENGTH, /** Opens for read/write access, Truncates file to zero length if it exists, or creates it if it doesn't - equivalent to "w+", "wb+" or "w+b" */
WICED_FILESYSTEM_OPEN_APPEND, /** Opens for read/write access, places the current location at the end of the file ready for appending - equivalent to "a", "ab" */
WICED_FILESYSTEM_OPEN_APPEND_CREATE, /** Opens for read/write access, creates it if it doesn't exist, and places the current location at the end of the file ready for appending - equivalent to "a+", "ab+" or "a+b" */
} wiced_filesystem_open_mode_t;
typedef enum {
WICED_FILESYSTEM_SEEK_SET = SEEK_SET, /* Offset from start of file */
WICED_FILESYSTEM_SEEK_CUR = SEEK_CUR, /* Offset from current position in file */
WICED_FILESYSTEM_SEEK_END = SEEK_END, /* Offset from end of file */
} wiced_filesystem_seek_type_t;
typedef enum {
WICED_SUCCESS = 0,
WICED_ERROR = 1
} wiced_result_t;
/******************************************************
* Type Definitions
******************************************************/
/**
* File-system Handle Structure
*/
typedef int wiced_filesystem_t;
/**
* File Handle Structure
*
*/
typedef int wiced_file_t;
/**
* File-system type Handle Structure
*/
typedef int wiced_filesystem_handle_type_t;
/**
* Initialise the BlockDevice and filesystem module
*
* Initialises the BlockDevice and filesystem module before mounting a physical device.
*
* @return WICED_SUCCESS on success
*/
wiced_result_t wiced_filesystem_init(void);
/**
* Open a file for reading or writing
*
* @param[in] fs_handle - The filesystem handle to use - obtained from wiced_filesystem_mount
* @param[out] file_handle_out - a pointer to a wiced_file_t structure which will receive the
* file handle after it is opened
* @param[in] filename - The filename of the file to open
* @param[in] mode - Specifies read or write access
*
* @return WICED_SUCCESS on success
*/
wiced_result_t wiced_filesystem_file_open(wiced_filesystem_t *fs_handle, wiced_file_t *file_handle_out, const char *filename, wiced_filesystem_open_mode_t mode);
/**
* Seek to a location within a file
*
* This is similar to the fseek() in ISO C.
*
* @param[in] file_handle - The file handle on which to perform the seek.
* Must have been previously opened with wiced_filesystem_fopen.
* @param[in] offset - The offset in bytes
* @param[in] whence - WICED_FILESYSTEM_SEEK_SET = Offset from start of file
* WICED_FILESYSTEM_SEEK_CUR = Offset from current position in file
* WICED_FILESYSTEM_SEEK_END = Offset from end of file
*
* @return WICED_SUCCESS on success
*/
wiced_result_t wiced_filesystem_file_seek(wiced_file_t *file_handle, int64_t offset, wiced_filesystem_seek_type_t whence);
/**
* Reads data from a file into a memory buffer
*
* @param[in] file_handle - the file handle to read from
* @param[out] data - A pointer to the memory buffer that will
* receive the data that is read
* @param[in] bytes_to_read - the number of bytes to read
* @param[out] returned_item_count - the number of items successfully read.
*
* @return WICED_SUCCESS on success
*/
wiced_result_t wiced_filesystem_file_read(wiced_file_t *file_handle, void *data, uint64_t bytes_to_read, uint64_t *returned_bytes_count);
/**
* Close a file
*
* This is similar to the fclose() in ISO C.
*
* @param[in] file_handle - the file handle to close
*
* @return WICED_SUCCESS = success
*/
wiced_result_t wiced_filesystem_file_close(wiced_file_t *file_handle);
#ifdef __cplusplus
} /*extern "C" */
#endif

View File

@ -0,0 +1,49 @@
Permissive Binary License
Version 1.0, July 2019
Redistribution. Redistribution and use in binary form, without
modification, are permitted provided that the following conditions are
met:
1) Redistributions must reproduce the above copyright notice and the
following disclaimer in the documentation and/or other materials
provided with the distribution.
2) Unless to the extent explicitly permitted by law, no reverse
engineering, decompilation, or disassembly of this software is
permitted.
3) Redistribution as part of a software development kit must include the
accompanying file named <20>DEPENDENCIES<45> and any dependencies listed in
that file.
4) Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
Limited patent license. The copyright holders (and contributors) grant a
worldwide, non-exclusive, no-charge, royalty-free patent license to
make, have made, use, offer to sell, sell, import, and otherwise
transfer this software, where such license applies only to those patent
claims licensable by the copyright holders (and contributors) that are
necessarily infringed by this software. This patent license shall not
apply to any combinations that include this software. No hardware is
licensed hereunder.
If you institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the software
itself infringes your patent(s), then your rights granted under this
license shall terminate as of the date such litigation is filed.
DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS." ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,400 @@
/*
* Copyright (c) 2019, Cypress Semiconductor Corporation, All Rights Reserved
* SPDX-License-Identifier: LicenseRef-PBL
*
* This file and the related binary are licensed under the
* Permissive Binary License, Version 1.0 (the "License");
* you may not use these files except in compliance with the License.
*
* You may obtain a copy of the License here:
* LICENSE-permissive-binary-license-1.0.txt and at
* https://www.mbed.com/licenses/PBL-1.0
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "wiced_resource.h"
#if defined(CY_STORAGE_WIFI_DATA)
CY_SECTION_WHD(CY_STORAGE_WIFI_DATA) __attribute__((used))
#endif
const unsigned char wifi_firmware_clm_blob_image_data[7222] = {
66, 76, 79, 66, 60, 0, 0, 0, 132, 159, 16, 216, 1, 0, 0, 0, 2, 0, 0,
0, 0, 0, 0, 0, 60, 0, 0, 0, 246, 27, 0, 0, 183, 10, 32, 40, 0, 0, 0,
0, 0, 0, 0, 0, 50, 28, 0, 0, 4, 0, 0, 0, 42, 255, 237, 159, 0, 0, 0,
0, 67, 76, 77, 32, 68, 65, 84, 65, 0, 0, 12, 0, 2, 0, 57, 46, 49, 48,
46, 51, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 46, 50, 57, 46,
52, 0, 0, 0, 0, 0, 0, 0, 0, 184, 10, 0, 0, 67, 108, 109, 73, 109, 112,
111, 114, 116, 58, 32, 49, 46, 51, 54, 46, 51, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 66, 114, 111, 97, 100, 99, 111, 109, 45, 48, 46, 48,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 49, 0, 81, 50, 0, 3, 3, 3, 9, 3, 11,
4, 4, 4, 7, 4, 8, 4, 10, 4, 11, 5, 7, 8, 8, 9, 9, 9, 11, 11, 11, 38,
38, 38, 46, 38, 62, 38, 110, 38, 118, 38, 134, 38, 142, 38, 159, 38,
175, 46, 46, 54, 54, 54, 62, 54, 134, 62, 62, 102, 102, 102, 110, 102,
134, 102, 142, 102, 159, 110, 126, 110, 134, 110, 142, 134, 134, 134,
159, 142, 142, 151, 151, 151, 159, 151, 175, 159, 159, 65, 69, 1, 65,
82, 1, 65, 84, 1, 65, 85, 2, 66, 69, 1, 66, 71, 1, 66, 78, 1, 67, 65,
2, 67, 72, 1, 67, 89, 1, 67, 90, 1, 68, 69, 3, 68, 75, 1, 69, 69, 1,
69, 83, 1, 70, 73, 1, 70, 82, 1, 71, 66, 1, 71, 82, 1, 72, 82, 1, 72,
85, 1, 73, 68, 5, 73, 69, 1, 73, 83, 1, 73, 84, 1, 74, 80, 3, 75, 82,
4, 75, 87, 1, 76, 73, 1, 76, 84, 1, 76, 85, 1, 76, 86, 1, 77, 65, 1,
77, 84, 1, 77, 88, 1, 78, 76, 1, 78, 79, 1, 80, 76, 1, 80, 84, 1, 80,
89, 1, 82, 79, 1, 82, 85, 5, 83, 69, 1, 83, 73, 1, 83, 75, 1, 84, 82,
7, 84, 87, 2, 85, 83, 26, 1, 0, 255, 1, 30, 2, 0, 3, 76, 1, 3, 76, 2,
1, 66, 12, 3, 1, 0, 255, 1, 30, 2, 0, 7, 72, 0, 1, 58, 0, 3, 68, 6,
3, 74, 8, 1, 74, 10, 3, 68, 11, 3, 66, 12, 3, 1, 0, 255, 1, 30, 2, 0,
2, 64, 2, 1, 56, 2, 3, 1, 0, 255, 1, 30, 2, 0, 5, 72, 0, 1, 76, 1, 3,
76, 7, 1, 72, 12, 1, 66, 12, 3, 1, 0, 255, 1, 30, 2, 0, 4, 58, 0, 3,
68, 2, 1, 66, 7, 3, 58, 12, 3, 1, 0, 255, 1, 30, 2, 0, 5, 92, 0, 1,
86, 0, 3, 126, 7, 0, 92, 12, 1, 86, 12, 3, 1, 0, 255, 1, 30, 2, 0, 5,
70, 0, 3, 80, 1, 1, 80, 7, 3, 76, 12, 1, 72, 12, 3, 2, 4, 255, 1, 20,
4, 2, 1, 76, 4, 0, 2, 0, 3, 1, 20, 4, 2, 1, 76, 4, 1, 2, 0, 255, 1,
20, 4, 0, 1, 76, 4, 0, 3, 0, 4, 1, 20, 5, 2, 5, 76, 1, 3, 76, 4, 1,
70, 12, 3, 76, 14, 3, 54, 17, 1, 3, 0, 4, 1, 20, 5, 0, 6, 60, 0, 3,
68, 2, 1, 64, 8, 3, 48, 14, 1, 44, 14, 3, 64, 17, 1, 3, 0, 4, 1, 20,
5, 0, 3, 64, 3, 3, 64, 5, 1, 46, 16, 3, 2, 0, 3, 1, 20, 4, 0, 3, 64,
2, 0, 48, 14, 1, 44, 14, 3, 3, 0, 4, 1, 20, 5, 0, 6, 62, 0, 3, 66, 4,
1, 66, 7, 3, 62, 12, 3, 66, 14, 3, 42, 17, 1, 3, 0, 255, 1, 20, 5, 2,
2, 84, 4, 3, 78, 5, 1, 1, 0, 255, 1, 20, 2, 0, 2, 69, 2, 1, 79, 2, 3,
3, 0, 255, 1, 30, 5, 0, 1, 120, 5, 0, 0, 0, 255, 0, 0, 0, 2, 0, 255,
1, 23, 4, 2, 1, 92, 4, 0, 2, 0, 255, 1, 36, 4, 2, 1, 100, 4, 0, 2, 4,
3, 1, 20, 4, 2, 1, 76, 4, 0, 1, 0, 255, 1, 20, 2, 2, 1, 76, 2, 0, 2,
0, 255, 1, 20, 4, 4, 3, 56, 0, 3, 64, 9, 3, 56, 16, 3, 2, 1, 76, 4,
1, 74, 48, 0, 74, 49, 0, 74, 50, 0, 74, 51, 0, 74, 52, 0, 74, 53, 0,
74, 54, 0, 74, 55, 0, 74, 56, 0, 74, 57, 0, 0, 0, 4, 0, 0, 0, 37, 4,
0, 0, 12, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 4, 0, 1, 2, 3, 8, 12,
13, 14, 15, 16, 17, 18, 19, 8, 4, 5, 6, 7, 8, 9, 10, 11, 1, 1, 1, 10,
1, 11, 1, 12, 1, 13, 1, 14, 2, 2, 2, 10, 2, 11, 2, 12, 3, 9, 10, 10,
11, 11, 12, 12, 12, 13, 12, 14, 13, 13, 14, 14, 34, 46, 36, 48, 36,
64, 36, 116, 36, 140, 36, 144, 36, 161, 36, 165, 36, 177, 52, 60, 52,
64, 52, 124, 52, 140, 52, 144, 52, 165, 56, 64, 64, 64, 64, 100, 100,
100, 100, 116, 100, 140, 100, 144, 100, 165, 104, 128, 104, 140, 104,
165, 132, 140, 132, 144, 132, 165, 149, 149, 149, 161, 149, 165, 149,
177, 153, 161, 165, 165, 0, 1, 2, 1, 4, 1, 5, 1, 18, 2, 18, 19, 4, 18,
19, 29, 48, 2, 18, 20, 2, 18, 22, 1, 19, 3, 19, 28, 49, 3, 19, 30, 49,
3, 19, 31, 50, 2, 19, 32, 2, 19, 49, 1, 20, 2, 20, 38, 2, 20, 40, 2,
20, 44, 2, 20, 48, 2, 20, 49, 2, 21, 46, 1, 22, 2, 22, 49, 2, 23, 49,
1, 24, 1, 25, 1, 26, 3, 28, 38, 49, 2, 28, 49, 3, 33, 38, 49, 2, 33,
49, 1, 38, 1, 48, 1, 49, 69, 48, 0, 88, 65, 0, 88, 85, 0, 65, 85, 2,
74, 80, 1, 0, 0, 3, 0, 0, 0, 124, 10, 0, 0, 16, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 34, 46, 4, 36, 64, 4, 100, 144,
4, 149, 177, 4, 50, 48, 50, 48, 45, 48, 49, 45, 51, 48, 32, 50, 49,
58, 51, 48, 58, 48, 53, 0, 4, 2, 64, 19, 0, 64, 49, 0, 1, 2, 40, 14,
0, 40, 39, 0, 4, 4, 56, 19, 0, 58, 28, 0, 60, 39, 0, 70, 49, 0, 1, 3,
52, 15, 0, 64, 30, 0, 72, 39, 0, 4, 3, 60, 20, 0, 60, 38, 0, 60, 49,
0, 1, 3, 56, 14, 0, 60, 25, 0, 60, 39, 0, 6, 1, 84, 20, 0, 3, 1, 84,
15, 0, 4, 1, 60, 20, 0, 1, 1, 56, 15, 0, 6, 1, 84, 20, 0, 3, 1, 88,
15, 0, 6, 2, 84, 20, 0, 84, 49, 0, 3, 2, 84, 15, 0, 84, 39, 0, 0, 0,
4, 2, 66, 20, 0, 66, 48, 0, 1, 2, 54, 15, 0, 54, 39, 0, 6, 2, 92, 20,
0, 80, 49, 0, 3, 2, 88, 15, 0, 76, 39, 0, 4, 2, 66, 20, 0, 64, 49, 0,
1, 2, 56, 15, 0, 56, 39, 0, 4, 1, 56, 19, 0, 1, 1, 48, 14, 0, 4, 1,
60, 19, 0, 1, 1, 56, 14, 0, 4, 1, 60, 19, 0, 1, 1, 56, 14, 0, 6, 2,
84, 23, 0, 112, 49, 0, 3, 2, 88, 19, 0, 116, 39, 0, 4, 5, 56, 19, 0,
70, 27, 0, 58, 34, 0, 68, 38, 0, 70, 49, 0, 1, 7, 52, 13, 0, 66, 22,
0, 68, 23, 0, 52, 26, 0, 62, 27, 0, 72, 33, 0, 74, 39, 0, 4, 4, 58,
19, 0, 80, 47, 0, 80, 51, 0, 80, 52, 0, 1, 4, 58, 13, 0, 66, 22, 0,
72, 38, 0, 80, 41, 0, 4, 6, 56, 19, 0, 68, 27, 0, 56, 34, 0, 68, 36,
0, 68, 42, 0, 68, 49, 0, 1, 6, 48, 14, 0, 68, 23, 0, 48, 26, 0, 62,
27, 0, 74, 33, 0, 72, 39, 0, 4, 5, 56, 19, 0, 78, 27, 0, 64, 34, 0,
68, 36, 0, 78, 43, 0, 1, 10, 62, 13, 0, 62, 22, 0, 78, 23, 0, 50, 26,
0, 56, 27, 0, 78, 32, 0, 78, 35, 0, 78, 37, 0, 60, 38, 0, 78, 41, 0,
4, 1, 120, 26, 0, 1, 1, 120, 21, 0, 4, 1, 120, 25, 0, 1, 1, 120, 20,
0, 4, 4, 56, 19, 0, 70, 27, 0, 58, 34, 0, 70, 49, 0, 1, 4, 48, 14, 0,
62, 23, 0, 48, 26, 0, 60, 39, 0, 4, 4, 56, 19, 0, 66, 27, 0, 60, 34,
0, 66, 49, 0, 1, 3, 56, 14, 0, 60, 24, 0, 60, 39, 0, 6, 2, 84, 20, 0,
84, 49, 0, 3, 2, 88, 15, 0, 88, 39, 0, 4, 4, 56, 19, 0, 70, 27, 0, 58,
34, 0, 70, 49, 0, 1, 4, 48, 14, 0, 62, 23, 0, 48, 26, 0, 60, 39, 0,
4, 2, 60, 28, 0, 68, 49, 0, 1, 2, 56, 24, 0, 56, 39, 0, 6, 2, 112, 28,
0, 112, 49, 0, 3, 2, 112, 24, 0, 112, 39, 0, 0, 2, 64, 18, 0, 64, 20,
0, 4, 4, 48, 18, 0, 48, 19, 0, 60, 29, 0, 60, 48, 0, 1, 2, 48, 17, 0,
48, 39, 0, 4, 2, 56, 19, 0, 68, 49, 0, 1, 2, 48, 14, 0, 60, 39, 0, 4,
6, 62, 19, 0, 90, 27, 0, 80, 35, 0, 90, 41, 0, 86, 45, 0, 118, 50, 0,
1, 6, 74, 14, 0, 98, 23, 0, 66, 26, 0, 74, 27, 0, 98, 34, 0, 118, 40,
0, 6, 1, 84, 24, 0, 3, 1, 88, 20, 0, 6, 1, 84, 24, 0, 3, 1, 88, 20,
0, 4, 2, 56, 19, 0, 60, 49, 0, 1, 2, 48, 14, 0, 60, 39, 0, 6, 2, 72,
20, 0, 72, 44, 0, 3, 2, 76, 15, 0, 76, 35, 0, 4, 2, 60, 20, 0, 60, 38,
0, 1, 2, 56, 15, 0, 64, 29, 0, 4, 2, 60, 20, 0, 60, 38, 0, 1, 1, 56,
18, 0, 4, 2, 84, 20, 0, 84, 38, 0, 1, 1, 56, 18, 0, 6, 1, 84, 22, 0,
3, 1, 88, 18, 0, 6, 1, 84, 22, 0, 3, 1, 88, 18, 0, 6, 2, 84, 20, 0,
112, 38, 0, 3, 2, 68, 15, 0, 96, 29, 0, 4, 2, 66, 20, 0, 66, 38, 0,
1, 2, 42, 15, 0, 64, 29, 0, 4, 2, 62, 20, 0, 66, 38, 0, 1, 2, 42, 15,
0, 64, 29, 0, 4, 2, 60, 20, 0, 60, 38, 0, 1, 2, 56, 15, 0, 64, 29, 0,
0, 0, 4, 4, 60, 20, 0, 60, 37, 0, 60, 44, 0, 60, 49, 0, 1, 4, 56, 15,
0, 60, 28, 0, 60, 35, 0, 60, 39, 0, 6, 2, 84, 21, 0, 84, 46, 0, 3, 2,
88, 16, 0, 88, 36, 0, 4, 2, 60, 20, 0, 60, 49, 0, 1, 2, 56, 15, 0, 60,
39, 0, 0, 2, 60, 20, 0, 60, 49, 0, 6, 1, 84, 25, 0, 3, 1, 84, 20, 0,
6, 1, 84, 25, 0, 3, 1, 88, 20, 0, 6, 2, 84, 20, 0, 112, 40, 0, 3, 2,
88, 15, 0, 116, 31, 0, 4, 3, 60, 20, 0, 60, 38, 0, 60, 49, 0, 1, 3,
56, 15, 0, 64, 29, 0, 60, 39, 0, 4, 1, 60, 49, 0, 1, 1, 52, 39, 0, 6,
1, 80, 49, 0, 3, 1, 80, 39, 0, 6, 1, 80, 49, 0, 3, 1, 80, 39, 0, 6,
2, 80, 19, 0, 80, 49, 0, 3, 2, 80, 14, 0, 80, 39, 0, 6, 1, 76, 49, 0,
3, 1, 76, 39, 0, 6, 1, 76, 48, 0, 3, 1, 68, 39, 0, 4, 1, 60, 49, 0,
1, 1, 60, 39, 0, 6, 1, 84, 49, 0, 3, 1, 88, 39, 0, 4, 1, 78, 49, 0,
1, 1, 78, 39, 0, 4, 3, 56, 33, 0, 68, 38, 0, 68, 49, 0, 1, 4, 48, 26,
0, 62, 27, 0, 74, 33, 0, 72, 39, 0, 4, 3, 56, 28, 0, 58, 38, 0, 62,
49, 0, 1, 4, 46, 23, 0, 48, 26, 0, 56, 29, 0, 56, 39, 0, 4, 2, 68, 33,
0, 68, 49, 0, 1, 2, 66, 26, 0, 60, 39, 0, 2, 1, 84, 48, 0, 65, 69, 1,
65, 82, 1, 65, 84, 1, 65, 85, 2, 66, 69, 1, 66, 71, 1, 66, 78, 1, 67,
65, 2, 67, 72, 1, 67, 89, 1, 67, 90, 1, 68, 69, 3, 68, 75, 1, 69, 69,
1, 69, 83, 1, 70, 73, 1, 70, 82, 1, 71, 66, 1, 71, 82, 1, 72, 82, 1,
72, 85, 1, 73, 68, 5, 73, 69, 1, 73, 83, 1, 73, 84, 1, 74, 80, 3, 75,
82, 4, 75, 87, 1, 76, 73, 1, 76, 84, 1, 76, 85, 1, 76, 86, 1, 77, 65,
1, 77, 84, 1, 77, 88, 1, 78, 76, 1, 78, 79, 1, 80, 76, 1, 80, 84, 1,
80, 89, 1, 82, 79, 1, 82, 85, 5, 83, 69, 1, 83, 73, 1, 83, 75, 1, 84,
87, 2, 85, 83, 25, 4, 5, 76, 0, 2, 76, 6, 2, 76, 10, 2, 76, 11, 2, 66,
12, 2, 1, 4, 62, 0, 0, 66, 4, 0, 62, 9, 0, 58, 10, 0, 4, 3, 58, 0, 2,
66, 7, 2, 58, 12, 2, 1, 5, 42, 0, 0, 50, 3, 0, 60, 8, 0, 54, 9, 0, 46,
10, 0, 4, 1, 56, 2, 2, 1, 1, 32, 1, 0, 4, 5, 58, 0, 2, 68, 6, 2, 74,
10, 2, 68, 11, 2, 66, 12, 2, 1, 5, 48, 0, 0, 58, 3, 0, 66, 8, 0, 58,
9, 0, 54, 10, 0, 4, 3, 86, 0, 2, 126, 7, 2, 86, 12, 2, 1, 3, 78, 0,
0, 126, 5, 0, 78, 10, 0, 4, 5, 70, 0, 2, 80, 6, 2, 80, 10, 2, 80, 11,
2, 72, 12, 2, 1, 5, 58, 0, 0, 68, 3, 0, 80, 8, 0, 68, 9, 0, 60, 10,
0, 4, 1, 64, 4, 2, 1, 1, 64, 2, 0, 4, 1, 76, 4, 2, 1, 1, 72, 2, 0, 0,
1, 64, 4, 2, 4, 4, 60, 0, 2, 64, 8, 2, 44, 13, 2, 44, 16, 2, 1, 3, 40,
0, 0, 52, 5, 0, 46, 11, 0, 0, 2, 64, 3, 2, 46, 16, 2, 4, 2, 64, 2, 2,
44, 14, 2, 1, 3, 54, 0, 0, 64, 6, 0, 52, 12, 0, 6, 1, 76, 4, 2, 3, 1,
76, 2, 0, 6, 1, 76, 4, 2, 3, 1, 76, 2, 0, 6, 1, 76, 4, 2, 3, 1, 76,
2, 0, 6, 1, 76, 4, 2, 3, 1, 128, 2, 0, 4, 1, 64, 4, 2, 1, 1, 64, 2,
0, 6, 1, 84, 4, 2, 3, 1, 72, 2, 0, 0, 1, 79, 2, 2, 4, 2, 120, 4, 2,
120, 17, 2, 1, 1, 120, 2, 0, 0, 0, 0, 1, 64, 4, 2, 4, 1, 80, 4, 2, 1,
1, 64, 2, 0, 4, 1, 88, 4, 2, 1, 1, 60, 2, 0, 6, 1, 100, 4, 2, 3, 1,
88, 2, 0, 4, 1, 64, 2, 2, 1, 1, 52, 1, 0, 4, 3, 56, 0, 2, 64, 9, 2,
56, 16, 2, 1, 2, 46, 0, 0, 52, 7, 0, 68, 69, 0, 0, 3, 0, 0, 0, 251,
3, 0, 0, 74, 80, 0, 0, 10, 0, 0, 0, 228, 2, 0, 0, 85, 83, 0, 0, 2, 0,
0, 0, 104, 0, 0, 0, 8, 12, 13, 14, 15, 16, 17, 18, 19, 8, 4, 5, 6, 7,
8, 9, 10, 11, 1, 14, 1, 0, 0, 0, 112, 11, 0, 0, 4, 3, 0, 0, 48, 3, 0,
0, 229, 27, 0, 0, 154, 3, 0, 0, 160, 10, 0, 0, 82, 1, 0, 0, 67, 24,
0, 0, 0, 9, 0, 0, 69, 4, 0, 0, 156, 11, 0, 0, 12, 4, 0, 0, 204, 27,
0, 0, 127, 178, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 212, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 0, 0, 20,
4, 0, 0, 49, 4, 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, 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, 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, 1,
0, 0, 0, 178, 10, 0, 0, 88, 65, 0, 0, 2, 0, 0, 0, 4, 4, 0, 0, 88, 84,
0, 0, 47, 0, 0, 0, 115, 8, 0, 0, 88, 86, 0, 0, 48, 0, 0, 0, 194, 0,
0, 0, 103, 1, 0, 0, 164, 11, 0, 0, 35, 97, 0, 17, 18, 19, 19, 0, 0,
35, 110, 0, 18, 8, 255, 255, 240, 0, 35, 114, 0, 17, 19, 19, 20, 0,
0, 48, 65, 0, 7, 8, 255, 255, 240, 16, 48, 66, 0, 0, 14, 0, 17, 0, 16,
48, 67, 0, 7, 6, 13, 5, 0, 16, 65, 67, 0, 18, 8, 255, 255, 240, 16,
65, 68, 0, 7, 33, 14, 39, 0, 48, 65, 69, 0, 7, 8, 6, 7, 0, 32, 65, 69,
1, 7, 33, 6, 43, 0, 32, 65, 70, 0, 7, 33, 14, 39, 0, 48, 65, 71, 0,
7, 41, 6, 47, 0, 32, 65, 73, 0, 6, 15, 5, 18, 0, 16, 65, 76, 0, 7, 33,
6, 43, 0, 32, 65, 77, 0, 7, 5, 13, 3, 0, 0, 65, 78, 0, 7, 14, 6, 17,
0, 32, 65, 79, 0, 7, 8, 255, 255, 240, 16, 65, 81, 0, 18, 8, 255, 255,
240, 16, 65, 82, 0, 7, 25, 6, 25, 0, 0, 65, 82, 1, 7, 14, 6, 17, 0,
0, 65, 83, 0, 6, 15, 5, 18, 0, 16, 65, 84, 0, 7, 33, 6, 43, 0, 32, 65,
84, 1, 7, 37, 6, 36, 0, 32, 65, 85, 0, 20, 42, 24, 46, 0, 0, 65, 85,
2, 20, 42, 23, 45, 0, 0, 65, 87, 0, 7, 34, 6, 31, 0, 0, 65, 88, 0, 18,
8, 255, 255, 240, 16, 65, 90, 0, 7, 14, 6, 17, 0, 32, 66, 65, 0, 7,
33, 6, 43, 0, 32, 66, 66, 0, 7, 22, 13, 23, 0, 16, 66, 68, 0, 7, 46,
6, 59, 0, 0, 66, 69, 0, 7, 33, 6, 43, 0, 32, 66, 69, 1, 7, 37, 6, 36,
0, 32, 66, 70, 0, 7, 33, 14, 39, 0, 16, 66, 71, 0, 7, 33, 6, 43, 0,
32, 66, 71, 1, 7, 37, 6, 36, 0, 32, 66, 72, 0, 7, 21, 6, 22, 0, 0, 66,
73, 0, 7, 33, 14, 39, 0, 16, 66, 74, 0, 7, 33, 14, 39, 0, 48, 66, 76,
0, 18, 8, 255, 255, 240, 16, 66, 77, 0, 6, 15, 5, 18, 0, 16, 66, 78,
0, 7, 8, 255, 255, 240, 0, 66, 78, 1, 19, 41, 22, 47, 0, 0, 66, 79,
0, 7, 15, 13, 18, 0, 32, 66, 81, 0, 18, 8, 255, 255, 240, 16, 66, 82,
0, 7, 43, 6, 52, 0, 32, 66, 83, 0, 20, 21, 23, 22, 0, 0, 66, 84, 0,
7, 8, 13, 7, 0, 48, 66, 86, 0, 18, 8, 255, 255, 240, 16, 66, 87, 0,
7, 45, 13, 51, 0, 48, 66, 89, 0, 7, 33, 255, 255, 240, 0, 66, 90, 0,
7, 15, 13, 18, 0, 16, 67, 65, 0, 0, 21, 0, 22, 0, 0, 67, 65, 2, 6, 15,
5, 18, 0, 16, 67, 67, 0, 18, 8, 255, 255, 240, 16, 67, 68, 0, 7, 33,
14, 39, 0, 48, 67, 70, 0, 7, 33, 14, 39, 0, 16, 67, 71, 0, 7, 33, 14,
39, 0, 48, 67, 72, 0, 7, 33, 6, 43, 0, 32, 67, 72, 1, 7, 37, 6, 36,
0, 32, 67, 73, 0, 7, 33, 14, 39, 0, 48, 67, 75, 0, 7, 44, 13, 50, 0,
16, 67, 76, 0, 7, 7, 6, 6, 0, 0, 67, 77, 0, 7, 33, 14, 39, 0, 16, 67,
78, 0, 23, 49, 26, 53, 0, 0, 67, 79, 0, 7, 13, 6, 11, 0, 32, 67, 80,
0, 18, 8, 255, 255, 240, 16, 67, 82, 0, 7, 14, 6, 15, 0, 32, 67, 85,
0, 7, 8, 14, 255, 192, 48, 67, 86, 0, 7, 33, 14, 39, 0, 16, 67, 87,
0, 18, 8, 255, 255, 240, 16, 67, 88, 0, 20, 42, 23, 46, 0, 16, 67, 89,
0, 7, 33, 6, 43, 0, 32, 67, 89, 1, 7, 37, 6, 36, 0, 32, 67, 90, 0, 7,
33, 6, 43, 0, 32, 67, 90, 1, 7, 37, 6, 36, 0, 32, 68, 69, 0, 7, 33,
6, 43, 0, 32, 68, 69, 3, 7, 37, 6, 36, 0, 32, 68, 74, 0, 7, 8, 255,
255, 240, 16, 68, 75, 0, 7, 33, 6, 43, 0, 32, 68, 75, 1, 7, 37, 6, 36,
0, 32, 68, 77, 0, 7, 15, 13, 18, 0, 16, 68, 79, 0, 7, 15, 13, 18, 0,
16, 68, 90, 0, 7, 5, 6, 4, 0, 32, 69, 48, 0, 7, 12, 6, 13, 0, 32, 69,
67, 0, 7, 14, 6, 17, 0, 32, 69, 69, 0, 7, 33, 6, 43, 0, 32, 69, 69,
1, 7, 37, 6, 36, 0, 32, 69, 71, 0, 7, 41, 21, 48, 0, 0, 69, 72, 0, 7,
6, 13, 5, 0, 16, 69, 82, 0, 7, 8, 255, 255, 240, 16, 69, 83, 0, 7, 33,
6, 43, 0, 32, 69, 83, 1, 7, 37, 6, 36, 0, 32, 69, 84, 0, 7, 33, 6, 43,
0, 0, 70, 73, 0, 7, 33, 6, 43, 0, 32, 70, 73, 1, 7, 37, 6, 36, 0, 32,
70, 74, 0, 7, 42, 13, 46, 0, 16, 70, 75, 0, 7, 33, 14, 39, 0, 16, 70,
77, 0, 6, 15, 5, 18, 0, 16, 70, 79, 0, 7, 33, 14, 39, 0, 48, 70, 82,
0, 7, 33, 6, 43, 0, 32, 70, 82, 1, 7, 37, 6, 36, 0, 32, 71, 65, 0, 7,
33, 14, 39, 0, 16, 71, 66, 0, 7, 33, 6, 43, 0, 32, 71, 66, 1, 7, 37,
6, 36, 0, 32, 71, 68, 0, 7, 43, 6, 52, 0, 0, 71, 69, 0, 7, 33, 14, 39,
0, 48, 71, 70, 0, 7, 33, 6, 43, 0, 0, 71, 71, 0, 7, 33, 14, 39, 0, 16,
71, 72, 0, 7, 33, 14, 39, 0, 48, 71, 73, 0, 7, 33, 14, 39, 0, 16, 71,
76, 0, 18, 8, 255, 255, 240, 16, 71, 77, 0, 7, 33, 14, 39, 0, 16, 71,
78, 0, 7, 33, 14, 39, 0, 48, 71, 80, 0, 7, 33, 6, 43, 0, 0, 71, 81,
0, 7, 33, 14, 39, 0, 16, 71, 82, 0, 7, 33, 6, 43, 0, 32, 71, 82, 1,
7, 37, 6, 36, 0, 32, 71, 83, 0, 18, 8, 255, 255, 240, 16, 71, 84, 0,
7, 14, 12, 17, 0, 16, 71, 85, 0, 0, 14, 0, 17, 0, 0, 71, 87, 0, 7, 33,
14, 39, 0, 16, 71, 89, 0, 7, 46, 13, 54, 0, 16, 72, 75, 0, 20, 43, 24,
52, 0, 0, 72, 77, 0, 18, 8, 255, 255, 240, 16, 72, 78, 0, 7, 47, 13,
61, 0, 0, 72, 82, 0, 7, 33, 6, 43, 0, 32, 72, 82, 1, 7, 37, 6, 36, 0,
32, 72, 84, 0, 7, 46, 13, 54, 0, 0, 72, 85, 0, 7, 33, 6, 43, 0, 32,
72, 85, 1, 7, 37, 6, 36, 0, 32, 73, 68, 0, 7, 8, 6, 7, 0, 0, 73, 68,
5, 7, 55, 14, 65, 0, 16, 73, 69, 0, 7, 33, 6, 43, 0, 32, 73, 69, 1,
7, 37, 6, 36, 0, 32, 73, 76, 0, 7, 5, 6, 4, 0, 32, 73, 77, 0, 7, 33,
14, 39, 0, 16, 73, 78, 0, 19, 41, 22, 47, 0, 32, 73, 79, 0, 7, 33, 14,
39, 0, 16, 73, 81, 0, 7, 33, 14, 39, 0, 16, 73, 82, 0, 7, 8, 14, 255,
192, 48, 73, 83, 0, 7, 33, 6, 43, 0, 32, 73, 83, 1, 7, 37, 6, 36, 0,
32, 73, 84, 0, 7, 33, 6, 43, 0, 32, 73, 84, 1, 7, 37, 6, 36, 0, 32,
74, 48, 0, 7, 38, 16, 42, 0, 0, 74, 49, 0, 15, 12, 255, 255, 240, 0,
74, 50, 0, 15, 5, 255, 255, 240, 0, 74, 51, 0, 15, 38, 255, 255, 240,
0, 74, 52, 0, 15, 24, 255, 255, 240, 0, 74, 53, 0, 15, 27, 255, 255,
240, 0, 74, 54, 0, 15, 28, 255, 255, 240, 0, 74, 55, 0, 15, 29, 255,
255, 240, 0, 74, 56, 0, 15, 40, 255, 255, 240, 0, 74, 57, 0, 7, 28,
16, 27, 0, 0, 74, 69, 0, 7, 33, 14, 39, 0, 16, 74, 77, 0, 7, 46, 14,
60, 0, 16, 74, 79, 0, 7, 1, 6, 0, 0, 32, 74, 80, 0, 15, 39, 17, 40,
0, 0, 74, 80, 1, 15, 28, 16, 27, 0, 0, 74, 80, 3, 15, 39, 16, 41, 0,
0, 74, 80, 88, 16, 8, 18, 7, 0, 0, 75, 65, 0, 22, 17, 25, 16, 0, 0,
75, 67, 0, 22, 46, 25, 54, 0, 0, 75, 68, 0, 7, 51, 6, 58, 0, 0, 75,
69, 0, 7, 33, 6, 38, 0, 32, 75, 71, 0, 7, 33, 14, 39, 0, 16, 75, 72,
0, 7, 43, 6, 52, 0, 0, 75, 73, 0, 20, 42, 23, 46, 0, 16, 75, 75, 0,
22, 8, 25, 7, 0, 0, 75, 77, 0, 7, 33, 14, 39, 0, 16, 75, 78, 0, 7, 15,
13, 18, 0, 16, 75, 80, 0, 18, 8, 255, 255, 240, 16, 75, 82, 0, 18, 55,
20, 44, 0, 0, 75, 82, 4, 23, 30, 26, 28, 0, 16, 75, 87, 0, 7, 8, 6,
7, 0, 32, 75, 87, 1, 7, 5, 6, 4, 0, 32, 75, 88, 0, 7, 48, 6, 56, 0,
0, 75, 89, 0, 8, 8, 8, 7, 0, 0, 75, 90, 0, 7, 36, 13, 34, 0, 0, 76,
65, 0, 7, 34, 6, 31, 0, 0, 76, 66, 0, 7, 46, 6, 59, 0, 32, 76, 67, 0,
7, 15, 13, 18, 0, 16, 76, 73, 0, 7, 33, 6, 43, 0, 0, 76, 73, 1, 7, 37,
6, 36, 0, 0, 76, 75, 0, 19, 43, 22, 52, 0, 0, 76, 82, 0, 7, 43, 21,
50, 0, 16, 76, 83, 0, 7, 33, 6, 43, 0, 0, 76, 84, 0, 7, 33, 6, 43, 0,
32, 76, 84, 1, 7, 37, 6, 36, 0, 32, 76, 85, 0, 7, 33, 6, 43, 0, 32,
76, 85, 1, 7, 37, 6, 36, 0, 32, 76, 86, 0, 7, 33, 6, 43, 0, 32, 76,
86, 1, 7, 37, 6, 36, 0, 32, 76, 89, 0, 7, 8, 15, 255, 192, 16, 77, 65,
0, 7, 12, 21, 12, 0, 32, 77, 65, 1, 7, 5, 21, 4, 0, 32, 77, 67, 0, 7,
33, 6, 43, 0, 0, 77, 68, 0, 7, 33, 6, 43, 0, 32, 77, 69, 0, 7, 33, 6,
43, 0, 32, 77, 70, 0, 7, 45, 13, 51, 0, 16, 77, 71, 0, 7, 33, 14, 39,
0, 48, 77, 72, 0, 18, 8, 255, 255, 240, 16, 77, 75, 0, 7, 33, 6, 43,
0, 32, 77, 76, 0, 7, 33, 14, 39, 0, 16, 77, 77, 0, 7, 33, 14, 39, 0,
16, 77, 78, 0, 7, 14, 12, 17, 0, 32, 77, 79, 0, 7, 50, 6, 59, 0, 0,
77, 80, 0, 6, 15, 5, 18, 0, 16, 77, 81, 0, 7, 33, 6, 43, 0, 0, 77, 82,
0, 7, 33, 6, 43, 0, 0, 77, 83, 0, 7, 33, 14, 39, 0, 48, 77, 84, 0, 7,
33, 6, 43, 0, 32, 77, 84, 1, 7, 37, 6, 36, 0, 32, 77, 85, 0, 7, 33,
6, 43, 0, 32, 77, 86, 0, 7, 10, 6, 10, 0, 32, 77, 87, 0, 7, 46, 6, 59,
0, 32, 77, 88, 0, 7, 5, 6, 4, 0, 0, 77, 88, 1, 7, 21, 6, 22, 0, 0, 77,
89, 0, 19, 41, 22, 47, 0, 0, 77, 90, 0, 7, 16, 13, 14, 0, 16, 78, 65,
0, 7, 16, 13, 14, 0, 16, 78, 67, 0, 7, 33, 14, 39, 0, 16, 78, 69, 0,
7, 33, 14, 39, 0, 16, 78, 70, 0, 7, 42, 12, 45, 0, 0, 78, 71, 0, 7,
26, 14, 26, 0, 48, 78, 73, 0, 7, 14, 6, 17, 0, 32, 78, 76, 0, 7, 33,
6, 43, 0, 32, 78, 76, 1, 7, 37, 6, 36, 0, 32, 78, 79, 0, 7, 33, 6, 43,
0, 32, 78, 79, 1, 7, 37, 6, 36, 0, 32, 78, 80, 0, 19, 9, 22, 8, 0, 0,
78, 82, 0, 7, 33, 14, 39, 0, 16, 78, 85, 0, 7, 14, 255, 255, 240, 16,
78, 90, 0, 7, 43, 6, 52, 0, 32, 79, 77, 0, 7, 33, 6, 43, 0, 32, 80,
65, 0, 19, 0, 22, 24, 0, 32, 80, 69, 0, 7, 14, 6, 17, 0, 32, 80, 70,
0, 7, 33, 14, 39, 0, 16, 80, 71, 0, 7, 2, 6, 0, 0, 0, 80, 72, 0, 7,
43, 6, 52, 0, 32, 80, 75, 0, 7, 50, 12, 55, 0, 32, 80, 76, 0, 7, 33,
6, 43, 0, 32, 80, 76, 1, 7, 37, 6, 36, 0, 32, 80, 77, 0, 7, 33, 14,
39, 0, 16, 80, 78, 0, 18, 8, 255, 255, 240, 16, 80, 82, 0, 0, 14, 0,
17, 0, 0, 80, 83, 0, 18, 8, 255, 255, 240, 0, 80, 84, 0, 7, 33, 6, 43,
0, 32, 80, 84, 1, 7, 37, 6, 36, 0, 32, 80, 87, 0, 7, 15, 13, 18, 0,
16, 80, 89, 0, 7, 46, 6, 59, 0, 0, 80, 89, 1, 7, 43, 6, 52, 0, 0, 81,
49, 0, 2, 8, 2, 7, 0, 0, 81, 50, 0, 0, 31, 0, 29, 0, 0, 81, 65, 0, 7,
50, 14, 57, 0, 48, 82, 69, 0, 7, 33, 6, 43, 0, 0, 82, 79, 0, 7, 33,
6, 43, 0, 32, 82, 79, 1, 7, 37, 6, 36, 0, 32, 82, 83, 0, 7, 33, 6, 43,
0, 32, 82, 85, 0, 7, 8, 255, 255, 240, 0, 82, 85, 5, 7, 11, 12, 9, 0,
0, 82, 87, 0, 7, 33, 14, 39, 0, 48, 83, 65, 0, 7, 34, 6, 32, 0, 32,
83, 66, 0, 7, 8, 255, 255, 240, 16, 83, 67, 0, 7, 45, 13, 51, 0, 16,
83, 68, 0, 7, 8, 14, 255, 192, 48, 83, 69, 0, 7, 33, 6, 43, 0, 32, 83,
69, 1, 7, 37, 6, 36, 0, 32, 83, 71, 0, 19, 44, 22, 50, 0, 32, 83, 72,
0, 18, 8, 255, 255, 240, 16, 83, 73, 0, 7, 33, 6, 43, 0, 32, 83, 73,
1, 7, 37, 6, 36, 0, 32, 83, 74, 0, 18, 8, 255, 255, 240, 16, 83, 75,
0, 7, 33, 6, 43, 0, 32, 83, 75, 1, 7, 37, 6, 36, 0, 32, 83, 76, 0, 7,
33, 14, 39, 0, 16, 83, 77, 0, 7, 33, 14, 39, 0, 16, 83, 78, 0, 7, 33,
6, 43, 0, 32, 83, 79, 0, 7, 8, 255, 255, 240, 16, 83, 82, 0, 7, 33,
14, 39, 0, 16, 83, 84, 0, 7, 33, 14, 39, 0, 16, 83, 86, 0, 7, 14, 12,
17, 0, 32, 83, 88, 0, 18, 8, 255, 255, 240, 16, 83, 89, 0, 18, 8, 255,
255, 240, 16, 83, 90, 0, 7, 33, 14, 39, 0, 16, 84, 65, 0, 18, 8, 255,
255, 240, 16, 84, 67, 0, 7, 33, 14, 39, 0, 16, 84, 68, 0, 7, 33, 14,
39, 0, 16, 84, 70, 0, 7, 33, 14, 39, 0, 16, 84, 71, 0, 7, 33, 14, 39,
0, 16, 84, 72, 0, 7, 43, 6, 52, 0, 32, 84, 74, 0, 7, 33, 14, 39, 0,
16, 84, 75, 0, 18, 8, 255, 255, 240, 16, 84, 76, 0, 7, 33, 14, 39, 0,
48, 84, 77, 0, 7, 33, 14, 39, 0, 16, 84, 78, 0, 7, 5, 6, 4, 0, 32, 84,
79, 0, 7, 8, 255, 255, 240, 16, 84, 82, 0, 7, 5, 6, 4, 0, 32, 84, 82,
7, 7, 33, 14, 39, 0, 48, 84, 84, 0, 7, 43, 6, 52, 0, 32, 84, 86, 0,
7, 8, 255, 255, 240, 16, 84, 87, 0, 0, 52, 0, 64, 0, 0, 84, 87, 2, 0,
53, 0, 62, 0, 0, 84, 90, 0, 7, 33, 14, 39, 0, 16, 85, 65, 0, 7, 8, 255,
255, 240, 0, 85, 71, 0, 7, 34, 6, 31, 0, 32, 85, 77, 0, 0, 14, 0, 17,
0, 0, 85, 83, 0, 5, 32, 4, 30, 0, 0, 85, 83, 25, 12, 8, 10, 7, 0, 0,
85, 83, 26, 4, 8, 1, 7, 0, 0, 85, 89, 0, 20, 43, 23, 52, 0, 0, 85, 90,
0, 7, 33, 14, 39, 0, 16, 86, 65, 0, 7, 33, 6, 43, 0, 0, 86, 67, 0, 7,
15, 13, 18, 0, 16, 86, 69, 0, 7, 41, 6, 47, 0, 0, 86, 71, 0, 7, 33,
6, 43, 0, 0, 86, 73, 0, 0, 14, 0, 17, 0, 0, 86, 78, 0, 7, 5, 6, 4, 0,
0, 86, 85, 0, 7, 43, 13, 49, 0, 16, 87, 70, 0, 7, 33, 13, 43, 0, 16,
87, 83, 0, 7, 43, 12, 49, 0, 16, 88, 48, 0, 3, 20, 0, 21, 0, 0, 88,
49, 0, 7, 41, 6, 47, 0, 0, 88, 50, 0, 21, 3, 6, 2, 0, 0, 88, 51, 0,
7, 33, 6, 35, 0, 32, 88, 65, 0, 7, 3, 255, 255, 240, 0, 88, 66, 0, 0,
23, 255, 255, 240, 0, 88, 82, 0, 1, 54, 3, 63, 0, 0, 88, 83, 0, 13,
4, 11, 1, 0, 32, 88, 84, 0, 12, 8, 10, 7, 0, 32, 88, 85, 0, 9, 37, 7,
37, 0, 32, 88, 86, 0, 11, 8, 9, 7, 0, 32, 88, 87, 0, 22, 35, 25, 33,
0, 32, 88, 88, 0, 10, 33, 255, 255, 240, 32, 88, 89, 0, 7, 33, 6, 43,
0, 32, 88, 90, 0, 14, 8, 255, 255, 240, 32, 89, 49, 0, 0, 14, 255, 255,
240, 16, 89, 50, 0, 0, 14, 255, 255, 240, 16, 89, 51, 0, 0, 14, 255,
255, 240, 16, 89, 52, 0, 0, 14, 255, 255, 240, 16, 89, 53, 0, 0, 14,
255, 255, 240, 16, 89, 54, 0, 0, 14, 255, 255, 240, 16, 89, 55, 0, 0,
14, 255, 255, 240, 16, 89, 69, 0, 7, 45, 13, 51, 0, 16, 89, 84, 0, 7,
33, 6, 43, 0, 0, 89, 89, 0, 18, 8, 255, 255, 240, 0, 90, 49, 0, 18,
8, 255, 255, 240, 16, 90, 50, 0, 18, 8, 255, 255, 240, 16, 90, 51, 0,
18, 8, 255, 255, 240, 16, 90, 52, 0, 18, 8, 255, 255, 240, 16, 90, 53,
0, 18, 8, 255, 255, 240, 16, 90, 54, 0, 18, 8, 255, 255, 240, 16, 90,
55, 0, 18, 8, 255, 255, 240, 16, 90, 56, 0, 18, 8, 255, 255, 240, 16,
90, 57, 0, 18, 8, 255, 255, 240, 16, 90, 65, 0, 7, 33, 6, 43, 0, 32,
90, 77, 0, 19, 41, 22, 47, 0, 0, 90, 87, 0, 7, 33, 14, 39, 0, 48, 10,
2, 255, 3, 17, 19, 24, 28, 30, 49, 0, 4, 56, 19, 1, 70, 27, 1, 58, 34,
1, 70, 49, 1, 14, 0, 255, 2, 23, 19, 23, 49, 2, 2, 84, 19, 1, 84, 49,
1, 14, 0, 255, 2, 23, 19, 23, 49, 0, 2, 66, 19, 1, 66, 49, 1, 23, 1,
1, 4, 23, 19, 17, 28, 23, 38, 30, 49, 2, 2, 84, 22, 1, 84, 49, 1, 24,
1, 5, 2, 23, 23, 30, 49, 0, 4, 56, 19, 1, 58, 28, 1, 60, 39, 1, 70,
49, 1, 15, 1, 255, 1, 23, 20, 2, 1, 84, 20, 1, 15, 1, 255, 1, 23, 20,
2, 1, 84, 20, 1, 20, 1, 255, 2, 21, 20, 21, 49, 2, 2, 84, 20, 1, 84,
49, 1, 0, 0, 255, 0, 0, 0, 19, 1, 255, 2, 23, 20, 23, 48, 0, 2, 66,
20, 1, 66, 48, 1, 20, 1, 255, 2, 23, 20, 20, 49, 0, 2, 66, 20, 1, 64,
49, 1, 20, 1, 255, 2, 23, 20, 20, 49, 2, 2, 92, 20, 1, 80, 49, 1, 9,
0, 255, 1, 23, 19, 2, 1, 84, 19, 1, 9, 0, 255, 1, 20, 19, 0, 1, 56,
19, 1, 11, 2, 255, 3, 17, 19, 24, 30, 30, 49, 0, 5, 56, 19, 1, 70, 27,
1, 58, 34, 1, 68, 38, 1, 70, 49, 1, 13, 2, 255, 3, 17, 19, 24, 31, 30,
49, 0, 5, 56, 19, 1, 78, 27, 1, 64, 34, 1, 68, 36, 1, 78, 43, 1, 26,
1, 255, 2, 23, 20, 30, 40, 2, 2, 84, 23, 1, 112, 49, 1, 14, 2, 255,
2, 17, 19, 30, 49, 0, 2, 58, 19, 1, 80, 49, 1, 27, 0, 255, 1, 30, 26,
0, 1, 120, 26, 1, 26, 2, 255, 1, 30, 25, 0, 1, 120, 25, 1, 10, 2, 2,
3, 17, 19, 24, 28, 30, 49, 0, 4, 56, 19, 1, 70, 27, 1, 58, 34, 1, 70,
49, 1, 10, 2, 255, 3, 17, 19, 24, 28, 30, 49, 0, 4, 56, 19, 1, 66, 27,
1, 60, 34, 1, 66, 49, 1, 20, 2, 255, 2, 23, 20, 33, 49, 2, 2, 84, 20,
1, 84, 49, 1, 10, 2, 1, 3, 17, 19, 24, 28, 30, 49, 0, 4, 56, 19, 1,
70, 27, 1, 58, 34, 1, 70, 49, 1, 32, 2, 255, 1, 30, 38, 2, 1, 84, 38,
1, 29, 2, 255, 2, 21, 28, 30, 49, 0, 2, 60, 28, 1, 68, 49, 1, 29, 1,
255, 2, 30, 28, 30, 49, 2, 2, 112, 28, 1, 112, 49, 1, 5, 2, 0, 2, 23,
18, 23, 19, 2, 2, 84, 18, 1, 84, 19, 1, 7, 2, 0, 2, 23, 18, 23, 20,
2, 2, 84, 18, 1, 84, 20, 1, 8, 2, 0, 3, 23, 18, 23, 20, 30, 38, 2, 2,
84, 18, 1, 84, 22, 1, 6, 1, 255, 4, 14, 18, 14, 19, 20, 29, 20, 48,
0, 4, 48, 18, 1, 48, 19, 1, 60, 29, 1, 60, 48, 1, 14, 0, 255, 2, 17,
19, 30, 49, 0, 2, 56, 19, 1, 68, 49, 1, 12, 2, 255, 3, 17, 19, 24, 31,
30, 50, 0, 6, 62, 19, 1, 90, 27, 1, 80, 35, 1, 90, 41, 1, 86, 45, 1,
118, 50, 1, 22, 1, 255, 2, 23, 20, 30, 38, 2, 1, 84, 22, 1, 25, 1, 255,
1, 23, 24, 2, 1, 84, 24, 1, 14, 0, 6, 2, 17, 19, 20, 49, 0, 2, 56, 19,
1, 60, 49, 1, 18, 1, 255, 2, 20, 20, 20, 44, 2, 2, 72, 20, 1, 72, 44,
1, 22, 1, 255, 2, 23, 20, 30, 38, 2, 1, 84, 22, 1, 22, 2, 255, 1, 20,
22, 0, 2, 62, 20, 1, 66, 38, 1, 16, 2, 255, 2, 20, 20, 28, 38, 2, 2,
84, 20, 1, 112, 38, 1, 4, 0, 255, 1, 23, 18, 2, 1, 84, 18, 1, 20, 1,
255, 2, 23, 20, 30, 49, 2, 2, 84, 20, 1, 84, 49, 1, 21, 1, 255, 3, 23,
20, 30, 37, 30, 46, 2, 2, 84, 21, 1, 84, 46, 1, 26, 1, 255, 3, 23, 20,
24, 39, 30, 49, 2, 1, 84, 25, 1, 26, 1, 255, 3, 23, 20, 24, 39, 30,
49, 2, 1, 84, 25, 1, 17, 1, 255, 2, 23, 20, 30, 40, 2, 2, 84, 20, 1,
112, 40, 1, 34, 0, 255, 1, 27, 49, 2, 1, 84, 49, 1, 34, 0, 255, 1, 30,
49, 0, 1, 78, 49, 1, 14, 0, 255, 2, 27, 19, 27, 49, 2, 2, 84, 19, 1,
84, 49, 1, 34, 0, 255, 1, 27, 49, 2, 1, 84, 49, 1, 34, 0, 255, 1, 20,
49, 2, 1, 76, 49, 1, 33, 0, 255, 1, 20, 48, 2, 1, 76, 48, 1, 31, 2,
255, 2, 17, 33, 30, 49, 0, 2, 68, 33, 1, 68, 49, 1, 30, 2, 255, 3, 17,
33, 24, 38, 30, 49, 0, 3, 56, 33, 1, 68, 38, 1, 68, 49, 1, 28, 2, 255,
3, 17, 28, 24, 38, 30, 49, 0, 3, 56, 28, 1, 58, 38, 1, 62, 49, 1, 33,
0, 255, 1, 27, 48, 2, 1, 84, 48, 1, 0, 0, 3, 0, 0, 0, 120, 11, 0, 0,
16, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1, 18,
1, 255, 1, 52, 1, 14, 1, 15, 3, 28, 39, 49, 2, 19, 49, 166, 169, 0,
0
};
const resource_hnd_t wifi_firmware_clm_blob = { RESOURCE_IN_MEMORY, 7222, {.mem = { (const char *) wifi_firmware_clm_blob_image_data }}};

View File

@ -0,0 +1,30 @@
/*
* Copyright (c) 2019, Cypress Semiconductor Corporation, All Rights Reserved
* SPDX-License-Identifier: LicenseRef-PBL
*
* This file and the related binary are licensed under the
* Permissive Binary License, Version 1.0 (the "License");
* you may not use these files except in compliance with the License.
*
* You may obtain a copy of the License here:
* LICENSE-permissive-binary-license-1.0.txt and at
* https://www.mbed.com/licenses/PBL-1.0
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* Automatically generated file - this comment ensures resources.h file creation */
/* Auto-generated header file. Do not edit */
#ifndef INCLUDED_RESOURCES_H_
#define INCLUDED_RESOURCES_H_
#include "wiced_resource.h"
#include "wiced_filesystem.h"
extern wiced_filesystem_t resource_fs_handle;
extern const resource_hnd_t wifi_firmware_image;
extern const unsigned char wifi_firmware_image_data[421098];
extern const resource_hnd_t wifi_firmware_clm_blob;
extern const unsigned char wifi_firmware_clm_blob_image_data[7222];
#endif /* ifndef INCLUDED_RESOURCES_H_ */

View File

@ -0,0 +1,87 @@
/*
* Copyright (c) 2019, Cypress Semiconductor Corporation, All Rights Reserved
* SPDX-License-Identifier: LicenseRef-PBL
*
* This file and the related binary are licensed under the
* Permissive Binary License, Version 1.0 (the "License");
* you may not use these files except in compliance with the License.
*
* You may obtain a copy of the License here:
* LICENSE-permissive-binary-license-1.0.txt and at
* https://www.mbed.com/licenses/PBL-1.0
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** @file
* NVRAM file for CY8CKIT-062-WiFi-BT (PSoC6 WiFi-BT Pioneer Kit) using
* Murata's Type 1DX module - Copied from bcm94343wwcd1.txt on 08/04/2019
* # 2.4 GHz, 20 MHz BW mode; No Antenna Diversity
*/
#ifndef INCLUDED_NVRAM_IMAGE_H_
#define INCLUDED_NVRAM_IMAGE_H_
#include <string.h>
#include <stdint.h>
#include "generated_mac_address.txt"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Character array of NVRAM image
*
* Generated from cyw94343cy8ckit-062-wifi-bt.txt
*/
static const char wifi_nvram_image[] =
"manfid=0x2d0" "\x00"
"prodid=0x0726" "\x00"
"vendid=0x14e4" "\x00"
"devid=0x43e2" "\x00"
"boardtype=0x0726" "\x00"
"boardrev=0x1202" "\x00"
"boardnum=22" "\x00"
NVRAM_GENERATED_MAC_ADDRESS "\x00"
"sromrev=11" "\x00"
"boardflags=0x00404201" "\x00"
"boardflags3=0x04000000" "\x00"
"xtalfreq=37400" "\x00"
"nocrc=1" "\x00"
"ag0=0" "\x00"
"aa2g=1" "\x00"
"ccode=ALL" "\x00"
"extpagain2g=0" "\x00"
"pa2ga0=-145,6667,-751" "\x00"
"AvVmid_c0=0x0,0xc8" "\x00"
"cckpwroffset0=2" "\x00"
"maxp2ga0=74" "\x00"
"cckbw202gpo=0" "\x00"
"legofdmbw202gpo=0x88888888" "\x00"
"mcsbw202gpo=0xaaaaaaaa" "\x00"
"propbw202gpo=0xdd" "\x00"
"ofdmdigfilttype=18" "\x00"
"ofdmdigfilttypebe=18" "\x00"
"papdmode=1" "\x00"
"papdvalidtest=1" "\x00"
"pacalidx2g=48" "\x00"
"papdepsoffset=-22" "\x00"
"papdendidx=58" "\x00"
"il0"NVRAM_GENERATED_MAC_ADDRESS "\x00"
"wl0id=0x431b" "\x00"
"muxenab=0x10" "\x00"
"\x00\x00";
#ifdef __cplusplus
} /* extern "C" */
#endif
#else /* ifndef INCLUDED_NVRAM_IMAGE_H_ */
#error Wi-Fi NVRAM image included twice
#endif /* ifndef INCLUDED_NVRAM_IMAGE_H_ */

View File

@ -0,0 +1,58 @@
/*
* Copyright 2020 Arduino SA
* 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
*
* 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.
*/
/** @file
* Provides configuration for WHD driver on Arduino Portenta H7
*/
#ifndef __WHD_CONFIG__
#define __WHD_CONFIG__
#include "whd_types.h"
#include "stm32h7xx_hal.h"
#include <stdint.h>
/* please define your configuration , either SDIO or SPI */
#define CY_WHD_CONFIG_USE_SDIO
//#define CY_WHD_CONFIG_USE_SPI
/* select resource implementation */
#define USES_RESOURCE_GENERIC_FILESYSTEM
/* if not defined default value is 2 */
#define CY_WIFI_OOB_INTR_PRIORITY 0
#define CYBSP_WIFI_HOST_WAKE_IRQ_EVENT CYHAL_GPIO_IRQ_FALL
#define CYBSP_WIFI_HOST_WAKE CYBSP_SDIO_OOB_IRQ
#define BSP_LED1 {GPIOK,{.Pin= GPIO_PIN_5 , .Mode = GPIO_MODE_OUTPUT_PP , .Pull = GPIO_NOPULL , .Speed= GPIO_SPEED_FREQ_LOW}}
#define BSP_LED2 {GPIOK,{.Pin= GPIO_PIN_6 , .Mode = GPIO_MODE_OUTPUT_PP , .Pull = GPIO_NOPULL , .Speed= GPIO_SPEED_FREQ_LOW}}
#define BSP_LED3 {GPIOK,{.Pin= GPIO_PIN_7 , .Mode = GPIO_MODE_OUTPUT_PP , .Pull = GPIO_NOPULL , .Speed= GPIO_SPEED_FREQ_LOW}}
/* power pin */
#define WIFI_WL_REG_ON {GPIOJ,{.Pin= GPIO_PIN_1, .Mode = GPIO_MODE_OUTPUT_PP , .Pull = GPIO_NOPULL , .Speed= GPIO_SPEED_FREQ_LOW}}
//#define WIFI_32K_CLK {GPIOA,{.Pin= GPIO_PIN_8, .Mode = GPIO_MODE_AF_PP , .Pull = GPIO_NOPULL , .Speed= GPIO_SPEED_FREQ_LOW , .Alternate = GPIO_AF0_MCO}}
#define WIFI_SDIO_CMD {GPIOD,{.Pin= GPIO_PIN_2 , .Mode = GPIO_MODE_AF_PP , .Pull = GPIO_NOPULL , .Speed= GPIO_SPEED_FREQ_VERY_HIGH, .Alternate = GPIO_AF12_SDIO1}}
#define WIFI_SDIO_CLK {GPIOC,{.Pin= GPIO_PIN_12, .Mode = GPIO_MODE_AF_PP , .Pull = GPIO_NOPULL , .Speed= GPIO_SPEED_FREQ_VERY_HIGH, .Alternate = GPIO_AF12_SDIO1}}
#define WIFI_SDIO_D0 {GPIOC,{.Pin= GPIO_PIN_8 , .Mode = GPIO_MODE_AF_PP , .Pull = GPIO_NOPULL , .Speed= GPIO_SPEED_FREQ_VERY_HIGH, .Alternate = GPIO_AF12_SDIO1}}
#define WIFI_SDIO_D1 {GPIOC,{.Pin= GPIO_PIN_9 , .Mode = GPIO_MODE_AF_PP , .Pull = GPIO_NOPULL , .Speed= GPIO_SPEED_FREQ_VERY_HIGH, .Alternate = GPIO_AF12_SDIO1}}
#define WIFI_SDIO_D2 {GPIOC,{.Pin= GPIO_PIN_10, .Mode = GPIO_MODE_AF_PP , .Pull = GPIO_NOPULL , .Speed= GPIO_SPEED_FREQ_VERY_HIGH, .Alternate = GPIO_AF12_SDIO1}}
#define WIFI_SDIO_D3 {GPIOC,{.Pin= GPIO_PIN_11, .Mode = GPIO_MODE_AF_PP , .Pull = GPIO_NOPULL , .Speed= GPIO_SPEED_FREQ_VERY_HIGH, .Alternate = GPIO_AF12_SDIO1}}
#define WIFI_SDIO_OOB_IRQ {GPIOJ,{.Pin= GPIO_PIN_5, .Mode = GPIO_MODE_IT_FALLING , .Pull = GPIO_NOPULL , .Speed= GPIO_SPEED_FREQ_VERY_HIGH}}
#endif

View File

@ -3186,7 +3186,10 @@
],
"detect_code": ["0813"],
"components_add": [
"QSPIF"
"QSPIF",
"WHD",
"4343W_FS",
"CYW43XXX"
],
"device_has_add": [
"USBDEVICE",