diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml new file mode 100644 index 0000000..ff38214 --- /dev/null +++ b/.github/workflows/CI.yml @@ -0,0 +1,73 @@ +name: CI +on: + - push + - pull_request +jobs: + test: + name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + version: + - 'lts' + - '1' + os: + - ubuntu-latest + arch: + - x64 + steps: + - uses: actions/checkout@v4 + - uses: julia-actions/setup-julia@v2 + with: + version: ${{ matrix.version }} + arch: ${{ matrix.arch }} + - uses: actions/cache@v4 + env: + cache-name: cache-artifacts + with: + path: ~/.julia/artifacts + key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }} + restore-keys: | + ${{ runner.os }}-test-${{ env.cache-name }}- + ${{ runner.os }}-test- + ${{ runner.os }}- + - uses: julia-actions/julia-buildpkg@latest + - run: | + git config --global user.name Tester + git config --global user.email te@st.er + - uses: julia-actions/julia-runtest@latest + continue-on-error: ${{ matrix.version == 'nightly' }} + # - uses: julia-actions/julia-processcoverage@v1 + # - uses: codecov/codecov-action@v4 + # with: + # file: lcov.info + # token: ${{ secrets.CODECOV_TOKEN }} + + docs: + name: Documentation + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: julia-actions/setup-julia@v2 + with: + version: '1' + - run: | + git config --global user.name name + git config --global user.email email + git config --global github.user username + - run: | + julia --project=docs -e ' + using Pkg + Pkg.develop(PackageSpec(path=pwd())) + Pkg.instantiate() + Pkg.build()' + - run: | + julia --project=docs -e ' + using Documenter: doctest + using PiGPIO + doctest(PiGPIO)' + - run: julia --project=docs docs/make.jl + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} diff --git a/.github/workflows/TagBot.yml b/.github/workflows/TagBot.yml index 0bc129d..4bad0ec 100644 --- a/.github/workflows/TagBot.yml +++ b/.github/workflows/TagBot.yml @@ -1,11 +1,33 @@ name: TagBot on: - schedule: - - cron: 10 20 * * * + issue_comment: + types: + - created + workflow_dispatch: + inputs: + lookback: + default: "3" +permissions: + actions: read + checks: read + contents: write + deployments: read + issues: read + discussions: read + packages: read + pages: read + pull-requests: read + repository-projects: read + security-events: read + statuses: read jobs: TagBot: + if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot' runs-on: ubuntu-latest steps: - uses: JuliaRegistries/TagBot@v1 with: token: ${{ secrets.GITHUB_TOKEN }} + # Edit the following line to reflect the actual name of the GitHub Secret containing your private key + ssh: ${{ secrets.DOCUMENTER_KEY }} + # ssh: ${{ secrets.NAME_OF_MY_SSH_PRIVATE_KEY_SECRET }} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 9622a2d..0000000 --- a/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -# Documentation: http://docs.travis-ci.com/user/languages/julia/ -language: julia -os: - - linux - - osx -julia: - - release - - nightly -notifications: - email: false -# uncomment the following lines to override the default test script -#script: -# - if [[ -a .git/shallow ]]; then git fetch --unshallow; fi -# - julia -e 'Pkg.clone(pwd()); Pkg.build("PiGPIO"); Pkg.test("PiGPIO"; coverage=true)' diff --git a/Manifest.toml b/Manifest.toml deleted file mode 100644 index de3b2cb..0000000 --- a/Manifest.toml +++ /dev/null @@ -1,2 +0,0 @@ -[[Sockets]] -uuid = "6462fe0b-24de-5631-8697-dd941f90decc" diff --git a/Project.toml b/Project.toml index 2ea1255..140882a 100644 --- a/Project.toml +++ b/Project.toml @@ -1,9 +1,19 @@ -name = "PiGPIO" -uuid = "bb151fc1-c6dc-5496-8ed6-07f94907e623" -version = "0.2.0" - -[compat] -julia = "1" - -[deps] -Sockets = "6462fe0b-24de-5631-8697-dd941f90decc" +name = "PiGPIO" +uuid = "bb151fc1-c6dc-5496-8ed6-07f94907e623" +version = "0.2.1" + +[compat] +Aqua = "0.8" +Sockets = "1" +Test = "1" +julia = "1" + +[deps] +Sockets = "6462fe0b-24de-5631-8697-dd941f90decc" + +[extras] +Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[targets] +test = ["Aqua", "Test"] diff --git a/README.md b/README.md index 3a8bd0c..97f393e 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ #### Control GPIO pins on the Raspberry Pi from Julia [![][docs-stable-img]][docs-stable-url] +[![documentation dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://juliaberry.github.io/PiGPIO.jl/dev/) [docs-stable-img]: https://img.shields.io/badge/docs-stable-blue.svg [docs-stable-url]: https://juliahub.com/docs/PiGPIO/ @@ -18,6 +19,9 @@ Which can be found [here](http://abyz.me.uk/rpi/pigpio/python.html) Click [here](https://medium.com/@imkimfung/using-julia-to-control-leds-on-a-raspberry-pi-b320be83e503) for an **in-depth tutorial** on how you can control GPIO pins such as LEDs from Julia on the Raspberry Pi. +> [!IMPORTANT] +> This package relies on the [pigpio daemon which does not support Raspberry Pi 5](https://github.com/JuliaBerry/PiGPIO.jl/issues/24). If you have a Raspberry Pi 5, consider to use +[WiringPi.jl](https://github.com/stensmo/WiringPi.jl/) ### Features * OS independent. Only Julia 1.0+ required. @@ -35,10 +39,20 @@ work is done by the daemon. One benefit of working this way is that you can remotely access the pi over a network and multiple instances can be connected to the daemon simultaneously. -## Launching the Daemon +## The daemon process `pigpiod` -Launching the daemon requires sudo privileges. Launch by typing `sudo pigpiod` -in the terminal. +On Raspberry Pi OS, the daemon `pigpiod` can be installed and launched by using the following shell commands: + +```bash +# install pigpiod +sudo apt-get install pigpiod +# enable pigpiod via system D +sudo systemctl enable pigpiod +# start pigpiod now +sudo systemctl start pigpiod +``` + +The daemon can also be launched manually with `sudo pigpiod` in the terminal. ## Installation and Usage @@ -48,20 +62,24 @@ Pkg.add("PiGPIO") using PiGPIO -pi=Pi() #connect to pigpiod daemon on localhost +pi=Pi() # connect to the pigpiod daemon on localhost ``` ## Example Usage +The `pin` number corresponds to the GPIO pins +(General Purpose Input/Output, aka "BCM" or "Broadcom") and not +to the physical pin numbers. + ```julia -set_mode(p::Pi, pin::Int, mode) -get_mode(p::Pi, pin::Int) -# mode can be INPUT or OUTPUT +set_mode(pi::Pi, pin::Int, mode) +get_mode(pi::Pi, pin::Int) +# mode can be PiGPIO.INPUT or PiGPIO.OUTPUT -PiGPIO.read(p, pin) -PiGPIO.write(p, pin, state) -#state can be HIGH, LOW, ON, OFF +PiGPIO.read(pi, pin) +PiGPIO.write(pi, pin, state) +# state can be PiGPIO.HIGH, PiGPIO.LOW, PiGPIO.ON, PiGPIO.OFF -PiGPIO.set_PWM_dutycycle(p, pin, dutycyle) -#dutycyle defaults to a range 0-255 +PiGPIO.set_PWM_dutycycle(pi, pin, dutycyle) +# dutycyle defaults to a range 0-255 ``` diff --git a/REQUIRE b/REQUIRE deleted file mode 100644 index 859ad46..0000000 --- a/REQUIRE +++ /dev/null @@ -1 +0,0 @@ -julia 0.7 diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index e1b4871..0000000 --- a/appveyor.yml +++ /dev/null @@ -1,34 +0,0 @@ -environment: - matrix: - - JULIAVERSION: "julialang/bin/winnt/x86/0.4/julia-0.4-latest-win32.exe" - - JULIAVERSION: "julialang/bin/winnt/x64/0.4/julia-0.4-latest-win64.exe" - - JULIAVERSION: "julianightlies/bin/winnt/x86/julia-latest-win32.exe" - - JULIAVERSION: "julianightlies/bin/winnt/x64/julia-latest-win64.exe" - -branches: - only: - - master - - /release-.*/ - -notifications: - - provider: Email - on_build_success: false - on_build_failure: false - on_build_status_changed: false - -install: -# Download most recent Julia Windows binary - - ps: (new-object net.webclient).DownloadFile( - $("http://s3.amazonaws.com/"+$env:JULIAVERSION), - "C:\projects\julia-binary.exe") -# Run installer silently, output to C:\projects\julia - - C:\projects\julia-binary.exe /S /D=C:\projects\julia - -build_script: -# Need to convert from shallow to complete for Pkg.clone to work - - IF EXIST .git\shallow (git fetch --unshallow) - - C:\projects\julia\bin\julia -e "versioninfo(); - Pkg.clone(pwd(), \"PiGPIO\"); Pkg.build(\"PiGPIO\")" - -test_script: - - C:\projects\julia\bin\julia --check-bounds=yes -e "Pkg.test(\"PiGPIO\")" diff --git a/docs/make.jl b/docs/make.jl index 6e8a85f..d71c57b 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -10,9 +10,12 @@ makedocs( sitename = "PiGPIO", format = Documenter.HTML(), modules = [PiGPIO], + # examples need to be run on a Raspberry Pi + doctest = false, + draft = true, pages = [ "index.md", - "Tutorial" => "tutorial.md" + "Tutorial" => "tutorial.md", "API Docs" => "api.md", "Examples" => [ "Blink Once" => "examples/01_blink.md", @@ -22,9 +25,6 @@ makedocs( ] ) -# Documenter can also automatically deploy documentation to gh-pages. -# See "Hosting Documentation" and deploydocs() in the Documenter manual -# for more information. -#=deploydocs( - repo = "" -)=# +deploydocs(; + repo="github.com/JuliaBerry/PiGPIO.jl", +) diff --git a/docs/tutorial.md b/docs/src/tutorial.md similarity index 100% rename from docs/tutorial.md rename to docs/src/tutorial.md diff --git a/src/PiGPIO.jl b/src/PiGPIO.jl index 15c1a8c..d63d6b9 100644 --- a/src/PiGPIO.jl +++ b/src/PiGPIO.jl @@ -3,6 +3,7 @@ module PiGPIO export Pi +import Base: run, write using Sockets include("constants.jl") diff --git a/src/constants.jl b/src/constants.jl index 6a51cd0..36bd581 100644 --- a/src/constants.jl +++ b/src/constants.jl @@ -57,6 +57,8 @@ WAVE_MODE_REPEAT_SYNC =3 WAVE_NOT_FOUND = 9998 # Transmitted wave not found. NO_TX_WAVE = 9999 # No wave being transmitted. +_SOCK_CMD_LEN = 16 + # pigpio command numbers _PI_CMD_MODES= 0 diff --git a/src/i2c.jl b/src/i2c.jl index 5af0bf7..a4ecc07 100644 --- a/src/i2c.jl +++ b/src/i2c.jl @@ -1,756 +1,765 @@ -""" -Returns a handle (>=0) for the device at the I2C bus address. - -i2c_bus:= >=0. -i2c_address:= 0-0x7F. -i2c_flags:= 0, no flags are currently defined. - -Normally you would only use the [*i2c_**] functions if -you are or will be connecting to the Pi over a network. If -you will always run on the local Pi use the standard SMBus -module instead. - -Physically buses 0 and 1 are available on the Pi. Higher -numbered buses will be available if a kernel supported bus -multiplexor is being used. - -For the SMBus commands the low level transactions are shown -at the end of the function description. The following -abbreviations are used. - -. . -S (1 bit) : Start bit -P (1 bit) : Stop bit -Rd/Wr (1 bit) : Read/Write bit. Rd equals 1, Wr equals 0. -A, NA (1 bit) : Accept and not accept bit. -Addr (7 bits): I2C 7 bit address. -reg (8 bits): Command byte, which often selects a register. -Data (8 bits): A data byte. -Count (8 bits): A byte defining the length of a block operation. - -[..]: Data sent by the device. -. . - -... -h = i2c_open(pi, 1, 0x53) # open device at address 0x53 on bus 1 -... -""" -function i2c_open(self::Pi, i2c_bus, i2c_address, i2c_flags=0) - # I p1 i2c_bus - # I p2 i2c_addr - # I p3 4 - ## extension ## - # I i2c_flags - extents = [pack("I", i2c_flags)] - return _u2i(_pigpio_command_ext( - self.sl, _PI_CMD_I2CO, i2c_bus, i2c_address, 4, extents)) -end - -""" -Closes the I2C device associated with handle. - -handle:= >=0 (as returned by a prior call to [*i2c_open*]). - -... -i2c_close(pi, h) -... -""" -function i2c_close(self::Pi, handle) - return _u2i(_pigpio_command(self.sl, _PI_CMD_I2CC, handle, 0)) -end - -""" -Sends a single bit to the device associated with handle. - -handle:= >=0 (as returned by a prior call to [*i2c_open*]). -bit:= 0 or 1, the value to write. - -SMBus 2.0 5.5.1 - Quick command. -. . -S Addr bit [A] P -. . - -... -i2c_write_quick(pi, 0, 1) # send 1 to device 0 -i2c_write_quick(pi, 3, 0) # send 0 to device 3 -... -""" -function i2c_write_quick(self::Pi, handle, bit) - return _u2i(_pigpio_command(self.sl, _PI_CMD_I2CWQ, handle, bit)) -end - -""" -Sends a single byte to the device associated with handle. - -handle:= >=0 (as returned by a prior call to [*i2c_open*]). -byte_val:= 0-255, the value to write. - -SMBus 2.0 5.5.2 - Send byte. -. . -S Addr Wr [A] byte_val [A] P -. . - -... -i2c_write_byte(pi, 1, 17) # send byte 17 to device 1 -i2c_write_byte(pi, 2, 0x23) # send byte 0x23 to device 2 -... -""" -function i2c_write_byte(self::Pi, handle, byte_val) - return _u2i( - _pigpio_command(self.sl, _PI_CMD_I2CWS, handle, byte_val)) -end - -""" -Reads a single byte from the device associated with handle. - -handle:= >=0 (as returned by a prior call to [*i2c_open*]). - -SMBus 2.0 5.5.3 - Receive byte. -. . -S Addr Rd [A] [Data] NA P -. . - -... -b = i2c_read_byte(pi, 2) # read a byte from device 2 -... -""" -function i2c_read_byte(self::Pi, handle) - return _u2i(_pigpio_command(self.sl, _PI_CMD_I2CRS, handle, 0)) -end - -""" -Writes a single byte to the specified register of the device -associated with handle. - -handle:= >=0 (as returned by a prior call to [*i2c_open*]). -reg:= >=0, the device register. -byte_val:= 0-255, the value to write. - -SMBus 2.0 5.5.4 - Write byte. -. . -S Addr Wr [A] reg [A] byte_val [A] P -. . - -... -# send byte 0xC5 to reg 2 of device 1 -i2c_write_byte_data(pi, 1, 2, 0xC5) - -# send byte 9 to reg 4 of device 2 -i2c_write_byte_data(pi, 2, 4, 9) -... -""" -function i2c_write_byte_data(self::Pi, handle, reg, byte_val) - # I p1 handle - # I p2 reg - # I p3 4 - ## extension ## - # I byte_val - extents = IOBuffer - write(extents, byte_val) - return _u2i(_pigpio_command_ext( - self.sl, _PI_CMD_I2CWB, handle, reg, 4, extents)) -end - -""" -Writes a single 16 bit word to the specified register of the -device associated with handle. - -handle:= >=0 (as returned by a prior call to [*i2c_open*]). -reg:= >=0, the device register. -word_val:= 0-65535, the value to write. - -SMBus 2.0 5.5.4 - Write word. -. . -S Addr Wr [A] reg [A] word_val_Low [A] word_val_High [A] P -. . - -... -# send word 0xA0C5 to reg 5 of device 4 -i2c_write_word_data(pi, 4, 5, 0xA0C5) - -# send word 2 to reg 2 of device 5 -i2c_write_word_data(pi, 5, 2, 23) -... -""" -function i2c_write_word_data(self::Pi, handle, reg, word_val) - # I p1 handle - # I p2 reg - # I p3 4 - ## extension ## - # I word_val - extents = IOBuffer - write(extents, word_val) - return _u2i(_pigpio_command_ext( - self.sl, _PI_CMD_I2CWW, handle, reg, 4, extents)) -end - -""" -Reads a single byte from the specified register of the device -associated with handle. - -handle:= >=0 (as returned by a prior call to [*i2c_open*]). -reg:= >=0, the device register. - -SMBus 2.0 5.5.5 - Read byte. -. . -S Addr Wr [A] reg [A] S Addr Rd [A] [Data] NA P -. . - -... -# read byte from reg 17 of device 2 -b = i2c_read_byte_data(pi, 2, 17) - -# read byte from reg 1 of device 0 -b = i2c_read_byte_data(pi, 0, 1) -... -""" -function i2c_read_byte_data(self, handle, reg) - return _u2i(_pigpio_command(self.sl, _PI_CMD_I2CRB, handle, reg)) -end - -""" -Reads a single 16 bit word from the specified register of the -device associated with handle. - -handle:= >=0 (as returned by a prior call to [*i2c_open*]). -reg:= >=0, the device register. - -SMBus 2.0 5.5.5 - Read word. -. . -S Addr Wr [A] reg [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P -. . - -... -# read word from reg 2 of device 3 -w = i2c_read_word_data(pi, 3, 2) - -# read word from reg 7 of device 2 -w = i2c_read_word_data(pi, 2, 7) -... -""" -function i2c_read_word_data(self, handle, reg) - return _u2i(_pigpio_command(self.sl, _PI_CMD_I2CRW, handle, reg)) -end - -""" -Writes 16 bits of data to the specified register of the device -associated with handle and reads 16 bits of data in return. - -handle:= >=0 (as returned by a prior call to [*i2c_open*]). -reg:= >=0, the device register. -word_val:= 0-65535, the value to write. - -SMBus 2.0 5.5.6 - Process call. -. . -S Addr Wr [A] reg [A] word_val_Low [A] word_val_High [A] -S Addr Rd [A] [DataLow] A [DataHigh] NA P -. . - -... -r = i2c_process_call(pi, h, 4, 0x1231) -r = i2c_process_call(pi, h, 6, 0) -... -""" -function i2c_process_call(self, handle, reg, word_val) - # I p1 handle - # I p2 reg - # I p3 4 - ## extension ## - # I word_val - extents = IOBuffer - write(extents, word_val) - return _u2i(_pigpio_command_ext( - self.sl, _PI_CMD_I2CPC, handle, reg, 4, extents)) -end - -""" -Writes up to 32 bytes to the specified register of the device -associated with handle. - -handle:= >=0 (as returned by a prior call to [*i2c_open*]). -reg:= >=0, the device register. -data:= the bytes to write. - -SMBus 2.0 5.5.7 - Block write. -. . -S Addr Wr [A] reg [A] length(data) [A] data0 [A] data1 [A] ... [A] -datan [A] P -. . - -... -i2c_write_block_data(pi, 4, 5, b'hello') - -i2c_write_block_data(pi, 4, 5, "data bytes") - -i2c_write_block_data(pi, 5, 0, b'\\x00\\x01\\x22') - -i2c_write_block_data(pi, 6, 2, [0, 1, 0x22]) -... -""" -function i2c_write_block_data(self, handle, reg, data) -# I p1 handle -# I p2 reg -# I p3 len -## extension ## -# s len data bytes - if length(data) - return _u2i(_pigpio_command_ext( - self.sl, _PI_CMD_I2CWK, handle, reg, length(data), data)) - else - return 0 - end -end - -""" -Reads a block of up to 32 bytes from the specified register of -the device associated with handle. - -handle:= >=0 (as returned by a prior call to [*i2c_open*]). -reg:= >=0, the device register. - -SMBus 2.0 5.5.7 - Block read. -. . -S Addr Wr [A] reg [A] -S Addr Rd [A] [Count] A [Data] A [Data] A ... A [Data] NA P -. . - -The amount of returned data is set by the device. - -The returned value is a tuple of the number of bytes read and a -bytearray containing the bytes. If there was an error the -number of bytes read will be less than zero (and will contain -the error code). - -... -(b, d) = i2c_read_block_data(pi, h, 10) -if b >= 0 -# process data -else -# process read failure -... -""" -function i2c_read_block_data(self::Pi, handle, reg) - # Don't raise exception. Must release lock. - bytes = u2i(_pigpio_command(self.sl, _PI_CMD_I2CRK, handle, reg, false)) - if bytes > 0 - data = rxbuf(bytes) - else - data = "" - end - - unlock(self.sl.l) - return bytes, data -end - -""" -Writes data bytes to the specified register of the device -associated with handle and reads a device specified number -of bytes of data in return. - -handle:= >=0 (as returned by a prior call to [*i2c_open*]). -reg:= >=0, the device register. -data:= the bytes to write. - -The SMBus 2.0 documentation states that a minimum of 1 byte may -be sent and a minimum of 1 byte may be received. The total -number of bytes sent/received must be 32 or less. - -SMBus 2.0 5.5.8 - Block write-block read. -. . -S Addr Wr [A] reg [A] length(data) [A] data0 [A] ... datan [A] -S Addr Rd [A] [Count] A [Data] ... A P -. . - -The returned value is a tuple of the number of bytes read and a -bytearray containing the bytes. If there was an error the -number of bytes read will be less than zero (and will contain -the error code). - -... -(b, d) = i2c_block_process_call(pi, h, 10, b'\\x02\\x05\\x00') - -(b, d) = i2c_block_process_call(pi, h, 10, b'abcdr') - -(b, d) = i2c_block_process_call(pi, h, 10, "abracad") - -(b, d) = i2c_block_process_call(pi, h, 10, [2, 5, 16]) -... -""" -function i2c_block_process_call(self::Pi, handle, reg, data) - # I p1 handle - # I p2 reg - # I p3 len - ## extension ## - # s len data bytes - - # Don't raise exception. Must release lock. - bytes = u2i(_pigpio_command_ext( - self.sl, _PI_CMD_I2CPK, handle, reg, length(data), data, false)) - if bytes > 0 - data = rxbuf(self, bytes) - else - data = "" - end - unlock(self.sl.l) - return bytes, data -end - -""" -Writes data bytes to the specified register of the device -associated with handle . 1-32 bytes may be written. - -handle:= >=0 (as returned by a prior call to [*i2c_open*]). -reg:= >=0, the device register. -data:= the bytes to write. - -. . -S Addr Wr [A] reg [A] data0 [A] data1 [A] ... [A] datan [NA] P -. . - -... -i2c_write_i2c_block_data(pi, 4, 5, 'hello') - -i2c_write_i2c_block_data(pi, 4, 5, b'hello') - -i2c_write_i2c_block_data(pi, 5, 0, b'\\x00\\x01\\x22') - -i2c_write_i2c_block_data(pi, 6, 2, [0, 1, 0x22]) -... -""" -function i2c_write_i2c_block_data(self::Pi, handle, reg, data) - # I p1 handle - # I p2 reg - # I p3 len - ## extension ## - # s len data bytes - if length(data) > 0 - return _u2i(_pigpio_command_ext( - self.sl, _PI_CMD_I2CWI, handle, reg, length(data), [data])) - else - return 0 - end -end - -""" -Reads count bytes from the specified register of the device -associated with handle . The count may be 1-32. - -handle:= >=0 (as returned by a prior call to [*i2c_open*]). -reg:= >=0, the device register. -count:= >0, the number of bytes to read. - -. . -S Addr Wr [A] reg [A] -S Addr Rd [A] [Data] A [Data] A ... A [Data] NA P -. . - -The returned value is a tuple of the number of bytes read and a -bytearray containing the bytes. If there was an error the -number of bytes read will be less than zero (and will contain -the error code). - -... -(b, d) = i2c_read_i2c_block_data(pi, h, 4, 32) -if b >= 0 -# process data -else -# process read failure -... -""" -function i2c_read_i2c_block_data(self::Pi, handle, reg, count) - # I p1 handle - # I p2 reg - # I p3 4 - ## extension ## - # I count - extents = IOBuffer() - write(extents, count) - # Don't raise exception. Must release lock. - bytes = u2i(_pigpio_command_ext( - self.sl, _PI_CMD_I2CRI, handle, reg, 4, extents, false)) - if bytes > 0 - data = rxbuf(self, bytes) - else - data = "" - end - - unlock(self.sl.l) - return bytes, data -end - -""" -Returns count bytes read from the raw device associated -with handle. - -handle:= >=0 (as returned by a prior call to [*i2c_open*]). -count:= >0, the number of bytes to read. - -. . -S Addr Rd [A] [Data] A [Data] A ... A [Data] NA P -. . - -The returned value is a tuple of the number of bytes read and a -bytearray containing the bytes. If there was an error the -number of bytes read will be less than zero (and will contain -the error code). - -... -(count, data) = i2c_read_device(pi, h, 12) -... -""" -function i2c_read_device(self::Pi, handle, count) - # Don't raise exception. Must release lock. - bytes = u2i( - _pigpio_command(self.sl, _PI_CMD_I2CRD, handle, count, false)) - if bytes > 0 - data = rxbuf(self, bytes) - else - data = "" - end - unlock(self.sl.l) - return bytes, data -end - -""" -Writes the data bytes to the raw device associated with handle. - -handle:= >=0 (as returned by a prior call to [*i2c_open*]). -data:= the bytes to write. - -. . -S Addr Wr [A] data0 [A] data1 [A] ... [A] datan [A] P -. . - -... -i2c_write_device(pi, h, b"\\x12\\x34\\xA8") - -i2c_write_device(pi, h, b"help") - -i2c_write_device(pi, h, 'help') - -i2c_write_device(pi, h, [23, 56, 231]) -... -""" -function i2c_write_device(self::Pi, handle, data) - # I p1 handle - # I p2 0 - # I p3 len - ## extension ## - # s len data bytes - if length(data) - return _u2i(_pigpio_command_ext( - self.sl, _PI_CMD_I2CWD, handle, 0, length(data), data)) - else - return 0 - end -end - -""" -This function executes a sequence of I2C operations. The -operations to be performed are specified by the contents of data -which contains the concatenated command codes and associated data. - -handle:= >=0 (as returned by a prior call to [*i2c_open*]). -data:= the concatenated I2C commands, see below - -The returned value is a tuple of the number of bytes read and a -bytearray containing the bytes. If there was an error the -number of bytes read will be less than zero (and will contain -the error code). - -... -(count, data) = i2c_zip(pi, h, [4, 0x53, 7, 1, 0x32, 6, 6, 0]) -... - -The following command codes are supported - -Name @ Cmd & Data @ Meaning -End @ 0 @ No more commands -Escape @ 1 @ Next P is two bytes -On @ 2 @ Switch combined flag on -Off @ 3 @ Switch combined flag off -Address @ 4 P @ Set I2C address to P -Flags @ 5 lsb msb @ Set I2C flags to lsb + (msb << 8) -Read @ 6 P @ Read P bytes of data -Write @ 7 P ... @ Write P bytes of data - -The address, read, and write commands take a parameter P. -Normally P is one byte (0-255). If the command is preceded by -the Escape command then P is two bytes (0-65535, least significant -byte first). - -The address defaults to that associated with the handle. -The flags default to 0. The address and flags maintain their -previous value until updated. - -Any read I2C data is concatenated in the returned bytearray. - -... -Set address 0x53, write 0x32, read 6 bytes -Set address 0x1E, write 0x03, read 6 bytes -Set address 0x68, write 0x1B, read 8 bytes -End - -0x04 0x53 0x07 0x01 0x32 0x06 0x06 -0x04 0x1E 0x07 0x01 0x03 0x06 0x06 -0x04 0x68 0x07 0x01 0x1B 0x06 0x08 -0x00 -... -""" -function i2c_zip(self::Pi, handle, data) - # I p1 handle - # I p2 0 - # I p3 len - ## extension ## - # s len data bytes - - # Don't raise exception. Must release lock. - bytes = u2i(_pigpio_command_ext( - self.sl, _PI_CMD_I2CZ, handle, 0, length(data), data, false)) - if bytes > 0 - data = self._rxbuf(bytes) - else - data = "" - end - unlock(self.sl.l) - return bytes, data -end - -""" -This function selects a pair of GPIO for bit banging I2C at a -specified baud rate. - -Bit banging I2C allows for certain operations which are not possible -with the standard I2C driver. - -o baud rates as low as 50 -o repeated starts -o clock stretching -o I2C on any pair of spare GPIO - -SDA:= 0-31 -SCL:= 0-31 -baud:= 50-500000 - -Returns 0 if OK, otherwise PI_BAD_USER_GPIO, PI_BAD_I2C_BAUD, or -PI_GPIO_IN_USE. - -NOTE - -The GPIO used for SDA and SCL must have pull-ups to 3V3 connected. -As a guide the hardware pull-ups on pins 3 and 5 are 1k8 in value. - -... -h = bb_i2c_open(pi, 4, 5, 50000) # bit bang on GPIO 4/5 at 50kbps -... -""" -function bb_i2c_open(self::Pi, SDA, SCL, baud=100000) - # I p1 SDA - # I p2 SCL - # I p3 4 - ## extension ## - # I baud - extents = IOBuffer() - write(extents, baud) - return _u2i(_pigpio_command_ext( - self.sl, _PI_CMD_BI2CO, SDA, SCL, 4, extents)) -end - -""" -This function stops bit banging I2C on a pair of GPIO -previously opened with [*bb_i2c_open*]. - -SDA:= 0-31, the SDA GPIO used in a prior call to [*bb_i2c_open*] - -Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_NOT_I2C_GPIO. - -... -bb_i2c_close(pi, SDA) -... -""" -function bb_i2c_close(self::Pi, SDA) - return _u2i(_pigpio_command(self.sl, _PI_CMD_BI2CC, SDA, 0)) -end - -""" -This function executes a sequence of bit banged I2C operations. -The operations to be performed are specified by the contents -of data which contains the concatenated command codes and -associated data. - -SDA:= 0-31 (as used in a prior call to [*bb_i2c_open*]) -data:= the concatenated I2C commands, see below - -The returned value is a tuple of the number of bytes read and a -bytearray containing the bytes. If there was an error the -number of bytes read will be less than zero (and will contain -the error code). - -... -(count, data) = pi.bb_i2c_zip( - h, [4, 0x53, 2, 7, 1, 0x32, 2, 6, 6, 3, 0]) -... - -The following command codes are supported - -Name @ Cmd & Data @ Meaning -End @ 0 @ No more commands -Escape @ 1 @ Next P is two bytes -Start @ 2 @ Start condition -Stop @ 3 @ Stop condition -Address @ 4 P @ Set I2C address to P -Flags @ 5 lsb msb @ Set I2C flags to lsb + (msb << 8) -Read @ 6 P @ Read P bytes of data -Write @ 7 P ... @ Write P bytes of data - -The address, read, and write commands take a parameter P. -Normally P is one byte (0-255). If the command is preceded by -the Escape command then P is two bytes (0-65535, least significant -byte first). - -The address and flags default to 0. The address and flags maintain -their previous value until updated. - -No flags are currently defined. - -Any read I2C data is concatenated in the returned bytearray. - -... -Set address 0x53 -start, write 0x32, (re)start, read 6 bytes, stop -Set address 0x1E -start, write 0x03, (re)start, read 6 bytes, stop -Set address 0x68 -start, write 0x1B, (re)start, read 8 bytes, stop -End - -0x04 0x53 -0x02 0x07 0x01 0x32 0x02 0x06 0x06 0x03 - -0x04 0x1E -0x02 0x07 0x01 0x03 0x02 0x06 0x06 0x03 - -0x04 0x68 -0x02 0x07 0x01 0x1B 0x02 0x06 0x08 0x03 - -0x00 -... -""" -function bb_i2c_zip(self::Pi, SDA, data) - # I p1 SDA - # I p2 0 - # I p3 len - ## extension ## - # s len data bytes - - # Don't raise exception. Must release lock. - bytes = u2i(_pigpio_command_ext( - self.sl, _PI_CMD_BI2CZ, SDA, 0, length(data), [data], false)) - if bytes > 0 - data = self._rxbuf(bytes) - else - data = "" - end - unlock(self.sl.l) - return bytes, data -end +""" +Returns a handle (>=0) for the device at the I2C bus address. + + * `i2c_bus`: >=0. + * `i2c_address`: 0-0x7F. + * `i2c_flags`: 0, no flags are currently defined. + +Normally you would only use the `i2c_*` functions if +you are or will be connecting to the Pi over a network. If +you will always run on the local Pi use the standard SMBus +module instead. + +Physically buses 0 and 1 are available on the Pi. Higher +numbered buses will be available if a kernel supported bus +multiplexor is being used. + +For the SMBus commands the low level transactions are shown +at the end of the function description. The following +abbreviations are used. + +``` +S (1 bit) : Start bit +P (1 bit) : Stop bit +Rd/Wr (1 bit) : Read/Write bit. Rd equals 1, Wr equals 0. +A, NA (1 bit) : Accept and not accept bit. +Addr (7 bits): I2C 7 bit address. +reg (8 bits): Command byte, which often selects a register. +Data (8 bits): A data byte. +Count (8 bits): A byte defining the length of a block operation. + +[..]: Data sent by the device. +``` + +```julia +h = i2c_open(pi, 1, 0x53) # open device at address 0x53 on bus 1 +``` +""" +function i2c_open(self::Pi, i2c_bus, i2c_address, i2c_flags=0) + # I p1 i2c_bus + # I p2 i2c_addr + # I p3 4 + ## extension ## + # I i2c_flags + + io = IOBuffer() + write(io,Int32(i2c_flags)) + extents = take!(io) + + return _u2i(_pigpio_command_ext( + self.sl, _PI_CMD_I2CO, i2c_bus, i2c_address, 4, extents)) +end + +""" +Closes the I2C device associated with handle. + + * `handle`: >=0 (as returned by a prior call to `i2c_open`). + +```julia +i2c_close(pi, h) +``` +""" +function i2c_close(self::Pi, handle) + return _u2i(_pigpio_command(self.sl, _PI_CMD_I2CC, handle, 0)) +end + +""" +Sends a single bit to the device associated with handle. + + * `handle`: >=0 (as returned by a prior call to `i2c_open`). + * `bit`: 0 or 1, the value to write. + +SMBus 2.0 5.5.1 - Quick command. +``` +S Addr bit [A] P +``` + +```julia +i2c_write_quick(pi, 0, 1) # send 1 to device 0 +i2c_write_quick(pi, 3, 0) # send 0 to device 3 +``` +""" +function i2c_write_quick(self::Pi, handle, bit) + return _u2i(_pigpio_command(self.sl, _PI_CMD_I2CWQ, handle, bit)) +end + +""" +Sends a single byte to the device associated with handle. + + * `handle`: >=0 (as returned by a prior call to `i2c_open`). + * `byte_val`: 0-255, the value to write. + +SMBus 2.0 5.5.2 - Send byte. +``` +S Addr Wr [A] byte_val [A] P +``` + +```julia +i2c_write_byte(pi, 1, 17) # send byte 17 to device 1 +i2c_write_byte(pi, 2, 0x23) # send byte 0x23 to device 2 +``` +""" +function i2c_write_byte(self::Pi, handle, byte_val) + return _u2i( + _pigpio_command(self.sl, _PI_CMD_I2CWS, handle, byte_val)) +end + +""" +Reads a single byte from the device associated with handle. + + * `handle`: >=0 (as returned by a prior call to `i2c_open`). + +SMBus 2.0 5.5.3 - Receive byte. +``` +S Addr Rd [A] [Data] NA P +``` + +```julia +b = i2c_read_byte(pi, 2) # read a byte from device 2 +``` +""" +function i2c_read_byte(self::Pi, handle) + return _u2i(_pigpio_command(self.sl, _PI_CMD_I2CRS, handle, 0)) +end + +""" +Writes a single byte to the specified register of the device +associated with handle. + + * `handle`: >=0 (as returned by a prior call to `i2c_open`). + * `reg`: >=0, the device register. + * `byte_val`: 0-255, the value to write. + +SMBus 2.0 5.5.4 - Write byte. +``` +S Addr Wr [A] reg [A] byte_val [A] P +``` + +```julia +# send byte 0xC5 to reg 2 of device 1 +i2c_write_byte_data(pi, 1, 2, 0xC5) + +# send byte 9 to reg 4 of device 2 +i2c_write_byte_data(pi, 2, 4, 9) +``` +""" +function i2c_write_byte_data(self::Pi, handle, reg, byte_val) + # I p1 handle + # I p2 reg + # I p3 4 + ## extension ## + # I byte_val + extents = IOBuffer() + write(extents, byte_val) + return _u2i(_pigpio_command_ext( + self.sl, _PI_CMD_I2CWB, handle, reg, 4, extents)) +end + +""" +Writes a single 16 bit word to the specified register of the +device associated with handle. + + * `handle`: >=0 (as returned by a prior call to `i2c_open`). + * `reg`: >=0, the device register. + * `word_val`: 0-65535, the value to write. + +SMBus 2.0 5.5.4 - Write word. +``` +S Addr Wr [A] reg [A] word_val_Low [A] word_val_High [A] P +``` + +```julia +# send word 0xA0C5 to reg 5 of device 4 +i2c_write_word_data(pi, 4, 5, 0xA0C5) + +# send word 2 to reg 2 of device 5 +i2c_write_word_data(pi, 5, 2, 23) +``` +""" +function i2c_write_word_data(self::Pi, handle, reg, word_val) + # I p1 handle + # I p2 reg + # I p3 4 + ## extension ## + # I word_val + extents = IOBuffer() + write(extents, word_val) + return _u2i(_pigpio_command_ext( + self.sl, _PI_CMD_I2CWW, handle, reg, 4, extents)) +end + +""" +Reads a single byte from the specified register of the device +associated with handle. + + * `handle`: >=0 (as returned by a prior call to `i2c_open`). + * `reg`: >=0, the device register. + +SMBus 2.0 5.5.5 - Read byte. +``` +S Addr Wr [A] reg [A] S Addr Rd [A] [Data] NA P +``` + +```julia +# read byte from reg 17 of device 2 +b = i2c_read_byte_data(pi, 2, 17) + +# read byte from reg 1 of device 0 +b = i2c_read_byte_data(pi, 0, 1) +``` +""" +function i2c_read_byte_data(self, handle, reg) + return _u2i(_pigpio_command(self.sl, _PI_CMD_I2CRB, handle, reg)) +end + +""" +Reads a single 16 bit word from the specified register of the +device associated with handle. + + * `handle`: >=0 (as returned by a prior call to `i2c_open`). + * `reg`: >=0, the device register. + +SMBus 2.0 5.5.5 - Read word. +``` +S Addr Wr [A] reg [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P +``` + +```julia +# read word from reg 2 of device 3 +w = i2c_read_word_data(pi, 3, 2) + +# read word from reg 7 of device 2 +w = i2c_read_word_data(pi, 2, 7) +``` +""" +function i2c_read_word_data(self, handle, reg) + return _u2i(_pigpio_command(self.sl, _PI_CMD_I2CRW, handle, reg)) +end + +""" +Writes 16 bits of data to the specified register of the device +associated with handle and reads 16 bits of data in return. + + * `handle`: >=0 (as returned by a prior call to `i2c_open`). + * `reg`: >=0, the device register. + * `word_val`: 0-65535, the value to write. + +SMBus 2.0 5.5.6 - Process call. +``` +S Addr Wr [A] reg [A] word_val_Low [A] word_val_High [A] +S Addr Rd [A] [DataLow] A [DataHigh] NA P +``` + +```julia +r = i2c_process_call(pi, h, 4, 0x1231) +r = i2c_process_call(pi, h, 6, 0) +``` +""" +function i2c_process_call(self, handle, reg, word_val) + # I p1 handle + # I p2 reg + # I p3 4 + ## extension ## + # I word_val + extents = IOBuffer() + write(extents, word_val) + return _u2i(_pigpio_command_ext( + self.sl, _PI_CMD_I2CPC, handle, reg, 4, extents)) +end + +""" +Writes up to 32 bytes to the specified register of the device +associated with handle. + + * `handle`: >=0 (as returned by a prior call to `i2c_open`). + * `reg`: >=0, the device register. + * `data`: the bytes to write. + +SMBus 2.0 5.5.7 - Block write. +``` +S Addr Wr [A] reg [A] length(data) [A] data0 [A] data1 [A] ... [A] +datan [A] P +``` + +```julia +i2c_write_block_data(pi, 4, 5, b'hello') + +i2c_write_block_data(pi, 4, 5, "data bytes") + +i2c_write_block_data(pi, 5, 0, b'\\x00\\x01\\x22') + +i2c_write_block_data(pi, 6, 2, [0, 1, 0x22]) +``` +""" +function i2c_write_block_data(self, handle, reg, data) +# I p1 handle +# I p2 reg +# I p3 len +## extension ## +# s len data bytes + if length(data) + return _u2i(_pigpio_command_ext( + self.sl, _PI_CMD_I2CWK, handle, reg, length(data), data)) + else + return 0 + end +end + +""" +Reads a block of up to 32 bytes from the specified register of +the device associated with handle. + + * `handle`: >=0 (as returned by a prior call to `i2c_open`). + * `reg`: >=0, the device register. + +SMBus 2.0 5.5.7 - Block read. +``` +S Addr Wr [A] reg [A] +S Addr Rd [A] [Count] A [Data] A [Data] A ... A [Data] NA P +``` + +The amount of returned data is set by the device. + +The returned value is a tuple of the number of bytes read and a +bytearray containing the bytes. If there was an error the +number of bytes read will be less than zero (and will contain +the error code). + +```julia +(b, d) = i2c_read_block_data(pi, h, 10) +if b >= 0 + # process data +else + # process read failure +end +``` +""" +function i2c_read_block_data(self::Pi, handle, reg) + # Don't raise exception. Must release lock. + bytes = u2i(_pigpio_command(self.sl, _PI_CMD_I2CRK, handle, reg, false)) + if bytes > 0 + data = rxbuf(self,bytes) + else + data = "" + end + + unlock(self.sl.l) + return bytes, data +end + +""" +Writes data bytes to the specified register of the device +associated with handle and reads a device specified number +of bytes of data in return. + + * `handle`: >=0 (as returned by a prior call to `i2c_open`). + * `reg`: >=0, the device register. + * `data`: the bytes to write. + +The SMBus 2.0 documentation states that a minimum of 1 byte may +be sent and a minimum of 1 byte may be received. The total +number of bytes sent/received must be 32 or less. + +SMBus 2.0 5.5.8 - Block write-block read. +``` +S Addr Wr [A] reg [A] length(data) [A] data0 [A] ... datan [A] +S Addr Rd [A] [Count] A [Data] ... A P +``` + +The returned value is a tuple of the number of bytes read and a +bytearray containing the bytes. If there was an error the +number of bytes read will be less than zero (and will contain +the error code). + +```julia +(b, d) = i2c_block_process_call(pi, h, 10, b'\\x02\\x05\\x00') + +(b, d) = i2c_block_process_call(pi, h, 10, b'abcdr') + +(b, d) = i2c_block_process_call(pi, h, 10, "abracad") + +(b, d) = i2c_block_process_call(pi, h, 10, [2, 5, 16]) +``` +""" +function i2c_block_process_call(self::Pi, handle, reg, data) + # I p1 handle + # I p2 reg + # I p3 len + ## extension ## + # s len data bytes + + # Don't raise exception. Must release lock. + bytes = u2i(_pigpio_command_ext( + self.sl, _PI_CMD_I2CPK, handle, reg, length(data), data, false)) + if bytes > 0 + data = rxbuf(self, bytes) + else + data = "" + end + unlock(self.sl.l) + return bytes, data +end + +""" +Writes data bytes to the specified register of the device +associated with handle . 1-32 bytes may be written. + + * `handle`: >=0 (as returned by a prior call to `i2c_open`). + * `reg`: >=0, the device register. + * `data`: the bytes to write. + +``` +S Addr Wr [A] reg [A] data0 [A] data1 [A] ... [A] datan [NA] P +``` + +```julia +i2c_write_i2c_block_data(pi, 4, 5, 'hello') + +i2c_write_i2c_block_data(pi, 4, 5, b'hello') + +i2c_write_i2c_block_data(pi, 5, 0, b'\\x00\\x01\\x22') + +i2c_write_i2c_block_data(pi, 6, 2, [0, 1, 0x22]) +``` +""" +function i2c_write_i2c_block_data(self::Pi, handle, reg, data) + # I p1 handle + # I p2 reg + # I p3 len + ## extension ## + # s len data bytes + if length(data) > 0 + return _u2i(_pigpio_command_ext( + self.sl, _PI_CMD_I2CWI, handle, reg, length(data), [data])) + else + return 0 + end +end + +""" +Reads count bytes from the specified register of the device +associated with handle . The count may be 1-32. + + * `handle`: >=0 (as returned by a prior call to `i2c_open`). + * `reg`: >=0, the device register. + * `count`: >0, the number of bytes to read. + +``` +S Addr Wr [A] reg [A] +S Addr Rd [A] [Data] A [Data] A ... A [Data] NA P +``` + +The returned value is a tuple of the number of bytes read and a +bytearray containing the bytes. If there was an error the +number of bytes read will be less than zero (and will contain +the error code). + +```julia +(b, d) = i2c_read_i2c_block_data(pi, h, 4, 32) +if b >= 0 + # process data +else + # process read failure +end +``` +""" +function i2c_read_i2c_block_data(self::Pi, handle, reg, count) + # I p1 handle + # I p2 reg + # I p3 4 + ## extension ## + # I count + extents = IOBuffer() + write(extents, count) + # Don't raise exception. Must release lock. + bytes = u2i(_pigpio_command_ext( + self.sl, _PI_CMD_I2CRI, handle, reg, 4, extents, false)) + if bytes > 0 + data = rxbuf(self, bytes) + else + data = "" + end + + unlock(self.sl.l) + return bytes, data +end + +""" +Returns count bytes read from the raw device associated +with handle. + + * `handle`: >=0 (as returned by a prior call to `i2c_open`). + * `count`: >0, the number of bytes to read. + +``` +S Addr Rd [A] [Data] A [Data] A ... A [Data] NA P +``` + +The returned value is a tuple of the number of bytes read and a +bytearray containing the bytes. If there was an error the +number of bytes read will be less than zero (and will contain +the error code). + +```julia +(count, data) = i2c_read_device(pi, h, 12) +``` +""" +function i2c_read_device(self::Pi, handle, count) + # Don't raise exception. Must release lock. + bytes = u2i( + _pigpio_command(self.sl, _PI_CMD_I2CRD, handle, count, false)) + if bytes > 0 + data = rxbuf(self, bytes) + else + data = "" + end + unlock(self.sl.l) + return bytes, data +end + +""" +Writes the data bytes to the raw device associated with handle. + + * `handle`: >=0 (as returned by a prior call to `i2c_open`). + * `data`: the bytes to write. + +``` +S Addr Wr [A] data0 [A] data1 [A] ... [A] datan [A] P +``` + +```julia +i2c_write_device(pi, h, b"\\x12\\x34\\xA8") + +i2c_write_device(pi, h, b"help") + +i2c_write_device(pi, h, 'help') + +i2c_write_device(pi, h, [23, 56, 231]) +``` +""" +function i2c_write_device(self::Pi, handle, data) + # I p1 handle + # I p2 0 + # I p3 len + ## extension ## + # s len data bytes + if length(data) + return _u2i(_pigpio_command_ext( + self.sl, _PI_CMD_I2CWD, handle, 0, length(data), data)) + else + return 0 + end +end + +""" +This function executes a sequence of I2C operations. The +operations to be performed are specified by the contents of data +which contains the concatenated command codes and associated data. + + * `handle`: >=0 (as returned by a prior call to `i2c_open`). + * `data`: the concatenated I2C commands, see below + +The returned value is a tuple of the number of bytes read and a +bytearray containing the bytes. If there was an error the +number of bytes read will be less than zero (and will contain +the error code). + +```julia +(count, data) = i2c_zip(pi, h, [4, 0x53, 7, 1, 0x32, 6, 6, 0]) +``` + +The following command codes are supported + +Name @ Cmd & Data @ Meaning +End @ 0 @ No more commands +Escape @ 1 @ Next P is two bytes +On @ 2 @ Switch combined flag on +Off @ 3 @ Switch combined flag off +Address @ 4 P @ Set I2C address to P +Flags @ 5 lsb msb @ Set I2C flags to lsb + (msb << 8) +Read @ 6 P @ Read P bytes of data +Write @ 7 P ... @ Write P bytes of data + +The address, read, and write commands take a parameter P. +Normally P is one byte (0-255). If the command is preceded by +the Escape command then P is two bytes (0-65535, least significant +byte first). + +The address defaults to that associated with the handle. +The flags default to 0. The address and flags maintain their +previous value until updated. + +Any read I2C data is concatenated in the returned bytearray. + +``` +Set address 0x53, write 0x32, read 6 bytes +Set address 0x1E, write 0x03, read 6 bytes +Set address 0x68, write 0x1B, read 8 bytes +End + +0x04 0x53 0x07 0x01 0x32 0x06 0x06 +0x04 0x1E 0x07 0x01 0x03 0x06 0x06 +0x04 0x68 0x07 0x01 0x1B 0x06 0x08 +0x00 +``` +""" +function i2c_zip(self::Pi, handle, data) + # I p1 handle + # I p2 0 + # I p3 len + ## extension ## + # s len data bytes + + # Don't raise exception. Must release lock. + bytes = u2i(_pigpio_command_ext( + self.sl, _PI_CMD_I2CZ, handle, 0, length(data), data, false)) + if bytes > 0 + data = rxbuf(self,bytes) + else + data = "" + end + unlock(self.sl.l) + return bytes, data +end + +""" +This function selects a pair of GPIO for bit banging I2C at a +specified baud rate. + +Bit banging I2C allows for certain operations which are not possible +with the standard I2C driver. + +o baud rates as low as 50 +o repeated starts +o clock stretching +o I2C on any pair of spare GPIO + + * `SDA`: 0-31 + * `SCL`: 0-31 + * `baud`: 50-500000 + +Returns 0 if OK, otherwise `PiGPIO.PI_BAD_USER_GPIO`, `PiGPIO.PI_BAD_I2C_BAUD`, +or `PiGPIO.PI_GPIO_IN_USE`. + +!!! note + + The GPIO used for SDA and SCL must have pull-ups to 3V3 connected. + As a guide the hardware pull-ups on pins 3 and 5 are 1k8 in value. + +```julia +h = bb_i2c_open(pi, 4, 5, 50000) # bit bang on GPIO 4/5 at 50kbps +``` +""" +function bb_i2c_open(self::Pi, SDA, SCL, baud=100000) + # I p1 SDA + # I p2 SCL + # I p3 4 + ## extension ## + # I baud + extents = IOBuffer() + write(extents, baud) + return _u2i(_pigpio_command_ext( + self.sl, _PI_CMD_BI2CO, SDA, SCL, 4, extents)) +end + +""" +This function stops bit banging I2C on a pair of GPIO +previously opened with `bb_i2c_open`. + + * `SDA`: 0-31, the SDA GPIO used in a prior call to `bb_i2c_open` + +Returns 0 if OK, otherwise `PiGPIO.PI_BAD_USER_GPIO`, or +`PiGPIO.PI_NOT_I2C_GPIO`. + +```julia +bb_i2c_close(pi, SDA) +``` +""" +function bb_i2c_close(self::Pi, SDA) + return _u2i(_pigpio_command(self.sl, _PI_CMD_BI2CC, SDA, 0)) +end + +""" +This function executes a sequence of bit banged I2C operations. +The operations to be performed are specified by the contents +of data which contains the concatenated command codes and +associated data. + + * `SDA`: 0-31 (as used in a prior call to `bb_i2c_open`) + * `data`: the concatenated I2C commands, see below + +The returned value is a tuple of the number of bytes read and a +bytearray containing the bytes. If there was an error the +number of bytes read will be less than zero (and will contain +the error code). + +```julia +(count, data) = pi.bb_i2c_zip( + h, [4, 0x53, 2, 7, 1, 0x32, 2, 6, 6, 3, 0]) +``` + +The following command codes are supported + +``` +Name @ Cmd & Data @ Meaning +End @ 0 @ No more commands +Escape @ 1 @ Next P is two bytes +Start @ 2 @ Start condition +Stop @ 3 @ Stop condition +Address @ 4 P @ Set I2C address to P +Flags @ 5 lsb msb @ Set I2C flags to lsb + (msb << 8) +Read @ 6 P @ Read P bytes of data +Write @ 7 P ... @ Write P bytes of data +``` + +The address, read, and write commands take a parameter P. +Normally P is one byte (0-255). If the command is preceded by +the Escape command then P is two bytes (0-65535, least significant +byte first). + +The address and flags default to 0. The address and flags maintain +their previous value until updated. + +No flags are currently defined. + +Any read I2C data is concatenated in the returned bytearray. + +``` +Set address 0x53 +start, write 0x32, (re)start, read 6 bytes, stop +Set address 0x1E +start, write 0x03, (re)start, read 6 bytes, stop +Set address 0x68 +start, write 0x1B, (re)start, read 8 bytes, stop +End + +0x04 0x53 +0x02 0x07 0x01 0x32 0x02 0x06 0x06 0x03 + +0x04 0x1E +0x02 0x07 0x01 0x03 0x02 0x06 0x06 0x03 + +0x04 0x68 +0x02 0x07 0x01 0x1B 0x02 0x06 0x08 0x03 + +0x00 +``` +""" +function bb_i2c_zip(self::Pi, SDA, data) + # I p1 SDA + # I p2 0 + # I p3 len + ## extension ## + # s len data bytes + + # Don't raise exception. Must release lock. + bytes = u2i(_pigpio_command_ext( + self.sl, _PI_CMD_BI2CZ, SDA, 0, length(data), [data], false)) + if bytes > 0 + data = rxbuf(self,bytes) + else + data = "" + end + unlock(self.sl.l) + return bytes, data +end diff --git a/src/pi.jl b/src/pi.jl index 7768aec..f080cfd 100644 --- a/src/pi.jl +++ b/src/pi.jl @@ -14,9 +14,9 @@ end """ A class to store pulse information. -gpio_on: the GPIO to switch on at the start of the pulse. -gpio_off: the GPIO to switch off at the start of the pulse. -delay: the delay in microseconds before the next pulse. +`gpio_on`: the GPIO to switch on at the start of the pulse. +`gpio_off`: the GPIO to switch off at the start of the pulse. +`delay`: the delay in microseconds before the next pulse. """ mutable struct Pulse gpio_on::Int @@ -25,34 +25,36 @@ mutable struct Pulse end """ -Returns a text description of a pigpio error. + PiGPIO.error_text(errnum) -errnum:= <0, the error number +Returns a text description of a PiGPIO error number. +`errnum` (`errnum` <0). -... -print(pigpio.error_text(-5)) -level not 0-1 -... +```julia +print(PiGPIO.error_text(-5)) +# output: level not 0-1 +``` """ function error_text(errnum) for e in _errors - if e[0] == errnum - return e[1] + if e[1] == errnum + return e[2] end end return "unknown error ($ernum)" end """ -Returns the microsecond difference between two ticks. + PiGPIO.tickDiff(t1,t2) -t1:= the earlier tick -t2:= the later tick +Returns the microsecond difference between two ticks `t1` (the earlier tick) +and `t2` the later tick. If `t2 - t1 < 0`, it is assumed that the time counter +wrapped around the Int32 limit. -... -print(pigpio.tickDiff(4294967272, 12)) -36 -... +```julia +print(PiGPIO.tickDiff(4294967272, 12)) +# output 36 +``` """ function tickDiff(t1, t2) tDiff = t2 - t1 @@ -62,6 +64,7 @@ function tickDiff(t1, t2) return tDiff end +u2i(x::UInt32) = signed(x) """ Converts a 32 bit unsigned number to signed. If the number @@ -69,7 +72,7 @@ is negative it indicates an error. On error a pigpio exception will be raised if exceptions is true. """ function _u2i(x::UInt32) - v = convert(Int32, x) + v = reinterpret(Int32, x) if v < 0 if exceptions error(error_text(v)) @@ -79,6 +82,7 @@ function _u2i(x::UInt32) end + struct InMsg cmd::Cuint # a bits type p1::Cuint # an array of bits types @@ -94,16 +98,18 @@ end """ Runs a pigpio socket command. -sl:= command socket and lock. -cmd:= the command to be executed. -p1:= command parameter 1 (if applicable). - p2:= command parameter 2 (if applicable). +* `sl`: command socket and lock. +* `cmd`: the command to be executed. +* `p1`: command parameter 1 (if applicable). +* `p2`: command parameter 2 (if applicable). """ function _pigpio_command(sl::SockLock, cmd::Integer, p1::Integer, p2::Integer, rl=true) lock(sl.l) Base.write(sl.s, UInt32.([cmd, p1, p2, 0])) - out = IOBuffer(Base.read(sl.s, 16)) - msg = reinterpret(Cuint, take!(out))[4] + + out = Base.read(sl.s, _SOCK_CMD_LEN) + @debug "_pigpio_command" out + msg = reinterpret(Cuint, out)[4] if rl unlock(sl.l) end @@ -113,33 +119,38 @@ end """ Runs an extended pigpio socket command. - sl:= command socket and lock. - cmd:= the command to be executed. - p1:= command parameter 1 (if applicable). - p2:= command parameter 2 (if applicable). - p3:= total size in bytes of following extents -extents:= additional data blocks + * `sl`: command socket and lock. + * `cmd`: the command to be executed. + * `p1`: command parameter 1 (if applicable). + * `p2`: command parameter 2 (if applicable). + * `p3`: total size in bytes of following extents + * `extents`: additional data blocks """ function _pigpio_command_ext(sl, cmd, p1, p2, p3, extents, rl=true) - ext = IOBuffer() - Base.write(ext, Array(reinterpret(UInt8, [cmd, p1, p2, p3]))) - for x in extents - write(ext, string(x)) - end + io = IOBuffer() + write(io,Cuint.((cmd, p1, p2, p3))...) + ext = vcat(take!(io),extents) + lock(sl.l) write(sl.s, ext) - msg = reinterpret(Cuint, sl.s)[4] + out = Base.read(sl.s, _SOCK_CMD_LEN) + @debug "_pigpio_command_ext" out ext + res = reinterpret(Cuint, out)[4] if rl unlock(sl.l) end return res end +function _pigpio_command_ext(sl, cmd, p1, p2, p3, extents::IO, rl=true) + _pigpio_command_ext(sl, cmd, p1, p2, p3, take!(extents), rl) +end + """An ADT class to hold callback information - gpio:= Broadcom GPIO number. - edge:= EITHER_EDGE, RISING_EDGE, or FALLING_EDGE. - func:= a user function taking three arguments (GPIO, level, tick). + * `gpio`: Broadcom GPIO number. + * `edge`: `PiGPIO.EITHER_EDGE`, `PiGPIO.RISING_EDGE`, or `PiGPIO.FALLING_EDGE`. + * `func`: a user function taking three arguments (GPIO, level, tick). """ mutable struct Callback_ADT gpio::Int @@ -172,7 +183,11 @@ function CallbackThread(control, host, port) #self.start() #TODO end -"""Stops notifications.""" +""" + PiGPIO.stop(self::CallbackThread) + +Stops notifications. +""" function stop(self::CallbackThread) if self.go self.go = false @@ -214,7 +229,7 @@ end """Runs the notification thread.""" -function run(self::CallbackThread) +function Base.run(self::CallbackThread) lastLevel = _pigpio_command(self.control, _PI_CMD_BR1, 0, 0) MSG_SIZ = 12 while self.go @@ -336,21 +351,23 @@ end """Returns count bytes from the command socket.""" function rxbuf(self::Pi, count) - ext = readbytes(self.sl.s, count, all) + ext = Base.read(self.sl.s, count) return ext end """ -Sets the GPIO mode. + set_mode(pi::Pi, pin::Int, mode) -gpio:= 0-53. -mode:= INPUT, OUTPUT, ALT0, ALT1, ALT2, ALT3, ALT4, ALT5. +Sets the GPIO `mode` of the given `pin` (integer between 0 and 53) of the +Pi instance `pi`. The mode con be `PiGPIO.INPUT`, `PiGPIO.OUTPUT`, +`PiGPIO.ALT0`, `PiGPIO.ALT1`, `PiGPIO.ALT2`, `PiGPIO.ALT3`, `PiGPIO.ALT4` or +`PiGPIO.ALT5`. -... -set_mode(pi, 4, pigpio.INPUT) # GPIO 4 as input -set_mode(pi, 17, pigpio.OUTPUT) # GPIO 17 as output -set_mode(pi, 24, pigpio.ALT2) # GPIO 24 as ALT2 -... +```julia +set_mode(pi, 4, PiGPIO.INPUT) # GPIO 4 as input +set_mode(pi, 17, PiGPIO.OUTPUT) # GPIO 17 as output +set_mode(pi, 24, PiGPIO.ALT2) # GPIO 24 as ALT2 +``` """ function set_mode(self::Pi, gpio, mode) return _u2i(_pigpio_command(self.sl, _PI_CMD_MODES, gpio, mode)) @@ -358,13 +375,13 @@ end """ -Returns the GPIO mode. + get_mode(self::Pi, gpio) -gpio:= 0-53. +Returns the GPIO mode for the pin `gpio` (integer between 0 and 53). -Returns a value as follows +Returns a value as follows: -. . +``` 0 = INPUT 1 = OUTPUT 2 = ALT5 @@ -373,12 +390,13 @@ Returns a value as follows 5 = ALT1 6 = ALT2 7 = ALT3 -. . +``` + -... +```julia print(get_mode(pi, 0)) -4 -... +# output 4 +``` """ function get_mode(self::Pi, gpio) return _u2i(_pigpio_command(self.sl, _PI_CMD_MODEG, gpio, 0)) @@ -386,16 +404,18 @@ end """ -Sets or clears the internal GPIO pull-up/down resistor. + set_pull_up_down(self::Pi, gpio, pud) -gpio:= 0-53. -pud:= PUD_UP, PUD_DOWN, PUD_OFF. +Sets or clears the internal GPIO pull-up/down resistor +for the pin `gpio` (integer between 0 and 53). +Possible values for `pud` are `PiGPIO.PUD_UP`, `PiGPIO.PUD_DOWN` or +`PiGPIO.PUD_OFF`. -... -set_pull_up_down(pi, 17, pigpio.PUD_OFF) -set_pull_up_down(pi, 23, pigpio.PUD_UP) -set_pull_up_down(pi, 24, pigpio.PUD_DOWN) -... +```julia +set_pull_up_down(pi, 17, PiGPIO.PUD_OFF) +set_pull_up_down(pi, 23, PiGPIO.PUD_UP) +set_pull_up_down(pi, 24, PiGPIO.PUD_DOWN) +``` """ function set_pull_up_down(self::Pi, gpio, pud) return _u2i(_pigpio_command(self.sl, _PI_CMD_PUD, gpio, pud)) @@ -403,46 +423,46 @@ end """ -Returns the GPIO level. + read(self::Pi, gpio) -gpio:= 0-53. +Returns the GPIO level for the pin `gpio` (an integer between 0 and 53). -... -set_mode(pi, 23, pigpio.INPUT) +```julia +set_mode(pi, 23, PiGPIO.INPUT) -set_pull_up_down(pi, 23, pigpio.PUD_DOWN) +set_pull_up_down(pi, 23, PiGPIO.PUD_DOWN) print(read(pi, 23)) -0 +# output 0 -set_pull_up_down(pi, 23, pigpio.PUD_UP) +set_pull_up_down(pi, 23, PiGPIO.PUD_UP) print(read(pi, 23)) -1 -... +# output 1 +``` """ function read(self::Pi, gpio) return _u2i(_pigpio_command(self.sl, _PI_CMD_READ, gpio, 0)) end """ -Sets the GPIO level. + write(self::Pi, gpio, level) -GPIO:= 0-53. -level:= 0, 1. +Sets the GPIO level for the pin `gpio` (an integer between 0 and 53) where +level is 0 or 1. If PWM or servo pulses are active on the GPIO they are switched off. -... -set_mode(pi, 17, pigpio.OUTPUT) +```julia +set_mode(pi, 17, PiGPIO.OUTPUT) write(pi, 17,0) print(read(pi, 17)) -0 +# output 0 write(pi, 17,1) print(read(pi, 17)) -1 -... +# output 1 +``` """ function write(self::Pi, gpio, level) return _u2i(_pigpio_command(self.sl, _PI_CMD_WRITE, gpio, level)) @@ -450,20 +470,22 @@ end """ + PiGPIO.set_PWM_dutycycle(self::Pi, user_gpio, dutycycle) + Starts (non-zero dutycycle) or stops (0) PWM pulses on the GPIO. -user_gpio:= 0-31. -dutycycle:= 0-range (range defaults to 255). + * `user_gpio`: 0-31. + * `dutycycle`: 0-range (range defaults to 255). -The [*set_PWM_range*] function can change the default range of 255. +The `set_PWM_range` function can change the default range of 255. -... +```julia set_PWM_dutycycle(pi, 4, 0) # PWM off set_PWM_dutycycle(pi, 4, 64) # PWM 1/4 on set_PWM_dutycycle(pi, 4, 128) # PWM 1/2 on set_PWM_dutycycle(pi, 4, 192) # PWM 3/4 on set_PWM_dutycycle(pi, 4, 255) # PWM full on -... +``` """ function set_PWM_dutycycle(self::Pi, user_gpio, dutycycle) return _u2i(_pigpio_command( @@ -471,15 +493,13 @@ function set_PWM_dutycycle(self::Pi, user_gpio, dutycycle) end """ -Returns the PWM dutycycle being used on the GPIO. - -user_gpio:= 0-31. - -Returns the PWM dutycycle. + PiGPIO.get_PWM_dutycycle(self::Pi, user_gpio) +Returns the PWM dutycycle being used on the GPIO. + * `user_gpio`: 0-31. For normal PWM the dutycycle will be out of the defined range -for the GPIO (see [*get_PWM_range*]). +for the GPIO (see `get_PWM_range`). If a hardware clock is active on the GPIO the reported dutycycle will be 500000 (500k) out of 1000000 (1M). @@ -487,59 +507,62 @@ dutycycle will be 500000 (500k) out of 1000000 (1M). If hardware PWM is active on the GPIO the reported dutycycle will be out of a 1000000 (1M). -... +```julia set_PWM_dutycycle(pi, 4, 25) print(get_PWM_dutycycle(pi, 4)) -25 +# output 25 set_PWM_dutycycle(pi, 4, 203) print(get_PWM_dutycycle(pi, 4)) -203 -... +# output 203 +``` """ function get_PWM_dutycycle(self::Pi, user_gpio) return _u2i(_pigpio_command(self.sl, _PI_CMD_GDC, user_gpio, 0)) end """ -Sets the range of PWM values to be used on the GPIO. + PiGPIO.set_PWM_range(self::Pi, user_gpio, range_) -user_gpio:= 0-31. - range_:= 25-40000. +Sets the range of PWM values to be used on the GPIO. +`user_gpio` is an integer between 0 and 31 and `range_` is between 25 and 40000. -... +```julia set_PWM_range(pi, 9, 100) # now 25 1/4, 50 1/2, 75 3/4 on set_PWM_range(pi, 9, 500) # now 125 1/4, 250 1/2, 375 3/4 on set_PWM_range(pi, 9, 3000) # now 750 1/4, 1500 1/2, 2250 3/4 on -... +``` """ function set_PWM_range(self::Pi, user_gpio, range_) return _u2i(_pigpio_command(self.sl, _PI_CMD_PRS, user_gpio, range_)) end """ -Returns the range of PWM values being used on the GPIO. + PiGPIO.get_PWM_range(self::Pi, user_gpio) -user_gpio:= 0-31. +Returns the range of PWM values being used on the GPIO. +`user_gpio` is an integer between 0 and 31. If a hardware clock or hardware PWM is active on the GPIO the reported range will be 1000000 (1M). -... +```julia set_PWM_range(pi, 9, 500) print(get_PWM_range(pi, 9)) -500 -... +# output 500 +``` """ function get_PWM_range(self::Pi, user_gpio) return _u2i(_pigpio_command(self.sl, _PI_CMD_PRG, user_gpio, 0)) end """ + PiGPIO.get_PWM_real_range(self::Pi, user_gpio) + Returns the real (underlying) range of PWM values being used on the GPIO. -user_gpio:= 0-31. + * `user_gpio`: 0-31. If a hardware clock is active on the GPIO the reported real range will be 1000000 (1M). @@ -547,11 +570,11 @@ real range will be 1000000 (1M). If hardware PWM is active on the GPIO the reported real range will be approximately 250M divided by the set PWM frequency. -... +```julia set_PWM_frequency(pi, 4, 800) print(get_PWM_real_range(pi, 4)) -250 -... +# output 250 +``` """ function get_PWM_real_range(self::Pi, user_gpio) return _u2i(_pigpio_command(self.sl, _PI_CMD_PRRG, user_gpio, 0)) @@ -560,8 +583,8 @@ end """ Sets the frequency (in Hz) of the PWM to be used on the GPIO. -user_gpio:= 0-31. -frequency:= >=0 Hz + * `user_gpio`: 0-31. + * `frequency`: >=0 Hz Returns the numerically closest frequency if OK, otherwise PI_BAD_USER_GPIO or PI_NOT_PERMITTED. @@ -578,7 +601,7 @@ sample rate is set when the pigpio daemon is started. The frequencies for each sample rate are -. . +``` Hertz 1: 40000 20000 10000 8000 5000 4000 2500 2000 1600 @@ -599,9 +622,10 @@ rate 10: 4000 2000 1000 800 500 400 250 200 160 125 100 80 50 40 25 20 10 5 -. . +``` + -... +```julia set_PWM_frequency(pi, 4,0) print(get_PWM_frequency(pi, 4)) 10 @@ -609,7 +633,7 @@ print(get_PWM_frequency(pi, 4)) set_PWM_frequency(pi, 4,100000) print(get_PWM_frequency(pi, 4)) 8000 -... +``` """ function set_PWM_frequency(self::Pi, user_gpio, frequency) return _u2i( @@ -619,20 +643,20 @@ end """ Returns the frequency of PWM being used on the GPIO. -user_gpio:= 0-31. +`user_gpio`= 0-31. Returns the frequency (in Hz) used for the GPIO. For normal PWM the frequency will be that defined for the GPIO -by [*set_PWM_frequency*]. +by `set_PWM_frequency`. If a hardware clock is active on the GPIO the reported frequency -will be that set by [*hardware_clock*]. +will be that set by `hardware_clock`. If hardware PWM is active on the GPIO the reported frequency -will be that set by [*hardware_PWM*]. +will be that set by `hardware_PWM`. -... +```julia set_PWM_frequency(pi, 4,0) print(get_PWM_frequency(pi, 4)) 10 @@ -640,7 +664,7 @@ print(get_PWM_frequency(pi, 4)) set_PWM_frequency(pi, 4, 800) print(get_PWM_frequency(pi, 4)) 800 -... +``` """ function get_PWM_frequency(self::Pi, user_gpio) return _u2i(_pigpio_command(self.sl, _PI_CMD_PFG, user_gpio, 0)) @@ -649,9 +673,8 @@ end """ Starts (500-2500) or stops (0) servo pulses on the GPIO. -user_gpio:= 0-31. -pulsewidth:= 0 (off), - 500 (most anti-clockwise) - 2500 (most clockwise). +* `user_gpio`: 0-31. +* `pulsewidth`: 0 (off), 500 (most anti-clockwise) - 2500 (most clockwise). The selected pulsewidth will continue to be transmitted until changed by a subsequent call to set_servo_pulsewidth. @@ -663,26 +686,26 @@ safe and represents the mid-point of rotation. You can DAMAGE a servo if you command it to move beyond its limits. -... +```julia set_servo_pulsewidth(pi, 17, 0) # off set_servo_pulsewidth(pi, 17, 1000) # safe anti-clockwise set_servo_pulsewidth(pi, 17, 1500) # centre set_servo_pulsewidth(pi, 17, 2000) # safe clockwise -... +``` """ function set_servo_pulsewidth(self::Pi, user_gpio, pulsewidth) return _u2i(_pigpio_command( - self.sl, _PI_CMD_SERVO, user_gpio, int(pulsewidth))) + self.sl, _PI_CMD_SERVO, user_gpio, Int(pulsewidth))) end """ Returns the servo pulsewidth being used on the GPIO. -user_gpio:= 0-31. +* `user_gpio`: 0-31. Returns the servo pulsewidth. -... +```julia set_servo_pulsewidth(pi, 4, 525) print(get_servo_pulsewidth(pi, 4)) 525 @@ -690,13 +713,15 @@ print(get_servo_pulsewidth(pi, 4)) set_servo_pulsewidth(pi, 4, 2130) print(get_servo_pulsewidth(pi, 4)) 2130 -... +``` """ function get_servo_pulsewidth(self::Pi, user_gpio) return _u2i(_pigpio_command(self.sl, _PI_CMD_GPW, user_gpio, 0)) end """ + PiGPIO.notify_open(self::Pi) + Returns a notification handle (>=0). A notification is a method for being notified of GPIO state @@ -705,30 +730,30 @@ changes via a pipe. Pipes are only accessible from the local machine so this function serves no purpose if you are using Python from a remote machine. The in-built (socket) notifications -provided by [*callback*] should be used instead. +provided by `callback` should be used instead. -Notifications for handle x will be available at the pipe -named /dev/pigpiox (where x is the handle number). +Notifications for handle `x` will be available at the pipe +named `/dev/pigpiox` (where `x` is the handle number). E.g. if the function returns 15 then the notifications must be -read from /dev/pigpio15. +read from `/dev/pigpio15`. Notifications have the following structure. -. . +``` I seqno I flags I tick I level -. . +``` seqno: starts at 0 each time the handle is opened and then increments by one for each report. -flags: two flags are defined, PI_NTFY_FLAGS_WDOG and -PI_NTFY_FLAGS_ALIVE. If bit 5 is set (PI_NTFY_FLAGS_WDOG) +flags: two flags are defined, `PI_NTFY_FLAGS_WDOG` and +`PI_NTFY_FLAGS_ALIVE`. If bit 5 is set (`PI_NTFY_FLAGS_WDOG`) then bits 0-4 of the flags indicate a GPIO which has had a -watchdog timeout; if bit 6 is set (PI_NTFY_FLAGS_ALIVE) this +watchdog timeout; if bit 6 is set (`PI_NTFY_FLAGS_ALIVE`) this indicates a keep alive signal on the pipe/socket and is sent once a minute in the absence of other notification activity. @@ -738,11 +763,12 @@ around after 1h12m. level: indicates the level of each GPIO. If bit 1<= 0 notify_begin(pi, h, 1234) -... +end +``` """ function notify_open(self::Pi) return _u2i(_pigpio_command(self.sl, _PI_CMD_NO, 0, 0)) @@ -751,8 +777,8 @@ end """ Starts notifications on a handle. -handle:= >=0 (as returned by a prior call to [*notify_open*]) -bits:= a 32 bit mask indicating the GPIO to be notified. + * `handle`: >=0 (as returned by a prior call to `notify_open`) + * `bits`: a 32 bit mask indicating the GPIO to be notified. The notification sends state changes for each GPIO whose corresponding bit in bits is set. @@ -760,11 +786,12 @@ corresponding bit in bits is set. The following code starts notifications for GPIO 1, 4, 6, 7, and 10 (1234 = 0x04D2 = 0b0000010011010010). -... -h = notify_open(pi, ) +```julia +h = notify_open(pi) if h >= 0 notify_begin(pi, h, 1234) -... +end +``` """ function notify_begin(self::Pi, handle, bits) return _u2i(_pigpio_command(self.sl, _PI_CMD_NB, handle, bits)) @@ -773,21 +800,22 @@ end """ Pauses notifications on a handle. -handle:= >=0 (as returned by a prior call to [*notify_open*]) + * `handle`: >=0 (as returned by a prior call to `notify_open`) Notifications for the handle are suspended until -[*notify_begin*] is called again. +`notify_begin` is called again. -... -h = notify_open(pi, ) +```julia +h = notify_open(pi) if h >= 0 notify_begin(pi, h, 1234) - ... + # ... notify_pause(pi, h) - ... + # ... notify_begin(pi, h, 1234) - ... -... + # ... +end +``` """ function notify_pause(self::Pi, handle) return _u2i(_pigpio_command(self.sl, _PI_CMD_NB, handle, 0)) @@ -796,16 +824,17 @@ end """ Stops notifications on a handle and releases the handle for reuse. -handle:= >=0 (as returned by a prior call to [*notify_open*]) + * `handle`: >=0 (as returned by a prior call to `notify_open`) -... -h = notify_open(pi, ) +```julia +h = notify_open(pi) if h >= 0 notify_begin(pi, h, 1234) - ... + # ... notify_close(pi, h) - ... -... + # ... +end +``` """ function notify_close(self::Pi, handle) return _u2i(_pigpio_command(self.sl, _PI_CMD_NC, handle, 0)) @@ -814,8 +843,8 @@ end """ Sets a watchdog timeout for a GPIO. - user_gpio:= 0-31. -wdog_timeout:= 0-60000. +* `user_gpio`: 0-31. +* `wdog_timeout`: 0-60000. The watchdog is nominally in milliseconds. @@ -830,10 +859,10 @@ to the fifo with the flags set to indicate a watchdog timeout. The callback class interprets the flags and will call registered callbacks for the GPIO with level TIMEOUT. -... +```julia set_watchdog(pi, 23, 1000) # 1000 ms watchdog on GPIO 23 set_watchdog(pi, 23, 0) # cancel watchdog on GPIO 23 -... +``` """ function set_watchdog(self::Pi, user_gpio, wdog_timeout) return _u2i(_pigpio_command( @@ -846,10 +875,10 @@ Returns the levels of the bank 1 GPIO (GPIO 0-31). The returned 32 bit integer has a bit set if the corresponding GPIO is high. GPIO n has bit value (1<=0, default 0. -arg2:= >=0, default 0. -argx:= extra arguments (each 0-255), default empty. +`arg1` is >=0, default 0. +`arg2` is >=0, default 0. +`argx` is an extra arguments (each 0-255), default empty. The returned value is an integer which by convention should be >=0 for OK and <0 for error. -... -value = custom_1(pi, ) +```julia +value = PiGPIO.custom_1(pi) -value = custom_1(pi, 23) +value = PiGPIO.custom_1(pi, 23) -value = custom_1(pi, 0, 55) +value = PiGPIO.custom_1(pi, 0, 55) -value = custom_1(pi, 23, 56, [1, 5, 7]) +value = PiGPIO.custom_1(pi, 23, 56, [1, 5, 7]) -value = custom_1(pi, 23, 56, b"hello") +value = PiGPIO.custom_1(pi, 23, 56, b"hello") -value = custom_1(pi, 23, 56, "hello") -... +value = PiGPIO.custom_1(pi, 23, 56, "hello") +``` """ function custom_1(self, arg1=0, arg2=0, argx=[]) # I p1 arg1 @@ -1143,28 +1188,29 @@ function custom_1(self, arg1=0, arg2=0, argx=[]) end """ + PiGPIO.custom_2(self, arg1=0, argx=[], retMax=8192) + Calls a pigpio function customised by the user. -arg1:= >=0, default 0. -argx:= extra arguments (each 0-255), default empty. -retMax:= >=0, maximum number of bytes to return, default 8192. +`arg1` is >=0, default 0. `argx` extra arguments (each 0-255), default empty. +`retMax` is >=0, maximum number of bytes to return, default 8192. The returned value is a tuple of the number of bytes returned and a bytearray containing the bytes. If there was an error the number of bytes read will be less than zero (and will contain the error code). -... -(count, data) = custom_2(pi, ) +```julia +(count, data) = PiGPIO.custom_2(pi) -(count, data) = custom_2(pi, 23) +(count, data) = PiGPIO.custom_2(pi, 23) -(count, data) = custom_2(pi, 23, [1, 5, 7]) +(count, data) = PiGPIO.custom_2(pi, 23, [1, 5, 7]) -(count, data) = custom_2(pi, 23, b"hello") +(count, data) = PiGPIO.custom_2(pi, 23, b"hello") -(count, data) = custom_2(pi, 23, "hello", 128) -... +(count, data) = PiGPIO.custom_2(pi, 23, "hello", 128) +``` """ function custom_2(self, arg1=0, argx=[], retMax=8192) # I p1 arg1 @@ -1177,7 +1223,7 @@ function custom_2(self, arg1=0, argx=[], retMax=8192) bytes = u2i(_pigpio_command_ext( self.sl, _PI_CMD_CF2, arg1, retMax, length(argx), [argx], false)) if bytes > 0 - data = rxbuf(bytes) + data = rxbuf(self,bytes) else data = "" end @@ -1186,12 +1232,14 @@ function custom_2(self, arg1=0, argx=[], retMax=8192) end """ + PiGPIO.callback(self::Pi, user_gpio, edge=RISING_EDGE, func=nothing) + Calls a user supplied function (a callback) whenever the specified GPIO edge is detected. -user_gpio:= 0-31. -edge:= EITHER_EDGE, RISING_EDGE (default), or FALLING_EDGE. -func:= user supplied callback function. +* `user_gpio`: 0-31. +* `edge`: `PiGPIO.EITHER_EDGE`, `PiGPIO.RISING_EDGE` (default), or `PiGPIO.FALLING_EDGE`. +* `func`: user supplied callback function. The user supplied callback receives three parameters, the GPIO, the level, and the tick. @@ -1206,15 +1254,14 @@ The callback may be cancelled by calling the cancel function. A GPIO may have multiple callbacks (although I can't think of a reason to do so). -... -end - +```julia function cbf(gpio, level, tick) -print(gpio, level, tick) + print(gpio, level, tick) +end -cb1 = callback(pi, 22, pigpio.EITHER_EDGE, cbf) +cb1 = callback(pi, 22, PiGPIO.EITHER_EDGE, cbf) -cb2 = callback(pi, 4, pigpio.EITHER_EDGE) +cb2 = callback(pi, 4, PiGPIO.EITHER_EDGE) cb3 = callback(pi, 17) @@ -1223,7 +1270,7 @@ print(cb3.tally()) cb3.reset_tally() cb1.cancel() # To cancel callback cb1. -... +``` """ function callback(self::Pi, user_gpio, edge=RISING_EDGE, func=nothing) return _callback(self._notify, user_gpio, edge, func) @@ -1232,10 +1279,10 @@ end """ Wait for an edge event on a GPIO. -user_gpio:= 0-31. - edge:= EITHER_EDGE, RISING_EDGE (default), or - FALLING_EDGE. -wait_timeout:= >=0.0 (default 60.0). +* `user_gpio`: 0-31. +* `edge`: `PiGPIO.EITHER_EDGE`, `PiGPIO.RISING_EDGE` (default), or + `PiGPIO.FALLING_EDGE`. +* `wait_timeout`: >=0.0 (default 60.0). The function returns when the edge is detected or after the number of seconds specified by timeout has expired. @@ -1243,22 +1290,24 @@ the number of seconds specified by timeout has expired. Do not use this function for precise timing purposes, the edge is only checked 20 times a second. Whenever you need to know the accurate time of GPIO events use -a [*callback*] function. +a `callback` function. The function returns true if the edge is detected, otherwise false. -... +```julia if wait_for_edge(pi, 23) -print("Rising edge detected") + print("Rising edge detected") else -print("wait for edge timed out") + print("wait for edge timed out") +end -if wait_for_edge(pi, 23, pigpio.FALLING_EDGE, 5.0) -print("Falling edge detected") +if wait_for_edge(pi, 23, PiGPIO.FALLING_EDGE, 5.0) + print("Falling edge detected") else -print("wait for falling edge timed out") -... + print("wait for falling edge timed out") +end +``` """ function wait_for_edge(self::Pi, user_gpio, edge=RISING_EDGE, wait_timeout=60.0) a = _wait_for_edge(self.notify, user_gpio, edge, wait_timeout) @@ -1266,13 +1315,16 @@ function wait_for_edge(self::Pi, user_gpio, edge=RISING_EDGE, wait_timeout=60.0) end """ + Pi(; host = get(ENV, "PIGPIO_ADDR", ""), + port = get(ENV, "PIGPIO_PORT", 8888)) + Grants access to a Pi's GPIO. -host:= the host name of the Pi on which the pigpio daemon is +`host` is the host name of the Pi on which the pigpio daemon is running. The default is localhost unless overridden by the PIGPIO_ADDR environment variable. -port:= the port number on which the pigpio daemon is listening. +`port` is the port number on which the pigpio daemon is listening. The default is 8888 unless overridden by the PIGPIO_PORT environment variable. The pigpio daemon must have been started with the same port number. @@ -1280,19 +1332,20 @@ port:= the port number on which the pigpio daemon is listening. This connects to the pigpio daemon and reserves resources to be used for sending commands and receiving notifications. -An instance attribute [*connected*] may be used to check the +An instance attribute `connected` may be used to check the success of the connection. If the connection is established -successfully [*connected*] will be true, otherwise false. +successfully `connected` will be true, otherwise false. -... -pi = pigpio.pi() # use defaults -pi = pigpio.pi('mypi') # specify host, default port -pi = pigpio.pi('mypi', 7777) # specify host and port +```julia +pi = PiGPIO.Pi() # use defaults +pi = PiGPIO.Pi(host = "mypi") # specify host, default port +pi = PiGPIO.Pi(host = "mypi", port = 7777) # specify host and port -pi = pigpio.pi() # exit script if no connection -if not pi.connected -exit() -... +pi = PiGPIO.Pi() # exit script if no connection +if !pi.connected + exit() +end +``` """ function Pi(; host = get(ENV, "PIGPIO_ADDR", ""), port = get(ENV, "PIGPIO_PORT", 8888)) port = Int(port) @@ -1324,10 +1377,14 @@ function Pi(; host = get(ENV, "PIGPIO_ADDR", ""), port = get(ENV, "PIGPIO_PORT", end -"""Release pigpio resources. -... -stop(pi) -... +""" + PiGPIO.stop(self::Pi) + +Release pigpio resources. + +```julia +PiGPIO.stop(pi) +``` """ function stop(self::Pi) self.connected = false diff --git a/src/spiSerial.jl b/src/spiSerial.jl index 5952f21..3db47cf 100644 --- a/src/spiSerial.jl +++ b/src/spiSerial.jl @@ -1,450 +1,457 @@ -""" -Returns a handle for the SPI device on channel. Data will be -transferred at baud bits per second. The flags may be used to -modify the default behaviour of 4-wire operation, mode 0, -active low chip select. - -An auxiliary SPI device is available on all models but the -A and B and may be selected by setting the A bit in the -flags. The auxiliary device has 3 chip selects and a -selectable word size in bits. - -spi_channel:= 0-1 (0-2 for the auxiliary SPI device). - baud:= 32K-125M (values above 30M are unlikely to work). -spi_flags:= see below. - -Normally you would only use the [*spi_**] functions if -you are or will be connecting to the Pi over a network. If -you will always run on the local Pi use the standard SPI -module instead. - -spi_flags consists of the least significant 22 bits. - -. . -21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -b b b b b b R T n n n n W A u2 u1 u0 p2 p1 p0 m m -. . - -mm defines the SPI mode. - -WARNING: modes 1 and 3 do not appear to work on -the auxiliary device. - -. . -Mode POL PHA -0 0 0 -1 0 1 -2 1 0 -3 1 1 -. . - -px is 0 if CEx is active low (default) and 1 for active high. - -ux is 0 if the CEx GPIO is reserved for SPI (default) -and 1 otherwise. - -A is 0 for the standard SPI device, 1 for the auxiliary SPI. - -W is 0 if the device is not 3-wire, 1 if the device is 3-wire. -Standard SPI device only. - -nnnn defines the number of bytes (0-15) to write before -switching the MOSI line to MISO to read data. This field -is ignored if W is not set. Standard SPI device only. - -T is 1 if the least significant bit is transmitted on MOSI -first, the default (0) shifts the most significant bit out -first. Auxiliary SPI device only. - -R is 1 if the least significant bit is received on MISO -first, the default (0) receives the most significant bit -first. Auxiliary SPI device only. - -bbbbbb defines the word size in bits (0-32). The default (0) -sets 8 bits per word. Auxiliary SPI device only. - -The [*spi_read*], [*spi_write*], and [*spi_xfer*] functions -transfer data packed into 1, 2, or 4 bytes according to -the word size in bits. - -For bits 1-8 there will be one byte per character. -For bits 9-16 there will be two bytes per character. -For bits 17-32 there will be four bytes per character. - -E.g. 32 12-bit words will be transferred in 64 bytes. - -The other bits in flags should be set to zero. - -... -# open SPI device on channel 1 in mode 3 at 50000 bits per second - -h = spi_open(pi, 1, 50000, 3) -... -""" -function spi_open(self::Pi, spi_channel, baud, spi_flags=0) - # I p1 spi_channel - # I p2 baud - # I p3 4 - ## extension ## - # I spi_flags - extents=IOBuffer() - write(extents, spi_flags::Cint) - return _u2i(_pigpio_command_ext( - self.sl, _PI_CMD_SPIO, spi_channel, baud, 4, extents)) -end - -""" -Closes the SPI device associated with handle. - -handle:= >=0 (as returned by a prior call to [*spi_open*]). - -... -spi_close(pi, h) -... -""" -function spi_close(self, handle) - return _u2i(_pigpio_command(self.sl, _PI_CMD_SPIC, handle, 0)) -end - -""" -Reads count bytes from the SPI device associated with handle. - -handle:= >=0 (as returned by a prior call to [*spi_open*]). -count:= >0, the number of bytes to read. - -The returned value is a tuple of the number of bytes read and a -bytearray containing the bytes. If there was an error the -number of bytes read will be less than zero (and will contain -the error code). - -... -(b, d) = spi_read(pi, h, 60) # read 60 bytes from device h -if b == 60 -# process read data -else -# error path -... -""" -function spi_read(self::Pi, handle, count) - # Don't raise exception. Must release lock. - bytes = u2i(_pigpio_command( - self.sl, _PI_CMD_SPIR, handle, count, false)) - if bytes > 0 - data = rxbuf(bytes) - else - data = "" - end - unlock(self.sl.l) - return bytes, data -end - -""" -Writes the data bytes to the SPI device associated with handle. - -handle:= >=0 (as returned by a prior call to [*spi_open*]). -data:= the bytes to write. - -... -spi_write(pi, 0, b'\\x02\\xc0\\x80') # write 3 bytes to device 0 - -spi_write(pi, 0, b'defgh') # write 5 bytes to device 0 - -spi_write(pi, 0, "def") # write 3 bytes to device 0 - -spi_write(pi, 1, [2, 192, 128]) # write 3 bytes to device 1 -... -""" -function spi_write(self::Pi, handle, data) - # I p1 handle - # I p2 0 - # I p3 len - ## extension ## - # s len data bytes - return _u2i(_pigpio_command_ext( - self.sl, _PI_CMD_SPIW, handle, 0, length(data), data)) -end - -""" -Writes the data bytes to the SPI device associated with handle, -returning the data bytes read from the device. - -handle:= >=0 (as returned by a prior call to [*spi_open*]). -data:= the bytes to write. - -The returned value is a tuple of the number of bytes read and a -bytearray containing the bytes. If there was an error the -number of bytes read will be less than zero (and will contain -the error code). - -... -(count, rx_data) = spi_xfer(pi, h, b'\\x01\\x80\\x00') - -(count, rx_data) = spi_xfer(pi, h, [1, 128, 0]) - -(count, rx_data) = spi_xfer(pi, h, b"hello") - -(count, rx_data) = spi_xfer(pi, h, "hello") -... -""" -function spi_xfer(self::Pi, handle, data) - # I p1 handle - # I p2 0 - # I p3 len - ## extension ## - # s len data bytes - - # Don't raise exception. Must release lock. - bytes = u2i(_pigpio_command_ext( - self.sl, _PI_CMD_SPIX, handle, 0, length(data), data, false)) - if bytes > 0 - data = rxbuf(bytes) - else - data = "" - end - unlock(self.sl.l) - return bytes, data -end - -""" -Returns a handle for the serial tty device opened -at baud bits per second. - -tty:= the serial device to open. -baud:= baud rate in bits per second, see below. -ser_flags:= 0, no flags are currently defined. - -Normally you would only use the [*serial_**] functions if -you are or will be connecting to the Pi over a network. If -you will always run on the local Pi use the standard serial -module instead. - -The baud rate must be one of 50, 75, 110, 134, 150, -200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, -38400, 57600, 115200, or 230400. - -... -h1 = serial_open(pi, "/dev/ttyAMA0", 300) - -h2 = serial_open(pi, "/dev/ttyUSB1", 19200, 0) -... -""" -function serial_open(self::Pi, tty, baud, ser_flags=0) - # I p1 baud - # I p2 ser_flags - # I p3 len - ## extension ## - # s len data bytes - return _u2i(_pigpio_command_ext( - self.sl, _PI_CMD_SERO, baud, ser_flags, length(tty), [tty])) -end - -""" -Closes the serial device associated with handle. - -handle:= >=0 (as returned by a prior call to [*serial_open*]). - -... -serial_close(pi, h1) -... -""" -function serial_close(self::Pi, handle) - return _u2i(_pigpio_command(self.sl, _PI_CMD_SERC, handle, 0)) -end - -""" -Returns a single byte from the device associated with handle. - -handle:= >=0 (as returned by a prior call to [*serial_open*]). - -... -b = serial_read_byte(pi, h1) -... -""" -function serial_read_byte(self::Pi, handle) - return _u2i(_pigpio_command(self.sl, _PI_CMD_SERRB, handle, 0)) -end - -""" -Writes a single byte to the device associated with handle. - -handle:= >=0 (as returned by a prior call to [*serial_open*]). -byte_val:= 0-255, the value to write. - -... -serial_write_byte(pi, h1, 23) - -serial_write_byte(h1, ord(pi, 'Z')) -... -""" -function serial_write_byte(self::Pi, handle, byte_val) - return _u2i( - _pigpio_command(self.sl, _PI_CMD_SERWB, handle, byte_val)) -end - -""" -Reads up to count bytes from the device associated with handle. - -handle:= >=0 (as returned by a prior call to [*serial_open*]). -count:= >0, the number of bytes to read. - -The returned value is a tuple of the number of bytes read and a -bytearray containing the bytes. If there was an error the -number of bytes read will be less than zero (and will contain -the error code). - -... -(b, d) = serial_read(pi, h2, 100) -if b > 0 -# process read data -... -""" -function serial_read(self::Pi, handle, count) - # Don't raise exception. Must release lock. - bytes = u2i( - _pigpio_command(self.sl, _PI_CMD_SERR, handle, count, false)) - if bytes > 0 - data = rxbuf(bytes) - else - data = "" - end - unlock(self.sl.l) - return bytes, data -end - -""" -Writes the data bytes to the device associated with handle. - -handle:= >=0 (as returned by a prior call to [*serial_open*]). -data:= the bytes to write. - -... -serial_write(pi, h1, b'\\x02\\x03\\x04') - -serial_write(pi, h2, b'help') - -serial_write(pi, h2, "hello") - -serial_write(pi, h1, [2, 3, 4]) -... -""" -function serial_write(self::Pi, handle, data) - # I p1 handle - # I p2 0 - # I p3 len - ## extension ## - # s len data bytes - - return _u2i(_pigpio_command_ext( - self.sl, _PI_CMD_SERW, handle, 0, length(data), [data])) -end - -""" -Returns the number of bytes available to be read from the -device associated with handle. - -handle:= >=0 (as returned by a prior call to [*serial_open*]). - -... -rdy = serial_data_available(pi, h1) - -if rdy > 0 -(b, d) = serial_read(pi, h1, rdy) -... -""" -function serial_data_available(self::Pi, handle) - return _u2i(_pigpio_command(self.sl, _PI_CMD_SERDA, handle, 0)) -end - -""" -Opens a GPIO for bit bang reading of serial data. - -user_gpio:= 0-31, the GPIO to use. -baud:= 50-250000, the baud rate. -bb_bits:= 1-32, the number of bits per word, default 8. - -The serial data is held in a cyclic buffer and is read using -[*bb_serial_read*]. - -It is the caller's responsibility to read data from the cyclic -buffer in a timely fashion. - -... -status = bb_serial_read_open(pi, 4, 19200) -status = bb_serial_read_open(pi, 17, 9600) -... -""" -function bb_serial_read_open(self, user_gpio, baud, bb_bits=8) - # pigpio message format - - # I p1 user_gpio - # I p2 baud - # I p3 4 - ## extension ## - # I bb_bits - extents = IOBuffer() - write(extents, bb_bits::Cuint) - return _u2i(_pigpio_command_ext( - self.sl, _PI_CMD_SLRO, user_gpio, baud, 4, extents)) -end - -""" -Returns data from the bit bang serial cyclic buffer. - -user_gpio:= 0-31 (opened in a prior call to [*bb_serial_read_open*]) - -The returned value is a tuple of the number of bytes read and a -bytearray containing the bytes. If there was an error the -number of bytes read will be less than zero (and will contain -the error code). - -The bytes returned for each character depend upon the number of -data bits [*bb_bits*] specified in the [*bb_serial_read_open*] -command. - -For [*bb_bits*] 1-8 there will be one byte per character. -For [*bb_bits*] 9-16 there will be two bytes per character. -For [*bb_bits*] 17-32 there will be four bytes per character. - -... -(count, data) = bb_serial_read(pi, 4) -... -""" -function bb_serial_read(self, user_gpio) - # Don't raise exception. Must release lock. - bytes = u2i( - _pigpio_command(self.sl, _PI_CMD_SLR, user_gpio, 10000, false)) - if bytes > 0 - data = self._rxbuf(bytes) - else - data = "" - end - unlock(self.sl.l) - return bytes, data -end - -""" -Closes a GPIO for bit bang reading of serial data. - -user_gpio:= 0-31 (opened in a prior call to [*bb_serial_read_open*]) - -... -status = bb_serial_read_close(pi, 17) -... -""" -function bb_serial_read_close(self, user_gpio) - return _u2i(_pigpio_command(self.sl, _PI_CMD_SLRC, user_gpio, 0)) -end - -""" -Invert serial logic. - -user_gpio:= 0-31 (opened in a prior call to [*bb_serial_read_open*]) -invert:= 0-1 (1 invert, 0 normal) - -... -status = bb_serial_invert(pi, 17, 1) -... -""" -function bb_serial_invert(self, user_gpio, invert) - return _u2i(_pigpio_command(self.sl, _PI_CMD_SLRI, user_gpio, invert)) -end +""" +Returns a handle for the SPI device on channel. Data will be +transferred at baud bits per second. The flags may be used to +modify the default behaviour of 4-wire operation, mode 0, +active low chip select. + +An auxiliary SPI device is available on all models but the +A and B and may be selected by setting the A bit in the +flags. The auxiliary device has 3 chip selects and a +selectable word size in bits. + +* `spi_channel`: 0-1 (0-2 for the auxiliary SPI device). +* `baud`: 32K-125M (values above 30M are unlikely to work). +* `spi_flags`: see below. + +Normally you would only use the `spi_*` functions if +you are or will be connecting to the Pi over a network. If +you will always run on the local Pi use the standard SPI +module instead. + +spi_flags consists of the least significant 22 bits. + +. . +21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +b b b b b b R T n n n n W A u2 u1 u0 p2 p1 p0 m m +. . + +mm defines the SPI mode. + +!!! warning + + modes 1 and 3 do not appear to work on the auxiliary device. + +. . +Mode POL PHA +0 0 0 +1 0 1 +2 1 0 +3 1 1 +. . + +px is 0 if CEx is active low (default) and 1 for active high. + +ux is 0 if the CEx GPIO is reserved for SPI (default) +and 1 otherwise. + +A is 0 for the standard SPI device, 1 for the auxiliary SPI. + +W is 0 if the device is not 3-wire, 1 if the device is 3-wire. +Standard SPI device only. + +nnnn defines the number of bytes (0-15) to write before +switching the MOSI line to MISO to read data. This field +is ignored if W is not set. Standard SPI device only. + +T is 1 if the least significant bit is transmitted on MOSI +first, the default (0) shifts the most significant bit out +first. Auxiliary SPI device only. + +R is 1 if the least significant bit is received on MISO +first, the default (0) receives the most significant bit +first. Auxiliary SPI device only. + +bbbbbb defines the word size in bits (0-32). The default (0) +sets 8 bits per word. Auxiliary SPI device only. + +The `spi_read`, `spi_write`, and `spi_xfer` functions +transfer data packed into 1, 2, or 4 bytes according to +the word size in bits. + +For bits 1-8 there will be one byte per character. +For bits 9-16 there will be two bytes per character. +For bits 17-32 there will be four bytes per character. + +E.g. 32 12-bit words will be transferred in 64 bytes. + +The other bits in flags should be set to zero. + +```julia +# open SPI device on channel 1 in mode 3 at 50000 bits per second + +h = spi_open(pi, 1, 50000, 3) +``` +""" +function spi_open(self::Pi, spi_channel, baud, spi_flags=0) + # I p1 spi_channel + # I p2 baud + # I p3 4 + ## extension ## + # I spi_flags + extents=IOBuffer() + write(extents, Cint(spi_flags)) + return _u2i(_pigpio_command_ext( + self.sl, _PI_CMD_SPIO, spi_channel, baud, 4, extents)) +end + +""" +Closes the SPI device associated with handle. + + * `handle`: >=0 (as returned by a prior call to `spi_open`). + +```julia +spi_close(pi, h) +``` +""" +function spi_close(self, handle) + return _u2i(_pigpio_command(self.sl, _PI_CMD_SPIC, handle, 0)) +end + +""" +Reads count bytes from the SPI device associated with handle. + + * `handle`: >=0 (as returned by a prior call to `spi_open`). + * `count`: >0, the number of bytes to read. + +The returned value is a tuple of the number of bytes read and a +bytearray containing the bytes. If there was an error the +number of bytes read will be less than zero (and will contain +the error code). + +```julia +(b, d) = spi_read(pi, h, 60) # read 60 bytes from device h +if b == 60 + # process read data +else + # error path +end +``` +""" +function spi_read(self::Pi, handle, count) + # Don't raise exception. Must release lock. + bytes = u2i(_pigpio_command( + self.sl, _PI_CMD_SPIR, handle, count, false)) + if bytes > 0 + data = rxbuf(self,bytes) + else + data = "" + end + unlock(self.sl.l) + return bytes, data +end + +""" +Writes the data bytes to the SPI device associated with handle. + + * `handle`: >=0 (as returned by a prior call to `spi_open`). + * `data`: the bytes to write. + +```julia +spi_write(pi, 0, b'\\x02\\xc0\\x80') # write 3 bytes to device 0 + +spi_write(pi, 0, b'defgh') # write 5 bytes to device 0 + +spi_write(pi, 0, "def") # write 3 bytes to device 0 + +spi_write(pi, 1, [2, 192, 128]) # write 3 bytes to device 1 +``` +""" +function spi_write(self::Pi, handle, data) + # I p1 handle + # I p2 0 + # I p3 len + ## extension ## + # s len data bytes + return _u2i(_pigpio_command_ext( + self.sl, _PI_CMD_SPIW, handle, 0, length(data), data)) +end + +""" +Writes the data bytes to the SPI device associated with handle, +returning the data bytes read from the device. + + * `handle`: >=0 (as returned by a prior call to `spi_open`). + * `data`: the bytes to write. + +The returned value is a tuple of the number of bytes read and a +bytearray containing the bytes. If there was an error the +number of bytes read will be less than zero (and will contain +the error code). + +```julia +(count, rx_data) = spi_xfer(pi, h, b'\\x01\\x80\\x00') + +(count, rx_data) = spi_xfer(pi, h, [1, 128, 0]) + +(count, rx_data) = spi_xfer(pi, h, b"hello") + +(count, rx_data) = spi_xfer(pi, h, "hello") +``` +""" +function spi_xfer(self::Pi, handle, data) + # I p1 handle + # I p2 0 + # I p3 len + ## extension ## + # s len data bytes + + # python code + # https://github.com/joan2937/pigpio/blob/c33738a320a3e28824af7807edafda440952c05d/pigpio.py#L4045 + + # Don't raise exception. Must release lock. + bytes = u2i(_pigpio_command_ext( + self.sl, _PI_CMD_SPIX, handle, 0, length(data), data, false)) + if bytes > 0 + data = rxbuf(self,bytes) + else + data = "" + end + unlock(self.sl.l) + return bytes, data +end + +""" +Returns a handle for the serial tty device opened +at baud bits per second. + + * `tty`: the serial device to open. + * `baud`: baud rate in bits per second, see below. + * `ser_flags`: 0, no flags are currently defined. + +Normally you would only use the `serial_*` functions if +you are or will be connecting to the Pi over a network. If +you will always run on the local Pi use the standard serial +module instead. + +The baud rate must be one of 50, 75, 110, 134, 150, +200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, +38400, 57600, 115200, or 230400. + +```julia +h1 = serial_open(pi, "/dev/ttyAMA0", 300) + +h2 = serial_open(pi, "/dev/ttyUSB1", 19200, 0) +``` +""" +function serial_open(self::Pi, tty, baud, ser_flags=0) + # I p1 baud + # I p2 ser_flags + # I p3 len + ## extension ## + # s len data bytes + return _u2i(_pigpio_command_ext( + self.sl, _PI_CMD_SERO, baud, ser_flags, length(tty), [tty])) +end + +""" +Closes the serial device associated with handle. + + * `handle`: >=0 (as returned by a prior call to `serial_open`). + +```julia +serial_close(pi, h1) +``` +""" +function serial_close(self::Pi, handle) + return _u2i(_pigpio_command(self.sl, _PI_CMD_SERC, handle, 0)) +end + +""" +Returns a single byte from the device associated with handle. + + * `handle`: >=0 (as returned by a prior call to `serial_open`). + +```julia +b = serial_read_byte(pi, h1) +``` +""" +function serial_read_byte(self::Pi, handle) + return _u2i(_pigpio_command(self.sl, _PI_CMD_SERRB, handle, 0)) +end + +""" +Writes a single byte to the device associated with handle. + + * `handle`: >=0 (as returned by a prior call to `serial_open`). + * `byte_val`: 0-255, the value to write. + +```julia +serial_write_byte(pi, h1, 23) + +serial_write_byte(h1, ord(pi, 'Z')) +``` +""" +function serial_write_byte(self::Pi, handle, byte_val) + return _u2i( + _pigpio_command(self.sl, _PI_CMD_SERWB, handle, byte_val)) +end + +""" +Reads up to count bytes from the device associated with handle. + + * `handle`: >=0 (as returned by a prior call to `serial_open`). + * `count`: >0, the number of bytes to read. + +The returned value is a tuple of the number of bytes read and a +bytearray containing the bytes. If there was an error the +number of bytes read will be less than zero (and will contain +the error code). + +```julia +(b, d) = serial_read(pi, h2, 100) +if b > 0 + # process read data +end +``` +""" +function serial_read(self::Pi, handle, count) + # Don't raise exception. Must release lock. + bytes = u2i( + _pigpio_command(self.sl, _PI_CMD_SERR, handle, count, false)) + if bytes > 0 + data = rxbuf(self,bytes) + else + data = "" + end + unlock(self.sl.l) + return bytes, data +end + +""" +Writes the data bytes to the device associated with handle. + + * `handle`: >=0 (as returned by a prior call to `serial_open`). + * `data`: the bytes to write. + +```julia +serial_write(pi, h1, b'\\x02\\x03\\x04') + +serial_write(pi, h2, b'help') + +serial_write(pi, h2, "hello") + +serial_write(pi, h1, [2, 3, 4]) +``` +""" +function serial_write(self::Pi, handle, data) + # I p1 handle + # I p2 0 + # I p3 len + ## extension ## + # s len data bytes + + return _u2i(_pigpio_command_ext( + self.sl, _PI_CMD_SERW, handle, 0, length(data), [data])) +end + +""" +Returns the number of bytes available to be read from the +device associated with handle. + +* `handle`: >=0 (as returned by a prior call to `serial_open`). + +```julia +rdy = serial_data_available(pi, h1) + +if rdy > 0 + (b, d) = serial_read(pi, h1, rdy) +end +``` +""" +function serial_data_available(self::Pi, handle) + return _u2i(_pigpio_command(self.sl, _PI_CMD_SERDA, handle, 0)) +end + +""" +Opens a GPIO for bit bang reading of serial data. + +* `user_gpio`: 0-31, the GPIO to use. +* `baud`: 50-250000, the baud rate. +* `bb_bits`: 1-32, the number of bits per word, default 8. + +The serial data is held in a cyclic buffer and is read using +`bb_serial_read`. + +It is the caller's responsibility to read data from the cyclic +buffer in a timely fashion. + +```julia +status = bb_serial_read_open(pi, 4, 19200) +status = bb_serial_read_open(pi, 17, 9600) +``` +""" +function bb_serial_read_open(self, user_gpio, baud, bb_bits=8) + # pigpio message format + + # I p1 user_gpio + # I p2 baud + # I p3 4 + ## extension ## + # I bb_bits + extents = IOBuffer() + write(extents, Cuint(bb_bits)) + return _u2i(_pigpio_command_ext( + self.sl, _PI_CMD_SLRO, user_gpio, baud, 4, extents)) +end + +""" +Returns data from the bit bang serial cyclic buffer. + +* `user_gpio`: 0-31 (opened in a prior call to `bb_serial_read_open`) + +The returned value is a tuple of the number of bytes read and a +bytearray containing the bytes. If there was an error the +number of bytes read will be less than zero (and will contain +the error code). + +The bytes returned for each character depend upon the number of +data bits `bb_bits` specified in the `bb_serial_read_open` +command. + +For `bb_bits` 1-8 there will be one byte per character. +For `bb_bits` 9-16 there will be two bytes per character. +For `bb_bits` 17-32 there will be four bytes per character. + +```julia +(count, data) = bb_serial_read(pi, 4) +``` +""" +function bb_serial_read(self, user_gpio) + # Don't raise exception. Must release lock. + bytes = u2i( + _pigpio_command(self.sl, _PI_CMD_SLR, user_gpio, 10000, false)) + if bytes > 0 + data = rxbuf(self,bytes) + else + data = "" + end + unlock(self.sl.l) + return bytes, data +end + +""" +Closes a GPIO for bit bang reading of serial data. + +* `user_gpio`: 0-31 (opened in a prior call to `bb_serial_read_open`) + +```julia +status = bb_serial_read_close(pi, 17) +``` +""" +function bb_serial_read_close(self, user_gpio) + return _u2i(_pigpio_command(self.sl, _PI_CMD_SLRC, user_gpio, 0)) +end + +""" +Invert serial logic. + +* `user_gpio`: 0-31 (opened in a prior call to `bb_serial_read_open`) +* `invert`: 0-1 (1 invert, 0 normal) + +```julia +status = bb_serial_invert(pi, 17, 1) +``` +""" +function bb_serial_invert(self, user_gpio, invert) + return _u2i(_pigpio_command(self.sl, _PI_CMD_SLRI, user_gpio, invert)) +end diff --git a/src/wave.jl b/src/wave.jl index 5ef9be1..bc2c41a 100644 --- a/src/wave.jl +++ b/src/wave.jl @@ -1,530 +1,542 @@ -""" -Clears all waveforms and any data added by calls to the -[*wave_add_**] functions. - -... -wave_clear(pi, ) -... -""" -function wave_clear(self::Pi) - return _u2i(_pigpio_command(self.sl, _PI_CMD_WVCLR, 0, 0)) -end - -""" -Starts a new empty waveform. - -You would not normally need to call this function as it is -automatically called after a waveform is created with the -[*wave_create*] function. - -... -wave_add_new(pi, ) -... -""" -function wave_add_new(self::Pi) - return _u2i(_pigpio_command(self.sl, _PI_CMD_WVNEW, 0, 0)) -end - -""" -Adds a list of pulses to the current waveform. - -pulses:= list of pulses to add to the waveform. - -Returns the new total number of pulses in the current waveform. - -The pulses are interleaved in time order within the existing -waveform (if any). - -Merging allows the waveform to be built in parts, that is the -settings for GPIO#1 can be added, and then GPIO#2 etc. - -If the added waveform is intended to start after or within -the existing waveform then the first pulse should consist -solely of a delay. - -... -G1=4 -G2=24 - -set_mode(pi, G1, pigpio.OUTPUT) -set_mode(pi, G2, pigpio.OUTPUT) - -flash_500=[] # flash every 500 ms -flash_100=[] # flash every 100 ms - -# ON OFF DELAY - -flash_500.append(pigpio.pulse(1<=0) if OK, otherwise PI_EMPTY_WAVEFORM, -PI_TOO_MANY_CBS, PI_TOO_MANY_OOL, or PI_NO_WAVEFORM_ID. - -The data provided by the [*wave_add_**] functions is consumed by -this function. - -As many waveforms may be created as there is space available. -The wave id is passed to [*wave_send_**] to specify the waveform -to transmit. - -Normal usage would be - -Step 1. [*wave_clear*] to clear all waveforms and added data. - -Step 2. [*wave_add_**] calls to supply the waveform data. - -Step 3. [*wave_create*] to create the waveform and get a unique id - -Repeat steps 2 and 3 as needed. - -Step 4. [*wave_send_**] with the id of the waveform to transmit. - -A waveform comprises one or more pulses. - -A pulse specifies - -1) the GPIO to be switched on at the start of the pulse. -2) the GPIO to be switched off at the start of the pulse. -3) the delay in microseconds before the next pulse. - -Any or all the fields can be zero. It doesn't make any sense -to set all the fields to zero (the pulse will be ignored). - -When a waveform is started each pulse is executed in order with -the specified delay between the pulse and the next. - -... -wid = wave_create(pi, ) -... -""" -function wave_create(self::Pi) - return _u2i(_pigpio_command(self.sl, _PI_CMD_WVCRE, 0, 0)) -end - -""" -This function deletes the waveform with id wave_id. - -wave_id:= >=0 (as returned by a prior call to [*wave_create*]). - -Wave ids are allocated in order, 0, 1, 2, etc. - -... -wave_delete(pi, 6) # delete waveform with id 6 - -wave_delete(pi, 0) # delete waveform with id 0 -... -""" -function wave_delete(self::Pi, wave_id) - return _u2i(_pigpio_command(self.sl, _PI_CMD_WVDEL, wave_id, 0)) -end - -""" -This function is deprecated and has been removed. - -Use [*wave_create*]/[*wave_send_**] instead. -""" -function wave_tx_start(self::Pi) # DEPRECATED - return _u2i(_pigpio_command(self.sl, _PI_CMD_WVGO, 0, 0)) -end - -""" -This function is deprecated and has beeen removed. - -Use [*wave_create*]/[*wave_send_**] instead. -""" -function wave_tx_repeat(self::Pi) # DEPRECATED - return _u2i(_pigpio_command(self.sl, _PI_CMD_WVGOR, 0, 0)) -end - -""" -Transmits the waveform with id wave_id. The waveform is sent -once. - -NOTE: Any hardware PWM started by [*hardware_PWM*] will -be cancelled. - -wave_id:= >=0 (as returned by a prior call to [*wave_create*]). - -Returns the number of DMA control blocks used in the waveform. - -... -cbs = wave_send_once(pi, wid) -... -""" -function wave_send_once(self::Pi, wave_id) - return _u2i(_pigpio_command(self.sl, _PI_CMD_WVTX, wave_id, 0)) -end - -""" -Transmits the waveform with id wave_id. The waveform repeats -until wave_tx_stop is called or another call to [*wave_send_**] -is made. - -NOTE: Any hardware PWM started by [*hardware_PWM*] will -be cancelled. - -wave_id:= >=0 (as returned by a prior call to [*wave_create*]). - -Returns the number of DMA control blocks used in the waveform. - -... -cbs = wave_send_repeat(pi, wid) -... -""" -function wave_send_repeat(self::Pi, wave_id) - return _u2i(_pigpio_command(self.sl, _PI_CMD_WVTXR, wave_id, 0)) -end - -""" -Transmits the waveform with id wave_id using mode mode. - -wave_id:= >=0 (as returned by a prior call to [*wave_create*]). -mode:= WAVE_MODE_ONE_SHOT, WAVE_MODE_REPEAT, - WAVE_MODE_ONE_SHOT_SYNC, or WAVE_MODE_REPEAT_SYNC. - -WAVE_MODE_ONE_SHOT: same as [*wave_send_once*]. - -WAVE_MODE_REPEAT same as [*wave_send_repeat*]. - -WAVE_MODE_ONE_SHOT_SYNC same as [*wave_send_once*] but tries -to sync with the previous waveform. - -WAVE_MODE_REPEAT_SYNC same as [*wave_send_repeat*] but tries -to sync with the previous waveform. - -WARNING: bad things may happen if you delete the previous -waveform before it has been synced to the new waveform. - -NOTE: Any hardware PWM started by [*hardware_PWM*] will -be cancelled. - -wave_id:= >=0 (as returned by a prior call to [*wave_create*]). - -Returns the number of DMA control blocks used in the waveform. - -... -cbs = wave_send_using_mode(pi, wid, WAVE_MODE_REPEAT_SYNC) -... -""" -function wave_send_using_mode(self::Pi, wave_id, mode) - return _u2i(_pigpio_command(self.sl, _PI_CMD_WVTXM, wave_id, mode)) -end - -""" -Returns the id of the waveform currently being -transmitted. - -Returns the waveform id or one of the following special -values - -WAVE_NOT_FOUND (9998) - transmitted wave not found. -NO_TX_WAVE (9999) - no wave being transmitted. - -... -wid = wave_tx_at(pi, ) -... -""" -function wave_tx_at(self::Pi) - return _u2i(_pigpio_command(self.sl, _PI_CMD_WVTAT, 0, 0)) -end - -""" -Returns 1 if a waveform is currently being transmitted, -otherwise 0. - -... -wave_send_once(pi, 0) # send first waveform - -while wave_tx_busy(pi, ): # wait for waveform to be sent -time.sleep(0.1) - -wave_send_once(pi, 1) # send next waveform -... -""" -function wave_tx_busy(self::Pi) - return _u2i(_pigpio_command(self.sl, _PI_CMD_WVBSY, 0, 0)) -end - -""" -Stops the transmission of the current waveform. - -This function is intended to stop a waveform started with -wave_send_repeat. - -... -wave_send_repeat(pi, 3) - -time.sleep(5) - -wave_tx_stop(pi, ) -... -""" -function wave_tx_stop(self::Pi) - return _u2i(_pigpio_command(self.sl, _PI_CMD_WVHLT, 0, 0)) -end - -""" -This function transmits a chain of waveforms. - -NOTE: Any hardware PWM started by [*hardware_PWM*] -will be cancelled. - -The waves to be transmitted are specified by the contents -of data which contains an ordered list of [*wave_id*]s -and optional command codes and related data. - -Returns 0 if OK, otherwise PI_CHAIN_NESTING, -PI_CHAIN_LOOP_CNT, PI_BAD_CHAIN_LOOP, PI_BAD_CHAIN_CMD, -PI_CHAIN_COUNTER, PI_BAD_CHAIN_DELAY, PI_CHAIN_TOO_BIG, -or PI_BAD_WAVE_ID. - -Each wave is transmitted in the order specified. A wave -may occur multiple times per chain. - -A blocks of waves may be transmitted multiple times by -using the loop commands. The block is bracketed by loop -start and end commands. Loops may be nested. - -Delays between waves may be added with the delay command. - -The following command codes are supported - -Name @ Cmd & Data @ Meaning -Loop Start @ 255 0 @ Identify start of a wave block -Loop Repeat @ 255 1 x y @ loop x + y*256 times -Delay @ 255 2 x y @ delay x + y*256 microseconds -Loop Forever @ 255 3 @ loop forever - -If present Loop Forever must be the last entry in the chain. - -The code is currently dimensioned to support a chain with -roughly 600 entries and 20 loop counters. - -... -#!/usr/bin/env python - -import time -import pigpio - -WAVES=5 -GPIO=4 - -wid=[0]*WAVES - -pi = pigpio.pi() # Connect to local Pi. - -set_mode(pi, GPIO, pigpio.OUTPUT); - -for i in range(WAVES) -pi.wave_add_generic([ -pigpio.pulse(1<=0) if OK, otherwise PI_EMPTY_WAVEFORM, +PI_TOO_MANY_CBS, PI_TOO_MANY_OOL, or PI_NO_WAVEFORM_ID. + +The data provided by the `wave_add_*` functions is consumed by +this function. + +As many waveforms may be created as there is space available. +The wave id is passed to `wave_send_*` to specify the waveform +to transmit. + +Normal usage would be + +Step 1. `wave_clear` to clear all waveforms and added data. + +Step 2. `wave_add_*` calls to supply the waveform data. + +Step 3. `wave_create` to create the waveform and get a unique id + +Repeat steps 2 and 3 as needed. + +Step 4. `wave_send_*` with the id of the waveform to transmit. + +A waveform comprises one or more pulses. + +A pulse specifies + +1) the GPIO to be switched on at the start of the pulse. +2) the GPIO to be switched off at the start of the pulse. +3) the delay in microseconds before the next pulse. + +Any or all the fields can be zero. It doesn't make any sense +to set all the fields to zero (the pulse will be ignored). + +When a waveform is started each pulse is executed in order with +the specified delay between the pulse and the next. + +```julia +wid = wave_create(pi, ) +``` +""" +function wave_create(self::Pi) + return _u2i(_pigpio_command(self.sl, _PI_CMD_WVCRE, 0, 0)) +end + +""" +This function deletes the waveform with id wave_id. + + * `wave_id`: >=0 (as returned by a prior call to `wave_create`). + +Wave ids are allocated in order, 0, 1, 2, etc. + +```julia +wave_delete(pi, 6) # delete waveform with id 6 + +wave_delete(pi, 0) # delete waveform with id 0 +``` +""" +function wave_delete(self::Pi, wave_id) + return _u2i(_pigpio_command(self.sl, _PI_CMD_WVDEL, wave_id, 0)) +end + +""" +This function is deprecated and has been removed. + +Use `wave_create`/`wave_send_*` instead. +""" +function wave_tx_start(self::Pi) # DEPRECATED + return _u2i(_pigpio_command(self.sl, _PI_CMD_WVGO, 0, 0)) +end + +""" +This function is deprecated and has beeen removed. + +Use `wave_create`/`wave_send_*` instead. +""" +function wave_tx_repeat(self::Pi) # DEPRECATED + return _u2i(_pigpio_command(self.sl, _PI_CMD_WVGOR, 0, 0)) +end + +""" +Transmits the waveform with id wave_id. The waveform is sent +once. + +!!! note + + Any hardware PWM started by `hardware_PWM` will be cancelled. + + * `wave_id`: >=0 (as returned by a prior call to `wave_create`). + +Returns the number of DMA control blocks used in the waveform. + +```julia +cbs = wave_send_once(pi, wid) +``` +""" +function wave_send_once(self::Pi, wave_id) + return _u2i(_pigpio_command(self.sl, _PI_CMD_WVTX, wave_id, 0)) +end + +""" + PiGPIO.wave_send_repeat(self::Pi, wave_id) + +Transmits the waveform with id `wave_id`. The waveform repeats +until `wave_tx_stop` is called or another call to `wave_send_*` +is made. + +!!! note + Any hardware PWM started by `hardware_PWM` will be cancelled. + + * `wave_id`: >=0 (as returned by a prior call to `wave_create`). + +Returns the number of DMA control blocks used in the waveform. + +```julia +cbs = wave_send_repeat(pi, wid) +``` +""" +function wave_send_repeat(self::Pi, wave_id) + return _u2i(_pigpio_command(self.sl, _PI_CMD_WVTXR, wave_id, 0)) +end + +""" +Transmits the waveform with id wave_id using mode mode. + + * `wave_id`: >0= (as returned by a prior call to `wave_create`). + * `mode`: `PiGPIO.WAVE_MODE_ONE_SHOT`, `PiGPIO.WAVE_MODE_REPEAT`, + `PiGPIO.WAVE_MODE_ONE_SHOT_SYNC`, or `PiGPIO.WAVE_MODE_REPEAT_SYNC`. + +`PiGPIO.WAVE_MODE_ONE_SHOT`: same as `wave_send_once`. + +`PiGPIO.WAVE_MODE_REPEAT` same as `wave_send_repeat`. + +`PiGPIO.WAVE_MODE_ONE_SHOT_SYNC` same as `wave_send_once` but tries +to sync with the previous waveform. + +`PiGPIO.WAVE_MODE_REPEAT_SYNC` same as `wave_send_repeat` but tries +to sync with the previous waveform. + +!!! warning + + Bad things may happen if you delete the previous waveform before it has been synced to the new waveform. + +!!! note + + Any hardware PWM started by `hardware_PWM` will be cancelled. + + * `wave_id`: >=0 (as returned by a prior call to `wave_create`). + +Returns the number of DMA control blocks used in the waveform. + +```julia +cbs = wave_send_using_mode(pi, wid, PiGPIO.WAVE_MODE_REPEAT_SYNC) +``` +""" +function wave_send_using_mode(self::Pi, wave_id, mode) + return _u2i(_pigpio_command(self.sl, _PI_CMD_WVTXM, wave_id, mode)) +end + +""" +Returns the id of the waveform currently being +transmitted. + +Returns the waveform id or one of the following special +values + +`PiGPIO.WAVE_NOT_FOUND` (9998) - transmitted wave not found. +`PiGPIO.NO_TX_WAVE` (9999) - no wave being transmitted. + +```julia +wid = wave_tx_at(pi, ) +``` +""" +function wave_tx_at(self::Pi) + return _u2i(_pigpio_command(self.sl, _PI_CMD_WVTAT, 0, 0)) +end + +""" +Returns 1 if a waveform is currently being transmitted, +otherwise 0. + +```julia +wave_send_once(pi, 0) # send first waveform + +while wave_tx_busy(pi, ): # wait for waveform to be sent +time.sleep(0.1) + +wave_send_once(pi, 1) # send next waveform +``` +""" +function wave_tx_busy(self::Pi) + return _u2i(_pigpio_command(self.sl, _PI_CMD_WVBSY, 0, 0)) +end + +""" +Stops the transmission of the current waveform. + +This function is intended to stop a waveform started with +`wave_send_repeat`. + +```julia +wave_send_repeat(pi, 3) + +sleep(5) + +wave_tx_stop(pi) +``` +""" +function wave_tx_stop(self::Pi) + return _u2i(_pigpio_command(self.sl, _PI_CMD_WVHLT, 0, 0)) +end + +""" +This function transmits a chain of waveforms. + +!!! note + Any hardware PWM started by `hardware_PWM` will be cancelled. + +The waves to be transmitted are specified by the contents +of data which contains an ordered list of `wave_id`s +and optional command codes and related data. + +Returns 0 if OK, otherwise PI_CHAIN_NESTING, +PI_CHAIN_LOOP_CNT, PI_BAD_CHAIN_LOOP, PI_BAD_CHAIN_CMD, +PI_CHAIN_COUNTER, PI_BAD_CHAIN_DELAY, PI_CHAIN_TOO_BIG, +or PI_BAD_WAVE_ID. + +Each wave is transmitted in the order specified. A wave +may occur multiple times per chain. + +A blocks of waves may be transmitted multiple times by +using the loop commands. The block is bracketed by loop +start and end commands. Loops may be nested. + +Delays between waves may be added with the delay command. + +The following command codes are supported + +``` +Name @ Cmd & Data @ Meaning +Loop Start @ 255 0 @ Identify start of a wave block +Loop Repeat @ 255 1 x y @ loop x + y*256 times +Delay @ 255 2 x y @ delay x + y*256 microseconds +Loop Forever @ 255 3 @ loop forever +``` + +If present Loop Forever must be the last entry in the chain. + +The code is currently dimensioned to support a chain with +roughly 600 entries and 20 loop counters. + +```julia +#!/usr/bin/env python + +import time +import pigpio + +WAVES=5 +GPIO=4 + +wid=[0]*WAVES + +pi = pigpio.pi() # Connect to local Pi. + +set_mode(pi, GPIO, pigpio.OUTPUT); + +for i in range(WAVES) +pi.wave_add_generic([ +pigpio.pulse(1<