Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <stdint.h>
- #include <stdbool.h>
- // CAUTION: DO NOT MODIFY REGISTERS FROM PRU unless you can be
- // absolutely certain that linux will not modify the register around the
- // same time, otherwise you'll create a race condition that may randomly
- // cause register writes to be lost.
- //
- // The only exceptions are CLEARDATAOUT and SETDATAOUT which are
- // write-only registers that perform atomic operations on the DATAOUT
- // register and are therefore safe for concurrent use by pru and linux.
- // (This also applies to IRQSTATUS_SET/CLR but obviously you shouldn't
- // mess with interrupt handling registers used by linux, with or without
- // race condition.)
- //
- typedef struct {
- /*000*/ uint32_t volatile REVISION;
- /*004*/ uint32_t volatile rsvd004[(0x010-0x004)/4];
- /*010*/ uint32_t volatile SYSCONFIG;
- /*014*/ uint32_t volatile rsvd014[(0x020-0x014)/4];
- /*020*/ uint32_t volatile EOI;
- /*024*/ uint32_t volatile IRQSTATUS_RAW[2];
- /*02c*/ uint32_t volatile IRQSTATUS[2];
- /*034*/ uint32_t volatile IRQSTATUS_SET[2];
- /*03c*/ uint32_t volatile IRQSTATUS_CLR[2];
- /*044*/ uint32_t volatile IRQWAKEN[2];
- /*04c*/ uint32_t volatile rsvd04c[(0x114-0x04c)/4];
- /*114*/ uint32_t volatile SYSSTATUS;
- /*118*/ uint32_t volatile rsvd118[(0x130-0x118)/4];
- /*130*/ uint32_t volatile CTRL;
- /*134*/ uint32_t volatile OE;
- /*138*/ uint32_t volatile DATAIN;
- /*13c*/ uint32_t volatile DATAOUT;
- /*140*/ uint32_t volatile LEVELDETECT0;
- /*144*/ uint32_t volatile LEVELDETECT1;
- /*148*/ uint32_t volatile RISINGDETECT;
- /*14c*/ uint32_t volatile FALLINGDETECT;
- /*150*/ uint32_t volatile DEBOUNCENABLE;
- /*154*/ uint32_t volatile DEBOUNCINGTIME;
- /*158*/ uint32_t volatile rsvd158[(0x190-0x158)/4];
- /*190*/ uint32_t volatile CLEARDATAOUT;
- /*194*/ uint32_t volatile SETDATAOUT;
- } sysGpio;
- #define GPIO0 (*(sysGpio *)0x44e07000)
- #define GPIO1 (*(sysGpio *)0x4804c000)
- #define GPIO2 (*(sysGpio *)0x481ac000)
- #define GPIO3 (*(sysGpio *)0x481ae000)
- //------------------ Safe wrapper functions ---------------------------------------------------
- //
- // The first argument must always be one of: &GPIO0, &GPIO1, &GPIO2, &GPIO3.
- //
- // For efficiency you can act on multiple gpios of one controller at the same time, with the
- // 32 gpios of one controller represented by the bits of an uint32_t. Convenience wrappers
- // that act on a single gpio are also provided further down.
- //
- // It is unsafe to change gpio direction from PRU so I'm not making a wrapper for that, set the
- // gpio direction from linux instead. Output values of gpios configured as input are ignored.
- // read all gpios of one gpio controller.
- static inline uint32_t gpio_read( sysGpio *dev )
- {
- return dev->DATAIN;
- }
- // set output value to 0 for one or more gpios of one gpio controller.
- static inline void gpio_set_low( sysGpio *dev, uint32_t mask )
- {
- dev->CLEARDATAOUT = mask;
- }
- // set output value to 1 for one or more gpios of one gpio controller.
- static inline void gpio_set_high( sysGpio *dev, uint32_t mask )
- {
- dev->SETDATAOUT = mask;
- }
- // combines gpio_set_low() and gpio_set_high(), but optimized to use only a single bus write.
- // this minimizes the delay between the two actions.
- static inline void gpio_set_low_set_high( sysGpio *dev, uint32_t low_mask, uint32_t high_mask )
- {
- *(uint64_t volatile *)&dev->CLEARDATAOUT = low_mask | (uint64_t)high_mask << 32;
- }
- // set output value for one or more gpios of one gpio controller, with value specified per gpio.
- static inline void gpio_set( sysGpio *dev, uint32_t mask, uint32_t values )
- {
- gpio_set_low_set_high( dev, mask & ~values, mask & values );
- }
- // set output value for one or more gpios of one gpio controller, using same value for all.
- static inline void gpio_fill( sysGpio *dev, uint32_t mask, bool value )
- {
- (&dev->CLEARDATAOUT)[ value ] = mask;
- }
- // Convenience wrappers for accessing a single gpio (0..31) of a gpio controller:
- // read one gpio
- static inline bool gpio_read_one( sysGpio *dev, uint8_t gpio )
- {
- return ( gpio_read( dev ) >> gpio ) & 1;
- }
- // set output value of one gpio to 0
- static inline void gpio_set_one_low( sysGpio *dev, uint8_t gpio )
- {
- gpio_set_low( dev, 1u << gpio );
- }
- // set output value of one gpio to 1
- static inline void gpio_set_one_high( sysGpio *dev, uint8_t gpio )
- {
- gpio_set_high( dev, 1u << gpio );
- }
- // set output value of one gpio
- static inline void gpio_set_one( sysGpio *dev, uint8_t gpio, bool value )
- {
- gpio_fill( dev, 1u << gpio, value );
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement