diff --git a/ARM.CMSIS-Driver_Validation.pdsc b/ARM.CMSIS-Driver_Validation.pdsc index 2930034..c680c5d 100644 --- a/ARM.CMSIS-Driver_Validation.pdsc +++ b/ARM.CMSIS-Driver_Validation.pdsc @@ -9,6 +9,7 @@ Active Development ... + - Add GPIO Driver validation - Improve Ethernet driver validation - Update examples - Update documentation @@ -17,7 +18,7 @@ - + @@ -57,6 +58,13 @@ + + CMSIS Driver GPIO + + + + + CMSIS Driver SPI @@ -138,6 +146,18 @@ + + GPIO driver validation + + #define RTE_CMSIS_DV_GPIO /* Driver Validation GPIO enabled */ + + + + + + + + SPI driver validation diff --git a/Config/DV_GPIO_Config.h b/Config/DV_GPIO_Config.h new file mode 100644 index 0000000..1c59872 --- /dev/null +++ b/Config/DV_GPIO_Config.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2023 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * $Revision: V1.0.0 + * + * Project: CMSIS-Driver Validation + * Title: General-Purpose Input/Output (GPIO) driver validation + * configuration file + * + * ----------------------------------------------------------------------------- + */ + +#ifndef DV_GPIO_CONFIG_H_ +#define DV_GPIO_CONFIG_H_ + +//-------- <<< Use Configuration Wizard in Context Menu >>> -------------------- + +// GPIO +// General-Purpose Input/Output (GPIO) driver validation configuration +// Driver_GPIO# <0-255> +// Choose the Driver_GPIO# instance to test. +// For example to test Driver_GPIO0 select 0. +// Configuration +// Pins and Tests configuration. +// Pin Under Test <0-255> +// Select pin to be tested. +// This pin should not have any external resistors or any external devices connected to it. +// Auxiliary Pin +// Select Auxiliary Pin with serial low resistance resistor connected to Pin Under Test. +// Suggested resistance of this serial resistor is around 1 kOhm. +// This pin should not have any external resistors or any external devices connected to it. +// +// Tests +// Enable / disable tests. +// GPIO_Setup +// Enable / disable Setup function tests. +// GPIO_SetDirection +// Enable / disable SetDirection function tests. +// GPIO_SetOutputMode +// Enable / disable SetOutputMode function tests. +// GPIO_SetPullResistor +// Enable / disable SetPullResistor function tests. +// GPIO_SetEventTrigger +// Enable / disable SetEventTrigger function tests. +// GPIO_SetOutput +// Enable / disable SetOutput function tests. +// GPIO_GetInput +// Enable / disable GetInput function tests. +// +// + +#define DRV_GPIO 0 +#define GPIO_CFG_PIN_UNDER_TEST 0 +#define GPIO_CFG_PIN_AUX 0 +#define GPIO_TC_SETUP_EN 1 +#define GPIO_TC_SET_DIRECTION_EN 1 +#define GPIO_TC_SET_OUTPUT_MODE_EN 1 +#define GPIO_TC_SET_PULL_RESISTOR_EN 1 +#define GPIO_TC_SET_EVENT_TRIGGER_EN 1 +#define GPIO_TC_SET_OUTPUT_EN 1 +#define GPIO_TC_GET_INPUT_EN 1 + +#endif /* DV_GPIO_CONFIG_H_ */ diff --git a/DoxyGen/CMSIS_DV.dxy.in b/DoxyGen/CMSIS_DV.dxy.in index fbb290f..8b04ee3 100644 --- a/DoxyGen/CMSIS_DV.dxy.in +++ b/DoxyGen/CMSIS_DV.dxy.in @@ -877,6 +877,7 @@ INPUT = ./src/DriverValidation.txt \ ./src/DV_Framework.txt \ ./src/DV_CAN.txt \ ./src/DV_ETH.txt \ + ./src/DV_GPIO.txt \ ./src/DV_I2C.txt \ ./src/DV_MCI.txt \ ./src/DV_SPI.txt \ diff --git a/DoxyGen/src/DV_GPIO.txt b/DoxyGen/src/DV_GPIO.txt new file mode 100644 index 0000000..dcc6d1c --- /dev/null +++ b/DoxyGen/src/DV_GPIO.txt @@ -0,0 +1,25 @@ +/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ +/** +\defgroup gpio_config Configuration +\ingroup dv_gpio + +The GPIO driver validation settings are available in the DV_GPIO_Config.h configuration file. + +\image html dv_gpio_config_h.png "DV_GPIO_Config.h configuration file in Configuration Wizard view mode" + +\section gpio_config_detail Configuration settings + +Driver_GPIO# selects the driver instance that will be tested.
+For example if we want to test Driver_GPIO0 then this setting would be set to 0. + +Configuration section contains configuration of two pins: +- Pin Under Test specifying the pin that will be tested.
+- Auxiliary Pin specifies the auxiliary pin with serial low resistance resistor connected to Pin Under Test. + Suggested resistance of this serial resistor is around 1 kOhm.
+ +Pins should not have any external resistors or any external devices connected to it except the low resistance resistor used for testing.
+ +Tests section contains selections of tests to be executed. +For details on tests performed by each test function please refer to \ref gpio_tests "GPIO Tests". + +*/ diff --git a/DoxyGen/src/DriverValidation.txt b/DoxyGen/src/DriverValidation.txt index 2c4fd42..95fcd43 100644 --- a/DoxyGen/src/DriverValidation.txt +++ b/DoxyGen/src/DriverValidation.txt @@ -29,6 +29,7 @@ The diagram below shows an overview of the CMSIS-Driver Validation configuration The CMSIS-Driver Validation provides validation for the following interfaces: - \ref dv_can "CAN" - Controller Area Network (CAN) interface driver. - \ref dv_eth "Ethernet" - Ethernet MAC and PHY peripheral interface driver. + - \ref dv_gpio "GPIO" - General Purpose Input-Output interface driver. - \ref dv_i2c "I2C" - Inter-Integrated Circuit (I2C) multi-master serial single-ended bus interface driver. - \ref dv_mci "MCI" - Memory Card Interface driver for SD/MMC memory. - \ref dv_spi "SPI" - Serial Peripheral Interface (SPI) driver. diff --git a/DoxyGen/src/images/dv_gpio_config_h.png b/DoxyGen/src/images/dv_gpio_config_h.png new file mode 100644 index 0000000..9830ff4 Binary files /dev/null and b/DoxyGen/src/images/dv_gpio_config_h.png differ diff --git a/DoxyGen/src/images/gpio_loopback.png b/DoxyGen/src/images/gpio_loopback.png new file mode 100644 index 0000000..8829832 Binary files /dev/null and b/DoxyGen/src/images/gpio_loopback.png differ diff --git a/DoxyGen/src/images/src/GPIO_pin_connection.pptx b/DoxyGen/src/images/src/GPIO_pin_connection.pptx new file mode 100644 index 0000000..fdd2acc Binary files /dev/null and b/DoxyGen/src/images/src/GPIO_pin_connection.pptx differ diff --git a/Include/cmsis_dv.h b/Include/cmsis_dv.h index 4bef9f2..c1a7392 100644 --- a/Include/cmsis_dv.h +++ b/Include/cmsis_dv.h @@ -278,4 +278,12 @@ extern void WIFI_Concurrent_Socket (void); extern void WIFI_Downstream_Rate (void); extern void WIFI_Upstream_Rate (void); +extern void GPIO_Setup (void); +extern void GPIO_SetDirection (void); +extern void GPIO_SetOutputMode (void); +extern void GPIO_SetPullResistor (void); +extern void GPIO_SetEventTrigger (void); +extern void GPIO_SetOutput (void); +extern void GPIO_GetInput (void); + #endif /* __CMSIS_DV_H */ diff --git a/Source/DV_GPIO.c b/Source/DV_GPIO.c new file mode 100644 index 0000000..95bc8b6 --- /dev/null +++ b/Source/DV_GPIO.c @@ -0,0 +1,807 @@ +/* + * Copyright (c) 2023 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-Driver Validation + * Title: General-purpose Input Output (GPIO) Driver Validation tests + * + * ----------------------------------------------------------------------------- + */ + +#ifndef __DOXYGEN__ // Exclude form the documentation + +#include +#include +#include + +#include "cmsis_dv.h" +#include "DV_GPIO_Config.h" +#include "DV_Framework.h" + +#include "Driver_GPIO.h" + +// Register Driver_GPIO# +extern ARM_DRIVER_GPIO CREATE_SYMBOL(Driver_GPIO, DRV_GPIO); +static ARM_DRIVER_GPIO *drv = &CREATE_SYMBOL(Driver_GPIO, DRV_GPIO); + +// Global variables (used in this module only) +static volatile uint32_t event; +static volatile ARM_GPIO_Pin_t event_pin; +static volatile uint32_t event_cnt; + +static char msg_buf[256]; + +// Local functions +static void GPIO_DrvEvent (ARM_GPIO_Pin_t pin, uint32_t evt); +static int32_t PinUnderTestIsAvailable (void); +static void PinUnderTestInit (void); +static void PinUnderTestUninit (void); +static int32_t AuxiliaryPinIsAvailable (void); +static void AuxiliaryPinInit (void); +static void AuxiliaryPinUninit (void); +static void AuxiliaryPinConfigInput (void); +static void AuxiliaryPinConfigOutput(void); +static void AuxiliaryPinSetOutput (uint32_t val); + +// Helper functions + +/* + \fn static void GPIO_DrvEvent (ARM_GPIO_Pin_t pin, uint32_t evt) + \brief Store event(s) into a global variables. + \detail This is a callback function called by the driver upon an event(s). + \param[in] pin GPIO pin + \param[in] evt GPIO event + \return none +*/ +static void GPIO_DrvEvent (ARM_GPIO_Pin_t pin, uint32_t evt) { + event |= evt; + event_pin = pin; + event_cnt++; +} + +/* + \fn static int32_t PinUnderTestIsAvailable (void) + \brief Check if Pin Under Test is available. + \detail This function is used to skip executing a test if Pin Under Test is not available. + \return execution status + - EXIT_SUCCESS: Pin Under Test is available + - EXIT_FAILURE: Pin Under Test is not available +*/ +static int32_t PinUnderTestIsAvailable (void) { + + if (drv->Setup(GPIO_CFG_PIN_UNDER_TEST, NULL) == ARM_DRIVER_OK) { + return EXIT_SUCCESS; + } else { + TEST_MESSAGE("[FAILED] Pin Under Test is not available!"); + return EXIT_FAILURE; + } +} + +/* + \fn static void PinUnderTestInit (void) + \brief Initialize Pin Under Test. + \param[in] none + \return none +*/ +static void PinUnderTestInit (void) { + + (void)drv->Setup(GPIO_CFG_PIN_UNDER_TEST, NULL); +} + +/* + \fn static void PinUnderTestUninit (void) + \brief Uninitialize Pin Under Test. + \param[in] none + \return none +*/ +static void PinUnderTestUninit (void) { + + (void)drv->SetDirection(GPIO_CFG_PIN_UNDER_TEST, ARM_GPIO_INPUT); + (void)drv->Setup (GPIO_CFG_PIN_UNDER_TEST, NULL); +} + +/* + \fn static int32_t AuxiliaryPinIsAvailable (void) + \brief Check if Auxiliary Pin is available. + \detail This function is used to skip executing a test if Auxiliary Pin is not available. + \return execution status + - EXIT_SUCCESS: Auxiliary Pin is available + - EXIT_FAILURE: Auxiliary Pin is not available +*/ +static int32_t AuxiliaryPinIsAvailable (void) { + + if (drv->Setup(GPIO_CFG_PIN_AUX, NULL) == ARM_DRIVER_OK) { + return EXIT_SUCCESS; + } else { + TEST_MESSAGE("[FAILED] Auxiliary Pin is not available!"); + return EXIT_FAILURE; + } +} + +/* + \fn static void AuxiliaryPinInit (void) + \brief Initialize Auxiliary Pin. + \param[in] none + \return none +*/ +static void AuxiliaryPinInit (void) { + + (void)drv->Setup(GPIO_CFG_PIN_AUX, NULL); +} + +/* + \fn static void AuxiliaryPinUninit (void) + \brief Uninitialize Auxiliary Pin. + \param[in] none + \return none +*/ +static void AuxiliaryPinUninit (void) { + + (void)drv->SetDirection(GPIO_CFG_PIN_AUX, ARM_GPIO_INPUT); + (void)drv->Setup (GPIO_CFG_PIN_AUX, NULL); +} + +/* + \fn static void AuxiliaryPinConfigInput (void) + \brief Configure Auxiliary Pin as Input. + \param[in] none + \return none +*/ +static void AuxiliaryPinConfigInput (void) { + + (void)drv->SetDirection(GPIO_CFG_PIN_AUX, ARM_GPIO_INPUT); +} + +/* + \fn static void AuxiliaryPinConfigOutput (void) + \brief Configure Auxiliary Pin as Output with Push-pull Output mode. + \param[in] none + \return none +*/ +static void AuxiliaryPinConfigOutput (void) { + + (void)drv->SetOutputMode(GPIO_CFG_PIN_AUX, ARM_GPIO_PUSH_PULL); + (void)drv->SetDirection (GPIO_CFG_PIN_AUX, ARM_GPIO_OUTPUT); +} + +/* + \fn static void AuxiliaryPinSetOutput (uint32_t val) + \brief Set Auxiliary Pin output level (0 or 1). + \param[in] val Output level + \return none +*/ +static void AuxiliaryPinSetOutput (uint32_t val) { + + drv->SetOutput(GPIO_CFG_PIN_AUX, val); + (void)osDelay(2U); // Wait for voltage to stabilize +} + +#endif // End of exclude form the documentation + +/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ +/** +\defgroup dv_gpio GPIO Validation +\brief GPIO driver validation +\details +The GPIO validation performs the following tests: +- API interface compliance +- Functions operation +- Event signaling + +To perform GPIO validation tests, it is required to select and configure two pins in the DV_GPIO_Config.h configuration file: +- Pin Under Test: pin to be tested +- Auxiliary Pin: pin with serial low resistance resistor connected to Pin Under Test (suggested resistance of this resistor is around 1 kOhm) + +\image html gpio_loopback.png + +\note + - Pins (Pin Under Test and Auxiliary Pin) should not have any external resistors or any external devices connected to it except the low resistance resistor used for testing. + +\defgroup gpio_tests Tests +\ingroup dv_gpio +@{ +*/ + +/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ +/* GPIO tests */ +/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ +/** +\brief Function: GPIO_Setup +\details +The function \b GPIO_Setup verifies the \b Setup function. +\code + int32_t Setup (ARM_GPIO_Pin_t pin, ARM_GPIO_SignalEvent_t cb_event); +\endcode + +Testing sequence: + - Call Setup function (without callback specified) and assert that it returned ARM_DRIVER_OK status + - Call Setup function (with callback specified) and assert that it returned ARM_DRIVER_OK status +*/ +void GPIO_Setup (void) { + + if (PinUnderTestIsAvailable() != EXIT_SUCCESS) { TEST_FAIL(); return; } + + // Call Setup function (without callback specified) and assert that it returned ARM_DRIVER_OK status + TEST_ASSERT(drv->Setup(GPIO_CFG_PIN_UNDER_TEST, NULL) == ARM_DRIVER_OK); + + // Call Setup function (with callback specified) and assert that it returned ARM_DRIVER_OK status + TEST_ASSERT(drv->Setup(GPIO_CFG_PIN_UNDER_TEST, GPIO_DrvEvent) == ARM_DRIVER_OK); + + PinUnderTestUninit(); +} + +/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ +/** +\brief Function: GPIO_SetDirection +\details +The function \b GPIO_SetDirection verifies the \b SetDirection function. +\code + int32_t ARM_GPIO_SetDirection (ARM_GPIO_Pin_t pin, ARM_GPIO_DIRECTION direction); +\endcode + +Testing sequence: + - Call SetDirection function (with Input direction) and assert that it returned ARM_DRIVER_OK status + - Configure Auxiliary Pin as Output + - Drive Auxiliary Pin low + - Read Pin Under Test input level and assert that it returned 0 + - Drive Auxiliary Pin high + - Read Pin Under Test input level and assert that it returned 1 + - Configure Auxiliary Pin as Input + - Call SetDirection function (with Output direction) and assert that it returned ARM_DRIVER_OK status + - Call SetOutput function and set output level low + - Read Auxiliary Pin input level and assert that it returned 0 + - Call SetOutput function and set output level high + - Read Auxiliary Pin input level and assert that it returned 1 +*/ +void GPIO_SetDirection (void) { + + if (PinUnderTestIsAvailable() != EXIT_SUCCESS) { TEST_FAIL(); return; } + if (AuxiliaryPinIsAvailable() != EXIT_SUCCESS) { TEST_FAIL(); return; } + + PinUnderTestInit(); + AuxiliaryPinInit(); + + // Call SetDirection function (with Input direction) and assert that it returned ARM_DRIVER_OK status + TEST_ASSERT(drv->SetDirection(GPIO_CFG_PIN_UNDER_TEST, ARM_GPIO_INPUT) == ARM_DRIVER_OK); + + // Configure Auxiliary Pin as Output + AuxiliaryPinConfigOutput(); + + // Drive Auxiliary Pin low + AuxiliaryPinSetOutput(0U); + + // Read Pin Under Test input level and assert that it returned 0 + TEST_ASSERT(drv->GetInput(GPIO_CFG_PIN_UNDER_TEST) == 0U); + + // Drive Auxiliary Pin high + AuxiliaryPinSetOutput(1U); + + // Read Pin Under Test input level and assert that it returned 1 + TEST_ASSERT(drv->GetInput(GPIO_CFG_PIN_UNDER_TEST) == 1U); + + // Configure Auxiliary Pin as Input + AuxiliaryPinConfigInput(); + + // Call SetDirection function (with Output direction) and assert that it returned ARM_DRIVER_OK status + TEST_ASSERT(drv->SetDirection(GPIO_CFG_PIN_UNDER_TEST, ARM_GPIO_OUTPUT) == ARM_DRIVER_OK); + + // Call SetOutput function and set output level low + drv->SetOutput(GPIO_CFG_PIN_UNDER_TEST, 0U); + + (void)osDelay(2U); + + // Read Auxiliary Pin input level and assert that it returned 0 + TEST_ASSERT(drv->GetInput(GPIO_CFG_PIN_AUX) == 0U); + + // Call SetOutput function and set output level high + drv->SetOutput(GPIO_CFG_PIN_UNDER_TEST, 1U); + + (void)osDelay(2U); + + // Read Auxiliary Pin input level and assert that it returned 1 + TEST_ASSERT(drv->GetInput(GPIO_CFG_PIN_AUX) == 1U); + + AuxiliaryPinUninit(); + PinUnderTestUninit(); +} + +/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ +/** +\brief Function: GPIO_SetOutputMode +\details +The function \b GPIO_SetOutputMode verifies the \b SetOutputMode function. +\code + int32_t ARM_GPIO_SetOutputMode (ARM_GPIO_Pin_t pin, ARM_GPIO_OUTPUT_MODE mode); +\endcode + +Testing sequence: + - Call SetDirection function (with Output direction) and assert that it returned ARM_DRIVER_OK status + - Call SetOutputMode function (with Push-pull mode) and assert that it returned ARM_DRIVER_OK status + - Configure Auxiliary Pin as Input + - Call SetOutput function and set output level low + - Read Auxiliary Pin input level and assert that it returned 0 + - Call SetOutput function and set output level high + - Read Auxiliary Pin input level and assert that it returned 1 + - Call SetOutputMode function (with Open-drain mode) and assert that it returned ARM_DRIVER_OK status + - Call SetOutput function and set output level low + - Read Auxiliary Pin input level and assert that it returned 0 +*/ +void GPIO_SetOutputMode (void) { + + if (PinUnderTestIsAvailable() != EXIT_SUCCESS) { TEST_FAIL(); return; } + if (AuxiliaryPinIsAvailable() != EXIT_SUCCESS) { TEST_FAIL(); return; } + + PinUnderTestInit(); + AuxiliaryPinInit(); + + // Call SetDirection function (with Output direction) and assert that it returned ARM_DRIVER_OK status + TEST_ASSERT(drv->SetDirection(GPIO_CFG_PIN_UNDER_TEST, ARM_GPIO_OUTPUT) == ARM_DRIVER_OK); + + // Call SetOutputMode function (with Push-pull mode) and assert that it returned ARM_DRIVER_OK status + TEST_ASSERT(drv->SetOutputMode(GPIO_CFG_PIN_UNDER_TEST, ARM_GPIO_PUSH_PULL) == ARM_DRIVER_OK); + + // Configure Auxiliary Pin as Input + AuxiliaryPinConfigInput(); + + // Call SetOutput function and set output level low + drv->SetOutput(GPIO_CFG_PIN_UNDER_TEST, 0U); + + (void)osDelay(2U); + + // Read Auxiliary Pin input level and assert that it returned 0 + TEST_ASSERT(drv->GetInput(GPIO_CFG_PIN_AUX) == 0U); + + // Call SetOutput function and set output level high + drv->SetOutput(GPIO_CFG_PIN_UNDER_TEST, 1U); + + (void)osDelay(2U); + + // Read Auxiliary Pin input level and assert that it returned 1 + TEST_ASSERT(drv->GetInput(GPIO_CFG_PIN_AUX) == 1U); + + // Call SetOutputMode function (with Open-drain mode) and assert that it returned ARM_DRIVER_OK status + TEST_ASSERT(drv->SetOutputMode(GPIO_CFG_PIN_UNDER_TEST, ARM_GPIO_OPEN_DRAIN) == ARM_DRIVER_OK); + + // Call SetOutput function and set output level low + drv->SetOutput(GPIO_CFG_PIN_UNDER_TEST, 0U); + + (void)osDelay(2U); + + // Read Auxiliary Pin input level and assert that it returned 0 + TEST_ASSERT(drv->GetInput(GPIO_CFG_PIN_AUX) == 0U); + + AuxiliaryPinUninit(); + PinUnderTestUninit(); +} + +/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ +/** +\brief Function: GPIO_SetPullResistor +\details +The function \b GPIO_SetPullResistor verifies the \b SetPullResistor function. +\code + int32_t ARM_GPIO_SetPullResistor (ARM_GPIO_Pin_t pin, ARM_GPIO_PULL_RESISTOR resistor); +\endcode + +Testing sequence: + - Call SetDirection function (with Input direction) and assert that it returned ARM_DRIVER_OK status + - Call SetPullResistor function (without resistor) and assert that it returned ARM_DRIVER_OK status + - Configure Auxiliary Pin as Output + - Drive Auxiliary Pin low + - Read Pin Under Test input level and assert that it returned 0 + - Drive Auxiliary Pin high + - Read Pin Under Test input level and assert that it returned 1 + - Configure Auxiliary Pin as Input + - Call SetPullResistor function (with Pull-down resistor) and assert that it returned ARM_DRIVER_OK status + - Read Pin Under Test input level and assert that it returned 0 + - Configure Auxiliary Pin as Output + - Drive Auxiliary Pin high + - Read Pin Under Test input level and assert that it returned 1 + - Configure Auxiliary Pin as Input + - Call SetPullResistor function (with Pull-up resistor) and assert that it returned ARM_DRIVER_OK status + - Read Pin Under Test input level and assert that it returned 1 + - Configure Auxiliary Pin as Output + - Drive Auxiliary Pin low + - Read Pin Under Test input level and assert that it returned 0 +*/ +void GPIO_SetPullResistor (void) { + + if (PinUnderTestIsAvailable() != EXIT_SUCCESS) { TEST_FAIL(); return; } + if (AuxiliaryPinIsAvailable() != EXIT_SUCCESS) { TEST_FAIL(); return; } + + PinUnderTestInit(); + AuxiliaryPinInit(); + + // Call SetDirection function (with Input direction) and assert that it returned ARM_DRIVER_OK status + TEST_ASSERT(drv->SetDirection(GPIO_CFG_PIN_UNDER_TEST, ARM_GPIO_INPUT) == ARM_DRIVER_OK); + + // Call SetPullResistor function (without resistor) and assert that it returned ARM_DRIVER_OK status + TEST_ASSERT(drv->SetPullResistor(GPIO_CFG_PIN_UNDER_TEST, ARM_GPIO_PULL_NONE) == ARM_DRIVER_OK); + + // Configure Auxiliary Pin as Output + AuxiliaryPinConfigOutput(); + + // Drive Auxiliary Pin low + AuxiliaryPinSetOutput(0U); + + // Read Pin Under Test input level and assert that it returned 0 + TEST_ASSERT(drv->GetInput(GPIO_CFG_PIN_UNDER_TEST) == 0U); + + // Drive Auxiliary Pin high + AuxiliaryPinSetOutput(1U); + + // Read Pin Under Test input level and assert that it returned 1 + TEST_ASSERT(drv->GetInput(GPIO_CFG_PIN_UNDER_TEST) == 1U); + + // Configure Auxiliary Pin as Input + AuxiliaryPinConfigInput(); + + (void)osDelay(2U); + + // Call SetPullResistor function (with Pull-down resistor) and assert that it returned ARM_DRIVER_OK status + TEST_ASSERT(drv->SetPullResistor(GPIO_CFG_PIN_UNDER_TEST, ARM_GPIO_PULL_DOWN) == ARM_DRIVER_OK); + + (void)osDelay(2U); + + // Read Pin Under Test input level and assert that it returned 0 + TEST_ASSERT(drv->GetInput(GPIO_CFG_PIN_UNDER_TEST) == 0U); + + // Configure Auxiliary Pin as Output + AuxiliaryPinConfigOutput(); + + // Drive Auxiliary Pin high + AuxiliaryPinSetOutput(1U); + + // Read Pin Under Test input level and assert that it returned 1 + TEST_ASSERT(drv->GetInput(GPIO_CFG_PIN_UNDER_TEST) == 1U); + + // Configure Auxiliary Pin as Input + AuxiliaryPinConfigInput(); + + (void)osDelay(2U); + + // Call SetPullResistor function (with Pull-up resistor) and assert that it returned ARM_DRIVER_OK status + TEST_ASSERT(drv->SetPullResistor(GPIO_CFG_PIN_UNDER_TEST, ARM_GPIO_PULL_UP) == ARM_DRIVER_OK); + + (void)osDelay(2U); + + // Read Pin Under Test input level and assert that it returned 1 + TEST_ASSERT(drv->GetInput(GPIO_CFG_PIN_UNDER_TEST) == 1U); + + // Configure Auxiliary Pin as Output + AuxiliaryPinConfigOutput(); + + // Drive Auxiliary Pin low + AuxiliaryPinSetOutput(0U); + + // Read Pin Under Test input level and assert that it returned 0 + TEST_ASSERT(drv->GetInput(GPIO_CFG_PIN_UNDER_TEST) == 0U); + + AuxiliaryPinUninit(); + PinUnderTestUninit(); +} + +/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ +/** +\brief Function: GPIO_SetEventTrigger +\details +The function \b GPIO_SetEventTrigger verifies the \b SetEventTrigger function. +\code + int32_t ARM_GPIO_SetEventTrigger (ARM_GPIO_Pin_t pin, ARM_GPIO_EVENT_TRIGGER trigger); +\endcode + +Testing sequence: + - Call Setup function (with callback specified) and assert that it returned ARM_DRIVER_OK status + - Configure Auxiliary Pin as Output + - Drive Auxiliary Pin low + - Call SetEventTrigger function (configure trigger on Rising-edge) and assert that it returned ARM_DRIVER_OK status + - Drive Auxiliary Pin high thus generate Rising-edge + - Assert that event ARM_GPIO_EVENT_RISING_EDGE was signaled + - Assert that event was signaled on Pin Under Test pin + - Assert that only 1 event was signaled + - Drive Auxiliary Pin low thus generate Falling-edge + - Assert that event was not signaled + - Drive Auxiliary Pin high + - Call SetEventTrigger function (configure trigger on Falling-edge) and assert that it returned ARM_DRIVER_OK status + - Drive Auxiliary Pin low thus generate Falling-edge + - Assert that event ARM_GPIO_EVENT_FALLING_EDGE was signaled + - Assert that event was signaled on Pin Under Test pin + - Assert that only 1 event was signaled + - Drive Auxiliary Pin high thus generate Rising-edge + - Assert that event was not signaled + - Drive Auxiliary Pin low + - Call SetEventTrigger function (configure trigger on Either-edge) and assert that it returned ARM_DRIVER_OK status + - Drive Auxiliary Pin high thus generate Rising-edge + - Assert that event ARM_GPIO_EVENT_RISING_EDGE or ARM_GPIO_EVENT_EITHER_EDGE was signaled + - Assert that event was signaled on Pin Under Test pin + - Assert that only 1 event was signaled + - Drive Auxiliary Pin low thus generate Falling-edge + - Assert that event ARM_GPIO_EVENT_FALLING_EDGE or ARM_GPIO_EVENT_EITHER_EDGE was signaled + - Assert that event was signaled on Pin Under Test pin + - Assert that only 1 event was signaled + - Drive Auxiliary Pin low + - Call SetEventTrigger function (disable trigger) and assert that it returned ARM_DRIVER_OK status + - Drive Auxiliary Pin high thus generate Rising-edge + - Drive Auxiliary Pin low thus generate Falling-edge + - Assert that event was not signaled +*/ +void GPIO_SetEventTrigger (void) { + + if (PinUnderTestIsAvailable() != EXIT_SUCCESS) { TEST_FAIL(); return; } + if (AuxiliaryPinIsAvailable() != EXIT_SUCCESS) { TEST_FAIL(); return; } + + PinUnderTestInit(); + AuxiliaryPinInit(); + + // Call Setup function (with callback specified) and assert that it returned ARM_DRIVER_OK status + TEST_ASSERT(drv->Setup(GPIO_CFG_PIN_UNDER_TEST, GPIO_DrvEvent) == ARM_DRIVER_OK); + + // Configure Auxiliary Pin as Output + AuxiliaryPinConfigOutput(); + + // Test Rising-edge + // Drive Auxiliary Pin low + AuxiliaryPinSetOutput(0U); + + event = 0U; + event_pin = 0U; + event_cnt = 0U; + + // Call SetEventTrigger function (configure trigger on Rising-edge) and assert that it returned ARM_DRIVER_OK status + TEST_ASSERT(drv->SetEventTrigger(GPIO_CFG_PIN_UNDER_TEST, ARM_GPIO_TRIGGER_RISING_EDGE) == ARM_DRIVER_OK); + + // Drive Auxiliary Pin high thus generate Rising-edge + AuxiliaryPinSetOutput(1U); + + // Assert that event ARM_GPIO_EVENT_RISING_EDGE was signaled + TEST_ASSERT_MESSAGE(event == ARM_GPIO_EVENT_RISING_EDGE, "[FAILED] Event ARM_GPIO_EVENT_RISING_EDGE was not signaled!"); + + // Assert that event was signaled on Pin Under Test pin + TEST_ASSERT_MESSAGE(event_pin == (uint32_t)GPIO_CFG_PIN_UNDER_TEST, "[FAILED] Event was not signaled on Pin Under Test pin!"); + + if (event_cnt != 1U) { + // If number of events signaled was different than 1 + (void)snprintf(msg_buf, sizeof(msg_buf), "[FAILED] Number of signaled events was %i! Expected number of events was 1!", event_cnt); + } + // Assert that only 1 event was signaled + TEST_ASSERT_MESSAGE(event_cnt == 1U, msg_buf); + + event = 0U; + event_pin = 0U; + event_cnt = 0U; + + // Drive Auxiliary Pin low thus generate Falling-edge + AuxiliaryPinSetOutput(0U); + + // Assert that event was not signaled + TEST_ASSERT_MESSAGE(event_cnt == 0U, "[FAILED] Event was signaled on Pin Under Test pin! Event signaled on falling-edge for rising-edge trigger!"); + + // Test Falling-edge + // Drive Auxiliary Pin high + AuxiliaryPinSetOutput(1U); + + event = 0U; + event_pin = 0U; + event_cnt = 0U; + + // Call SetEventTrigger function (configure trigger on Falling-edge) and assert that it returned ARM_DRIVER_OK status + TEST_ASSERT(drv->SetEventTrigger(GPIO_CFG_PIN_UNDER_TEST, ARM_GPIO_TRIGGER_FALLING_EDGE) == ARM_DRIVER_OK); + + // Drive Auxiliary Pin low thus generate Falling-edge + AuxiliaryPinSetOutput(0U); + + // Assert that event ARM_GPIO_EVENT_FALLING_EDGE was signaled + TEST_ASSERT_MESSAGE(event == ARM_GPIO_EVENT_FALLING_EDGE, "[FAILED] Event ARM_GPIO_EVENT_FALLING_EDGE was not signaled!"); + + // Assert that event was signaled on Pin Under Test pin + TEST_ASSERT_MESSAGE(event_pin == (uint32_t)GPIO_CFG_PIN_UNDER_TEST, "[FAILED] Event was not signaled on Pin Under Test pin!"); + + if (event_cnt != 1U) { + // If number of events signaled was different than 1 + (void)snprintf(msg_buf, sizeof(msg_buf), "[FAILED] Number of signaled events was %i! Expected number of events was 1!", event_cnt); + } + // Assert that only 1 event was signaled + TEST_ASSERT_MESSAGE(event_cnt == 1U, msg_buf); + + event = 0U; + event_pin = 0U; + event_cnt = 0U; + + // Drive Auxiliary Pin high thus generate Rising-edge + AuxiliaryPinSetOutput(0U); + + // Assert that event was not signaled + TEST_ASSERT_MESSAGE(event_cnt == 0U, "[FAILED] Event was signaled on Pin Under Test pin! Event signaled on rising-edge for falling-edge trigger!"); + + // Test Either-edge + // Drive Auxiliary Pin low + AuxiliaryPinSetOutput(0U); + + event = 0U; + event_pin = 0U; + event_cnt = 0U; + + // Call SetEventTrigger function (configure trigger on Either-edge) and assert that it returned ARM_DRIVER_OK status + TEST_ASSERT(drv->SetEventTrigger(GPIO_CFG_PIN_UNDER_TEST, ARM_GPIO_TRIGGER_EITHER_EDGE) == ARM_DRIVER_OK); + + // Drive Auxiliary Pin high thus generate Rising-edge + AuxiliaryPinSetOutput(1U); + + // Assert that event ARM_GPIO_EVENT_RISING_EDGE or ARM_GPIO_EVENT_EITHER_EDGE was signaled + TEST_ASSERT_MESSAGE((event == ARM_GPIO_EVENT_RISING_EDGE) || + (event == ARM_GPIO_EVENT_EITHER_EDGE), "[FAILED] Event ARM_GPIO_EVENT_RISING_EDGE or ARM_GPIO_EVENT_EITHER_EDGE was not signaled!"); + + // Assert that event was signaled on Pin Under Test pin + TEST_ASSERT_MESSAGE(event_pin == (uint32_t)GPIO_CFG_PIN_UNDER_TEST, "[FAILED] Event was not signaled on Pin Under Test pin!"); + + if (event_cnt != 1U) { + // If number of events signaled was different than 1 + (void)snprintf(msg_buf, sizeof(msg_buf), "[FAILED] Number of signaled events was %i! Expected number of events was 1!", event_cnt); + } + // Assert that only 1 event was signaled + TEST_ASSERT_MESSAGE(event_cnt == 1U, msg_buf); + + event = 0U; + event_pin = 0U; + event_cnt = 0U; + + // Drive Auxiliary Pin low thus generate Falling-edge + AuxiliaryPinSetOutput(0U); + + // Assert that event ARM_GPIO_EVENT_FALLING_EDGE or ARM_GPIO_EVENT_EITHER_EDGE was signaled + TEST_ASSERT_MESSAGE((event == ARM_GPIO_EVENT_FALLING_EDGE) || + (event == ARM_GPIO_EVENT_EITHER_EDGE), "[FAILED] Event ARM_GPIO_EVENT_FALLING_EDGE or ARM_GPIO_EVENT_EITHER_EDGE was not signaled!"); + + // Assert that event was signaled on Pin Under Test pin + TEST_ASSERT_MESSAGE(event_pin == (uint32_t)GPIO_CFG_PIN_UNDER_TEST, "[FAILED] Event was not signaled on Pin Under Test pin!"); + + if (event_cnt != 1U) { + // If number of events signaled was different than 1 + (void)snprintf(msg_buf, sizeof(msg_buf), "[FAILED] Number of signaled events was %i! Expected number of events was 1!", event_cnt); + } + // Assert that only 1 event was signaled + TEST_ASSERT_MESSAGE(event_cnt == 1U, msg_buf); + + // Test no trigger enabled functionality + // Drive Auxiliary Pin low + AuxiliaryPinSetOutput(0U); + + event = 0U; + event_pin = 0U; + event_cnt = 0U; + + // Call SetEventTrigger function (disable trigger) and assert that it returned ARM_DRIVER_OK status + TEST_ASSERT(drv->SetEventTrigger(GPIO_CFG_PIN_UNDER_TEST, ARM_GPIO_TRIGGER_NONE) == ARM_DRIVER_OK); + + // Drive Auxiliary Pin high thus generate Rising-edge + AuxiliaryPinSetOutput(1U); + + // Drive Auxiliary Pin low thus generate Falling-edge + AuxiliaryPinSetOutput(0U); + + // Assert that event was not signaled + TEST_ASSERT_MESSAGE(event_cnt == 0U, "[FAILED] Event was signaled on Pin Under Test pin with trigger functionality disabled!"); + + AuxiliaryPinUninit(); + PinUnderTestUninit(); +} + +/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ +/** +\brief Function: GPIO_SetOutput +\details +The function \b GPIO_SetOutput verifies the \b SetOutput function. + +Testing sequence: + - Call SetDirection function (with Output direction) and assert that it returned ARM_DRIVER_OK status + - Call SetOutputMode function (with Push-pull mode) and assert that it returned ARM_DRIVER_OK status + - Configure Auxiliary Pin as Input + - Call SetOutput function and set output level low + - Read Auxiliary Pin input level and assert that it returned 0 + - Call SetOutput function and set output level high + - Read Auxiliary Pin input level and assert that it returned 1 +*/ +void GPIO_SetOutput (void) { + + if (PinUnderTestIsAvailable() != EXIT_SUCCESS) { TEST_FAIL(); return; } + if (AuxiliaryPinIsAvailable() != EXIT_SUCCESS) { TEST_FAIL(); return; } + + PinUnderTestInit(); + AuxiliaryPinInit(); + + // Call SetDirection function (with Output direction) and assert that it returned ARM_DRIVER_OK status + TEST_ASSERT(drv->SetDirection(GPIO_CFG_PIN_UNDER_TEST, ARM_GPIO_OUTPUT) == ARM_DRIVER_OK); + + // Call SetOutputMode function (with Push-pull mode) and assert that it returned ARM_DRIVER_OK status + TEST_ASSERT(drv->SetOutputMode(GPIO_CFG_PIN_UNDER_TEST, ARM_GPIO_PUSH_PULL) == ARM_DRIVER_OK); + + // Configure Auxiliary Pin as Input + AuxiliaryPinConfigInput(); + + // Call SetOutput function and set output level low + drv->SetOutput(GPIO_CFG_PIN_UNDER_TEST, 0U); + + (void)osDelay(2U); + + // Read Auxiliary Pin input level and assert that it returned 0 + TEST_ASSERT(drv->GetInput(GPIO_CFG_PIN_AUX) == 0U); + + // Call SetOutput function and set output level high + drv->SetOutput(GPIO_CFG_PIN_UNDER_TEST, 1U); + + (void)osDelay(2U); + + // Read Auxiliary Pin input level and assert that it returned 1 + TEST_ASSERT(drv->GetInput(GPIO_CFG_PIN_AUX) == 1U); + + AuxiliaryPinUninit(); + PinUnderTestUninit(); +} + +/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ +/** +\brief Function: GPIO_GetInput +\details +The function \b GPIO_GetInput verifies the \b GetInput function. + +Testing sequence: + - Call SetDirection function (with Input direction) and assert that it returned ARM_DRIVER_OK status + - Configure Auxiliary Pin as Output + - Drive Auxiliary Pin low + - Read Pin Under Test input level and assert that it returned 0 + - Drive Auxiliary Pin high + - Read Pin Under Test input level and assert that it returned 1 +*/ +void GPIO_GetInput (void) { + + if (PinUnderTestIsAvailable() != EXIT_SUCCESS) { TEST_FAIL(); return; } + if (AuxiliaryPinIsAvailable() != EXIT_SUCCESS) { TEST_FAIL(); return; } + + PinUnderTestInit(); + AuxiliaryPinInit(); + + // Call SetDirection function (with Input direction) and assert that it returned ARM_DRIVER_OK status + TEST_ASSERT(drv->SetDirection(GPIO_CFG_PIN_UNDER_TEST, ARM_GPIO_INPUT) == ARM_DRIVER_OK); + + // Configure Auxiliary Pin as Output + AuxiliaryPinConfigOutput(); + + // Drive Auxiliary Pin low + AuxiliaryPinSetOutput(0U); + + (void)osDelay(2U); + + // Read Pin Under Test input level and assert that it returned 0 + TEST_ASSERT(drv->GetInput(GPIO_CFG_PIN_UNDER_TEST) == 0U); + + // Drive Auxiliary Pin high + AuxiliaryPinSetOutput(1U); + + (void)osDelay(2U); + + // Read Pin Under Test input level and assert that it returned 1 + TEST_ASSERT(drv->GetInput(GPIO_CFG_PIN_UNDER_TEST) == 1U); + + AuxiliaryPinUninit(); + PinUnderTestUninit(); +} + +/** +@} +*/ +// end of group dv_gpio diff --git a/Source/cmsis_dv.c b/Source/cmsis_dv.c index d762170..ab15ba0 100644 --- a/Source/cmsis_dv.c +++ b/Source/cmsis_dv.c @@ -24,6 +24,9 @@ */ #include "cmsis_dv.h" +#ifdef RTE_CMSIS_DV_GPIO +#include "DV_GPIO_Config.h" +#endif #ifdef RTE_CMSIS_DV_SPI #include "DV_SPI_Config.h" #endif @@ -403,6 +406,18 @@ static TEST_CASE TC_List_WiFi[] = { }; #endif +#ifdef RTE_CMSIS_DV_GPIO +static TEST_CASE TC_List_GPIO[] = { + TCD ( GPIO_Setup, GPIO_TC_SETUP_EN ), + TCD ( GPIO_SetDirection, GPIO_TC_SET_DIRECTION_EN ), + TCD ( GPIO_SetOutputMode, GPIO_TC_SET_OUTPUT_MODE_EN ), + TCD ( GPIO_SetPullResistor, GPIO_TC_SET_PULL_RESISTOR_EN ), + TCD ( GPIO_SetEventTrigger, GPIO_TC_SET_EVENT_TRIGGER_EN ), + TCD ( GPIO_SetOutput, GPIO_TC_SET_OUTPUT_EN ), + TCD ( GPIO_GetInput, GPIO_TC_GET_INPUT_EN ) +}; +#endif + #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdate-time" @@ -509,6 +524,17 @@ TEST_GROUP ts[] = { ARRAY_SIZE (TC_List_WiFi), }, #endif + +#ifdef RTE_CMSIS_DV_GPIO /* GPIO test group */ +{ + __FILE__, __DATE__, __TIME__, + "CMSIS-Driver_Validation v" RTE_CMSIS_DV_PACK_VER " CMSIS-Driver GPIO Test Report", + NULL, + NULL, + TC_List_GPIO, + ARRAY_SIZE (TC_List_GPIO), +}, +#endif }; /* Number of test groups in suite */ diff --git a/gen_pack.sh b/gen_pack.sh index 13d4c94..1352df8 100755 --- a/gen_pack.sh +++ b/gen_pack.sh @@ -46,6 +46,7 @@ PACKCHK_ARGS=() # Specify additional dependencies for packchk PACKCHK_DEPS=" + ARM.CMSIS.pdsc Keil.STM32F2xx_DFP.pdsc Keil.STM32F4xx_DFP.pdsc Keil.STM32F7xx_DFP.pdsc