diff --git a/CMakeLists.txt b/CMakeLists.txt index 737398a..f83e54c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,6 +97,7 @@ set(TARGET_SOURCES "board/pin_mux.c" "src/main.c" "src/task_hello.c" + "src/whd_port/rtos/cyabs_rtos.c" "xip/fire_rt1052_pro_flexspi_nor_config.c" ) @@ -161,12 +162,12 @@ set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS} -x assembler-with-cpp") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections") -set(WHD_INTERFACE "SDIO" CACHE STRING "") +set(WHD_EXTERNAL_PATH "${CMAKE_SOURCE_DIR}/include/whd_port" CACHE STRING "") add_subdirectory(lib/whd) set(FREERTOS_HEAP "4" CACHE STRING "" FORCE) set(FREERTOS_PORT "GCC_ARM_CM7" CACHE STRING "" FORCE) -set(FREERTOS_CONFIG_FILE_DIRECTORY "${CMAKE_SOURCE_DIR}/include") +set(FREERTOS_CONFIG_FILE_DIRECTORY "${CMAKE_SOURCE_DIR}/include" CACHE STRING "" FORCE) add_subdirectory(lib/freertos) # Shared sources, includes and definitions diff --git a/include/FreeRTOSConfig.h b/include/FreeRTOSConfig.h index a2e8a17..be2c853 100644 --- a/include/FreeRTOSConfig.h +++ b/include/FreeRTOSConfig.h @@ -43,7 +43,7 @@ #define configUSE_TICKLESS_IDLE 0 #define configCPU_CLOCK_HZ (SystemCoreClock) #define configTICK_RATE_HZ ((TickType_t)1000) -#define configMAX_PRIORITIES 5 +#define configMAX_PRIORITIES 8 #define configMINIMAL_STACK_SIZE ((unsigned short)90) #define configMAX_TASK_NAME_LEN 20 #define configUSE_16_BIT_TICKS 0 diff --git a/include/whd_port/bsp/cybsp.h b/include/whd_port/bsp/cybsp.h new file mode 100644 index 0000000..4bfa30c --- /dev/null +++ b/include/whd_port/bsp/cybsp.h @@ -0,0 +1,39 @@ +/***************************************************************************//** +* \file cybsp.h +* +* \brief +* Basic API for setting up specific boards +* +******************************************************************************** +* \copyright +* Copyright 2021 Cypress Semiconductor Corporation (an Infineon company) or +* an affiliate of Cypress Semiconductor Corporation +* +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#pragma once + +#include "cybsp_types.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +//#define CYBSP_WIFI_INTERFACE_TYPE CYBSP_SDIO_INTERFACE + +#ifdef __cplusplus +} +#endif /* __cplusplus */ diff --git a/include/whd_port/bsp/cybsp_types.h b/include/whd_port/bsp/cybsp_types.h new file mode 100644 index 0000000..28dd6c2 --- /dev/null +++ b/include/whd_port/bsp/cybsp_types.h @@ -0,0 +1,40 @@ +/***************************************************************************//** +* \file cybsp.h +* +* \brief +* Basic API for setting up specific boards +* +******************************************************************************** +* \copyright +* Copyright 2021 Cypress Semiconductor Corporation (an Infineon company) or +* an affiliate of Cypress Semiconductor Corporation +* +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#pragma once + +#if defined(__cplusplus) +extern "C" { +#endif + +/* WIFI interface types */ +#define CYBSP_SDIO_INTERFACE (0) +#define CYBSP_SPI_INTERFACE (1) +#define CYBSP_M2M_INTERFACE (2) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ diff --git a/include/whd_port/hal/cy_result.h b/include/whd_port/hal/cy_result.h new file mode 100644 index 0000000..f76b7d9 --- /dev/null +++ b/include/whd_port/hal/cy_result.h @@ -0,0 +1,134 @@ +/***************************************************************************//** +* \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-2019 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/** + * \addtogroup group_result Result Type + * \ingroup group_abstraction + * \{ + * Basic function result handling. Defines a simple type for conveying + * information about whether something succeeded or details about any issues + * that were detected. + * + * \defgroup group_result_macros Macros + */ + +#pragma once + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +/** + * \addtogroup group_result_macros + * \{ + */ + +/** Mask for the bit at position "x" */ +#define CY_BIT_MASK(x) ( (1U << (x) ) - 1U ) + +/** Bit position of the result code */ +#define CY_RSLT_CODE_POSITION (0U) +/** Bit width of the result code */ +#define CY_RSLT_CODE_WIDTH (16U) +/** 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) + +/** Mask for the result code */ +#define CY_RSLT_CODE_MASK CY_BIT_MASK(CY_RSLT_CODE_WIDTH) +/** Mask for the module identifier */ +#define CY_RSLT_MODULE_MASK CY_BIT_MASK(CY_RSLT_MODULE_WIDTH) +/** Mask for the result type */ +#define CY_RSLT_TYPE_MASK CY_BIT_MASK(CY_RSLT_TYPE_WIDTH) + +/** Informational-only result status */ +#define CY_RSLT_TYPE_INFO (0U) +/** Warning result */ +#define CY_RSLT_TYPE_WARNING (1U) +/** Error result */ +#define CY_RSLT_TYPE_ERROR (2U) +/** Fatal error result */ +#define CY_RSLT_TYPE_FATAL (3U) + +/** Get the value of the result code field */ +#define CY_RSLT_GET_CODE(x) ( ( (x) >> CY_RSLT_CODE_POSITION ) & CY_RSLT_CODE_MASK ) +/** Get the value of the result type field */ +#define CY_RSLT_GET_TYPE(x) ( ( (x) >> CY_RSLT_TYPE_POSITION ) & CY_RSLT_TYPE_MASK ) +/** Get the value of the module identifier field */ +#define CY_RSLT_GET_MODULE(x) ( ( (x) >> CY_RSLT_MODULE_POSITION ) & CY_RSLT_MODULE_MASK ) + + +/**** DRIVER Module codes: 0x0000 - 0x00FF ****/ +/** Base identifier for peripheral driver library */ +#define CY_RSLT_MODULE_DRIVERS_PDL_BASE (0x0000U) +/** Base identifier for peripheral driver library */ +#define CY_RSLT_MODULE_DRIVERS_WHD_BASE (0x0080U) + +/**** ABSTRACTION Module codes: 0x0100 - 0x01FF ****/ +/** Base identifier for chip support modules */ +#define CY_RSLT_MODULE_ABSTRACTION_HAL_BASE (0x0100U) +/** Base identifier for board support modules */ +#define CY_RSLT_MODULE_ABSTRACTION_BSP (0x0180U) +/** Base identifier for file system modules */ +#define CY_RSLT_MODULE_ABSTRACTION_FS (0x0181U) +/** Base identifier for resource abstraction modules */ +#define CY_RSLT_MODULE_ABSTRACTION_RESOURCE (0x0182U) +/** Base identifier for rtos abstraction modules */ +#define CY_RSLT_MODULE_ABSTRACTION_OS (0x0183U) +/** Base identifier for environment abstraction modules */ +#define CY_RSLT_MODULE_ABSTRACTION_ENV (0x0184U) + +/**** Middleware Module codes: 0x0200 - 0x02FF ****/ +#define CY_RSLT_MODULE_MIDDLEWARE_BASE (0x0200U) + + + +/** Provides the result of an operation as a structured bitfield */ +typedef uint32_t cy_rslt_t; + +/** Result value indicating success */ +#define CY_RSLT_SUCCESS ( (cy_rslt_t)0x00000000U ) + +/** Create a result value from the specified type, module, and result code */ +#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 ) ) + +/** \} group_result_macros */ + +#ifdef __cplusplus +} +#endif + +/** \} group_result */ diff --git a/include/whd_port/hal/cyhal_dma.h b/include/whd_port/hal/cyhal_dma.h new file mode 100644 index 0000000..445562b --- /dev/null +++ b/include/whd_port/hal/cyhal_dma.h @@ -0,0 +1,399 @@ +/***************************************************************************//** +* \file cyhal_dma.h +* +* \brief +* Provides a high level interface for interacting with the Infineon DMA. +* 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-2021 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#pragma once + +#include +#include +#include "cy_result.h" +#include "cyhal_hw_types.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +/** + * \} + */ + +/** Direction for DMA transfers. */ +typedef enum +{ + CYHAL_DMA_DIRECTION_MEM2MEM, //!< Memory to memory + CYHAL_DMA_DIRECTION_MEM2PERIPH, //!< Memory to peripheral + CYHAL_DMA_DIRECTION_PERIPH2MEM, //!< Peripheral to memory + CYHAL_DMA_DIRECTION_PERIPH2PERIPH, //!< Peripheral to peripheral +} cyhal_dma_direction_t; + +/** Flags enum of DMA events. Multiple events can be enabled via \ref cyhal_m2m_enable_event and + * the callback from \ref cyhal_m2m_register_callback will be run to notify. */ +typedef enum +{ + CYHAL_DMA_NO_INTR = 0, //!< No interrupt + CYHAL_DMA_TRANSFER_COMPLETE = 1 << 0, /**< Indicates that an individual transfer (burst or + full) has completed based on the specified \ref + cyhal_dma_transfer_action_t */ + CYHAL_DMA_DESCRIPTOR_COMPLETE = 1 << 1, //!< Indicates that the full transfer has completed + CYHAL_DMA_SRC_BUS_ERROR = 1 << 2, //!< Indicates that there is a source bus error + CYHAL_DMA_DST_BUS_ERROR = 1 << 3, //!< Indicates that there is a destination bus error + CYHAL_DMA_SRC_MISAL = 1 << 4, //!< Indicates that the source address is not aligned + CYHAL_DMA_DST_MISAL = 1 << 5, //!< Indicates that the destination address is not aligned + CYHAL_DMA_CURR_PTR_NULL = 1 << 6, //!< Indicates that the current descriptor pointer is null + CYHAL_DMA_ACTIVE_CH_DISABLED = 1 << 7, //!< Indicates that the active channel is disabled + CYHAL_DMA_DESCR_BUS_ERROR = 1 << 8, //!< Indicates that there has been a descriptor bus error +} cyhal_m2m_event_t; + +/** Specifies the transfer type to trigger when an input signal is received. */ +typedef enum +{ + CYHAL_DMA_INPUT_TRIGGER_SINGLE_ELEMENT, //!< Transfer a single element when an input signal is received + CYHAL_DMA_INPUT_TRIGGER_SINGLE_BURST, //!< Transfer a single burst when an input signal is received + CYHAL_DMA_INPUT_TRIGGER_ALL_ELEMENTS, //!< Transfer all elements when an input signal is received +} cyhal_dma_input_t; + +/** Specifies the transfer completion event that triggers a signal output. */ +typedef enum +{ + CYHAL_DMA_OUTPUT_TRIGGER_SINGLE_ELEMENT, //!< Trigger an output when a single element is transferred + CYHAL_DMA_OUTPUT_TRIGGER_SINGLE_BURST, //!< Trigger an output when a single burst is transferred + CYHAL_DMA_OUTPUT_TRIGGER_ALL_ELEMENTS, //!< Trigger an output when all elements are transferred +} cyhal_dma_output_t; + +typedef enum +{ + /** A single burst is triggered and a \ref CYHAL_DMA_TRANSFER_COMPLETE will occur after + * each burst. The channel will be left enabled and can continue to be triggered. */ + CYHAL_DMA_TRANSFER_BURST, + /** All bursts are triggered and a single \ref CYHAL_DMA_TRANSFER_COMPLETE will occur at + * the end. The channel will be left enabled and can continue to be triggered. */ + CYHAL_DMA_TRANSFER_FULL, + /** A single burst is triggered and a \ref CYHAL_DMA_TRANSFER_COMPLETE will occur after + * each burst. When all bursts are complete, the channel will be disabled. */ + CYHAL_DMA_TRANSFER_BURST_DISABLE, + /** All bursts are triggered and a single \ref CYHAL_DMA_TRANSFER_COMPLETE will occur at + * the end. When complete, the channel will be disabled. */ + CYHAL_DMA_TRANSFER_FULL_DISABLE, +} cyhal_dma_transfer_action_t; + +/** \brief Configuration of a DMA channel. When configuring address, + * increments, and transfer width keep in mind your hardware may have more + * stringent address and data alignment requirements. */ +typedef struct +{ + uint32_t src_addr; //!< Source address + int16_t src_increment; //!< Source address auto increment amount in multiples of transfer_width + uint32_t dst_addr; //!< Destination address + int16_t dst_increment; //!< Destination address auto increment amount in multiples of transfer_width + uint8_t transfer_width; //!< Transfer width in bits. Valid values are: 8, 16, or 32 + uint32_t length; //!< Number of elements to be transferred in total + uint32_t burst_size; //!< Number of elements to be transferred per trigger. If set to 0 every element is transferred, otherwise burst_size must evenly divide length. + cyhal_dma_transfer_action_t action; //!< Sets the behavior of the channel when triggered (using start_transfer). Ignored if burst_size is not configured. +} cyhal_dma_cfg_t; + +/** Event handler for DMA interrupts */ +typedef void (*cyhal_dma_event_callback_t)(void *callback_arg, cyhal_m2m_event_t event); + +/** Generic trigger source defined for devices that do not support trigger mux. */ +typedef uint32_t cyhal_source_t; + +/** Generic trigger destination defined for devices that do not support trigger mux. */ +typedef uint32_t cyhal_dest_t; + +/** DMA input connection information to setup while initializing the driver. */ +typedef struct +{ + cyhal_source_t source; //!< Source of signal to DMA; obtained from another driver's cyhal__enable_output + cyhal_dma_input_t input; //!< DMA input signal to be driven +} cyhal_dma_src_t; + +/** DMA output connection information to setup while initializing the driver. */ +typedef struct +{ + cyhal_dma_output_t output; //!< Output signal of DMA + cyhal_dest_t dest; //!< Destination of DMA signal +} cyhal_dma_dest_t; + +/** Initialize the DMA peripheral. + * + * If a source signal is provided for \p src, this will connect the provided signal to the DMA + * just as would be done by calling \ref cyhal_dma_connect_digital. Similarly, if a destination + * target is provided for \p dest this will enable the specified output just as would be done + * by calling \ref cyhal_dma_enable_output. + * @param[out] obj Pointer to a DMA object. The caller must allocate the memory + * for this object but the init function will initialize its contents. + * @param[in] src An optional source signal to connect to the DMA + * @param[in] dest An optional destination singal to drive from the DMA + * @param[out] dest_source An optional pointer to user-allocated source signal object which + * will be initialized by enable_output. If \p dest is non-null, this must also be non-null. + * \p dest_source should be passed to (dis)connect_digital functions to (dis)connect the + * associated endpoints. + * @param[in] priority The priority of this DMA operation relative to others. The number of + * priority levels which are supported is hardware dependent. All implementations define a + * #CYHAL_DMA_PRIORITY_DEFAULT constant which is always valid. If supported, implementations will + * also define #CYHAL_DMA_PRIORITY_HIGH, #CYHAL_DMA_PRIORITY_MEDIUM, and #CYHAL_DMA_PRIORITY_LOW. + * The behavior of any other value is implementation defined. See the implementation-specific DMA + * documentation for more details. + * @param[in] direction The direction memory is copied + * @return The status of the init request + */ +cy_rslt_t cyhal_dma_init_adv(cyhal_dma_t *obj, cyhal_dma_src_t *src, cyhal_dma_dest_t *dest, + cyhal_source_t *dest_source, uint8_t priority, cyhal_dma_direction_t direction); + +/** Initialize the DMA peripheral. + * + * @param[out] obj Pointer to a DMA object. The caller must allocate the memory for this + * object but the init function will initialize its contents. + * @param[in] priority The priority of this DMA operation relative to others. The number of + * priority levels which are supported is hardware dependent. All implementations define a + * #CYHAL_DMA_PRIORITY_DEFAULT constant which is always valid. If supported, implementations will + * also define #CYHAL_DMA_PRIORITY_HIGH, #CYHAL_DMA_PRIORITY_MEDIUM, and #CYHAL_DMA_PRIORITY_LOW. + * The behavior of any other value is implementation defined. See the implementation-specific DMA + * documentation for more details. + * @param[in] direction The direction memory is copied + * @return The status of the init request + */ +#define cyhal_m2m_init(obj, priority, direction) (cyhal_dma_init_adv(obj, NULL, NULL, NULL, priority, direction) ) + +/** Free the DMA object. Freeing a DMA object while a transfer is in progress + * (\ref cyhal_m2m_is_busy) is invalid. + * + * @param[in,out] obj The DMA object + */ +void cyhal_m2m_free(cyhal_dma_t *obj); + +/** Setup the DMA channel behavior. This will also enable the channel to allow it to be triggered. + * The transfer can be software triggered by calling \ref cyhal_dma_start_transfer or by hardware. + * A hardware input signal is setup by \ref cyhal_dma_connect_digital or \ref cyhal_dma_init_adv. + * \note If hardware triggers are used, any necessary event callback setup (\ref + * cyhal_m2m_register_callback and \ref cyhal_m2m_enable_event) should be done before calling + * this function to ensure the handlers are in place before the transfer can happen. + * \note The automatic enablement of the channel as part of this function is expected to change + * in a future update. This would only happen on a new major release (eg: 1.0 -> 2.0). + * + * @param[in] obj The DMA object + * @param[in] cfg Configuration parameters for the transfer + * @return The status of the configure request + */ +cy_rslt_t cyhal_dma_configure(cyhal_dma_t *obj, const cyhal_dma_cfg_t *cfg); + +/** Enable the DMA transfer so that it can start transferring data when triggered. A trigger is + * caused either by calling \ref cyhal_dma_start_transfer or by hardware as a result of a connection + * made in either \ref cyhal_dma_connect_digital or \ref cyhal_dma_init_adv. The DMA can be disabled + * by calling \ref cyhal_dma_disable or by setting the \ref cyhal_dma_cfg_t action to \ref + * CYHAL_DMA_TRANSFER_BURST_DISABLE, or \ref CYHAL_DMA_TRANSFER_FULL_DISABLE. + * + * @param[in] obj The DMA object + * @return The status of the enable request + */ +cy_rslt_t cyhal_dma_enable(cyhal_dma_t *obj); + +/** Disable the DMA transfer so that it does not continue to trigger. It can be reenabled by calling + * \ref cyhal_dma_enable or \ref cyhal_dma_configure. + * + * @param[in] obj The DMA object + * @return The status of the enable request + */ +cy_rslt_t cyhal_dma_disable(cyhal_dma_t *obj); + +/** Initiates DMA channel transfer for specified DMA object. This should only be done after the + * channel has been configured (\ref cyhal_dma_configure) and any necessary event callbacks setup + * (\ref cyhal_m2m_register_callback \ref cyhal_m2m_enable_event) + * + * @param[in] obj The DMA object + * @return The status of the start_transfer request + */ +cy_rslt_t cyhal_dma_start_transfer(cyhal_dma_t *obj); + +/** Checks if the transfer has been triggered, but not yet complete (eg: is pending, blocked or running) + * + * @param[in] obj The DMA object + * @return True if DMA channel is busy + */ +bool cyhal_m2m_is_busy(cyhal_dma_t *obj); + +/** Register a DMA callback handler. + * + * This function will be called when one of the events enabled by \ref cyhal_m2m_enable_event occurs. + * + * @param[in] obj The DMA object + * @param[in] callback The callback handler which will be invoked when an event triggers + * @param[in] callback_arg Generic argument that will be provided to the callback when called + */ +void cyhal_m2m_register_callback(cyhal_dma_t *obj, cyhal_dma_event_callback_t callback, void *callback_arg); + +/** Configure DMA event enablement. + * + * When an enabled event occurs, the function specified by \ref cyhal_m2m_register_callback will be called. + * + * @param[in] obj The DMA object + * @param[in] event The DMA event type + * @param[in] intr_priority The priority for NVIC interrupt events. The priority from the most + * recent call will take precedence, i.e all events will have the same priority. + * @param[in] enable True to turn on interrupts, False to turn off + */ +void cyhal_m2m_enable_event(cyhal_dma_t *obj, cyhal_m2m_event_t event, uint8_t intr_priority, bool enable); + +/** Connects a source signal and enables the specified input to the DMA channel. This connection + * can also be setup automatically on initialization via \ref cyhal_dma_init_adv. If the signal + * needs to be disconnected later, \ref cyhal_dma_disconnect_digital can be used. + * + * @param[in] obj The DMA object + * @param[in] source Source signal obtained from another driver's cyhal__enable_output + * @param[in] input Which input to enable + * @return The status of the connection + */ +cy_rslt_t cyhal_dma_connect_digital(cyhal_dma_t *obj, cyhal_source_t source, cyhal_dma_input_t input); + +/** Enables the specified output signal from a DMA channel that is triggered when a transfer is + * completed. This can also be setup automatically on initialization via \ref cyhal_dma_init_adv. + * If the output is not needed in the future, \ref cyhal_dma_disable_output can be used. + * + * @param[in] obj The DMA object + * @param[in] output Which event triggers the output + * @param[out] source Pointer to user-allocated source signal object which + * will be initialized by enable_output. \p source should be passed to + * (dis)connect_digital functions to (dis)connect the associated endpoints. + * @return The status of the output enable + */ +cy_rslt_t cyhal_dma_enable_output(cyhal_dma_t *obj, cyhal_dma_output_t output, cyhal_source_t *source); + +/** Disconnects a source signal and disables the specified input to the DMA channel. This removes + * the connection that was established by either \ref cyhal_dma_init_adv or \ref + * cyhal_dma_connect_digital. + * + * @param[in] obj The DMA object + * @param[in] source Source signal from cyhal__enable_output to disable + * @param[in] input Which input to disable + * @return The status of the disconnect + */ +cy_rslt_t cyhal_dma_disconnect_digital(cyhal_dma_t *obj, cyhal_source_t source, cyhal_dma_input_t input); + +/** Disables the specified output signal from a DMA channel. This turns off the signal that was + * enabled by either \ref cyhal_dma_init_adv or \ref cyhal_dma_enable_output. It is recommended + * that the signal is disconnected (cyhal__disconnect_digital) from anything it might be + * driving before being disabled. + * + * @param[in] obj The DMA object + * @param[in] output Which output to disable + * @return The status of the disablement + * */ +cy_rslt_t cyhal_dma_disable_output(cyhal_dma_t *obj, cyhal_dma_output_t output); + +//cyhal_dma_impl.h ++ +/** M2M DMA group */ +typedef enum +{ + _CYHAL_M2M_GRP_WWD, //!< Group used for WWD + _CYHAL_M2M_GRP_USR_1, //!< User group 1 + _CYHAL_M2M_GRP_USR_2 //!< User group 2 +} _cyhal_m2m_group_t; + + +/** WHD M2M reinitialization for setting RX_buffer_size. + * + * Function for WHD to reinitialize the DMA with a different RX buffer size. + * @param[in] obj Pointer to a DMA object. The caller must allocate the memory + * for this object but the init function will initialize its contents. + * @param[in] rx_buffer_size Size of the RX buffer. + */ +void _cyhal_m2m_reinit_dma(cyhal_dma_t *obj, uint32_t rx_buffer_size); + +/** WHD M2M packet-based DMA TX data. + * + * Port of m2m_dma_tx_data() referenced by wwd_bus_protocol.c in WICED. + * @param[in] obj Pointer to a DMA object. The caller must allocate the memory + * for this object but the init function will initialize its contents. + * @param[in] buffer Data buffer to be used in the packet DMA transaction. + * @return The status of the tx operation. + */ +int cyhal_m2m_tx_send(cyhal_dma_t *obj, void *buffer); + +/** WHD M2M packet-based DMA reclaim next completed TXD + * + * Port of m2m_dma_tx_reclaim() referenced by wwd_bus_protocol.c in WICED. + * @param[in] obj Pointer to a DMA object. The caller must allocate the memory + * for this object but the init function will initialize its contents. + */ +void cyhal_m2m_tx_release(cyhal_dma_t *obj); + +/** WHD M2M packet-based DMA read DMA packet + * + * Port of m2m_read_dma_packet() referenced by wwd_bus_protocol.c in WICED. + * @param[in] obj Pointer to a DMA object. The caller must allocate the memory + * for this object but the init function will initialize its contents. + * @param[out] packet packet pointer + * @param[out] hwtag Hardware tag + * @return DMA packet pointer + */ +void *cyhal_m2m_rx_receive(cyhal_dma_t *obj, void *packet, uint16_t **hwtag); + +/** WHD M2M packet-based DMA refill RX + * + * Port of m2m_refill_dma() referenced by wwd_bus_protocol.c in WICED. + * @param[in] obj Pointer to a DMA object. The caller must allocate the memory + * for this object but the init function will initialize its contents. + * @return DMA refilled (true) or failed (false) + */ +bool cyhal_m2m_rx_prepare(cyhal_dma_t *obj); + +/** WHD M2M packet-based DMA RX active status + * + * Port of m2m_rxactive_dma() referenced by wwd_bus_protocol.c in WICED. + * @param[in] obj Pointer to a DMA object. The caller must allocate the memory + * for this object but the init function will initialize its contents. + * @return RX active status + */ +int cyhal_m2m_rx_status(cyhal_dma_t *obj); + +uint32_t cyhal_m2m_intr_status(cyhal_dma_t *obj, bool *signal_txdone); + +//cyhal_dma_impl.h ++ + + +//cyhal_system_impl.h ++ +void _cyhal_system_timer_enable_irq(void); + +/* Disable external interrupts from M2M_ExtIRQn to APPS Core */ +void _cyhal_system_m2m_disable_irq(void); + +/* Enable external interrupts from M2M_ExtIRQn to APPS Core */ +void _cyhal_system_m2m_enable_irq(void); + +/* Disable external interrupts from SW0_ExtIRQn to APPS Core */ +void _cyhal_system_sw0_disable_irq(void); + +/* Enable external interrupts from SW0_ExtIRQn to APPS Core */ +void _cyhal_system_sw0_enable_irq(void); + +//cyhal_system_impl.h ++ + +#if defined(__cplusplus) +} +#endif + +/** \} group_hal_dma */ diff --git a/include/whd_port/hal/cyhal_gpio.h b/include/whd_port/hal/cyhal_gpio.h new file mode 100644 index 0000000..539a5bb --- /dev/null +++ b/include/whd_port/hal/cyhal_gpio.h @@ -0,0 +1,207 @@ +/***************************************************************************//** +* \file cyhal_gpio.h +* +* \brief +* Provides a high level interface for interacting with the Cypress GPIO. +* 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-2019 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/** + * \addtogroup group_hal_gpio GPIO (General Purpose Input Output) + * \ingroup group_hal + * \{ + * High level interface for interacting with the Cypress GPIO. + * + * \defgroup group_hal_gpio_macros Macros + * \defgroup group_hal_gpio_functions Functions + * \defgroup group_hal_gpio_data_structures Data Structures + * \defgroup group_hal_gpio_enums Enumerated Types + */ + +#pragma once + +#include +#include +#include "cy_result.h" +#include "cyhal_hw_types.h" + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************* +* Defines +*******************************************************************************/ + +/** + * \addtogroup group_hal_gpio_macros + * \{ + */ + +/** Integer representation of no connect pin (required to exist in all BSPs) */ +#define CYHAL_NC_PIN_VALUE ( (cyhal_gpio_t)0xFFFFFFFF ) + +/** \} group_hal_gpio_macros */ + + +/** + * \addtogroup group_hal_gpio_enums + * \{ + */ + +/******************************************************************************* +* Enumerations +*******************************************************************************/ + +/** Pin IRQ events */ +typedef enum +{ + CYHAL_GPIO_IRQ_NONE = 0, /**< No interrupt */ + CYHAL_GPIO_IRQ_RISE = 1, /**< Interrupt on rising edge */ + CYHAL_GPIO_IRQ_FALL = 2, /**< Interrupt on falling edge */ + CYHAL_GPIO_IRQ_BOTH = 3, /**< Interrupt on both rising and falling edges */ +} cyhal_gpio_irq_event_t; + +/** Pin direction */ +typedef enum +{ + CYHAL_GPIO_DIR_INPUT = 0, /**< Input pin */ + CYHAL_GPIO_DIR_OUTPUT = 1, /**< Output pin */ + CYHAL_GPIO_DIR_BIDIRECTIONAL = 2, /**< Input and output pin */ +} cyhal_gpio_direction_t; + +/** Pin drive mode */ +typedef enum +{ + CYHAL_GPIO_DRIVE_NONE = 0, /**< No drive; Hi-Z */ + CYHAL_GPIO_DRIVE_ANALOG = 0, /**< Analog Hi-Z */ + CYHAL_GPIO_DRIVE_PULLUP = 2, /**< Pull-up resistor */ + CYHAL_GPIO_DRIVE_PULLDOWN = 3, /**< Pull-down resistor */ + CYHAL_GPIO_DRIVE_OPENDRAINDRIVESLOW = 4, /**< Open-drain, Drives Low */ + CYHAL_GPIO_DRIVE_OPENDRAINDRIVESHIGH = 5, /**< Open-drain, Drives High */ + CYHAL_GPIO_DRIVE_STRONG = 6, /**< Strong output */ + CYHAL_GPIO_DRIVE_PULLUPDOWN = 7, /**< Pull-up and pull-down resistors */ +} cyhal_gpio_drive_mode_t; + +/** \} group_hal_gpio_enums */ + + +/** + * \addtogroup group_hal_gpio_data_structures + * \{ + */ + +/** GPIO callback function type */ +typedef void (*cyhal_gpio_irq_handler_t)(void *handler_arg, cyhal_gpio_irq_event_t event); + +/** \} group_hal_gpio_data_structures */ + + +/** + * \addtogroup group_hal_gpio_functions + * \{ + */ + +/******************************************************************************* +* Functions +*******************************************************************************/ + +/** Initialize the GPIO pin + * + * @param[in] pin The GPIO pin to initialize + * @param[in] direction The pin direction (input/output) + * @param[in] drvMode The pin drive mode + * @param[in] initVal Initial value on the pin + * + * @return The status of the init request + */ +cy_rslt_t cyhal_gpio_init(cyhal_gpio_t pin, cyhal_gpio_direction_t direction, cyhal_gpio_drive_mode_t drvMode, + bool initVal); + +/** Uninitialize the gpio peripheral and the cyhal_gpio_t object + * + * @param[in] pin Pin number + */ +void cyhal_gpio_free(cyhal_gpio_t pin); + +/** Set the pin direction + * + * @param[in] pin The pin number + * @param[in] direction The pin direction to be set + * @return The status of the dir request + */ +cy_rslt_t cyhal_gpio_direction(cyhal_gpio_t pin, cyhal_gpio_direction_t direction); + +/** Set the input pin mode + * + * @param[in] pin The GPIO object + * @param[in] drvMode The pin mode to be set + * + * @return The status of the mode request + */ +cy_rslt_t cyhal_gpio_drivemode(cyhal_gpio_t pin, cyhal_gpio_drive_mode_t drvMode); + +/** Set the output value for the pin. This only works for output & in_out pins. + * + * @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 input & in_out pins. + * + * @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 + * + * @param[in] pin The GPIO object + */ +void cyhal_gpio_toggle(cyhal_gpio_t pin); + +/** Register/clear an interrupt handler for the pin toggle pin IRQ event + * + * @param[in] pin The pin number + * @param[in] intrPriority The NVIC interrupt channel priority + * @param[in] handler The function to call when the specified event happens. Pass NULL to unregister the handler. + * @param[in] handler_arg Generic argument that will be provided to the handler when called, can be NULL + */ +void cyhal_gpio_register_irq(cyhal_gpio_t pin, uint8_t intrPriority, cyhal_gpio_irq_handler_t handler, + void *handler_arg); + +/** Enable or Disable the GPIO IRQ + * + * @param[in] pin The GPIO object + * @param[in] event The GPIO IRQ event + * @param[in] enable True to turn on interrupts, False to turn off + */ +void cyhal_gpio_irq_enable(cyhal_gpio_t pin, cyhal_gpio_irq_event_t event, bool enable); + +/** \} group_hal_gpio_functions */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +/** \} group_hal_gpio */ diff --git a/include/whd_port/hal/cyhal_hw_types.h b/include/whd_port/hal/cyhal_hw_types.h new file mode 100644 index 0000000..8359920 --- /dev/null +++ b/include/whd_port/hal/cyhal_hw_types.h @@ -0,0 +1,93 @@ +/***************************************************************************//** +* \file cyhal_hw_types_template.h +* +* \brief +* Provides a template for configuration resources used by the HAL. Items +* here need to be implemented for each HAL port. It is up to the environment +* being ported into what the actual types are. There are some suggestions below +* but these are not required. All that is required is that the type is defined; +* it does not matter to the HAL what type is actually chosen for the +* implementation +* All TODOs and references to 'PORT' need to be replaced by with meaningful +* values for the device being supported. +* +******************************************************************************** +* \copyright +* Copyright 2018-2019 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/** + * \addtogroup group_hal_hw_types PORT Hardware Types + * \ingroup group_hal_PORT + * \{ + * Struct definitions for configuration resources in the PORT. + * + * \defgroup group_hal_hw_types_data_structures Data Structures + */ + +#pragma once + +/* + #include "TODO: Port specific header file" + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup group_hal_hw_types_data_structures + * \{ + */ + +/** GPIO object */ +typedef uint32_t /* TODO: port specific type */ cyhal_gpio_t; + +/** Clock divider object */ +typedef struct +{ + /* TODO: replace with port specific items */ + void *div_type; +} cyhal_clock_divider_t; + +/** SDIO object */ +typedef struct +{ + /* TODO: replace with port specific items */ + void *empty; +} cyhal_sdio_t; + +/** SPI object */ +typedef struct +{ + /* TODO: replace with port specific items */ + void *empty; +} cyhal_spi_t; + +/** M2M/DMA object */ +typedef struct +{ + /* TODO: replace with port specific items */ + void *empty; +} cyhal_m2m_t; + +/** \} group_hal_hw_types_data_structures */ + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/** \} group_hal_hw_types */ diff --git a/include/whd_port/hal/cyhal_modules.h b/include/whd_port/hal/cyhal_modules.h new file mode 100755 index 0000000..bac87df --- /dev/null +++ b/include/whd_port/hal/cyhal_modules.h @@ -0,0 +1,85 @@ +/***************************************************************************//** +* \file cyhal_modules.h +* +* \brief +* Provides an enum of all HAL modules types that can be used for generating +* custom cy_rslt_t items. +* +******************************************************************************** +* \copyright +* Copyright 2018-2019 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/** + * \addtogroup group_hal_modules Driver Modules + * \ingroup group_hal + * \{ + * Enum definition for all HAL resource modules. + * + * \defgroup group_hal_modules_enums Enumerated Types + */ + +#pragma once + +#include "cy_result.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * \addtogroup group_hal_modules_enums + * \{ + */ + +/** Enum to in indicate which module an errors occurred in. */ +enum cyhal_rslt_module_chip +{ + CYHAL_RSLT_MODULE_CHIP_HWMGR = CY_RSLT_MODULE_ABSTRACTION_HAL_BASE, //!< An error occurred in hardware management module + CYHAL_RSLT_MODULE_ADC, //!< An error occurred in ADC module + CYHAL_RSLT_MODULE_COMP, //!< An error occurred in comparator module + CYHAL_RSLT_MODULE_CRC, //!< An error occurred in crypto CRC module + CYHAL_RSLT_MODULE_DAC, //!< An error occurred in DAC module + CYHAL_RSLT_MODULE_DMA, //!< An error occurred in DMA module + CYHAL_RSLT_MODULE_FLASH, //!< An error occurred in flash module + CYHAL_RSLT_MODULE_GPIO, //!< An error occurred in GPIO module + CYHAL_RSLT_MODULE_I2C, //!< An error occurred in I2C module + CYHAL_RSLT_MODULE_I2S, //!< An error occurred in I2S module + CYHAL_RSLT_MODULE_INTERCONNECT, //!< An error occurred in Interconnct module + CYHAL_RSLT_MODULE_OPAMP, //!< An error occurred in OpAmp module + CYHAL_RSLT_MODULE_PDMPCM, //!< An error occurred in PDM/PCM module + CYHAL_RSLT_MODULE_PWM, //!< An error occurred in PWM module + CYHAL_RSLT_MODULE_QSPI, //!< An error occurred in QSPI module + CYHAL_RSLT_MODULE_RTC, //!< An error occurred in RTC module + CYHAL_RSLT_MODULE_SDHC, //!< An error occurred in SDHC module + CYHAL_RSLT_MODULE_SDIO, //!< An error occurred in SDIO module + CYHAL_RSLT_MODULE_SPI, //!< An error occurred in SPI module + CYHAL_RSLT_MODULE_SYSTEM, //!< An error occurred in System module + CYHAL_RSLT_MODULE_TIMER, //!< An error occurred in Timer module + CYHAL_RSLT_MODULE_TRNG, //!< An error occurred in RNG module + CYHAL_RSLT_MODULE_UART, //!< An error occurred in UART module + CYHAL_RSLT_MODULE_USB, //!< An error occurred in USB module + CYHAL_RSLT_MODULE_WDT, //!< An error occurred in WDT module +}; + +/** \} group_hal_modules_enums */ + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/** \} group_hal_modules */ diff --git a/include/whd_port/hal/cyhal_sdio.h b/include/whd_port/hal/cyhal_sdio.h new file mode 100644 index 0000000..ab8d5e9 --- /dev/null +++ b/include/whd_port/hal/cyhal_sdio.h @@ -0,0 +1,273 @@ +/***************************************************************************//** +* \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-2019 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/** + * \addtogroup group_hal_sdio SDIO (Secure Digital Input Output) + * \ingroup group_hal + * \{ + * High level interface for interacting with the Cypress SDIO interface. + * + * \defgroup group_hal_sdio_macros Macros + * \defgroup group_hal_sdio_functions Functions + * \defgroup group_hal_sdio_data_structures Data Structures + * \defgroup group_hal_sdio_enums Enumerated Types + */ + +#pragma once + +#include +#include +#include "cy_result.h" +#include "cyhal_hw_types.h" +#include "cyhal_modules.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +/** + * \addtogroup group_hal_sdio_macros + * \{ + */ + +#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 */ + +/* HAL return value defines */ + +/** Incorrect parameter value define */ +#define CYHAL_SDIO_RSLT_ERR_BAD_PARAM CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, \ + CYHAL_RSLT_MODULE_SDIO, \ + CYHAL_SDIO_BAD_ARGUMENT) + +/** Clock initialization error define */ +#define CYHAL_SDIO_RSLT_ERR_CLOCK CY_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 CY_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) CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, \ + CYHAL_RSLT_MODULE_SDIO, (retVal) ) + +/** \} group_hal_sdio_macros */ + + +/** + * \addtogroup group_hal_sdio_enums + * \{ + */ + +/** 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; + +/** Events that can cause an SDIO interrupt */ +typedef enum +{ + CYHAL_SDIO_CMD_COMPLETE = 0x0001, //!> Command Complete + CYHAL_SDIO_XFER_COMPLETE = 0x0002, //!> Host read/write transfer is complete + CYHAL_SDIO_BGAP_EVENT = 0x0004, //!> This bit is set when both read/write transaction is stopped + CYHAL_SDIO_DMA_INTERRUPT = 0x0008, //!> Host controller detects an SDMA Buffer Boundary during transfer + CYHAL_SDIO_BUF_WR_READY = 0x0010, //!> This bit is set if the Buffer Write Enable changes from 0 to 1 + CYHAL_SDIO_BUF_RD_READY = 0x0020, //!> This bit is set if the Buffer Read Enable changes from 0 to 1 + CYHAL_SDIO_CARD_INSERTION = 0x0040, //!> This bit is set if the Card Inserted in the Present State + CYHAL_SDIO_CARD_REMOVAL = 0x0080, //!> This bit is set if the Card Inserted in the Present State + CYHAL_SDIO_CARD_INTERRUPT = 0x0100, //!> The synchronized value of the DAT[1] interrupt input for SD mode + CYHAL_SDIO_INT_A = 0x0200, //!> Reserved: set to 0 + CYHAL_SDIO_INT_B = 0x0400, //!> Reserved: set to 0 + CYHAL_SDIO_INT_C = 0x0800, //!> Reserved: set to 0, + CYHAL_SDIO_RE_TUNE_EVENT = 0x1000, //!> Reserved: set to 0, + CYHAL_SDIO_FX_EVENT = 0x2000, //!> This status is set when R[14] of response register is set to 1 + CYHAL_SDIO_CQE_EVENT = 0x4000, //!> This status is set if Command Queuing/Crypto event has occurred + CYHAL_SDIO_ERR_INTERRUPT = 0x8000, //!> If any of the bits in the Error Interrupt Status register are set + CYHAL_SDIO_ALL_INTERRUPTS = 0xE1FF, //!> Is used to enable/disable all interrupts +} cyhal_sdio_irq_event_t; + +/** \} group_hal_sdio_enums */ + + +/** + * \addtogroup group_hal_sdio_data_structures + * \{ + */ + +/** SDIO controller initial configuration */ +typedef struct +{ + uint32_t frequencyhal_hz; //!< Clock frequency, in hertz + uint16_t block_size; //!< Block size +} cyhal_sdio_cfg_t; + +/** Handler for SDIO interrupts */ +typedef void (*cyhal_sdio_irq_handler_t)(void *handler_arg, cyhal_sdio_irq_event_t event); + +/** \} group_hal_sdio_data_structures */ + + +/** + * \addtogroup group_hal_sdio_functions + * \{ + */ + +/** Initialize the SDIO peripheral + * + * @param[out] obj The SDIO object + * @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 + */ +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 peripheral, not currently invoked. It requires further + * resource management. + * + * @param[in,out] obj The SDIO object + */ +void cyhal_sdio_free(cyhal_sdio_t *obj); + +/** Configure the SDIO block. + * + * @param[in,out] obj The SDIO object + * @param[in] config The sdio configuration to apply + * @return The status of the configure request + */ +cy_rslt_t cyhal_sdio_configure(cyhal_sdio_t *obj, const cyhal_sdio_cfg_t *config); + +/** Sends a command to the SDIO block. + * + * @param[in,out] obj The SDIO object + * @param[in] direction The direction of transfer (read/write) + * @param[in] command The SDIO command to send + * @param[in] argument The argument to the command + * @param[out] response The response from the SDIO device + * @return The status of the configure request + */ +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 (CMD=53) to the SDIO block. + * + * @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. The data buffer + * should be aligned to the block size (64 bytes) if data + * size is greater that block size (64 bytes). + * @param[in] length The number of bytes to send + * @param[out] response The response from the SDIO device + * @return The status of the configure request + */ +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 asynchronus data transfer (CMD=53) to the SDIO block. + * + * @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 configure request + */ +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 Indication of whether the SDIO is still transmitting + */ +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 + */ +cy_rslt_t cyhal_sdio_abort_async(const cyhal_sdio_t *obj); + +/** The sdio interrupt handler registration + * + * @param[in] obj The SDIO object + * @param[in] handler The callback handler which will be invoked when the interrupt fires + * @param[in] handler_arg Generic argument that will be provided to the handler when called + */ +void cyhal_sdio_register_irq(cyhal_sdio_t *obj, cyhal_sdio_irq_handler_t handler, void *handler_arg); + +/** Configure sdio interrupt. + * + * @param[in] obj The SDIO object + * @param[in] event The sdio IRQ type + * @param[in] enable Set to non-zero to enable events, or zero to disable them + */ +void cyhal_sdio_irq_enable(cyhal_sdio_t *obj, cyhal_sdio_irq_event_t event, bool enable); + +/** \} group_hal_sdio_functions */ + +#if defined(__cplusplus) +} +#endif + +/** \} group_hal_sdio */ diff --git a/include/whd_port/hal/cyhal_spi.h b/include/whd_port/hal/cyhal_spi.h new file mode 100644 index 0000000..afe4e1f --- /dev/null +++ b/include/whd_port/hal/cyhal_spi.h @@ -0,0 +1,249 @@ +/***************************************************************************//** +* \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-2019 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/** + * \addtogroup group_hal_spi SPI (Serial Peripheral Interface) + * \ingroup group_hal + * \{ + * High level interface for interacting with the Cypress SPI. + * + * \defgroup group_hal_spi_macros Macros + * \defgroup group_hal_spi_functions Functions + * \defgroup group_hal_spi_data_structures Data Structures + * \defgroup group_hal_spi_enums Enumerated Types + */ + +#pragma once + +#include +#include +#include "cy_result.h" +#include "cyhal_hw_types.h" +#include "cyhal_modules.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +/** + * \addtogroup group_hal_spi_macros + * \{ + */ + +/** Bad argument */ +#define CYHAL_SPI_RSLT_BAD_ARGUMENT (CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SPI, 0) ) +/** Failed to initialize SPI clock */ +#define CYHAL_SPI_RSLT_CLOCK_ERROR (CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SPI, 1) ) +/** Failed to Transfer SPI data */ +#define CYHAL_SPI_RSLT_TRANSFER_ERROR (CY_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 (CY_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 (CY_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 (CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SPI, 6) ) +/** The requested resource type is invalid */ +#define CYHAL_SPI_RSLT_ERR_INVALID_PIN (CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SPI, 7) ) + +/** \} group_hal_spi_macros */ + + +/** SPI interrupt triggers */ +typedef enum +{ + CYHAL_SPI_IRQ_NONE = 0, //!< Disable all interrupt call backs + /** 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_irq_event_t; + +/** Handler for SPI interrupts */ +typedef void (*cyhal_spi_irq_handler_t)(void *handler_arg, cyhal_spi_irq_event_t event); + +/** SPI operating modes */ +typedef enum +{ + /** Standard motorola SPI CPOL=0, CPHA=0 with MSB first operation */ + CYHAL_SPI_MODE_00_MSB, + /** Standard motorola SPI CPOL=0, CPHA=0 with LSB first operation */ + CYHAL_SPI_MODE_00_LSB, + /** Standard motorola SPI CPOL=0, CPHA=1 with MSB first operation */ + CYHAL_SPI_MODE_01_MSB, + /** Standard motorola SPI CPOL=0, CPHA=1 with LSB first operation */ + CYHAL_SPI_MODE_01_LSB, + /** Standard motorola SPI CPOL=1, CPHA=0 with MSB first operation */ + CYHAL_SPI_MODE_10_MSB, + /** Standard motorola SPI CPOL=1, CPHA=0 with LSB first operation */ + CYHAL_SPI_MODE_10_LSB, + /** Standard motorola SPI CPOL=1, CPHA=1 with MSB first operation */ + CYHAL_SPI_MODE_11_MSB, + /** Standard motorola SPI CPOL=1, CPHA=1 with LSB first operation */ + CYHAL_SPI_MODE_11_LSB, +} cyhal_spi_mode_t; + +/** 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 The SPI object to initialize + * @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 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_divider_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 frequency request + */ +cy_rslt_t cyhal_spi_frequency(cyhal_spi_t *obj, uint32_t hz); + +/** Get a received value out of the SPI receive buffer + * + * 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_read(cyhal_spi_t *obj, uint32_t *value); + +/** Write a byte out + * + * @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_write(cyhal_spi_t *obj, uint32_t value); + +/** 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 with the + * value 0xff. + * + * @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, udpated 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); + +/** Begin the SPI transfer. Buffer pointers and lengths are specified in tx_buff and rx_buff + * + * @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); + +/** The SPI interrupt handler registration + * + * @param[in] obj The SPI object + * @param[in] handler The callback handler which will be invoked when the interrupt fires + * @param[in] handler_arg Generic argument that will be provided to the handler when called + */ +void cyhal_spi_register_irq(cyhal_spi_t *obj, cyhal_spi_irq_handler_t handler, void *handler_arg); + +/** Configure SPI interrupt. This function is used for word-approach + * + * @param[in] obj The SPI object + * @param[in] event The SPI IRQ type + * @param[in] enable True to turn on interrupts, False to turn off + */ +void cyhal_spi_irq_enable(cyhal_spi_t *obj, cyhal_spi_irq_event_t event, bool enable); + +/** \} group_hal_spi_functions */ + +#if defined(__cplusplus) +} +#endif diff --git a/include/whd_port/rtos/cyabs_rtos.h b/include/whd_port/rtos/cyabs_rtos.h new file mode 100644 index 0000000..d47f301 --- /dev/null +++ b/include/whd_port/rtos/cyabs_rtos.h @@ -0,0 +1,289 @@ +/***************************************************************************//** +* \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-2019 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#ifndef INCLUDED_CY_RTOS_INTERFACE_H_ +#define INCLUDED_CY_RTOS_INTERFACE_H_ + +#include "cyabs_rtos_impl.h" +#include +#include +#include + +/* + * Note, cyabs_rtos_impl.h above is included and is the implementation of some basic + * types for the abstraction layer. The types expected to be defined are. + * + * cy_thread_t : typedef from underlying RTOS thread type + * cy_thread_arg_t : typedef from the RTOS type that is passed to the + * entry function of a thread. + * cy_time_t : count of time in milliseconds + * cy_rtos_error_t : typedef from the underlying RTOS error type * + * + */ + + +/** + * \addtogroup group_abstraction_rtos RTOS abstraction + * \ingroup group_abstraction + * \{ + * Basic abstraction layer for dealing with RTOSes. + * + * \defgroup group_abstraction_rtos_macros Macros + * \defgroup group_abstraction_rtos_enums Enums + * \defgroup group_abstraction_rtos_data_structures Data Structures + * \defgroup group_abstraction_rtos_functions Functions + */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*********************************************** CONSTANTS **********************************************/ + +/** + * \addtogroup group_abstraction_rtos_macros + * \{ + */ + +/** 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 CY_RTOS_GENERAL_ERROR can be +// returns and cy_rtos_last_error() used to retrieve the RTOS specific error message. +// +/** Requested operationd 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) +/** 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) +/** 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) + +/** \} group_abstraction_rtos_macros */ + + +/*********************************************** TYPES **********************************************/ + +/** + * \addtogroup group_abstraction_rtos_data_structures + * \{ + */ + +/** + * 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 + */ +typedef void (*cy_thread_entry_fn_t)(cy_thread_arg_t arg); + +/** \} group_abstraction_rtos_data_structures */ + + +/** + * \addtogroup group_abstraction_rtos_functions + * \{ + */ + +/*********************************************** 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 + * cy_rtos_finish_thread() just before doing so. All created threds that can terminate, either + * by themselves or forcefully by another thread MUST be joined 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 + * @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. [CY_RSLT_SUCCESS, CY_RTOS_NO_MEMORY, CY_RTOS_GENERAL_ERROR] + */ +extern 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 (cy_rtos_join_thread) to ensure their resources are fully + * cleaned up. + * + * @return The status of thread exit request. [CY_RSLT_SUCCESS, CY_RTOS_GENERAL_ERROR] + */ +extern cy_rslt_t cy_rtos_exit_thread(void); + +/** Terminates another thread. + * + * This function is called to terminate another thread and reap the resoruces claimed + * by it 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 resoruces 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 (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. [CY_RSLT_SUCCESS, CY_RTOS_GENERAL_ERROR] + */ +extern cy_rslt_t cy_rtos_terminate_thread(cy_thread_t *thread); + +/** Checks if the thread is running + * + * This function is called to determine if a thread is running or not. + * + * @param[in] thread handle of the terminated thread to delete + * @param[out] state returns true if the thread is running, otherwise false + * + * @returns The status of the thread check. [CY_RSLT_SUCCESS, CY_RTOS_GENERAL_ERROR] + */ +extern cy_rslt_t cy_rtos_is_thread_running(cy_thread_t *thread, bool *state); + +/** 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. [CY_RSLT_SUCCESS, CY_RTOS_GENERAL_ERROR] + */ +extern cy_rslt_t cy_rtos_join_thread(cy_thread_t *thread); + +/*********************************************** Semaphores **********************************************/ + +/** + * 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 sempahore + * + * @return The status of the sempahore creation. [CY_RSLT_SUCCESS, CY_RTOS_NO_MEMORY, CY_RTOS_GENERAL_ERROR] + */ +extern 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 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 [CY_RSLT_SUCCESS, CY_RTOS_NO_MEMORY, CY_RTOS_GENERAL_ERROR] + */ +extern 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 [CY_RSLT_SUCCESS, CY_RTOS_NO_MEMORY, CY_RTOS_GENERAL_ERROR] + */ +extern cy_rslt_t cy_rtos_set_semaphore(cy_semaphore_t *semaphore, bool in_isr); + +/** + * Deletes a sempahore + * + * This function frees the resources associated with a sempahore. + * + * @param[in] semaphore Pointer to the sempahore handle + * + * @return The status of semaphore deletion [CY_RSLT_SUCCESS, CY_RTOS_NO_MEMORY, CY_RTOS_GENERAL_ERROR] + */ +extern cy_rslt_t cy_rtos_deinit_semaphore(cy_semaphore_t *semaphore); + + +/*********************************************** 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. + */ +extern 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 miliseconds to delay for + * + * @return The status of the creation request. [CY_RSLT_SUCCESS, CY_RTOS_GENERAL_ERROR] + */ +extern cy_rslt_t cy_rtos_delay_milliseconds(cy_time_t num_ms); + +/** \} group_abstraction_rtos_functions */ + +/** @} */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif +#endif /* ifndef INCLUDED_CY_RTOS_INTERFACE_H_ */ diff --git a/include/whd_port/rtos/cyabs_rtos_impl.h b/include/whd_port/rtos/cyabs_rtos_impl.h new file mode 100644 index 0000000..7aae2ab --- /dev/null +++ b/include/whd_port/rtos/cyabs_rtos_impl.h @@ -0,0 +1,46 @@ +/***************************************************************************//** +* \file cyabs_rtos_impl.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-2019 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ +#include +#include + +/* RTOS thread priority, some priorities are aliases since we don't have that much levels */ +typedef enum { + CY_RTOS_PRIORITY_MIN = 0, + CY_RTOS_PRIORITY_LOW = 0, + CY_RTOS_PRIORITY_BELOWNORMAL = 1, + CY_RTOS_PRIORITY_NORMAL = 1, + CY_RTOS_PRIORITY_ABOVENORMAL = 1, + CY_RTOS_PRIORITY_HIGH = 2, + CY_RTOS_PRIORITY_REALTIME = 2, + CY_RTOS_PRIORITY_MAX = 3, +} cy_thread_priority_t; + +typedef void* cy_semaphore_t; /** RTOS definition of a semaphore */ +typedef void* cy_thread_t; /** Note: This is equivelent to TaskHandle_t */ +typedef int32_t cy_rtos_error_t; /** RTOS definition of a error status */ +typedef uint32_t cy_time_t; +typedef void* cy_thread_arg_t; diff --git a/lib/whd/CMakeLists.txt b/lib/whd/CMakeLists.txt index 4401b97..b498ee9 100644 --- a/lib/whd/CMakeLists.txt +++ b/lib/whd/CMakeLists.txt @@ -2,16 +2,11 @@ cmake_minimum_required(VERSION 3.10) project(whd) -if(DEFINED WHD_INTERFACE) - if(WHD_INTERFACE STREQUAL "SDIO") - set(WHD_INTERFACE_DEF "CYBSP_WIFI_INTERFACE_TYPE=CYBSP_SDIO_INTERFACE") - elseif(WHD_INTERFACE STREQUAL "SPI") - set(WHD_INTERFACE_DEF "CYBSP_WIFI_INTERFACE_TYPE=CYBSP_SPI_INTERFACE") - else() - message(WARNING "Invalid WHD_INTERFACE set, using default (SDIO).") - endif() +if(DEFINED WHD_EXTERNAL_PATH) + set(WHD_EXTERNAL_INC ${WHD_EXTERNAL_PATH}) else() - message(WARNING "No WHD_INTERFACE defined, using default (SDIO).") + set(WHD_EXTERNAL_INC "wifi-host-driver/External") + message(WARNING "No WHD_EXTERNAL_PATH defined, using default.") endif() set(WHD_SOURCES @@ -43,9 +38,9 @@ set(WHD_SOURCES ) set(WHD_INCLUDES - "wifi-host-driver/External/bsp" - "wifi-host-driver/External/hal" - "wifi-host-driver/External/rtos" + "${WHD_EXTERNAL_INC}/bsp" + "${WHD_EXTERNAL_INC}/hal" + "${WHD_EXTERNAL_INC}/rtos" "wifi-host-driver/WiFi_Host_Driver/inc" "wifi-host-driver/WiFi_Host_Driver/src" "wifi-host-driver/WiFi_Host_Driver/src/include" diff --git a/src/whd_port/rtos/cyabs_rtos.c b/src/whd_port/rtos/cyabs_rtos.c new file mode 100644 index 0000000..944488d --- /dev/null +++ b/src/whd_port/rtos/cyabs_rtos.c @@ -0,0 +1,77 @@ +#include "cyabs_rtos.h" + +/* FreeRTOS */ +#include "FreeRTOS.h" +#include "semphr.h" +#include "task.h" + +/** + * @note FreeRTOS does not provide Join-like API for one task to wait for another task to exit, + * so we have to implement the 'join' function with a binary semaphore. + * The task being signalled to stop will release the semaphore right before the task is deleted, + * then we can 'join' the task by simply wait for the semaphore to be given. + * This semaphore is created along with the new task, and is deleted within 'join' function, + * and the handle of the semaphore is stored in the Thread Local Storage (TLS) of the target task. + * + */ + +#define CY_RTOS_JOIN_SEMPHR_TLS_ID 0 + +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) { + /* Create a semaphore to let the thread join */ + SemaphoreHandle_t thr_join_semphr = xSemaphoreCreateBinary(); + if (thr_join_semphr == NULL) { + return CY_RTOS_NO_MEMORY; + } + + if (xTaskCreate((TaskFunction_t)entry_function, name, stack_size / sizeof(portSTACK_TYPE), (void *)arg, priority, + (TaskHandle_t *)thread) != pdPASS) { + vSemaphoreDelete(thr_join_semphr); + return CY_RTOS_NO_MEMORY; + } + + /* Store the semaphore handle into the thread local storage */ + vTaskSetThreadLocalStoragePointer(*thread, CY_RTOS_JOIN_SEMPHR_TLS_ID, thr_join_semphr); + + return CY_RSLT_SUCCESS; +} + +cy_rslt_t cy_rtos_exit_thread(void) { + TaskHandle_t cur_task_handle; + SemaphoreHandle_t thr_join_semphore; + + /* Get current task handle and retrieve the semaphore handle from TLS */ + cur_task_handle = xTaskGetCurrentTaskHandle(); + thr_join_semphore = pvTaskGetThreadLocalStoragePointer(cur_task_handle, CY_RTOS_JOIN_SEMPHR_TLS_ID); + + /* Notify that the task is now exit. */ + xSemaphoreGive(thr_join_semphore); + + vTaskDelete(NULL); + + return CY_RSLT_SUCCESS; +} + +cy_rslt_t cy_rtos_terminate_thread(cy_thread_t *thread) { + /* Empty function, thread resource will be released after task function returns. */ + return CY_RSLT_SUCCESS; +} + +cy_rslt_t cy_rtos_join_thread(cy_thread_t *thread) { + SemaphoreHandle_t thr_join_semaphore; + + /* Retrieve the semaphore handle from TLS */ + thr_join_semaphore = pvTaskGetThreadLocalStoragePointer((TaskHandle_t)*thread, CY_RTOS_JOIN_SEMPHR_TLS_ID); + + /* Wait until the target task exit */ + if(xSemaphoreTake(thr_join_semaphore, portMAX_DELAY) != pdPASS) { + /* Really unexpected */ + return CY_RTOS_GENERAL_ERROR; + } + + /* Delete the semaphore here. */ + vSemaphoreDelete(thr_join_semaphore); + + return CY_RSLT_SUCCESS; +} \ No newline at end of file