mirror of https://github.com/ARMmbed/mbed-os.git
Portenta add interface to cypress hal
parent
ef7ce6ba68
commit
4200d752b2
|
@ -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 */
|
|
@ -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_ */
|
|
@ -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_ */
|
||||
|
|
@ -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
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
Loading…
Reference in New Issue