Add gpio event driver
This commit is contained in:
parent
85e960e612
commit
df0e302bf8
77
src/platform/nrf52/gpiote.cc
Normal file
77
src/platform/nrf52/gpiote.cc
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include "platform/nrf52/InterruptHandler.h"
|
||||||
|
#include "platform/nrf52/InterruptGuardian.h"
|
||||||
|
|
||||||
|
#include "platform/nrf52/gpiote.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "nrf52.h"
|
||||||
|
#include "nrf52_bitfields.h"
|
||||||
|
|
||||||
|
NRF_GPIOTE_Type *const GPIOTE_REGS = reinterpret_cast<NRF_GPIOTE_Type *>(NRF_GPIOTE_BASE);
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace pinetime::platform::nrf52;
|
||||||
|
|
||||||
|
Gpiote::Gpiote()
|
||||||
|
: InterruptHandler(InterruptGuardian::Nrf52IrqN::GPIOTE_IRQ)
|
||||||
|
, num_registered(0)
|
||||||
|
{
|
||||||
|
for(auto it = this->gpiote_channels.begin(); it != this->gpiote_channels.end(); ++it) {
|
||||||
|
*it = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gpiote::enable()
|
||||||
|
{
|
||||||
|
NVIC_SetPriority(GPIOTE_IRQn, 7);
|
||||||
|
NVIC_EnableIRQ(GPIOTE_IRQn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gpiote::disable()
|
||||||
|
{
|
||||||
|
NVIC_DisableIRQ(GPIOTE_IRQn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gpiote::register_handler(pinetime::interfaces::GpioInterface *gpio)
|
||||||
|
{
|
||||||
|
if(num_registered == GPIOTE_CHANNELS) {
|
||||||
|
//FIXME: Error notification
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(num_registered == 0) {
|
||||||
|
this->enable();
|
||||||
|
} else {
|
||||||
|
//check if gpio already registered
|
||||||
|
for(auto it = this->gpiote_channels.begin(); it != this->gpiote_channels.end(); ++it) {
|
||||||
|
if(*it == gpio) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uint32_t i = 0;
|
||||||
|
for(auto it = this->gpiote_channels.begin(); it != this->gpiote_channels.end(); ++it) {
|
||||||
|
if(*it == nullptr) {
|
||||||
|
*it = gpio;
|
||||||
|
GPIOTE_REGS->INTENSET = GPIOTE_INTENSET_IN0_Msk;
|
||||||
|
GPIOTE_REGS->CONFIG[i] = (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos)
|
||||||
|
| ((gpio->pin_number()) << GPIOTE_CONFIG_PSEL_Pos)
|
||||||
|
| (GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gpiote::handle()
|
||||||
|
{
|
||||||
|
for(uint32_t i = 0; i < GPIOTE_CHANNELS; ++i) {
|
||||||
|
if(GPIOTE_REGS->EVENTS_IN[i] != 0) {
|
||||||
|
GPIOTE_REGS->EVENTS_IN[i] = 0;
|
||||||
|
pinetime::interfaces::GpioInterface *h = this->gpiote_channels[i];
|
||||||
|
assert(h != nullptr);
|
||||||
|
h->handle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
44
src/platform/nrf52/gpiote.h
Normal file
44
src/platform/nrf52/gpiote.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#ifndef __PLATFORM_NRF52_GPIOTE_H__
|
||||||
|
#define __PLATFORM_NRF52_GPIOTE_H__
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
#include "gpio_interface.h"
|
||||||
|
#include "platform/nrf52/InterruptHandler.h"
|
||||||
|
|
||||||
|
namespace pinetime::platform::nrf52
|
||||||
|
{
|
||||||
|
class Gpiote;
|
||||||
|
}
|
||||||
|
extern pinetime::platform::nrf52::Gpiote gpiote;
|
||||||
|
|
||||||
|
namespace pinetime::platform::nrf52
|
||||||
|
{
|
||||||
|
|
||||||
|
class Gpiote
|
||||||
|
: public pinetime::platform::nrf52::InterruptHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Gpiote();
|
||||||
|
|
||||||
|
static inline Gpiote & instance() { return gpiote; }
|
||||||
|
|
||||||
|
void enable() override;
|
||||||
|
void disable() override;
|
||||||
|
|
||||||
|
void register_handler(pinetime::interfaces::GpioInterface *);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void handle() override;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
GPIOTE_CHANNELS = 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
std::array<pinetime::interfaces::GpioInterface *, GPIOTE_CHANNELS> gpiote_channels;
|
||||||
|
uint32_t num_registered;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -54,3 +54,13 @@ void SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler(void)
|
|||||||
|
|
||||||
h->handle();
|
h->handle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GPIOTE_IRQHandler(void)
|
||||||
|
{
|
||||||
|
uint32_t irq_nr = InterruptGuardian::Nrf52IrqN::GPIOTE_IRQ;
|
||||||
|
InterruptHandler *h = InterruptGuardian::instance.nrf52_vector[irq_nr];
|
||||||
|
|
||||||
|
assert(h != nullptr);
|
||||||
|
|
||||||
|
h->handle();
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user