Compare commits

...

78 commits

Author SHA1 Message Date
Drew Fustini
cf306ed7f9
Merge pull request #366 from omerk/master
Fix compilation for newer versions of Python
2023-04-24 10:44:48 -07:00
omerk
57e630c155 fix compilation for newer versions of Python
PyEval_ThreadsInitialized() and PyEval_InitThreads() are deprecated and break the build, adding a version check to ignore if we are compiling with a newer Python version.
2023-04-22 23:15:33 +01:00
Drew Fustini
7361d9a997
Merge pull request #346 from pdp7/master
Fix pwm output for ecap pins P9_28 and P9_42 #342
2021-01-25 01:07:12 -08:00
Drew Fustini
fe2e30a8a6
Fix pwm output for ecap pins P9_28 and P9_42 #342
PWM outputs on P9_28 and P9_42 are part of the ECAP hardware block.  This causes 'ecap' to be in the path instead of 'pwm'.  For example:
`/sys/devices/platform/ocp/48300000.epwmss/48300100.ecap/pwm/pwmchip0/pwm0`
is one character longer than:
`/sys/devices/platform/ocp/48302000.epwmss/48302200.pwm/pwm/pwmchip4/pwm0`
Thus the index in pwm_path must be adjusted for the ecap_path_udev path.  This fixes issue #342
2021-01-24 22:09:43 -08:00
Drew Fustini
11e9d2d82e
Merge pull request #345 from martinezjavier/fix-multiple-def-error
fix link error due multiple variables definitions
2020-12-06 09:21:53 -08:00
Javier Martinez Canillas
be710eaf9b
fix link error due multiple variables definitions
Building with GCC 10.2.1 fails due linking errors caused by having multiple
definitions of the variables defined in the source/constants.h header file.

Fix this by moving the variables definition to the source/constants.c file,
to avoid the variables to be defined each time that the header is included.

While being there, use a single variable instead of having one for each
object that is added to the module.
2020-11-28 00:47:41 +01:00
Drew Fustini
0c7cdaf259
Merge pull request #340 from MLH-Fellowship/229-enable-pwm
Enable DMTimer PWM pins on BBB and PB
2020-07-31 17:22:57 -05:00
Drew Fustini
dbecfcddad add long_description_content_type to satisfy pypi
Refer to https://packaging.python.org/guides/making-a-pypi-friendly-readme/
2020-07-30 21:27:59 -05:00
Drew Fustini
d3bae3c1ab update CHANGELOG 2020-07-29 21:37:42 -05:00
Drew Fustini
1b2eb9d19d
Update version in setup.py to v1.2 2020-07-29 15:34:41 -05:00
Drew Fustini
8ba2f122a9
Remove suppression of gcc warnings in CFLAGS #336
CFLAGS is only -Wall now.  -Werror has been removed to the build will no longer fail on warnings.  Therefore, there is no need to suppress certain warnings.
2020-07-29 14:21:47 -05:00
Drew Fustini
24a617aecf
remove -Werror from CFLAGS
In issue #335, @mvduin noted that it is a poor idea to have compilation fail on warnings because a newer compiler version may add new warnings and as a result break compilation.
2020-07-29 14:06:32 -05:00
Drew Fustini
50fe27e928
Update README.md
update installation instructions to use python3
2020-07-29 10:57:43 -05:00
Drew Fustini
c25f27a51d
Update README.md
Change the kernel versions
2020-07-29 10:44:16 -05:00
Drew Fustini
536783c533
Update README.md
change link to current Debian image
2020-07-29 10:41:33 -05:00
Darren Schachter
af9ea512e8 Remove unnecessary conditional 2020-07-24 10:45:40 -04:00
Darren Schachter
db0adf258c Fix udev PWM path for DMTimer pins 2020-07-23 12:01:49 -04:00
Darren Schachter
928e8dc499 Add udev PWM path for DMTimer pins 2020-07-22 15:25:24 -04:00
Darren Schachter
1c012a42ed Add missing comma 2020-07-22 14:58:03 -04:00
Darren Schachter
1151dd9a8c Add dmtimer PWM entries in table for BBB 2020-07-22 14:05:10 -04:00
Darren Schachter
dcdb1adae9 Improve error logging 2020-07-22 13:50:37 -04:00
Darren Schachter
4149f2d4bc Change path for dmtimer PWM pins 2020-07-22 12:16:49 -04:00
Darren Schachter
0f9f472e36 Add is_dmtimer_pin function 2020-07-22 11:50:20 -04:00
Darren Schachter
c70c9bad97 Add dmtimer PWM entries in table for PocketBeagle 2020-07-22 10:36:03 -04:00
Drew Fustini
6f2a675d4b
Merge pull request #337 from SamPovilus/docfix
fixing document locaiton and version as current location dosn't load
2020-07-03 14:47:06 +02:00
Sam Povilus
40f1160ac3 fixing document locaiton and version as current location dosn't load 2020-07-02 19:54:43 -06:00
Drew Fustini
16f3249053
Merge pull request #327 from zer0cod3r/master
UART4 added to Pocketbeagle
2020-03-08 13:21:38 +01:00
Daniel Nguyen
61c29a1ecd
Update common.c 2020-03-07 14:19:39 -08:00
Daniel Nguyen
0be8cb5231
Update common.c
Added UART4 to Pocketbeagle
2020-03-07 14:15:49 -08:00
Drew Fustini
bd4745da78
Update README.md 2020-02-03 02:27:44 +01:00
Drew Fustini
dd6de40ba0
Update README.md 2020-02-03 02:25:02 +01:00
Drew Fustini
bf3e6b5bf0
Update ISSUE_TEMPLATE.md 2020-02-03 02:21:49 +01:00
Drew Fustini
a87a6d9496
Merge pull request #321 from adafruit/issue308
Fix warnings from gcc 8.2 in Debian 10 (Buster)
2019-12-17 05:49:41 +00:00
Drew Fustini
59dcd95755
Update tox.ini to Python 3.6
Try to fix TravisCI error that Python 3.4 does not exist
2019-12-17 05:34:03 +00:00
Drew Fustini
1ca2830828
Update travis config to specify Python 3.6
Attempt to fix Travis error:
https://travis-ci.com/adafruit/adafruit-beaglebone-io-python/builds/140636005

```
1.74s$ git clone --depth=50 --branch=issue308 https://github.com/adafruit/adafruit-beaglebone-io-python.git adafruit/adafruit-beaglebone-io-python
0.01s0.01s$ source ~/virtualenv/python3.6/bin/activate
$ python --version
Python 3.6.7
$ pip --version
pip 19.0.3 from /home/travis/virtualenv/python3.6.7/lib/python3.6/site-packages/pip (python 3.6)
install
1.54s$ pip install tox
5.96s$ tox
GLOB sdist-make: /home/travis/build/adafruit/adafruit-beaglebone-io-python/setup.py
py27 create: /home/travis/build/adafruit/adafruit-beaglebone-io-python/.tox/py27
py27 inst: /home/travis/build/adafruit/adafruit-beaglebone-io-python/.tox/.tmp/package/1/Adafruit_BBIO-1.1.1.zip
py27 installed: Adafruit-BBIO==1.1.1
py27 run-test-pre: PYTHONHASHSEED='645938357'
py27 run-test: commands[0] | echo 'run pytest on beaglebone'
run pytest on beaglebone
py34 create: /home/travis/build/adafruit/adafruit-beaglebone-io-python/.tox/py34
ERROR: InterpreterNotFound: python3.4
___________________________________ summary ____________________________________
  py27: commands succeeded
ERROR:  py34: InterpreterNotFound: python3.4
The command "tox" exited with 1.
Done. Your build exited with 1.
```
2019-12-17 05:27:46 +00:00
Drew Fustini
eca84d64d7 Fix warning about casting incompatible function types #308
Debian 10 (Buster) has gcc 8.2 which warns about:

cast between incompatible function types from ‘PyObject * (*)(PyObject *, PyObject *, PyObject *)’

The solution is to cast to '(PyCFunction)(void *)'
2019-12-11 09:06:12 +00:00
Drew Fustini
7fb13f9f3d Fix warnings on format truncation and sizeof in strncpy #308
Debian 10 (Buster) has gcc 8.2 which warns about:

source/c_pwm.c:459:65: error: argument to ‘sizeof’ in ‘strncpy’ call is the same expression as the source; did you mean to use the size of the destination? [-Werror=sizeof-pointer-memaccess]
source/c_pwm.c:396:43: error: ‘%s’ directive output may be truncated writing up to 199 bytes into a region of size 100 [-Werror=format-truncation=]
2019-12-11 09:03:44 +00:00
Drew Fustini
3a5d23d01b Fix warning about casting incompatible function types #308
Debian 10 (Buster) has gcc 8.2 which warns about:

cast between incompatible function types from ‘PyObject * (*)(PyObject *, PyObject *, PyObject *)’

The solution is to cast to '(PyCFunction)(void *)'
2019-12-06 10:26:49 +00:00
Drew Fustini
9298393cf5 Fix warning print format strings being truncated #308
Debian 10 (Buster) has gcc 8.2 which warns about:

error: ‘%s’ directive output may be truncated writing up to 19 bytes into a region of size between 10 and 59 [-Werror=format-truncation=]
  snprintf(path, sizeof(path), "%s/%s/state", ocp_dir, pinmux_dir);
2019-12-06 10:24:47 +00:00
Drew Fustini
7032af7e5f Fix warning about casting incompatible function types #308
Debian 10 (Buster) has gcc 8.2 which warns about:

cast between incompatible function types from ‘PyObject * (*)(PyObject *, PyObject *, PyObject *)’

The solution is to cast to '(PyCFunction)(void *)'
2019-12-06 10:20:18 +00:00
Drew Fustini
b867bbffe3
Change name of P1_3 to match bone.js 2019-04-03 00:21:27 +01:00
Drew Fustini
5df30a8b73
do not set pin mode for built-in USRn LEDs
This fix resolves Adafruit_BBIO issue #310 and https://github.com/adafruit/Adafruit_Blinka/issues/96 which was preventing the USR LEDs from being used by the CircuitPython Blinka library
2019-04-01 03:10:02 +01:00
Drew Fustini
e06bec0d24
Update setup.py 2019-03-30 15:04:45 +00:00
Drew Fustini
0923b85884
Ignore new compiler warnings in gcc 8.2.0
I was testing the new Debian "buster" image by @RobertCNelson and we noticed that the Adafruit_BBIO build was failing on compiler warnings.  This seems to be due to the introduction of new compiler warnings in the more recent version of gcc that is on the buster image: https://rcn-ee.net/rootfs/bb.org/testing/2019-03-03/buster-iot/bone-debian-buster-iot-armhf-2019-03-03-4gb.img.xz a shot
2019-03-18 23:12:00 +01:00
Drew Fustini
b2a6be54a1 force Encoder period to be an integer #299 2018-12-19 13:31:34 -06:00
Drew Fustini
2cfded3459
Fix dead link to bone.js #296 2018-12-10 07:32:21 -06:00
Drew Fustini
e96e1efb53 remove deug output 2018-11-23 05:35:27 +00:00
Drew Fustini
96aa8ed2aa do not set pinmux on the beaglebone blue
beaglebone blue has complete dtb file and does not need pinmux set for gpio ports
2018-11-23 04:54:32 +00:00
Drew Fustini
f70453ed41 upload to PyPI againt to resolve #293 2018-11-20 08:26:47 +00:00
Drew Fustini
71d1bb293a update version to 1.1.0 2018-10-18 06:58:25 +00:00
Drew Fustini
1f7c20e899 remove debug logging 2018-10-17 14:59:09 -05:00
Drew Fustini
c09ab8ee43 fix pwm on pocketbeagle and beaglebone blue #286
pocketbeagle and beaglebone blue have complete dtb file
and do not need overlays
2018-10-17 14:56:11 -05:00
Drew Fustini
b1ee5998f0
Merge pull request #285 from sam-bristow/bugfix/uart-error-reporting
Return error-code for problem UART interface
2018-10-11 11:26:28 -05:00
Drew Fustini
32b1f7e1bb
Merge pull request #284 from sam-bristow/py3-docs
Update UART examples
2018-10-11 11:26:14 -05:00
Sam Bristow
448854c209 Return error-code for failing interface
Rather than returning the error code for UART1 regardless of which
interface had problems, we should return the error code for the
interface that actually had an error.

Pretty sure this was a simple copy-paste mistake.
2018-10-09 23:57:20 +13:00
Sam Bristow
783bfacee8 Use new python-serial API
Version 3.0 of python-serial introduced an updated API, we may as well
use it.

This change also uses context-managers for dealing with UARTs as they
are less error-prone and the code is much cleaner/shorter.
2018-10-09 23:39:43 +13:00
Sam Bristow
eff11b83fe Use print() function in all code and docs
Low-hanging fruit of Python3 compatibility work.

I've left fix_py_compile.py as it is only ever going to be run under
Python 2.
2018-10-09 23:34:26 +13:00
Drew Fustini
7affea78fd do not load overlays for the beaglebone blue #283
beaglebone blue has complete dtb file and does not need overlays

refer to issue 283:
https://github.com/adafruit/adafruit-beaglebone-io-python/issues/283
2018-10-07 22:10:02 +00:00
Drew Fustini
79e2d30526
Merge pull request #282 from erikwelsh/master
Fixed GPIO export problem; Leaves GPIO in bad state on latest BeagleB…
2018-10-07 15:41:45 -05:00
Erik Welsh
e626f07d8d Fixed GPIO export problem; Leaves GPIO in bad state on latest BeagleBone image on PocketBeagle 2018-09-30 16:24:33 +00:00
Drew Fustini
8353c7c39b
update UART section in README
Signed-off-by: Drew Fustini <drew@pdp7.com>
2018-08-31 05:19:22 -05:00
Drew Fustini
bf97de641a
update install and test shell scripts
Signed-off-by: Drew Fustini <drew@pdp7.com>
2018-08-31 04:34:38 -05:00
Drew Fustini
c749402003
Add UART entries for the PocketBeagle (issue #242)
PocketBeagle pins with UART pin mode:

  P1_30 uart0_txd
  P1_32 uart0_rxd
  P2_11 uart1_rxd
  P2_09 uart1_txd
  P1_08 uart2_rxd
  P1_10 uart2_txd
  P2_29 uart3_txd

Available UART names on PocketBeagle:

 PB-UART0: /dev/ttyO0, Rx: P1_30, Tx: P1_32
 PB-UART1: /dev/ttyO1, Rx: P2_11, Tx: P2_09
 PB-UART2: /dev/ttyO2, Rx: P1_08, Tx: P1_10
 PB-UART3: /dev/ttyO3, Rx: P2_29, Tx: none

Signed-off-by: Drew Fustini <drew@pdp7.com>
2018-08-31 04:10:47 -05:00
Drew Fustini
829f97a917
Update ADC.rst 2018-08-16 01:20:47 -05:00
Drew Fustini
4a82f4c430
Update Encoder.rst 2018-08-16 01:17:32 -05:00
Drew Fustini
e9d56e06c7
Update ADC.rst
testing readthedocs webhook
2018-08-16 01:06:50 -05:00
Drew Fustini
a841a9dd0a
Merge pull request #271 from fcooper/documentation-updates
Documentation updates
2018-08-06 18:51:54 -05:00
Franklin S Cooper Jr
44c371a77a docs/GPIO.rst Make documentation a bit newbie friendly
Make it clear in the parameter snippet that the various attributes
belong to the GPIO class.

Signed-off-by: Franklin S Cooper Jr <fcooper27@gmail.com>
2018-07-31 21:17:50 -05:00
Franklin S Cooper Jr
61ca14b926 docs/GPIO.rst: Add information on blinking led
Copy information regarding blinking leds to the GPIO documentation

Signed-off-by: Franklin S Cooper Jr <fcooper27@gmail.com>
2018-07-31 21:03:29 -05:00
Franklin S Cooper Jr
339314535b docs/SPI.rst: Fix bus numbering in examples
Commit 8dfbf64c36 ("Fix spidev path mismatch (#216)")
changes how the SPI constructor maps to the spidev entry.
Update the documentation to reflect this change.

Signed-off-by: Franklin S Cooper Jr <fcooper27@gmail.com>
2018-07-31 20:44:11 -05:00
Demo User
4cc4b76188
update README with recommended Debian image
Signed-off-by: Drew Fustini <drew@pdp7.com>
2018-07-20 05:54:26 -05:00
Drew Fustini
bbf0927781
Merge pull request #251 from amarburg/master
Added usleep after successfully enabling PWM via udev.
2018-06-26 11:16:03 -05:00
Drew Fustini
dc24ebfba6
Merge pull request #257 from zsserg/develop
Fixed SEGFAULT when calling remove_event_detect()  and added epoll_ctl() return code handling
2018-06-26 10:58:47 -05:00
zserg
3265d156e4 * Minor style fixes
* Added comments
* Added debug logging
* Line 724 - now <initial> flag is properly reset upon removal of event detection from GPIO pin
2018-05-31 18:10:26 +01:00
zserg
b054cc083e * Fixed SEGFAULT in event_gpio,c run_callbacks()
* Added more elaborate epoll() error logging
2018-05-30 16:47:47 +01:00
Aaron Marburg
e061d1358e Added usleep after successfully enabling PWM via udev. 2018-04-12 22:46:49 +00:00
zserg
7091eeb36e Merge branch 'master' into develop 2018-02-19 17:45:22 +00:00
zserg
9fd1073982 * Fixed SEGFAULT when calling remove_event_detect() inside python callback function. 2018-02-18 00:02:50 +00:00
31 changed files with 534 additions and 262 deletions

View file

@ -1,47 +1,13 @@
Thank you for opening an issue on an Adafruit Python library repository. To
improve the speed of resolution please review the following guidelines and
common troubleshooting steps below before creating the issue:
Thank you for opening an issue on the Adafruit BeagleBone Python library repository.
- **Do not use GitHub issues for troubleshooting projects and issues.** Instead use
the forums at http://forums.adafruit.com to ask questions and troubleshoot why
something isn't working as expected. In many cases the problem is a common issue
that you will more quickly receive help from the forum community. GitHub issues
are meant for known defects in the code. If you don't know if there is a defect
in the code then start with troubleshooting on the forum first.
- **If following a tutorial or guide be sure you didn't miss a step.** Carefully
check all of the steps and commands to run have been followed. Consult the
forum if you're unsure or have questions about steps in a guide/tutorial.
In order to understand your system configuration better, please run:
```
sudo /opt/scripts/tools/version.sh
```
- **For Python/Raspberry Pi projects check these very common issues to ensure they don't apply**:
and paste the output in a reply.
- If you are receiving an **ImportError: No module named...** error then a
library the code depends on is not installed. Check the tutorial/guide or
README to ensure you have installed the necessary libraries. Usually the
missing library can be installed with the `pip` tool, but check the tutorial/guide
for the exact command.
This script should be present for any image downloaded from:
https://beagleboard.org/ or https://rcn-ee.com/
- **Be sure you are supplying adequate power to the board.** Check the specs of
your board and power in an external power supply. In many cases just
plugging a board into your computer is not enough to power it and other
peripherals.
- **Double check all soldering joints and connections.** Flakey connections
cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints.
If you're sure this issue is a defect in the code and checked the steps above
please fill in the following fields to provide enough troubleshooting information.
You may delete the guideline and text above to just leave the following details:
- Platform/operating system (i.e. Raspberry Pi with Raspbian operating system,
Windows 32-bit, Windows 64-bit, Mac OSX 64-bit, etc.): **INSERT PLATFORM/OPERATING
SYSTEM HERE**
- Python version (run `python -version` or `python3 -version`): **INSERT PYTHON
VERSION HERE**
- Error message you are receiving, including any Python exception traces: **INSERT
ERROR MESAGE/EXCEPTION TRACES HERE***
- List the steps to reproduce the problem below (if possible attach code or commands
to run): **LIST REPRO STEPS BELOW**

View file

@ -1,4 +1,6 @@
language: python
python:
- "3.6"
install:
- pip install tox
script:

View file

@ -351,7 +351,8 @@ class RotaryEncoder(object):
new positions.
'''
period = self._NS_FACTOR / frequency # Period in nanoseconds
# github issue #299: force period to be an integer
period = int(self._NS_FACTOR / frequency) # Period in nanoseconds
self._eqep.node.period = str(period)
self._logger.debug(
"Set frequency(): Channel {}, frequency: {} Hz, "

View file

@ -41,7 +41,7 @@ Usage examples::
# Print all block devices in /sys, with their sizes
for block_dev in sys.block:
print block_dev, str(int(block_dev.size) / 1048576) + ' M'
print(block_dev, str(int(block_dev.size) / 1048576) + ' M')
>>> import sysfs
>>> # Read/write Beaglebone Black's eQEP module attributes

View file

@ -1,3 +1,89 @@
1.1.2
---
Daniel Nguyen (2):
Update common.c
Update common.c
Drew Fustini (28):
upload to PyPI againt to resolve #293
do not set pinmux on the beaglebone blue
remove deug output
Fix dead link to bone.js #296
force Encoder period to be an integer #299
Ignore new compiler warnings in gcc 8.2.0
Update setup.py
do not set pin mode for built-in USRn LEDs
Change name of P1_3 to match bone.js
Fix warning about casting incompatible function types #308
Fix warning print format strings being truncated #308
Fix warning about casting incompatible function types #308
Fix warnings on format truncation and sizeof in strncpy #308
Fix warning about casting incompatible function types #308
Update travis config to specify Python 3.6
Update tox.ini to Python 3.6
Merge pull request #321 from adafruit/issue308
Update ISSUE_TEMPLATE.md
Update README.md
Update README.md
Merge pull request #327 from zer0cod3r/master
Merge pull request #337 from SamPovilus/docfix
Update README.md
Update README.md
Update README.md
remove -Werror from CFLAGS
Remove suppression of gcc warnings in CFLAGS #336
Update version in setup.py to v1.2
Sam Povilus (1):
fixing document locaiton and version as current location dosn't load
1.1.1
---
Attempt upload to PyPI again to avoid
error reported in issue #293
1.1.0
---
Aaron Marburg (1):
* Added usleep after successfully enabling PWM via udev.
Drew Fustini (16):
* Merge pull request #233 from zsserg/fixed_segfault_in_event_detection
* Merge pull request #257 from zsserg/develop
* Merge pull request #251 from amarburg/master
* Merge pull request #271 from fcooper/documentation-updates
* Update ADC.rst
* Update Encoder.rst
* Update ADC.rst
* Add UART entries for the PocketBeagle (issue #242)
* update install and test shell scripts
* update UART section in README
* Merge pull request #282 from erikwelsh/master
* do not load overlays for the beaglebone blue #283
* Merge pull request #284 from sam-bristow/py3-docs
* Merge pull request #285 from sam-bristow/bugfix/uart-error-reporting
* fix pwm on pocketbeagle and beaglebone blue #286
* remove debug logging
Erik Welsh (1):
* Fixed GPIO export problem; Leaves GPIO in bad state on latest BeagleBone image on PocketBeagle
Franklin S Cooper Jr (3):
* docs/SPI.rst: Fix bus numbering in examples
* docs/GPIO.rst: Add information on blinking led
* docs/GPIO.rst Make documentation a bit newbie friendly
Sam Bristow (3):
* Use print() function in all code and docs
* Use new python-serial API
* Return error-code for failing interface
zserg (5):
* Fixed SEGFAULT when calling remove_event_detect() inside python callback function.
* Fixed SEGFAULT when calling remove_event_detect() inside python callback function.
* Fixed SEGFAULT in event_gpio,c run_callbacks() * Added more elaborate epoll() error logging
* Minor style fixes
1.0.10
----
**features**

View file

@ -7,36 +7,37 @@
Adafruit BBIO is an API to enable [GPIO](README.md#gpio-setup), [PWM](README.md#pwm), [ADC](README.md#adc), [UART](README.md#uart), [SPI](README.md#spi) and [eQEP](README.md#eqep) (Quadrature Encoder) hardware access from Python applications running on the Beaglebone.
* It is recommended to use an [official BeagleBoard.org Debian image](https://beagleboard.org/latest-images)
* **Currently recommended image: [Debian 9.2 "Stretch" iot (2017-10-29)](https://elinux.org/Beagleboard:BeagleBoneBlack_Debian#microSD.2FStandalone:_.28stretch-iot.29_.28All_BeagleBone_Variants_.26_PocketBeagle.29)**
* Install [Linux kernel](https://elinux.org/Beagleboard:BeagleBoneBlack_Debian#Kernel_Options) [4.14.x](https://elinux.org/Beagleboard:BeagleBoneBlack_Debian#Mainline_.284.14.x_lts.29) to enable [non-root control of GPIO](https://github.com/rcn-ee/repos/blob/master/bb-customizations/suite/stretch/debian/80-gpio-noroot.rules) and [PWM](https://github.com/rcn-ee/repos/blob/master/bb-customizations/suite/stretch/debian/81-pwm-noroot.rules) [_(commit)_](https://github.com/adafruit/adafruit-beaglebone-io-python/commit/b65cbf8e41b444bad7c4ef6cfd4f88a30210fd78)
* **Currently recommended image: [Debian 10.3 "Buster" IoT (2020-04-06)](http://beagleboard.org/latest-images)** _(default kernel is 4.19.x-ti)_
* Adafruit_BBIO supports Linux kernels 3.8 through 4.14
* Adafruit_BBIO supports Linux kernels 3.8 through 4.19
* New versions of Adafruit_BBIO may break backwards compatibility. Please read the [changelog](CHANGELOG.md).
* It is recommended to use Python 3
## Installation on Debian
Easiest:
Note: Follow the instructions on BeagleBoard.org to [get connected to the Internet](https://beagleboard.org/upgrade#connect)
**Easiest:**
```
sudo ntpdate pool.ntp.org
sudo apt-get update
sudo apt-get install build-essential python-dev python-pip -y
sudo pip install Adafruit_BBIO
sudo apt-get install build-essential python3-dev python3-pip -y
sudo pip3 install Adafruit_BBIO
```
Manual:
**Manual:**
```
sudo ntpdate pool.ntp.org
sudo apt-get update
sudo apt-get install build-essential python-dev python-pip -y
sudo apt-get install build-essential python3-dev python3-pip -y
git clone git://github.com/adafruit/adafruit-beaglebone-io-python.git
cd adafruit-beaglebone-io-python
sudo python setup.py install
sudo python3 setup.py install
```
Upgrade Adafruit_BBIO to latest version on [PyPI](https://pypi.python.org/pypi/Adafruit_BBIO):
```
sudo pip install --upgrade Adafruit_BBIO
sudo pip3 install --upgrade Adafruit_BBIO
```
## Usage
@ -150,7 +151,7 @@ Detecting events:
#your amazing code here
#detect wherever:
if GPIO.event_detected("P9_12"):
print "event detected!"
print("event detected!")
### PWM
**The PWM Duty Cycle range was reversed in 0.0.15 from 100(off)-0(on) to 0(off)-100(on). Please update your code accordingly.**
@ -198,14 +199,21 @@ import serial
UART.setup("UART1")
ser = serial.Serial(port = "/dev/ttyO1", baudrate=9600)
ser.close()
ser.open()
if ser.isOpen():
print "Serial is open!"
ser.write("Hello World!")
ser.close()
with serial.Serial(port = "/dev/ttyO1", baudrate=9600) as ser:
print("Serial is open!")
ser.write(b"Hello World!")
```
* Available UART names on BeagleBone
* `UART1`: /dev/ttyO1, Rx: P9_26, Tx: P9_24
* `UART2`: /dev/ttyO2, Rx: P9_22, Tx: P9_21
* `UART4`: /dev/ttyO4, Rx: P9_11, Tx: P9_13
* `UART5`: /dev/ttyO5, Rx: P8_38, Tx: P8_37
* note: `UART5` requires `disable_uboot_overlay_video=1` in `/boot/uEnv.txt`
* Available UART names on PocketBeagle
* `PB-UART0`: /dev/ttyO0, Rx: P1_30, Tx: P1_32
* `PB-UART1`: /dev/ttyO1, Rx: P2_11, Tx: P2_09
* `PB-UART2`: /dev/ttyO2, Rx: P1_08, Tx: P1_10
* [Loopback test with UART1 and UART2](https://learn.adafruit.com/setting-up-io-python-library-on-beaglebone-black/uart#testing-and-using-the-uart)
@ -258,13 +266,25 @@ To use the enhanced Quadrature Encoder Pulse (eQEP) module, please refer to the
Install py.test to run the tests. You'll also need the python compiler package for pytest:
```
sudo pip install pytest
sudo pip3 install pytest
```
Execute the following in the root of the project:
```
sudo pytest
pytest
```
NOTE: `sudo` should not be required when running [Debian 9.2 "Stretch" iot (2017-10-29)](https://elinux.org/Beagleboard:BeagleBoneBlack_Debian#microSD.2FStandalone:_.28stretch-iot.29_.28All_BeagleBone_Variants_.26_PocketBeagle.29) with [Linux kernel](https://elinux.org/Beagleboard:BeagleBoneBlack_Debian#Kernel_Options) [4.14.x](https://elinux.org/Beagleboard:BeagleBoneBlack_Debian#Mainline_.284.14.x_lts.29) as udev configures group ownership and permission for [GPIO](https://github.com/rcn-ee/repos/blob/master/bb-customizations/suite/stretch/debian/80-gpio-noroot.rules) and [PWM](https://github.com/rcn-ee/repos/blob/master/bb-customizations/suite/stretch/debian/81-pwm-noroot.rules)
NOTE: `sudo` should not be required as udev configures group ownership and permission for [GPIO](https://github.com/rcn-ee/repos/blob/master/bb-customizations/suite/stretch/debian/80-gpio-noroot.rules) and [PWM](https://github.com/rcn-ee/repos/blob/master/bb-customizations/suite/stretch/debian/81-pwm-noroot.rules)
## Reporting issues
When reporting issues, plesae run the following script which will print the system configuration:
```
sudo /opt/scripts/tools/version.sh
```
and paste the output in a reply.
This script should be present for any Debian or Ubunut image downloaded from:
https://beagleboard.org/ or https://rcn-ee.com/
## Credits

View file

@ -2,7 +2,7 @@
--------------------------------------------
This module enables reading analog input values from the analog to digital
converter (ADC) on the Beaglebone processor.
converter (ADC) on the TI AM3358 SoC on the BeagleBone.
Example::
@ -35,8 +35,8 @@ Example::
Read the raw analog value for the channel.
:note: Kernels older than 4.1.x returned a raw value range based on
the reference voltage of 1.8 V from 0 to 1800.
:note: Kernels older than 4.1.x returned a raw value range 0 - 1800
based on the reference voltage of 1.8 V.
:param str channel: GPIO channel to read the value from (e.g. "P8_16").
:returns: raw value reading from 0 to 4095 (12 bits).

View file

@ -1,4 +1,4 @@
:mod:`Encoder` --- Quadrature Encoder interface
:mod:`Encoder` --- Quadrature Encoder interface (eQEP)
-----------------------------------------------
.. automodule:: Adafruit_BBIO.Encoder

View file

@ -21,6 +21,14 @@ I/O (GPIO).
`Beaglebone pin names table <https://github.com/adafruit/adafruit-beaglebone-io-python/blob/master/source/common.c#L73>`_
.. note::
On-board LEDs (USR0-USR3) are handled by LED class driver rather than the GPIO pin driver.
They have a different path in the /sys/ filesystem.
Setup the pin for output and write GPIO.HIGH or GPIO.LOW
Example::
# Use the config-pin command line tool to set a pin's function to GPIO
@ -38,17 +46,36 @@ Example::
GPIO.output("P8_14", GPIO.HIGH) # You can also write '1' instead
GPIO.output("P8_14", GPIO.LOW) # You can also write '0' instead
# Blinking onboard led example
import Adafruit_BBIO.GPIO as GPIO
import time
for i in range(4):
GPIO.setup("USR%d" % i, GPIO.OUT)
while True:
for i in range(4):
GPIO.output("USR%d" % i, GPIO.HIGH)
time.sleep(1)
for i in range(4):
GPIO.output("USR%d" % i, GPIO.LOW)
time.sleep(1)
.. module:: Adafruit_BBIO.GPIO
.. function:: setup(channel, direction[, pull_up_down=PUD_OFF, initial=None, delay=0])
.. function:: setup(channel, direction[, pull_up_down=GPIO.PUD_OFF, initial=None, delay=0])
Set up the given GPIO channel, its direction and (optional) pull/up down control
:param str channel: GPIO channel to set up (e.g. "P8_16").
:param int direction: GPIO channel direction (:data:`IN` or :data:`OUT`).
:param int direction: GPIO channel direction
(:data:`GPIO.IN` or :data:`GPIO.OUT`).
:param int pull_up_down: pull-up/pull-down resistor configuration
(:data:`PUD_OFF`, :data:`PUD_UP` or :data:`PUD_DOWN`).
:param int initial: initial value for an output channel (:data:`LOW`/:data:`HIGH`).
(:data:`GPIO.PUD_OFF`, :data:`GPIO.PUD_UP` or :data:`GPIO.PUD_DOWN`).
:param int initial: initial value for an output channel
(:data:`GPIO.LOW`/:data:`GPIO.HIGH`).
:param int delay: time in milliseconds to wait after exporting the GPIO pin.
.. function:: cleanup()
@ -66,7 +93,7 @@ Example::
:param str channel: GPIO channel to output the value to (e.g. "P8_16").
:param value: value to set the output to-- 0/1 or False/True
or :data:`LOW`/:data:`HIGH`.
or :data:`GPIO.LOW`/:data:`GPIO.HIGH`.
:type value: int or bool
.. function:: input(channel)
@ -82,8 +109,8 @@ Example::
Enable edge detection events for the given GPIO channel.
:param str channel: GPIO channel to detect events from (e.g. "P8_16").
:param int edge: edge to detect :data:`RISING`, :data:`FALLING`
or :data:`BOTH`
:param int edge: edge to detect :data:`GPIO.RISING`, :data:`GPIO.FALLING`
or :data:`GPIO.BOTH`
:param func callback: a function to call once the event has been detected.
:param int bouncetime: switch bounce timeout in ms for the callback.
@ -118,8 +145,8 @@ Example::
Wait for an edge on the given channel.
:param str channel: GPIO channel to wait on (e.g. "P8_16").
:param int edge: edge to detect :data:`RISING`, :data:`FALLING`
or :data:`BOTH`
:param int edge: edge to detect :data:`GPIO.RISING`, :data:`GPIO.FALLING`
or :data:`GPIO.BOTH`
:param int timeout: time to wait for an edge, in milliseconds.
-1 will wait forever.

View file

@ -27,22 +27,22 @@ Example::
# spi = SPI(bus, device) #/dev/spidev<bus>.<device>
# /dev/spidev0.0
spi = SPI(1, 0)
spi = SPI(0, 0)
print(spi.xfer2([32, 11, 110, 22, 220]))
spi.close()
# /dev/spidev0.1
spi = SPI(1, 1)
spi = SPI(0, 1)
print(spi.xfer2([32, 11, 110, 22, 220]))
spi.close()
# /dev/spidev1.0
spi = SPI(2, 0)
spi = SPI(1, 0)
print(spi.xfer2([32, 11, 110, 22, 220]))
spi.close()
# /dev/spidev1.1
spi = SPI(2, 1)
spi = SPI(1, 1)
print(spi.xfer2([32, 11, 110, 22, 220]))
spi.close()

View file

@ -14,13 +14,9 @@ Example::
UART.setup("UART1")
ser = serial.Serial(port = "/dev/ttyO1", baudrate=9600)
ser.close()
ser.open()
if ser.isOpen():
print "Serial is open!"
ser.write("Hello World!")
ser.close()
with serial.Serial(port = "/dev/ttyO1", baudrate=9600) as ser:
print("Serial is open!")
ser.write(b"Hello World!")
.. module:: Adafruit_BBIO.UART

View file

@ -1,9 +1,7 @@
#!/bin/bash
# useful for testing changes against all versions of python
make clean
echo "Install Python 2.7"
python2.7 ./setup.py install
echo "Install Python 3.5"
python3.5 ./setup.py install
echo "Install Python 3.6"
python3.6 ./setup.py install
echo "Install Python 2"
python2 ./setup.py install
echo "Install Python 3"
python3 ./setup.py install

View file

@ -2,10 +2,8 @@
# useful for testing changes against all versions of python
cd test
echo "Testing Python 2.7"
python2.7 -mpytest
echo "Testing Python 3.5"
python3.5 -mpytest
echo "Testing Python 3.6"
python3.6 -mpytest
echo "Testing Python 2"
python2 -mpytest
echo "Testing Python 3"
python3 -mpytest
cd ..

View file

@ -21,7 +21,7 @@ if kernel >= '4.1.0':
else:
kernel41 = None
CFLAGS = ['-Wall', '-Werror', '-Wextra', '-Wno-missing-field-initializers', '-Wno-strict-aliasing' ]
CFLAGS = ['-Wall']
classifiers = ['Development Status :: 3 - Alpha',
'Operating System :: POSIX :: Linux',
@ -40,11 +40,12 @@ extension_args = {
}
setup(name = 'Adafruit_BBIO',
version = '1.0.10',
version = '1.2.0',
author = 'Justin Cooper',
author_email = 'justin@adafruit.com',
description = 'A module to control BeagleBone IO channels',
long_description = open_as_utf8('README.md').read() + open_as_utf8('CHANGELOG.md').read(),
long_description_content_type = 'text/markdown',
license = 'MIT',
keywords = 'Adafruit BeagleBone IO GPIO PWM ADC',
url = 'https://github.com/adafruit/adafruit-beaglebone-io-python/',

View file

@ -41,9 +41,9 @@ int adc_initialized = 0;
BBIO_err initialize_adc(void)
{
#ifdef BBBVERSION41
char test_path[49];
char test_path[149];
#else
char test_path[40];
char test_path[140];
#endif
FILE *fh;
BBIO_err err;
@ -94,10 +94,10 @@ BBIO_err read_value(unsigned int ain, float *value)
{
FILE * fh;
#ifdef BBBVERSION41
char ain_path[49];
char ain_path[149];
snprintf(ain_path, sizeof(ain_path), "%s%d_raw", adc_prefix_dir, ain);
#else
char ain_path[40];
char ain_path[140];
snprintf(ain_path, sizeof(ain_path), "%s%d", adc_prefix_dir, ain);
#endif

View file

@ -9,11 +9,16 @@
BBIO_err set_pin_mode(const char *key, const char *mode)
{
// char ocp_dir[] defined in common.h
char path[60]; // "/sys/devices/platform/ocp/ocp:P#_##_pinmux/state"
char path[100]; // "/sys/devices/platform/ocp/ocp:P#_##_pinmux/state"
char pinmux_dir[20]; // "ocp:P#_##_pinmux"
char pin[6]; //"P#_##"
FILE *f = NULL;
// pin mode can not be set for the built-in USRn LEDs
if (strncmp(key, "USR", 3) == 0) {
return BBIO_OK;
}
if (strlen(key) == 4) // Key P#_# format, must inject '0' to be P#_0#
snprintf(pin, sizeof(pin), "%.3s0%c", key,key[3]);
else //copy string
@ -32,6 +37,14 @@ BBIO_err set_pin_mode(const char *key, const char *mode)
snprintf(pinmux_dir, sizeof(pinmux_dir), "ocp:%s_pinmux", pin);
snprintf(path, sizeof(path), "%s/%s/state", ocp_dir, pinmux_dir);
/* beaglebone blue has complete dtb file and does not need overlays */
if(beaglebone_blue()) {
fprintf(stderr, "DEBUG: Adafruit_BBIO: set_pin_mode() :: Pinmux file: %s, mode: %s", path, mode);
fprintf(stderr, "DEBUG: Adafruit_BBIO: set_pin_mode(): beaglebone_blue() is TRUE; return BBIO_OK\n");
return BBIO_OK;
}
f = fopen(path, "w");
if (NULL == f) {
return BBIO_ACCESS;

View file

@ -94,6 +94,14 @@ void export_pwm(struct pwm_exp *new_pwm)
}
}
int is_dmtimer_pin(pwm_t *p) {
char temp[6];
strncpy(temp, p->module, 5);
temp[5] = '\0';
return (strcmp(temp, "timer") == 0);
}
BBIO_err initialize_pwm(void)
{
#ifdef BBBVERSION41 // don't load overlay in 4.1+
@ -119,7 +127,7 @@ BBIO_err initialize_pwm(void)
BBIO_err pwm_set_frequency(const char *key, float freq) {
int len;
char buffer[20];
char buffer[100];
unsigned long period_ns;
struct pwm_exp *pwm;
@ -195,7 +203,7 @@ BBIO_err pwm_set_frequency(const char *key, float freq) {
// Only works before chip is enabled
BBIO_err pwm_set_polarity(const char *key, int polarity) {
int len;
char buffer[9]; /* allow room for trailing NUL byte */
char buffer[100]; /* allow room for trailing NUL byte */
struct pwm_exp *pwm;
#ifdef BBBVERSION41
int enabled; /* Maintain original state */
@ -275,7 +283,7 @@ BBIO_err pwm_set_polarity(const char *key, int polarity) {
BBIO_err pwm_set_duty_cycle(const char *key, float duty) {
int len;
char buffer[20];
char buffer[100];
struct pwm_exp *pwm;
if (duty < 0.0 || duty > 100.0)
@ -309,17 +317,17 @@ BBIO_err pwm_setup(const char *key, __attribute__ ((unused)) float duty, __attri
struct pwm_exp *new_pwm;
#ifdef BBBVERSION41
char pwm_dev_path[45]; // "/sys/devices/platform/ocp/48300000.epwmss"
char pwm_addr_path[60]; // "/sys/devices/platform/ocp/48300000.epwmss/48300200.ehrpwm"
char pwm_chip_path[75]; // "/sys/devices/platform/ocp/48300000.epwmss/48300200.ehrpwm/pwm/pwmchip0"
char pwm_export_path[80]; // "/sys/devices/platform/ocp/48300000.epwmss/48300200.ehrpwm/pwm/pwmchip0/export"
char pwm_path[85]; // "/sys/devices/platform/ocp/48300000.epwmss/48300200.ehrpwm/pwm/pwmchip0/pwm1"
char pwm_path_udev[85]; // "/sys/devices/platform/ocp/48300000.epwmss/48300200.ehrpwm/pwm/pwmchip0/pwm-0:1"
char ecap_path_udev[85];// "/sys/devices/platform/ocp/48300000.epwmss/48300100.ecap/pwm/pwmchip0/pwm-0:0/"
char duty_path[95]; // "/sys/devices/platform/ocp/48300000.epwmss/48300200.ehrpwm/pwm/pwmchip0/pwm1/duty_cycle"
char period_path[95];
char polarity_path[95];
char enable_path[90];
char pwm_dev_path[100]; // "/sys/devices/platform/ocp/48300000.epwmss"
char pwm_addr_path[150]; // "/sys/devices/platform/ocp/48300000.epwmss/48300200.ehrpwm"
char pwm_chip_path[200]; // "/sys/devices/platform/ocp/48300000.epwmss/48300200.ehrpwm/pwm/pwmchip0"
char pwm_export_path[250]; // "/sys/devices/platform/ocp/48300000.epwmss/48300200.ehrpwm/pwm/pwmchip0/export"
char pwm_path[250]; // "/sys/devices/platform/ocp/48300000.epwmss/48300200.ehrpwm/pwm/pwmchip0/pwm2"
char pwm_path_udev[250]; // "/sys/devices/platform/ocp/48300000.epwmss/48300200.ehrpwm/pwm/pwmchip0/pwm-0:2"
char ecap_path_udev[300]; // "/sys/devices/platform/ocp/48300000.epwmss/48300200.ecap/pwm/pwmchip0/pwm-0:0/"
char duty_path[300]; // "/sys/devices/platform/ocp/48300000.epwmss/48300200.ehrpwm/pwm/pwmchip0/pwm2/duty_cycle"
char period_path[300];
char polarity_path[300];
char enable_path[300];
char pin_mode[PIN_MODE_LEN]; // "pwm" or "pwm2"
int e;
@ -338,6 +346,10 @@ BBIO_err pwm_setup(const char *key, __attribute__ ((unused)) float duty, __attri
// Make sure that one of the universal capes is loaded
if( !uboot_overlay_enabled() // only check kernel overlays if u-boot overlays are not being used
&&
!beaglebone_blue() // beaglebone blue has complete dtb file and does not need overlays
&&
!pocketbeagle() // pocketbeagle has complete dtb file and does not need overlays
&&
!( device_tree_loaded("cape-univ-audio") // from cdsteinkuehler/beaglebone-universal-io
|| device_tree_loaded("cape-univ-emmc") // ""
@ -371,16 +383,27 @@ BBIO_err pwm_setup(const char *key, __attribute__ ((unused)) float duty, __attri
return err;
}
err = build_path(ocp_dir, p->chip, pwm_dev_path, sizeof(pwm_dev_path));
if (err != BBIO_OK) {
syslog(LOG_ERR, "Adafruit_BBIO: pwm_setup: %s couldn't build pwm_dev_path: %i", key, err);
return err;
}
int dmtimer_pin = is_dmtimer_pin(p);
err = build_path(pwm_dev_path, p->addr, pwm_addr_path, sizeof(pwm_addr_path));
if (err != BBIO_OK) {
syslog(LOG_ERR, "Adafruit_BBIO: pwm_setup: %s couldn't build pwm_addr_path: %i", key, err);
return err;
if(!dmtimer_pin) {
err = build_path(ocp_dir, p->chip, pwm_dev_path, sizeof(pwm_dev_path));
if (err != BBIO_OK) {
syslog(LOG_ERR, "Adafruit_BBIO: pwm_setup: %s couldn't build pwm_dev_path: %i", key, err);
return err;
}
err = build_path(pwm_dev_path, p->addr, pwm_addr_path, sizeof(pwm_addr_path));
if (err != BBIO_OK) {
syslog(LOG_ERR, "Adafruit_BBIO: pwm_setup: %s couldn't build pwm_addr_path: %i", key, err);
return err;
}
}
else {
err = build_path("/sys/devices/platform", p->addr, pwm_addr_path, sizeof(pwm_addr_path));
if (err != BBIO_OK) {
syslog(LOG_ERR, "Adafruit_BBIO: pwm_setup: %s couldn't build pwm_addr_path, are you sure you've loaded the correct dmtimer device tree overlay?: %i", key, err);
return err;
}
}
err = build_path(pwm_addr_path, "pwm/pwmchip", pwm_chip_path, sizeof(pwm_chip_path));
@ -393,10 +416,10 @@ BBIO_err pwm_setup(const char *key, __attribute__ ((unused)) float duty, __attri
syslog(LOG_DEBUG, "Adafruit_BBIO: pwm_start: key: %s, pwm_path: %s", key, pwm_path);
//pwm with udev patch
snprintf(pwm_path_udev, sizeof(pwm_path_udev), "%s/pwm-%c:%d", pwm_chip_path, pwm_path[66], p->index);
snprintf(pwm_path_udev, sizeof(pwm_path_udev), "%s/pwm-%c:%d", pwm_chip_path, dmtimer_pin ? pwm_path[47] : pwm_path[66], p->index);
syslog(LOG_DEBUG, "Adafruit_BBIO: pwm_start: key: %s, pwm_path_udev: %s", key, pwm_path_udev);
//ecap output with udev patch
snprintf(ecap_path_udev, sizeof(ecap_path_udev), "%s/pwm-%c:%d", pwm_chip_path, pwm_path[67], p->index);
snprintf(ecap_path_udev, sizeof(ecap_path_udev), "%s/pwm-%c:%d", pwm_chip_path, dmtimer_pin ? pwm_path[47] : pwm_path[67], p->index);
syslog(LOG_DEBUG, "Adafruit_BBIO: pwm_start: key: %s, ecap_path_udev: %s", key, ecap_path_udev);
// Export PWM if hasn't already been
@ -452,11 +475,12 @@ BBIO_err pwm_setup(const char *key, __attribute__ ((unused)) float duty, __attri
return BBIO_GEN;
}
} else {
strncpy(pwm_path, ecap_path_udev, sizeof(ecap_path_udev));
strncpy(pwm_path, ecap_path_udev, sizeof(pwm_path));
}
}
} else {
strncpy(pwm_path, pwm_path_udev, sizeof(pwm_path_udev));
strncpy(pwm_path, pwm_path_udev, sizeof(pwm_path));
usleep(100*1000);
}
}
}
@ -465,12 +489,12 @@ BBIO_err pwm_setup(const char *key, __attribute__ ((unused)) float duty, __attri
snprintf(duty_path, sizeof(duty_path), "%s/duty_cycle", pwm_path);
snprintf(enable_path, sizeof(enable_path), "%s/enable", pwm_path);
#else
char fragment[18];
char pwm_fragment[20];
char pwm_path[45];
char duty_path[56];
char period_path[50];
char polarity_path[55];
char fragment[100];
char pwm_fragment[100];
char pwm_path[100];
char duty_path[200];
char period_path[100];
char polarity_path[100];
int period_fd, duty_fd, polarity_fd;
if (!pwm_initialized) {
@ -582,9 +606,10 @@ BBIO_err pwm_setup(const char *key, __attribute__ ((unused)) float duty, __attri
BBIO_err pwm_start(const char *key, float duty, float freq, int polarity)
{
syslog(LOG_DEBUG, "Adafruit_BBIO: pwm_start: %s, %f, %f, %i", key, duty, freq, polarity);
//fprintf(stderr, "Adafruit_BBIO: pwm_start: %s, %f, %f, %i\n", key, duty, freq, polarity);
BBIO_err err;
char buffer[20];
char buffer[100];
ssize_t len;
struct pwm_exp *pwm = lookup_exported_pwm(key);
@ -688,7 +713,7 @@ BBIO_err pwm_disable(const char *key)
#ifndef BBBVERSION41
BBIO_err err;
char fragment[18];
char fragment[100];
snprintf(fragment, sizeof(fragment), "bone_pwm_%s", key);
err = unload_device_tree(fragment);
if (err != BBIO_OK)
@ -703,7 +728,7 @@ BBIO_err pwm_disable(const char *key)
{
#ifdef BBBVERSION41
char buffer[2];
char buffer[100];
size_t len;
// Disable the PWM

View file

@ -46,13 +46,13 @@ BBIO_err uart_cleanup(void)
if (e1 != BBIO_OK)
return e1;
if (e2 != BBIO_OK)
return e1;
return e2;
if (e3 != BBIO_OK)
return e1;
return e3;
if (e4 != BBIO_OK)
return e1;
return e4;
if (e5 != BBIO_OK)
return e1;
return e5;
return BBIO_OK;
}

View file

@ -69,7 +69,7 @@ typedef struct pins_t {
int ain;
} pins_t;
//Table generated based on https://raw.github.com/jadonk/bonescript/master/node_modules/bonescript/bone.js
//Table generated based on https://github.com/jadonk/bonescript/blob/master/src/bone.js
pins_t table[] = {
{ "USR0", "USR0", 53, -1, -1},
{ "USR1", "USR1", 54, -1, -1},
@ -81,10 +81,10 @@ pins_t table[] = {
{ "GPIO1_7", "P8_4", 39, -1, -1},
{ "GPIO1_2", "P8_5", 34, -1, -1},
{ "GPIO1_3", "P8_6", 35, -1, -1},
{ "TIMER4", "P8_7", 66, -1, -1},
{ "TIMER7", "P8_8", 67, -1, -1},
{ "TIMER5", "P8_9", 69, -1, -1},
{ "TIMER6", "P8_10", 68, -1, -1},
{ "TIMER4", "P8_7", 66, 2, -1},
{ "TIMER7", "P8_8", 67, 2, -1},
{ "TIMER5", "P8_9", 69, 2, -1},
{ "TIMER6", "P8_10", 68, 2, -1},
{ "GPIO1_13", "P8_11", 45, -1, -1},
{ "GPIO1_12", "P8_12", 44, -1, -1},
{ "EHRPWM2B", "P8_13", 23, 4, -1},
@ -189,7 +189,7 @@ pins_t table[] = {
// These are for the PocketBeagle
{ "VIN_AC", "P1_1", 0, -1, -1},
{ "GPIO2_23", "P1_2", 87, -1, -1},
{ "USB1_VBUS_OUT", "P1_3", 0, -1, -1},
{ "USB1_DRVVBUS", "P1_3", 0, -1, -1},
{ "GPIO2_25", "P1_4", 89, -1, -1},
{ "USB1_VBUS_IN", "P1_5", 0, -1, -1},
{ "SPI0_CS0", "P1_6", 5, -1, -1},
@ -206,15 +206,15 @@ pins_t table[] = {
{ "VREFN", "P1_17", 0, -1, -1},
{ "VREFP", "P1_18", 0, -1, -1},
{ "AIN0", "P1_19", 0, -1, 0},
{ "GPIO0_20", "P1_20", 20, -1, -1},
{ "GPIO0_20", "P1_20", 20, 4, -1},
{ "AIN1", "P1_21", 0, -1, 1},
{ "GND", "P1_22", 0, -1, -1},
{ "AIN2", "P1_23", 0, -1, 2},
{ "VOUT-5V", "P1_24", 0, -1, -1},
{ "AIN3", "P1_25", 0, -1, 3},
{ "I2C2_SDA", "P1_26", 12, -1, -1},
{ "I2C2_SDA", "P1_26", 12, 1, -1},
{ "AIN4", "P1_27", 0, -1, 4},
{ "I2C2_SCL", "P1_28", 13, -1, -1},
{ "I2C2_SCL", "P1_28", 13, 1, -1},
{ "GPIO3_21", "P1_29", 117, -1, -1},
{ "UART0_TXD", "P1_30", 43, -1, -1},
{ "GPIO3_18", "P1_31", 114, -1, -1},
@ -249,11 +249,11 @@ pins_t table[] = {
{ "GPIO1_12", "P2_24", 44, -1, -1},
{ "SPI1_CS0", "P2_25", 41, -1, -1},
{ "RESET#", "P2_26", 0, -1, -1},
{ "SPI1_D0", "P2_27", 40, -1, -1},
{ "SPI1_D0", "P2_27", 40, 5, -1},
{ "GPIO3_20", "P2_28", 116, -1, -1},
{ "SPI1_SCLK", "P2_29", 7, -1, -1},
{ "GPIO3_17", "P2_30", 113, -1, -1},
{ "SPI1_CS1", "P2_31", 19, -1, -1},
{ "SPI1_CS1", "P2_31", 19, 2, -1},
{ "GPIO3_16", "P2_32", 112, -1, -1},
{ "GPIO1_13", "P2_33", 45, -1, -1},
{ "GPIO3_19", "P2_34", 115, -1, -1},
@ -263,18 +263,33 @@ pins_t table[] = {
{ NULL, NULL, 0, 0, 0 }
};
// Issue #243: UART setup not working for pocket beagle pins
// Add UART entries for the PocketBeagle:
// P1_30 uart0_txd
// P1_32 uart0_rxd
// P2_11 uart1_rxd
// P2_09 uart1_txd
// P1_08 uart2_rxd
// P1_10 uart2_txd
// P2_05 uart4_rxd
// P2_07 uart4_txd
uart_t uart_table[] = {
{ "UART1", "/dev/ttyO1", "ADAFRUIT-UART1", "P9_26", "P9_24"},
{ "UART2", "/dev/ttyO2", "ADAFRUIT-UART2", "P9_22", "P9_21"},
{ "UART3", "/dev/ttyO3", "ADAFRUIT-UART3", "P9_42", ""},
{ "UART4", "/dev/ttyO4", "ADAFRUIT-UART4", "P9_11", "P9_13"},
{ "UART5", "/dev/ttyO5", "ADAFRUIT-UART5", "P8_38", "P8_37"},
{ "PB-UART0", "/dev/ttyO0", "ADAFRUIT-UART0", "P1_30", "P1_32"},
{ "PB-UART1", "/dev/ttyO1", "ADAFRUIT-UART1", "P2_11", "P2_09"},
{ "PB-UART2", "/dev/ttyO2", "ADAFRUIT-UART2", "P1_08", "P1_10"},
{ "PB-UART4", "/dev/ttyO4", "ADAFRUIT-UART4", "P2_05", "P2_07"},
{ NULL, NULL, 0, 0, 0 }
};
// Copied from https://github.com/jadonk/bonescript/blob/master/src/bone.js
// See am335x technical manual, p. 183, for more info:
// http://www.ti.com/lit/ug/spruh73n/spruh73n.pdf
// https://www.ti.com/lit/ug/spruh73q/spruh73q.pdf
pwm_t pwm_table[] = {
{ "ehrpwm2", 6, 1, 4, "ehrpwm.2:1", "EHRPWM2B", "48304000", "48304200", "P8_13"},
{ "ehrpwm2", 5, 0, 4, "ehrpwm.2:0", "EHRPWM2A", "48304000", "48304200", "P8_19"},
@ -290,12 +305,21 @@ pwm_t pwm_table[] = {
{ "ehrpwm0", 1, 1, 1, "ehrpwm.0:1", "EHRPWM0B", "48300000", "48300200", "P9_29"},
{ "ehrpwm0", 0, 0, 1, "ehrpwm.0:0", "EHRPWM0A", "48300000", "48300200", "P9_31"},
{ "ecap0", 2, 0, 0, "ecap.0", "ECAPPWM0", "48300000", "48300100", "P9_42"},
{ "timer4", 0, 0, 2, "", "", "", "dmtimer-pwm-4", "P8_7" },
{ "timer7", 0, 0, 2, "", "", "", "dmtimer-pwm-7", "P8_8" },
{ "timer5", 0, 0, 2, "", "", "", "dmtimer-pwm-5", "P8_9" },
{ "timer6", 0, 0, 2, "", "", "", "dmtimer-pwm-6", "P8_10" },
{ "ehrpwm0", 0, 0, 1, "ehrpwm.0:0", "EHRPWM0A", "48300000", "48300200", "P1_8"},
{ "ehrpwm0", 0, 0, 1, "ehrpwm.0:0", "EHRPWM0A", "48300000", "48300200", "P1_36"},
{ "ehrpwm0", 1, 1, 1, "ehrpwm.0:1", "EHRPWM0B", "48300000", "48300200", "P1_10"},
{ "ehrpwm0", 1, 1, 1, "ehrpwm.0:1", "EHRPWM0B", "48300000", "48300200", "P1_33"},
{ "ehrpwm1", 3, 0, 6, "ehrpwm.1:0", "EHRPWM1A", "48302000", "48302200", "P2_1"},
{ "ehrpwm2", 6, 1, 3, "ehrpwm.2:1", "EHRPWM2B", "48304000", "48304200", "P2_3"},
{ "timer7", 0, 0, 4, "", "", "", "dmtimer-pwm-7", "P1_20" },
{ "timer6", 0, 0, 1, "", "", "", "dmtimer-pwm-6", "P1_26" },
{ "timer5", 0, 0, 1, "", "", "", "dmtimer-pwm-5", "P1_28" },
{ "timer7", 0, 0, 5, "", "", "", "dmtimer-pwm-7", "P2_27" },
{ "timer4", 0, 0, 2, "", "", "", "dmtimer-pwm-4", "P2_31" },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }
};
@ -624,12 +648,10 @@ BBIO_err load_device_tree(const char *name)
{
char line[256];
FILE *file = NULL;
char slots[100];
#ifdef BBBVERSION41
char slots[41];
snprintf(ctrl_dir, sizeof(ctrl_dir), "/sys/devices/platform/bone_capemgr");
#else
char slots[40];
build_path("/sys/devices", "bone_capemgr", ctrl_dir, sizeof(ctrl_dir));
#endif
@ -641,7 +663,15 @@ BBIO_err load_device_tree(const char *name)
return BBIO_OK;
}
/* beaglebone blue has complete dtb file and does not need overlays */
if(beaglebone_blue()) {
//fprintf(stderr, "common.c: load_device_tree(): beaglebone_blue(): TRUE\n");
return BBIO_OK;
}
/* pocketbeagle has complete dtb file and does not need overlays */
if(pocketbeagle()) {
//fprintf(stderr, "common.c: load_device_tree(): pocketbeagle(): TRUE\n");
return BBIO_OK;
}
@ -678,11 +708,10 @@ BBIO_err load_device_tree(const char *name)
int device_tree_loaded(const char *name)
{
FILE *file = NULL;
char slots[100];
#ifdef BBBVERSION41
char slots[41];
snprintf(ctrl_dir, sizeof(ctrl_dir), "/sys/devices/platform/bone_capemgr");
#else
char slots[40];
build_path("/sys/devices", "bone_capemgr", ctrl_dir, sizeof(ctrl_dir));
#endif
char line[256];
@ -695,7 +724,15 @@ int device_tree_loaded(const char *name)
return 1;
}
/* beaglebone blue has complete dtb file and does not need overlays */
if(beaglebone_blue()) {
//fprintf(stderr, "common.c: device_tree_loaded(): beaglebone_blue(): TRUE\n");
return BBIO_OK;
}
/* pocketbeagle has complete dtb file and does not need overlays */
if(pocketbeagle()) {
//fprintf(stderr, "common.c: device_tree_loaded(): pocketbeagle(): TRUE\n");
return BBIO_OK;
}
@ -727,16 +764,27 @@ int device_tree_loaded(const char *name)
BBIO_err unload_device_tree(const char *name)
{
FILE *file = NULL;
char slots[100];
#ifdef BBBVERSION41
char slots[41];
snprintf(ctrl_dir, sizeof(ctrl_dir), "/sys/devices/platform/bone_capemgr");
#else
char slots[40];
build_path("/sys/devices", "bone_capemgr", ctrl_dir, sizeof(ctrl_dir));
#endif
char line[256];
char *slot_line;
/* beaglebone blue has complete dtb file and does not need overlays */
if(beaglebone_blue()) {
//fprintf(stderr, "common.c: unload_device_tree(): beaglebone_blue(): TRUE\n");
return BBIO_OK;
}
/* pocketbeagle has complete dtb file and does not need overlays */
if(pocketbeagle()) {
//fprintf(stderr, "common.c: unload_device_tree(): pocketbeagle(): TRUE\n");
return BBIO_OK;
}
snprintf(slots, sizeof(slots), "%s/slots", ctrl_dir);
file = fopen(slots, "r+");
if (!file) {

View file

@ -35,39 +35,41 @@ SOFTWARE.
void define_constants(PyObject *module)
{
high = Py_BuildValue("i", HIGH);
PyModule_AddObject(module, "HIGH", high);
PyObject *object;
low = Py_BuildValue("i", LOW);
PyModule_AddObject(module, "LOW", low);
object = Py_BuildValue("i", HIGH);
PyModule_AddObject(module, "HIGH", object);
output = Py_BuildValue("i", OUTPUT);
PyModule_AddObject(module, "OUT", output);
object = Py_BuildValue("i", LOW);
PyModule_AddObject(module, "LOW", object);
input = Py_BuildValue("i", INPUT);
PyModule_AddObject(module, "IN", input);
object = Py_BuildValue("i", OUTPUT);
PyModule_AddObject(module, "OUT", object);
alt0 = Py_BuildValue("i", ALT0);
PyModule_AddObject(module, "ALT0", alt0);
object = Py_BuildValue("i", INPUT);
PyModule_AddObject(module, "IN", object);
pud_off = Py_BuildValue("i", PUD_OFF);
PyModule_AddObject(module, "PUD_OFF", pud_off);
object = Py_BuildValue("i", ALT0);
PyModule_AddObject(module, "ALT0", object);
pud_up = Py_BuildValue("i", PUD_UP);
PyModule_AddObject(module, "PUD_UP", pud_up);
object = Py_BuildValue("i", PUD_OFF);
PyModule_AddObject(module, "PUD_OFF", object);
pud_down = Py_BuildValue("i", PUD_DOWN);
PyModule_AddObject(module, "PUD_DOWN", pud_down);
object = Py_BuildValue("i", PUD_UP);
PyModule_AddObject(module, "PUD_UP", object);
object = Py_BuildValue("i", PUD_DOWN);
PyModule_AddObject(module, "PUD_DOWN", object);
rising_edge = Py_BuildValue("i", RISING_EDGE);
PyModule_AddObject(module, "RISING", rising_edge);
object = Py_BuildValue("i", RISING_EDGE);
PyModule_AddObject(module, "RISING", object);
falling_edge = Py_BuildValue("i", FALLING_EDGE);
PyModule_AddObject(module, "FALLING", falling_edge);
object = Py_BuildValue("i", FALLING_EDGE);
PyModule_AddObject(module, "FALLING", object);
both_edge = Py_BuildValue("i", BOTH_EDGE);
PyModule_AddObject(module, "BOTH", both_edge);
object = Py_BuildValue("i", BOTH_EDGE);
PyModule_AddObject(module, "BOTH", object);
version = Py_BuildValue("s", "0.0.20");
PyModule_AddObject(module, "VERSION", version);
object = Py_BuildValue("s", "0.0.20");
PyModule_AddObject(module, "VERSION", object);
}

View file

@ -1,19 +1,6 @@
#ifndef CONSTANTS_H
#define CONSTANTS_H
PyObject *high;
PyObject *low;
PyObject *input;
PyObject *output;
PyObject *alt0;
PyObject *pud_off;
PyObject *pud_up;
PyObject *pud_down;
PyObject *rising_edge;
PyObject *falling_edge;
PyObject *both_edge;
PyObject *version;
void define_constants(PyObject *module);
#endif

View file

@ -80,18 +80,39 @@ BBIO_err gpio_export(unsigned int gpio)
// already exported by us?
if (exported_gpios[gpio] != GPIO_NOT_EXPORTED) {
syslog(LOG_DEBUG, "Adafruit_BBIO: gpio_export: %u already exported", gpio);
syslog(LOG_DEBUG, "Adafruit_BBIO: gpio_export(): %u already exported before", gpio);
ret = BBIO_OK;
goto exit;
}
// Is GPIO an LED?
if ( ((gpio >= USR_LED_GPIO_MIN) && (gpio <= USR_LED_GPIO_MAX))
||
( beaglebone_blue()
&&
(
(gpio == USR_LED_RED)
|| (gpio == USR_LED_GREEN)
|| (gpio == BAT25)
|| (gpio == BAT50)
|| (gpio == BAT75)
|| (gpio == BAT100)
|| (gpio == WIFI)
)
)
)
{
syslog(LOG_WARNING, "Adafruit_BBIO: gpio_export: %u not applicable to built-in LEDs", gpio);
return BBIO_OK; // export is not applicable to the USR LED pins
}
// already exported by someone else?
char gpio_path[64];
snprintf(gpio_path, sizeof(gpio_path), "/sys/class/gpio/gpio%d", gpio);
if (access(gpio_path, R_OK|W_OK|X_OK) != -1) {
exported_gpios[gpio] = GPIO_ALREADY_EXPORTED;
syslog(LOG_DEBUG, "Adafruit_BBIO: gpio_export: %u already exported", gpio);
syslog(LOG_DEBUG, "Adafruit_BBIO: gpio_export(): %u already exported externally", gpio);
ret = BBIO_OK;
goto exit;
}
@ -99,7 +120,7 @@ BBIO_err gpio_export(unsigned int gpio)
const char gpio_export[] = "/sys/class/gpio/export";
if ((fd = open(gpio_export, O_WRONLY)) < 0) {
syslog(LOG_ERR, "Adafruit_BBIO: gpio_export: %u couldn't open \"%s\": %i-%s",
syslog(LOG_ERR, "Adafruit_BBIO: gpio_export(): %u couldn't open \"%s\": %i-%s",
gpio, gpio_export, errno, strerror(errno));
ret = BBIO_SYSFS;
goto exit;
@ -116,19 +137,19 @@ BBIO_err gpio_export(unsigned int gpio)
// add to list
exported_gpios[gpio] = GPIO_EXPORTED;
syslog(LOG_DEBUG, "Adafruit_BBIO: gpio_export: %u OK", gpio);
syslog(LOG_DEBUG, "Adafruit_BBIO: gpio_export(): %u OK", gpio);
ret = BBIO_OK;
exit:
if(fd && (ret = close(fd))) {
syslog(LOG_ERR, "Adafruit_BBIO: gpio_export: %u couldn't close \"%s\": %i-%s",
syslog(LOG_ERR, "Adafruit_BBIO: gpio_export(): %u couldn't close \"%s\": %i-%s",
gpio, gpio_export, errno, strerror(errno));
ret = BBIO_SYSFS;
}
usleep(200000); // Hack to wait for newly exported pins to get correct ownership
return ret;
}
// Closes fd corresponding to specified GPIO pin and removes it from fdx list
void close_value_fd(unsigned int gpio)
{
struct fdx *f = fd_list;
@ -140,10 +161,12 @@ void close_value_fd(unsigned int gpio)
if (f->gpio == gpio)
{
close(f->fd);
syslog(LOG_DEBUG, "Adafruit_BBIO: close_value_fd(): closed file descriptor %d", f->fd);
if (prev == NULL)
fd_list = f->next;
else
prev->next = f->next;
syslog(LOG_DEBUG, "Adafruit_BBIO: close_value_fd(): removing file descriptor %d for pin %u from opened descriptors list",f->fd, f->gpio);
temp = f;
f = f->next;
free(temp);
@ -153,7 +176,7 @@ void close_value_fd(unsigned int gpio)
}
}
}
// Returns file descriptor corresponding to specified GPIO pin
int fd_lookup(unsigned int gpio)
{
struct fdx *f = fd_list;
@ -165,7 +188,7 @@ int fd_lookup(unsigned int gpio)
}
return 0;
}
// Adds GPIO file descriptor to fdx list
int add_fd_list(unsigned int gpio, int fd)
{
struct fdx *new_fd;
@ -184,6 +207,7 @@ int add_fd_list(unsigned int gpio, int fd)
new_fd->next = fd_list;
}
fd_list = new_fd;
syslog(LOG_DEBUG, "Adafruit_BBIO: add_fd_list(): registered file descriptor %d for pin %u.",fd, gpio);
return 0;
}
@ -242,6 +266,7 @@ int open_value_file(unsigned int gpio)
gpio, filename, errno, strerror(errno));
return -1;
}
syslog(LOG_DEBUG, "Adafruit_BBIO: open_value_file(): opened file descriptor %d for pin %u.",fd, gpio);
add_fd_list(gpio, fd);
return fd;
}
@ -251,15 +276,16 @@ BBIO_err gpio_unexport(unsigned int gpio)
int fd, len;
char str_gpio[10];
//If gpio is not exported by us - no need to do anything
if (exported_gpios[gpio] != GPIO_EXPORTED)
return 0;
//close gpio pin file descriptor
close_value_fd(gpio);
#define GPIO_UNEXPORT "/sys/class/gpio/unexport"
if ((fd = open(GPIO_UNEXPORT, O_WRONLY)) < 0) {
syslog(LOG_ERR, "Adafruit_BBIO: gpio_unexport: %u couldn't open '"GPIO_UNEXPORT"': %i-%s",
syslog(LOG_ERR, "Adafruit_BBIO: gpio_unexport(): %u couldn't open '"GPIO_UNEXPORT"': %i-%s",
gpio, errno, strerror(errno));
return BBIO_SYSFS;
}
@ -268,7 +294,7 @@ BBIO_err gpio_unexport(unsigned int gpio)
int ret = write(fd, str_gpio, len);
close(fd);
if (ret < 0) {
syslog(LOG_ERR, "Adafruit_BBIO: gpio_unexport: %u couldn't write '"GPIO_UNEXPORT"': %i-%s",
syslog(LOG_ERR, "Adafruit_BBIO: gpio_unexport(): %u couldn't write '"GPIO_UNEXPORT"': %i-%s",
gpio, errno, strerror(errno));
return BBIO_SYSFS;
}
@ -276,7 +302,7 @@ BBIO_err gpio_unexport(unsigned int gpio)
// remove from list
exported_gpios[gpio] = GPIO_NOT_EXPORTED;
syslog(LOG_DEBUG, "Adafruit_BBIO: gpio_unexport: %u OK", gpio);
syslog(LOG_DEBUG, "Adafruit_BBIO: gpio_unexport(): %u OK", gpio);
return BBIO_OK;
}
@ -308,7 +334,7 @@ BBIO_err gpio_set_direction(unsigned int gpio, unsigned int in_flag)
snprintf(filename, sizeof(filename), "/sys/class/gpio/gpio%d/direction", gpio);
if ((fd = open(filename, O_WRONLY)) < 0) {
syslog(LOG_ERR, "Adafruit_BBIO: gpio_set_direction: %u couldn't open '%s': %i-%s",
syslog(LOG_ERR, "Adafruit_BBIO: gpio_set_direction(): %u couldn't open '%s': %i-%s",
gpio, filename, errno, strerror(errno));
return BBIO_SYSFS;
}
@ -322,7 +348,7 @@ BBIO_err gpio_set_direction(unsigned int gpio, unsigned int in_flag)
int ret = write(fd, direction, strlen(direction));
close(fd);
if (ret < 0) {
syslog(LOG_ERR, "Adafruit_BBIO: gpio_set_direction: %u couldn't write '%s': %i-%s",
syslog(LOG_ERR, "Adafruit_BBIO: gpio_set_direction(): %u couldn't write '%s': %i-%s",
gpio, filename, errno, strerror(errno));
return BBIO_SYSFS;
}
@ -339,7 +365,7 @@ BBIO_err gpio_get_direction(unsigned int gpio, unsigned int *value)
snprintf(filename, sizeof(filename), "/sys/class/gpio/gpio%d/direction", gpio);
if ((fd = open(filename, O_RDONLY | O_NONBLOCK)) < 0) {
syslog(LOG_ERR, "Adafruit_BBIO: gpio_get_direction: %u couldn't open '%s': %i-%s",
syslog(LOG_ERR, "Adafruit_BBIO: gpio_get_direction(): %u couldn't open '%s': %i-%s",
gpio, filename, errno, strerror(errno));
return BBIO_SYSFS;
}
@ -348,7 +374,7 @@ BBIO_err gpio_get_direction(unsigned int gpio, unsigned int *value)
int ret = read(fd, &direction, sizeof(direction) - 1);
close(fd);
if (ret < 0) {
syslog(LOG_ERR, "Adafruit_BBIO: gpio_get_direction: %u couldn't read '%s': %i-%s",
syslog(LOG_ERR, "Adafruit_BBIO: gpio_get_direction(): %u couldn't read '%s': %i-%s",
gpio, filename, errno, strerror(errno));
return BBIO_SYSFS;
}
@ -438,7 +464,7 @@ BBIO_err gpio_set_value(unsigned int gpio, unsigned int value)
fd = open(filename, O_WRONLY);
if (fd < 0) {
syslog(LOG_ERR, "Adafruit_BBIO: gpio_set_value: %u couldn't open '%s': %i-%s",
syslog(LOG_ERR, "Adafruit_BBIO: gpio_set_value(): %u couldn't open '%s': %i-%s",
gpio, filename, errno, strerror(errno));
return BBIO_SYSFS;
}
@ -452,7 +478,7 @@ BBIO_err gpio_set_value(unsigned int gpio, unsigned int value)
int ret = write(fd, vstr, strlen(vstr));
close(fd);
if (ret < 0) {
syslog(LOG_ERR, "Adafruit_BBIO: gpio_set_value: %u couldn't write '%s': %i-%s",
syslog(LOG_ERR, "Adafruit_BBIO: gpio_set_value(): %u couldn't write '%s': %i-%s",
gpio, filename, errno, strerror(errno));
return BBIO_SYSFS;
}
@ -469,7 +495,7 @@ BBIO_err gpio_get_value(unsigned int gpio, unsigned int *value)
if (!fd)
{
if ((fd = open_value_file(gpio)) == -1) {
syslog(LOG_ERR, "Adafruit_BBIO: gpio_set_value: %u couldn't open value file: %i-%s",
syslog(LOG_ERR, "Adafruit_BBIO: gpio_set_value(): %u couldn't open value file: %i-%s",
gpio, errno, strerror(errno));
return BBIO_SYSFS;
}
@ -478,7 +504,7 @@ BBIO_err gpio_get_value(unsigned int gpio, unsigned int *value)
lseek(fd, 0, SEEK_SET);
int ret = read(fd, &ch, sizeof(ch));
if (ret < 0) {
syslog(LOG_ERR, "Adafruit_BBIO: gpio_set_value: %u couldn't read value file: %i-%s",
syslog(LOG_ERR, "Adafruit_BBIO: gpio_set_value(): %u couldn't read value file: %i-%s",
gpio, errno, strerror(errno));
return BBIO_SYSFS;
}
@ -511,7 +537,7 @@ int gpio_set_edge(unsigned int gpio, unsigned int edge)
return 0;
}
//Returns gpio number corresponding to fd file descriptor
unsigned int gpio_lookup(int fd)
{
struct fdx *f = fd_list;
@ -554,17 +580,30 @@ int add_edge_callback(unsigned int gpio, void (*func)(unsigned int gpio))
cb = cb->next;
cb->next = new_cb;
}
syslog(LOG_DEBUG, "Adafruit_BBIO: add_edge_callback(): added callback to %p for pin %u", new_cb->func, gpio);
return 0;
}
void run_callbacks(unsigned int gpio)
{
struct callback *cb = callbacks;
//Memory cookie
unsigned char cookie[2] = {0};
while (cb != NULL)
{
//Store memory contents of the first byte of current callback structure as a "magic cookie"
memcpy(&cookie[0], cb, 1);
syslog(LOG_DEBUG, "Adafruit_BBIO: run_callbacks(): running callback %p for pin %u", cb->func, gpio);
if (cb->gpio == gpio)
cb->func(cb->gpio);
//Check the first byte of callback structure after executing callback function body
memcpy(&cookie[1], cb, 1);
// Current callback pointer might have changed _only_ if linked list structure has been altered from within the callback function, which should happen _only_ in remove_event_detect() call
// If that happened, cb* pointer will be now addressing different memory location with different data.
if (cookie[0] != cookie[1]) break;
if (cb != NULL)
cb = cb->next;
}
@ -580,6 +619,7 @@ void remove_callbacks(unsigned int gpio)
{
if (cb->gpio == gpio)
{
syslog(LOG_DEBUG, "Adafruit_BBIO: remove_callbacks(): removing callback to %p for pin %u", cb->func, cb->gpio);
if (prev == NULL)
callbacks = cb->next;
else
@ -593,7 +633,7 @@ void remove_callbacks(unsigned int gpio)
}
}
}
// Resets <initial> flag for the corresponding gpio
void set_initial_false(unsigned int gpio)
{
struct fdx *f = fd_list;
@ -605,7 +645,7 @@ void set_initial_false(unsigned int gpio)
f = f->next;
}
}
// Checks if <initial> flag is set for the corresponding gpio
int gpio_initial(unsigned int gpio)
{
struct fdx *f = fd_list;
@ -629,28 +669,38 @@ void *poll_thread(__attribute__ ((unused)) void *threadarg)
thread_running = 1;
while (thread_running)
{
// epoll_wait() returns -1 on error/timeout
if ((n = epoll_wait(epfd, &events, 1, -1)) == -1)
{
thread_running = 0;
syslog(LOG_ERR, "Adafruit_BBIO: poll_thread(): exiting due to error/timeout returned by epoll_wait()");
pthread_exit(NULL);
}
// otherwise it returns number of file descriptors ready
if (n > 0) {
// Set read/write offset to the beginning of the file
lseek(events.data.fd, 0, SEEK_SET);
// Try to check if there's new data available on fd by reading from it, i.e. no error ocurred
if (read(events.data.fd, &buf, 1) != 1)
{
thread_running = 0;
syslog(LOG_ERR, "Adafruit_BBIO: poll_thread(): exiting due to no data available to read");
pthread_exit(NULL);
}
// Find out gpio number corresponding to fd on which event has happened
gpio = gpio_lookup(events.data.fd);
if (gpio_initial(gpio)) { // ignore first epoll trigger
syslog(LOG_DEBUG, "Adafruit_BBIO: poll_thread(): discarding first epoll() event for pin %u",gpio);
set_initial_false(gpio);
} else {
event_occurred[gpio] = 1;
syslog(LOG_DEBUG, "Adafruit_BBIO: poll_thread(): running callbacks for pin %u",gpio);
run_callbacks(gpio);
}
}
}
thread_running = 0;
syslog(LOG_DEBUG, "Adafruit_BBIO: poll_thread(): normal exit");
pthread_exit(NULL);
}
@ -692,6 +742,7 @@ int gpio_event_remove(unsigned int gpio)
if (f->gpio == gpio)
{
f->is_evented = 0;
f->initial = 1;
return 0;
}
f = f->next;
@ -702,17 +753,17 @@ int gpio_event_remove(unsigned int gpio)
int add_edge_detect(unsigned int gpio, unsigned int edge)
// return values:
// 0 - Success
// 1 - Edge detection already added
// 2 - Other error
// -1 - Even detection already enabled for that GPIO
// Other error codes are system-wide
{
int fd = fd_lookup(gpio);
pthread_t threads;
struct epoll_event ev;
long t = 0;
// check to see if this gpio has been added already
// check to see if this gpio has been added already to the list of gpios with event detection enabled
if (gpio_event_add(gpio) != 0)
return 1;
return -1;
// export /sys/class/gpio interface
gpio_export(gpio);
@ -722,24 +773,37 @@ int add_edge_detect(unsigned int gpio, unsigned int edge)
if (!fd)
{
if ((fd = open_value_file(gpio)) == -1)
return 2;
{
syslog(LOG_ERR, "Adafruit_BBIO: add_edge_detect(): open_value_file() error %i-%s", errno, strerror(errno));
return errno;
}
}
// create epfd if not already open
if ((epfd == -1) && ((epfd = epoll_create(1)) == -1))
return 2;
{
syslog(LOG_ERR, "Adafruit_BBIO: add_edge_detect(): epoll_create() error %i-%s", errno, strerror(errno));
return errno;
}
// add to epoll fd
ev.events = EPOLLIN | EPOLLET | EPOLLPRI;
ev.data.fd = fd;
if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) == -1)
return 2;
{
syslog(LOG_ERR, "Adafruit_BBIO: add_edge_detect(): epoll_ctl() error %i-%s", errno, strerror(errno));
return errno;
}
// start poll thread if it is not already running
if (!thread_running)
{
if (pthread_create(&threads, NULL, poll_thread, (void *)t) != 0)
return 2;
{
syslog(LOG_ERR, "Adafruit_BBIO: add_edge_detect(): pthread_create() error %i-%s", errno, strerror(errno));
return errno;
}
}
return 0;
@ -753,17 +817,21 @@ void remove_edge_detect(unsigned int gpio)
// delete callbacks for gpio
remove_callbacks(gpio);
// delete epoll of fd
// delete fd from epoll
epoll_ctl(epfd, EPOLL_CTL_DEL, fd, &ev);
// set edge to none
gpio_set_edge(gpio, NO_EDGE);
// unexport gpio
//clear event
gpio_event_remove(gpio);
// clear detected flag
event_occurred[gpio] = 0;
syslog(LOG_DEBUG, "Adafruit_BBIO: remove_edge_detect(): event detection disabled for pin %u",gpio);
}
int event_detected(unsigned int gpio)

View file

@ -72,6 +72,7 @@ int add_edge_detect(unsigned int gpio, unsigned int edge);
void remove_edge_detect(unsigned int gpio);
int add_edge_callback(unsigned int gpio, void (*func)(unsigned int gpio));
int event_detected(unsigned int gpio);
int gpio_initial(unsigned int gpio);
int gpio_event_add(unsigned int gpio);
int gpio_event_remove(unsigned int gpio);
int gpio_is_evented(unsigned int gpio);

View file

@ -8,5 +8,5 @@ address = 0x49
while True:
temp = bus.read_byte_data(address, 0)
print (temp, end="\r")
print(temp, end="\r")
time.sleep(0.25)

View file

@ -377,12 +377,12 @@ static PyObject *py_add_event_detect(__attribute__ ((unused)) PyObject *self, Py
if ((result = add_edge_detect(gpio, edge)) != 0) // starts a thread
{
if (result == 1)
if (result == -1)
{
PyErr_SetString(PyExc_RuntimeError, "Edge detection already enabled for this GPIO channel");
PyErr_SetString(PyExc_KeyError, "Edge detection already enabled for this GPIO channel");
return NULL;
} else {
PyErr_SetString(PyExc_RuntimeError, "Failed to add edge detection");
PyErr_SetFromErrno(PyExc_RuntimeError);
return NULL;
}
}
@ -555,14 +555,14 @@ static PyObject *py_setwarnings(__attribute__ ((unused)) PyObject *self, __attri
static const char moduledocstring[] = "GPIO functionality of a BeagleBone using Python";
PyMethodDef gpio_methods[] = {
{"setup", (PyCFunction)py_setup_channel, METH_VARARGS | METH_KEYWORDS, "Set up the GPIO channel, direction and (optional) pull/up down control\nchannel - Either: RPi board pin number (not BCM GPIO 00..nn number). Pins start from 1\n or : BCM GPIO number\ndirection - INPUT or OUTPUT\n[pull_up_down] - PUD_OFF (default), PUD_UP or PUD_DOWN\n[initial] - Initial value for an output channel\n[delay] - Time in milliseconds to wait after exporting gpio pin"},
{"setup", (PyCFunction)(void *)py_setup_channel, METH_VARARGS | METH_KEYWORDS, "Set up the GPIO channel, direction and (optional) pull/up down control\nchannel - Either: RPi board pin number (not BCM GPIO 00..nn number). Pins start from 1\n or : BCM GPIO number\ndirection - INPUT or OUTPUT\n[pull_up_down] - PUD_OFF (default), PUD_UP or PUD_DOWN\n[initial] - Initial value for an output channel\n[delay] - Time in milliseconds to wait after exporting gpio pin"},
{"cleanup", py_cleanup, METH_VARARGS, "Clean up by resetting all GPIO channels that have been used by this program to INPUT with no pullup/pulldown and no event detection"},
{"output", py_output_gpio, METH_VARARGS, "Output to a GPIO channel\ngpio - gpio channel\nvalue - 0/1 or False/True or LOW/HIGH"},
{"input", py_input_gpio, METH_VARARGS, "Input from a GPIO channel. Returns HIGH=1=True or LOW=0=False\ngpio - gpio channel"},
{"add_event_detect", (PyCFunction)py_add_event_detect, METH_VARARGS | METH_KEYWORDS, "Enable edge detection events for a particular GPIO channel.\nchannel - either board pin number or BCM number depending on which mode is set.\nedge - RISING, FALLING or BOTH\n[callback] - A callback function for the event (optional)\n[bouncetime] - Switch bounce timeout in ms for callback"},
{"add_event_detect", (PyCFunction)(void *)py_add_event_detect, METH_VARARGS | METH_KEYWORDS, "Enable edge detection events for a particular GPIO channel.\nchannel - either board pin number or BCM number depending on which mode is set.\nedge - RISING, FALLING or BOTH\n[callback] - A callback function for the event (optional)\n[bouncetime] - Switch bounce timeout in ms for callback"},
{"remove_event_detect", py_remove_event_detect, METH_VARARGS, "Remove edge detection for a particular GPIO channel\ngpio - gpio channel"},
{"event_detected", py_event_detected, METH_VARARGS, "Returns True if an edge has occured on a given GPIO. You need to enable edge detection using add_event_detect() first.\ngpio - gpio channel"},
{"add_event_callback", (PyCFunction)py_add_event_callback, METH_VARARGS | METH_KEYWORDS, "Add a callback for an event already defined using add_event_detect()\ngpio - gpio channel\ncallback - a callback function\n[bouncetime] - Switch bounce timeout in ms"},
{"add_event_callback", (PyCFunction)(void *)py_add_event_callback, METH_VARARGS | METH_KEYWORDS, "Add a callback for an event already defined using add_event_detect()\ngpio - gpio channel\ncallback - a callback function\n[bouncetime] - Switch bounce timeout in ms"},
{"wait_for_edge", py_wait_for_edge, METH_VARARGS, "Wait for an edge.\ngpio - gpio channel\nedge - RISING, FALLING or BOTH\ntimeout (optional) - time to wait in miliseconds. -1 will wait forever (default)"},
{"gpio_function", py_gpio_function, METH_VARARGS, "Return the current GPIO function (IN, OUT, ALT0)\ngpio - gpio channel"},
{"setwarnings", py_setwarnings, METH_VARARGS, "Enable or disable warning messages"},
@ -599,8 +599,10 @@ PyMODINIT_FUNC initGPIO(void)
initlog(LOG_INFO, NULL, BBIO_LOG_OPTION);
#if PY_VERSION_HEX < 0x03090000
if (!PyEval_ThreadsInitialized())
PyEval_InitThreads();
#endif
if (Py_AtExit(event_cleanup) != 0)
{

View file

@ -215,10 +215,10 @@ static PyObject *py_set_frequency(__attribute__ ((unused)) PyObject *self, PyObj
static const char moduledocstring[] = "PWM functionality of a BeagleBone using Python";
PyMethodDef pwm_methods[] = {
{"start", (PyCFunction)py_start_channel, METH_VARARGS | METH_KEYWORDS, "Set up and start the PWM channel. channel can be in the form of 'P8_10', or 'EHRPWM2A'"},
{"stop", (PyCFunction)py_stop_channel, METH_VARARGS | METH_KEYWORDS, "Stop the PWM channel. channel can be in the form of 'P8_10', or 'EHRPWM2A'"},
{ "set_duty_cycle", (PyCFunction)py_set_duty_cycle, METH_VARARGS | METH_KEYWORDS, "Change the duty cycle\ndutycycle - between 0.0 and 100.0" },
{ "set_frequency", (PyCFunction)py_set_frequency, METH_VARARGS | METH_KEYWORDS, "Change the frequency\nfrequency - frequency in Hz (freq > 0.0)" },
{"start", (PyCFunction)(void *)py_start_channel, METH_VARARGS | METH_KEYWORDS, "Set up and start the PWM channel. channel can be in the form of 'P8_10', or 'EHRPWM2A'"},
{"stop", (PyCFunction)(void *)py_stop_channel, METH_VARARGS | METH_KEYWORDS, "Stop the PWM channel. channel can be in the form of 'P8_10', or 'EHRPWM2A'"},
{ "set_duty_cycle", (PyCFunction)(void *)py_set_duty_cycle, METH_VARARGS | METH_KEYWORDS, "Change the duty cycle\ndutycycle - between 0.0 and 100.0" },
{ "set_frequency", (PyCFunction)(void *)py_set_frequency, METH_VARARGS | METH_KEYWORDS, "Change the frequency\nfrequency - frequency in Hz (freq > 0.0)" },
{"cleanup", py_cleanup, METH_VARARGS, "Clean up by resetting all GPIO channels that have been used by this program to INPUT with no pullup/pulldown and no event detection"},
//{"setwarnings", py_setwarnings, METH_VARARGS, "Enable or disable warning messages"},
{NULL, NULL, 0, NULL}

View file

@ -777,17 +777,17 @@ PyDoc_STRVAR(SPI_type_doc,
"specified SPI device interface.\n");
static PyMethodDef SPI_methods[] = {
{"open", (PyCFunction)SPI_open, METH_VARARGS | METH_KEYWORDS,
{"open", (PyCFunction)(void *)SPI_open, METH_VARARGS | METH_KEYWORDS,
SPI_open_doc},
{"close", (PyCFunction)SPI_close, METH_NOARGS,
{"close", (PyCFunction)(void *)SPI_close, METH_NOARGS,
SPI_close_doc},
{"readbytes", (PyCFunction)SPI_readbytes, METH_VARARGS,
{"readbytes", (PyCFunction)(void *)SPI_readbytes, METH_VARARGS,
SPI_read_doc},
{"writebytes", (PyCFunction)SPI_writebytes, METH_VARARGS,
{"writebytes", (PyCFunction)(void *)SPI_writebytes, METH_VARARGS,
SPI_write_doc},
{"xfer", (PyCFunction)SPI_xfer, METH_VARARGS,
{"xfer", (PyCFunction)(void *)SPI_xfer, METH_VARARGS,
SPI_xfer_doc},
{"xfer2", (PyCFunction)SPI_xfer2, METH_VARARGS,
{"xfer2", (PyCFunction)(void *)SPI_xfer2, METH_VARARGS,
SPI_xfer2_doc},
{NULL},
};

View file

@ -46,7 +46,7 @@ from Adafruit_BBIO.SPI import SPI
#spi = SPI(1,1) #/dev/spidev2.1
spi = SPI(0,0)
print spi.xfer2([32, 11, 110, 22, 220])
print(spi.xfer2([32, 11, 110, 22, 220]))
spi.close()
```

View file

@ -20,7 +20,7 @@ pins = [
# /sys/devices/platform/ocp/48304000.epwmss/48304100.ecap/pwm/pwmchip5/pwm-5:0/duty_cycle
for pin in pins:
print pin
print(pin)
PWM.start(pin, 50, 2000, 1)
PWM.stop(pin)
PWM.cleanup()

View file

@ -1,4 +1,5 @@
import pytest
import serial
import platform
import Adafruit_BBIO.UART as UART
@ -11,7 +12,7 @@ def teardown_module(module):
# ADC.cleanup()
class TestAdc:
class TestUart:
def test_setup_uart_wrong_name(self):
if kernel >= '4.1.0':
pass
@ -25,9 +26,39 @@ class TestAdc:
else:
UART.setup("UART1")
def test_setup_adc_multiple(self):
def test_setup_uart_multiple(self):
if kernel >= '4.1.0':
pass
else:
UART.setup("UART1")
UART.setup("UART1")
# test UART entries for the PocketBeagle (issue #243)
def test_pocketbeagle(self):
if kernel < '4.1.0':
pass
value = open('/proc/device-tree/model').read()
if(value.startswith("TI AM335x PocketBeagle")):
uarts = {
'PB-UART0': '/dev/ttyO0',
'PB-UART1': '/dev/ttyO1',
'PB-UART2': '/dev/ttyO2',
}
else:
uarts = {
'UART1': '/dev/ttyO1',
'UART2': '/dev/ttyO2',
'UART4': '/dev/ttyO4'
# note: UART5 requires
# "disable_uboot_overlay_video=1" in /boot/uEnv.txt
#'UART5': '/dev/ttyO5'
}
for name, device in sorted(uarts.items()):
UART.setup(name)
uart = serial.Serial(port = device, baudrate=9600)
uart.close()
uart.open()
if uart.isOpen():
uart.write("hello world".encode("utf-8"))
uart.close()

View file

@ -4,7 +4,7 @@
# and then run "tox" from this directory.
[tox]
envlist = py27, py34
envlist = py27, py36
[testenv]
commands = echo "run pytest on beaglebone"