mirror of https://github.com/ARMmbed/mbed-os.git
Portenta add SDIO GPIO and filesystem implementation
parent
4200d752b2
commit
94ceb8379d
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright 2020 Arduino SA
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** @file
|
||||
* Provides cyhal porting to generic mbed APIs
|
||||
*/
|
||||
#include "cyhal.h"
|
||||
#include "mbed_thread.h"
|
||||
#include "mbed_wait_api.h"
|
||||
|
||||
static cyhal_sdio_t sdio_obj;
|
||||
|
||||
/* Edit Pin configuration */
|
||||
const pinconfig_t PinConfig[] = {
|
||||
|
||||
[CYBSP_WIFI_WL_REG_ON] = WIFI_WL_REG_ON,
|
||||
#ifdef CYBSP_WIFI_32K_CLK
|
||||
[CYBSP_WIFI_32K_CLK] = WIFI_32K_CLK,
|
||||
#endif /* CYBSP_WIFI_32K_CLK */
|
||||
[CYBSP_LED1 ] = BSP_LED1,
|
||||
[CYBSP_LED2 ] = BSP_LED2,
|
||||
[CYBSP_WIFI_SDIO_CMD] = WIFI_SDIO_CMD,
|
||||
[CYBSP_WIFI_SDIO_CLK] = WIFI_SDIO_CLK,
|
||||
[CYBSP_WIFI_SDIO_D0 ] = WIFI_SDIO_D0,
|
||||
[CYBSP_WIFI_SDIO_D1 ] = WIFI_SDIO_D1,
|
||||
[CYBSP_WIFI_SDIO_D2 ] = WIFI_SDIO_D2,
|
||||
[CYBSP_WIFI_SDIO_D3 ] = WIFI_SDIO_D3,
|
||||
[CYBSP_SDIO_OOB_IRQ ] = WIFI_SDIO_OOB_IRQ //VIKR
|
||||
};
|
||||
|
||||
void Cy_SysLib_Delay(uint32_t milliseconds)
|
||||
{
|
||||
thread_sleep_for(milliseconds);
|
||||
}
|
||||
|
||||
void Cy_SysLib_DelayUs(uint16_t microseconds)
|
||||
{
|
||||
wait_us(microseconds);
|
||||
}
|
||||
|
||||
void cyhal_system_delay_ms(uint32_t milliseconds)
|
||||
{
|
||||
Cy_SysLib_Delay(milliseconds);
|
||||
}
|
||||
|
||||
cyhal_sdio_t *cybsp_get_wifi_sdio_obj(void)
|
||||
{
|
||||
return &sdio_obj;
|
||||
}
|
|
@ -0,0 +1,592 @@
|
|||
/***************************************************************************//**
|
||||
* \file cy_syslib.h
|
||||
* \version 2.40.1
|
||||
*
|
||||
* Provides an API declaration of the SysLib driver.
|
||||
*
|
||||
********************************************************************************
|
||||
* \copyright
|
||||
* Copyright 2016-2019 Cypress Semiconductor Corporation
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*******************************************************************************/
|
||||
|
||||
/**
|
||||
* \addtogroup group_syslib
|
||||
* \{
|
||||
* The system libraries provide APIs that can be called in the user application
|
||||
* to handle the timing, logical checking or register.
|
||||
*
|
||||
* The functions and other declarations used in this driver are in cy_syslib.h.
|
||||
* You can include cy_pdl.h (ModusToolbox only) to get access to all functions
|
||||
* and declarations in the PDL.
|
||||
*
|
||||
* The SysLib driver contains a set of different system functions. These functions
|
||||
* can be called in the application routine. Major features of the system library:
|
||||
* * Delay functions
|
||||
* * The register Read/Write macro
|
||||
* * Assert and Halt
|
||||
* * Assert Classes and Levels
|
||||
* * A software reset
|
||||
* * Reading the reset cause
|
||||
* * An API to invalidate the flash cache and buffer
|
||||
* * Data manipulation macro
|
||||
* * A variable type definition from MISRA-C which specifies signedness
|
||||
* * Cross compiler compatible attributes
|
||||
* * Getting a silicon-unique ID API
|
||||
* * Setting wait states API
|
||||
* * Resetting the backup domain API
|
||||
* * APIs to serve Fault handler
|
||||
*
|
||||
* \section group_syslib_configuration Configuration Considerations
|
||||
* <b> Assertion Usage </b> <br />
|
||||
* Use the CY_ASSERT() macro to check expressions that must be true as long as the
|
||||
* program is running correctly. It is a convenient way to insert sanity checks.
|
||||
* The CY_ASSERT() macro is defined in the cy_syslib.h file which is part of
|
||||
* the PDL library. The behavior of the macro is as follows: if the expression
|
||||
* passed to the macro is false, output an error message that includes the file
|
||||
* name and line number, and then halts the CPU. \n
|
||||
* In case of fault, the CY_ASSERT() macro calls the Cy_SysLib_AssertFailed() function.
|
||||
* This is a weakly linked function. The default implementation stores the file
|
||||
* name and line number of the ASSERT into global variables, cy_assertFileName
|
||||
* and cy_assertLine . It then calls the Cy_SysLib_Halt() function.
|
||||
* \note Firmware can redefine the Cy_SysLib_AssertFailed() function for custom processing.
|
||||
*
|
||||
* The PDL source code uses this assert mechanism extensively. It is recommended
|
||||
* that you enable asserts when debugging firmware. \n
|
||||
* <b> Assertion Classes and Levels </b> <br />
|
||||
* The PDL defines three assert classes, which correspond to different kinds
|
||||
* of parameters. There is a corresponding assert "level" for each class.
|
||||
* <table class="doxtable">
|
||||
* <tr><th>Class Macro</th><th>Level Macro</th><th>Type of check</th></tr>
|
||||
* <tr>
|
||||
* <td>CY_ASSERT_CLASS_1</td>
|
||||
* <td>CY_ASSERT_L1</td>
|
||||
* <td>A parameter that could change between different PSoC devices
|
||||
* (e.g. the number of clock paths)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>CY_ASSERT_CLASS_2</td>
|
||||
* <td>CY_ASSERT_L2</td>
|
||||
* <td>A parameter that has fixed limits such as a counter period</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>CY_ASSERT_CLASS_3</td>
|
||||
* <td>CY_ASSERT_L3</td>
|
||||
* <td>A parameter that is an enum constant</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
* Firmware defines which ASSERT class is enabled by defining CY_ASSERT_LEVEL.
|
||||
* This is a compiler command line argument, similar to how the DEBUG / NDEBUG
|
||||
* macro is passed. \n
|
||||
* Enabling any class also enables any lower-numbered class.
|
||||
* CY_ASSERT_CLASS_3 is the default level, and it enables asserts for all three
|
||||
* classes. The following example shows the command-line option to enable all
|
||||
* the assert levels:
|
||||
* \code -D CY_ASSERT_LEVEL=CY_ASSERT_CLASS_3 \endcode
|
||||
* \note The use of special characters, such as spaces, parenthesis, etc. must
|
||||
* be protected with quotes.
|
||||
*
|
||||
* After CY_ASSERT_LEVEL is defined, firmware can use
|
||||
* one of the three level macros to make an assertion. For example, if the
|
||||
* parameter can vary between devices, firmware uses the L1 macro.
|
||||
* \code CY_ASSERT_L1(clkPath < SRSS_NUM_CLKPATH); \endcode
|
||||
* If the parameter has bounds, firmware uses L2.
|
||||
* \code CY_ASSERT_L2(trim <= CY_CTB_TRIM_VALUE_MAX); \endcode
|
||||
* If the parameter is an enum, firmware uses L3.
|
||||
* \code CY_ASSERT_L3(config->LossAction <= CY_SYSCLK_CSV_ERROR_FAULT_RESET); \endcode
|
||||
* Each check uses the appropriate level macro for the kind of parameter being checked.
|
||||
* If a particular assert class/level is not enabled, then the assert does nothing.
|
||||
*
|
||||
* \section group_syslib_more_information More Information
|
||||
* Refer to the technical reference manual (TRM).
|
||||
*
|
||||
* \section group_syslib_MISRA MISRA-C Compliance
|
||||
* <table class="doxtable">
|
||||
* <tr>
|
||||
* <th>MISRA Rule</th>
|
||||
* <th>Rule Class (Required/Advisory)</th>
|
||||
* <th>Rule Description</th>
|
||||
* <th>Description of Deviation(s)</th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>1.2</td>
|
||||
* <td>R</td>
|
||||
* <td>No reliance shall be placed on undefined or unspecified behaviour.</td>
|
||||
* <td>This specific behavior is explicitly covered in rule 20.1.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>2.1</td>
|
||||
* <td>R</td>
|
||||
* <td>This function contains a mixture of in-line assembler statements and C statements.</td>
|
||||
* <td>This si required by design of the Cy_SysLib_Halt function.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>18.4</td>
|
||||
* <td>R</td>
|
||||
* <td>Unions shall not be used.</td>
|
||||
* <td>The unions are used for CFSR, HFSR and SHCSR Fault Status Registers
|
||||
* content access as a word in code and as a structure during debug.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>19.13</td>
|
||||
* <td>A</td>
|
||||
* <td>The # and ## operators should not be used.</td>
|
||||
* <td>The ## preprocessor operator is used in macros to form the field mask.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>20.1</td>
|
||||
* <td>R</td>
|
||||
* <td>Reserved identifiers, macros and functions in the standard library, shall not be
|
||||
* defined, redefined or undefined.</td>
|
||||
* <td>The driver defines the macros with leading underscores
|
||||
* (_CLR_SET_FLD/_BOOL2FLD/_FLD2BOOL) and therefore generates this MISRA violation.</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section group_syslib_changelog Changelog
|
||||
* <table class="doxtable">
|
||||
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
|
||||
* <tr>
|
||||
* <td>2.40.1</td>
|
||||
* <td>Correct the CY_RAMFUNC_BEGIN macro for the IAR compiler.</td>
|
||||
* <td>Removed the IAR compiler warning.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>2.40</td>
|
||||
* <td>Added new macros CY_SYSLIB_DIV_ROUND and CY_SYSLIB_DIV_ROUNDUP to easy perform integer division with rounding.</td>
|
||||
* <td>Improve PDL code base.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td rowspan="3">2.30</td>
|
||||
* <td>Updated implementation of the Cy_SysLib_AsmInfiniteLoop() function to be compatible with ARMC6.</td>
|
||||
* <td>Provided support for the ARM Compiler 6.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>Minor documentation edits.</td>
|
||||
* <td>Documentation update and clarification.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>Added new macros CY_RAMFUNC_BEGIN and CY_RAMFUNC_END for convenient placement function in RAM for all supported compilers.</td>
|
||||
* <td>Improve user experience.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td rowspan="2">2.20</td>
|
||||
* <td>Updated implementation of the \ref Cy_SysLib_AssertFailed() function to be available in Release and Debug modes.</td>
|
||||
* <td>Provided support for the PDL static library in Release mode.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>Minor documentation edits.</td>
|
||||
* <td>Documentation update and clarification.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td rowspan="4">2.10</td>
|
||||
* <td>Flattened the organization of the driver source code into the single source directory and the single include directory.</td>
|
||||
* <td>Driver library directory-structure simplification.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>Added the following macros: \ref CY_REG32_CLR_SET, \ref _CLR_SET_FLD16U, \ref CY_REG16_CLR_SET, \ref _CLR_SET_FLD8U, \ref CY_REG8_CLR_SET</td>
|
||||
* <td>Register access simplification.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>Removed the Cy_SysLib_GetNumHfclkResetCause API function.</td>
|
||||
* <td>This feature is not supported by SRSS_ver1.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>Added register access layer. Use register access macros instead
|
||||
* of direct register access using dereferenced pointers.</td>
|
||||
* <td>Makes register access device-independent, so that the PDL does
|
||||
* not need to be recompiled for each supported part number.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>2.0.1</td>
|
||||
* <td>Minor documentation edits</td>
|
||||
* <td>Documentation update and clarification</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td rowspan="4"> 2.0</td>
|
||||
* <td>
|
||||
* Added Cy_SysLib_ResetBackupDomain() API implementation. \n
|
||||
* Added CY_NOINLINE attribute implementation. \n
|
||||
* Added DIE_YEAR field to 64-bit unique ID return value of Cy_SysLib_GetUniqueId() API. \n
|
||||
* Added storing of SCB->HFSR, SCB->SHCSR registers and SCB->MMFAR, SCB->BFAR addresses to Fault Handler debug structure. \n
|
||||
* Optimized Cy_SysLib_SetWaitStates() API implementation.
|
||||
* </td>
|
||||
* <td>Improvements made based on usability feedback.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>Added Assertion Classes and Levels.</td>
|
||||
* <td>For error checking, parameter validation and status returns in the PDL API.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>Applied CY_NOINIT attribute to cy_assertFileName, cy_assertLine, and cy_faultFrame global variables.</td>
|
||||
* <td>To store debug information into a non-zero init area for future analysis.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>Removed CY_WEAK attribute implementation.</td>
|
||||
* <td>CMSIS __WEAK attribute should be used instead.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>1.0</td>
|
||||
* <td>Initial version</td>
|
||||
* <td></td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \defgroup group_syslib_macros Macros
|
||||
* \defgroup group_syslib_functions Functions
|
||||
* \defgroup group_syslib_data_structures Data Structures
|
||||
* \defgroup group_syslib_enumerated_types Enumerated Types
|
||||
*
|
||||
*/
|
||||
|
||||
#if !defined(CY_SYSLIB_H)
|
||||
#define CY_SYSLIB_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* Data manipulation defines
|
||||
*******************************************************************************/
|
||||
|
||||
/** Get the lower 8 bits of a 16-bit value. */
|
||||
#define CY_LO8(x) ((uint8_t) ((x) & 0xFFU))
|
||||
/** Get the upper 8 bits of a 16-bit value. */
|
||||
#define CY_HI8(x) ((uint8_t) ((uint16_t)(x) >> 8U))
|
||||
|
||||
/** Get the lower 16 bits of a 32-bit value. */
|
||||
#define CY_LO16(x) ((uint16_t) ((x) & 0xFFFFU))
|
||||
/** Get the upper 16 bits of a 32-bit value. */
|
||||
#define CY_HI16(x) ((uint16_t) ((uint32_t)(x) >> 16U))
|
||||
|
||||
/** Swap the byte ordering of a 16-bit value */
|
||||
#define CY_SWAP_ENDIAN16(x) ((uint16_t)(((x) << 8U) | (((x) >> 8U) & 0x00FFU)))
|
||||
|
||||
/** Swap the byte ordering of a 32-bit value */
|
||||
#define CY_SWAP_ENDIAN32(x) ((uint32_t)((((x) >> 24U) & 0x000000FFU) | (((x) & 0x00FF0000U) >> 8U) | \
|
||||
(((x) & 0x0000FF00U) << 8U) | ((x) << 24U)))
|
||||
|
||||
/** Swap the byte ordering of a 64-bit value */
|
||||
#define CY_SWAP_ENDIAN64(x) ((uint64_t) (((uint64_t) CY_SWAP_ENDIAN32((uint32_t)(x)) << 32U) | \
|
||||
CY_SWAP_ENDIAN32((uint32_t)((x) >> 32U))))
|
||||
|
||||
/* MISRA rule 6.3 recommends using specific-length typedef for the basic
|
||||
* numerical types of signed and unsigned variants of char, float, and double.
|
||||
*/
|
||||
typedef char char_t; /**< Specific-length typedef for the basic numerical types of char */
|
||||
typedef float float32_t; /**< Specific-length typedef for the basic numerical types of float */
|
||||
typedef double float64_t; /**< Specific-length typedef for the basic numerical types of double */
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Macro Name: CY_GET_REG8(addr)
|
||||
****************************************************************************//**
|
||||
*
|
||||
* Reads the 8-bit value from the specified address. This function can't be
|
||||
* used to access the Core register, otherwise a fault occurs.
|
||||
*
|
||||
* \param addr The register address.
|
||||
*
|
||||
* \return The read value.
|
||||
*
|
||||
*******************************************************************************/
|
||||
#define CY_GET_REG8(addr) (*((const volatile uint8_t *)(addr)))
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Macro Name: CY_SET_REG8(addr, value)
|
||||
****************************************************************************//**
|
||||
*
|
||||
* Writes an 8-bit value to the specified address. This function can't be
|
||||
* used to access the Core register, otherwise a fault occurs.
|
||||
*
|
||||
* \param addr The register address.
|
||||
*
|
||||
* \param value The value to write.
|
||||
*
|
||||
*******************************************************************************/
|
||||
#define CY_SET_REG8(addr, value) (*((volatile uint8_t *)(addr)) = (uint8_t)(value))
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Macro Name: CY_GET_REG16(addr)
|
||||
****************************************************************************//**
|
||||
*
|
||||
* Reads the 16-bit value from the specified address.
|
||||
*
|
||||
* \param addr The register address.
|
||||
*
|
||||
* \return The read value.
|
||||
*
|
||||
*******************************************************************************/
|
||||
#define CY_GET_REG16(addr) (*((const volatile uint16_t *)(addr)))
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Macro Name: CY_SET_REG16(addr, value)
|
||||
****************************************************************************//**
|
||||
*
|
||||
* Writes the 16-bit value to the specified address.
|
||||
*
|
||||
* \param addr The register address.
|
||||
*
|
||||
* \param value The value to write.
|
||||
*
|
||||
*******************************************************************************/
|
||||
#define CY_SET_REG16(addr, value) (*((volatile uint16_t *)(addr)) = (uint16_t)(value))
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Macro Name: CY_GET_REG24(addr)
|
||||
****************************************************************************//**
|
||||
*
|
||||
* Reads the 24-bit value from the specified address.
|
||||
*
|
||||
* \param addr The register address.
|
||||
*
|
||||
* \return The read value.
|
||||
*
|
||||
*******************************************************************************/
|
||||
#define CY_GET_REG24(addr) (((uint32_t) (*((const volatile uint8_t *)(addr)))) | \
|
||||
(((uint32_t) (*((const volatile uint8_t *)(addr) + 1))) << 8U) | \
|
||||
(((uint32_t) (*((const volatile uint8_t *)(addr) + 2))) << 16U))
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Macro Name: CY_SET_REG24(addr, value)
|
||||
****************************************************************************//**
|
||||
*
|
||||
* Writes the 24-bit value to the specified address.
|
||||
*
|
||||
* \param addr The register address.
|
||||
*
|
||||
* \param value The value to write.
|
||||
*
|
||||
*******************************************************************************/
|
||||
#define CY_SET_REG24(addr, value) do \
|
||||
{ \
|
||||
(*((volatile uint8_t *) (addr))) = (uint8_t)(value); \
|
||||
(*((volatile uint8_t *) (addr) + 1)) = (uint8_t)((value) >> 8U); \
|
||||
(*((volatile uint8_t *) (addr) + 2)) = (uint8_t)((value) >> 16U); \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Macro Name: CY_GET_REG32(addr)
|
||||
****************************************************************************//**
|
||||
*
|
||||
* Reads the 32-bit value from the specified register. The address is the little
|
||||
* endian order (LSB in lowest address).
|
||||
*
|
||||
* \param addr The register address.
|
||||
*
|
||||
* \return The read value.
|
||||
*
|
||||
*******************************************************************************/
|
||||
#define CY_GET_REG32(addr) (*((const volatile uint32_t *)(addr)))
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Macro Name: CY_SET_REG32(addr, value)
|
||||
****************************************************************************//**
|
||||
*
|
||||
* Writes the 32-bit value to the specified register. The address is the little
|
||||
* endian order (LSB in lowest address).
|
||||
*
|
||||
* \param addr The register address.
|
||||
*
|
||||
* \param value The value to write.
|
||||
*
|
||||
*******************************************************************************/
|
||||
#define CY_SET_REG32(addr, value) (*((volatile uint32_t *)(addr)) = (uint32_t)(value))
|
||||
|
||||
/*******************************************************************************
|
||||
* Macro Name: _CLR_SET_FLD32U
|
||||
****************************************************************************//**
|
||||
*
|
||||
* The macro for setting a register with a name field and value for providing
|
||||
* get-clear-modify-write operations.
|
||||
* Returns a resulting value to be assigned to the register.
|
||||
*
|
||||
*******************************************************************************/
|
||||
#define _CLR_SET_FLD32U(reg, field, value) (((reg) & ((uint32_t)(~(field ## _Msk)))) | (_VAL2FLD(field, value)))
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Macro Name: CY_REG32_CLR_SET
|
||||
****************************************************************************//**
|
||||
*
|
||||
* Uses _CLR_SET_FLD32U macro for providing get-clear-modify-write
|
||||
* operations with a name field and value and writes a resulting value
|
||||
* to the 32-bit register.
|
||||
*
|
||||
*******************************************************************************/
|
||||
#define CY_REG32_CLR_SET(reg, field, value) ((reg) = _CLR_SET_FLD32U((reg), field, (value)))
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Macro Name: _CLR_SET_FLD16U
|
||||
****************************************************************************//**
|
||||
*
|
||||
* The macro for setting a 16-bit register with a name field and value for providing
|
||||
* get-clear-modify-write operations.
|
||||
* Returns a resulting value to be assigned to the 16-bit register.
|
||||
*
|
||||
*******************************************************************************/
|
||||
#define _CLR_SET_FLD16U(reg, field, value) ((uint16_t)(((reg) & ((uint16_t)(~(field ## _Msk)))) | \
|
||||
((uint16_t)_VAL2FLD(field, value))))
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Macro Name: CY_REG16_CLR_SET
|
||||
****************************************************************************//**
|
||||
*
|
||||
* Uses _CLR_SET_FLD16U macro for providing get-clear-modify-write
|
||||
* operations with a name field and value and writes a resulting value
|
||||
* to the 16-bit register.
|
||||
*
|
||||
*******************************************************************************/
|
||||
#define CY_REG16_CLR_SET(reg, field, value) ((reg) = _CLR_SET_FLD16U((reg), field, (value)))
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Macro Name: _CLR_SET_FLD8U
|
||||
****************************************************************************//**
|
||||
*
|
||||
* The macro for setting a 8-bit register with a name field and value for providing
|
||||
* get-clear-modify-write operations.
|
||||
* Returns a resulting value to be assigned to the 8-bit register.
|
||||
*
|
||||
*******************************************************************************/
|
||||
#define _CLR_SET_FLD8U(reg, field, value) ((uint8_t)(((reg) & ((uint8_t)(~(field ## _Msk)))) | \
|
||||
((uint8_t)_VAL2FLD(field, value))))
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Macro Name: CY_REG8_CLR_SET
|
||||
****************************************************************************//**
|
||||
*
|
||||
* Uses _CLR_SET_FLD8U macro for providing get-clear-modify-write
|
||||
* operations with a name field and value and writes a resulting value
|
||||
* to the 8-bit register.
|
||||
*
|
||||
*******************************************************************************/
|
||||
#define CY_REG8_CLR_SET(reg, field, value) ((reg) = _CLR_SET_FLD8U((reg), field, (value)))
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Macro Name: _BOOL2FLD
|
||||
****************************************************************************//**
|
||||
*
|
||||
* Returns a field mask if the value is not false.
|
||||
* Returns 0, if the value is false.
|
||||
*
|
||||
*******************************************************************************/
|
||||
#define _BOOL2FLD(field, value) (((value) != false) ? (field ## _Msk) : 0UL)
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Macro Name: _FLD2BOOL
|
||||
****************************************************************************//**
|
||||
*
|
||||
* Returns true, if the value includes the field mask.
|
||||
* Returns false, if the value doesn't include the field mask.
|
||||
*
|
||||
*******************************************************************************/
|
||||
#define _FLD2BOOL(field, value) (((value) & (field ## _Msk)) != 0UL)
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Macro Name: CY_SYSLIB_DIV_ROUND
|
||||
****************************************************************************//**
|
||||
*
|
||||
* Calculates a / b with rounding to the nearest integer,
|
||||
* a and b must have the same sign.
|
||||
*
|
||||
*******************************************************************************/
|
||||
#define CY_SYSLIB_DIV_ROUND(a, b) (((a) + ((b) / 2U)) / (b))
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Macro Name: CY_SYSLIB_DIV_ROUNDUP
|
||||
****************************************************************************//**
|
||||
*
|
||||
* Calculates a / b with rounding up if remainder != 0,
|
||||
* both a and b must be positive.
|
||||
*
|
||||
*******************************************************************************/
|
||||
#define CY_SYSLIB_DIV_ROUNDUP(a, b) ((((a) - 1U) / (b)) + 1U)
|
||||
|
||||
typedef uint32_t cy_status;
|
||||
/** The ARM 32-bit status value for backward compatibility with the UDB components. Do not use it in your code. */
|
||||
typedef uint32_t cystatus;
|
||||
typedef uint8_t uint8; /**< Alias to uint8_t for backward compatibility */
|
||||
typedef uint16_t uint16; /**< Alias to uint16_t for backward compatibility */
|
||||
typedef uint32_t uint32; /**< Alias to uint32_t for backward compatibility */
|
||||
typedef int8_t int8; /**< Alias to int8_t for backward compatibility */
|
||||
typedef int16_t int16; /**< Alias to int16_t for backward compatibility */
|
||||
typedef int32_t int32; /**< Alias to int32_t for backward compatibility */
|
||||
typedef float float32; /**< Alias to float for backward compatibility */
|
||||
typedef double float64; /**< Alias to double for backward compatibility */
|
||||
typedef int64_t int64; /**< Alias to int64_t for backward compatibility */
|
||||
typedef uint64_t uint64; /**< Alias to uint64_t for backward compatibility */
|
||||
/* Signed or unsigned depending on the compiler selection */
|
||||
typedef char char8; /**< Alias to char for backward compatibility */
|
||||
typedef volatile uint8_t reg8; /**< Alias to uint8_t for backward compatibility */
|
||||
typedef volatile uint16_t reg16; /**< Alias to uint16_t for backward compatibility */
|
||||
typedef volatile uint32_t reg32; /**< Alias to uint32_t for backward compatibility */
|
||||
|
||||
/** The ARM 32-bit Return error / status code for backward compatibility.
|
||||
* Do not use them in your code.
|
||||
*/
|
||||
#define CY_RET_SUCCESS (0x00U) /* Successful */
|
||||
#define CY_RET_BAD_PARAM (0x01U) /* One or more invalid parameters */
|
||||
#define CY_RET_INVALID_OBJECT (0x02U) /* An invalid object specified */
|
||||
#define CY_RET_MEMORY (0x03U) /* A memory-related failure */
|
||||
#define CY_RET_LOCKED (0x04U) /* A resource lock failure */
|
||||
#define CY_RET_EMPTY (0x05U) /* No more objects available */
|
||||
#define CY_RET_BAD_DATA (0x06U) /* Bad data received (CRC or other error check) */
|
||||
#define CY_RET_STARTED (0x07U) /* Operation started, but not necessarily completed yet */
|
||||
#define CY_RET_FINISHED (0x08U) /* Operation is completed */
|
||||
#define CY_RET_CANCELED (0x09U) /* Operation is canceled */
|
||||
#define CY_RET_TIMEOUT (0x10U) /* Operation timed out */
|
||||
#define CY_RET_INVALID_STATE (0x11U) /* Operation is not setup or is in an improper state */
|
||||
#define CY_RET_UNKNOWN ((cy_status) 0xFFFFFFFFU) /* Unknown failure */
|
||||
|
||||
/** ARM 32-bit Return error / status codes for backward compatibility with the UDB components.
|
||||
* Do not use them in your code.
|
||||
*/
|
||||
#define CYRET_SUCCESS (0x00U) /* Successful */
|
||||
#define CYRET_BAD_PARAM (0x01U) /* One or more invalid parameters */
|
||||
#define CYRET_INVALID_OBJECT (0x02U) /* An invalid object specified */
|
||||
#define CYRET_MEMORY (0x03U) /* A memory-related failure */
|
||||
#define CYRET_LOCKED (0x04U) /* A resource lock failure */
|
||||
#define CYRET_EMPTY (0x05U) /* No more objects available */
|
||||
#define CYRET_BAD_DATA (0x06U) /* Bad data received (CRC or other error check) */
|
||||
#define CYRET_STARTED (0x07U) /* Operation started, but not necessarily completed yet */
|
||||
#define CYRET_FINISHED (0x08U) /* Operation is completed */
|
||||
#define CYRET_CANCELED (0x09U) /* Operation is canceled */
|
||||
#define CYRET_TIMEOUT (0x10U) /* Operation timed out */
|
||||
#define CYRET_INVALID_STATE (0x11U) /* Operation is not setup or is in an improper state */
|
||||
#define CYRET_UNKNOWN ((cystatus) 0xFFFFFFFFU) /* Unknown failure */
|
||||
|
||||
/** \} group_syslib_functions */
|
||||
|
||||
#endif /* CY_SYSLIB_H */
|
||||
|
||||
/** \} group_syslib */
|
||||
|
||||
/* [] END OF FILE */
|
|
@ -0,0 +1,81 @@
|
|||
/***************************************************************************//**
|
||||
* \file cy_utils.h
|
||||
*
|
||||
* \brief
|
||||
* Basic utility macros and functions.
|
||||
*
|
||||
********************************************************************************
|
||||
* \copyright
|
||||
* Copyright 2018-2019 Cypress Semiconductor Corporation
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*******************************************************************************/
|
||||
|
||||
/**
|
||||
* \addtogroup group_utils Utilities
|
||||
* \ingroup group_abstraction
|
||||
* \{
|
||||
* Basic utility macros and functions.
|
||||
*
|
||||
* \defgroup group_utils_macros Macros
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \addtogroup group_utils_macros
|
||||
* \{
|
||||
*/
|
||||
|
||||
/** Simple macro to supress the unused parameter warning by casting to void. */
|
||||
#define CY_UNUSED_PARAMETER(x) ( (void)(x) )
|
||||
|
||||
/** Halt the processor in the debug state
|
||||
* @return
|
||||
*/
|
||||
static inline uint32_t CY_HALT()
|
||||
{
|
||||
__asm(" bkpt 1");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CY_ASSERT
|
||||
#undef CY_ASSERT
|
||||
#endif /* ifdef(CY_ASSERT) */
|
||||
|
||||
/** Utility macro when neither NDEBUG or CY_NO_ASSERT is not declared to check a condition and, if false, trigger a breakpoint */
|
||||
#if defined(NDEBUG) || defined(CY_NO_ASSERT)
|
||||
#define CY_ASSERT(x) CY_UNUSED_PARAMETER(x)
|
||||
#else
|
||||
#define CY_ASSERT(x) do { \
|
||||
if(!(x)) \
|
||||
{ \
|
||||
CY_HALT(); \
|
||||
} \
|
||||
} while(0)
|
||||
#endif /* defined(NDEBUG) */
|
||||
|
||||
/** \} group_utils_macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** \} group_utils */
|
|
@ -0,0 +1,50 @@
|
|||
/***************************************************************************//**
|
||||
* \file cybsp.h
|
||||
*
|
||||
* \brief
|
||||
* Basic API for setting up boards containing a Cypress MCU.
|
||||
*
|
||||
********************************************************************************
|
||||
* \copyright
|
||||
* Copyright 2018-2020 Cypress Semiconductor Corporation
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cy_result.h"
|
||||
#include "cyhal_sdio.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \addtogroup group_bsp_functions Functions
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Get the initialized sdio object used for communicating with the WiFi Chip.
|
||||
* \note This function should only be called after cybsp_init();
|
||||
* \returns The initialized sdio object.
|
||||
*/
|
||||
cyhal_sdio_t* cybsp_get_wifi_sdio_obj(void);
|
||||
|
||||
/** \} group_bsp_functions */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright 2020 Arduino SA
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** @file
|
||||
* Provides cyhal porting to generic mbed APIs
|
||||
*/
|
||||
#include "whd_config.h"
|
||||
#include "cyhal_hw_types.h"
|
||||
#include "cyhal_gpio.h"
|
||||
#include "cyhal_sdio.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CYBSP_WIFI_WL_REG_ON,
|
||||
CYBSP_WIFI_32K_CLK,
|
||||
CYBSP_LED1,
|
||||
CYBSP_LED2,
|
||||
CYBSP_WIFI_SDIO_CMD,
|
||||
CYBSP_WIFI_SDIO_CLK,
|
||||
CYBSP_WIFI_SDIO_D0,
|
||||
CYBSP_WIFI_SDIO_D1,
|
||||
CYBSP_WIFI_SDIO_D2,
|
||||
CYBSP_WIFI_SDIO_D3,
|
||||
CYBSP_SDIO_OOB_IRQ,
|
||||
CYBSP_WIFI_MAX,
|
||||
} wwd_sdio_pin_t;
|
||||
|
||||
void cyhal_system_delay_ms(uint32_t milliseconds);
|
||||
cy_rslt_t sdio_enable_high_speed(void);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Copyright 2020 Arduino SA
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** @file
|
||||
* Provides the porting layer for STM32 GPIOs on WHD driver
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "cyhal.h"
|
||||
#include "cybsp.h"
|
||||
#include "mbed.h"
|
||||
#include "wiced_filesystem.h"
|
||||
|
||||
extern pinconfig_t PinConfig[];
|
||||
|
||||
/*******************************************************************************
|
||||
* Internal
|
||||
*******************************************************************************/
|
||||
static mbed::InterruptIn *oob_irq;
|
||||
static cyhal_gpio_event_t oob_event = CYHAL_GPIO_IRQ_FALL;
|
||||
static cyhal_gpio_event_callback_t oob_handler;
|
||||
static void *oob_handler_arg;
|
||||
|
||||
/*******************************************************************************
|
||||
* Internal Interrrupt Service Routine
|
||||
*******************************************************************************/
|
||||
static void cb()
|
||||
{
|
||||
oob_handler(oob_handler_arg, oob_event);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* HAL Implementation
|
||||
*******************************************************************************/
|
||||
cy_rslt_t cyhal_gpio_init(cyhal_gpio_t pin, cyhal_gpio_direction_t direction, cyhal_gpio_drive_mode_t drvMode, bool initVal)
|
||||
{
|
||||
cy_rslt_t ret = CY_RSLT_SUCCESS;
|
||||
|
||||
// Workaround to enable GPIOJ clock
|
||||
if (pin == CYBSP_WIFI_WL_REG_ON) {
|
||||
__HAL_RCC_GPIOJ_CLK_ENABLE();
|
||||
// Ensure FS and BlockDevice are initialized on time if needed
|
||||
wiced_filesystem_init();
|
||||
}
|
||||
// Ignore the parameter and take the pin config directly from a static array defintions
|
||||
HAL_GPIO_Init(PinConfig[pin].port, &PinConfig[pin].config);
|
||||
if (direction == CYHAL_GPIO_DIR_OUTPUT) {
|
||||
HAL_GPIO_WritePin(PinConfig[pin].port, PinConfig[pin].config.Pin, (initVal) ? GPIO_PIN_SET : GPIO_PIN_RESET);
|
||||
}
|
||||
// Workaround to initialize sdio interface without cypress bsp init
|
||||
if (pin == CYBSP_WIFI_WL_REG_ON) {
|
||||
cyhal_sdio_t *sdio_p = cybsp_get_wifi_sdio_obj();
|
||||
ret = cyhal_sdio_init(sdio_p, CYBSP_WIFI_SDIO_CMD, CYBSP_WIFI_SDIO_CLK, CYBSP_WIFI_SDIO_D0, CYBSP_WIFI_SDIO_D1, CYBSP_WIFI_SDIO_D2, CYBSP_WIFI_SDIO_D3);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void cyhal_gpio_write(cyhal_gpio_t pin, bool value)
|
||||
{
|
||||
HAL_GPIO_WritePin(PinConfig[pin].port, PinConfig[pin].config.Pin, (value) ? GPIO_PIN_SET : GPIO_PIN_RESET);
|
||||
}
|
||||
|
||||
void cyhal_gpio_register_callback(cyhal_gpio_t pin, cyhal_gpio_event_callback_t handler, void *handler_arg)
|
||||
{
|
||||
if (handler && handler_arg && (oob_irq == NULL)) {
|
||||
oob_irq = new mbed::InterruptIn(PJ_5);
|
||||
oob_handler = handler;
|
||||
oob_handler_arg = handler_arg;
|
||||
}
|
||||
}
|
||||
|
||||
void cyhal_gpio_enable_event(cyhal_gpio_t pin, cyhal_gpio_event_t event, uint8_t intr_priority, bool enable)
|
||||
{
|
||||
oob_event = event;
|
||||
if (enable) {
|
||||
if (event == CYHAL_GPIO_IRQ_RISE) {
|
||||
oob_irq->rise(cb);
|
||||
}
|
||||
if (event == CYHAL_GPIO_IRQ_FALL) {
|
||||
oob_irq->fall(cb);
|
||||
}
|
||||
} else if (oob_irq != NULL) {
|
||||
delete oob_irq;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
/***************************************************************************//**
|
||||
* \file cyhal_hw_types_template.h
|
||||
*
|
||||
* \brief
|
||||
* Provides a template for configuration resources used by the HAL. Items
|
||||
* here need to be implemented for each HAL port. It is up to the environment
|
||||
* being ported into what the actual types are. There are some suggestions below
|
||||
* but these are not required. All that is required is that the type is defined;
|
||||
* it does not matter to the HAL what type is actually chosen for the
|
||||
* implementation
|
||||
* All TODOs and references to 'PORT' need to be replaced by with meaningful
|
||||
* values for the device being supported.
|
||||
*
|
||||
********************************************************************************
|
||||
* \copyright
|
||||
* Copyright 2018-2019 Cypress Semiconductor Corporation
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*******************************************************************************/
|
||||
|
||||
/**
|
||||
* \addtogroup group_hal_hw_types PORT Hardware Types
|
||||
* \ingroup group_hal_PORT
|
||||
* \{
|
||||
* Struct definitions for configuration resources in the PORT.
|
||||
*
|
||||
* \defgroup group_hal_hw_types_data_structures Data Structures
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <stdbool.h>
|
||||
#include "stm32h7xx_hal.h"
|
||||
#include "PinNames.h"
|
||||
|
||||
/*
|
||||
#include "TODO: Port specific header file"
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef CYHAL_ISR_PRIORITY_DEFAULT
|
||||
/** Priority that is applied by default to all drivers when initalized. Priorities can be
|
||||
* overridden on each driver as part of enabling events.
|
||||
*/
|
||||
#define CYHAL_ISR_PRIORITY_DEFAULT (7)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \addtogroup group_hal_hw_types_data_structures
|
||||
* \{
|
||||
*/
|
||||
|
||||
typedef int32_t cyhal_gpio_t;
|
||||
|
||||
/** GPIO object */
|
||||
typedef struct
|
||||
{
|
||||
GPIO_TypeDef *port;
|
||||
GPIO_InitTypeDef config;
|
||||
} pinconfig_t;
|
||||
|
||||
/** Clock divider object */
|
||||
typedef struct
|
||||
{
|
||||
/* TODO: replace with port specific items */
|
||||
void *div_type;
|
||||
} cyhal_clock_divider_t;
|
||||
|
||||
/** Clock object */
|
||||
typedef struct
|
||||
{
|
||||
//For backwards compatibility with cyhal_clock_divider_t only. Do not use going forward.
|
||||
int div_type; /*!< Deprecated */
|
||||
uint8_t div_num; /*!< Deprecated */
|
||||
//End BWC items
|
||||
int block;
|
||||
uint8_t channel;
|
||||
bool reserved;
|
||||
} cyhal_clock_t;
|
||||
|
||||
/** SDIO object */
|
||||
typedef void* *cyhal_sdio_t;
|
||||
|
||||
/** SPI object */
|
||||
typedef struct
|
||||
{
|
||||
/* TODO: replace with port specific items */
|
||||
void *empty;
|
||||
} cyhal_spi_t;
|
||||
|
||||
|
||||
#include "whd_debug.h"
|
||||
|
||||
#if defined(WPRINT_ENABLE_WHD_ERROR) || defined(WPRINT_ENABLE_WHD_INFO) || defined(WPRINT_ENABLE_WHD_DEBUG)
|
||||
/** \} group_hal_hw_types_data_structures */
|
||||
#define PRINTF(...) do { \
|
||||
(void) printf(__VA_ARGS__); \
|
||||
} while (0)
|
||||
#else
|
||||
#define PRINTF(...)
|
||||
#endif
|
||||
|
||||
#include "whd_config.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/** \} group_hal_hw_types */
|
|
@ -0,0 +1,483 @@
|
|||
/*
|
||||
* Copyright 2020 Cypress Semiconductor Corporation
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** @file
|
||||
* Provides the porting layer for STM32 SDIO on WHD driver
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "whd_thread.h"
|
||||
#include "bus_protocols/whd_bus_sdio_protocol.h"
|
||||
#include "cyabs_rtos.h"
|
||||
#include "cyhal_sdio.h"
|
||||
|
||||
#define SDIO_RESPONSE_SHORT SDMMC_RESPONSE_SHORT
|
||||
#define SDIO_WAIT_NO SDMMC_WAIT_NO
|
||||
#define SDIO_CPSM_ENABLE SDMMC_CPSM_ENABLE
|
||||
#define SDIO_CMDTRANS SDMMC_CMD_CMDTRANS
|
||||
#define SDIO_FLAG_CMDACT (SDMMC_STA_CPSMACT | SDMMC_STA_DPSMACT)
|
||||
#define SDIO_TRANSFER_DIR_TO_SDIO SDMMC_TRANSFER_DIR_TO_SDMMC
|
||||
#define SDIO_TRANSFER_DIR_TO_CARD SDMMC_TRANSFER_DIR_TO_CARD
|
||||
#define SDIO_TRANSFER_MODE_BLOCK SDMMC_TRANSFER_MODE_BLOCK
|
||||
#define SDIO_DPSM_ENABLE SDMMC_DPSM_ENABLE
|
||||
#define SDIO_DPSM_DISABLE SDMMC_DPSM_DISABLE
|
||||
#define SDIO_DCTRL_SDIOEN SDMMC_DCTRL_SDIOEN /* 1 << 11 */
|
||||
#define SDIO_DCTRL_DTMODE_1 SDMMC_DCTRL_DTMODE_1 /* 1<<3 */
|
||||
#define SDIO_STA_DTIMEOUT SDMMC_STA_DTIMEOUT
|
||||
#define SDIO_STA_CTIMEOUT SDMMC_STA_CTIMEOUT
|
||||
#define SDIO_STA_CCRCFAIL SDMMC_STA_CCRCFAIL
|
||||
#define SDIO_STA_DCRCFAIL SDMMC_STA_DCRCFAIL
|
||||
#define SDIO_STA_TXUNDERR SDMMC_STA_TXUNDERR
|
||||
#define SDIO_STA_RXOVERR SDMMC_STA_RXOVERR
|
||||
#define SDIO_STA_TXACT SDMMC_STA_CPSMACT
|
||||
#define SDIO_STA_RXACT SDMMC_STA_DPSMACT
|
||||
#define SDIO_STA_CMDREND SDMMC_STA_CMDREND
|
||||
#define SDIO_STA_CMDSENT SDMMC_STA_CMDSENT
|
||||
#define SDIO_CMD_CMDTRANS SDMMC_CMD_CMDTRANS
|
||||
#define SDIO SDMMC1
|
||||
|
||||
#define COMMAND_FINISHED_CMD52_TIMEOUT_LOOPS (100000)
|
||||
#define BUS_LEVEL_MAX_RETRIES 10
|
||||
|
||||
#define SDIO_CMD_5 5
|
||||
#define SDIO_CMD_53 53
|
||||
|
||||
#define SDIO_STA_STBITERR ((uint32_t)0x00000200) /*!<Start bit not detected on all data signals in wide bus mode */
|
||||
#define SDIO_ERROR_MASK ( SDMMC_STA_CCRCFAIL | SDMMC_STA_DCRCFAIL | SDMMC_STA_CTIMEOUT | SDMMC_STA_DTIMEOUT | SDMMC_STA_TXUNDERR | SDMMC_STA_RXOVERR )
|
||||
|
||||
#define LINK_MTU 1024
|
||||
#define MAX(a,b) (a>b)?a:b
|
||||
|
||||
extern pinconfig_t PinConfig[];
|
||||
extern SD_HandleTypeDef hsd;
|
||||
|
||||
/* for debug prints only */
|
||||
//static int num = 0;
|
||||
|
||||
static uint32_t dctrl;
|
||||
|
||||
static whd_driver_t whd_handler;
|
||||
static cyhal_sdio_irq_handler_t sdio_irq_handler;
|
||||
|
||||
static uint8_t temp_dma_buffer[2048] __attribute__((aligned(8)));
|
||||
static uint8_t *user_data;
|
||||
static uint32_t user_data_size;
|
||||
static uint8_t *dma_data_source;
|
||||
static uint32_t dma_transfer_size;
|
||||
static cyhal_transfer_t current_transfer_direction;
|
||||
|
||||
static cy_semaphore_t sdio_transfer_finished_semaphore;
|
||||
static volatile uint32_t sdio_transfer_failed = 0;
|
||||
static volatile uint32_t irqstatus = 0;
|
||||
static int current_command = 0;
|
||||
|
||||
static cy_rslt_t sdio_enable_high_speed(void)
|
||||
{
|
||||
SDMMC_InitTypeDef sdio_init_structure;
|
||||
|
||||
sdio_init_structure.ClockDiv = SDMMC_HSpeed_CLK_DIV;
|
||||
sdio_init_structure.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
|
||||
sdio_init_structure.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
|
||||
sdio_init_structure.BusWide = SDMMC_BUS_WIDE_4B;
|
||||
sdio_init_structure.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_ENABLE;
|
||||
|
||||
SDMMC_Init(SDMMC1, sdio_init_structure);
|
||||
return CY_RSLT_SUCCESS;
|
||||
}
|
||||
|
||||
static uint32_t find_optimal_block_size(uint32_t data_size)
|
||||
{
|
||||
if (data_size > (uint32_t) 256) {
|
||||
return 512;
|
||||
}
|
||||
if (data_size > (uint32_t) 128) {
|
||||
return 256;
|
||||
}
|
||||
if (data_size > (uint32_t) 64) {
|
||||
return 128;
|
||||
}
|
||||
if (data_size > (uint32_t) 32) {
|
||||
return 64;
|
||||
}
|
||||
if (data_size > (uint32_t) 16) {
|
||||
return 32;
|
||||
}
|
||||
if (data_size > (uint32_t) 8) {
|
||||
return 16;
|
||||
}
|
||||
if (data_size > (uint32_t) 4) {
|
||||
return 8;
|
||||
}
|
||||
if (data_size > (uint32_t) 2) {
|
||||
return 4;
|
||||
}
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
static uint32_t sdio_get_blocksize(uint32_t blocksize)
|
||||
{
|
||||
uint32_t n = 0;
|
||||
blocksize >>= 1;
|
||||
while (blocksize) {
|
||||
n++;
|
||||
blocksize >>= 1;
|
||||
}
|
||||
n <<= 4;
|
||||
return n;
|
||||
}
|
||||
|
||||
static void sdio_prepare_data_transfer(cyhal_transfer_t direction, uint32_t block_size, uint8_t *data, uint16_t data_size)
|
||||
{
|
||||
/* Setup a single transfer using the temp buffer */
|
||||
user_data = data;
|
||||
user_data_size = data_size;
|
||||
dma_transfer_size = (uint32_t)(((data_size + (uint16_t) block_size - 1) / (uint16_t) block_size) * (uint16_t) block_size);
|
||||
|
||||
if (direction == CYHAL_WRITE) {
|
||||
|
||||
#if !(defined(DUAL_CORE) && defined(CORE_CM4))
|
||||
SCB_CleanDCache_by_Addr((uint32_t *)dma_data_source, data_size + 32);
|
||||
#endif
|
||||
memcpy(temp_dma_buffer, data, data_size);
|
||||
dma_data_source = temp_dma_buffer;
|
||||
} else {
|
||||
dma_data_source = (uint8_t *)temp_dma_buffer;
|
||||
//VIKR
|
||||
//memset(dma_data_source,0x12,data_size);
|
||||
|
||||
#if !(defined(DUAL_CORE) && defined(CORE_CM4))
|
||||
/* Cache-Invalidate the output from DMA */
|
||||
SCB_CleanDCache_by_Addr((uint32_t *)dma_data_source, data_size + 32);
|
||||
#endif
|
||||
}
|
||||
|
||||
SDIO->DTIMER = (uint32_t) 0xFFFFFFFF;
|
||||
SDIO->DLEN = dma_transfer_size;
|
||||
dctrl = sdio_get_blocksize(block_size) | ((direction == CYHAL_READ) ? SDIO_TRANSFER_DIR_TO_SDIO : SDIO_TRANSFER_DIR_TO_CARD) | SDIO_TRANSFER_MODE_BLOCK | SDIO_DPSM_DISABLE | SDIO_DCTRL_SDIOEN;
|
||||
SDIO->DCTRL = dctrl;
|
||||
|
||||
SDMMC1->IDMACTRL = SDMMC_ENABLE_IDMA_SINGLE_BUFF;
|
||||
SDMMC1->IDMABASE0 = (uint32_t) dma_data_source;
|
||||
}
|
||||
|
||||
static void sdio_enable_bus_irq(void)
|
||||
{
|
||||
SDMMC1->MASK = SDMMC_IT_RXOVERR | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND | SDMMC_IT_CMDREND | SDMMC_IT_CMDSENT;
|
||||
}
|
||||
|
||||
void SDMMC1_IRQHandler(void)
|
||||
{
|
||||
uint32_t intstatus = SDIO->STA;
|
||||
|
||||
irqstatus = intstatus;
|
||||
//VIKR | SDIO_STA_STBITERR )
|
||||
if ((intstatus & (SDIO_STA_CCRCFAIL | SDIO_STA_DCRCFAIL | SDIO_STA_TXUNDERR | SDIO_STA_RXOVERR)) != 0) {
|
||||
WPRINT_WHD_DEBUG(("sdio error flagged\n"));
|
||||
sdio_transfer_failed = intstatus;
|
||||
SDIO->ICR = (uint32_t) 0xffffffff;
|
||||
cy_rtos_set_semaphore(&sdio_transfer_finished_semaphore, WHD_TRUE);
|
||||
} else {
|
||||
if ((intstatus & (SDMMC_STA_CMDREND | SDMMC_STA_CMDSENT)) != 0) {
|
||||
if ((SDMMC1->RESP1 & 0x800) != 0) {
|
||||
sdio_transfer_failed = irqstatus;
|
||||
cy_rtos_set_semaphore(&sdio_transfer_finished_semaphore, WHD_TRUE);
|
||||
}
|
||||
|
||||
/* Clear all command/response interrupts */
|
||||
SDMMC1->ICR = (SDMMC_STA_CMDREND | SDMMC_STA_CMDSENT);
|
||||
}
|
||||
|
||||
/* Check whether the external interrupt was triggered */
|
||||
if (intstatus & SDMMC_STA_SDIOIT) {
|
||||
/* Clear the interrupt */
|
||||
SDMMC1->ICR = SDMMC_STA_SDIOIT;
|
||||
/* Inform WICED WWD thread */
|
||||
sdio_irq_handler(whd_handler, CYHAL_SDIO_CARD_INTERRUPT);
|
||||
}
|
||||
|
||||
if (intstatus & SDMMC_STA_DATAEND) {
|
||||
SDMMC1->ICR = SDMMC_STA_DATAEND;
|
||||
SDMMC1->DLEN = 0;
|
||||
SDMMC1->DCTRL = SDMMC_DCTRL_SDIOEN;
|
||||
SDMMC1->IDMACTRL = SDMMC_DISABLE_IDMA;
|
||||
SDMMC1->CMD = 0;
|
||||
cy_rtos_set_semaphore(&sdio_transfer_finished_semaphore, WHD_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//void sdio_dma_irq(void)
|
||||
//{
|
||||
// /* Clear interrupt */
|
||||
// DMA2->LIFCR = (uint32_t)(0x3F << 22);
|
||||
// cy_rtos_set_semaphore(&sdio_transfer_finished_semaphore, WHD_TRUE);
|
||||
//}
|
||||
|
||||
cy_rslt_t cyhal_sdio_init(cyhal_sdio_t *obj, cyhal_gpio_t cmd, cyhal_gpio_t clk, cyhal_gpio_t data0, cyhal_gpio_t data1, cyhal_gpio_t data2, cyhal_gpio_t data3)
|
||||
{
|
||||
cy_rslt_t ret = CY_RSLT_SUCCESS;
|
||||
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||
__HAL_RCC_SDMMC1_CLK_ENABLE();
|
||||
|
||||
HAL_GPIO_Init(PinConfig[cmd].port, &PinConfig[cmd].config);
|
||||
HAL_GPIO_Init(PinConfig[clk].port, &PinConfig[clk].config);
|
||||
HAL_GPIO_Init(PinConfig[data0].port, &PinConfig[data0].config);
|
||||
HAL_GPIO_Init(PinConfig[data1].port, &PinConfig[data1].config);
|
||||
HAL_GPIO_Init(PinConfig[data2].port, &PinConfig[data2].config);
|
||||
HAL_GPIO_Init(PinConfig[data3].port, &PinConfig[data3].config);
|
||||
|
||||
/* Reset SDIO Block */
|
||||
SDMMC_PowerState_OFF(SDMMC1);
|
||||
__HAL_RCC_SDMMC1_FORCE_RESET();
|
||||
__HAL_RCC_SDMMC1_RELEASE_RESET();
|
||||
|
||||
/* Enable the SDIO Clock */
|
||||
__HAL_RCC_SDMMC1_CLK_ENABLE();
|
||||
|
||||
#if !(defined(DUAL_CORE) && defined(CORE_CM4))
|
||||
/* Disable DCache for STM32H7 family */
|
||||
SCB_CleanDCache();
|
||||
SCB_DisableDCache();
|
||||
#endif
|
||||
|
||||
WPRINT_WHD_DEBUG(("in init: %p\n", sdio_transfer_finished_semaphore));
|
||||
|
||||
// Lower speed configuration
|
||||
SDMMC_InitTypeDef sdio_init_structure;
|
||||
|
||||
sdio_init_structure.ClockDiv = SDMMC_INIT_CLK_DIV;
|
||||
sdio_init_structure.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
|
||||
sdio_init_structure.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
|
||||
sdio_init_structure.BusWide = SDMMC_BUS_WIDE_1B;
|
||||
sdio_init_structure.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
|
||||
ret = SDMMC_Init(SDMMC1, sdio_init_structure);
|
||||
ret |= SDMMC_PowerState_ON(SDMMC1);
|
||||
ret |= SDMMC_SetSDMMCReadWaitMode(SDMMC1, SDMMC_READ_WAIT_MODE_CLK);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Clear all SDIO interrupts */
|
||||
SDMMC1->ICR = (uint32_t) 0xffffffff;
|
||||
|
||||
/* Turn on SDIO IRQ */
|
||||
/* Must be lower priority than the value of configMAX_SYSCALL_INTERRUPT_PRIORITY */
|
||||
/* otherwise FreeRTOS will not be able to mask the interrupt */
|
||||
/* keep in mind that ARMCM7 interrupt priority logic is inverted, the highest value */
|
||||
/* is the lowest priority */
|
||||
HAL_NVIC_EnableIRQ((IRQn_Type) SDMMC1_IRQn);
|
||||
HAL_NVIC_SetPriority(SDMMC1_IRQn, 5, 0);
|
||||
|
||||
WPRINT_WHD_DEBUG(("after enable sdio: %p\n", sdio_transfer_finished_semaphore));
|
||||
|
||||
if (cy_rtos_init_semaphore(&sdio_transfer_finished_semaphore, 1, 0) != WHD_SUCCESS) {
|
||||
cy_rtos_deinit_semaphore(&sdio_transfer_finished_semaphore);
|
||||
return -1;
|
||||
}
|
||||
|
||||
WPRINT_WHD_DEBUG(("cy_rtos_init_semaphore: %p\n", sdio_transfer_finished_semaphore));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void cyhal_sdio_free(cyhal_sdio_t *obj)
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
|
||||
cy_rslt_t cyhal_sdio_configure(cyhal_sdio_t *obj, const cyhal_sdio_cfg_t *config)
|
||||
{
|
||||
return sdio_enable_high_speed();
|
||||
}
|
||||
|
||||
cy_rslt_t cyhal_sdio_send_cmd(const cyhal_sdio_t *obj, cyhal_transfer_t direction, cyhal_sdio_command_t command, uint32_t argument, uint32_t *response)
|
||||
{
|
||||
uint32_t loop_count = 0;
|
||||
cy_rslt_t result;
|
||||
uint16_t attempts = 0;
|
||||
uint32_t temp_sta;
|
||||
|
||||
if (response != NULL) {
|
||||
*response = 0;
|
||||
}
|
||||
current_command = 0;
|
||||
|
||||
restart:
|
||||
SDIO->ICR = (uint32_t) 0xFFFFFFFF;
|
||||
++attempts;
|
||||
|
||||
/* Check if we've tried too many times */
|
||||
if (attempts >= (uint16_t) BUS_LEVEL_MAX_RETRIES) {
|
||||
/* WWD_SDIO_RETRIES_EXCEEDED */
|
||||
result = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Send the command */
|
||||
SDIO->ARG = argument;
|
||||
SDIO->CMD = (uint32_t)(command | SDIO_RESPONSE_SHORT | SDIO_WAIT_NO | SDIO_CPSM_ENABLE);
|
||||
loop_count = (uint32_t) COMMAND_FINISHED_CMD52_TIMEOUT_LOOPS;
|
||||
do {
|
||||
temp_sta = SDIO->STA;
|
||||
loop_count--;
|
||||
if (loop_count == 0 || ((response != NULL) && ((temp_sta & SDIO_ERROR_MASK) != 0))) {
|
||||
WPRINT_WHD_DEBUG(("Restart single access loop count %ld stat %lx\n", loop_count, temp_sta));
|
||||
HAL_Delay(10U);
|
||||
goto restart;
|
||||
}
|
||||
} while ((temp_sta & SDIO_FLAG_CMDACT) != 0);
|
||||
|
||||
if (response != NULL) {
|
||||
*response = SDIO->RESP1;
|
||||
}
|
||||
result = CY_RSLT_SUCCESS;
|
||||
|
||||
exit:
|
||||
if (result) {
|
||||
WPRINT_WHD_ERROR(("SDIO->POWER %lx \n", SDIO->POWER));
|
||||
WPRINT_WHD_ERROR(("SDIO->CLKCR %lx \n", SDIO->CLKCR));
|
||||
WPRINT_WHD_ERROR(("result %lx \n", result));
|
||||
WPRINT_WHD_ERROR(("cyhal_sdio_send_cmd %s\n", (result == 0) ? "Passed" : "Failed"));
|
||||
while (1);
|
||||
}
|
||||
SDMMC1->CMD = 0;
|
||||
|
||||
//WPRINT_WHD_DEBUG(("%d %s cmd 0x%x arg 0x%x resp 0x%x\n",num++,(direction!=CYHAL_READ)?"Write":"Read",command,argument,(response)?*response:0));
|
||||
return result;
|
||||
}
|
||||
|
||||
cy_rslt_t cyhal_sdio_bulk_transfer(cyhal_sdio_t *obj, cyhal_transfer_t direction, uint32_t argument, const uint32_t *data, uint16_t length, uint32_t *response)
|
||||
{
|
||||
cy_rslt_t result;
|
||||
uint16_t attempts = 0;
|
||||
uint32_t block_size = 64;
|
||||
sdio_cmd_argument_t arg;
|
||||
uint32_t cmd;
|
||||
current_command = SDIO_CMD_53;
|
||||
current_transfer_direction = direction;
|
||||
arg.value = argument;
|
||||
|
||||
sdio_enable_bus_irq();
|
||||
if (response != NULL) {
|
||||
*response = 0;
|
||||
}
|
||||
|
||||
restart:
|
||||
sdio_transfer_failed = 0;
|
||||
SDMMC1->ICR = (uint32_t) 0xFFFFFFFF;
|
||||
++attempts;
|
||||
|
||||
/* Check if we've tried too many times */
|
||||
if (attempts >= (uint16_t) BUS_LEVEL_MAX_RETRIES) {
|
||||
/* WWD_SDIO_RETRIES_EXCEEDED */
|
||||
WPRINT_WHD_ERROR(("Too much attempt\n"));
|
||||
result = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Dodgy STM32 hack to set the CMD53 byte mode size to be the same as the block size */
|
||||
if (arg.cmd53.block_mode == 0) {
|
||||
block_size = find_optimal_block_size(arg.cmd53.count);
|
||||
if (block_size < SDIO_512B_BLOCK) {
|
||||
arg.cmd53.count = block_size;
|
||||
} else {
|
||||
arg.cmd53.count = 0;
|
||||
}
|
||||
argument = arg.value;
|
||||
}
|
||||
|
||||
SDMMC1->CMD |= SDMMC_CMD_CMDTRANS;
|
||||
|
||||
/* Prepare the SDIO for a data transfer */
|
||||
sdio_prepare_data_transfer(direction, block_size, (uint8_t *) data, (uint32_t) length);
|
||||
|
||||
/* Send the command */
|
||||
//WPRINT_WHD_DEBUG(("%d bs=%d argument=%x\n",num++,block_size,argument));
|
||||
SDMMC1->ARG = argument;
|
||||
cmd = (uint32_t)(SDIO_CMD_53 | SDMMC_RESPONSE_SHORT | SDMMC_WAIT_NO | SDMMC_CPSM_ENABLE | SDMMC_CMD_CMDTRANS);
|
||||
SDMMC1->CMD = cmd;
|
||||
|
||||
/* Wait for the whole transfer to complete */
|
||||
//WPRINT_WHD_DEBUG(("cy_rtos_get_semaphore: %d\n", sdio_transfer_finished_semaphore));
|
||||
result = cy_rtos_get_semaphore(&sdio_transfer_finished_semaphore, 50, WHD_FALSE);
|
||||
|
||||
if (result != CY_RSLT_SUCCESS) {
|
||||
WPRINT_WHD_ERROR(("failed getting semaphore\n"));
|
||||
goto exit;
|
||||
}
|
||||
if (sdio_transfer_failed) {
|
||||
WPRINT_WHD_DEBUG(("try again sdio_transfer_failed %"PRIu32" irq %"PRIu32"\n", sdio_transfer_failed, irqstatus));
|
||||
goto restart;
|
||||
}
|
||||
/* Check if there were any SDIO errors */
|
||||
if ((SDIO->STA & (SDIO_STA_DTIMEOUT | SDIO_STA_CTIMEOUT)) != 0) {
|
||||
WPRINT_WHD_DEBUG(("sdio errors SDIO_STA_DTIMEOUT | SDIO_STA_CTIMEOUT\n"));
|
||||
goto restart;
|
||||
} else if (((SDIO->STA & (SDIO_STA_CCRCFAIL | SDIO_STA_DCRCFAIL | SDIO_STA_TXUNDERR | SDIO_STA_RXOVERR)) != 0)) {
|
||||
WPRINT_WHD_DEBUG(("sdio errors SDIO_STA_CCRCFAIL | SDIO_STA_DCRCFAIL | SDIO_STA_TXUNDERR | SDIO_STA_RXOVER \n"));
|
||||
goto restart;
|
||||
}
|
||||
|
||||
if (direction == CYHAL_READ) {
|
||||
memcpy(user_data, dma_data_source, (size_t) user_data_size);
|
||||
}
|
||||
|
||||
if (response != NULL) {
|
||||
*response = SDIO->RESP1;
|
||||
}
|
||||
result = CY_RSLT_SUCCESS;
|
||||
|
||||
exit:
|
||||
SDMMC1->CMD = 0;
|
||||
|
||||
//WPRINT_WHD_DEBUG(("%d %s cmd 53 argument %lx datasize %d blocknumber 0x%x cmdis %lx %lu dctrl = %x\n", num++, (direction != CYHAL_READ) ? "Write" : "Read", argument, length, arg.cmd53.count, cmd, cmd, dctrl));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
cy_rslt_t cyhal_sdio_transfer_async(cyhal_sdio_t *obj, cyhal_transfer_t direction, uint32_t argument, const uint32_t *data, uint16_t length)
|
||||
{
|
||||
//TODO
|
||||
return CYHAL_SDIO_RET_NO_SP_ERRORS;
|
||||
}
|
||||
|
||||
bool cyhal_sdio_is_busy(const cyhal_sdio_t *obj)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
cy_rslt_t cyhal_sdio_abort_async(const cyhal_sdio_t *obj)
|
||||
{
|
||||
//TODO
|
||||
return CYHAL_SDIO_RET_NO_SP_ERRORS;
|
||||
}
|
||||
|
||||
void cyhal_sdio_register_callback(cyhal_sdio_t *obj, cyhal_sdio_irq_handler_t handler, void *handler_arg)
|
||||
{
|
||||
whd_handler = (whd_driver_t)handler_arg;
|
||||
sdio_irq_handler = handler;
|
||||
}
|
||||
|
||||
void cyhal_sdio_enable_event(cyhal_sdio_t *obj, cyhal_sdio_irq_event_t event, uint8_t intr_priority, bool enable)
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
|
|
@ -0,0 +1,211 @@
|
|||
/*
|
||||
* Copyright 2020 Arduino SA
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** @file
|
||||
* Provides wiced fs porting to generic mbed APIs
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "sockets.h"
|
||||
#include "resources.h"
|
||||
#include "wiced_filesystem.h"
|
||||
#include "QSPIFBlockDevice.h"
|
||||
#include "MBRBlockDevice.h"
|
||||
#include "FATFileSystem.h"
|
||||
|
||||
#define WIFI_DEFAULT_FIRMWARE_PATH "/wlan/4343WA1.BIN"
|
||||
#define WIFI_DEFAULT_MOUNT_NAME "wlan"
|
||||
#define WIFI_DEFAULT_PARTITION 1
|
||||
#define WIFI_DEFAULT_FS 0
|
||||
|
||||
QSPIFBlockDevice *qspi_bd = NULL;
|
||||
MBRBlockDevice *mbr_bd = NULL;
|
||||
FATFileSystem *wifi_fs = NULL;
|
||||
|
||||
MBED_WEAK void wiced_filesystem_mount_error(void)
|
||||
{
|
||||
WPRINT_WHD_ERROR(("Failed to mount the filesystem containing the WiFi firmware.\n\r"));
|
||||
whd_print_logbuffer();
|
||||
while (1) {}
|
||||
}
|
||||
|
||||
MBED_WEAK void wiced_filesystem_firmware_error(void)
|
||||
{
|
||||
WPRINT_WHD_ERROR(("Please run the \"PortentaWiFiFirmwareUpdater\" sketch once to install the WiFi firmware.\n\r"));
|
||||
whd_print_logbuffer();
|
||||
while (1) {}
|
||||
}
|
||||
|
||||
MBED_WEAK wiced_result_t whd_firmware_check_hook(const char *mounted_name, int mount_err)
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *ent;
|
||||
std::string dir_name(mounted_name);
|
||||
if (mount_err) {
|
||||
wiced_filesystem_mount_error();
|
||||
} else {
|
||||
if ((dir = opendir(mounted_name)) != NULL) {
|
||||
// print all the files and directories within directory
|
||||
while ((ent = readdir(dir)) != NULL) {
|
||||
std::string fullname = "/" + dir_name + "/" + std::string(ent->d_name);
|
||||
if (fullname == WIFI_DEFAULT_FIRMWARE_PATH) {
|
||||
closedir(dir);
|
||||
return WICED_SUCCESS;
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
||||
wiced_filesystem_firmware_error();
|
||||
}
|
||||
return WICED_ERROR;
|
||||
}
|
||||
|
||||
static wiced_result_t whd_default_firmware_restore(void)
|
||||
{
|
||||
#if MBED_CONF_APP_WIFI_FIRMWARE_RESTORE
|
||||
size_t ret;
|
||||
FILE *fp;
|
||||
|
||||
//This should only happen the firs time or if the partition table has been overwritten i.e QSPI tests
|
||||
WPRINT_WHD_DEBUG(("MBRBlockDevice init failed, repatitioning\n\r"));
|
||||
if (mbr_bd->partition(qspi_bd, 1, 0x0B, 0, 1024 * 1024) != BD_ERROR_OK) {
|
||||
return WICED_ERROR;
|
||||
}
|
||||
WPRINT_WHD_DEBUG(("MBRBockDevice repatitioning OK, reinit\n\r"));
|
||||
|
||||
if (mbr_bd->init() != BD_ERROR_OK) {
|
||||
return WICED_ERROR;
|
||||
}
|
||||
WPRINT_WHD_DEBUG(("MBRBockDevice init OK\n\r"));
|
||||
|
||||
wifi_fs = new FATFileSystem(WIFI_DEFAULT_MOUNT_NAME);
|
||||
|
||||
if (wifi_fs->reformat(mbr_bd) != 0) {
|
||||
return WICED_ERROR;
|
||||
}
|
||||
WPRINT_WHD_DEBUG(("FATFileSystem reformat and mount OK\n\r"));
|
||||
|
||||
fp = fopen(WIFI_DEFAULT_FIRMWARE_PATH, "wb");
|
||||
if (fp == NULL) {
|
||||
return WICED_ERROR;
|
||||
}
|
||||
ret = fwrite(wifi_firmware_image_data, wifi_firmware_image.size, 1, fp);
|
||||
if (ret != wifi_firmware_image.size) {
|
||||
return WICED_ERROR;
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
if (mbr_bd->sync() != 0) {
|
||||
return WICED_ERROR;
|
||||
}
|
||||
WPRINT_WHD_DEBUG(("Sync BlockDevice OK\n\r"));
|
||||
|
||||
if (wifi_fs->unmount() != 0) {
|
||||
return WICED_ERROR;
|
||||
}
|
||||
WPRINT_WHD_DEBUG(("Unmount FS\n\r"));
|
||||
wifi_fs = NULL;
|
||||
#endif
|
||||
|
||||
return WICED_SUCCESS;
|
||||
}
|
||||
|
||||
wiced_result_t wiced_filesystem_init(void)
|
||||
{
|
||||
if (mbr_bd == NULL && wifi_fs == NULL) {
|
||||
WPRINT_WHD_DEBUG(("Initialize FileSystem with Mbed default settings\n\r"));
|
||||
qspi_bd = new QSPIFBlockDevice(PD_11, PD_12, PF_7, PD_13, PF_10, PG_6, QSPIF_POLARITY_MODE_1, 40000000);
|
||||
|
||||
if (qspi_bd->init() == BD_ERROR_OK) {
|
||||
mbr_bd = new MBRBlockDevice(qspi_bd, WIFI_DEFAULT_PARTITION);
|
||||
if (mbr_bd->init() == BD_ERROR_OK) {
|
||||
return WICED_SUCCESS;
|
||||
} else {
|
||||
return whd_default_firmware_restore();
|
||||
}
|
||||
}
|
||||
return WICED_ERROR;
|
||||
} else {
|
||||
WPRINT_WHD_DEBUG(("FileSystem initialized with user settings\n\r"));
|
||||
return WICED_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
wiced_result_t wiced_filesystem_mount(BlockDevice *device, wiced_filesystem_handle_type_t fs_type, wiced_filesystem_t *fs_handle_out, const char *mounted_name)
|
||||
{
|
||||
wifi_fs = new FATFileSystem(mounted_name);
|
||||
|
||||
int err = wifi_fs->mount(device);
|
||||
whd_firmware_check_hook(mounted_name, err);
|
||||
if (!err) {
|
||||
//fs_handle_out = wifi_fs
|
||||
return WICED_SUCCESS;
|
||||
}
|
||||
return WICED_ERROR;
|
||||
}
|
||||
|
||||
wiced_result_t wiced_filesystem_file_open(wiced_filesystem_t *fs_handle, wiced_file_t *file_handle_out, const char *filename, wiced_filesystem_open_mode_t mode)
|
||||
{
|
||||
/* This is called by mbed test system */
|
||||
//if (mbr_bd == NULL && wifi_fs == NULL) {
|
||||
// wiced_filesystem_init();
|
||||
//}
|
||||
//This can be called from user sketch to provide custom block device and mount point before WiFi.beginAP or WiFi.begin
|
||||
if (wifi_fs == NULL) {
|
||||
wiced_filesystem_mount(mbr_bd, WIFI_DEFAULT_FS, fs_handle, WIFI_DEFAULT_MOUNT_NAME);
|
||||
}
|
||||
|
||||
if (wifi_fs == NULL) {
|
||||
return WICED_ERROR;
|
||||
}
|
||||
|
||||
*file_handle_out = open(filename, mode);
|
||||
if (*file_handle_out == -1) {
|
||||
return WICED_ERROR;
|
||||
}
|
||||
return WICED_SUCCESS;
|
||||
}
|
||||
|
||||
wiced_result_t wiced_filesystem_file_seek(wiced_file_t *file_handle, int64_t offset, wiced_filesystem_seek_type_t whence)
|
||||
{
|
||||
if (*file_handle == -1) {
|
||||
return WICED_ERROR;
|
||||
}
|
||||
lseek(*file_handle, offset, whence);
|
||||
return WICED_SUCCESS;
|
||||
}
|
||||
|
||||
wiced_result_t wiced_filesystem_file_read(wiced_file_t *file_handle, void *data, uint64_t bytes_to_read, uint64_t *returned_bytes_count)
|
||||
{
|
||||
if (*file_handle == -1) {
|
||||
return WICED_ERROR;
|
||||
}
|
||||
*returned_bytes_count = read(*file_handle, data, bytes_to_read);
|
||||
return WICED_SUCCESS;
|
||||
}
|
||||
|
||||
wiced_result_t wiced_filesystem_file_close(wiced_file_t *file_handle)
|
||||
{
|
||||
if (*file_handle == -1) {
|
||||
return WICED_ERROR;
|
||||
}
|
||||
close(*file_handle);
|
||||
return WICED_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* Copyright 2020 Arduino SA
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** @file
|
||||
* Provides wiced fs porting to generic mbed APIs
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "whd_config.h"
|
||||
#include "BlockDevice.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
|
||||
typedef enum {
|
||||
WICED_FILESYSTEM_OPEN_FOR_READ, /** Specifies read access to the object. Data can be read from the file - equivalent to "r" or "rb" */
|
||||
WICED_FILESYSTEM_OPEN_FOR_WRITE, /** Specifies read/write access to the object. Data can be written to the file - equivalent to "r+" or "rb+" or "r+b" */
|
||||
WICED_FILESYSTEM_OPEN_WRITE_CREATE, /** Opens for read/write access, creates it if it doesn't exist */
|
||||
WICED_FILESYSTEM_OPEN_ZERO_LENGTH, /** Opens for read/write access, Truncates file to zero length if it exists, or creates it if it doesn't - equivalent to "w+", "wb+" or "w+b" */
|
||||
WICED_FILESYSTEM_OPEN_APPEND, /** Opens for read/write access, places the current location at the end of the file ready for appending - equivalent to "a", "ab" */
|
||||
WICED_FILESYSTEM_OPEN_APPEND_CREATE, /** Opens for read/write access, creates it if it doesn't exist, and places the current location at the end of the file ready for appending - equivalent to "a+", "ab+" or "a+b" */
|
||||
} wiced_filesystem_open_mode_t;
|
||||
|
||||
typedef enum {
|
||||
WICED_FILESYSTEM_SEEK_SET = SEEK_SET, /* Offset from start of file */
|
||||
WICED_FILESYSTEM_SEEK_CUR = SEEK_CUR, /* Offset from current position in file */
|
||||
WICED_FILESYSTEM_SEEK_END = SEEK_END, /* Offset from end of file */
|
||||
} wiced_filesystem_seek_type_t;
|
||||
|
||||
typedef enum {
|
||||
WICED_SUCCESS = 0,
|
||||
WICED_ERROR = 1
|
||||
} wiced_result_t;
|
||||
|
||||
/******************************************************
|
||||
* Type Definitions
|
||||
******************************************************/
|
||||
|
||||
/**
|
||||
* File-system Handle Structure
|
||||
*/
|
||||
typedef int wiced_filesystem_t;
|
||||
|
||||
/**
|
||||
* File Handle Structure
|
||||
*
|
||||
*/
|
||||
typedef int wiced_file_t;
|
||||
|
||||
/**
|
||||
* File-system type Handle Structure
|
||||
*/
|
||||
typedef int wiced_filesystem_handle_type_t;
|
||||
|
||||
/**
|
||||
* Initialise the BlockDevice and filesystem module
|
||||
*
|
||||
* Initialises the BlockDevice and filesystem module before mounting a physical device.
|
||||
*
|
||||
* @return WICED_SUCCESS on success
|
||||
*/
|
||||
wiced_result_t wiced_filesystem_init(void);
|
||||
|
||||
/**
|
||||
* Mount the physical device
|
||||
*
|
||||
* This assumes that the device is ready to read/write immediately.
|
||||
*
|
||||
* @param[in] device - physical media to init
|
||||
* @param[out] fs_handle_out - Receives the filesystem handle.
|
||||
*
|
||||
* @return WICED_SUCCESS on success
|
||||
*/
|
||||
wiced_result_t wiced_filesystem_mount(mbed::BlockDevice *device, wiced_filesystem_handle_type_t fs_type, wiced_filesystem_t *fs_handle_out, const char *mounted_name);
|
||||
/**
|
||||
* Open a file for reading or writing
|
||||
*
|
||||
* @param[in] fs_handle - The filesystem handle to use - obtained from wiced_filesystem_mount
|
||||
* @param[out] file_handle_out - a pointer to a wiced_file_t structure which will receive the
|
||||
* file handle after it is opened
|
||||
* @param[in] filename - The filename of the file to open
|
||||
* @param[in] mode - Specifies read or write access
|
||||
*
|
||||
* @return WICED_SUCCESS on success
|
||||
*/
|
||||
wiced_result_t wiced_filesystem_file_open(wiced_filesystem_t *fs_handle, wiced_file_t *file_handle_out, const char *filename, wiced_filesystem_open_mode_t mode);
|
||||
|
||||
/**
|
||||
* Seek to a location within a file
|
||||
*
|
||||
* This is similar to the fseek() in ISO C.
|
||||
*
|
||||
* @param[in] file_handle - The file handle on which to perform the seek.
|
||||
* Must have been previously opened with wiced_filesystem_fopen.
|
||||
* @param[in] offset - The offset in bytes
|
||||
* @param[in] whence - WICED_FILESYSTEM_SEEK_SET = Offset from start of file
|
||||
* WICED_FILESYSTEM_SEEK_CUR = Offset from current position in file
|
||||
* WICED_FILESYSTEM_SEEK_END = Offset from end of file
|
||||
*
|
||||
* @return WICED_SUCCESS on success
|
||||
*/
|
||||
wiced_result_t wiced_filesystem_file_seek(wiced_file_t *file_handle, int64_t offset, wiced_filesystem_seek_type_t whence);
|
||||
|
||||
/**
|
||||
* Reads data from a file into a memory buffer
|
||||
*
|
||||
* @param[in] file_handle - the file handle to read from
|
||||
* @param[out] data - A pointer to the memory buffer that will
|
||||
* receive the data that is read
|
||||
* @param[in] bytes_to_read - the number of bytes to read
|
||||
* @param[out] returned_item_count - the number of items successfully read.
|
||||
*
|
||||
* @return WICED_SUCCESS on success
|
||||
*/
|
||||
wiced_result_t wiced_filesystem_file_read(wiced_file_t *file_handle, void *data, uint64_t bytes_to_read, uint64_t *returned_bytes_count);
|
||||
|
||||
/**
|
||||
* Close a file
|
||||
*
|
||||
* This is similar to the fclose() in ISO C.
|
||||
*
|
||||
* @param[in] file_handle - the file handle to close
|
||||
*
|
||||
* @return WICED_SUCCESS = success
|
||||
*/
|
||||
wiced_result_t wiced_filesystem_file_close(wiced_file_t *file_handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C" */
|
||||
#endif
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright 2020 Arduino SA
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** @file
|
||||
* Provides configuration for WHD driver on Arduino Portenta H7
|
||||
*/
|
||||
|
||||
#ifndef __WHD_CONFIG__
|
||||
#define __WHD_CONFIG__
|
||||
|
||||
#include "whd_types.h"
|
||||
#include "stm32h7xx_hal.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/* please define your configuration , either SDIO or SPI */
|
||||
#define CY_WHD_CONFIG_USE_SDIO
|
||||
//#define CY_WHD_CONFIG_USE_SPI
|
||||
|
||||
/* select resource implementation */
|
||||
#define USES_RESOURCE_GENERIC_FILESYSTEM
|
||||
|
||||
/* if not defined default value is 2 */
|
||||
#define CY_WIFI_OOB_INTR_PRIORITY 0
|
||||
|
||||
#define CYBSP_WIFI_HOST_WAKE_IRQ_EVENT CYHAL_GPIO_IRQ_FALL
|
||||
#define CYBSP_WIFI_HOST_WAKE CYBSP_SDIO_OOB_IRQ
|
||||
|
||||
#define BSP_LED1 {GPIOK,{.Pin= GPIO_PIN_5 , .Mode = GPIO_MODE_OUTPUT_PP , .Pull = GPIO_NOPULL , .Speed= GPIO_SPEED_FREQ_LOW}}
|
||||
#define BSP_LED2 {GPIOK,{.Pin= GPIO_PIN_6 , .Mode = GPIO_MODE_OUTPUT_PP , .Pull = GPIO_NOPULL , .Speed= GPIO_SPEED_FREQ_LOW}}
|
||||
#define BSP_LED3 {GPIOK,{.Pin= GPIO_PIN_7 , .Mode = GPIO_MODE_OUTPUT_PP , .Pull = GPIO_NOPULL , .Speed= GPIO_SPEED_FREQ_LOW}}
|
||||
|
||||
/* power pin */
|
||||
#define WIFI_WL_REG_ON {GPIOJ,{.Pin= GPIO_PIN_1, .Mode = GPIO_MODE_OUTPUT_PP , .Pull = GPIO_NOPULL , .Speed= GPIO_SPEED_FREQ_LOW}}
|
||||
//#define WIFI_32K_CLK {GPIOA,{.Pin= GPIO_PIN_8, .Mode = GPIO_MODE_AF_PP , .Pull = GPIO_NOPULL , .Speed= GPIO_SPEED_FREQ_LOW , .Alternate = GPIO_AF0_MCO}}
|
||||
|
||||
#define WIFI_SDIO_CMD {GPIOD,{.Pin= GPIO_PIN_2 , .Mode = GPIO_MODE_AF_PP , .Pull = GPIO_NOPULL , .Speed= GPIO_SPEED_FREQ_VERY_HIGH, .Alternate = GPIO_AF12_SDIO1}}
|
||||
#define WIFI_SDIO_CLK {GPIOC,{.Pin= GPIO_PIN_12, .Mode = GPIO_MODE_AF_PP , .Pull = GPIO_NOPULL , .Speed= GPIO_SPEED_FREQ_VERY_HIGH, .Alternate = GPIO_AF12_SDIO1}}
|
||||
#define WIFI_SDIO_D0 {GPIOC,{.Pin= GPIO_PIN_8 , .Mode = GPIO_MODE_AF_PP , .Pull = GPIO_NOPULL , .Speed= GPIO_SPEED_FREQ_VERY_HIGH, .Alternate = GPIO_AF12_SDIO1}}
|
||||
#define WIFI_SDIO_D1 {GPIOC,{.Pin= GPIO_PIN_9 , .Mode = GPIO_MODE_AF_PP , .Pull = GPIO_NOPULL , .Speed= GPIO_SPEED_FREQ_VERY_HIGH, .Alternate = GPIO_AF12_SDIO1}}
|
||||
#define WIFI_SDIO_D2 {GPIOC,{.Pin= GPIO_PIN_10, .Mode = GPIO_MODE_AF_PP , .Pull = GPIO_NOPULL , .Speed= GPIO_SPEED_FREQ_VERY_HIGH, .Alternate = GPIO_AF12_SDIO1}}
|
||||
#define WIFI_SDIO_D3 {GPIOC,{.Pin= GPIO_PIN_11, .Mode = GPIO_MODE_AF_PP , .Pull = GPIO_NOPULL , .Speed= GPIO_SPEED_FREQ_VERY_HIGH, .Alternate = GPIO_AF12_SDIO1}}
|
||||
#define WIFI_SDIO_OOB_IRQ {GPIOJ,{.Pin= GPIO_PIN_5, .Mode = GPIO_MODE_IT_FALLING , .Pull = GPIO_NOPULL , .Speed= GPIO_SPEED_FREQ_VERY_HIGH}}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue