Contents Up Previous Next

HiPi::BCM2835

The HiPi::BCM2835 module provides a Perl wrapper around Mike McCauley's bcm2835 C library.
( http://www.airspayce.com/mikem/bcm2835/ ).

Mike also provides his own Perl wrapper for the library - Device::BCM2835

HiPi::BCM2835 provides direct access to the peripheral registers of the Broadcom BCM2835 System On a Chip. (SOC)

It provides access to GPIO and other IO functions on the SOC, allowing access to all of the the GPIO pins exposed on the Raspberry Pi board so you can control and interface with various external devices.

It provides functions for reading digital inputs and setting digital outputs, using SPI and I2C, and for accessing the system timers. Pin event detection is supported by polling (interrupts are not supported).

Note that this is different to accessing these peripherals using kernel device drivers. Module HiPi::BCM2835 does not rely on kernel device drivers. It accesses the SOC addresses directly.

Access Permissions

Because HiPi::BCM2835 accesses the SOC registers directly via /dev/mem, it must run with the necessary root privileges to gain access to /dev/mem. This means you must start your Perl script with root privileges using sudo or from the root account. This always presents a security risk.

You can ameliorate the risk somewhat by reducing your process permissions to those of an ordinary user once HiPi::BCM2835 has opened and mapped the required areas of the SOC registers. The HiPi::Utils module provides a function to simplify this action.

  use HiPi::BCM2835;
  use HiPi::Utils;

  my($user, $group) = ('pi', 'pi');

  my $bcm = HiPi::BCM2835->new();

  # or using function type calls :
  # HiPi::BCM2835::bcm2835_init();

  HiPi::Utils::drop_permissions_name($user, $group);

Pin Identifiers and Other Constants

The functions and methods in HiPi::BCM2835 expect arguments for pin identifiers to be the internal GPIO numbers for the bcm2835 SOC in the Raspberry Pi.

To simplify your code the HiPi::Constant module will export a set of constants under the tag 'raspberry' that includes a list of Pin constants named for the pin position on the Raspberry Pi physical connectors.

use HiPi::Constant qw( :raspberry );

# this will export, amongst other things, the following 
# pin constants that you can pass to the HiPi::BCM2835 
# methods and functions

    RPI_PAD1_PIN_3 
    RPI_PAD1_PIN_5 
    RPI_PAD1_PIN_7 
    RPI_PAD1_PIN_8 
    RPI_PAD1_PIN_10 
    RPI_PAD1_PIN_11 
    RPI_PAD1_PIN_12 
    RPI_PAD1_PIN_13
    RPI_PAD1_PIN_15 
    RPI_PAD1_PIN_16 
    RPI_PAD1_PIN_18 
    RPI_PAD1_PIN_19
    RPI_PAD1_PIN_21 
    RPI_PAD1_PIN_22 
    RPI_PAD1_PIN_23 
    RPI_PAD1_PIN_24 
    RPI_PAD1_PIN_26
 
# on Model B Revision 2 or a Model A boards
# then constants for Pad 5 are also exported

    RPI_PAD5_PIN_3 
    RPI_PAD5_PIN_4 
    RPI_PAD5_PIN_5 
    RPI_PAD5_PIN_6

# the constant RPI_BOARD_REVISION is also exported
# under the :raspberry tag and will be defined as 
# 1 or 2 depending on your board revision 

The Hipi::Constant module exports several other sets of constants which may be useful in using HiPi::BCM2835.

See HiPi::Constant documentation

The HiPi::BCM2835 exports its own set of constants as noted below. The pin constants exported by HiPi::Constant do not require that differentiate between Raspberry Pi board revisions in your code for the Pad 1 GPIO pins.

Object Oriented Interface

The module provides both a functional and an object oriented interface. The OO interface is described here.

Constructor

my $bcm = HiPi::BCM2835->new();

GPIO Register Access

These functions allow you to control the GPIO interface. You can set the 
function of each GPIO pin, read the input state and set the output state.
$bcm->delay( $millis );
    $millis  Delay in milliseconds

    Delays for the specified number of milliseconds. Uses nanosleep(), 
    and therefore does not use CPU until the time is up. However, you are 
    at the mercy of nanosleep(). From the manual for nanosleep(): If the 
    interval specified in req is not an exact multiple of the granularity 
    underlying clock (see time(7)), then the interval will be rounded up 
    to the next multiple. Furthermore, after the sleep completes, there 
    may still be a delay before the CPU becomes free to once again execute 
    the calling thread.
$bcm->delayMicroseconds( $micros );
    $micros  Delay in microseconds

    Delays for the specified number of microseconds. Uses a combination of 
    nanosleep() and a busy wait loop on the BCM2835 system timers, However, 
    you are at the mercy of nanosleep(). From the manual for nanosleep(): 
    If the interval specified in req is not an exact multiple of the
    granularity underlying clock (see time(7)), then the interval will be 
    rounded up to the next multiple. Furthermore, after the sleep completes, 
    there may still be a delay before the CPU becomes free to once again 
    execute the calling thread. For times less than about 450 microseconds, 
    uses a busy wait on the System Timer. It is reported that a delay of 0 
    microseconds on RaspberryPi will in fact result in a delay of about 
    80 microseconds. Your mileage may vary.
my $level = $bcm->gpio_lev( $pin );
    $pin  GPIO Pin Number
    
    Reads the current level on the specified pin and returns either 
    HIGH or LOW ( 1 or 0 ). Works whether or not the pin is an input or 
    an output.
$bcm->gpio_set( $pin );
    $pin  GPIO Pin Number
    
    Sets the specified pin output to HIGH.
    See also: $bcm->gpio_write();
$bcm->gpio_clr( $pin );
    $pin  GPIO Pin Number

    Sets the specified pin output to LOW.

    See also: $bcm->gpio_write();
$bcm->gpio_write( $pin, $value );
    $pin    GPIO Pin Number
    $value  HIGH or LOW  ( 1 or 0 )

    Sets the output state of the specified pin
$bcm->gpio_set_multi( $mask );
    $mask   Mask of pins to affect. Use eg: 
            (1 << RPI_GPIO_P1_03) | (1 << RPI_GPIO_P1_05)

    Sets any of the first 32 GPIO output pins specified in the mask 
    to HIGH.
    See also: $bcm->gpio_write_multi()
$bcm->gpio_clr_multi( $mask );
    $mask  Mask of pins to affect. 

    Sets any of the first 32 GPIO output pins specified in the mask to LOW.
    Use eg: (1 << RPI_GPIO_P1_03) | (1 << RPI_GPIO_P1_05)
    
    See also: $bcm->gpio_write_multi();
$bcm->gpio_write_multi( $mask, $value );
    $mask   Mask of pins to affect. Use eg: 
            (1 << RPI_GPIO_P1_03) | (1 << RPI_GPIO_P1_05)
    $value  HIGH or LOW  ( 1 or 0 )
	
    Sets any of the first 32 GPIO output pins specified in the $mask 
    to the state given by $value;
$bcm->gpio_write_mask( $value, $mask );
    $value  values required for each bit masked in by mask
            eg: (1 << RPI_GPIO_P1_03) | (1 << RPI_GPIO_P1_05)
    $mask   Mask of pins to affect. Use eg: 
            (1 << RPI_GPIO_P1_03) | (1 << RPI_GPIO_P1_05)
 
    Sets the first 32 GPIO output pins specified in the $mask to the 
    corresponding value in the $value mask
$bcm->gpio_fsel( $pin, $mode );
    $pin    GPIO Pin Number
    $mode   Mode to set the pin to, one of 

            BCM2835_GPIO_FSEL_INPT
            BCM2835_GPIO_FSEL_OUTP
            BCM2835_GPIO_FSEL_ALT0
            BCM2835_GPIO_FSEL_ALT1
            BCM2835_GPIO_FSEL_ALT2
            BCM2835_GPIO_FSEL_ALT3
            BCM2835_GPIO_FSEL_ALT4
            BCM2835_GPIO_FSEL_ALT5
	
    Sets the Function Select register for the given pin, which configures
    the pin as Input, Output or one of the 6 alternate functions.

    You may use HiPi::Constant values instead which can be exported 
    from the HiPi::Constant module under the tag :raspberry

    use HiPi::Constant qw( :raspberry );

    # exported constant will include:
            RPI_PINMODE_INPT 
            RPI_PINMODE_OUTP 
            RPI_PINMODE_ALT0 
            RPI_PINMODE_ALT1
            RPI_PINMODE_ALT2 
            RPI_PINMODE_ALT3 
            RPI_PINMODE_ALT4 
            RPI_PINMODE_ALT5
$bcm->gpio_set_pud( $pin, $pud );
    $pin  GPIO Pin Number
    $pud  The desired pull up / pull down mode. One of
            BCM2835_GPIO_PUD_OFF
            BCM2835_GPIO_PUD_DOWN
            BCM2835_GPIO_PUD_UP

    Sets the Pull-up/down mode for the specified pin. This is more 
    convenient than clocking the mode in with $bcm->gpio_pud() and
    $bcm->gpio_pudclk().

    You may use HiPi::Constant values instead which can be exported 
    from the HiPi::Constant module under the tag :raspberry

    use HiPi::Constant qw( :raspberry );

    # exported constant will include:
            RPI_PUD_OFF 
            RPI_PUD_DOWN
            RPI_PUD_UP
$bcm->gpio_fen( $pin );
    $pin  GPIO Pin Number

    Enable Falling Edge Detect Enable for the specified pin. When a 
    falling edge is detected, sets the appropriate pin in Event Detect 
    Status. The GPRENn registers use synchronous edge detection. This 
    means the input signal is sampled using the system clock and then it 
    is looking for a ?100? pattern on the sampled signal. This has the 
    effect of suppressing glitches.
$bcm->gpio_clr_fen( $pin );
    $pin  GPIO Pin Number

    Disable Falling Edge Detect Enable for the specified pin.
$bcm->gpio_ren( $pin );
    $pin  GPIO Pin Number

    Enable Rising Edge Detect Enable for the specified pin. When a rising
    edge is detected, sets the appropriate pin in Event Detect Status. 
    The GPRENn registers use synchronous edge detection. This means the 
    input signal is sampled using the system clock and then it is looking 
    for a ?011? pattern on the sampled signal. This has the effect of 
    suppressing glitches.
$bcm->gpio_clr_ren( $pin );
    $pin  GPIO Pin Number

    Disable Rising Edge Detect Enable for the specified pin.
$bcm->gpio_afen( $pin );
    $pin  GPIO Pin Number

    Enable Asynchronous Falling Edge Detect Enable for the specified pin. 
    When a falling edge is detected, sets the appropriate pin in Event 
    Detect Status. Asynchronous means the incoming signal is not sampled 
    by the system clock. As such falling edges of very short duration can 
    be detected.
$bcm->gpio_clr_afen( $pin );
    $pin  GPIO Pin Number

    Disable Asynchronous Falling Edge Detect Enable for the specified pin.
$bcm->gpio_aren( $pin );
    $pin  GPIO Pin Number

    Enable Asynchronous Rising Edge Detect Enable for the specified pin.
    When a rising edge is detected, sets the appropriate pin in Event 
    Detect Status. Asynchronous means the incoming signal is not sampled 
    by the system clock. As such rising edges of very short duration can 
    be detected.
$bcm->gpio_clr_aren( $pin );
    $pin  GPIO Pin Number

    Disable Asynchronous Rising Edge Detect Enable for the specified pin.
$bcm->gpio_len( $pin );
    $pin  GPIO Pin Number

    Enable Low Detect Enable for the specified pin. When a LOW level is
    detected on the pin, sets the appropriate pin in Event Detect Status.
$bcm->gpio_clr_len( $pin );
    $pin  GPIO Pin Number

    Disable Low Detect Enable for the specified pin.
$bcm->gpio_hen( $pin );
    $pin  GPIO Pin Number

    Enable High Detect Enable for the specified pin. When a HIGH level is
    detected on the pin, sets the appropriate pin in Event Detect Status.
$bcm->gpio_clr_hen( $pin );
    $pin  GPIO Pin Number

    Disable High Detect Enable for the specified pin.
my $eds = $bcm->gpio_eds( $pin );
    $pin  GPIO Pin Number

    Event Detect Status. Tests whether the specified pin has detected a 
    level or edge as requested by $bcm->gpio_ren(), $bcm->gpio_fen(), 
    $bcm->gpio_hen(), $bcm->gpio_len(), $bcm->gpio_aren(),  or
    $bcm->gpio_afen(). 
    Clear the flag for a given pin by calling $bcm->gpio_set_eds($pin);
   
    Returns true if the event detect status for the given pin is true.
$bcm->gpio_set_eds( $pin );
   $pin  GPIO Pin Number

    Sets the Event Detect Status register for a given pin to 1, which has 
    the effect of clearing the flag. Use this afer seeing an Event Detect 
    Status on the pin.
my $bits = $bcm->gpio_pad( $group );
    $group   The GPIO pad group number, one of
             BCM2835_PAD_GROUP_GPIO_0_27
             BCM2835_PAD_GROUP_GPIO_28_45
             BCM2835_PAD_GROUP_GPIO_46_53

    Reads and returns the Pad Control for the given GPIO group.
    The return value is a mask of bits from:
             BCM2835_PAD_SLEW_RATE_UNLIMITED
             BCM2835_PAD_HYSTERESIS_ENABLED
             BCM2835_PAD_DRIVE_2mA
             BCM2835_PAD_DRIVE_4mA
             BCM2835_PAD_DRIVE_6mA
             BCM2835_PAD_DRIVE_8mA
             BCM2835_PAD_DRIVE_10mA 
             BCM2835_PAD_DRIVE_12mA
             BCM2835_PAD_DRIVE_14mA
             BCM2835_PAD_DRIVE_16mA
$bcm->gpio_set_pad( $group, $control );
    $group   The GPIO pad group number, one of
             BCM2835_PAD_GROUP_GPIO_0_27
             BCM2835_PAD_GROUP_GPIO_28_45
             BCM2835_PAD_GROUP_GPIO_46_53
    $control Mask of bits from the following
             BCM2835_PAD_SLEW_RATE_UNLIMITED
             BCM2835_PAD_HYSTERESIS_ENABLED
             BCM2835_PAD_DRIVE_2mA
             BCM2835_PAD_DRIVE_4mA
             BCM2835_PAD_DRIVE_6mA
             BCM2835_PAD_DRIVE_8mA
             BCM2835_PAD_DRIVE_10mA 
             BCM2835_PAD_DRIVE_12mA
             BCM2835_PAD_DRIVE_14mA
             BCM2835_PAD_DRIVE_16mA
   
    Sets the Pad Control for the given GPIO group.
$bcm->gpio_pud( $pud );
    $pud  The desired pull up / pull down mode. One of
             BCM2835_GPIO_PUD_OFF
             BCM2835_GPIO_PUD_DOWN
             BCM2835_GPIO_PUD_UP

    Sets the Pull-up/down register for the given pin. This is used with
    $bcm->gpio_pudclk( $pin ) to set the Pull-up/down resistor for the 
    given pin. However, it is usually more convenient to use 
    $bcm->gpio_set_pud($pin) which combines both actions into a single
    call.

    You may use HiPi::Constant values instead which can be exported 
    from the HiPi::Constant module under the tag :raspberry

    use HiPi::Constant qw( :raspberry );

    # exported constant will include:
             RPI_PUD_OFF 
             RPI_PUD_DOWN
             RPI_PUD_UP
$bcm->gpio_pudclk( $pin, $on );
    $pin  GPIO Pin Number
    $on   HIGH ( 1 ) to clock the value from $bcm->gpio_pud() into the pin. 
          LOW  ( 0 ) to remove
    
    Clocks the Pull-up/down value, set earlier by a call to 
    $bcm->gpio_pud( $pid ), into the pin.

SPI Access

These functions let you use SPI0 (Serial Peripheral Interface) to interface with an external SPI device by accessing the Broadcom peripheral directly. You may wish to use the kernel device driver instead as wrapped by HiPi::Device::SPI.
$bcm->spi_begin();
    Start SPI operations. Forces RPi SPI0 pins P1-19 (MOSI), P1-21 (MISO),
    P1-23 (CLK), P1-24 (CE0) and P1-26 (CE1) to alternate function ALT0, 
    which enables those pins for SPI interface. You should call 
    $bcm->spi_end() when all SPI funcitons are complete to return the pins
    to their default functions
$bcm->spi_end();
    End SPI operations. SPI0 pins P1-19 (MOSI), P1-21 (MISO), P1-23 (CLK), 
    P1-24 (CE0) and P1-26 (CE1) are returned to their default INPUT 
    behaviour.
$bcm->spi_chipSelect( $cs );
    $cs  Specifies the CS pins(s) that are used to activate the desired 
         slave. One of
             BCM2835_SPI_CS0      # select CS0
             BCM2835_SPI_CS1      # select CS1
             BCM2835_SPI_CS2      # select both
             BCM2835_SPI_CS_NONE  # select none

    Sets the chip select pin(s) When an bcm2835_spi_transfer() is made, 
    the selected pin(s) will be asserted during the transfer.
$bcm->spi_setBitOrder( $order );
    $order   The desired bit order, one of
             BCM2835_SPI_BIT_ORDER_LSBFIRST
             BCM2835_SPI_BIT_ORDER_MSBFIRST

    Sets the SPI bit order NOTE: currently has no effect. 
    Not supported by SPI0.
$bcm->spi_setChipSelectPolarity( $cs, $active );
    $cs       The chip select pin to affect
    $active   Whether the chip select pin is to be active HIGH

    Sets the chip select pin polarity for a given pin When an 
    $bcm->spi_transfer() occurs, the currently selected chip select 
    pin(s) will be asserted to the value given by active. When transfers 
    are not happening, the chip select pin(s) return to the complement
    (inactive) value.
$bcm->spi_setClockDivider( $divider );
    $divider   The desired SPI clock divider, one of 

      BCM2835_SPI_CLOCK_DIVIDER_65536  # 65536 = 262.144us = 3.814697260kHz
      BCM2835_SPI_CLOCK_DIVIDER_32768  # 32768 = 131.072us = 7.629394531kHz
      BCM2835_SPI_CLOCK_DIVIDER_16384  # 16384 = 65.536us = 15.25878906kHz
      BCM2835_SPI_CLOCK_DIVIDER_8192   # 8192 = 32.768us = 30/51757813kHz
      BCM2835_SPI_CLOCK_DIVIDER_4096   # 4096 = 16.384us = 61.03515625kHz
      BCM2835_SPI_CLOCK_DIVIDER_2048   # 2048 = 8.192us = 122.0703125kHz
      BCM2835_SPI_CLOCK_DIVIDER_1024   # 1024 = 4.096us = 244.140625kHz
      BCM2835_SPI_CLOCK_DIVIDER_512    # 512 = 2.048us = 488.28125kHz
      BCM2835_SPI_CLOCK_DIVIDER_256    # 256 = 1.024us = 976.5625MHz
      BCM2835_SPI_CLOCK_DIVIDER_128    # 128 = 512ns = = 1.953125MHz
      BCM2835_SPI_CLOCK_DIVIDER_64     # 64 = 256ns = 3.90625MHz
      BCM2835_SPI_CLOCK_DIVIDER_32     # 32 = 128ns = 7.8125MHz
      BCM2835_SPI_CLOCK_DIVIDER_16     # 16 = 64ns = 15.625MHz
      BCM2835_SPI_CLOCK_DIVIDER_8      # 8 = 32ns = 31.25MHz
      BCM2835_SPI_CLOCK_DIVIDER_4      # 4 = 16ns = 62.5MHz
      BCM2835_SPI_CLOCK_DIVIDER_2      # 2 = 8ns = 125MHz, fastest you can get
      BCM2835_SPI_CLOCK_DIVIDER_1      # 0 = 262.144us = 3.814697260kHz, 
                                       # same as 0/65536
    
    Sets the SPI clock divider and therefore the SPI clock speed. 
    Specifies the divider used to generate the SPI clock from the system
    clock. Figures below give the divider, clock period and clock 
    frequency. Clock divided is based on nominal base clock rate of 250MHz.
    It is reported that (contrary to the documentation) any even divider
    may used. The frequencies shown for each divider have been confirmed
    by measurement
$bcm->spi_setDataMode( $mode );
    $mode   The desired data mode, one of
            BCM2835_SPI_MODE0 
            BCM2835_SPI_MODE1
            BCM2835_SPI_MODE2
            BCM2835_SPI_MODE3  

    Sets the SPI data mode. Sets the clock polariy and phase
my $byte = $bcm->spi_transfer( $value );
    $value  The 8 bit data byte to write to MOSI

    Transfers one byte to and from the currently selected SPI slave. 
    Asserts the currently selected CS pins (as previously set by 
    $bcm->spi_chipSelect() during the transfer. Clocks the 8 bit value 
    out on MOSI, and simultaneously clocks in data from MISO. Returns 
    the read data byte from the slave. Uses polled transfer as per 
    section 10.6.1 of the BCM 2835 ARM Peripherls manual
my $buffout = $bcm->spi_transfern( $buffin );
    $buffin   The data to send

    Transfers any number of bytes to and from the currently selected 
    SPI slave using $bcm->spi_transfernb.
my $buffout = $bcm->spi_transfernb( $buffin );
    $buffin   The data to send

    Transfers any number of bytes to and from the currently selected 
    SPI slave. Asserts the currently selected CS pins (as previously 
    set by $bcm->spi_chipSelect() ) during the transfer. Clocks the 8 bit 
    bytes of $buffin out on MOSI, and simultaneously clocks in data from 
    MISO. The data read read from the slave is returned. Uses polled 
    transfer as per section 10.6.1 of the BCM 2835 ARM Peripherls manual.
$bcm->spi_writenb( $buffin );
    $buffin   The data to send

    Transfers any number of bytes to the currently selected SPI slave. 
    Asserts the currently selected CS pins (as previously set by 
    $bcm->spi_chipSelect) during the transfer.

I2C Access

These functions let you use I2C (The Broadcom Serial Control bus with the Philips I2C bus/interface version 2.1 January 2000.) to interface with an external I2C device. It is recommended that you do not use these methods directly but instead use an instance of HiPi::BCM2835::I2C.
$bcm->i2c_begin();
    Start I2C operations. Forces RPi I2C pins P1-03 (SDA) and P1-05 
    (SCL) to alternate function ALT0, which enables those pins for I2C
    interface. You should call $bcm->i2c_end() when all I2C functions 
    are complete to return the pins to their default functions
$bcm->i2c_end();
    End I2C operations. I2C pins P1-03 (SDA) and P1-05 (SCL) are 
    returned to their default INPUT behaviour.
my $buffout = $bcm->i2c_read( $numbytes );
    $numbytes  The number of bytes to read
    
    Transfers any number of bytes from the currently selected I2C slave.
    (as previously set by $bcm->i2cSetSlaveAddress)
$bcm->i2c_setClockDivider( $divider );
    $divider   The desired I2C clock divider, one of
           
    BCM2835_I2C_CLOCK_DIVIDER_2500 # 2500 = 10us = 100 kHz
    BCM2835_I2C_CLOCK_DIVIDER_626  # 622 = 2.504us = 399.3610 kHz
    BCM2835_I2C_CLOCK_DIVIDER_150  # 150 = 60ns = 1.666 MHz (default)
    BCM2835_I2C_CLOCK_DIVIDER_148  # 148 = 59ns = 1.689 MHz

    Sets the I2C clock divider and therefore the I2C clock speed.
$bcm->i2c_setSlaveAddress( $address );
    $address   The I2C slave address.
    
    Sets the I2C slave address.
my $result = $bcm->i2c_write( $buffer );
    $buffer   data to send
	
    Transfers any number of bytes to the currently selected I2C slave. 
    (as previously set by $bcm->i2c_setSlaveAddress).
    Returns true on success, false otherwise.

System Timer Access

Allows access to and delays using the System Timer Counter.
$bcm->st_delay( $offset, $micros );
    $offset   	Offset in microseconds
    $micros     Delay in microseconds

    Delays for the specified number of microseconds with offset.
my $count = $bcm->st_read();
    Returns value read from the System Timer Counter Lower 
    32 bits register

Low Level Register Access

These functions provide low level register access, and should not generally need to be used
my $result = $bcm->peri_read( $paddr );
    $paddr = Physical address to read from. See BCM2835_GPIO_BASE etc.

    Reads 32 bit value from a peripheral address The read is done twice, 
    and is therefore always safe in terms of manual section 1.3 
    Peripheral access precautions for correct memory ordering.
my $result = $bcm->peri_read_nb( $paddr );
    $paddr = Physical address to read from. See BCM2835_GPIO_BASE etc.

    Reads 32 bit value from a peripheral address without the read barrier.
    You should only use this when your code has previously called 
    $bcm->peri_read() within the same peripheral, and no other peripheral 
    access has occurred since.
$bcm->peri_set_bits( $paddr, $value, $mask);
    $paddr  Physical address to read from. See BCM2835_GPIO_BASE etc.
    $value  The 32 bit value to write, masked in by mask.
    $mask   Bitmask that defines the register bits that will be altered.

    Alters a number of bits in a 32 peripheral regsiter. It reads the 
    current value and then alters the bits deines as 1 in mask, according
    to the bit value in value. All other bits that are 0 in the mask are
    unaffected. Use this to alter a subset of the bits in a register. The 
    write is done twice, and is therefore always safe in terms of manual 
    section 1.3 Peripheral access precautions for correct memory ordering
$bmc->peri_write($paddr, $value);
    $paddr  Physical address to read from. See BCM2835_GPIO_BASE etc.
    $value  The 32 bit value to write

    Writes 32 bit value from a peripheral address The write is done twice,
    and is therefore always safe in terms of manual section 1.3 Peripheral
    access precautions for correct memory ordering
$bmc->peri_write_nb($paddr, $value);
    $paddr  Physical address to read from. See BCM2835_GPIO_BASE etc.
    $value  The 32 bit value to write

    Writes 32 bit value from a peripheral address without the write barrier
    You should only use this when your code has previously called 
    $bcm->peri_write() within the same peripheral, and no other peripheral 
    access has occurred since.

OO Interface Specific Methods

The HiPi::BCM2835 OO interface provides a few additional methods that are not available in the underlying bcm2835 library and are not available via the functional interface of this library. Some methods wrap functionality that are easily implemented in C but would require a more involved implementation in Perl.
my $pinobj = $bmc->get_pin( $pinid );
    $pinid  GPIO Pin Number

    returns an object instance of HiPi::BCM2835::Pin
my $function = $bmc->gpio_fget( $pin );
    $pin  GPIO Pin Number
    
    Returns the current function of the selected pin. Return
    value will be one of
            BCM2835_GPIO_FSEL_INPT
            BCM2835_GPIO_FSEL_OUTP
            BCM2835_GPIO_FSEL_ALT0
            BCM2835_GPIO_FSEL_ALT1
            BCM2835_GPIO_FSEL_ALT2
            BCM2835_GPIO_FSEL_ALT3
            BCM2835_GPIO_FSEL_ALT4
            BCM2835_GPIO_FSEL_ALT5

    You may use HiPi::Constant values instead which can be exported 
    from the HiPi::Constant module under the tag :raspberry

    use HiPi::Constant qw( :raspberry );

    # exported constant will include:
            RPI_PINMODE_INPT 
            RPI_PINMODE_OUTP 
            RPI_PINMODE_ALT0 
            RPI_PINMODE_ALT1
            RPI_PINMODE_ALT2 
            RPI_PINMODE_ALT3 
            RPI_PINMODE_ALT4 
            RPI_PINMODE_ALT5
my $fname = $bmc->gpio_fget_name( $pin );
    $pin  GPIO Pin Number
    
    Calls $bmc->gpio_fget and returns a human readable form.
    Example return values are: 
    'GPIO_17', 'I2C1_SDA', 'SPI0_MOSI', 'PWM0'
    This method is used to return the pin names shown in
    the HiPi Control GUI GPIO Panels
my $mask = $bmc->gpio_get_eds( $pin );
    $pin  GPIO Pin Number

    returns a mask specifying the current edge detection settings
    of the specified pin. The return value is an or'd combination 
    of one or more of the following values
    
    RPI_INT_NONE 
    RPI_INT_FALL 
    RPI_INT_RISE 
    RPI_INT_BOTH
    RPI_INT_AFALL 
    RPI_INT_ARISE 
    RPI_INT_HIGH 
    RPI_INT_LOW

    You can then determine if a specific edge detection is 
    active by , for example,

    my $fall_is_active = $mask & RPI_INT_FALL;

    You can export these values into your namespace from the
    HiPi::Constant module under the tag :raspberry

    use HiPi::Constant qw( :raspberry );

Functional Interface

Function names are the same as their object oriented counterparts but prefixed with bcm2835_

So, where using the object oriented interface you would call

my $level = $bcm->gpio_lev( $pin );

the equivalent function call would be:

my $level = HiPi::BCM2835::bcm2835_gpio_lev( $pin );

There are some important differences between the functional and OO interfaces. When using

my $bcm = HiPi::BCM2835->new();

the constructor initialises the bcm2835 library for you. When all the HiPi::BCM2835 objects using the library are destroyed, the DESTROY method closes the library.

When using the functional interface, you must initialise and close the library yourself

my $okstart = HiPi::BCM2835::bcm2835_init();
.......
.......
my $okend = HiPi::BCM2835::bcm2835_close();

In addition there are some important differences in the methods / functions that transfer data using the SPI and I2C access interface. The OO methods adopt a standard Perl approach as in:

my $buffout = $bcm->spi_transfernb( $buffin );

The functional code implements a direct copy of the C interface

HiPi::BCM2835::bcm2835_spi_transfernb($buffin, $buffout);

In this case $buffout must be initialised to the same length as $buffin before the function call is made.

The following functions have a different signature in the functional interface.

HiPi::BCM2835::bcm2835_spi_transfern( $buffer );
    $buffer   The data to send

    Transfers any number of bytes to and from the currently selected 
    SPI slave using HiPi::BCM2835::bcm2835_spi_transfernb().
    When the function returns, $buffer will contain the bytes read
    from the slave.
HiPi::BCM2835::bcm2835_spi_transfernb( $buffin, $buffout );
    $buffin   The data to send
    $buffout  Buffer to receive reply. This must be pre initialised
              to the same length as $buffin.

    Transfers any number of bytes to and from the currently selected 
    SPI slave. Asserts the currently selected CS pins (as previously 
    set by HiPi::BCM2835::bcm2835_spi_chipSelect) during the transfer. 
    Clocks the 8 bit bytes of $buffin out on MOSI, and simultaneously 
    clocks in data from MISO. The data read read from the slave is 
    returned. Uses polled transfer as per section 10.6.1 of the 
    BCM 2835 ARM Peripherls manual.
HiPi::BCM2835::bcm2835_i2c_read( $buffout );
    $buffout  Pre-allocated buffer to receive the read result.
              length( $buffer ) bytes will be read.
    
    Transfers any number of bytes from the currently selected I2C slave.
    (as previously set by $bcm->i2cSetSlaveAddress)

Exported Constant Tags

See Also: pin Identifiers

You can export the following constants by tag into your namespace using the standard form:

use HiPi::BCM2835 qw( :registers :memory );

The standard tag :all is also available to import everything into your namespace.

tag :registers

    BCM2835_ST_BASE
    BCM2835_GPIO_PADS
    BCM2835_CLOCK_BASE
    BCM2835_GPIO_BASE
    BCM2835_SPI0_BASE
    BCM2835_BSC0_BASE
    BCM2835_GPIO_PWM
    BCM2835_BSC1_BASE

tag :memory

    BCM2835_PAGE_SIZE
    BCM2835_BLOCK_SIZE

tag :function

    BCM2835_GPFSEL0
    BCM2835_GPFSEL1
    BCM2835_GPFSEL2
    BCM2835_GPFSEL3
    BCM2835_GPFSEL4
    BCM2835_GPFSEL5
    BCM2835_GPSET0
    BCM2835_GPSET1
    BCM2835_GPCLR0
    BCM2835_GPCLR1
    BCM2835_GPLEV0
    BCM2835_GPLEV1
    BCM2835_GPEDS0
    BCM2835_GPEDS1
    BCM2835_GPREN0
    BCM2835_GPREN1
    BCM2835_GPFEN0
    BCM2835_GPFEN1
    BCM2835_GPHEN0
    BCM2835_GPHEN1
    BCM2835_GPLEN0
    BCM2835_GPLEN1
    BCM2835_GPAREN0
    BCM2835_GPAREN1
    BCM2835_GPAFEN0
    BCM2835_GPAFEN1
    BCM2835_GPPUD
    BCM2835_GPPUDCLK0
    BCM2835_GPPUDCLK1
    BCM2835_GPIO_FSEL_INPT
    BCM2835_GPIO_FSEL_OUTP
    BCM2835_GPIO_FSEL_ALT0
    BCM2835_GPIO_FSEL_ALT1
    BCM2835_GPIO_FSEL_ALT2
    BCM2835_GPIO_FSEL_ALT3
    BCM2835_GPIO_FSEL_ALT4
    BCM2835_GPIO_FSEL_ALT5
    BCM2835_GPIO_FSEL_MASK

tag :pud

    BCM2835_GPIO_PUD_OFF
    BCM2835_GPIO_PUD_DOWN
    BCM2835_GPIO_PUD_UP

tag :pads

    BCM2835_PADS_GPIO_0_27  
    BCM2835_PADS_GPIO_28_45
    BCM2835_PADS_GPIO_46_53  
    BCM2835_PAD_PASSWRD   
    BCM2835_PAD_SLEW_RATE_UNLIMITED
    BCM2835_PAD_HYSTERESIS_ENABLED 
    BCM2835_PAD_DRIVE_2mA 
    BCM2835_PAD_DRIVE_4mA 
    BCM2835_PAD_DRIVE_6mA 
    BCM2835_PAD_DRIVE_8mA 
    BCM2835_PAD_DRIVE_10mA 
    BCM2835_PAD_DRIVE_12mA 
    BCM2835_PAD_DRIVE_14mA 
    BCM2835_PAD_DRIVE_16mA 
    BCM2835_PAD_GROUP_GPIO_0_27 
    BCM2835_PAD_GROUP_GPIO_28_45 
    BCM2835_PAD_GROUP_GPIO_46_53 

tag :pins

    RPI_GPIO_P1_03  
    RPI_GPIO_P1_05
    RPI_GPIO_P1_07
    RPI_GPIO_P1_08
    RPI_GPIO_P1_10
    RPI_GPIO_P1_11 
    RPI_GPIO_P1_12  
    RPI_GPIO_P1_13  
    RPI_GPIO_P1_15   
    RPI_GPIO_P1_16 
    RPI_GPIO_P1_18 
    RPI_GPIO_P1_19 
    RPI_GPIO_P1_21 
    RPI_GPIO_P1_22 
    RPI_GPIO_P1_23  
    RPI_GPIO_P1_24 
    RPI_GPIO_P1_26      
    RPI_V2_GPIO_P1_03  
    RPI_V2_GPIO_P1_05  
    RPI_V2_GPIO_P1_07  
    RPI_V2_GPIO_P1_08 
    RPI_V2_GPIO_P1_10
    RPI_V2_GPIO_P1_11 
    RPI_V2_GPIO_P1_12 
    RPI_V2_GPIO_P1_13 
    RPI_V2_GPIO_P1_15 
    RPI_V2_GPIO_P1_16 
    RPI_V2_GPIO_P1_18 
    RPI_V2_GPIO_P1_19 
    RPI_V2_GPIO_P1_21 
    RPI_V2_GPIO_P1_22 
    RPI_V2_GPIO_P1_23 
    RPI_V2_GPIO_P1_24 
    RPI_V2_GPIO_P1_26
    RPI_V2_GPIO_P5_03
    RPI_V2_GPIO_P5_04
    RPI_V2_GPIO_P5_05
    RPI_V2_GPIO_P5_06   

tag :spi

    BCM2835_SPI0_CS  
    BCM2835_SPI0_FIFO
    BCM2835_SPI0_CLK 
    BCM2835_SPI0_DLEN  
    BCM2835_SPI0_LTOH  
    BCM2835_SPI0_DC  
    BCM2835_SPI0_CS_LEN_LONG
    BCM2835_SPI0_CS_DMA_LEN
    BCM2835_SPI0_CS_CSPOL2 
    BCM2835_SPI0_CS_CSPOL1
    BCM2835_SPI0_CS_CSPOL0 
    BCM2835_SPI0_CS_RXF  
    BCM2835_SPI0_CS_RXR
    BCM2835_SPI0_CS_TXD 
    BCM2835_SPI0_CS_RXD 
    BCM2835_SPI0_CS_DONE 
    BCM2835_SPI0_CS_TE_EN 
    BCM2835_SPI0_CS_LMONO 
    BCM2835_SPI0_CS_LEN
    BCM2835_SPI0_CS_REN 
    BCM2835_SPI0_CS_ADCS 
    BCM2835_SPI0_CS_INTR 
    BCM2835_SPI0_CS_INTD
    BCM2835_SPI0_CS_DMAEN 
    BCM2835_SPI0_CS_TA 
    BCM2835_SPI0_CS_CSPOL 
    BCM2835_SPI0_CS_CLEAR 
    BCM2835_SPI0_CS_CLEAR_RX 
    BCM2835_SPI0_CS_CLEAR_TX
    BCM2835_SPI0_CS_CPOL 
    BCM2835_SPI0_CS_CPHA 
    BCM2835_SPI0_CS_CS 
    BCM2835_SPI_BIT_ORDER_LSBFIRST
    BCM2835_SPI_BIT_ORDER_MSBFIRST
    BCM2835_SPI_MODE0 
    BCM2835_SPI_MODE1
    BCM2835_SPI_MODE2
    BCM2835_SPI_MODE3 
    BCM2835_SPI_CS0 
    BCM2835_SPI_CS1 
    BCM2835_SPI_CS2 
    BCM2835_SPI_CS_NONE 
    BCM2835_SPI_CLOCK_DIVIDER_65536
    BCM2835_SPI_CLOCK_DIVIDER_32768 
    BCM2835_SPI_CLOCK_DIVIDER_16384
    BCM2835_SPI_CLOCK_DIVIDER_8192
    BCM2835_SPI_CLOCK_DIVIDER_4096 
    BCM2835_SPI_CLOCK_DIVIDER_2048 
    BCM2835_SPI_CLOCK_DIVIDER_1024
    BCM2835_SPI_CLOCK_DIVIDER_512 
    BCM2835_SPI_CLOCK_DIVIDER_256
    BCM2835_SPI_CLOCK_DIVIDER_128 
    BCM2835_SPI_CLOCK_DIVIDER_64
    BCM2835_SPI_CLOCK_DIVIDER_32 
    BCM2835_SPI_CLOCK_DIVIDER_16
    BCM2835_SPI_CLOCK_DIVIDER_8
    BCM2835_SPI_CLOCK_DIVIDER_4
    BCM2835_SPI_CLOCK_DIVIDER_2
    BCM2835_SPI_CLOCK_DIVIDER_1

tag :pwm

    BCM2835_PWM_CONTROL
    BCM2835_PWM_STATUS
    BCM2835_PWM0_RANGE 
    BCM2835_PWM0_DATA
    BCM2835_PWM1_RANGE 
    BCM2835_PWM1_DATA 
    BCM2835_PWMCLK_CNTL
    BCM2835_PWMCLK_DIV 
    BCM2835_PWM1_MS_MODE
    BCM2835_PWM1_USEFIFO
    BCM2835_PWM1_REVPOLAR
    BCM2835_PWM1_OFFSTATE
    BCM2835_PWM1_REPEATFF
    BCM2835_PWM1_SERIAL
    BCM2835_PWM1_ENABLE
    BCM2835_PWM0_MS_MODE
    BCM2835_PWM0_USEFIFO
    BCM2835_PWM0_REVPOLAR
    BCM2835_PWM0_OFFSTATE
    BCM2835_PWM0_REPEATFF
    BCM2835_PWM0_SERIAL
    BCM2835_PWM0_ENABLE

tag :i2c

    BCM2835_BSC_C 
    BCM2835_BSC_S 
    BCM2835_BSC_DLEN
    BCM2835_BSC_A 
    BCM2835_BSC_FIFO
    BCM2835_BSC_DIV
    BCM2835_BSC_DEL
    BCM2835_BSC_CLKT
    BCM2835_BSC_C_I2CEN 
    BCM2835_BSC_C_INTR 
    BCM2835_BSC_C_INTT 
    BCM2835_BSC_C_INTD 
    BCM2835_BSC_C_ST 
    BCM2835_BSC_C_CLEAR_1
    BCM2835_BSC_C_CLEAR_2
    BCM2835_BSC_C_READ 
    BCM2835_BSC_S_CLKT
    BCM2835_BSC_S_ERR 
    BCM2835_BSC_S_RXF 
    BCM2835_BSC_S_TXE 
    BCM2835_BSC_S_RXD 
    BCM2835_BSC_S_TXD 
    BCM2835_BSC_S_RXR 
    BCM2835_BSC_S_TXW 
    BCM2835_BSC_S_DONE 
    BCM2835_BSC_S_TA 
    BCM2835_BSC_FIFO_SIZE
    BCM2835_I2C_CLOCK_DIVIDER_2500
    BCM2835_I2C_CLOCK_DIVIDER_626
    BCM2835_I2C_CLOCK_DIVIDER_150
    BCM2835_I2C_CLOCK_DIVIDER_148
    BCM2835_I2C_REASON_OK
    BCM2835_I2C_REASON_ERROR_NACK
    BCM2835_I2C_REASON_ERROR_CLKT
    BCM2835_I2C_REASON_ERROR_DATA





Contents Up Previous Next


HiPi Modules Copyright © 2013 Mark Dootson