HiPi::BCM2385
NOTE: This module cannot be used on a Raspberry Pi 5
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.
Install using debian package
- Raspberry Pi OS 32 bit ( Bookworm ) libhipi-bcm2835-perl_0.69-1.bookworm_armhf.deb
- Raspberry Pi OS 64 bit ( Bookworm ) libhipi-bcm2835-perl_0.69-1.bookworm_arm64.deb
- Raspberry Pi OS 32 bit ( Bullseye ) libhipi-bcm2835-perl_0.69-1.bullseye_armhf.deb
- Raspberry Pi OS 64 bit ( Bullseye ) libhipi-bcm2835-perl_0.69-1.bullseye_arm64.deb
Compile from latest source
Install from CPAN
cpan -i HiPi::BCM2835
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 qw( :raspberry ); # this will export, amongst other things, the following # pin constants that you can pass to the HiPi::BCM2835 # methods and functions RPI_PIN_3 RPI_PIN_5 RPI_PIN_7 RPI_PIN_8 RPI_PIN_10 RPI_PIN_11 RPI_PIN_12 RPI_PIN_13 RPI_PIN_15 RPI_PIN_16 RPI_PIN_18 RPI_PIN_19 RPI_PIN_21 RPI_PIN_22 RPI_PIN_23 RPI_PIN_24 RPI_PIN_26 RPI_PIN_27 RPI_PIN_28 RPI_PIN_29 RPI_PIN_31 RPI_PIN_32 RPI_PIN_33 RPI_PIN_35 RPI_PIN_36 RPI_PIN_37 RPI_PIN_38 RPI_PIN_40 # 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 do not require that you 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_get_pud( $pin );
$pin GPIO Pin Number On PI 4 returns one of BCM2835_GPIO_PUD_OFF BCM2835_GPIO_PUD_DOWN BCM2835_GPIO_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 usedmy $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
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