The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
##########################################################################################
# Distribution : HiPi Modules for Raspberry Pi
# File         : lib/HiPi/Constant.pm
# Description  : Constants for HiPi
# Copyright    : Copyright (c) 2013-2017 Mark Dootson
# License      : This is free software; you can redistribute it and/or modify it under
#                the same terms as the Perl 5 programming language system itself.
#########################################################################################

package HiPi::Constant;

#########################################################################################
use strict;
use warnings;
use parent qw( Exporter );
use HiPi::RaspberryPi;

our $VERSION ='0.67';

our @EXPORT_OK = ( qw( hipi_export_ok  hipi_export_constants hipi_export_tags ) );
our %EXPORT_TAGS = ( hipi => \@EXPORT_OK );

my $MCP_DAC_RESOLUTION_08 = 0x010;
my $MCP_DAC_RESOLUTION_10 = 0x020;
my $MCP_DAC_RESOLUTION_12 = 0x030;
my $MCP_DAC_DUAL_CHANNEL  = 0x001;
my $MCP_DAC_CAN_BUFFER    = 0x002;

my $const = {
    i2c => {
        I2C_READMODE_SYSTEM => 0,
        I2C_READMODE_REPEATED_START => 1,
        I2C_READMODE_START_STOP => 2,
        
        I2C_SCANMODE_AUTO  => 0,
        I2C_SCANMODE_QUICK => 1,
        I2C_SCANMODE_READ  => 2,
        
        I2C_RETRIES     => 0x0701,
        I2C_TIMEOUT     => 0x0702,
        I2C_SLAVE       => 0x0703,
        I2C_TENBIT      => 0x0704,
        I2C_FUNCS       => 0x0705,
        I2C_SLAVE_FORCE => 0x0706,
        I2C_RDWR        => 0x0707,
        I2C_PEC         => 0x0708,
        I2C_SMBUS       => 0x0720,
        
        I2C_M_TEN          => 0x0010,
        I2C_M_RD		   => 0x0001,
        I2C_M_NOSTART	   => 0x4000,
        I2C_M_REV_DIR_ADDR => 0x2000,
        I2C_M_IGNORE_NAK   => 0x1000,
        I2C_M_NO_RD_ACK	   => 0x0800,
        I2C_M_RECV_LEN	   => 0x0400,
        
        I2C0_SDA	           => 28,
        I2C0_SCL	           => 29,
        I2C1_SDA	           => 2,
        I2C1_SCL	           => 3,
        I2C_SDA	               => 2,
        I2C_SCL	               => 3,
        ID_SD	               => 0,
        ID_SC	               => 1,
        
    },
    
    rpi => {
        RPI_PIN_3  =>  2,
        RPI_PIN_5  =>  3,
        RPI_PIN_7  =>  4,
        RPI_PIN_8  => 14,
        RPI_PIN_10 => 15,
        RPI_PIN_11 => 17,
        RPI_PIN_12 => 18,
        RPI_PIN_13 => 27,
        RPI_PIN_15 => 22,
        RPI_PIN_16 => 23,
        RPI_PIN_18 => 24,
        RPI_PIN_19 => 10,
        RPI_PIN_21 =>  9,
        RPI_PIN_22 => 25,
        RPI_PIN_23 => 11,
        RPI_PIN_24 =>  8,
        RPI_PIN_26 =>  7,
        RPI_PIN_27 => 0,
        RPI_PIN_28 => 1,
        RPI_PIN_29 => 5,
        RPI_PIN_31 => 6,
        RPI_PIN_32 => 12,
        RPI_PIN_33 => 13,
        RPI_PIN_35 => 19,
        RPI_PIN_36 => 16,
        RPI_PIN_37 => 26,
        RPI_PIN_38 => 20,
        RPI_PIN_40 => 21,
        
        RPI_OUTPUT => 1,
        RPI_INPUT  => 0,
        
        RPI_MODE_INPUT  => 0,
        RPI_MODE_OUTPUT => 1,
        RPI_MODE_ALT0   => 4,
        RPI_MODE_ALT1   => 5,
        RPI_MODE_ALT2   => 6,
        RPI_MODE_ALT3   => 7,
        RPI_MODE_ALT4   => 3,
        RPI_MODE_ALT5   => 2,
        
        RPI_INT_NONE           => 0x00,
        RPI_INT_FALL           => 0x01,
        RPI_INT_RISE           => 0x02,
        RPI_INT_BOTH           => 0x03,
        RPI_INT_AFALL          => 0x04,
        RPI_INT_ARISE          => 0x08,
        RPI_INT_HIGH           => 0x10,
        RPI_INT_LOW            => 0x20,
        
        # legacy
        RPI_PINMODE_INPT       => 0,
        RPI_PINMODE_OUTP       => 1,
        RPI_PINMODE_ALT0       => 4,
        RPI_PINMODE_ALT1       => 5,
        RPI_PINMODE_ALT2       => 6,
        RPI_PINMODE_ALT3       => 7,
        RPI_PINMODE_ALT4       => 3,
        RPI_PINMODE_ALT5       => 2,
        
        RPI_HIGH   => 1,
        RPI_LOW    => 0,
        
        RPI_BOARD_TYPE_1 => 1,
        RPI_BOARD_TYPE_2 => 2,
        RPI_BOARD_TYPE_3 => 3,
        
        RPI_PUD_NULL           => -1,
        RPI_PUD_OFF            => 0,
        RPI_PUD_DOWN           => 1,
        RPI_PUD_UP             => 2,
        
        RPI_BOARD_REVISION     => HiPi::RaspberryPi::board_type(),
        
        DEV_GPIO_PIN_STATUS_NONE         => 0x00,
        DEV_GPIO_PIN_STATUS_EXPORTED     => 0x01,
    },
    
    spi => {
        SPI_CPHA        => 0x01,
        SPI_CPOL        => 0x02,
        SPI_MODE_0      => 0x00,
        SPI_MODE_1      => 0x01,
        SPI_MODE_2      => 0x02,
        SPI_MODE_3      => 0x03,
        SPI_CS_HIGH     => 0x04,
        SPI_LSB_FIRST   => 0x08,
        SPI_3WIRE       => 0x10,
        SPI_LOOP        => 0x20,
        SPI_NO_CS       => 0x40,
        SPI_READY       => 0x80,
        SPI_SPEED_KHZ_500 => 500000,
        SPI_SPEED_MHZ_1   => 1000000,
        SPI_SPEED_MHZ_2   => 2000000,
        SPI_SPEED_MHZ_4   => 4000000,
        SPI_SPEED_MHZ_8   => 8000000,
        SPI_SPEED_MHZ_16  => 16000000,
        SPI_SPEED_MHZ_32  => 32000000,
    },
    
    mcp23x17 => {
        MCP23S17_A0     => 0x1000,
        MCP23S17_A1     => 0x1001,
        MCP23S17_A2     => 0x1002,
        MCP23S17_A3     => 0x1003,
        MCP23S17_A4     => 0x1004,
        MCP23S17_A5     => 0x1005,
        MCP23S17_A6     => 0x1006,
        MCP23S17_A7     => 0x1007,
        MCP23S17_B0     => 0x1010,
        MCP23S17_B1     => 0x1011,
        MCP23S17_B2     => 0x1012,
        MCP23S17_B3     => 0x1013,
        MCP23S17_B4     => 0x1014,
        MCP23S17_B5     => 0x1015,
        MCP23S17_B6     => 0x1016,
        MCP23S17_B7     => 0x1017,
        
        MCP23S17_BANK   => 7,
        MCP23S17_MIRROR => 6,
        MCP23S17_SEQOP  => 5,
        MCP23S17_DISSLW => 4,
        MCP23S17_HAEN   => 3,
        MCP23S17_ODR    => 2,
        MCP23S17_INTPOL => 1,
        
        MCP23S17_INPUT  => 1,
        MCP23S17_OUTPUT => 0,
        
        MCP23S17_HIGH   => 1,
        MCP23S17_LOW    => 0,
    
        MCP23017_A0     => 0x1000,
        MCP23017_A1     => 0x1001,
        MCP23017_A2     => 0x1002,
        MCP23017_A3     => 0x1003,
        MCP23017_A4     => 0x1004,
        MCP23017_A5     => 0x1005,
        MCP23017_A6     => 0x1006,
        MCP23017_A7     => 0x1007,
        MCP23017_B0     => 0x1010,
        MCP23017_B1     => 0x1011,
        MCP23017_B2     => 0x1012,
        MCP23017_B3     => 0x1013,
        MCP23017_B4     => 0x1014,
        MCP23017_B5     => 0x1015,
        MCP23017_B6     => 0x1016,
        MCP23017_B7     => 0x1017,
        
        MCP23017_BANK   => 7,
        MCP23017_MIRROR => 6,
        MCP23017_SEQOP  => 5,
        MCP23017_DISSLW => 4,
        MCP23017_HAEN   => 3,
        MCP23017_ODR    => 2,
        MCP23017_INTPOL => 1,
        
        MCP23017_INPUT  => 1,
        MCP23017_OUTPUT => 0,
        
        MCP23017_HIGH   => 1,
        MCP23017_LOW    => 0,
    
        MCP_PIN_A0     => 'A0',
        MCP_PIN_A1     => 'A1',
        MCP_PIN_A2     => 'A2',
        MCP_PIN_A3     => 'A3',
        MCP_PIN_A4     => 'A4',
        MCP_PIN_A5     => 'A5',
        MCP_PIN_A6     => 'A6',
        MCP_PIN_A7     => 'A7',
        MCP_PIN_B0     => 'B0',
        MCP_PIN_B1     => 'B1',
        MCP_PIN_B2     => 'B2',
        MCP_PIN_B3     => 'B3',
        MCP_PIN_B4     => 'B4',
        MCP_PIN_B5     => 'B5',
        MCP_PIN_B6     => 'B6',
        MCP_PIN_B7     => 'B7',
    },
    
    mpl3115a2 => {
        MPL_REG_STATUS              => 0x00,
        MPL_REG_OUT_P_MSB           => 0x01,
        MPL_REG_OUT_P_CSB           => 0x02,
        MPL_REG_OUT_P_LSB           => 0x03,
        MPL_REG_OUT_T_MSB           => 0x04,
        MPL_REG_OUT_T_LSB           => 0x05,
        MPL_REG_DR_STATUS           => 0x06,
        MPL_REG_OUT_P_DELTA_MSB     => 0x07,
        MPL_REG_OUT_P_DELTA_CSB     => 0x08,
        MPL_REG_OUT_P_DELTA_LSB     => 0x09,
        MPL_REG_OUT_T_DELTA_MSB     => 0x0A,
        MPL_REG_OUT_T_DELTA_LSB     => 0x0B,
        MPL_REG_WHO_AM_I            => 0x0C,
        MPL_REG_F_STATUS            => 0x0D,
        MPL_REG_F_DATA              => 0x0E,
        MPL_REG_F_SETUP             => 0x0F,
        MPL_REG_TIME_DLY            => 0x10,
        MPL_REG_SYSMOD              => 0x11,
        MPL_REG_INT_SOURCE          => 0x12,
        MPL_REG_PT_DATA_CFG         => 0x13,
        MPL_REG_BAR_IN_MSB          => 0x14,
        MPL_REG_MAR_IN_LSB          => 0x15,
        MPL_REG_P_TGT_MSB           => 0x16,
        MPL_REG_P_TGT_LSB           => 0x17,
        MPL_REG_T_TGT               => 0x18,
        MPL_REG_P_WND_MSB           => 0x19,
        MPL_REG_P_WND_LSB           => 0x1A,
        MPL_REG_T_WND               => 0x1B,
        MPL_REG_P_MIN_MSB           => 0x1C,
        MPL_REG_P_MIN_CSB           => 0x1D,
        MPL_REG_P_MIN_LSB           => 0x1E,
        MPL_REG_T_MIN_MSB           => 0x1F,
        MPL_REG_T_MIN_LSB           => 0x20,
        MPL_REG_P_MAX_MSB           => 0x21,
        MPL_REG_P_MAX_CSB           => 0x22,
        MPL_REG_P_MAX_LSB           => 0x23,
        MPL_REG_T_MAX_MSB           => 0x24,
        MPL_REG_T_MAX_LSB           => 0x25,
        MPL_REG_CTRL_REG1           => 0x26,
        MPL_REG_CTRL_REG2           => 0x27,
        MPL_REG_CTRL_REG3           => 0x28,
        MPL_REG_CTRL_REG4           => 0x29,
        MPL_REG_CTRL_REG5           => 0x2A,
        MPL_REG_OFF_P               => 0x2B,
        MPL_REG_OFF_T               => 0x2C,
        MPL_REG_OFF_H               => 0x2D,
        
        MPL_CTRL_REG1_SBYB          => 0x01,
        MPL_CTRL_REG1_OST           => 0x02,
        MPL_CTRL_REG1_RST           => 0x04,
        MPL_CTRL_REG1_OS0           => 0x08,
        MPL_CTRL_REG1_OS1           => 0x10,
        MPL_CTRL_REG1_OS2           => 0x20,
        MPL_CTRL_REG1_RAW           => 0x40,
        MPL_CTRL_REG1_ALT           => 0x80,
        
        MPL_CTRL_REG1_MASK          => 0xFF,
        
        MPL_CTRL_REG2_ST0           => 0x01,
        MPL_CTRL_REG2_ST1           => 0x02,
        MPL_CTRL_REG2_ST2           => 0x04,
        MPL_CTRL_REG2_ST3           => 0x08,
        MPL_CTRL_REG2_ALARM_SEL     => 0x10,
        MPL_CTRL_REG2_LOAD_OUTPUT   => 0x20,
        
        MPL_CTRL_REG2_MASK          => 0x3F,
        
        MPL_CTRL_REG3_PP_0D2        => 0x01,
        MPL_CTRL_REG3_IPOL2         => 0x02,
        MPL_CTRL_REG3_PP_OD1        => 0x10,
        MPL_CTRL_REG3_IPOL1         => 0x20,
      
        MPL_CTRL_REG3_MASK          => 0x33,
        
        MPL_CTRL_REG4_INT_EN_DRDY   => 0x80,
        MPL_CTRL_REG4_INT_EN_FIFO   => 0x40,
        MPL_CTRL_REG4_INT_EN_PW     => 0x20,
        MPL_CTRL_REG4_INT_EN_TW     => 0x10,
        MPL_CTRL_REG4_INT_EN_PTH    => 0x08,
        MPL_CTRL_REG4_INT_EN_TTH    => 0x04,
        MPL_CTRL_REG4_INT_EN_PCHG   => 0x02,
        MPL_CTRL_REG4_INT_EN_TCHG   => 0x01,
        
        MPL_CTRL_REG4_MASK          => 0xFF,
        
        MPL_INTREGS_DRDY  => 0x80,
        MPL_INTREGS_FIFO  => 0x40,
        MPL_INTREGS_PW    => 0x20,
        MPL_INTREGS_TW    => 0x10,
        MPL_INTREGS_PTH   => 0x08,
        MPL_INTREGS_TTH   => 0x04,
        MPL_INTREGS_PCHG  => 0x02,
        MPL_INTREGS_TCHG  => 0x01,
        
        MPL_INTREGS_MASK          => 0xFF,
        
        MPL_DR_STATUS_PTOW          => 0x80,
        MPL_DR_STATUS_POW           => 0x40,
        MPL_DR_STATUS_TOW           => 0x20,
        MPL_DR_STATUS_PTDR          => 0x08,
        MPL_DR_STATUS_PDR           => 0x04,
        MPL_DR_STATUS_TDR           => 0x02,
        
        MPL_DR_STATUS_MASK          => 0xEE,
        
        MPL_F_STATUS_F_OVF          => 0x80,
        MPL_F_STATUS_F_WMRK_FLAG    => 0x40,
        MPL_F_STATUS_F_CNT5         => 0x20,
        MPL_F_STATUS_F_CNT4         => 0x10,
        MPL_F_STATUS_F_CNT3         => 0x08,
        MPL_F_STATUS_F_CNT2         => 0x04,
        MPL_F_STATUS_F_CNT1         => 0x02,
        MPL_F_STATUS_F_CNT0         => 0x01,
        
        MPL_F_STATUS_MASK           => 0xFF,
        
        MPL_PT_DATA_CFG_DREM        => 0x04,
        MPL_PT_DATA_CFG_PDEFE       => 0x02,
        MPL_PT_DATA_CFG_TDEFE       => 0x01,
        
        MPL_PT_DATA_CFG_MASK        => 0x07,
        
        MPL_BIT_SBYB          => 0,
        MPL_BIT_OST           => 1,
        MPL_BIT_RST           => 2,
        MPL_BIT_OS0           => 3,
        MPL_BIT_OS1           => 4,
        MPL_BIT_OS2           => 5,
        MPL_BIT_RAW           => 6,
        MPL_BIT_ALT           => 7,
        
        MPL_BIT_ST0           => 0,
        MPL_BIT_ST1           => 1,
        MPL_BIT_ST2           => 2,
        MPL_BIT_ST3           => 3,
        MPL_BIT_ALARM_SEL     => 4,
        MPL_BIT_LOAD_OUTPUT   => 5,
        
        MPL_BIT_PP_0D2        => 0,
        MPL_BIT_IPOL2         => 1,
        MPL_BIT_PP_OD1        => 4,
        MPL_BIT_IPOL1         => 5,
        
        # interrupt bits for CTRL_REG5,
        # INT_SOURCE
        
        MPL_BIT_DRDY          => 7,
        MPL_BIT_FIFO          => 6,
        MPL_BIT_PW            => 5,
        MPL_BIT_TW            => 4,
        MPL_BIT_PTH           => 3,
        MPL_BIT_TTH           => 2,
        MPL_BIT_PCHG          => 1,
        MPL_BIT_TCHG          => 0,
        
        MPL_BIT_PTOW          => 7,
        MPL_BIT_POW           => 6,
        MPL_BIT_TOW           => 5,
        MPL_BIT_PTDR          => 3,
        MPL_BIT_PDR           => 2,
        MPL_BIT_TDR           => 1,
        
        MPL_BIT_F_OVF        => 7,
        MPL_BIT_F_WMRK_FLAG  => 6,
        MPL_BIT_F_CNT5       => 5,
        MPL_BIT_F_CNT4       => 4,
        MPL_BIT_F_CNT3       => 3,
        MPL_BIT_F_CNT2       => 2,
        MPL_BIT_F_CNT1       => 1,
        MPL_BIT_F_CNT0       => 0,
        
        MPL_BIT_DREM         => 2,
        MPL_BIT_PDEFE        => 1,
        MPL_BIT_TDEFE        => 0,
        
        
        MPL_OSREAD_DELAY     => 1060, # left for compatibility with code that uses it.
                                      
        MPL_FUNC_ALTITUDE    => 1,
        MPL_FUNC_PRESSURE    => 2,
        MPL3115A2_ID         => 0xC4,
        
        
        MPL_CONTROL_MASK     => 0b00111000, #128 oversampling
        MPL_BYTE_MASK        => 0xFF,
        MPL_WORD_MASK        => 0xFFFF,
        
        MPL_OVERSAMPLE_1     => 0b00000000,
        MPL_OVERSAMPLE_2     => 0b00001000,
        MPL_OVERSAMPLE_4     => 0b00010000,
        MPL_OVERSAMPLE_8     => 0b00011000,
        MPL_OVERSAMPLE_16    => 0b00100000,
        MPL_OVERSAMPLE_32    => 0b00101000,
        MPL_OVERSAMPLE_64    => 0b00110000,
        MPL_OVERSAMPLE_128   => 0b00111000,
        
        MPL_OVERSAMPLE_MASK  => 0b00111000,
        
        MPL_BB_I2C_PERI_0    => 0x10,
        MPL_BB_I2C_PERI_1    => 0x20,
        
    },
    
    lcd => {
        HD44780_CLEAR_DISPLAY           => 0x01,
        HD44780_HOME_UNSHIFT            => 0x02,
        HD44780_CURSOR_MODE_LEFT        => 0x04,
        HD44780_CURSOR_MODE_LEFT_SHIFT  => 0x05,
        HD44780_CURSOR_MODE_RIGHT       => 0x06,
        HD44780_CURSOR_MODE_RIGHT_SHIFT => 0x07,
        HD44780_DISPLAY_OFF             => 0x08,
        
        HD44780_DISPLAY_ON              => 0x0C,
        HD44780_CURSOR_OFF              => 0x0C,
        HD44780_CURSOR_UNDERLINE        => 0x0E,
        HD44780_CURSOR_BLINK            => 0x0F,
        
        HD44780_SHIFT_CURSOR_LEFT       => 0x10,
        HD44780_SHIFT_CURSOR_RIGHT      => 0x14,
        HD44780_SHIFT_DISPLAY_LEFT      => 0x18,
        HD44780_SHIFT_DISPLAY_RIGHT     => 0x1C,
        
        HD44780_CURSOR_POSITION         => 0x80,
        
        SRX_CURSOR_OFF       => 0x0C,
        SRX_CURSOR_BLINK     => 0x0F,
        SRX_CURSOR_UNDERLINE => 0x0E,
        
        HTV2_END_SERIALRX_COMMAND    => chr(0xFF),
    
        HTV2_BAUD_2400    => 0,
        HTV2_BAUD_4800    => 1,
        HTV2_BAUD_9600    => 2,
        HTV2_BAUD_14400   => 3,
        HTV2_BAUD_19200   => 4,
        HTV2_BAUD_28800   => 5,
        HTV2_BAUD_57600   => 6,
        HTV2_BAUD_115200  => 7,
        
        HTV2_CMD_PRINT          => 1,
        HTV2_CMD_SET_CURSOR_POS => 2,
        HTV2_CMD_CLEAR_LINE     => 3,
        HTV2_CMD_CLEAR_DISPLAY  => 4,
        HTV2_CMD_LCD_TYPE       => 5,
        HTV2_CMD_HD44780_CMD    => 6,
        HTV2_CMD_BACKLIGHT      => 7,
        HTV2_CMD_WRITE_CHAR     => 10,
        HTV2_CMD_I2C_ADDRESS    => 32,
        HTV2_CMD_BAUD_RATE      => 33,
        HTV2_CMD_CUSTOM_CHAR    => 64,
        
        SLCD_START_COMMAND    => chr(0xFE),
        SLCD_SPECIAL_COMMAND  => chr(0x7C),
    },
    
    hrf69 => {
        RF69_REG_FIFO			=> 0x00,
        RF69_REG_OPMODE			=> 0x01,
        RF69_REG_REGDATAMODUL	=> 0x02,
        RF69_REG_BITRATEMSB		=> 0x03,
        RF69_REG_BITRATELSB		=> 0x04,
        RF69_REG_FDEVMSB		=> 0x05,
        RF69_REG_FDEVLSB		=> 0x06,
        RF69_REG_FRMSB			=> 0x07,
        RF69_REG_FRMID			=> 0x08,
        RF69_REG_FRLSB			=> 0x09,
        RF69_REG_CALLIB         => 0x0A,
        RF69_REG_AFCCTRL		=> 0x0B,
        RF69_REG_LISTEN1        => 0x0D,
        RF69_REG_LISTEN2        => 0x0E,
        RF69_REG_LISTEN3        => 0x0F,
        RF69_REG_VERSION        => 0x10,
        RF69_REG_PALEVEL        => 0x11,
        RF69_REG_PARAMP         => 0x12,
        RF69_REG_OCP            => 0x13,
        RF69_REG_LNA            => 0x18,
        RF69_REG_RXBW			=> 0x19,
        RF69_REG_AFCBW          => 0x1A,
        RF69_REG_OOKPEAK        => 0x1B,
        RF69_REG_OOKAVG         => 0x1C,
        RF69_REG_OOKFIX         => 0x1D,
        RF69_REG_AFCFEI			=> 0x1E,
        RF69_REG_AFCMSB         => 0x1F,
        RF69_REG_AFCLSB         => 0x20,
        RF69_REG_FEIMSB         => 0x21,
        RF69_REG_FEILSB         => 0x22,
        RF69_REG_RSSICONFIG     => 0x23,
        RF69_REG_RSSIVALUE      => 0x24,
        RF69_REG_DIOMAPPING1    => 0x25,
        RF69_REG_DIOMAPPING2    => 0x26,
        RF69_REG_IRQFLAGS1		=> 0x27,
        RF69_REG_IRQFLAGS2		=> 0x28,
        RF69_REG_RSSITHRESH		=> 0x29,
        RF69_REG_RXTIMEOUT1     => 0x2A,
        RF69_REG_RXTIMEOUT2     => 0x2B,
        RF69_REG_PREAMBLEMSB    => 0x2C,
        RF69_REG_PREAMBLELSB	=> 0x2D,
        RF69_REG_SYNCCONFIG		=> 0x2E,
        RF69_REG_SYNCVALUE1		=> 0x2F,
        RF69_REG_SYNCVALUE2		=> 0x30,
        RF69_REG_SYNCVALUE3		=> 0x31,
        RF69_REG_SYNCVALUE4		=> 0x32,
        RF69_REG_SYNCVALUE5     => 0x33,
        RF69_REG_SYNCVALUE6     => 0x34,
        RF69_REG_SYNCVALUE7     => 0x35,
        RF69_REG_SYNCVALUE8     => 0x36,
        RF69_REG_PACKETCONFIG1  => 0x37,
        RF69_REG_PAYLOADLEN     => 0x38,
        RF69_REG_NODEADDRESS    => 0x39,
        RF69_REG_BROADCASTADDRESS => 0x3A,
        RF69_REG_AUTOMODES      => 0x3B,
        RF69_REG_FIFOTHRESH     => 0x3C,
        RF69_REG_PACKETCONFIG2  => 0x3D,
        RF69_REG_AESKEY1        => 0x3E,
        RF69_REG_AESKEY2        => 0x3F,
        RF69_REG_AESKEY3        => 0x40,
        RF69_REG_AESKEY4        => 0x41,
        RF69_REG_AESKEY5        => 0x42,
        RF69_REG_AESKEY6        => 0x43,
        RF69_REG_AESKEY7        => 0x44,
        RF69_REG_AESKEY8        => 0x45,
        RF69_REG_AESKEY9        => 0x46,
        RF69_REG_AESKEY10       => 0x47,
        RF69_REG_AESKEY11       => 0x48,
        RF69_REG_AESKEY12       => 0x49,
        RF69_REG_AESKEY13       => 0x4A,
        RF69_REG_AESKEY14       => 0x4B,
        RF69_REG_AESKEY15       => 0x4C,
        RF69_REG_AESKEY16       => 0x4D,
        RF69_REG_TEMP1          => 0x4E,
        RF69_REG_TEMP2          => 0x4F,
        
        RF69_REG_TESTLNA        => 0x58,
        RF69_REG_TESTPA1        => 0x5A,
        RF69_REG_TESTPA2        => 0x5C,
        RF69_REG_TESTDAGC       => 0x6F,
        
        RF69_REG_TESTAFC        => 0x71,
        
        RF69_MASK_REG_WRITE          => 0x80,
    
        RF69_TRUE                    => 1,
        RF69_FALSE                   => 0,
        
        RF69_MASK_OPMODE_SEQOFF      => 0x80,
        RF69_MASK_OPMODE_LISTENON    => 0x40,
        RF69_MASK_OPMODE_LISTENABORT => 0x20,
        RF69_MASK_OPMODE_RX          => 0x10,
        RF69_MASK_OPMODE_TX          => 0x0C,
        RF69_MASK_OPMODE_FS          => 0x08,
        RF69_MASK_OPMODE_SB          => 0x04,
        
        RF69_MASK_MODEREADY          => 0x80,
        RF69_MASK_FIFONOTEMPTY       => 0x40,
        
        RF69_MASK_FIFOLEVEL		    => 0x20,
        RF69_MASK_FIFOOVERRUN	    => 0x10,
        RF69_MASK_PACKETSENT		=> 0x08,
        RF69_MASK_TXREADY		    => 0x20,
        RF69_MASK_PACKETMODE		=> 0x60,
        RF69_MASK_MODULATION		=> 0x18,
        RF69_MASK_PAYLOADRDY		=> 0x04,
        RF69_MASK_REGDATAMODUL_FSK	=> 0x00,  # Modulation scheme FSK
        RF69_MASK_REGDATAMODUL_OOK	=> 0x08,  # Modulation scheme OOK
        
        RF69_VAL_AFCCTRLS		=> 0x00,  # standard AFC routine
        RF69_VAL_AFCCTRLI		=> 0x20,  # improved AFC routine
        RF69_VAL_LNA50			=> 0x08,  # LNA input impedance 50 ohms
        RF69_VAL_LNA50G			=> 0x0E,  # LNA input impedance 50 ohms, LNA gain -> 48db
        RF69_VAL_LNA200			=> 0x88,  # LNA input impedance 200 ohms
        RF69_VAL_RXBW60			=> 0x43,  # channel filter bandwidth 10kHz -> 60kHz  page:26
        RF69_VAL_RXBW120		=> 0x41,  # channel filter bandwidth 120kHz
        RF69_VAL_AFCFEIRX		=> 0x04,  # AFC is performed each time RX mode is entered
        RF69_VAL_RSSITHRESH220	=> 0xDC,  # RSSI threshold => 0xE4 -> => 0xDC (220)
        RF69_VAL_PREAMBLELSB3	=> 0x03,  # preamble size LSB 3
        RF69_VAL_PREAMBLELSB5	=> 0x05,  # preamble size LSB 5
    },
    
    mcp3adc => {
        # msb = channels, lsb = hsb return value mask - 10 bit = 0x03, 12 bit = 0x0F
        MCP3004 => 0x0403, # 4 channels, 10 bit
        MCP3008 => 0x0803, # 8 channels, 10 bit
        MCP3204 => 0x040F, # 4 channels, 12 bit
        MCP3208 => 0x080F, # 8 channels, 12 bit
        
        MCP3ADC_CHAN_0    => 0b00001000,  # single-ended CH0
        MCP3ADC_CHAN_1    => 0b00001001,  # single-ended CH1
        MCP3ADC_CHAN_2    => 0b00001010,  # single-ended CH2
        MCP3ADC_CHAN_3    => 0b00001011,  # single-ended CH3
        MCP3ADC_CHAN_4    => 0b00001100,  # single-ended CH4
        MCP3ADC_CHAN_5    => 0b00001101,  # single-ended CH5
        MCP3ADC_CHAN_6    => 0b00001110,  # single-ended CH6
        MCP3ADC_CHAN_7    => 0b00001111,  # single-ended CH7
        MCP3ADC_DIFF_0_1  => 0b00000000,  # differential +CH0 -CH1
        MCP3ADC_DIFF_1_0  => 0b00000001,  # differential -CH0 +CH1
        MCP3ADC_DIFF_2_3  => 0b00000010,  # differential +CH2 -CH3
        MCP3ADC_DIFF_3_2  => 0b00000011,  # differential -CH2 +CH3
        MCP3ADC_DIFF_4_5  => 0b00000100,  # differential +CH4 -CH5
        MCP3ADC_DIFF_5_4  => 0b00000101,  # differential -CH4 +CH5
        MCP3ADC_DIFF_6_7  => 0b00000110,  # differential +CH6 -CH7
        MCP3ADC_DIFF_7_6  => 0b00000111,  # differential -CH6 +CH7
        
        MCP3008_S0        => 0b00001000,  # single-ended CH0
        MCP3008_S1        => 0b00001001,  # single-ended CH1
        MCP3008_S2        => 0b00001010,  # single-ended CH2
        MCP3008_S3        => 0b00001011,  # single-ended CH3
        MCP3008_S4        => 0b00001100,  # single-ended CH4
        MCP3008_S5        => 0b00001101,  # single-ended CH5
        MCP3008_S6        => 0b00001110,  # single-ended CH6
        MCP3008_S7        => 0b00001111,  # single-ended CH7
        MCP3008_DIFF_0_1  => 0b00000000,  # differential +CH0 -CH1
        MCP3008_DIFF_1_0  => 0b00000001,  # differential -CH0 +CH1
        MCP3008_DIFF_2_3  => 0b00000010,  # differential +CH2 -CH3
        MCP3008_DIFF_3_2  => 0b00000011,  # differential -CH2 +CH3
        MCP3008_DIFF_4_5  => 0b00000100,  # differential +CH4 -CH5
        MCP3008_DIFF_5_4  => 0b00000101,  # differential -CH4 +CH5
        MCP3008_DIFF_6_7  => 0b00000110,  # differential +CH6 -CH7
        MCP3008_DIFF_7_6  => 0b00000110,  # differential -CH6 +CH7
        
        MCP3208_S0        => 0b00001000,  # single-ended CH0
        MCP3208_S1        => 0b00001001,  # single-ended CH1
        MCP3208_S2        => 0b00001010,  # single-ended CH2
        MCP3208_S3        => 0b00001011,  # single-ended CH3
        MCP3208_S4        => 0b00001100,  # single-ended CH4
        MCP3208_S5        => 0b00001101,  # single-ended CH5
        MCP3208_S6        => 0b00001110,  # single-ended CH6
        MCP3208_S7        => 0b00001111,  # single-ended CH7
        MCP3208_DIFF_0_1  => 0b00000000,  # differential +CH0 -CH1
        MCP3208_DIFF_1_0  => 0b00000001,  # differential -CH0 +CH1
        MCP3208_DIFF_2_3  => 0b00000010,  # differential +CH2 -CH3
        MCP3208_DIFF_3_2  => 0b00000011,  # differential -CH2 +CH3
        MCP3208_DIFF_4_5  => 0b00000100,  # differential +CH4 -CH5
        MCP3208_DIFF_5_4  => 0b00000101,  # differential -CH4 +CH5
        MCP3208_DIFF_6_7  => 0b00000110,  # differential +CH6 -CH7
        MCP3208_DIFF_7_6  => 0b00000110,  # differential -CH6 +CH7
        
        MCP3004_S0        => 0b00001000,  # single-ended CH0
        MCP3004_S1        => 0b00001001,  # single-ended CH1
        MCP3004_S2        => 0b00001010,  # single-ended CH2
        MCP3004_S3        => 0b00001011,  # single-ended CH3
        MCP3004_DIFF_0_1  => 0b00000000,  # differential +CH0 -CH1
        MCP3004_DIFF_1_0  => 0b00000001,  # differential -CH0 +CH1
        MCP3004_DIFF_2_3  => 0b00000010,  # differential +CH2 -CH3
        MCP3004_DIFF_3_2  => 0b00000011,  # differential -CH2 +CH3
        
        MCP3204_S0        => 0b00001000,  # single-ended CH0
        MCP3204_S1        => 0b00001001,  # single-ended CH1
        MCP3204_S2        => 0b00001010,  # single-ended CH2
        MCP3204_S3        => 0b00001011,  # single-ended CH3
        MCP3204_DIFF_0_1  => 0b00000000,  # differential +CH0 -CH1
        MCP3204_DIFF_1_0  => 0b00000001,  # differential -CH0 +CH1
        MCP3204_DIFF_2_3  => 0b00000010,  # differential +CH2 -CH3
        MCP3204_DIFF_3_2  => 0b00000011,  # differential -CH2 +CH3
        
    },
    
    mcp4dac => {
        MCP_DAC_RESOLUTION_08 => $MCP_DAC_RESOLUTION_08,
        MCP_DAC_RESOLUTION_10 => $MCP_DAC_RESOLUTION_10,
        MCP_DAC_RESOLUTION_12 => $MCP_DAC_RESOLUTION_12,
        MCP_DAC_CAN_BUFFER    => $MCP_DAC_CAN_BUFFER,
        MCP_DAC_DUAL_CHANNEL  => $MCP_DAC_DUAL_CHANNEL,
    
        MCP_DAC_CHANNEL_A => 0x00,
        MCP_DAC_CHANNEL_B => 0x8000,
        MCP_DAC_BUFFER    => 0x4000,
        MCP_DAC_GAIN      => 0x00,
        MCP_DAC_NO_GAIN   => 0x2000,
        MCP_DAC_LIVE      => 0x1000,
        MCP_DAC_SHUTDOWN  => 0x00,
        
        MCP4801 =>  0x100|$MCP_DAC_RESOLUTION_08,
        MCP4811 =>  0x200|$MCP_DAC_RESOLUTION_10,
        MCP4821 =>  0x300|$MCP_DAC_RESOLUTION_12,
        MCP4802 =>  0x400|$MCP_DAC_RESOLUTION_08|$MCP_DAC_DUAL_CHANNEL,
        MCP4812 =>  0x500|$MCP_DAC_RESOLUTION_10|$MCP_DAC_DUAL_CHANNEL,
        MCP4822 =>  0x600|$MCP_DAC_RESOLUTION_12|$MCP_DAC_DUAL_CHANNEL,
        MCP4901 =>  0x700|$MCP_DAC_RESOLUTION_08|$MCP_DAC_CAN_BUFFER,
        MCP4911 =>  0x800|$MCP_DAC_RESOLUTION_10|$MCP_DAC_CAN_BUFFER,
        MCP4921 =>  0x900|$MCP_DAC_RESOLUTION_12|$MCP_DAC_CAN_BUFFER,
        MCP4902 =>  0xA00|$MCP_DAC_RESOLUTION_08|$MCP_DAC_DUAL_CHANNEL|$MCP_DAC_CAN_BUFFER,
        MCP4912 =>  0xB00|$MCP_DAC_RESOLUTION_10|$MCP_DAC_DUAL_CHANNEL|$MCP_DAC_CAN_BUFFER,
        MCP4922 =>  0xC00|$MCP_DAC_RESOLUTION_12|$MCP_DAC_DUAL_CHANNEL|$MCP_DAC_CAN_BUFFER,
    },
    
    openthings => {
        
        OPENTHINGS_MANUFACTURER_ENERGENIE   => 0x04,
        OPENTHINGS_MANUFACTURER_SENTEC      => 0x01,
        OPENTHINGS_MANUFACTURER_HILDERBRAND => 0x02,
        OPENTHINGS_MANUFACTURER_RASPBERRY   => 0x3F,
        
        OPENTHINGS_PARAM_ALARM           => 0x21,
        OPENTHINGS_PARAM_DEBUG_OUTPUT    => 0x2D,
        OPENTHINGS_PARAM_IDENTIFY        => 0x3F,
        OPENTHINGS_PARAM_SOURCE_SELECTOR => 0x40,
        OPENTHINGS_PARAM_WATER_DETECTOR  => 0x41,
        OPENTHINGS_PARAM_GLASS_BREAKAGE  => 0x42,
        OPENTHINGS_PARAM_CLOSURES        => 0x43,
        OPENTHINGS_PARAM_DOOR_BELL       => 0x44,
        OPENTHINGS_PARAM_ENERGY          => 0x45,
        OPENTHINGS_PARAM_FALL_SENSOR     => 0x46,
        OPENTHINGS_PARAM_GAS_VOLUME      => 0x47,
        OPENTHINGS_PARAM_AIR_PRESSURE    => 0x48,
        OPENTHINGS_PARAM_ILLUMINANCE     => 0x49,
        OPENTHINGS_PARAM_LEVEL           => 0x4C,
        OPENTHINGS_PARAM_RAINFALL        => 0x4D,
        OPENTHINGS_PARAM_APPARENT_POWER  => 0x50,
        OPENTHINGS_PARAM_POWER_FACTOR    => 0x51,
        OPENTHINGS_PARAM_REPORT_PERIOD   => 0x52,
        OPENTHINGS_PARAM_SMOKE_DETECTOR  => 0x53,
        OPENTHINGS_PARAM_TIME_AND_DATE   => 0x54,
        OPENTHINGS_PARAM_VIBRATION       => 0x56,
        OPENTHINGS_PARAM_WATER_VOLUME    => 0x57,
        OPENTHINGS_PARAM_WIND_SPEED      => 0x58,
        OPENTHINGS_PARAM_GAS_PRESSURE    => 0x61,
        OPENTHINGS_PARAM_BATTERY_LEVEL   => 0x62,
        OPENTHINGS_PARAM_CO_DETECTOR     => 0x63,
        OPENTHINGS_PARAM_DOOR_SENSOR     => 0x64,
        OPENTHINGS_PARAM_EMERGENCY       => 0x65,
        OPENTHINGS_PARAM_FREQUENCY       => 0x66,
        OPENTHINGS_PARAM_GAS_FLOW_RATE   => 0x67,
        OPENTHINGS_PARAM_RELATIVE_HUMIDITY =>0x68,
        OPENTHINGS_PARAM_CURRENT         => 0x69,
        OPENTHINGS_PARAM_JOIN            => 0x6A,
        OPENTHINGS_PARAM_LIGHT_LEVEL     => 0x6C,
        OPENTHINGS_PARAM_MOTION_DETECTOR => 0x6D,
        OPENTHINGS_PARAM_OCCUPANCY       => 0x6F,
        OPENTHINGS_PARAM_REAL_POWER      => 0x70,
        OPENTHINGS_PARAM_REACTIVE_POWER  => 0x71,
        OPENTHINGS_PARAM_ROTATION_SPEED  => 0x72,
        OPENTHINGS_PARAM_SWITCH_STATE    => 0x73,
        OPENTHINGS_PARAM_TEMPERATURE     => 0x74,
        OPENTHINGS_PARAM_VOLTAGE         => 0x76,
        OPENTHINGS_PARAM_WATER_FLOW_RATE => 0x77,
        OPENTHINGS_PARAM_WATER_PRESSURE  => 0x78,
        OPENTHINGS_PARAM_PHASE_1_POWER   => 0x79,
        OPENTHINGS_PARAM_PHASE_2_POWER   => 0x7A,
        OPENTHINGS_PARAM_PHASE_3_POWER   => 0x7B,
        OPENTHINGS_PARAM_3_PHASE_TOTAL   => 0x7C,
        
        # from Energenie examples
        OPENTHINGS_PARAM_TEST            => 0xAA,
        OPENTHINGS_WRITE_MASK            => 0x80,
        
        OPENTHINGS_UINT        => 0x00,
        OPENTHINGS_UINT_BP4    => 0x10,
        OPENTHINGS_UINT_BP8    => 0x20,
        OPENTHINGS_UINT_BP12   => 0x30,
        OPENTHINGS_UINT_BP16   => 0x40,
        OPENTHINGS_UINT_BP20   => 0x50,
        OPENTHINGS_UINT_BP24   => 0x60,
        OPENTHINGS_CHAR        => 0x70,
        OPENTHINGS_SINT        => 0x80,
        OPENTHINGS_SINT_BP8    => 0x90,
        OPENTHINGS_SINT_BP16   => 0xA0,
        OPENTHINGS_SINT_BP24   => 0xB0,
        OPENTHINGS_ENUMERATION => 0xC0,
        # D0,E0 RESERVED
        OPENTHINGS_FLOAT       => 0xF0,
    },
    
    energenie => {
        ENERGENIE_ENER314_DUMMY_GROUP => 0xFFFFFF,
        
        ENERGENIE_MANUFACTURER_ID    => 0x04,
    
        ENERGENIE_PRODUCT_ID_MIHO004 => 0x01,
        ENERGENIE_PRODUCT_ID_MIHO005 => 0x02,
        ENERGENIE_PRODUCT_ID_MIHO013 => 0x03,
        ENERGENIE_PRODUCT_ID_MIHO006 => 0x05,
        
        ENERGENIE_PRODUCT_ID_MIHO032 => 0x0C,
        ENERGENIE_PRODUCT_ID_MIHO033 => 0x0D,
        
        ENERGENIE_DEFAULT_CRYPTSEED  => 242,
        ENERGENIE_DEFAULT_CRYPTPIP   => 0x0100,
        
        ENERGENIE_FIFOTHRESH_FSK    => 0x81, # Condition to start packet transmission: at least one byte in FIFO
        ENERGENIE_FIFOTHRESH_OOK    => 0x1E, # Condition to start packet transmission: wait for 30 bytes in FIFO
        ENERGENIE_TXOOK_REPEAT_RATE => 25,
        ENERGENIE_MESSAGE_BUF_SIZE  => 66,
        ENERGENIE_MAX_FIFO_SIZE     => 66,
        ENERGENIE_NODEADDRESS01	 => 0x01,  # Node address used in address filtering
        ENERGENIE_NODEADDRESS04	 => 0x04,  # Node address used in address filtering
        ENERGENIE_FDEVMSB_FSK	     => 0x01,  # frequency deviation 5kHz => 0x0052 -> 30kHz => 0x01EC
        ENERGENIE_FDEVLSB_FSK		 => 0xEC,  # frequency deviation 5kHz => 0x0052 -> 30kHz => 0x01EC
        ENERGENIE_FDEVMSB_OOK	     => 0,
        ENERGENIE_FDEVLSB_OOK		 => 0,
        ENERGENIE_FRMSB_434		 => 0x6C,  # carrier freq -> 434.3MHz => 0x6C9333
        ENERGENIE_FRMID_434		 => 0x93,  # carrier freq -> 434.3MHz => 0x6C9333
        ENERGENIE_FRLSB_434		 => 0x33,  # carrier freq -> 434.3MHz => 0x6C9333
        ENERGENIE_FRMSB_433		 => 0x6C,  # carrier freq -> 433.92MHz => 0x6C7AE1
        ENERGENIE_FRMID_433		 => 0x7A,  # carrier freq -> 433.92MHz => 0x6C7AE1
        ENERGENIE_FRLSB_433		 => 0xE1,  # carrier freq -> 433.92MHz => 0x6C7AE1
        ENERGENIE_SYNCVALUE1_FSK	 => 0x2D,  # 1st byte of Sync word
        ENERGENIE_SYNCVALUE2_FSK	 => 0xD4,  # 2nd byte of Sync word
        ENERGENIE_SYNCVALUE1_OOK	 => 0x80,  # 1nd byte of Sync word
        
        ENERGENIE_SYNC_SIZE_2		=> 0x88,  # Size of the Synch word = 2 (SyncSize + 1)
        ENERGENIE_SYNC_SIZE_4		=> 0x98,  # Size of the Synch word = 4 (SyncSize + 1)
        
        ENERGENIE_PACKETCONFIG1_FSK	      => 0xA2,  # Variable length, Manchester coding, Addr must match NodeAddress
        ENERGENIE_PACKETCONFIG1_FSK_NOADDR   => 0xA0,  # Variable length, Manchester coding
        ENERGENIE_PACKETCONFIG1_OOK	      => 0,  # Fixed length, no Manchester coding
        ENERGENIE_NODEADDRESS                => 0x06, # Node address used in address filtering ( when enabled )
        
        ENERGENIE_PAYLOADLEN_OOK	=> 13 + 8 * 17,  # fixed OOK Payload Length
    },
    
    si470n => {
        SI4701 => 1,
        SI4702 => 2,
        SI4703 => 3,
    },
    
    pca9685 => {
        PCA_9685_SERVOTYPE_DEFAULT  => 1,
        PCA_9685_SERVOTYPE_EXT_1    => 2,
        PCA_9685_SERVOTYPE_EXT_2    => 3,
        PCA_9685_SERVOTYPE_SG90     => 4,
        
        PCA_9685_SERVO_CHANNEL_MASK => 0x0FFF,
        PCA_9685_FULL_MASK  => 0x1000,
        
        PCA_9685_SERVO_DIRECTION_CW => 1,
        PCA_9685_SERVO_DIRECTION_AC => 2,
    },
};

my $tagaliases = {
    mcp23x17 => [ qw( mcp23017 mcp23S17 ) ],
    rpi      => [ qw( raspberry ) ],
};

sub hipi_export_ok {
    my @names = ();
    for my $tag ( keys %$const ) {
        for my $cname ( keys %{$const->{$tag}} ) {
            push @names, $cname;
        }
    }
    return @names;
}

sub hipi_export_constants {
    my $constants = {};
    for my $tag ( keys %$const ) {
        for my $cname ( keys %{$const->{$tag}} ) {
            $constants->{$cname} = $const->{$tag}->{$cname};
        }
    }
    return $constants;
}

sub hipi_export_tags {
    my %tags = ();
    for my $tag ( keys %$const ) {
        my @names = ();
        for my $cname ( keys %{$const->{$tag}} ) {
            push @names, $cname;
        }
        $tags{$tag} = \@names;
        if(exists($tagaliases->{$tag})) {
            for my $alias ( @{ $tagaliases->{$tag} } ) {
                $tags{$alias} = \@names;
            }
        }
    }
    return %tags;
}

1;

__END__