Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
B
buspirate-python
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Dorota Czaplejewicz
buspirate-python
Commits
8067d32f
Commit
8067d32f
authored
May 05, 2016
by
Juergen Hasch
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add tests, make API more Pythonic
parent
7948142d
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
535 additions
and
505 deletions
+535
-505
examples/spi_example.py
examples/spi_example.py
+5
-8
pyBusPirateLite/BBIO_base.py
pyBusPirateLite/BBIO_base.py
+7
-115
pyBusPirateLite/BitBang.py
pyBusPirateLite/BitBang.py
+99
-24
pyBusPirateLite/I2C.py
pyBusPirateLite/I2C.py
+11
-3
pyBusPirateLite/SPI.py
pyBusPirateLite/SPI.py
+113
-40
pyBusPirateLite/UART.py
pyBusPirateLite/UART.py
+34
-18
tests/bbio_test.py
tests/bbio_test.py
+0
-188
tests/test_bbio_base.py
tests/test_bbio_base.py
+83
-0
tests/test_bitbang.py
tests/test_bitbang.py
+39
-17
tests/test_common_functions.py
tests/test_common_functions.py
+0
-40
tests/test_i2c.py
tests/test_i2c.py
+57
-0
tests/test_spi.py
tests/test_spi.py
+30
-0
tests/test_uart.py
tests/test_uart.py
+57
-0
tests/testmode.py
tests/testmode.py
+0
-52
No files found.
examples/spi_example.py
View file @
8067d32f
...
...
@@ -2,18 +2,15 @@
# -*- coding: utf-8 -*-
# Example of SPI data transfer
from
pyBusPirateLite.SPI
import
SPI
,
CFG_PUSH_PULL
,
CFG_IDLE
from
pyBusPirateLite.BBIO_base
import
PIN_POWER
,
PIN_CS
from
pyBusPirateLite.SPI
import
*
spi
=
SPI
()
spi
.
outputs
=
PIN_POWER
|
PIN_CS
spi
.
state
=
PIN_POWER
|
PIN_CS
spi
.
config
=
CFG_PUSH_PULL
|
CFG_IDLE
spi
.
pins
=
PIN_POWER
|
PIN_CS
spi
.
config
=
CFG_PUSH_PULL
spi
.
speed
=
'1MHz'
# send two bytes and receive answer
spi
.
cs
=
True
data
=
spi
.
transfer
(
[
0x82
,
0x00
])
data
=
spi
.
transfer
(
[
0x82
,
0x55
])
spi
.
cs
=
False
print
(
ord
(
data
[
2
]))
spi
.
pins
=
PIN_CS
# turn off power
pyBusPirateLite/BBIO_base.py
View file @
8067d32f
...
...
@@ -86,6 +86,11 @@ class BBIO_base:
self
.
port
.
flushInput
()
for
i
in
range
(
20
):
self
.
write
(
0x00
)
r
=
self
.
response
(
1
,
True
)
if
r
:
break
self
.
port
.
flushInput
()
self
.
write
(
0x00
)
if
self
.
response
(
5
)
==
"BBIO1"
:
self
.
mode
=
'bb'
self
.
bp_config
=
0x00
# configuration bits determine action of power sources and pullups
...
...
@@ -97,34 +102,6 @@ class BBIO_base:
self
.
recurse_flush
(
self
.
enter
)
raise
BPError
(
'Could not enter bitbang mode'
)
def
reset
(
self
):
""" Reset to raw bitbang mode
Notes
-----
This command resets the Bus Pirate into raw bitbang mode from the user terminal. It also resets to raw bitbang
mode from raw SPI mode, or any other protocol mode. This command always returns a five byte bitbang version
string "BBIOx", where x is the current protocol version (currently 1).
Some terminals send a NULL character (0x00) on start-up, causing the Bus Pirate to enter binary mode when it
wasn't wanted. To get around this, you must now enter 0x00 at least 20 times to enter raw bitbang mode.
Note: The Bus Pirate user terminal could be stuck in a configuration menu when your program attempts to enter
binary mode. One way to ensure that you're at the command line is to send <enter> at least 10 times, and then
send '#' to reset. Next, send 0x00 to the command line 20+ times until you get the BBIOx version string.
After entering bitbang mode, you can enter other binary protocol modes.
Raises
-------
BPError
If bus pirate does not respond correctly
"""
self
.
port
.
flushInput
()
for
i
in
range
(
20
):
self
.
write
(
0x00
)
self
.
timeout
(
self
.
minDelay
*
10
)
if
self
.
response
(
5
)
==
"BBIO1"
:
self
.
port
.
flushInput
()
return
raise
ProtocolError
(
'Could not return to bitbang mode'
)
def
hw_reset
(
self
):
"""Reset Bus Pirate
...
...
@@ -187,6 +164,7 @@ class BBIO_base:
sleep
(
timeout
)
def
write
(
self
,
value
):
# print('val %s' % value.to_bytes(1, 'big'))
self
.
port
.
write
(
value
.
to_bytes
(
1
,
'big'
))
def
response
(
self
,
byte_count
=
1
,
binary
=
False
):
...
...
@@ -201,95 +179,10 @@ class BBIO_base:
"""
data
=
self
.
port
.
read
(
byte_count
)
if
binary
is
True
:
if
byte_count
==
1
:
print
(
'Response: %s'
%
ord
(
data
))
return
data
else
:
print
(
'Decoded response: %s'
%
data
)
return
data
.
decode
()
@
property
def
outputs
(
self
):
"""
Returns
-------
byte
Current state of the pins
PIN_AUX, PIN_MOSI, PIN_CLK, PIN_MISO, PIN_CS
"""
self
.
write
(
0x40
|
~
self
.
pins_direction
&
0x1f
)
# map input->1, output->0
self
.
timeout
(
self
.
minDelay
*
10
)
return
ord
(
self
.
response
(
1
,
True
))
&
0x1f
@
outputs
.
setter
def
outputs
(
self
,
pinlist
=
0
):
""" Configure pins as input our output
Notes
-----
The Bus pirate responds to each direction update with a byte showing the current state of the pins, regardless
of direction. This is useful for open collector I/O modes. Used in every mode to configure pins.
In bb it configures as either input or output, in the other modes it normally configures peripherals such as
power supply and the aux pin
Parameters
----------
pinlist : byte
List of pins to be set as outputs (default: all inputs)
PIN_AUX, PIN_MOSI, PIN_CLK, PIN_MISO, PIN_CS
Returns
-------
byte
Current state of the pins
PIN_AUX, PIN_MOSI, PIN_CLK, PIN_MISO, PIN_CS
"""
self
.
pins_direction
=
pinlist
&
0x1f
self
.
write
(
0x40
|
~
self
.
pins_direction
&
0x1f
)
# map input->1, output->0
self
.
timeout
(
self
.
minDelay
*
10
)
return
ord
(
self
.
response
(
1
,
True
))
&
0x1f
@
property
def
pins
(
self
):
""" Get pins status
Returns
-------
byte
Current state of the pins
PIN_POWER, PIN_PULLUP, PIN_AUX, PIN_MOSI, PIN_CLK, PIN_MISO, PIN_CS
"""
self
.
write
(
0x80
|
self
.
pins_state
&
0x7f
)
self
.
timeout
(
self
.
minDelay
*
10
)
self
.
pins_state
=
ord
(
self
.
response
(
1
,
True
))
&
0x7f
return
self
.
pins_state
@
pins
.
setter
def
pins
(
self
,
pinlist
=
0
):
""" Set pins to high or low
Notes
-----
The lower 7bits of the command byte control the Bus Pirate pins and peripherals.
Bitbang works like a player piano or bitmap. The Bus Pirate pins map to the bits in the command byte as follows:
1|POWER|PULLUP|AUX|MOSI|CLK|MISO|CS
The Bus pirate responds to each update with a byte in the same format that shows the current state of the pins.
Parameters
----------
pinlist : byte
List of pins to be set high
PIN_POWER, PIN_PULLUP, PIN_AUX, PIN_MOSI, PIN_CLK, PIN_MISO, PIN_CS
"""
self
.
pins_state
=
pinlist
&
0x7f
self
.
write
(
0x80
|
self
.
pins_state
)
self
.
timeout
(
self
.
minDelay
*
10
)
self
.
pins_state
=
ord
(
self
.
response
(
1
,
True
))
&
0x7f
_attempts_
=
0
def
recurse_end
(
self
):
self
.
_attempts_
=
0
...
...
@@ -337,7 +230,6 @@ def send_stop_bit(self):
def
read_byte
(
self
):
"""Reads a byte from the bus, returns the byte. You must ACK or NACK each
byte manually. NO ERROR CHECKING (obviously)"""
self
.
check_mode
(
not_bb
)
if
self
.
mode
==
'raw'
:
self
.
write
(
0x06
)
return
self
.
response
(
1
,
True
)
# this was changed, before it didn't have the 'True' which means it
...
...
@@ -357,7 +249,7 @@ def bulk_trans(self, byte_count=1, byte_string=None):
In modes other than I2C I think it returns whatever data it gets while
sending, but this feature is untested. PLEASE REPORT so that I can
document it."""
self
.
check_mode
(
not_bb
)
#
self.check_mode(not_bb)
if
byte_string
is
None
:
pass
self
.
write
(
0x10
|
(
byte_count
-
1
))
...
...
pyBusPirateLite/BitBang.py
View file @
8067d32f
...
...
@@ -26,7 +26,7 @@ import serial
from
.BBIO_base
import
BBIO_base
,
BPError
,
ProtocolError
class
BitBang
(
BBIO_base
):
def
__init__
(
self
,
portname
=
''
,
speed
=
115200
,
timeout
=
1
):
def
__init__
(
self
,
portname
=
''
,
speed
=
115200
,
timeout
=
1
,
connect
=
True
):
""" Provide access to the Bus Pirate bitbang mode
Parameters
...
...
@@ -43,8 +43,89 @@ class BitBang(BBIO_base):
>>> bb = BitBang()
"""
super
().
__init__
()
self
.
connect
(
portname
,
speed
,
timeout
)
self
.
enter
()
if
connect
is
True
:
self
.
connect
(
portname
,
speed
,
timeout
)
self
.
enter
()
@
property
def
outputs
(
self
):
"""
Returns
-------
byte
Current state of the pins
PIN_AUX, PIN_MOSI, PIN_CLK, PIN_MISO, PIN_CS
"""
self
.
write
(
0x40
|
~
self
.
pins_direction
&
0x1f
)
# map input->1, output->0
self
.
timeout
(
self
.
minDelay
*
10
)
return
ord
(
self
.
response
(
1
,
True
))
&
0x1f
@
outputs
.
setter
def
outputs
(
self
,
pinlist
=
0
):
""" Configure pins as input our output
Notes
-----
The Bus pirate responds to each direction update with a byte showing the current state of the pins, regardless
of direction. This is useful for open collector I/O modes. Used in every mode to configure pins.
In bb it configures as either input or output, in the other modes it normally configures peripherals such as
power supply and the aux pin
Parameters
----------
pinlist : byte
List of pins to be set as outputs (default: all inputs)
PIN_AUX, PIN_MOSI, PIN_CLK, PIN_MISO, PIN_CS
Returns
-------
byte
Current state of the pins
PIN_AUX, PIN_MOSI, PIN_CLK, PIN_MISO, PIN_CS
"""
self
.
pins_direction
=
pinlist
&
0x1f
self
.
write
(
0x40
|
~
self
.
pins_direction
&
0x1f
)
# map input->1, output->0
self
.
timeout
(
self
.
minDelay
*
10
)
self
.
response
(
1
,
True
)
@
property
def
pins
(
self
):
""" Get pins status
Returns
-------
byte
Current state of the pins
PIN_POWER, PIN_PULLUP, PIN_AUX, PIN_MOSI, PIN_CLK, PIN_MISO, PIN_CS
"""
self
.
write
(
0x80
|
(
self
.
pins_state
&
0x7f
))
self
.
timeout
(
self
.
minDelay
*
10
)
self
.
pins_state
=
ord
(
self
.
response
(
1
,
True
))
&
0x7f
return
self
.
pins_state
@
pins
.
setter
def
pins
(
self
,
pinlist
=
0
):
""" Set pins to high or low
Notes
-----
The lower 7bits of the command byte control the Bus Pirate pins and peripherals.
Bitbang works like a player piano or bitmap. The Bus Pirate pins map to the bits in the command byte as follows:
1|POWER|PULLUP|AUX|MOSI|CLK|MISO|CS
The Bus pirate responds to each update with a byte in the same format that shows the current state of the pins.
Parameters
----------
pinlist : byte
List of pins to be set high
PIN_POWER, PIN_PULLUP, PIN_AUX, PIN_MOSI, PIN_CLK, PIN_MISO, PIN_CS
"""
self
.
pins_state
=
pinlist
&
0x7f
self
.
write
(
0x80
|
self
.
pins_state
)
self
.
timeout
(
self
.
minDelay
*
10
)
self
.
pins_state
=
ord
(
self
.
response
(
1
,
True
))
&
0x7f
@
property
def
adc
(
self
):
...
...
@@ -58,6 +139,7 @@ class BitBang(BBIO_base):
self
.
write
(
0x14
)
self
.
timeout
(
self
.
minDelay
)
ret
=
self
.
response
(
2
,
True
)
print
(
'0: %d, 1: %d'
%
(
ret
[
0
],
ret
[
1
]))
voltage
=
(
ret
[
0
]
<<
8
)
+
ret
[
1
]
voltage
=
(
voltage
*
6.6
)
/
1024
return
voltage
...
...
@@ -137,8 +219,8 @@ class BitBang(BBIO_base):
raise
ProtocolError
(
'Self test did not return to bitbang mode'
)
return
ord
(
errors
)
def
set_pwm_frequency
(
self
,
frequency
,
dutycycle
=
.
5
):
"""
set PWM frequency and duty cycle.
def
enable_PWM
(
self
,
frequency
,
dutycycle
=
.
5
):
"""
Enable PWM output
Parameters
----------
...
...
@@ -149,10 +231,16 @@ class BitBang(BBIO_base):
Notes
-----
Stolen from http://codepad.org/qtYpZmIF
Configure and enable pulse-width modulation output in the AUX pin. Requires a 5 byte configuration sequence.
Responds 0x01 after a complete sequence is received. The PWM remains active after leaving binary bitbang mode!
Equations to calculate the PWM frequency and period are in the PIC24F output compare manual.
Bit 0 and 1 of the first configuration byte set the prescaler value. The Next two bytes set the duty cycle
register, high 8bits first. The final two bytes set the period register, high 8bits first.
Parameter calculation stolen from http://codepad.org/qtYpZmIF
"""
if
DutyC
ycle
>
1
:
if
dutyc
ycle
>
1
:
raise
ValueError
(
'Duty cycle should be between 0 and 1'
)
Fosc
=
24e6
Tcy
=
2.0
/
Fosc
...
...
@@ -165,30 +253,17 @@ class BitBang(BBIO_base):
Prescaler
=
PrescalerList
[
n
]
PRy
=
PwmPeriod
*
1.0
/
(
Tcy
*
Prescaler
)
PRy
=
int
(
PRy
-
1
)
OCR
=
int
(
PRy
*
DutyC
ycle
)
OCR
=
int
(
PRy
*
dutyc
ycle
)
if
PRy
<
(
2
**
16
-
1
):
break
# valid value for PRy, keep values
else
:
raise
ValueError
(
'frequency requested is invalid'
)
if
self
.
setup_PWM
(
prescaler
=
Prescaler
,
dutycycle
=
OCR
,
period
=
PRy
):
self
.
recurse_end
()
return
1
return
self
.
recurse
(
self
.
set_pwm_frequency
,
frequency
,
DutyCycle
)
def
setup_PWM
(
self
,
prescaler
,
dutycycle
,
period
):
""" Setup pulse-width modulation
prescaler
=
Prescaler
dutycycle
=
OCR
period
=
PRy
Notes
-----
Configure and enable pulse-width modulation output in the AUX pin. Requires a 5 byte configuration sequence.
Responds 0x01 after a complete sequence is received. The PWM remains active after leaving binary bitbang mode!
Equations to calculate the PWM frequency and period are in the PIC24F output compare manual.
Bit 0 and 1 of the first configuration byte set the prescaler value. The Next two bytes set the duty cycle
register, high 8bits first. The final two bytes set the period register, high 8bits first.
"""
self
.
write
(
0x12
)
self
.
write
(
prescaler
)
self
.
write
((
dutycycle
>>
8
)
&
0xFF
)
...
...
pyBusPirateLite/I2C.py
View file @
8067d32f
...
...
@@ -35,7 +35,7 @@ pin_mapping = {'AUX': 0b10,
class
I2C
(
BBIO_base
):
def
__init__
(
self
,
portname
=
''
,
speed
=
115200
,
timeout
=
1
):
def
__init__
(
self
,
portname
=
''
,
speed
=
115200
,
timeout
=
1
,
connect
=
True
):
""" Provide access to the Bus Pirate I2C interface
Parameters
...
...
@@ -53,8 +53,9 @@ class I2C(BBIO_base):
>>> i2c.speed = '400kHz'
"""
super
().
__init__
()
self
.
connect
(
portname
,
speed
,
timeout
)
self
.
enter
()
if
connect
is
True
:
self
.
connect
(
portname
,
speed
,
timeout
)
self
.
enter
()
def
enter
(
self
):
""" Enter I2C mode
...
...
@@ -185,6 +186,13 @@ class I2C(BBIO_base):
@
property
def
speed
(
self
):
""" Return current I2C clock speed
Returns
-------
str
I2C clock speed (5kHz, 50kHz, 100kHz, 400kHz)
"""
return
self
.
i2c_speed
@
speed
.
setter
...
...
pyBusPirateLite/SPI.py
View file @
8067d32f
...
...
@@ -42,9 +42,14 @@ CFG_CLK_EDGE = 0x02
CFG_IDLE
=
0x04
CFG_PUSH_PULL
=
0x08
PIN_CS
=
1
PIN_AUX
=
2
PIN_PULLUP
=
4
PIN_POWER
=
8
class
SPI
(
BBIO_base
):
def
__init__
(
self
,
portname
=
''
,
speed
=
115200
,
timeout
=
1
):
def
__init__
(
self
,
portname
=
''
,
speed
=
115200
,
timeout
=
1
,
connect
=
True
):
""" Provide high-speed access to the Bus Pirate SPI hardware
Parameters
...
...
@@ -59,7 +64,6 @@ class SPI(BBIO_base):
Example
-------
>>> spi = SPI()
>>> spi.state = PIN_POWER | PIN_CS
>>> spi.config(CFG_PUSH_PULL | CFG_IDLE)
>>> spi.speed = '1MHz'
>>> spi.cs = True
...
...
@@ -67,12 +71,16 @@ class SPI(BBIO_base):
>>> spi.cs = False
"""
super
().
__init__
()
self
.
connect
(
portname
,
speed
,
timeout
)
self
.
enter
()
self
.
spi_config
=
None
if
connect
is
True
:
self
.
connect
(
portname
,
speed
,
timeout
)
self
.
enter
()
self
.
_config
=
None
self
.
_speed
=
None
self
.
_cs
=
None
self
.
_pins
=
None
def
enter
(
self
):
"""Enter raw SPI mode
"""
Enter raw SPI mode
Once in raw bitbang mode, send 0x01 to enter raw SPI mode. The Bus Pirate responds 'SPIx',
where x is the raw SPI protocol version (currently 1). Get the version string at any time by sending 0x01 again.
...
...
@@ -89,8 +97,6 @@ class SPI(BBIO_base):
self
.
timeout
(
self
.
minDelay
*
10
)
if
self
.
response
(
4
)
==
"SPI1"
:
self
.
mode
=
'spi'
self
.
bp_port
=
0b00
# two bit port
self
.
bp_config
=
0b0000
self
.
recurse_end
()
return
self
.
recurse_flush
(
self
.
enter
)
...
...
@@ -103,9 +109,37 @@ class SPI(BBIO_base):
self
.
timeout
(
self
.
minDelay
*
10
)
return
self
.
response
(
4
)
@
property
def
pins
(
self
):
return
self
.
_pins
@
pins
.
setter
def
pins
(
self
,
cfg
):
""" Configure peripherals
Parameters
----------
cfg: int
Pin configuration 0000wxyz
w=power, x=pull-ups, y=AUX, z=CS
Notes
-----
Enable (1) and disable (0) Bus Pirate peripherals and pins. Bit w enables the power supplies, bit x toggles
the on-board pull-up resistors, y sets the state of the auxiliary pin, and z sets the chip select pin.
Features not present in a specific hardware version are ignored. Bus Pirate responds 0x01 on success.
* CS pin always follows the current HiZ pin configuration.
* AUX is always a normal pin output (0=GND, 1=3.3volts).
"""
self
.
write
(
0x40
|
(
cfg
&
0x0f
))
if
self
.
response
(
1
,
True
)
!=
b'
\x01
'
:
raise
ValueError
(
"Could not set SPI pins"
)
self
.
_pins
=
cfg
@
property
def
config
(
self
):
return
self
.
spi
_config
return
self
.
_config
@
config
.
setter
def
config
(
self
,
cfg
):
...
...
@@ -123,7 +157,7 @@ class SPI(BBIO_base):
----------
cfg : byte
CFG_SAMPLE: sample time (0 = middle)
CFG_CLK_EDGE: clock edge (1 = active to idle
CFG_CLK_EDGE: clock edge (1 = active to idle
)
CFG_IDLE: clock idle phase (0 = low)
CFG_PUSH_PULL: pin output (0 = HiZ, 1 = push-pull)
...
...
@@ -137,10 +171,10 @@ class SPI(BBIO_base):
If configuration could not be set
"""
self
.
write
(
0x80
|
cfg
)
self
.
timeout
(
0.1
)
if
self
.
response
(
1
,
True
)
!=
'
\x01
'
:
self
.
timeout
(
self
.
minDelay
)
if
self
.
response
(
1
,
True
)
!=
b
'
\x01
'
:
raise
ValueError
(
"Could not set SPI configuration"
)
self
.
spi
_config
=
cfg
self
.
_config
=
cfg
def
transfer
(
self
,
txdata
):
""" Bulk SPI transfer, send/read 1-16 bytes
...
...
@@ -179,8 +213,10 @@ class SPI(BBIO_base):
self
.
write
(
0x10
+
length
-
1
)
for
data
in
txdata
:
self
.
write
(
data
)
if
self
.
response
(
1
,
True
)
!=
'
\x01
'
:
if
self
.
response
(
1
,
True
)
!=
b
'
\x01
'
:
raise
ValueError
(
"Could not transfer SPI data"
)
rxdata
=
self
.
response
(
length
,
True
)
return
rxdata
def
write_then_read
(
self
,
numtx
,
numrx
,
txdata
,
cs
=
True
):
""" Write then read
...
...
@@ -243,16 +279,17 @@ class SPI(BBIO_base):
self
.
write
(
numrx
&
0xff
)
for
data
in
txdata
:
self
.
write
(
data
)
if
self
.
response
(
1
,
True
)
!=
'
\x01
'
:
if
self
.
response
(
1
,
True
)
!=
b
'
\x01
'
:
raise
ProtocolError
(
"Error transmitting data"
)
@
property
def
cs
(
self
):
""" Return chip select pin status """
return
self
.
_cs
@
cs
.
setter
def
cs
(
self
,
value
):
"""
"""
Set chip select pin
Parameters
----------
value: bool
...
...
@@ -267,37 +304,73 @@ class SPI(BBIO_base):
self
.
write
(
0x02
)
else
:
self
.
write
(
0x03
)
if
self
.
response
(
1
,
True
)
!=
'
\x01
'
:
if
self
.
response
(
1
,
True
)
!=
b
'
\x01
'
:
raise
ProtocolError
(
"CS could not be set"
)
self
.
_cs
=
value
@
property
def
speed
(
self
):
return
self
.
_speed
@
speed
.
setter
def
speed
(
self
,
frequency
):
""" Set SPI bus speed
Parameters
----------
frequency : str
SPI clock speed (30kHz, 125kHz, 250kHz, 1MHz, 2MHz, 2.6MHz, 4MHz, 8MHz)
Raises
------
ProtocolError
If I2C speed could not be set
"""
try
:
clock
=
SPI_speed
[
frequency
]
except
KeyError
:
raise
ValueError
(
'Clock speed not supported'
)
self
.
write
(
0x60
|
clock
)
@
property
def
speed
(
self
):
return
self
.
spi_speed
if
self
.
response
(
1
,
True
)
!=
b'
\x01
'
:
raise
ProtocolError
(
'Could not set SPI speed'
)
self
.
_speed
=
frequency
def
sniffer
(
self
,
cs
):
""" Sniff SPI traffic when CS low(10)/all(01) TODO
@
speed
.
setter
def
speed
(
self
,
frequency
):
""" Set SPI speed
Parameters
----------
cs : Bool
True: Capture when CS is low
False: Capture all
Notes
-----
0000 11XX
The SPI sniffer is implemented in hardware and should work up to 10MHz. It follows the configuration settings
you entered for SPI mode. The sniffer can read all traffic, or filter by the state of the CS pin.
[/] - CS enable/disable
xy - escape character (
\\
) precedes two byte values X (MOSI pin) and Y (MISO pin) (updated in v5.1)
Parameters
----------
frequency : str
SPI clock speed (30kHz, 125kHz, 250kHz, 1MHz, 2MHz, 2.6MHz, 4MHz, 8MHz)
Sniffed traffic is encoded according to the table above. The two data bytes are escaped with the '
\'
character
to help locate data in the stream.
Raises
------
ProtocolError
If I2C speed could not be set
"""
try
:
clock
=
SPI_speed
[
frequency
]
except
KeyError
:
raise
ValueError
(
'Clock speed not supported'
)
self
.
write
(
0x60
|
clock
)
Send the SPI sniffer command to start the sniffer, the Bus Pirate responds 0x01 then sniffed data starts to
flow. Send any byte to exit. Bus Pirate responds 0x01 on exit. (0x01 reply location was changed in v5.8)
if
self
.
response
(
1
,
True
)
!=
0x01
:
raise
ProtocolError
(
'Could not set SPI speed'
)
self
.
spi_speed
=
frequency
If the sniffer can't keep with the SPI data, the MODE LED turns off and the sniff is aborted. (new in v5.1)
The sniffer follows the output clock edge and output polarity settings of the SPI mode, but not the input
sample phase.
More detailed notes on the SPI sniffer in the SPI user terminal documentation.
"""
if
cs
is
True
:
cmd
=
0x0e
else
:
cmd
=
0x0d
self
.
write
(
cmd
)
if
self
.
response
(
1
,
True
)
!=
b'
\x01
'
:
raise
ProtocolError
(
'Could not set SPI sniff mode'
)
pyBusPirateLite/UART.py
View file @
8067d32f
...
...
@@ -23,7 +23,7 @@ You should have received a copy of the GNU General Public License
along with pyBusPirate. If not, see <http://www.gnu.org/licenses/>.
"""
from
.BBIO_base
import
BBIO_base
,
BPError
,
ProtocolError
from
.BBIO_base
import
BBIO_base
,
BPError
FOSC
=
(
32000000
/
2
)
...
...
@@ -68,10 +68,11 @@ class UART(BBIO_base):
super
().
__init__
()
self
.
connect
(
portname
,
speed
,
timeout
)
self
.
enter
()
self
.
uart_config
=
None
self
.
_config
=
None
self
.
_echo
=
False
def
enter
(
self
):
"""
"""
Enter UART mode
Raises
------
...
...
@@ -80,9 +81,6 @@ class UART(BBIO_base):
"""
if
self
.
mode
==
'uart'
:
return
if
self
.
mode
!=
'bb'
:
super
().
enter
()
self
.
write
(
0x03
)
self
.
timeout
(
self
.
minDelay
*
10
)
if
self
.
response
(
4
)
==
"ART1"
:
...
...
@@ -90,10 +88,30 @@ class UART(BBIO_base):
self
.
bp_port
=
0b00
# two bit port
self
.
bp_config
=
0b0000
self
.
recurse_end
()
return
1
return
self
.
recurse_flush
(
self
.
enter
)
raise
BPError
(
'Could not enter UART mode'
)
@
property
def
modestring
(
self
):
""" Return mode version string """
self
.
write
(
0x01
)
self
.
timeout
(
self
.
minDelay
*
10
)
return
self
.
response
(
4
)
@
property
def
echo
(
self
):
return
self
.
_echo
@
echo
.
setter
def
echo
(
self
,
mode
):
if
mode
is
True
:
self
.
write
(
0x03
)
else
:
self
.
write
(
0x02
)
if
self
.
response
(
1
,
True
)
!=
'
\x01
'
:
raise
ValueError
(
"Could not set echo mode"
)
self
.
_echo
=
mode
def
manual_speed_cfg
(
self
,
baud
):
""" Manual baud rate configuration, send 2 bytes
...
...
@@ -104,38 +122,36 @@ class UART(BBIO_base):
Use the UART manual [PDF] or an online calculator to find the correct value (key values: fosc 32mHz,
clock divider = 2, BRGH=1) . Bus Pirate responds 0x01 to each byte. Settings take effect immediately.
"""
if
self
.
mode
==
'uart'
:
raise
BPError
(
'Not in UART mode'
)
BRG
=
((
FOSC
)
/
(
4
*
baud
))
-
1
BRG
=
(
FOSC
/
(
4
*
baud
))
-
1
BRGH
=
((
BRG
>>
8
)
&
0xFF
)
BRGL
=
(
BRG
&
0xFF
)
self
.
port
.
write
(
chr
(
0x02
)
)
self
.
port
.
write
(
chr
(
BRGH
)
)
self
.
port
.
write
(
chr
(
BRGL
)
)
self
.
write
(
0x03
)
self
.
write
(
BRGH
)
self
.
write
(
BRGL
)
self
.
timeout
(
0.1
)
return
self
.
response
()
def
begin_input
(
self
):
self
.
port
.
write
(
chr
(
0x04
)
)
self
.
write
(
0x04
)