Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions TESTS/mbed_hal/gpio/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/* mbed Microcontroller Library
* Copyright (c) 2019 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "utest/utest.h"
#include "unity/unity.h"
#include "greentea-client/test_env.h"

using namespace utest::v1;

#include "PinNames.h"
#include "gpio_api.h"

static void gpio_nc_test()
{
gpio_t nc_obj;
gpio_init(&nc_obj, NC);
TEST_ASSERT_FALSE(gpio_is_connected(&nc_obj));

gpio_t led_obj;
gpio_init(&led_obj, LED1);
if (LED1 == NC) {
TEST_ASSERT_FALSE(gpio_is_connected(&led_obj));
} else {
TEST_ASSERT_TRUE(gpio_is_connected(&led_obj));
}
}

Case cases[] = {
Case("gpio NC test", gpio_nc_test)
};

utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
{
GREENTEA_SETUP(20, "default_auto");
return greentea_test_setup_handler(number_of_cases);
}

Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);

int main()
{
Harness::run(specification);
}
38 changes: 25 additions & 13 deletions hal/gpio_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@ extern "C" {

/**
* \defgroup hal_gpio GPIO HAL functions
*
* # Defined behavior
* * ::gpio_init and other init functions can be called with NC or a valid PinName for the target - Verified by ::gpio_nc_test
* * ::gpio_is_connected can be used to test whether a gpio_t object was initialized with NC - Verified by ::gpio_nc_test
*
* # Undefined behavior
* * Calling any ::gpio_mode, ::gpio_dir, ::gpio_write or ::gpio_read on a gpio_t object that was initialized
* with NC.
* * Calling ::gpio_set with NC.
*
* @{
*/

Expand All @@ -38,43 +48,45 @@ extern "C" {
* @return The GPIO port mask for this pin
**/
uint32_t gpio_set(PinName pin);
/* Checks if gpio object is connected (pin was not initialized with NC)
* @param pin The pin to be set as GPIO
* @return 0 if port is initialized with NC

/** Checks if gpio object is connected (pin was not initialized with NC)
* @param obj The GPIO object
* @return 0 if object was initialized with NC
* @return non-zero if object was initialized with a valid PinName
**/
int gpio_is_connected(const gpio_t *obj);

/** Initialize the GPIO pin
*
* @param obj The GPIO object to initialize
* @param pin The GPIO pin to initialize
* @param pin The GPIO pin to initialize (may be NC)
*/
void gpio_init(gpio_t *obj, PinName pin);

/** Set the input pin mode
*
* @param obj The GPIO object
* @param obj The GPIO object (must be connected)
* @param mode The pin mode to be set
*/
void gpio_mode(gpio_t *obj, PinMode mode);

/** Set the pin direction
*
* @param obj The GPIO object
* @param obj The GPIO object (must be connected)
* @param direction The pin direction to be set
*/
void gpio_dir(gpio_t *obj, PinDirection direction);

/** Set the output value
*
* @param obj The GPIO object
* @param obj The GPIO object (must be connected)
* @param value The value to be set
*/
void gpio_write(gpio_t *obj, int value);

/** Read the input value
*
* @param obj The GPIO object
* @param obj The GPIO object (must be connected)
* @return An integer value 1 or 0
*/
int gpio_read(gpio_t *obj);
Expand All @@ -85,38 +97,38 @@ int gpio_read(gpio_t *obj);
/** Init the input pin and set mode to PullDefault
*
* @param gpio The GPIO object
* @param pin The pin name
* @param pin The pin name (may be NC)
*/
void gpio_init_in(gpio_t *gpio, PinName pin);

/** Init the input pin and set the mode
*
* @param gpio The GPIO object
* @param pin The pin name
* @param pin The pin name (may be NC)
* @param mode The pin mode to be set
*/
void gpio_init_in_ex(gpio_t *gpio, PinName pin, PinMode mode);

/** Init the output pin as an output, with predefined output value 0
*
* @param gpio The GPIO object
* @param pin The pin name
* @param pin The pin name (may be NC)
* @return An integer value 1 or 0
*/
void gpio_init_out(gpio_t *gpio, PinName pin);

/** Init the pin as an output and set the output value
*
* @param gpio The GPIO object
* @param pin The pin name
* @param pin The pin name (may be NC)
* @param value The value to be set
*/
void gpio_init_out_ex(gpio_t *gpio, PinName pin, int value);

/** Init the pin to be in/out
*
* @param gpio The GPIO object
* @param pin The pin name
* @param pin The pin name (may be NC)
* @param direction The pin direction to be set
* @param mode The pin mode to be set
* @param value The value to be set for an output pin
Expand Down
2 changes: 1 addition & 1 deletion targets/TARGET_ARM_FM/TARGET_FVP_MPS2/gpio_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ uint32_t gpio_set(PinName pin)
// with the object created for the pin
void gpio_init(gpio_t *obj, PinName pin)
{
obj->pin = pin;
if (pin == NC) {
return;
} else {
int pin_value = 0;
obj->pin = pin;
if (pin <= 15) {
pin_value = pin;
} else if (pin >= 16 && pin <= 31) {
Expand Down
7 changes: 7 additions & 0 deletions targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/gpio_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,13 @@ void gpio_init(gpio_t *obj, PinName pin)
{
struct arm_gpio_dev_t *gpio_dev;

if (pin == NC) {
obj->pin_number = NC;
obj->gpio_dev = NULL;
obj->mps2_io_dev = NULL;
return;
}

if (pin >= EXP0 && pin <= EXP51) {
/* GPIO pins */
switch (GPIO_DEV_NUMBER(pin)) {
Expand Down
2 changes: 1 addition & 1 deletion targets/TARGET_ARM_SSG/TARGET_IOTSS/gpio_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ uint32_t gpio_set(PinName pin) {
// this links the board control bits for each pin
// with the object created for the pin
void gpio_init(gpio_t *obj, PinName pin) {
obj->pin = pin;
if(pin == NC){ return;}
else {
int pin_value = 0;
obj->pin = pin;
if(pin <=15){
pin_value = pin;
}else if (pin >= 16 && pin <= 31){
Expand Down
1 change: 0 additions & 1 deletion targets/TARGET_Atmel/TARGET_SAM_CortexM0P/gpio_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ uint32_t gpio_set(PinName pin)

void gpio_init(gpio_t *obj, PinName pin)
{
MBED_ASSERT(pin != (PinName)NC);
struct port_config pin_conf;
PortGroup *const port_base = (PortGroup*)port_get_group_from_gpio_pin(pin);

Expand Down
4 changes: 3 additions & 1 deletion targets/TARGET_Atmel/TARGET_SAM_CortexM4/gpio_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,15 @@ uint32_t gpio_set(PinName pin)

void gpio_init(gpio_t *obj, PinName pin)
{
MBED_ASSERT(pin != (PinName)NC);
if (g_sys_init == 0) {
sysclk_init();
system_board_init();
g_sys_init = 1;
}
obj->pin = pin;
if (pin == NC) {
return;
}

ioport_set_pin_dir(pin, IOPORT_DIR_INPUT);
ioport_set_pin_mode(pin, IOPORT_MODE_PULLUP);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,11 @@ void gpio_init(gpio_t *obj, PinName pin)
{
uint32_t pin_name;

obj->pin = pin;

if (pin == (PinName)NC)
return;

obj->pin = pin;
obj->mode = PullNone;
obj->direction = PIN_INPUT;
pin_name = gpio_set(pin); // get the IP pin name
Expand Down
8 changes: 5 additions & 3 deletions targets/TARGET_TT/TARGET_TT_M3HQ/gpio_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@ void gpio_init(gpio_t *obj, PinName pin)
{
// Store above pin mask, pin name into GPIO object
obj->pin = pin;
obj->mask = gpio_set(pin);
obj->port = (PortName) (pin >> 3);
TSB_CG->FSYSENA |= (1<<(obj->port));
if (pin != NC) {
obj->mask = gpio_set(pin);
obj->port = (PortName) (pin >> 3);
TSB_CG->FSYSENA |= (1<<(obj->port));
}
}

void gpio_mode(gpio_t *obj, PinMode mode)
Expand Down
12 changes: 7 additions & 5 deletions targets/TARGET_TT/TARGET_TT_M4G9/gpio_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,13 @@ void gpio_init(gpio_t *obj, PinName pin)
{
// Store above pin mask, pin name into GPIO object
obj->pin = pin;
obj->pin_num = PIN_POS(pin);
obj->mask = gpio_set(pin);
obj->port = (PortName) PIN_PORT(pin);
//Enable clock for particular port
TSB_CG->FSYSMENB |= (1 << ((obj->port) + 2));
if (pin != NC) {
obj->pin_num = PIN_POS(pin);
obj->mask = gpio_set(pin);
obj->port = (PortName) PIN_PORT(pin);
//Enable clock for particular port
TSB_CG->FSYSMENB |= (1 << ((obj->port) + 2));
}
}

void gpio_mode(gpio_t *obj, PinMode mode)
Expand Down
2 changes: 1 addition & 1 deletion targets/TARGET_WIZNET/TARGET_W7500x/gpio_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,13 @@ uint32_t gpio_set(PinName pin)

void gpio_init(gpio_t *obj, PinName pin)
{
obj->pin = pin;
if (pin == (PinName)NC) {
return;
}

obj->port_num = WIZ_PORT(pin);
obj->pin_index = WIZ_PIN_INDEX(pin);
obj->pin = pin;
GPIO_TypeDef *gpio = (GPIO_TypeDef *)Get_GPIO_BaseAddress(obj->port_num);
obj->reg_data_in = &gpio->DATA;
}
Expand Down
2 changes: 1 addition & 1 deletion targets/TARGET_ublox/TARGET_HI2110/gpio_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@

void gpio_init(gpio_t *obj, PinName pin)
{
obj->pin = pin;
if (pin == (PinName)NC) {
return;
}

MBED_ASSERT (pin < NUM_PINS);

obj->pin = pin;
obj->mask = (1ul << pin);

obj->reg_set = &GPIO_OUT_BITSET;
Expand Down