Advertisement
zmatt

sys_gpio.h for pru (on am335x)

Sep 3rd, 2021
1,364
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.47 KB | None | 0 0
  1. #pragma once
  2. #include <stdint.h>
  3. #include <stdbool.h>
  4.  
  5. // CAUTION:  DO NOT MODIFY REGISTERS FROM PRU unless you can be
  6. // absolutely certain that linux will not modify the register around the
  7. // same time, otherwise you'll create a race condition that may randomly
  8. // cause register writes to be lost.
  9. //
  10. // The only exceptions are CLEARDATAOUT and SETDATAOUT which are
  11. // write-only registers that perform atomic operations on the DATAOUT
  12. // register and are therefore safe for concurrent use by pru and linux.
  13. // (This also applies to IRQSTATUS_SET/CLR but obviously you shouldn't
  14. // mess with interrupt handling registers used by linux, with or without
  15. // race condition.)
  16. //
  17. typedef struct {
  18. /*000*/ uint32_t volatile REVISION;
  19.  
  20. /*004*/ uint32_t volatile rsvd004[(0x010-0x004)/4];
  21.  
  22. /*010*/ uint32_t volatile SYSCONFIG;
  23.  
  24. /*014*/ uint32_t volatile rsvd014[(0x020-0x014)/4];
  25.  
  26. /*020*/ uint32_t volatile EOI;
  27. /*024*/ uint32_t volatile IRQSTATUS_RAW[2];
  28. /*02c*/ uint32_t volatile IRQSTATUS[2];
  29. /*034*/ uint32_t volatile IRQSTATUS_SET[2];
  30. /*03c*/ uint32_t volatile IRQSTATUS_CLR[2];
  31. /*044*/ uint32_t volatile IRQWAKEN[2];
  32.  
  33. /*04c*/ uint32_t volatile rsvd04c[(0x114-0x04c)/4];
  34.  
  35. /*114*/ uint32_t volatile SYSSTATUS;
  36.  
  37. /*118*/ uint32_t volatile rsvd118[(0x130-0x118)/4];
  38.  
  39. /*130*/ uint32_t volatile CTRL;
  40.  
  41. /*134*/ uint32_t volatile OE;
  42. /*138*/ uint32_t volatile DATAIN;
  43. /*13c*/ uint32_t volatile DATAOUT;
  44.  
  45. /*140*/ uint32_t volatile LEVELDETECT0;
  46. /*144*/ uint32_t volatile LEVELDETECT1;
  47. /*148*/ uint32_t volatile RISINGDETECT;
  48. /*14c*/ uint32_t volatile FALLINGDETECT;
  49.  
  50. /*150*/ uint32_t volatile DEBOUNCENABLE;
  51. /*154*/ uint32_t volatile DEBOUNCINGTIME;
  52.  
  53. /*158*/ uint32_t volatile rsvd158[(0x190-0x158)/4];
  54.  
  55. /*190*/ uint32_t volatile CLEARDATAOUT;
  56. /*194*/ uint32_t volatile SETDATAOUT;
  57.  
  58. } sysGpio;
  59.  
  60. #define GPIO0 (*(sysGpio *)0x44e07000)
  61. #define GPIO1 (*(sysGpio *)0x4804c000)
  62. #define GPIO2 (*(sysGpio *)0x481ac000)
  63. #define GPIO3 (*(sysGpio *)0x481ae000)
  64.  
  65.  
  66. //------------------ Safe wrapper functions ---------------------------------------------------
  67. //
  68. // The first argument must always be one of: &GPIO0, &GPIO1, &GPIO2, &GPIO3.
  69. //
  70. // For efficiency you can act on multiple gpios of one controller at the same time, with the
  71. // 32 gpios of one controller represented by the bits of an uint32_t.  Convenience wrappers
  72. // that act on a single gpio are also provided further down.
  73. //
  74. // It is unsafe to change gpio direction from PRU so I'm not making a wrapper for that, set the
  75. // gpio direction from linux instead.  Output values of gpios configured as input are ignored.
  76.  
  77.  
  78. // read all gpios of one gpio controller.
  79. static inline uint32_t gpio_read( sysGpio *dev )
  80. {
  81.     return dev->DATAIN;
  82. }
  83.  
  84. // set output value to 0 for one or more gpios of one gpio controller.
  85. static inline void gpio_set_low( sysGpio *dev, uint32_t mask )
  86. {
  87.     dev->CLEARDATAOUT = mask;
  88. }
  89.  
  90. // set output value to 1 for one or more gpios of one gpio controller.
  91. static inline void gpio_set_high( sysGpio *dev, uint32_t mask )
  92. {
  93.     dev->SETDATAOUT = mask;
  94. }
  95.  
  96. // combines gpio_set_low() and gpio_set_high(), but optimized to use only a single bus write.
  97. // this minimizes the delay between the two actions.
  98. static inline void gpio_set_low_set_high( sysGpio *dev, uint32_t low_mask, uint32_t high_mask )
  99. {
  100.     *(uint64_t volatile *)&dev->CLEARDATAOUT = low_mask | (uint64_t)high_mask << 32;
  101. }
  102.  
  103. // set output value for one or more gpios of one gpio controller, with value specified per gpio.
  104. static inline void gpio_set( sysGpio *dev, uint32_t mask, uint32_t values )
  105. {
  106.     gpio_set_low_set_high( dev, mask & ~values, mask & values );
  107. }
  108.  
  109. // set output value for one or more gpios of one gpio controller, using same value for all.
  110. static inline void gpio_fill( sysGpio *dev, uint32_t mask, bool value )
  111. {
  112.     (&dev->CLEARDATAOUT)[ value ] = mask;
  113. }
  114.  
  115.  
  116. // Convenience wrappers for accessing a single gpio (0..31) of a gpio controller:
  117.  
  118. // read one gpio
  119. static inline bool gpio_read_one( sysGpio *dev, uint8_t gpio )
  120. {
  121.     return ( gpio_read( dev ) >> gpio ) & 1;
  122. }
  123.  
  124. // set output value of one gpio to 0
  125. static inline void gpio_set_one_low( sysGpio *dev, uint8_t gpio )
  126. {
  127.     gpio_set_low( dev, 1u << gpio );
  128. }
  129.  
  130. // set output value of one gpio to 1
  131. static inline void gpio_set_one_high( sysGpio *dev, uint8_t gpio )
  132. {
  133.     gpio_set_high( dev, 1u << gpio );
  134. }
  135.  
  136. // set output value of one gpio
  137. static inline void gpio_set_one( sysGpio *dev, uint8_t gpio, bool value )
  138. {
  139.     gpio_fill( dev, 1u << gpio, value );
  140. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement