Skip to content

Add a gpio-irq pinmap #11074

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 29, 2019
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
4 changes: 4 additions & 0 deletions TESTS/mbed_hal/pinmap/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
using namespace utest::v1;

#include "gpio_api.h"
#include "gpio_irq_api.h"
#include "analogin_api.h"
#include "analogout_api.h"
#include "can_api.h"
Expand All @@ -40,6 +41,9 @@ typedef struct {

const pinmap_info_t pinmap_functions[] = {
PINMAP_TEST_ENTRY(gpio_pinmap),
#if DEVICE_INTERRUPTIN
PINMAP_TEST_ENTRY(gpio_irq_pinmap),
#endif
#if DEVICE_ANALOGIN
PINMAP_TEST_ENTRY(analogin_pinmap),
#endif
Expand Down
65 changes: 23 additions & 42 deletions TESTS/mbed_hal_fpga_ci_test_shield/gpio_irq/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,32 +30,38 @@

using namespace utest::v1;

#include "mbed.h"
#include "MbedTester.h"
#include "pinmap.h"
#include "test_utils.h"

MbedTester tester(DefaultFormFactor::pins(), DefaultFormFactor::restricted_pins());

static uint32_t call_counter;
static volatile uint32_t call_counter;
void test_gpio_irq_handler(uint32_t id, gpio_irq_event event)
{
call_counter++;
}

const PinList *form_factor = pinmap_ff_default_pins();
const PinList *restricted = pinmap_restricted_pins();
MbedTester tester(form_factor, restricted);

#define WAIT() wait_us(10)


void gpio_irq_test(PinName pin)
{
// Reset everything and set all tester pins to hi-Z.
tester.reset();

// Map pins for test.
tester.pin_map_set(pin, MbedTester::LogicalPinGPIO0);

// Select GPIO0.
tester.select_peripheral(MbedTester::PeripheralGPIO);

gpio_t gpio;
// configure pin as input
gpio_init_in(&gpio, pin);

gpio_irq_t gpio_irq;
uint32_t id = 123;
gpio_irq_init(&gpio_irq, pin, test_gpio_irq_handler, id);
TEST_ASSERT_EQUAL(0, gpio_irq_init(&gpio_irq, pin, test_gpio_irq_handler, id));

gpio_irq_set(&gpio_irq, IRQ_RISE, true);
gpio_irq_enable(&gpio_irq);
Expand Down Expand Up @@ -241,51 +247,26 @@ void gpio_irq_test(PinName pin)
WAIT();
TEST_ASSERT_EQUAL(2, call_counter);


gpio_irq_free(&gpio_irq);
}


void gpio_irq_test()
{
for (uint32_t i = 0; i < form_factor->count; i++) {
const PinName test_pin = form_factor->pins[i];
if (test_pin == NC) {
continue;
}
if (pinmap_list_has_pin(restricted, test_pin)) {
printf("Skipping gpio pin %s (%i)\r\n", pinmap_ff_default_pin_to_string(test_pin), test_pin);
continue;
}
tester.pin_map_reset();
tester.pin_map_set(test_pin, MbedTester::LogicalPinGPIO0);

printf("GPIO irq test on pin %3s (%3i)\r\n", pinmap_ff_default_pin_to_string(test_pin), test_pin);
gpio_irq_test(test_pin);
}
}

utest::v1::status_t setup(const Case *const source, const size_t index_of_case)
{
tester.reset();
tester.select_peripheral(MbedTester::PeripheralGPIO);

return greentea_case_setup_handler(source, index_of_case);
}

utest::v1::status_t teardown(const Case *const source, const size_t passed, const size_t failed,
const failure_t reason)
void init_free_test(PinName pin)
{
return greentea_case_teardown_handler(source, passed, failed, reason);
gpio_t gpio;
gpio_irq_t gpio_irq;
gpio_init_in(&gpio, pin);
TEST_ASSERT_EQUAL(0, gpio_irq_init(&gpio_irq, pin, test_gpio_irq_handler, 123));
gpio_irq_free(&gpio_irq);
}

Case cases[] = {
Case("GPIO - irq test", setup, gpio_irq_test, teardown)
Case("init/free", all_ports<GPIOIRQPort, DefaultFormFactor, init_free_test>),
Case("rising & falling edge", all_ports<GPIOIRQPort, DefaultFormFactor, gpio_irq_test>),
};

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

Expand Down
13 changes: 13 additions & 0 deletions components/testing/COMPONENT_FPGA_CI_TEST_SHIELD/test_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,19 @@ const char *const GPIOMaps::pin_type_names[] = { "IO" };
const char *const GPIOMaps::name = "GPIO";
typedef Port<1, GPIOMaps, DefaultFormFactor, TF1> GPIOPort;

#if DEVICE_INTERRUPTIN
#include "gpio_irq_api.h"
struct GPIOIRQMaps {
static const PinMap *maps[];
static const char *const pin_type_names[];
static const char *const name;
};
const PinMap *GPIOIRQMaps::maps[] = { gpio_irq_pinmap() };
const char *const GPIOIRQMaps::pin_type_names[] = { "IRQ_IN" };
const char *const GPIOIRQMaps::name = "GPIO_IRQ";
typedef Port<1, GPIOIRQMaps, DefaultFormFactor, TF1> GPIOIRQPort;
#endif

#if DEVICE_SPI
#include "spi_api.h"
struct SPIMaps {
Expand Down
13 changes: 13 additions & 0 deletions hal/gpio_irq_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#define MBED_GPIO_IRQ_API_H

#include "device.h"
#include "pinmap.h"

#if DEVICE_INTERRUPTIN

Expand Down Expand Up @@ -85,6 +86,18 @@ void gpio_irq_enable(gpio_irq_t *obj);
*/
void gpio_irq_disable(gpio_irq_t *obj);

/** Get the pins that support all GPIO IRQ tests
*
* Return a PinMap array of pins that support GPIO IRQ.
* The array is terminated with {NC, NC, 0}.
*
* Targets should override the weak implementation of this
* function to provide the actual pinmap for GPIO IRQ testing.
*
* @return PinMap array
*/
const PinMap *gpio_irq_pinmap(void);

/**@}*/

#ifdef __cplusplus
Expand Down
31 changes: 31 additions & 0 deletions hal/mbed_gpio_irq.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* 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 "hal/gpio_irq_api.h"

#if DEVICE_INTERRUPTIN

#include "platform/mbed_toolchain.h"
#include "hal/gpio_api.h"

MBED_WEAK const PinMap *gpio_irq_pinmap()
{
// Targets should override this weak implementation to provide correct data.
// By default, this is exactly the same as GPIO PinMap.
return gpio_pinmap();
}

#endif
4 changes: 2 additions & 2 deletions targets/TARGET_Cypress/TARGET_PSOC6_FUTURE/gpio_irq_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ static void gpio_irq_dispatcher(uint32_t port_id)
MBED_ASSERT(obj);
Cy_GPIO_ClearInterrupt(port, pin);
event = (obj->mode == IRQ_FALL)? IRQ_FALL : IRQ_RISE;
obj->handler(obj->id_arg, event);
((gpio_irq_handler) obj->handler)(obj->id_arg, event);
}
}
}
Expand Down Expand Up @@ -202,7 +202,7 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
MBED_ASSERT("Invalid pin ID!");
return (-1);
}
obj->handler = handler;
obj->handler = (uint32_t) handler;
obj->id_arg = id;
return gpio_irq_setup_channel(obj);
} else {
Expand Down
5 changes: 2 additions & 3 deletions targets/TARGET_Cypress/TARGET_PSOC6_FUTURE/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
#include "PinNames.h"
#include "PortNames.h"

#include "gpio_irq_api.h"
#include "gpio_object.h"
#include "cy_sysclk.h"
#include "cy_syspm.h"
Expand All @@ -37,8 +36,8 @@ struct gpio_irq_s {
GPIO_PRT_Type* port;
uint32_t port_id;
uint32_t pin;
gpio_irq_event mode;
gpio_irq_handler handler;
uint32_t mode;
uint32_t handler;
uint32_t id_arg;
#if defined (TARGET_MCU_PSOC6_M0)
cy_en_intr_t cm0p_irq_src;
Expand Down