/*
BCM2835 ARM Peripherals

Datasheet:
https://www.raspberrypi.org/app/uploads/2012/02/BCM2835-ARM-Peripherals.pdf


      3V3 Power  *---[ 01 | 02 ]---*  5V Power
    GPIO2 (SDA)  *---[ 03 | 04 ]---*  5V Power
    GPIO3 (SCL)  *---[ 05 | 06 ]---*  Ground
 GPIO4 (GPCLK0)  *---[ 07 | 08 ]---*  GPIO14 (TXD)
         Ground  *---[ 09 | 10 ]---*  GPIO15 (RXD)
         GPIO17  *---[ 11 | 12 ]---*  GPIO18 (PCM_CLK)
         GPIO27  *---[ 13 | 14 ]---*  Ground
         GPIO22  *---[ 15 | 16 ]---*  GPIO23
      3V3 Power  *---[ 17 | 18 ]---*  GPIO24
  GPIO10 (MOSI)  *---[ 19 | 20 ]---*  Ground
   GPIO9 (MISO)  *---[ 21 | 22 ]---*  GPIO25
  GPIO11 (SCLK)  *---[ 23 | 24 ]---*  GPIO8 (CE0)
         Ground  *---[ 25 | 26 ]---*  GPIO7 (CE1)
  GPIO0 (ID_SD)  *---[ 27 | 28 ]---*  GPIO1 (ID_SC)
          GPIO5  *---[ 29 | 30 ]---*  Ground
          GPIO6  *---[ 31 | 32 ]---*  GPIO12 (PWM0)
  GPIO13 (PWM1)  *---[ 33 | 34 ]---*  Ground
GPIO19 (PCM_FS)  *---[ 35 | 36 ]---*  GPIO16
         GPIO26  *---[ 37 | 38 ]---*  GPIO20 (PCM_DIN)
         Ground  *---[ 39 | 40 ]---*  GPIO21 (PCM_DOUT)


gpiochip0 - 54 lines:

---------------------   ---------------------   ---------------------
line 00: ID_SDA         line 18: GPIO18         line 36: SD1_DATA0
line 01: ID_SCL         line 19: GPIO19         line 37: SD1_DATA1
line 02: GPIO2          line 20: GPIO20         line 38: SD1_DATA2
line 03: GPIO3          line 21: GPIO21         line 39: SD1_DATA3
line 04: GPIO4          line 22: GPIO22         line 40: PWM0_OUT
line 05: GPIO5          line 23: GPIO23         line 41: PWM1_OUT
line 06: GPIO6          line 24: GPIO24         line 42: ETH_CLK
line 07: GPIO7          line 25: GPIO25         line 43: WIFI_CLK
line 08: GPIO8          line 26: GPIO26         line 44: SDA0
line 09: GPIO9          line 27: GPIO27         line 45: SCL0
line 10: GPIO10         line 28: NC             line 46: SMPS_SCL
line 11: GPIO11         line 29: LAN_RUN_BOOT   line 47: SMPS_SDA
line 12: GPIO12         line 30: CTS0           line 48: SD_CLK_R
line 13: GPIO13         line 31: RTS0           line 49: SD_CMD_R
line 14: GPIO14         line 32: TXD0           line 50: SD_DATA0_R
line 15: GPIO15         line 33: RXD0           line 51: SD_DATA1_R
line 16: GPIO16         line 34: SD1_CLK        line 52: SD_DATA2_R
line 17: GPIO17         line 35: SD1_CMD        line 53: SD_DATA3_R
---------------------   ---------------------   ---------------------
*/

#ifndef BCM_2835_H
#define BCM_2835_H

#define BCM_FSEL0   0
#define BCM_FSEL1   1
#define BCM_FSEL2   2
#define BCM_FSEL3   3
#define BCM_FSEL4   4
#define BCM_FSEL5   5
#define BCM_SET0    7
#define BCM_SET1    8
#define BCM_CLR0    10
#define BCM_CLR1    11
#define BCM_LEV0    13
#define BCM_LEV1    14
#define BCM_EDS0    16
#define BCM_EDS1    17
#define BCM_REN0    19
#define BCM_REN1    20
#define BCM_FEN0    22
#define BCM_FEN1    23
#define BCM_HEN0    25
#define BCM_HEN1    26
#define BCM_LEN0    28
#define BCM_LEN1    29
#define BCM_AREN0   31
#define BCM_AREN1   32
#define BCM_AFEN0   34
#define BCM_AFEN1   35
#define BCM_PUD     37
#define BCM_PUDCLK0 38
#define BCM_PUDCLK1 39

#define LOW  0
#define HIGH 1

typedef unsigned char u8_t;
typedef unsigned int u32_t;

typedef enum {
  FSEL_IN   = 0x00,
  FSEL_OUT  = 0x01,
  FSEL_ALT0 = 0x04,
  FSEL_ALT1 = 0x05,
  FSEL_ALT2 = 0x06,
  FSEL_ALT3 = 0x07,
  FSEL_ALT4 = 0x03,
  FSEL_ALT5 = 0x02,
} bcm_fsel_e;

typedef enum {
  PUD_OFF  = 0x00,
  PUD_DOWN = 0x01,
  PUD_UP   = 0x02,
} bcm_pud_e;

int bcm_init(void);
void bcm_fsel(u32_t pin, bcm_fsel_e fsel);
void bcm_set(u32_t pin);
void bcm_clr(u32_t pin);
int bcm_lev(u32_t pin);
void bcm_pud(u32_t pin, bcm_pud_e pud);

void bcm_write(u32_t pin, int level);
int bcm_read(u32_t pin);
void bcm_pulse(u32_t pin, int level, u32_t sleep);

#endif
