From 46a37cf5afb2fd1d99fd58dfb0cb3cd93c3f3d4a Mon Sep 17 00:00:00 2001 From: David Date: Fri, 5 Feb 2021 23:29:32 +0000 Subject: [PATCH 1/2] Upgrade BCM2835 library to 1.26 --- src/bcm2835/bcm2835.c | 246 ++++++++++++++++++++++++++---------------- src/bcm2835/bcm2835.h | 107 ++++++++++++++---- 2 files changed, 239 insertions(+), 114 deletions(-) diff --git a/src/bcm2835/bcm2835.c b/src/bcm2835/bcm2835.c index fdc91b7..e444a34 100755 --- a/src/bcm2835/bcm2835.c +++ b/src/bcm2835/bcm2835.c @@ -5,10 +5,8 @@ // // Author: Mike McCauley // Copyright (C) 2011-2013 Mike McCauley -// $Id: bcm2835.c,v 1.27 2019/07/22 23:04:24 mikem Exp mikem $ +// $Id: bcm2835.c,v 1.28 2020/01/11 05:07:13 mikem Exp mikem $ */ - - #include #include #include @@ -38,8 +36,8 @@ /* Physical address and size of the peripherals block // May be overridden on RPi2 */ -uint32_t *bcm2835_peripherals_base = (uint32_t *)BCM2835_PERI_BASE; -uint32_t bcm2835_peripherals_size = BCM2835_PERI_SIZE; +off_t bcm2835_peripherals_base = BCM2835_PERI_BASE; +size_t bcm2835_peripherals_size = BCM2835_PERI_SIZE; /* Virtual memory address of the mapped peripherals block */ @@ -126,6 +124,23 @@ static uint8_t bcm2835_correct_order(uint8_t b) return b; } +#ifdef BCM2835_HAVE_LIBCAP +#include +static int bcm2835_has_capability(cap_value_t capability) +{ + int ok = 0; + cap_t cap = cap_get_proc(); + if (cap) + { + cap_flag_value_t value; + if (cap_get_flag(cap,capability,CAP_EFFECTIVE,&value) == 0 && value == CAP_SET) + ok = 1; + cap_free(cap); + } + return ok; +} +#endif + /* // Low level register access functions */ @@ -484,12 +499,11 @@ void bcm2835_gpio_pudclk(uint8_t pin, uint8_t on) /* Read GPIO pad behaviour for groups of GPIOs */ uint32_t bcm2835_gpio_pad(uint8_t group) { - if (bcm2835_pads == MAP_FAILED) { - return 0; - } - - volatile uint32_t* paddr = bcm2835_pads + BCM2835_PADS_GPIO_0_27/4 + group; - return bcm2835_peri_read(paddr); + if (bcm2835_pads == MAP_FAILED) { + return 0; + } + volatile uint32_t* paddr = bcm2835_pads + BCM2835_PADS_GPIO_0_27/4 + group; + return bcm2835_peri_read(paddr); } /* Set GPIO pad behaviour for groups of GPIOs @@ -498,12 +512,12 @@ uint32_t bcm2835_gpio_pad(uint8_t group) */ void bcm2835_gpio_set_pad(uint8_t group, uint32_t control) { - if (bcm2835_pads == MAP_FAILED) { - return; - } + if (bcm2835_pads == MAP_FAILED) { + return; + } - volatile uint32_t* paddr = bcm2835_pads + BCM2835_PADS_GPIO_0_27/4 + group; - bcm2835_peri_write(paddr, control | BCM2835_PAD_PASSWRD); + volatile uint32_t* paddr = bcm2835_pads + BCM2835_PADS_GPIO_0_27/4 + group; + bcm2835_peri_write(paddr, control | BCM2835_PAD_PASSWRD); } /* Some convenient arduino-like functions @@ -664,6 +678,14 @@ uint8_t bcm2835_gpio_get_pud(uint8_t pin) return ret; } +static void bcm2835_aux_spi_reset(void) + { + volatile uint32_t* cntl0 = bcm2835_spi1 + BCM2835_AUX_SPI_CNTL0/4; + volatile uint32_t* cntl1 = bcm2835_spi1 + BCM2835_AUX_SPI_CNTL1/4; + + bcm2835_peri_write(cntl1, 0); + bcm2835_peri_write(cntl0, BCM2835_AUX_SPI_CNTL0_CLEARFIFO); +} int bcm2835_spi_begin(void) { @@ -919,58 +941,58 @@ int bcm2835_aux_spi_begin(void) volatile uint32_t* cntl1 = bcm2835_spi1 + BCM2835_AUX_SPI_CNTL1/4; if (bcm2835_spi1 == MAP_FAILED) - return 0; /* bcm2835_init() failed, or not root */ + return 0; /* bcm2835_init() failed, or not root */ /* Set the SPI pins to the Alt 4 function to enable SPI1 access on them */ - bcm2835_gpio_fsel(RPI_V2_GPIO_P1_36, BCM2835_GPIO_FSEL_ALT4); /* SPI1_CE2_N */ - bcm2835_gpio_fsel(RPI_V2_GPIO_P1_35, BCM2835_GPIO_FSEL_ALT4); /* SPI1_MISO */ - bcm2835_gpio_fsel(RPI_V2_GPIO_P1_38, BCM2835_GPIO_FSEL_ALT4); /* SPI1_MOSI */ - bcm2835_gpio_fsel(RPI_V2_GPIO_P1_40, BCM2835_GPIO_FSEL_ALT4); /* SPI1_SCLK */ + bcm2835_gpio_fsel(RPI_V2_GPIO_P1_36, BCM2835_GPIO_FSEL_ALT4); /* SPI1_CE2_N */ + bcm2835_gpio_fsel(RPI_V2_GPIO_P1_35, BCM2835_GPIO_FSEL_ALT4); /* SPI1_MISO */ + bcm2835_gpio_fsel(RPI_V2_GPIO_P1_38, BCM2835_GPIO_FSEL_ALT4); /* SPI1_MOSI */ + bcm2835_gpio_fsel(RPI_V2_GPIO_P1_40, BCM2835_GPIO_FSEL_ALT4); /* SPI1_SCLK */ - bcm2835_aux_spi_setClockDivider(bcm2835_aux_spi_CalcClockDivider(1000000)); // Default 1MHz SPI + bcm2835_aux_spi_setClockDivider(bcm2835_aux_spi_CalcClockDivider(1000000)); // Default 1MHz SPI - bcm2835_peri_write(enable, BCM2835_AUX_ENABLE_SPI0); - bcm2835_peri_write(cntl1, 0); - bcm2835_peri_write(cntl0, BCM2835_AUX_SPI_CNTL0_CLEARFIFO); + bcm2835_peri_write(enable, BCM2835_AUX_ENABLE_SPI0); + bcm2835_peri_write(cntl1, 0); + bcm2835_peri_write(cntl0, BCM2835_AUX_SPI_CNTL0_CLEARFIFO); return 1; /* OK */ } void bcm2835_aux_spi_end(void) { - /* Set all the SPI1 pins back to input */ - bcm2835_gpio_fsel(RPI_V2_GPIO_P1_36, BCM2835_GPIO_FSEL_INPT); /* SPI1_CE2_N */ - bcm2835_gpio_fsel(RPI_V2_GPIO_P1_35, BCM2835_GPIO_FSEL_INPT); /* SPI1_MISO */ - bcm2835_gpio_fsel(RPI_V2_GPIO_P1_38, BCM2835_GPIO_FSEL_INPT); /* SPI1_MOSI */ - bcm2835_gpio_fsel(RPI_V2_GPIO_P1_40, BCM2835_GPIO_FSEL_INPT); /* SPI1_SCLK */ + /* Set all the SPI1 pins back to input */ + bcm2835_gpio_fsel(RPI_V2_GPIO_P1_36, BCM2835_GPIO_FSEL_INPT); /* SPI1_CE2_N */ + bcm2835_gpio_fsel(RPI_V2_GPIO_P1_35, BCM2835_GPIO_FSEL_INPT); /* SPI1_MISO */ + bcm2835_gpio_fsel(RPI_V2_GPIO_P1_38, BCM2835_GPIO_FSEL_INPT); /* SPI1_MOSI */ + bcm2835_gpio_fsel(RPI_V2_GPIO_P1_40, BCM2835_GPIO_FSEL_INPT); /* SPI1_SCLK */ } #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) uint16_t bcm2835_aux_spi_CalcClockDivider(uint32_t speed_hz) { - uint16_t divider; + uint16_t divider; - if (speed_hz < (uint32_t) BCM2835_AUX_SPI_CLOCK_MIN) { - speed_hz = (uint32_t) BCM2835_AUX_SPI_CLOCK_MIN; - } else if (speed_hz > (uint32_t) BCM2835_AUX_SPI_CLOCK_MAX) { - speed_hz = (uint32_t) BCM2835_AUX_SPI_CLOCK_MAX; - } + if (speed_hz < (uint32_t) BCM2835_AUX_SPI_CLOCK_MIN) { + speed_hz = (uint32_t) BCM2835_AUX_SPI_CLOCK_MIN; + } else if (speed_hz > (uint32_t) BCM2835_AUX_SPI_CLOCK_MAX) { + speed_hz = (uint32_t) BCM2835_AUX_SPI_CLOCK_MAX; + } - divider = (uint16_t) DIV_ROUND_UP(BCM2835_CORE_CLK_HZ, 2 * speed_hz) - 1; + divider = (uint16_t) DIV_ROUND_UP(BCM2835_CORE_CLK_HZ, 2 * speed_hz) - 1; - if (divider > (uint16_t) BCM2835_AUX_SPI_CNTL0_SPEED_MAX) { - return (uint16_t) BCM2835_AUX_SPI_CNTL0_SPEED_MAX; - } + if (divider > (uint16_t) BCM2835_AUX_SPI_CNTL0_SPEED_MAX) { + return (uint16_t) BCM2835_AUX_SPI_CNTL0_SPEED_MAX; + } - return divider; + return divider; } static uint32_t spi1_speed; void bcm2835_aux_spi_setClockDivider(uint16_t divider) { - spi1_speed = (uint32_t) divider; + spi1_speed = (uint32_t) divider; } void bcm2835_aux_spi_write(uint16_t data) @@ -980,19 +1002,19 @@ void bcm2835_aux_spi_write(uint16_t data) volatile uint32_t* stat = bcm2835_spi1 + BCM2835_AUX_SPI_STAT/4; volatile uint32_t* io = bcm2835_spi1 + BCM2835_AUX_SPI_IO/4; - uint32_t _cntl0 = (spi1_speed << BCM2835_AUX_SPI_CNTL0_SPEED_SHIFT); - _cntl0 |= BCM2835_AUX_SPI_CNTL0_CS2_N; - _cntl0 |= BCM2835_AUX_SPI_CNTL0_ENABLE; - _cntl0 |= BCM2835_AUX_SPI_CNTL0_MSBF_OUT; - _cntl0 |= 16; // Shift length + uint32_t _cntl0 = (spi1_speed << BCM2835_AUX_SPI_CNTL0_SPEED_SHIFT); + _cntl0 |= BCM2835_AUX_SPI_CNTL0_CS2_N; + _cntl0 |= BCM2835_AUX_SPI_CNTL0_ENABLE; + _cntl0 |= BCM2835_AUX_SPI_CNTL0_MSBF_OUT; + _cntl0 |= 16; // Shift length - bcm2835_peri_write(cntl0, _cntl0); - bcm2835_peri_write(cntl1, BCM2835_AUX_SPI_CNTL1_MSBF_IN); + bcm2835_peri_write(cntl0, _cntl0); + bcm2835_peri_write(cntl1, BCM2835_AUX_SPI_CNTL1_MSBF_IN); - while (bcm2835_peri_read(stat) & BCM2835_AUX_SPI_STAT_TX_FULL) - ; + while (bcm2835_peri_read(stat) & BCM2835_AUX_SPI_STAT_TX_FULL) + ; - bcm2835_peri_write(io, (uint32_t) data << 16); + bcm2835_peri_write(io, (uint32_t) data << 16); } void bcm2835_aux_spi_writenb(const char *tbuf, uint32_t len) { @@ -1002,49 +1024,49 @@ void bcm2835_aux_spi_writenb(const char *tbuf, uint32_t len) { volatile uint32_t* txhold = bcm2835_spi1 + BCM2835_AUX_SPI_TXHOLD/4; volatile uint32_t* io = bcm2835_spi1 + BCM2835_AUX_SPI_IO/4; - char *tx = (char *) tbuf; - uint32_t tx_len = len; - uint32_t count; - uint32_t data; - uint32_t i; - uint8_t byte; + char *tx = (char *) tbuf; + uint32_t tx_len = len; + uint32_t count; + uint32_t data; + uint32_t i; + uint8_t byte; - uint32_t _cntl0 = (spi1_speed << BCM2835_AUX_SPI_CNTL0_SPEED_SHIFT); - _cntl0 |= BCM2835_AUX_SPI_CNTL0_CS2_N; - _cntl0 |= BCM2835_AUX_SPI_CNTL0_ENABLE; - _cntl0 |= BCM2835_AUX_SPI_CNTL0_MSBF_OUT; - _cntl0 |= BCM2835_AUX_SPI_CNTL0_VAR_WIDTH; + uint32_t _cntl0 = (spi1_speed << BCM2835_AUX_SPI_CNTL0_SPEED_SHIFT); + _cntl0 |= BCM2835_AUX_SPI_CNTL0_CS2_N; + _cntl0 |= BCM2835_AUX_SPI_CNTL0_ENABLE; + _cntl0 |= BCM2835_AUX_SPI_CNTL0_MSBF_OUT; + _cntl0 |= BCM2835_AUX_SPI_CNTL0_VAR_WIDTH; - bcm2835_peri_write(cntl0, _cntl0); - bcm2835_peri_write(cntl1, BCM2835_AUX_SPI_CNTL1_MSBF_IN); + bcm2835_peri_write(cntl0, _cntl0); + bcm2835_peri_write(cntl1, BCM2835_AUX_SPI_CNTL1_MSBF_IN); - while (tx_len > 0) { + while (tx_len > 0) { - while (bcm2835_peri_read(stat) & BCM2835_AUX_SPI_STAT_TX_FULL) - ; + while (bcm2835_peri_read(stat) & BCM2835_AUX_SPI_STAT_TX_FULL) + ; - count = MIN(tx_len, 3); - data = 0; + count = MIN(tx_len, 3); + data = 0; - for (i = 0; i < count; i++) { - byte = (tx != NULL) ? (uint8_t) *tx++ : (uint8_t) 0; - data |= byte << (8 * (2 - i)); - } + for (i = 0; i < count; i++) { + byte = (tx != NULL) ? (uint8_t) *tx++ : (uint8_t) 0; + data |= byte << (8 * (2 - i)); + } - data |= (count * 8) << 24; - tx_len -= count; + data |= (count * 8) << 24; + tx_len -= count; - if (tx_len != 0) { - bcm2835_peri_write(txhold, data); - } else { - bcm2835_peri_write(io, data); - } + if (tx_len != 0) { + bcm2835_peri_write(txhold, data); + } else { + bcm2835_peri_write(io, data); + } - while (bcm2835_peri_read(stat) & BCM2835_AUX_SPI_STAT_BUSY) - ; + while (bcm2835_peri_read(stat) & BCM2835_AUX_SPI_STAT_BUSY) + ; - (void) bcm2835_peri_read(io); - } + (void) bcm2835_peri_read(io); + } } void bcm2835_aux_spi_transfernb(const char *tbuf, char *rbuf, uint32_t len) { @@ -1144,6 +1166,41 @@ void bcm2835_aux_spi_transfern(char *buf, uint32_t len) { bcm2835_aux_spi_transfernb(buf, buf, len); } +/* Writes (and reads) a single byte to AUX SPI */ +uint8_t bcm2835_aux_spi_transfer(uint8_t value) +{ + volatile uint32_t* cntl0 = bcm2835_spi1 + BCM2835_AUX_SPI_CNTL0/4; + volatile uint32_t* cntl1 = bcm2835_spi1 + BCM2835_AUX_SPI_CNTL1/4; + volatile uint32_t* stat = bcm2835_spi1 + BCM2835_AUX_SPI_STAT/4; + volatile uint32_t* io = bcm2835_spi1 + BCM2835_AUX_SPI_IO/4; + + uint32_t data; + + uint32_t _cntl0 = (spi1_speed << BCM2835_AUX_SPI_CNTL0_SPEED_SHIFT); + _cntl0 |= BCM2835_AUX_SPI_CNTL0_CS2_N; + _cntl0 |= BCM2835_AUX_SPI_CNTL0_ENABLE; + _cntl0 |= BCM2835_AUX_SPI_CNTL0_MSBF_OUT; + _cntl0 |= BCM2835_AUX_SPI_CNTL0_CPHA_IN; + _cntl0 |= 8; // Shift length. + + uint32_t _cntl1 = BCM2835_AUX_SPI_CNTL1_MSBF_IN; + + bcm2835_peri_write(cntl1, _cntl1); + bcm2835_peri_write(cntl0, _cntl0); + + bcm2835_peri_write(io, (uint32_t) bcm2835_correct_order(value) << 24); + + while (bcm2835_peri_read(stat) & BCM2835_AUX_SPI_STAT_BUSY) + ; + + data = bcm2835_correct_order(bcm2835_peri_read(io) & 0xff); + + bcm2835_aux_spi_reset(); + + return data; +} + + int bcm2835_i2c_begin(void) { uint16_t cdiv; @@ -1366,7 +1423,7 @@ uint8_t bcm2835_i2c_read(char* buf, uint32_t len) reason = BCM2835_I2C_REASON_ERROR_DATA; } - bcm2835_peri_set_bits(control, BCM2835_BSC_S_DONE , BCM2835_BSC_S_DONE); + bcm2835_peri_set_bits(status, BCM2835_BSC_S_DONE , BCM2835_BSC_S_DONE); return reason; } @@ -1783,8 +1840,8 @@ int bcm2835_init(void) (buf[3] == 0x00) && ((base_address == BCM2835_PERI_BASE) || (base_address == BCM2835_RPI2_PERI_BASE) || (base_address == BCM2835_RPI4_PERI_BASE))) { - bcm2835_peripherals_base = (uint32_t *)base_address; - bcm2835_peripherals_size = peri_size; + bcm2835_peripherals_base = (off_t)base_address; + bcm2835_peripherals_size = (size_t)peri_size; if( base_address == BCM2835_RPI4_PERI_BASE ) { pud_type_rpi4 = 1; @@ -1804,7 +1861,11 @@ int bcm2835_init(void) */ memfd = -1; ok = 0; - if (geteuid() == 0) + if (geteuid() == 0 +#ifdef BCM2835_HAVE_LIBCAP + || bcm2835_has_capability(CAP_SYS_RAWIO) +#endif + ) { /* Open the master /dev/mem device */ if ((memfd = open("/dev/mem", O_RDWR | O_SYNC) ) < 0) @@ -1815,7 +1876,7 @@ int bcm2835_init(void) } /* Base of the peripherals block is mapped to VM */ - bcm2835_peripherals = mapmem("gpio", bcm2835_peripherals_size, memfd, (off_t)(uint32_t)bcm2835_peripherals_base); + bcm2835_peripherals = mapmem("gpio", bcm2835_peripherals_size, memfd, bcm2835_peripherals_base); if (bcm2835_peripherals == MAP_FAILED) goto exit; /* Now compute the base addresses of various peripherals, @@ -1848,7 +1909,7 @@ int bcm2835_init(void) /* Base of the peripherals block is mapped to VM */ bcm2835_peripherals_base = 0; - bcm2835_peripherals = mapmem("gpio", bcm2835_peripherals_size, memfd, (off_t)(uint32_t)bcm2835_peripherals_base); + bcm2835_peripherals = mapmem("gpio", bcm2835_peripherals_size, memfd, bcm2835_peripherals_base); if (bcm2835_peripherals == MAP_FAILED) goto exit; bcm2835_gpio = bcm2835_peripherals; ok = 1; @@ -1964,6 +2025,3 @@ int main(int argc, char **argv) return 0; } #endif - - - diff --git a/src/bcm2835/bcm2835.h b/src/bcm2835/bcm2835.h index 49d04fa..67c19a3 100755 --- a/src/bcm2835/bcm2835.h +++ b/src/bcm2835/bcm2835.h @@ -4,7 +4,7 @@ Author: Mike McCauley Copyright (C) 2011-2013 Mike McCauley - $Id: bcm2835.h,v 1.25 2019/07/22 23:04:13 mikem Exp $ + $Id: bcm2835.h,v 1.26 2020/01/11 05:07:13 mikem Exp mikem $ */ /*! \mainpage C library for Broadcom BCM 2835 as used in Raspberry Pi @@ -26,7 +26,7 @@ BCM 2835). The version of the package that this documentation refers to can be downloaded - from http://www.airspayce.com/mikem/bcm2835/bcm2835-1.60.tar.gz + from http://www.airspayce.com/mikem/bcm2835/bcm2835-1.68.tar.gz You can find the latest version at http://www.airspayce.com/mikem/bcm2835 Several example programs are provided. @@ -72,6 +72,34 @@ bcm2835_spi_begin() and bcm2835_i2c_begin() will return false and all other non-gpio operations may fail silently or crash. + If your program needs acccess to /dev/mem but not as root, + and if you have the libcap-dev package installed on the target, + you can compile this library to use + libcap2 so that it tests whether the exceutable has the cap_sys_rawio capability, and therefore + permission to access /dev/mem. + To enable this ability, uncomment the #define BCM2835_HAVE_LIBCAP in bcm2835.h or + -DBCM2835_HAVE_LIBCAP on your compiler command line. + After your program has been compiled: + \code + sudo setcap cap_sys_rawio+ep *myprogname* + \endcode + You also need to do these steps on the host once, to support libcap and not-root read/write access + to /dev/mem: + 1. Install libcap support + \code + sudo apt-get install libcap2 libcap-dev + 2. Add current user to kmem group + \code + sudo adduser $USER kmem + \endcode + 3. Allow write access to /dev/mem by members of kmem group + \code + echo 'SUBSYSTEM=="mem", KERNEL=="mem", GROUP="kmem", MODE="0660"' | sudo tee /etc/udev/rules.d/98-mem.rules + \endcode + \code + sudo reboot + \endcode + \par Installation This library consists of a single non-shared library and header file, which will be @@ -308,14 +336,14 @@ utility, spincl, is licensed under Open Source GNU GPLv3 by iP Solutions (http://ipsolutionscorp.com), as a free download with source included: http://ipsolutionscorp.com/raspberry-pi-spi-utility/ - \par Open Source Licensing GPL V2 + \par Open Source Licensing GPL V3 This is the appropriate option if you want to share the source code of your application with everyone you distribute it to, and you also want to give them the right to share who uses it. If you wish to use this software under Open Source Licensing, you must contribute all your source code to the open source - community in accordance with the GPL Version 2 when your application is - distributed. See https://www.gnu.org/licenses/gpl-2.0.html and COPYING + community in accordance with the GPL Version 3 when your application is + distributed. See https://www.gnu.org/licenses/gpl-3.0.html and COPYING \par Commercial Licensing @@ -542,6 +570,31 @@ Applied patch from Mark Dootson for RPi 4 compatibility. Thanks Mark. Not tested here on RPi4, but others report it works. Tested as still working correctly on earlier RPi models. Tested with Debian Buster on earlier models + \version 1.61 2020-01-11 + Fixed errors in the documentation for bcm2835_spi_write. + Fixes issue seen on Raspberry Pi 4 boards where 64-bit off_t is used by + default via -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64. The offset was + being incorrectly converted, this way is clearer and fixes the problem. Contributed by Jonathan Perkin. + + \version 1.62 2020-01-12 + Fixed a problem that could cause compile failures with size_t and off_t + + \version 1.63 2020-03-07 + Added bcm2835_aux_spi_transfer, contributed by Michivi + Adopted GPL V3 licensing + + \version 1.64 2020-04-11 + Fixed error in definitions of BCM2835_AUX_SPI_STAT_TX_LVL and BCM2835_AUX_SPI_STAT_RX_LVL. Patch from + Eric Marzec. Thanks. + + \version 1.65, 1.66 2020-04-16 + Added support for use of capability cap_sys_rawio to determine if access to /dev/mem is available for non-root + users. Contributed by Doug McFadyen. + + \version 1.67, 1.66 2020-06-11 + Fixed an error in bcm2835_i2c_read() where the status byte was not correctly updated with BCM2835_BSC_S_DONE + Reported by Zihan. Thanks. + \author Mike McCauley (mikem@airspayce.com) DO NOT CONTACT THE AUTHOR DIRECTLY: USE THE LISTS */ @@ -552,11 +605,16 @@ #include -#define BCM2835_VERSION 10060 /* Version 1.60 */ +#define BCM2835_VERSION 10066 /* Version 1.66 */ + +// Define this if you want to use libcap2 to determine if you have the cap_sys_rawio capability +// and therefore the capability of opening /dev/mem, even if you are not root. +// See the comments above in the documentation for 'Running As Root' +//#define BCM2835_HAVE_LIBCAP /* RPi 2 is ARM v7, and has DMB instruction for memory barriers. Older RPis are ARM v6 and don't, so a coprocessor instruction must be used instead. - However, not all versions of gcc in all distros support the dmb assembler instruction even on conmpatible processors. + However, not all versions of gcc in all distros support the dmb assembler instruction even on compatible processors. This test is so any ARMv7 or higher processors with suitable GCC will use DMB. */ #if __ARM_ARCH >= 7 @@ -626,13 +684,14 @@ /*! Base Address of the BSC1 registers */ #define BCM2835_BSC1_BASE 0x804000 +#include /*! Physical address and size of the peripherals block May be overridden on RPi2 */ -extern uint32_t *bcm2835_peripherals_base; +extern off_t bcm2835_peripherals_base; /*! Size of the peripherals block to be mapped */ -extern uint32_t bcm2835_peripherals_size; +extern size_t bcm2835_peripherals_size; /*! Virtual memory address of the mapped peripherals block */ extern uint32_t *bcm2835_peripherals; @@ -955,8 +1014,8 @@ typedef enum #define BCM2835_AUX_SPI_CNTL1_MSBF_IN 0x00000002 /*!< */ #define BCM2835_AUX_SPI_CNTL1_KEEP_IN 0x00000001 /*!< */ -#define BCM2835_AUX_SPI_STAT_TX_LVL 0xFF000000 /*!< */ -#define BCM2835_AUX_SPI_STAT_RX_LVL 0x00FF0000 /*!< */ +#define BCM2835_AUX_SPI_STAT_TX_LVL 0xF0000000 /*!< */ +#define BCM2835_AUX_SPI_STAT_RX_LVL 0x00F00000 /*!< */ #define BCM2835_AUX_SPI_STAT_TX_FULL 0x00000400 /*!< */ #define BCM2835_AUX_SPI_STAT_TX_EMPTY 0x00000200 /*!< */ #define BCM2835_AUX_SPI_STAT_RX_FULL 0x00000100 /*!< */ @@ -1073,7 +1132,7 @@ typedef enum GPIO register offsets from BCM2835_BSC*_BASE. Offsets into the BSC Peripheral block in bytes per 3.1 BSC Register Map */ -#define BCM2835_BSC_C 0x0000 /*!< BSC Master Control */ +#define BCM2835_BSC_C 0x0000 /*!< BSC Master Control */ #define BCM2835_BSC_S 0x0004 /*!< BSC Master Status */ #define BCM2835_BSC_DLEN 0x0008 /*!< BSC Master Data Length */ #define BCM2835_BSC_A 0x000c /*!< BSC Master Slave Address */ @@ -1700,11 +1759,10 @@ extern "C" { */ extern void bcm2835_spi_writenb(const char* buf, uint32_t len); - /*! Transfers half-word to and from the currently selected SPI slave. + /*! Transfers half-word to the currently selected SPI slave. Asserts the currently selected CS pins (as previously set by bcm2835_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 \param[in] data The 8 bit data byte to write to MOSI \sa bcm2835_spi_writenb() @@ -1712,14 +1770,14 @@ extern "C" { extern void bcm2835_spi_write(uint16_t data); /*! Start AUX SPI operations. - Forces RPi AUX SPI pins P1-36 (MOSI), P1-38 (MISO), P1-40 (CLK) and P1-36 (CE2) + Forces RPi AUX SPI pins P1-38 (MOSI), P1-38 (MISO), P1-40 (CLK) and P1-36 (CE2) to alternate function ALT4, which enables those pins for SPI interface. \return 1 if successful, 0 otherwise (perhaps because you are not running as root) */ extern int bcm2835_aux_spi_begin(void); /*! End AUX SPI operations. - SPI1 pins P1-36 (MOSI), P1-38 (MISO), P1-40 (CLK) and P1-36 (CE2) + SPI1 pins P1-38 (MOSI), P1-38 (MISO), P1-40 (CLK) and P1-36 (CE2) are returned to their default INPUT behaviour. */ extern void bcm2835_aux_spi_end(void); @@ -1736,10 +1794,10 @@ extern "C" { */ extern uint16_t bcm2835_aux_spi_CalcClockDivider(uint32_t speed_hz); - /*! Transfers half-word to and from the AUX SPI slave. + /*! Transfers half-word to the AUX SPI slave. Asserts the currently selected CS pins during the transfer. \param[in] data The 8 bit data byte to write to MOSI - \return The 8 bit byte simultaneously read from MISO + \return The 16 bit byte simultaneously read from MISO \sa bcm2835_spi_transfern() */ extern void bcm2835_aux_spi_write(uint16_t data); @@ -1755,7 +1813,7 @@ extern "C" { using bcm2835_aux_spi_transfernb. The returned data from the slave replaces the transmitted data in the buffer. \param[in,out] buf Buffer of bytes to send. Received bytes will replace the contents - \param[in] len Number of bytes int eh buffer, and the number of bytes to send/received + \param[in] len Number of bytes in the buffer, and the number of bytes to send/received \sa bcm2835_aux_spi_transfer() */ extern void bcm2835_aux_spi_transfern(char *buf, uint32_t len); @@ -1770,6 +1828,15 @@ extern "C" { */ extern void bcm2835_aux_spi_transfernb(const char *tbuf, char *rbuf, uint32_t len); + /*! Transfers one byte to and from the AUX SPI slave. + Clocks the 8 bit value out on MOSI, and simultaneously clocks in data from MISO. + Returns the read data byte from the slave. + \param[in] value The 8 bit data byte to write to MOSI + \return The 8 bit byte simultaneously read from MISO + \sa bcm2835_aux_spi_transfern() + */ + extern uint8_t bcm2835_aux_spi_transfer(uint8_t value); + /*! @} */ /*! \defgroup i2c I2C access @@ -1959,4 +2026,4 @@ Broadcom bcm2835. Contributed by Shahrooz Shahparnia. /*! example spimem_test.c Shows how to use the included little library (spiram.c and spiram.h) to read and write SPI RAM chips such as 23K256-I/P -*/ +*/ \ No newline at end of file From de658cab7e223192984df974a00109dbd422ef30 Mon Sep 17 00:00:00 2001 From: David Date: Fri, 5 Feb 2021 23:33:35 +0000 Subject: [PATCH 2/2] Include build on node.js 14.x --- .github/workflows/nodejs.yml | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 3fa35b3..4d86098 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -5,28 +5,27 @@ name: Node.js CI on: push: - branches: [ master ] + branches: [master] pull_request: - branches: [ master ] + branches: [master] jobs: build: - runs-on: ubuntu-latest strategy: matrix: - node-version: [8.x, 10.x, 12.x] + node-version: [8.x, 10.x, 12.x, 14.x] steps: - - uses: actions/checkout@v2 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - - run: npm ci - - run: npm run build --if-present - - run: npm test + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - run: npm ci + - run: npm run build --if-present + - run: npm test publish: runs-on: ubuntu-latest