mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-21 18:06:50 +00:00
parent
433f859cb9
commit
98da445269
@ -49,6 +49,9 @@ struct Genode::Board_base
|
|||||||
IRQ_CONTROLLER_BASE = 0x2000b200,
|
IRQ_CONTROLLER_BASE = 0x2000b200,
|
||||||
IRQ_CONTROLLER_SIZE = 0x100,
|
IRQ_CONTROLLER_SIZE = 0x100,
|
||||||
|
|
||||||
|
GPIO_CONTROLLER_BASE = 0x20200000,
|
||||||
|
GPIO_CONTROLLER_SIZE = 0x1000,
|
||||||
|
|
||||||
USB_DWC_OTG_BASE = 0x20980000,
|
USB_DWC_OTG_BASE = 0x20980000,
|
||||||
USB_DWC_OTG_SIZE = 0x20000,
|
USB_DWC_OTG_SIZE = 0x20000,
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
# denote wich specs are also fullfilled by this spec
|
# denote wich specs are also fullfilled by this spec
|
||||||
SPECS += arm_v6 usb framebuffer
|
SPECS += arm_v6 usb framebuffer gpio
|
||||||
|
|
||||||
# add repository relative include paths
|
# add repository relative include paths
|
||||||
REP_INC_DIR += include/platform/rpi
|
REP_INC_DIR += include/platform/rpi
|
||||||
|
2
repos/os/lib/mk/foc_rpi/gpio.mk
Normal file
2
repos/os/lib/mk/foc_rpi/gpio.mk
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
INC_DIR += $(REP_DIR)/src/drivers/gpio/rpi/foc
|
||||||
|
include $(REP_DIR)/lib/mk/rpi/gpio.inc
|
2
repos/os/lib/mk/hw_rpi/gpio.mk
Normal file
2
repos/os/lib/mk/hw_rpi/gpio.mk
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
INC_DIR += $(REP_DIR)/src/drivers/gpio/rpi/hw
|
||||||
|
include $(REP_DIR)/lib/mk/rpi/gpio.inc
|
5
repos/os/lib/mk/rpi/gpio.inc
Normal file
5
repos/os/lib/mk/rpi/gpio.inc
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
SRC_CC += main.cc
|
||||||
|
LIBS += base config server
|
||||||
|
INC_DIR += $(REP_DIR)/src/drivers/gpio/rpi
|
||||||
|
|
||||||
|
vpath % $(REP_DIR)/src/drivers/gpio/rpi
|
207
repos/os/src/drivers/gpio/rpi/driver.h
Normal file
207
repos/os/src/drivers/gpio/rpi/driver.h
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
/*
|
||||||
|
* \brief Gpio driver for the RaspberryPI
|
||||||
|
* \author Reinier Millo Sánchez <rmillo@uclv.cu>
|
||||||
|
* \author Alexy Gallardo Segura <alexy@uclv.cu>
|
||||||
|
* \author Humberto Lopéz Leon <humberto@uclv.cu>
|
||||||
|
* \date 2015-07-23
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2012 Ksys Labs LLC
|
||||||
|
* Copyright (C) 2012-2015 Genode Labs GmbH
|
||||||
|
*
|
||||||
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
|
* under the terms of the GNU General Public License version 2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _DRIVER_H_
|
||||||
|
#define _DRIVER_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <base/printf.h>
|
||||||
|
#include <drivers/board_base.h>
|
||||||
|
#include <gpio/driver.h>
|
||||||
|
#include <irq_session/connection.h>
|
||||||
|
|
||||||
|
/* local includes */
|
||||||
|
#include <irq.h>
|
||||||
|
#include <gpio.h>
|
||||||
|
|
||||||
|
static int verbose = 1;
|
||||||
|
|
||||||
|
namespace Gpio { class Rpi_driver; }
|
||||||
|
|
||||||
|
class Gpio::Rpi_driver : public Driver
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
enum { MAX_PINS = 54 };
|
||||||
|
|
||||||
|
Server::Entrypoint &_ep;
|
||||||
|
Reg _reg;
|
||||||
|
Genode::Irq_connection _irq;
|
||||||
|
Genode::Signal_rpc_member<Rpi_driver> _dispatcher;
|
||||||
|
Genode::Signal_context_capability _sig_cap[MAX_PINS];
|
||||||
|
bool _irq_enabled[MAX_PINS];
|
||||||
|
bool _async;
|
||||||
|
|
||||||
|
void _handle(unsigned)
|
||||||
|
{
|
||||||
|
_reg.for_each_gpio_status([&] (unsigned i, bool s) {
|
||||||
|
if (!s || !_irq_enabled[i] || !_sig_cap[i].valid()) { return; }
|
||||||
|
Genode::Signal_transmitter(_sig_cap[i]).submit();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Rpi_driver(Server::Entrypoint &ep)
|
||||||
|
:
|
||||||
|
_ep(ep),
|
||||||
|
_reg(Genode::Board_base::GPIO_CONTROLLER_BASE,
|
||||||
|
0, Genode::Board_base::GPIO_CONTROLLER_SIZE),
|
||||||
|
_irq(IRQ),
|
||||||
|
_dispatcher(ep,*this,&Rpi_driver::_handle),
|
||||||
|
_async(false)
|
||||||
|
{
|
||||||
|
_irq.sigh(_dispatcher);
|
||||||
|
_irq.ack_irq();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _invalid_gpio(unsigned gpio) {
|
||||||
|
PERR("invalid GPIO pin number %u", gpio); }
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void set_async_events(bool async) { _async = async; }
|
||||||
|
|
||||||
|
void set_func(unsigned gpio, Reg::Function function)
|
||||||
|
{
|
||||||
|
if (verbose) PDBG("gpio=%d function=%d", gpio, function);
|
||||||
|
|
||||||
|
_reg.set_gpio_function(gpio, function);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Rpi_driver& factory(Server::Entrypoint &ep);
|
||||||
|
|
||||||
|
|
||||||
|
/******************************
|
||||||
|
** Driver interface **
|
||||||
|
******************************/
|
||||||
|
|
||||||
|
bool gpio_valid(unsigned gpio) { return gpio < MAX_PINS; }
|
||||||
|
|
||||||
|
void direction(unsigned gpio, bool input)
|
||||||
|
{
|
||||||
|
if (!gpio_valid(gpio)) { _invalid_gpio(gpio); return; }
|
||||||
|
if (verbose) PDBG("gpio=%d input=%d", gpio, input);
|
||||||
|
Reg::Function f = input ? Reg::FSEL_INPUT : Reg::FSEL_OUTPUT;
|
||||||
|
_reg.set_gpio_function(gpio, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void write(unsigned gpio, bool level)
|
||||||
|
{
|
||||||
|
if (!gpio_valid(gpio)) { _invalid_gpio(gpio); return; }
|
||||||
|
if (verbose) PDBG("gpio=%d level=%d", gpio, level);
|
||||||
|
|
||||||
|
if (_reg.get_gpio_function(gpio)!=Reg::FSEL_OUTPUT)
|
||||||
|
PWRN("GPIO pin (%d) is not configured for output.", gpio);
|
||||||
|
|
||||||
|
if (level)
|
||||||
|
_reg.set_gpio_level(gpio);
|
||||||
|
else
|
||||||
|
_reg.clear_gpio_level(gpio);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool read(unsigned gpio)
|
||||||
|
{
|
||||||
|
if (!gpio_valid(gpio)) { _invalid_gpio(gpio); return 0; }
|
||||||
|
if(_reg.get_gpio_function(gpio) != Reg::FSEL_INPUT)
|
||||||
|
PWRN("GPIO pin (%d) is not configured for input.", gpio);
|
||||||
|
|
||||||
|
return _reg.get_gpio_level(gpio);
|
||||||
|
}
|
||||||
|
|
||||||
|
void debounce_enable(unsigned, bool) { PWRN("Not supported!"); }
|
||||||
|
void debounce_time(unsigned, unsigned long) { PWRN("Not supported!"); }
|
||||||
|
|
||||||
|
void falling_detect(unsigned gpio)
|
||||||
|
{
|
||||||
|
if (!gpio_valid(gpio)) { _invalid_gpio(gpio); return; }
|
||||||
|
if (verbose) PDBG("gpio=%d", gpio);
|
||||||
|
|
||||||
|
if(_async)
|
||||||
|
_reg.set_gpio_async_falling_detect(gpio);
|
||||||
|
else
|
||||||
|
_reg.set_gpio_falling_detect(gpio);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rising_detect(unsigned gpio)
|
||||||
|
{
|
||||||
|
if (!gpio_valid(gpio)) { _invalid_gpio(gpio); return; }
|
||||||
|
if (verbose) PDBG("gpio=%d", gpio);
|
||||||
|
|
||||||
|
if(_async)
|
||||||
|
_reg.set_gpio_async_rising_detect(gpio);
|
||||||
|
else
|
||||||
|
_reg.set_gpio_rising_detect(gpio);
|
||||||
|
}
|
||||||
|
|
||||||
|
void high_detect(unsigned gpio)
|
||||||
|
{
|
||||||
|
if (!gpio_valid(gpio)) { _invalid_gpio(gpio); return; }
|
||||||
|
if (verbose) PDBG("gpio=%d", gpio);
|
||||||
|
|
||||||
|
_reg.set_gpio_high_detect(gpio);
|
||||||
|
}
|
||||||
|
|
||||||
|
void low_detect(unsigned gpio)
|
||||||
|
{
|
||||||
|
if (!gpio_valid(gpio)) { _invalid_gpio(gpio); return; }
|
||||||
|
if (verbose) PDBG("gpio=%d", gpio);
|
||||||
|
|
||||||
|
_reg.set_gpio_low_detect(gpio);
|
||||||
|
}
|
||||||
|
|
||||||
|
void irq_enable(unsigned gpio, bool enable)
|
||||||
|
{
|
||||||
|
if (!gpio_valid(gpio)) { _invalid_gpio(gpio); return; }
|
||||||
|
if (verbose) PDBG("gpio=%d enable=%d", gpio, enable);
|
||||||
|
|
||||||
|
_irq_enabled[gpio] = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ack_irq(unsigned gpio)
|
||||||
|
{
|
||||||
|
if (!gpio_valid(gpio)) { _invalid_gpio(gpio); return; }
|
||||||
|
if (verbose) PDBG("gpio=%d", gpio);
|
||||||
|
|
||||||
|
_reg.clear_event(gpio);
|
||||||
|
_irq.ack_irq();
|
||||||
|
}
|
||||||
|
|
||||||
|
void register_signal(unsigned gpio,
|
||||||
|
Genode::Signal_context_capability cap)
|
||||||
|
{
|
||||||
|
if (!gpio_valid(gpio)) { _invalid_gpio(gpio); return; }
|
||||||
|
if (verbose) PDBG("gpio=%d", gpio);
|
||||||
|
|
||||||
|
_sig_cap[gpio] = cap;
|
||||||
|
}
|
||||||
|
|
||||||
|
void unregister_signal(unsigned gpio)
|
||||||
|
{
|
||||||
|
if (!gpio_valid(gpio)) { _invalid_gpio(gpio); return; }
|
||||||
|
if (verbose) PDBG("gpio=%d", gpio);
|
||||||
|
Genode::Signal_context_capability cap;
|
||||||
|
|
||||||
|
_sig_cap[gpio] = cap;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Gpio::Rpi_driver& Gpio::Rpi_driver::factory(Server::Entrypoint &ep)
|
||||||
|
{
|
||||||
|
static Rpi_driver driver(ep);
|
||||||
|
return driver;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _DRIVER_H_ */
|
25
repos/os/src/drivers/gpio/rpi/foc/irq.h
Normal file
25
repos/os/src/drivers/gpio/rpi/foc/irq.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* \brief GPIO interrupt number
|
||||||
|
* \author Reinier Millo Sánchez <rmillo@uclv.cu>
|
||||||
|
* \date 2015-07-27
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Genode Labs GmbH
|
||||||
|
*
|
||||||
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
|
* under the terms of the GNU General Public License version 2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _IRQ_H_
|
||||||
|
#define _IRQ_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <drivers/board_base.h>
|
||||||
|
|
||||||
|
namespace Gpio
|
||||||
|
{
|
||||||
|
enum { IRQ = 49 };
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _IRQ_H_ */
|
238
repos/os/src/drivers/gpio/rpi/gpio.h
Normal file
238
repos/os/src/drivers/gpio/rpi/gpio.h
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
/*
|
||||||
|
* \brief Gpio driver for the RaspberryPI
|
||||||
|
* \author Reinier Millo Sánchez <rmillo@uclv.cu>
|
||||||
|
* \author Alexy Gallardo Segura <alexy@uclv.cu>
|
||||||
|
* \author Humberto Lopéz Leon <humberto@uclv.cu>
|
||||||
|
* \date 2015-07-23
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2012 Ksys Labs LLC
|
||||||
|
* Copyright (C) 2012-2015 Genode Labs GmbH
|
||||||
|
*
|
||||||
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
|
* under the terms of the GNU General Public License version 2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _GPIO_H_
|
||||||
|
#define _GPIO_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <base/printf.h>
|
||||||
|
#include <os/attached_io_mem_dataspace.h>
|
||||||
|
#include <util/mmio.h>
|
||||||
|
#include <timer_session/connection.h>
|
||||||
|
|
||||||
|
namespace Gpio {
|
||||||
|
|
||||||
|
using namespace Genode;
|
||||||
|
|
||||||
|
class Reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Gpio::Reg : Attached_io_mem_dataspace, Mmio
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GPIO Function Select Registers
|
||||||
|
*/
|
||||||
|
struct Gpfsel : Register_array <0x00,32,6,32> {
|
||||||
|
struct Sel0 : Bitfield <0,3> {};
|
||||||
|
struct Sel1 : Bitfield <3,3> {};
|
||||||
|
struct Sel2 : Bitfield <6,3> {};
|
||||||
|
struct Sel3 : Bitfield <9,3> {};
|
||||||
|
struct Sel4 : Bitfield <12,3> {};
|
||||||
|
struct Sel5 : Bitfield <15,3> {};
|
||||||
|
struct Sel6 : Bitfield <18,3> {};
|
||||||
|
struct Sel7 : Bitfield <21,3> {};
|
||||||
|
struct Sel8 : Bitfield <24,3> {};
|
||||||
|
struct Sel9 : Bitfield <27,3> {};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GPIO Pin Output Set Registers
|
||||||
|
*/
|
||||||
|
struct Gpset : Register_array <0x1c,32,64,1> {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GPIO Pin Output Clear Registers
|
||||||
|
*/
|
||||||
|
struct Gpclr : Register_array <0x28,32,64,1> {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GPIO Pin Level Registers
|
||||||
|
*/
|
||||||
|
struct Gplev : Register_array <0x34,32,64,1> {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GPIO Pin Event Detect Status Registers
|
||||||
|
*/
|
||||||
|
struct Gppeds : Register_array <0x40,32,64,1> {};
|
||||||
|
struct Gppeds_raw : Register <0x40,64> {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GPIO Pin Rising Edge Detect Enable Registers
|
||||||
|
*/
|
||||||
|
struct Gpren : Register_array <0x4c,32,64,1> {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GPIO Pin Falling Edge Detect Enable Registers
|
||||||
|
*/
|
||||||
|
struct Gpfen : Register_array <0x58,32,64,1> {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GPIO Pin High Detect Enable Registers
|
||||||
|
*/
|
||||||
|
struct Gphen : Register_array <0x64,32,64,1> {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GPIO Pin Low Detect Enable Registers
|
||||||
|
*/
|
||||||
|
struct Gplen : Register_array <0x70,32,64,1> {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GPIO Pin Aync. Rising Edge Detect Registers
|
||||||
|
*/
|
||||||
|
struct Gparen : Register_array <0x7c,32,64,1> {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GPIO Pin Async. Falling Edge Detect Registers
|
||||||
|
*/
|
||||||
|
struct Gpafen : Register_array <0x88,32,64,1> {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GPIO Pin Pull-up/down Enable Registers
|
||||||
|
*/
|
||||||
|
struct Gppud : Register <0x94,32> {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GPIO Pin Pull-up/down Enable Clock Registers
|
||||||
|
*/
|
||||||
|
struct Gppudclk : Register_array <0x98,32,64,1> {};
|
||||||
|
|
||||||
|
struct Timer_delayer : Timer::Connection, Mmio::Delayer
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Implementation of 'Delayer' interface
|
||||||
|
*/
|
||||||
|
void usleep(unsigned us) { Timer::Connection::usleep(us); }
|
||||||
|
|
||||||
|
} _delayer;
|
||||||
|
|
||||||
|
template <typename T0, typename T1, typename T2,
|
||||||
|
typename T3, typename T4, typename T5>
|
||||||
|
void _set_gpio_det(unsigned gpio)
|
||||||
|
{
|
||||||
|
write<T0>(0, gpio);
|
||||||
|
write<T1>(0, gpio);
|
||||||
|
write<T2>(0, gpio);
|
||||||
|
write<T3>(0, gpio);
|
||||||
|
write<T4>(0, gpio);
|
||||||
|
write<T5>(1, gpio);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Reg(addr_t base, off_t offset, size_t size)
|
||||||
|
:
|
||||||
|
Attached_io_mem_dataspace(base, size),
|
||||||
|
Mmio((addr_t)local_addr<Reg>() + offset)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
enum Function {
|
||||||
|
FSEL_INPUT = 0,
|
||||||
|
FSEL_OUTPUT = 1,
|
||||||
|
FSEL_ALT0 = 4,
|
||||||
|
FSEL_ALT1 = 5,
|
||||||
|
FSEL_ALT2 = 6,
|
||||||
|
FSEL_ALT3 = 7,
|
||||||
|
FSEL_ALT4 = 3,
|
||||||
|
FSEL_ALT5 = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
void set_gpio_function(unsigned gpio, Function function)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Set a pull-up internal resistor in the input pin to avoid
|
||||||
|
* electromagnetic radiation or static noise
|
||||||
|
*/
|
||||||
|
if (function == FSEL_INPUT) {
|
||||||
|
write<Gppud>(1);
|
||||||
|
_delayer.usleep(1);
|
||||||
|
write<Gppudclk>(1, gpio);
|
||||||
|
_delayer.usleep(1);
|
||||||
|
write<Gppud>(0);
|
||||||
|
write<Gppudclk>(0, gpio);
|
||||||
|
}
|
||||||
|
/* set the pin function */
|
||||||
|
unsigned sel_id = gpio % 10;
|
||||||
|
unsigned reg_id = gpio / 10;
|
||||||
|
switch(sel_id){
|
||||||
|
case 0: write<Gpfsel::Sel0>(function, reg_id); break;
|
||||||
|
case 1: write<Gpfsel::Sel1>(function, reg_id); break;
|
||||||
|
case 2: write<Gpfsel::Sel2>(function, reg_id); break;
|
||||||
|
case 3: write<Gpfsel::Sel3>(function, reg_id); break;
|
||||||
|
case 4: write<Gpfsel::Sel4>(function, reg_id); break;
|
||||||
|
case 5: write<Gpfsel::Sel5>(function, reg_id); break;
|
||||||
|
case 6: write<Gpfsel::Sel6>(function, reg_id); break;
|
||||||
|
case 7: write<Gpfsel::Sel7>(function, reg_id); break;
|
||||||
|
case 8: write<Gpfsel::Sel8>(function, reg_id); break;
|
||||||
|
case 9: write<Gpfsel::Sel9>(function, reg_id); break;
|
||||||
|
default:;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned get_gpio_function(unsigned gpio)
|
||||||
|
{
|
||||||
|
unsigned sel_id = gpio % 10;
|
||||||
|
unsigned reg_id = gpio / 10;
|
||||||
|
switch(sel_id){
|
||||||
|
case 0: return read<Gpfsel::Sel0>(reg_id);
|
||||||
|
case 1: return read<Gpfsel::Sel1>(reg_id);
|
||||||
|
case 2: return read<Gpfsel::Sel2>(reg_id);
|
||||||
|
case 3: return read<Gpfsel::Sel3>(reg_id);
|
||||||
|
case 4: return read<Gpfsel::Sel4>(reg_id);
|
||||||
|
case 5: return read<Gpfsel::Sel5>(reg_id);
|
||||||
|
case 6: return read<Gpfsel::Sel6>(reg_id);
|
||||||
|
case 7: return read<Gpfsel::Sel7>(reg_id);
|
||||||
|
case 8: return read<Gpfsel::Sel8>(reg_id);
|
||||||
|
case 9: return read<Gpfsel::Sel9>(reg_id);
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_gpio_level(unsigned gpio) { return read<Gppudclk>(gpio); }
|
||||||
|
void set_gpio_level(unsigned gpio) { write<Gpset>(1, gpio); }
|
||||||
|
void clear_gpio_level(unsigned gpio) { write<Gpclr>(1, gpio); }
|
||||||
|
|
||||||
|
void set_gpio_falling_detect(unsigned gpio) {
|
||||||
|
_set_gpio_det<Gpren, Gphen, Gplen, Gparen, Gpafen, Gpfen>(gpio); }
|
||||||
|
|
||||||
|
void set_gpio_rising_detect(unsigned gpio) {
|
||||||
|
_set_gpio_det<Gphen, Gplen, Gparen, Gpafen, Gpfen, Gpren>(gpio); }
|
||||||
|
|
||||||
|
void set_gpio_high_detect(unsigned gpio) {
|
||||||
|
_set_gpio_det<Gpren, Gplen, Gparen, Gpafen, Gpfen, Gphen>(gpio); }
|
||||||
|
|
||||||
|
void set_gpio_low_detect(unsigned gpio) {
|
||||||
|
_set_gpio_det<Gpren, Gphen, Gparen, Gpafen, Gpfen, Gplen>(gpio); }
|
||||||
|
|
||||||
|
void set_gpio_async_falling_detect(unsigned gpio) {
|
||||||
|
_set_gpio_det<Gpren, Gphen, Gplen, Gparen, Gpfen, Gpafen>(gpio); }
|
||||||
|
|
||||||
|
void set_gpio_async_rising_detect(unsigned gpio) {
|
||||||
|
_set_gpio_det<Gpren, Gphen, Gplen, Gpafen, Gpfen, Gparen>(gpio); }
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
void for_each_gpio_status(F f)
|
||||||
|
{
|
||||||
|
Gppeds_raw::access_t const gppeds = read<Gppeds_raw>();
|
||||||
|
for(unsigned i = 0; i < Gppeds_raw::ACCESS_WIDTH; i++) {
|
||||||
|
f(i, gppeds & (1 << i)); }
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_event(unsigned gpio) { write<Gppeds>(1, gpio); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _GPIO_H_ */
|
25
repos/os/src/drivers/gpio/rpi/hw/irq.h
Normal file
25
repos/os/src/drivers/gpio/rpi/hw/irq.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* \brief GPIO interrupt number
|
||||||
|
* \author Reinier Millo Sánchez <rmillo@uclv.cu>
|
||||||
|
* \date 2015-07-27
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Genode Labs GmbH
|
||||||
|
*
|
||||||
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
|
* under the terms of the GNU General Public License version 2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _IRQ_H_
|
||||||
|
#define _IRQ_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <drivers/board_base.h>
|
||||||
|
|
||||||
|
namespace Gpio
|
||||||
|
{
|
||||||
|
enum { IRQ = Genode::Board_base::GPU_IRQ_BASE + 49 };
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _IRQ_H_ */
|
103
repos/os/src/drivers/gpio/rpi/main.cc
Normal file
103
repos/os/src/drivers/gpio/rpi/main.cc
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
* \brief Gpio driver for the RaspberryPI
|
||||||
|
* \author Reinier Millo Sánchez <rmillo@uclv.cu>
|
||||||
|
* \author Alexy Gallardo Segura <alexy@uclv.cu>
|
||||||
|
* \author Humberto Lopéz Leon <humberto@uclv.cu>
|
||||||
|
* \date 2015-07-23
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Genode Labs GmbH
|
||||||
|
*
|
||||||
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
|
* under the terms of the GNU General Public License version 2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <base/printf.h>
|
||||||
|
#include <base/sleep.h>
|
||||||
|
#include <cap_session/connection.h>
|
||||||
|
#include <gpio/component.h>
|
||||||
|
#include <gpio/config.h>
|
||||||
|
#include <os/server.h>
|
||||||
|
|
||||||
|
/* local includes */
|
||||||
|
#include "driver.h"
|
||||||
|
|
||||||
|
struct Main
|
||||||
|
{
|
||||||
|
Server::Entrypoint &ep;
|
||||||
|
Genode::Sliced_heap sliced_heap;
|
||||||
|
Gpio::Rpi_driver &driver;
|
||||||
|
Gpio::Root root;
|
||||||
|
|
||||||
|
Main(Server::Entrypoint &ep)
|
||||||
|
:
|
||||||
|
ep(ep),
|
||||||
|
sliced_heap(Genode::env()->ram_session(), Genode::env()->rm_session()),
|
||||||
|
driver(Gpio::Rpi_driver::factory(ep)),
|
||||||
|
root(&ep.rpc_ep(), &sliced_heap, driver)
|
||||||
|
{
|
||||||
|
using namespace Genode;
|
||||||
|
printf("--- RaspberryPI gpio driver ---\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check configuration for async events detect
|
||||||
|
*/
|
||||||
|
unsigned int async = 0;
|
||||||
|
try {
|
||||||
|
config()->xml_node().attribute("async_events").value(&async);
|
||||||
|
} catch (...) { }
|
||||||
|
driver.set_async_events(async>0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for common GPIO configuration
|
||||||
|
*/
|
||||||
|
Gpio::process_config(driver);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check configuration for specific function
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
Xml_node gpio_node = config()->xml_node().sub_node("gpio");
|
||||||
|
|
||||||
|
for (;; gpio_node = gpio_node.next("gpio")) {
|
||||||
|
unsigned num = 0;
|
||||||
|
unsigned function = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
gpio_node.attribute("num").value(&num);
|
||||||
|
gpio_node.attribute("function").value(&function);
|
||||||
|
|
||||||
|
switch(function){
|
||||||
|
case 0: driver.set_func(num, Gpio::Reg::FSEL_ALT0); break;
|
||||||
|
case 1: driver.set_func(num, Gpio::Reg::FSEL_ALT1); break;
|
||||||
|
case 2: driver.set_func(num, Gpio::Reg::FSEL_ALT2); break;
|
||||||
|
case 3: driver.set_func(num, Gpio::Reg::FSEL_ALT3); break;
|
||||||
|
case 4: driver.set_func(num, Gpio::Reg::FSEL_ALT4); break;
|
||||||
|
case 5: driver.set_func(num, Gpio::Reg::FSEL_ALT5); break;
|
||||||
|
default: PWRN("Wrong pin function. Ignore node.");
|
||||||
|
}
|
||||||
|
} catch(Xml_node::Nonexistent_attribute) {
|
||||||
|
PWRN("Missing attribute. Ignore node.");
|
||||||
|
}
|
||||||
|
if (gpio_node.is_last("gpio")) break;
|
||||||
|
}
|
||||||
|
} catch (Xml_node::Nonexistent_sub_node) { PWRN("No GPIO config"); }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Announce service
|
||||||
|
*/
|
||||||
|
env()->parent()->announce(ep.manage(root));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/************
|
||||||
|
** Server **
|
||||||
|
************/
|
||||||
|
|
||||||
|
namespace Server {
|
||||||
|
char const *name() { return "gpio_drv_ep"; }
|
||||||
|
size_t stack_size() { return 1024*sizeof(long); }
|
||||||
|
void construct(Entrypoint &ep) { static Main server(ep); }
|
||||||
|
}
|
3
repos/os/src/drivers/gpio/rpi/target.mk
Normal file
3
repos/os/src/drivers/gpio/rpi/target.mk
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
TARGET = gpio_drv
|
||||||
|
REQUIRES = rpi
|
||||||
|
LIBS += gpio
|
Loading…
x
Reference in New Issue
Block a user