Removed test suite. Fixed links in main README.
This commit is contained in:
parent
f8ded46ad6
commit
a9d2bfada4
@ -24,7 +24,7 @@ env:
|
||||
- TRAVIS_TESTS="unix docs translations website" TRAVIS_BOARDS="feather_huzzah circuitplayground_express grandcentral_m4_express pca10056 pca10059 feather_nrf52832 feather_nrf52840_express makerdiary_nrf52840_mdk" TRAVIS_SDK=arm:nrf:esp8266
|
||||
- TRAVIS_BOARDS="metro_m0_express metro_m4_express pirkey_m0 trellis_m4_express trinket_m0" TRAVIS_SDK=arm
|
||||
- TRAVIS_BOARDS="feather_radiofruit_zigbee gemma_m0 hallowing_m0_express itsybitsy_m0_express itsybitsy_m4_express meowmeow" TRAVIS_SDK=arm
|
||||
- TRAVIS_BOARDS="feather_m0_express_crickit feather_m0_rfm69 feather_m0_rfm9x feather_m4_express arduino_zero arduino_mkr1300" TRAVIS_SDK=arm
|
||||
- TRAVIS_BOARDS="feather_m0_express_crickit feather_m0_rfm69 feather_m0_rfm9x feather_m4_express arduino_zero arduino_mkr1300 arduino_mkrzero" TRAVIS_SDK=arm
|
||||
- TRAVIS_BOARDS="circuitplayground_express_crickit feather_m0_adalogger feather_m0_basic feather_m0_express catwan_usbstick" TRAVIS_SDK=arm
|
||||
|
||||
addons:
|
||||
|
@ -60,13 +60,15 @@ Other
|
||||
supported using the `Adafruit CircuitPython SD
|
||||
library <https://github.com/adafruit/Adafruit_CircuitPython_SD>`__)
|
||||
- `Arduino Zero <https://www.arduino.cc/en/Main/ArduinoBoardZero>`__
|
||||
- `Arduino MKR Zero <https://store.arduino.cc/arduino-mkrzero>`
|
||||
- `Arduino MKR Zero <https://store.arduino.cc/arduino-mkrzero>`__ (MicroSD card
|
||||
supported using the `Adafruit CircuitPython SD
|
||||
library <https://github.com/adafruit/Adafruit_CircuitPython_SD>`__)
|
||||
|
||||
"Third-party" or "non-Adafruit" boards
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- `Electronic Cats Meow Meow <https://electroniccats.com/gomeow/>`__
|
||||
- `Electronic Cats CatWAN USB Stick <https://electroniccats.com/producto/catwan_usb_stick/>`
|
||||
- `Electronic Cats CatWAN USB Stick <https://electroniccats.com/producto/catwan_usb_stick/>`__
|
||||
|
||||
Download
|
||||
--------
|
||||
|
@ -1,57 +0,0 @@
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
Board test suite for CircuitPython. Run these tests to ensure that a CircuitPython port was created correctly, individual pin mappings are correct, and buses (e.g. SPI) work.
|
||||
|
||||
Tests can be run individually. Copy code found in each *<name>_test.py* module (found in *source* directory) to main.py in your CIRCUITPYTHON device drive.
|
||||
|
||||
Alternatively, tests can be imported as modules. Copy the *lib* directory to CIRCUITPYTHON device drive and import the test in your own code. Each test can be run with the `run_test(pins)` function.
|
||||
|
||||
The *main.py* example shows how to call tests from within a script. *main.py* runs the following tests:
|
||||
|
||||
* LED Test
|
||||
* GPIO Test
|
||||
* Voltage Monitor Test
|
||||
* UART Test
|
||||
* SPI Test
|
||||
* I2C Test
|
||||
|
||||
Dependencies
|
||||
=============
|
||||
|
||||
This test suite depends on:
|
||||
|
||||
* `Adafruit CircuitPython <https://github.com/adafruit/circuitpython>`_
|
||||
* `SD Card <https://github.com/adafruit/Adafruit_CircuitPython_SD>`_
|
||||
* `Bus Device <https://github.com/adafruit/Adafruit_CircuitPython_BusDevice>`_
|
||||
|
||||
Please ensure all dependencies are available on the CircuitPython filesystem.
|
||||
This is easily achieved by downloading
|
||||
`the Adafruit library and driver bundle <https://github.com/adafruit/Adafruit_CircuitPython_Bundle>`_.
|
||||
|
||||
Usage Example
|
||||
=============
|
||||
|
||||
You will need the following components:
|
||||
|
||||
* Multimeter
|
||||
* LED
|
||||
* 1x 330 Ohm resistor
|
||||
* 2x 4.7k Ohm resistor
|
||||
* Microchip 25AA040A SPI EEPROM
|
||||
* Microchip AT24HC04B I2C EEPROM
|
||||
* Breadboard
|
||||
* Wires
|
||||
|
||||
Connect the components as shown to your board.
|
||||
|
||||
.. image:: docs/test_jig.png
|
||||
:alt: Test jig Fritzing diagram
|
||||
|
||||
Copy the *lib* folder to the CIRCUITPYTHON drive. Copy *main.py* to the root directory of your CIRCUITPYTHON drive. Open a Serial terminal and connect to the board. Follow the directions given to run through the tests.
|
||||
|
||||
Building
|
||||
========
|
||||
|
||||
Individual test modules can be built with the mpy-cross cross-compiler. This is required to save RAM space if you plan to run more than one test at a time. See `the mpy-cross directory in circuitpython <https://github.com/adafruit/circuitpython/tree/master/mpy-cross>`_ to learn more.
|
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 164 KiB |
Binary file not shown.
Before Width: | Height: | Size: 146 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,235 +0,0 @@
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2018 Shawn Hymel for Adafruit Industries
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
"""
|
||||
`board_test_suite`
|
||||
====================================================
|
||||
CircuitPython board hardware test suite
|
||||
|
||||
* Author(s): Shawn Hymel
|
||||
* Date: December 8, 2018
|
||||
|
||||
Implementation Notes
|
||||
--------------------
|
||||
Run this to test various input/output abilities of a board. Tests the following:
|
||||
|
||||
* Onboard LEDs
|
||||
* GPIO output
|
||||
* Onboard battery voltage monitor
|
||||
* SPI
|
||||
* I2C
|
||||
|
||||
You will need the following components:
|
||||
|
||||
* Multimeter
|
||||
* LED
|
||||
* 1x 330 Ohm resistor
|
||||
* 2x 4.7k Ohm resistor
|
||||
* Microchip 25AA040A SPI EEPROM
|
||||
* Microchip AT24HC04B I2C EEPROM
|
||||
* Breadboard
|
||||
* Wires
|
||||
|
||||
Copy lib directory to CIRCUITPYTHON drive. Copy the contents of this file to
|
||||
main.py in root of CIRCUITPYTHON. Open Serial terminal to board and follow
|
||||
prompts given.
|
||||
"""
|
||||
|
||||
import board
|
||||
|
||||
import led_test
|
||||
import gpio_test
|
||||
import voltage_monitor_test
|
||||
import uart_test
|
||||
import spi_test
|
||||
import i2c_test
|
||||
|
||||
# Constants
|
||||
UART_TX_PIN_NAME = 'TX'
|
||||
UART_RX_PIN_NAME = 'RX'
|
||||
UART_BAUD_RATE = 9600
|
||||
SPI_MOSI_PIN_NAME = 'MOSI'
|
||||
SPI_MISO_PIN_NAME = 'MISO'
|
||||
SPI_SCK_PIN_NAME = 'SCK'
|
||||
SPI_CS_PIN_NAME = 'D2'
|
||||
I2C_SDA_PIN_NAME = 'SDA'
|
||||
I2C_SCL_PIN_NAME = 'SCL'
|
||||
|
||||
# Results dictionary
|
||||
test_results = {}
|
||||
|
||||
# Save tested pins
|
||||
pins_tested = []
|
||||
|
||||
# Print welcome message
|
||||
print()
|
||||
print(" .... ")
|
||||
print(" #@@%%%%%%&@@/ ")
|
||||
print(" (&@%%%%%%%%%%%%%@& ")
|
||||
print(" .(@&%%%@* *&%%%%%%@. ")
|
||||
print(" ,@@&&%%%%%%%%//@%,/ /&%%%%%%@ ")
|
||||
print(" %@%%%&%%%%%%%#(@@@&&%%%%%%%%@* ")
|
||||
print(" @&%%&%%%%%%%%%%%%%%%%%%%%%%@/ ")
|
||||
print(" &@@&%%%%&&&%%%%%%%%%%%%%%@, ")
|
||||
print(" ,/ &@&&%%%%%%%%%%%%%%%%%@ ")
|
||||
print(" ,* *@&%%%%%%%%%%%%# ")
|
||||
print(" ( @%%%%%%%%%%%@ ")
|
||||
print(" , @%%%%%%%%%%&@ ")
|
||||
print(" #&%%%%%%%%%%@. ")
|
||||
print(" #@###%%%%%%%@/ ")
|
||||
print(" (@##(%%%%%%%@% ")
|
||||
print(" /@###(#%%%%%&@ ")
|
||||
print(" #@####%%%%%%%@ ")
|
||||
print(" (@###(%%%%%%%@, ")
|
||||
print(" .@##(((#%%%%%&( .,,. ")
|
||||
print(" ,@#####%%%%%%%@ ,%@@%%%%%%%&@% ")
|
||||
print(" ,#&@####(%%%%%%%@@@@@&%%%%%%%%%%%###& ")
|
||||
print(" @%%@%####(#%%%%%&@%%%%%%%%%%%%%%##/((@@@@&* ")
|
||||
print(" (##@%#####%%%%%%%@(#%%%(/####(/####(%@%%%%%%@/ ")
|
||||
print(" (@&%@@###(#%%%%%%@&/####(/#####/#&@@&%%%%%%%##@ ")
|
||||
print(" #@%%%%@#####(#%%%%%%@@@@@@@@@@@@@&%%%%%%%%%%%%#/(@@@@@/ ")
|
||||
print(" @%(/#@%######%%%%%%%@%%%%%%%%%%%%%%%%%%%%%(/(###@%%%%%%@% ")
|
||||
print(" .@@#(#@#####(#%%%%%%&@###//#####/#####/(####/#%@&%%%%%%%%&& ")
|
||||
print(" /@%%&@@@(#((((#%%%%%%&@###((#####/#####((##%@@&%%%%%%%%%%%/@. ")
|
||||
print(" ,@%%%%%%#####%%%%%%%%@@@@&&&&&&&%&@@@@@@&%%%%%%%%%%%%%%%##@, ")
|
||||
print(" %%%%%%%%@######(%%%%%%%@&%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%#/(#&& ")
|
||||
print(" (@###/(%@##((##(%%%%%%%%@%%%%%%%%%%%%%%%%%%%%%%%%%##%###/(&& ")
|
||||
print(" ,@@%@%##((#%@#######%%%%%%%%@&%%%%##%%%%##%%%%#/#####((####(@* ")
|
||||
print(" *&(, %@@%##%@#######(%%%%%%%%@#/#####((#####(#####(/#&@&. ")
|
||||
print(" .@###((#%%%%%%%%%&@@###((#####(###%@@&, ")
|
||||
print(" #@#(#######%&@@&* .*#&@@@@@@@%(, ")
|
||||
print(" .,,,.. ")
|
||||
print()
|
||||
print("**********************************************************************")
|
||||
print("* Welcome to the CircuitPython board test suite! *")
|
||||
print("* Follow the directions to run each test. *")
|
||||
print("**********************************************************************")
|
||||
print()
|
||||
|
||||
# List out all the pins available to us
|
||||
pins = [p for p in dir(board)]
|
||||
print("All pins found:", end=' ')
|
||||
|
||||
# Print pins
|
||||
for p in pins:
|
||||
print(p, end=' ')
|
||||
print('\n')
|
||||
|
||||
# Run LED test
|
||||
print("@)}---^----- LED TEST -----^---{(@")
|
||||
print()
|
||||
result = led_test.run_test(pins)
|
||||
test_results["LED Test"] = result[0]
|
||||
pins_tested.append(result[1])
|
||||
print()
|
||||
print(result[0])
|
||||
print()
|
||||
|
||||
# Run GPIO test
|
||||
print("@)}---^----- GPIO TEST -----^---{(@")
|
||||
print()
|
||||
result = gpio_test.run_test(pins)
|
||||
test_results["GPIO Test"] = result[0]
|
||||
pins_tested.append(result[1])
|
||||
print()
|
||||
print(result[0])
|
||||
print()
|
||||
|
||||
# Run voltage monitor test
|
||||
print("@)}---^----- VOLTAGE MONITOR TEST -----^---{(@")
|
||||
print()
|
||||
result = voltage_monitor_test.run_test(pins)
|
||||
test_results["Voltage Monitor Test"] = result[0]
|
||||
pins_tested.append(result[1])
|
||||
print()
|
||||
print(result[0])
|
||||
print()
|
||||
|
||||
# Run UART test
|
||||
print("@)}---^----- UART TEST -----^---{(@")
|
||||
print()
|
||||
result = uart_test.run_test(pins, UART_TX_PIN_NAME, UART_RX_PIN_NAME, UART_BAUD_RATE)
|
||||
test_results["UART Test"] = result[0]
|
||||
pins_tested.append(result[1])
|
||||
print()
|
||||
print(result[0])
|
||||
print()
|
||||
|
||||
# Run SPI test
|
||||
print("@)}---^----- SPI TEST -----^---{(@")
|
||||
print()
|
||||
result = spi_test.run_test( pins,
|
||||
mosi_pin=SPI_MOSI_PIN_NAME,
|
||||
miso_pin=SPI_MISO_PIN_NAME,
|
||||
sck_pin=SPI_SCK_PIN_NAME,
|
||||
cs_pin=SPI_CS_PIN_NAME)
|
||||
test_results["SPI Test"] = result[0]
|
||||
pins_tested.append(result[1])
|
||||
print()
|
||||
print(result[0])
|
||||
print()
|
||||
|
||||
# Run I2C test
|
||||
print("@)}---^----- I2C TEST -----^---{(@")
|
||||
print()
|
||||
result = i2c_test.run_test(pins, sda_pin=I2C_SDA_PIN_NAME, scl_pin=I2C_SCL_PIN_NAME)
|
||||
test_results["I2C Test"] = result[0]
|
||||
pins_tested.append(result[1])
|
||||
print()
|
||||
print(result[0])
|
||||
print()
|
||||
|
||||
# Print out test results
|
||||
print("@)}---^----- TEST RESULTS -----^---{(@")
|
||||
print()
|
||||
|
||||
# Find appropriate spaces for printing test results
|
||||
num_spaces = 0
|
||||
for key in test_results:
|
||||
if len(key) > num_spaces:
|
||||
num_spaces = len(key)
|
||||
|
||||
# Print test results
|
||||
for key in test_results:
|
||||
print(key + ":", end=' ')
|
||||
for i in range(num_spaces - len(key)):
|
||||
print(end=' ')
|
||||
print(test_results[key])
|
||||
print()
|
||||
|
||||
# Figure out which pins were tested and not tested
|
||||
tested = []
|
||||
for sublist in pins_tested:
|
||||
for p in sublist:
|
||||
tested.append(p)
|
||||
not_tested = list(set(pins).difference(set(tested)))
|
||||
|
||||
# Print tested pins
|
||||
print("The following pins were tested:", end=' ')
|
||||
for p in tested:
|
||||
print(p, end=' ')
|
||||
print('\n')
|
||||
|
||||
# Print pins not tested
|
||||
print("The following pins were NOT tested:", end=' ')
|
||||
for p in not_tested:
|
||||
print(p, end=' ')
|
||||
print('\n')
|
@ -1,154 +0,0 @@
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2018 Shawn Hymel for Adafruit Industries
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
"""
|
||||
`gpio_test`
|
||||
====================================================
|
||||
GPIO Test Module
|
||||
|
||||
* Author(s): Shawn Hymel
|
||||
* Date: December 8, 2018
|
||||
|
||||
Implementation Notes
|
||||
--------------------
|
||||
Toggles all available GPIO on a board. Verify their operation with an LED,
|
||||
multimeter, another microcontroller, etc.
|
||||
|
||||
Run this script as its own main.py to individually run the test, or compile
|
||||
with mpy-cross and call from separate test script.
|
||||
"""
|
||||
|
||||
import board
|
||||
import digitalio
|
||||
import supervisor
|
||||
import time
|
||||
|
||||
# Constants
|
||||
LED_ON_DELAY_TIME = 0.2 # Seconds
|
||||
LED_OFF_DELAY_TIME = 0.2 # Seconds
|
||||
LED_PIN_NAMES = ['L', 'LED', 'RED_LED', 'GREEN_LED', 'BLUE_LED']
|
||||
|
||||
# Test result strings
|
||||
PASS = "PASS"
|
||||
FAIL = "FAIL"
|
||||
NA = "N/A"
|
||||
|
||||
# Determine if given value is a number
|
||||
def _is_number(s):
|
||||
try:
|
||||
float(s)
|
||||
return True
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
# Release pins
|
||||
def _deinit_pins(gpios):
|
||||
for g in gpios:
|
||||
g.deinit()
|
||||
|
||||
# Toggle IO pins while waiting for answer
|
||||
def _toggle_wait(gpios):
|
||||
|
||||
global test_results
|
||||
|
||||
timestamp = time.monotonic()
|
||||
led_state = False
|
||||
print("Are the pins listed above toggling? [y/n]")
|
||||
while True:
|
||||
if led_state:
|
||||
if time.monotonic() > timestamp + LED_ON_DELAY_TIME:
|
||||
led_state = False
|
||||
timestamp = time.monotonic()
|
||||
else:
|
||||
if time.monotonic() > timestamp + LED_OFF_DELAY_TIME:
|
||||
led_state = True
|
||||
timestamp = time.monotonic()
|
||||
for gpio in gpios:
|
||||
gpio.value = led_state
|
||||
if supervisor.runtime.serial_bytes_available:
|
||||
answer = input()
|
||||
if answer == 'y':
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
break
|
||||
|
||||
def run_test(pins):
|
||||
|
||||
# Create a list of analog GPIO pins
|
||||
analog_pins = [p for p in pins if p[0] == 'A' and _is_number(p[1])]
|
||||
|
||||
# Create a list of digital GPIO
|
||||
digital_pins = [p for p in pins if p[0] == 'D' and _is_number(p[1])]
|
||||
|
||||
# Toggle LEDs if we find any
|
||||
gpio_pins = analog_pins + digital_pins
|
||||
if gpio_pins:
|
||||
|
||||
# Create a list of IO objects for us to toggle
|
||||
gpios = [digitalio.DigitalInOut(getattr(board, p)) for p in gpio_pins]
|
||||
|
||||
# Print out the LEDs found
|
||||
print("GPIO pins found:", end=' ')
|
||||
for p in gpio_pins:
|
||||
print(p, end=' ')
|
||||
print('\n')
|
||||
|
||||
# Set all IO to output
|
||||
for gpio in gpios:
|
||||
gpio.direction = digitalio.Direction.OUTPUT
|
||||
|
||||
# Toggle pins while waiting for user to verify LEDs blinking
|
||||
result = _toggle_wait(gpios)
|
||||
|
||||
# Release pins
|
||||
_deinit_pins(gpios)
|
||||
|
||||
if result:
|
||||
return PASS, gpio_pins
|
||||
else:
|
||||
return FAIL, gpio_pins
|
||||
|
||||
else:
|
||||
print("No GPIO pins found")
|
||||
return NA, []
|
||||
|
||||
def _main():
|
||||
|
||||
# List out all the pins available to us
|
||||
pins = [p for p in dir(board)]
|
||||
print()
|
||||
print("All pins found:", end=' ')
|
||||
|
||||
# Print pins
|
||||
for p in pins:
|
||||
print(p, end=' ')
|
||||
print('\n')
|
||||
|
||||
# Run test
|
||||
result = run_test(pins)
|
||||
print()
|
||||
print(result[0])
|
||||
print("Pins tested: " + str(result[1]))
|
||||
|
||||
# Execute only if run as main.py or code.py
|
||||
if __name__ == "__main__":
|
||||
_main()
|
@ -1,191 +0,0 @@
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2018 Shawn Hymel for Adafruit Industries
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
"""
|
||||
`i2c_test`
|
||||
====================================================
|
||||
I2C Test Module
|
||||
|
||||
* Author(s): Shawn Hymel
|
||||
* Date: December 8, 2018
|
||||
|
||||
Implementation Notes
|
||||
--------------------
|
||||
Performs random writes and reads to I2C EEPROM.
|
||||
|
||||
Requires Microchip AT24HC04B I2C EEPROM.
|
||||
|
||||
Run this script as its own main.py to individually run the test, or compile
|
||||
with mpy-cross and call from separate test script.
|
||||
"""
|
||||
|
||||
import board
|
||||
import busio
|
||||
import random
|
||||
import time
|
||||
|
||||
# Constants
|
||||
SDA_PIN_NAME = 'SDA'
|
||||
SCL_PIN_NAME = 'SCL'
|
||||
NUM_I2C_TESTS = 10 # Number of times to write and read EEPROM values
|
||||
EEPROM_I2C_MAX_ADDR = 255 # Self-imposed max memory address
|
||||
|
||||
# Microchip AT24HC04B EEPROM I2C address
|
||||
EEPROM_I2C_ADDR = 0x50
|
||||
|
||||
# Test result strings
|
||||
PASS = "PASS"
|
||||
FAIL = "FAIL"
|
||||
NA = "N/A"
|
||||
|
||||
# Open comms to I2C EEPROM by trying a write to memory address
|
||||
def _eeprom_i2c_wait(i2c, i2c_addr, mem_addr, timeout = 1.0):
|
||||
|
||||
# Try to access the I2C EEPROM (it becomes unresonsive during a write)
|
||||
timestamp = time.monotonic()
|
||||
while time.monotonic() < timestamp + timeout:
|
||||
try:
|
||||
i2c.writeto(i2c_addr, bytearray([mem_addr]), end=1, stop=False)
|
||||
return True
|
||||
except:
|
||||
pass
|
||||
|
||||
return False
|
||||
|
||||
# Write to address. Returns status (True for successful write, False otherwise)
|
||||
def _eeprom_i2c_write_byte(i2c, i2c_addr, mem_addr, mem_data, timeout = 1.0):
|
||||
|
||||
# Make sure address is only one byte:
|
||||
if mem_addr > 255:
|
||||
return False
|
||||
|
||||
# Make sure data is only one byte:
|
||||
if mem_data > 255:
|
||||
return False
|
||||
|
||||
# Write data to memory at given address
|
||||
try:
|
||||
i2c.writeto(i2c_addr, bytearray([mem_addr, mem_data]))
|
||||
except:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
# Read from address. Returns tuple [status, result]
|
||||
def _eeprom_i2c_read_byte(i2c, i2c_addr, mem_addr, timeout = 1.0):
|
||||
|
||||
# Make sure address is only one byte:
|
||||
if mem_addr > 255:
|
||||
return False, bytearray()
|
||||
|
||||
# Try writing to address (EEPROM is unresponsive while writing)
|
||||
if _eeprom_i2c_wait(i2c, i2c_addr, mem_addr, timeout) == False:
|
||||
return False, bytearray()
|
||||
|
||||
# Finish the read
|
||||
buf = bytearray(1)
|
||||
i2c.readfrom_into(i2c_addr, buf)
|
||||
|
||||
return True, buf
|
||||
|
||||
def run_test(pins, sda_pin=SDA_PIN_NAME, scl_pin=SCL_PIN_NAME):
|
||||
|
||||
# Write values to I2C EEPROM and verify the values match
|
||||
if list(set(pins).intersection(set([sda_pin, scl_pin]))):
|
||||
|
||||
# Tell user to connect EEPROM chip
|
||||
print("Connect a Microchip AT24HC04B EEPROM I2C chip. " +
|
||||
"Press enter to continue.")
|
||||
input()
|
||||
|
||||
# Set up I2C
|
||||
i2c = busio.I2C(getattr(board, scl_pin), getattr(board, sda_pin))
|
||||
|
||||
# Wait for I2C lock
|
||||
while not i2c.try_lock():
|
||||
pass
|
||||
|
||||
# Pick a random address, write to it, read from it, and see if they match
|
||||
pass_test = True
|
||||
for i in range(NUM_I2C_TESTS):
|
||||
|
||||
# Randomly pick an address and a data value (one byte)
|
||||
mem_addr = random.randint(0, EEPROM_I2C_MAX_ADDR)
|
||||
mem_data = random.randint(0, 255)
|
||||
print("Address:\t" + hex(mem_addr))
|
||||
print("Writing:\t" + hex(mem_data))
|
||||
|
||||
# Try writing this random value to the random address
|
||||
result = _eeprom_i2c_write_byte(i2c, EEPROM_I2C_ADDR, mem_addr, mem_data)
|
||||
if result == False:
|
||||
print("FAIL: I2C could not communicate")
|
||||
pass_test = False
|
||||
break
|
||||
|
||||
# Try reading the written value back from EEPROM
|
||||
result = _eeprom_i2c_read_byte(i2c, EEPROM_I2C_ADDR, mem_addr)
|
||||
print("Read:\t\t" + hex(result[1][0]))
|
||||
print()
|
||||
if result[0] == False:
|
||||
print("FAIL: I2C could not communicate")
|
||||
pass_test = False
|
||||
break
|
||||
|
||||
# Compare the read value to the original value
|
||||
if result[1][0] != mem_data:
|
||||
print("FAIL: Data does not match")
|
||||
pass_test = False
|
||||
break
|
||||
|
||||
# Release I2C pins
|
||||
i2c.deinit()
|
||||
|
||||
# Store results
|
||||
if pass_test:
|
||||
return PASS, [sda_pin, scl_pin]
|
||||
else:
|
||||
return FAIL, [sda_pin, scl_pin]
|
||||
|
||||
else:
|
||||
print("No I2C pins found")
|
||||
return NA, []
|
||||
|
||||
def _main():
|
||||
|
||||
# List out all the pins available to us
|
||||
pins = [p for p in dir(board)]
|
||||
print()
|
||||
print("All pins found:", end=' ')
|
||||
|
||||
# Print pins
|
||||
for p in pins:
|
||||
print(p, end=' ')
|
||||
print('\n')
|
||||
|
||||
# Run test
|
||||
result = run_test(pins)
|
||||
print()
|
||||
print(result[0])
|
||||
print("Pins tested: " + str(result[1]))
|
||||
|
||||
# Execute only if run as main.py or code.py
|
||||
if __name__ == "__main__":
|
||||
_main()
|
@ -1,142 +0,0 @@
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2018 Shawn Hymel for Adafruit Industries
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
"""
|
||||
`led_test`
|
||||
====================================================
|
||||
LED Test Module
|
||||
|
||||
* Author(s): Shawn Hymel
|
||||
* Date: December 8, 2018
|
||||
|
||||
Implementation Notes
|
||||
--------------------
|
||||
Toggles all available onboard LEDs. You will need to manually verify their
|
||||
operation by watching them.
|
||||
|
||||
Run this script as its own main.py to individually run the test, or compile
|
||||
with mpy-cross and call from separate test script.
|
||||
"""
|
||||
|
||||
import board
|
||||
import digitalio
|
||||
import supervisor
|
||||
import time
|
||||
|
||||
# Constants
|
||||
LED_ON_DELAY_TIME = 0.2 # Seconds
|
||||
LED_OFF_DELAY_TIME = 0.2 # Seconds
|
||||
LED_PIN_NAMES = ['L', 'LED', 'RED_LED', 'GREEN_LED', 'BLUE_LED']
|
||||
|
||||
# Test result strings
|
||||
PASS = "PASS"
|
||||
FAIL = "FAIL"
|
||||
NA = "N/A"
|
||||
|
||||
# Release pins
|
||||
def _deinit_pins(gpios):
|
||||
for g in gpios:
|
||||
g.deinit()
|
||||
|
||||
# Toggle IO pins while waiting for answer
|
||||
def _toggle_wait(gpios):
|
||||
|
||||
global test_results
|
||||
|
||||
timestamp = time.monotonic()
|
||||
led_state = False
|
||||
print("Are the pins listed above toggling? [y/n]")
|
||||
while True:
|
||||
if led_state:
|
||||
if time.monotonic() > timestamp + LED_ON_DELAY_TIME:
|
||||
led_state = False
|
||||
timestamp = time.monotonic()
|
||||
else:
|
||||
if time.monotonic() > timestamp + LED_OFF_DELAY_TIME:
|
||||
led_state = True
|
||||
timestamp = time.monotonic()
|
||||
for gpio in gpios:
|
||||
gpio.value = led_state
|
||||
if supervisor.runtime.serial_bytes_available:
|
||||
answer = input()
|
||||
if answer == 'y':
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
break
|
||||
|
||||
def run_test(pins):
|
||||
|
||||
# Look for pins with LED names
|
||||
led_pins = list(set(pins).intersection(set(LED_PIN_NAMES)))
|
||||
|
||||
# Toggle LEDs if we find any
|
||||
if led_pins:
|
||||
|
||||
# Print out the LEDs found
|
||||
print("LEDs found:", end=' ')
|
||||
for p in led_pins:
|
||||
print(p, end=' ')
|
||||
print('\n')
|
||||
|
||||
# Create a list of IO objects for us to toggle
|
||||
leds = [digitalio.DigitalInOut(getattr(board, p)) for p in led_pins]
|
||||
|
||||
# Set all LEDs to output
|
||||
for led in leds:
|
||||
led.direction = digitalio.Direction.OUTPUT
|
||||
|
||||
# Blink LEDs and wait for user to verify test
|
||||
result = _toggle_wait(leds)
|
||||
|
||||
# Release pins
|
||||
_deinit_pins(leds)
|
||||
|
||||
if result:
|
||||
return PASS, led_pins
|
||||
else:
|
||||
return FAIL, led_pins
|
||||
|
||||
else:
|
||||
print("No LED pins found")
|
||||
return NA, []
|
||||
|
||||
def _main():
|
||||
|
||||
# List out all the pins available to us
|
||||
pins = [p for p in dir(board)]
|
||||
print()
|
||||
print("All pins found:", end=' ')
|
||||
|
||||
# Print pins
|
||||
for p in pins:
|
||||
print(p, end=' ')
|
||||
print('\n')
|
||||
|
||||
# Run test
|
||||
result = run_test(pins)
|
||||
print()
|
||||
print(result[0])
|
||||
print("Pins tested: " + str(result[1]))
|
||||
|
||||
# Execute only if run as main.py or code.py
|
||||
if __name__ == "__main__":
|
||||
_main()
|
@ -1,110 +0,0 @@
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2018 Shawn Hymel for Adafruit Industries
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
"""
|
||||
`sd_cd_test`
|
||||
====================================================
|
||||
SD CD Test Module
|
||||
|
||||
* Author(s): Shawn Hymel
|
||||
* Date: December 8, 2018
|
||||
|
||||
Implementation Notes
|
||||
--------------------
|
||||
Reports the output of an SD card's chip detect (CD) pin.
|
||||
|
||||
Requires SD card.
|
||||
|
||||
Run this script as its own main.py to individually run the test, or compile
|
||||
with mpy-cross and call from separate test script.
|
||||
"""
|
||||
|
||||
import board
|
||||
import digitalio
|
||||
|
||||
# Constants
|
||||
SD_CD_PIN_NAME = 'SD_CD'
|
||||
|
||||
# Test result strings
|
||||
PASS = "PASS"
|
||||
FAIL = "FAIL"
|
||||
NA = "N/A"
|
||||
|
||||
def run_test(pins, cd_pin=SD_CD_PIN_NAME):
|
||||
|
||||
# Ask user to insert and remove SD card
|
||||
if list(set(pins).intersection(set([cd_pin]))):
|
||||
|
||||
# Configure CD pin as input with pullup
|
||||
cd = digitalio.DigitalInOut(getattr(board, cd_pin))
|
||||
cd.direction = digitalio.Direction.INPUT
|
||||
cd.pull = digitalio.Pull.UP
|
||||
|
||||
# Tell user to insert SD card
|
||||
print("Connect " + cd_pin + " to CD pin on SD card holder.")
|
||||
print("Insert SD card into holder.")
|
||||
print("Press enter to continue.")
|
||||
input()
|
||||
|
||||
# Make sure we see that the pin is low
|
||||
if cd.value == True:
|
||||
print("Error: Card not detected")
|
||||
return FAIL, [cd_pin]
|
||||
|
||||
# Tell user to remove SD card
|
||||
print("Card detected. Remove card and press enter to continue.")
|
||||
input()
|
||||
|
||||
# Make sure we see that the pin is high
|
||||
if cd.value == False:
|
||||
print("Error: Card detected")
|
||||
return FAIL, [cd_pin]
|
||||
|
||||
# Test passed
|
||||
print("Card removed")
|
||||
return PASS, [cd_pin]
|
||||
|
||||
else:
|
||||
print("No CD pin found")
|
||||
return NA, []
|
||||
|
||||
|
||||
def _main():
|
||||
|
||||
# List out all the pins available to us
|
||||
pins = [p for p in dir(board)]
|
||||
print()
|
||||
print("All pins found:", end=' ')
|
||||
|
||||
# Print pins
|
||||
for p in pins:
|
||||
print(p, end=' ')
|
||||
print('\n')
|
||||
|
||||
# Run test
|
||||
result = run_test(pins)
|
||||
print()
|
||||
print(result[0])
|
||||
print("Pins tested: " + str(result[1]))
|
||||
|
||||
# Execute only if run as main.py or code.py
|
||||
if __name__ == "__main__":
|
||||
_main()
|
@ -1,157 +0,0 @@
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2018 Shawn Hymel for Adafruit Industries
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
"""
|
||||
`sd_test`
|
||||
====================================================
|
||||
SD Test Module
|
||||
|
||||
* Author(s): Shawn Hymel
|
||||
* Date: December 8, 2018
|
||||
|
||||
Implementation Notes
|
||||
--------------------
|
||||
Performs random writes and reads to SD card over SPI.
|
||||
|
||||
Requires SD card.
|
||||
|
||||
Requires adafruit_sdcard.mpy and adafruit_bus_device modules.
|
||||
|
||||
Run this script as its own main.py to individually run the test, or compile
|
||||
with mpy-cross and call from separate test script.
|
||||
"""
|
||||
|
||||
import adafruit_sdcard
|
||||
import board
|
||||
import busio
|
||||
import digitalio
|
||||
import storage
|
||||
import random
|
||||
|
||||
# Constants
|
||||
MOSI_PIN_NAME = 'SD_MOSI'
|
||||
MISO_PIN_NAME = 'SD_MISO'
|
||||
SCK_PIN_NAME = 'SD_SCK'
|
||||
CS_PIN_NAME = 'SD_CS'
|
||||
FILENAME = "test.txt" # File that will be written to
|
||||
BAUD_RATE = 100000 # Bits per second
|
||||
NUM_UART_BYTES = 40 # Number of bytes to transmit over UART
|
||||
ASCII_MIN = 0x21 # '!' Lowest ASCII char in random range (inclusive)
|
||||
ASCII_MAX = 0x7E # '~' Highest ASCII char in random range (inclusive)
|
||||
|
||||
# Test result strings
|
||||
PASS = "PASS"
|
||||
FAIL = "FAIL"
|
||||
NA = "N/A"
|
||||
|
||||
def run_test( pins,
|
||||
mosi_pin=MOSI_PIN_NAME,
|
||||
miso_pin=MISO_PIN_NAME,
|
||||
sck_pin=SCK_PIN_NAME,
|
||||
cs_pin=CS_PIN_NAME,
|
||||
filename=FILENAME):
|
||||
|
||||
# Write characters to file on SD card and verify they were written
|
||||
if list(set(pins).intersection(set([mosi_pin, miso_pin, sck_pin]))):
|
||||
|
||||
# Tell user to connect SD card
|
||||
print("Insert SD card into holder and connect SPI lines to holder.")
|
||||
print("Connect " + cs_pin + " to the CS (CD/DAT3) pin on the SD " +
|
||||
"card holder.")
|
||||
print("WARNING: " + filename + " will be created or overwritten.")
|
||||
print("Press enter to continue.")
|
||||
input()
|
||||
|
||||
# Configure CS pin
|
||||
cs = digitalio.DigitalInOut(getattr(board, cs_pin))
|
||||
cs.direction = digitalio.Direction.OUTPUT
|
||||
cs.value = True
|
||||
|
||||
# Set up SPI
|
||||
spi = busio.SPI(getattr(board, sck_pin),
|
||||
MOSI=getattr(board, mosi_pin),
|
||||
MISO=getattr(board, miso_pin))
|
||||
|
||||
# Try to connect to the card and mount the filesystem
|
||||
try:
|
||||
sdcard = adafruit_sdcard.SDCard(spi, cs)
|
||||
vfs = storage.VfsFat(sdcard)
|
||||
storage.mount(vfs, "/sd")
|
||||
except:
|
||||
print("Could not mount SD card")
|
||||
return FAIL, [mosi_pin, miso_pin, sck_pin]
|
||||
|
||||
# Generate test string
|
||||
test_str = ""
|
||||
for i in range(NUM_UART_BYTES):
|
||||
test_str += chr(random.randint(ASCII_MIN, ASCII_MAX))
|
||||
|
||||
# Write test string to a text file on the card
|
||||
try:
|
||||
with open("/sd/" + filename, "w") as f:
|
||||
print("Writing:\t" + test_str)
|
||||
f.write(test_str)
|
||||
except:
|
||||
print("Could not write to SD card")
|
||||
return FAIL, [mosi_pin, miso_pin, sck_pin]
|
||||
|
||||
# Read from test file on the card
|
||||
read_str = ""
|
||||
try:
|
||||
with open("/sd/" + filename, "r") as f:
|
||||
lines = f.readlines()
|
||||
for line in lines:
|
||||
read_str += line
|
||||
print("Read:\t\t" + read_str)
|
||||
except:
|
||||
print("Could not read from SD card")
|
||||
return FAIL, [mosi_pin, miso_pin, sck_pin]
|
||||
|
||||
# Release SPI
|
||||
spi.deinit()
|
||||
|
||||
# Compare strings
|
||||
if read_str == test_str:
|
||||
return PASS, [mosi_pin, miso_pin, sck_pin]
|
||||
else:
|
||||
return FAIL, [mosi_pin, miso_pin, sck_pin]
|
||||
|
||||
def _main():
|
||||
|
||||
# List out all the pins available to us
|
||||
pins = [p for p in dir(board)]
|
||||
print()
|
||||
print("All pins found:", end=' ')
|
||||
|
||||
# Print pins
|
||||
for p in pins:
|
||||
print(p, end=' ')
|
||||
print('\n')
|
||||
|
||||
# Run test
|
||||
result = run_test(pins)
|
||||
print()
|
||||
print(result[0])
|
||||
print("Pins tested: " + str(result[1]))
|
||||
|
||||
# Execute only if run as main.py or code.py
|
||||
if __name__ == "__main__":
|
||||
_main()
|
@ -1,232 +0,0 @@
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2018 Shawn Hymel for Adafruit Industries
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
"""
|
||||
`spi_test`
|
||||
====================================================
|
||||
SPI Test Module
|
||||
|
||||
* Author(s): Shawn Hymel
|
||||
* Date: December 8, 2018
|
||||
|
||||
Implementation Notes
|
||||
--------------------
|
||||
Performs random writes and reads to SPI EEPROM.
|
||||
|
||||
Requires Microchip 25AA040A SPI EEPROM.
|
||||
|
||||
Run this script as its own main.py to individually run the test, or compile
|
||||
with mpy-cross and call from separate test script.
|
||||
"""
|
||||
|
||||
import board
|
||||
import digitalio
|
||||
import busio
|
||||
import random
|
||||
import time
|
||||
|
||||
# Constants
|
||||
MOSI_PIN_NAME = 'MOSI'
|
||||
MISO_PIN_NAME = 'MISO'
|
||||
SCK_PIN_NAME = 'SCK'
|
||||
CS_PIN_NAME = 'D2'
|
||||
BAUD_RATE = 100000 # Bits per second
|
||||
NUM_SPI_TESTS = 10 # Number of times to write and read EEPROM values
|
||||
|
||||
# Microchip 25AA040A EEPROM SPI commands and bits
|
||||
EEPROM_SPI_WRSR = 0x01
|
||||
EEPROM_SPI_WRITE = 0x02
|
||||
EEPROM_SPI_READ = 0x03
|
||||
EEPROM_SPI_WRDI = 0x04
|
||||
EEPROM_SPI_RDSR = 0x05
|
||||
EEPROM_SPI_WREN = 0x06
|
||||
EEPROM_SPI_WIP_BIT = 0
|
||||
EEPROM_SPI_MAX_ADDR = 255 # Self-imposed max memory address
|
||||
EEPROM_I2C_MAX_ADDR = 255 # Self-imposed max memory address
|
||||
|
||||
# Test result strings
|
||||
PASS = "PASS"
|
||||
FAIL = "FAIL"
|
||||
NA = "N/A"
|
||||
|
||||
# Wait for WIP bit to go low
|
||||
def _eeprom_spi_wait(spi, cs, timeout = 1.0):
|
||||
|
||||
# Continually read from STATUS register
|
||||
timestamp = time.monotonic()
|
||||
while time.monotonic() < timestamp + timeout:
|
||||
|
||||
# Perfrom RDSR operation
|
||||
cs.value = False
|
||||
result = bytearray(1)
|
||||
spi.write(bytearray([EEPROM_SPI_RDSR]))
|
||||
spi.readinto(result)
|
||||
cs.value = True
|
||||
|
||||
# Mask out and compare WIP bit
|
||||
if (result[0] & (1 << EEPROM_SPI_WIP_BIT)) == 0:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
# Write to address. Returns status (True for successful write, False otherwise)
|
||||
def _eeprom_spi_write_byte(spi, cs, address, data, timeout = 1.0):
|
||||
|
||||
# Make sure address is only one byte:
|
||||
if address > 255:
|
||||
return False
|
||||
|
||||
# Make sure data is only one byte:
|
||||
if data > 255:
|
||||
return False
|
||||
|
||||
# Wait for WIP to be low
|
||||
if _eeprom_spi_wait(spi, cs, timeout) == False:
|
||||
return False
|
||||
|
||||
# Enable writing
|
||||
cs.value = False
|
||||
spi.write(bytearray([EEPROM_SPI_WREN]))
|
||||
cs.value = True
|
||||
|
||||
# Write to address
|
||||
cs.value = False
|
||||
spi.write(bytearray([EEPROM_SPI_WRITE, address, data]))
|
||||
cs.value = True
|
||||
|
||||
return True
|
||||
|
||||
# Read from address. Returns tuple [status, result]
|
||||
def _eeprom_spi_read_byte(spi, cs, address, timeout = 1.0):
|
||||
|
||||
# Make sure address is only one byte:
|
||||
if address > 255:
|
||||
return False, bytearray()
|
||||
|
||||
# Wait for WIP to be low
|
||||
if _eeprom_spi_wait(spi, cs, timeout) == False:
|
||||
return False, bytearray()
|
||||
|
||||
# Read byte from address
|
||||
cs.value = False
|
||||
result = bytearray(1)
|
||||
spi.write(bytearray([EEPROM_SPI_READ, address]))
|
||||
spi.readinto(result)
|
||||
cs.value = True
|
||||
|
||||
return True, result
|
||||
|
||||
def run_test( pins,
|
||||
mosi_pin=MOSI_PIN_NAME,
|
||||
miso_pin=MISO_PIN_NAME,
|
||||
sck_pin=SCK_PIN_NAME,
|
||||
cs_pin=CS_PIN_NAME):
|
||||
|
||||
# Write values to SPI EEPROM and verify the values match
|
||||
if list(set(pins).intersection(set([mosi_pin, miso_pin, sck_pin]))):
|
||||
|
||||
# Tell user to connect EEPROM chip
|
||||
print("Connect a Microchip 25AA040A EEPROM SPI chip.")
|
||||
print("Connect " + cs_pin + " to the CS pin on the 25AA040.")
|
||||
print("Press enter to continue.")
|
||||
input()
|
||||
|
||||
# Configure CS pin
|
||||
cs = digitalio.DigitalInOut(getattr(board, cs_pin))
|
||||
cs.direction = digitalio.Direction.OUTPUT
|
||||
cs.value = True
|
||||
|
||||
# Set up SPI
|
||||
spi = busio.SPI(getattr(board, sck_pin),
|
||||
MOSI=getattr(board, mosi_pin),
|
||||
MISO=getattr(board, miso_pin))
|
||||
|
||||
# Wait for SPI lock
|
||||
while not spi.try_lock():
|
||||
pass
|
||||
spi.configure(baudrate=BAUD_RATE, phase=0, polarity=0)
|
||||
|
||||
# Pick a random address, write to it, read from it, and see if they match
|
||||
pass_test = True
|
||||
for i in range(NUM_SPI_TESTS):
|
||||
|
||||
# Randomly pick an address and a data value (one byte)
|
||||
mem_addr = random.randint(0, EEPROM_SPI_MAX_ADDR)
|
||||
mem_data = random.randint(0, 255)
|
||||
print("Address:\t" + hex(mem_addr))
|
||||
print("Writing:\t" + hex(mem_data))
|
||||
|
||||
# Try writing this random value to the random address
|
||||
result = _eeprom_spi_write_byte(spi, cs, mem_addr, mem_data)
|
||||
if result == False:
|
||||
print("FAIL: SPI could not communicate")
|
||||
pass_test = False
|
||||
break
|
||||
|
||||
# Try reading the written value back from EEPRom
|
||||
result = _eeprom_spi_read_byte(spi, cs, mem_addr)
|
||||
print("Read:\t\t" + hex(result[1][0]))
|
||||
print()
|
||||
if result[0] == False:
|
||||
print("FAIL: SPI could not communicate")
|
||||
pass_test = False
|
||||
break
|
||||
|
||||
# Compare the read value to the original value
|
||||
if result[1][0] != mem_data:
|
||||
print("FAIL: Data does not match")
|
||||
pass_test = False
|
||||
break
|
||||
|
||||
# Release SPI pins
|
||||
spi.deinit()
|
||||
|
||||
# Return results
|
||||
if pass_test:
|
||||
return PASS, [mosi_pin, miso_pin, sck_pin]
|
||||
else:
|
||||
return FAIL, [mosi_pin, miso_pin, sck_pin]
|
||||
|
||||
else:
|
||||
print("No SPI pins found")
|
||||
return NA, []
|
||||
|
||||
def _main():
|
||||
|
||||
# List out all the pins available to us
|
||||
pins = [p for p in dir(board)]
|
||||
print()
|
||||
print("All pins found:", end=' ')
|
||||
|
||||
# Print pins
|
||||
for p in pins:
|
||||
print(p, end=' ')
|
||||
print('\n')
|
||||
|
||||
# Run test
|
||||
result = run_test(pins)
|
||||
print()
|
||||
print(result[0])
|
||||
print("Pins tested: " + str(result[1]))
|
||||
|
||||
# Execute only if run as main.py or code.py
|
||||
if __name__ == "__main__":
|
||||
_main()
|
@ -1,121 +0,0 @@
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2018 Shawn Hymel for Adafruit Industries
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
"""
|
||||
`uart_test`
|
||||
====================================================
|
||||
UART Test Module
|
||||
|
||||
* Author(s): Shawn Hymel
|
||||
* Date: December 8, 2018
|
||||
|
||||
Implementation Notes
|
||||
--------------------
|
||||
Performs random writes and reads across UART.
|
||||
|
||||
You will need to connect a loopback wire from TX to RX on your board.
|
||||
|
||||
Run this script as its own main.py to individually run the test, or compile
|
||||
with mpy-cross and call from separate test script.
|
||||
"""
|
||||
|
||||
import board
|
||||
import busio
|
||||
import random
|
||||
|
||||
# Constants
|
||||
TX_PIN_NAME = 'TX'
|
||||
RX_PIN_NAME = 'RX'
|
||||
BAUD_RATE = 9600
|
||||
NUM_UART_BYTES = 40 # Number of bytes to transmit over UART
|
||||
ASCII_MIN = 0x21 # '!' Lowest ASCII char in random range (inclusive)
|
||||
ASCII_MAX = 0x7E # '~' Highest ASCII char in random range (inclusive)
|
||||
|
||||
# Test result strings
|
||||
PASS = "PASS"
|
||||
FAIL = "FAIL"
|
||||
NA = "N/A"
|
||||
|
||||
def run_test(pins, tx_pin=TX_PIN_NAME, rx_pin=RX_PIN_NAME, baud_rate=BAUD_RATE):
|
||||
|
||||
# Echo some values over the UART
|
||||
if list(set(pins).intersection(set([tx_pin, rx_pin]))):
|
||||
|
||||
# Tell user to create loopback connection
|
||||
print("Connect a wire from TX to RX. Press enter to continue.")
|
||||
input()
|
||||
|
||||
# Initialize UART
|
||||
uart = busio.UART(getattr(board, tx_pin),
|
||||
getattr(board, rx_pin),
|
||||
baudrate=baud_rate)
|
||||
uart.reset_input_buffer()
|
||||
|
||||
# Generate test string
|
||||
test_str = ""
|
||||
for i in range(NUM_UART_BYTES):
|
||||
test_str += chr(random.randint(ASCII_MIN, ASCII_MAX))
|
||||
|
||||
# Transmit test string
|
||||
uart.write(test_str)
|
||||
print("Transmitting:\t" + test_str)
|
||||
|
||||
# Wait for received string
|
||||
data = uart.read(len(test_str))
|
||||
recv_str = ''
|
||||
if data is not None:
|
||||
recv_str = ''.join([chr(b) for b in data])
|
||||
print("Received:\t" + recv_str)
|
||||
|
||||
# Release UART pins
|
||||
uart.deinit()
|
||||
|
||||
# Compare strings
|
||||
if recv_str == test_str:
|
||||
return PASS, [tx_pin, rx_pin]
|
||||
else:
|
||||
return FAIL, [tx_pin, rx_pin]
|
||||
|
||||
else:
|
||||
print("No UART pins found")
|
||||
return NA, []
|
||||
|
||||
def _main():
|
||||
|
||||
# List out all the pins available to us
|
||||
pins = [p for p in dir(board)]
|
||||
print()
|
||||
print("All pins found:", end=' ')
|
||||
|
||||
# Print pins
|
||||
for p in pins:
|
||||
print(p, end=' ')
|
||||
print('\n')
|
||||
|
||||
# Run test
|
||||
result = run_test(pins)
|
||||
print()
|
||||
print(result[0])
|
||||
print("Pins tested: " + str(result[1]))
|
||||
|
||||
# Execute only if run as main.py or code.py
|
||||
if __name__ == "__main__":
|
||||
_main()
|
@ -1,111 +0,0 @@
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2018 Shawn Hymel for Adafruit Industries
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
"""
|
||||
`voltage_monitor_test`
|
||||
====================================================
|
||||
Voltage Monitor Test Module
|
||||
|
||||
* Author(s): Shawn Hymel
|
||||
* Date: December 8, 2018
|
||||
|
||||
Implementation Notes
|
||||
--------------------
|
||||
Prints out the measured voltage on any onboard voltage/battery monitor pins.
|
||||
Note that these pins sometimes have an onboard voltage divider to decrease
|
||||
the voltage.
|
||||
|
||||
Requires multimeter
|
||||
|
||||
Run this script as its own main.py to individually run the test, or compile
|
||||
with mpy-cross and call from separate test script.
|
||||
"""
|
||||
|
||||
import board
|
||||
import analogio
|
||||
|
||||
# Constants
|
||||
VOLTAGE_MONITOR_PIN_NAMES = ['VOLTAGE_MONITOR', 'BATTERY']
|
||||
ANALOG_REF = 3.3 # Reference analog voltage
|
||||
ANALOGIN_BITS = 16 # ADC resolution (bits) for CircuitPython
|
||||
|
||||
# Test result strings
|
||||
PASS = "PASS"
|
||||
FAIL = "FAIL"
|
||||
NA = "N/A"
|
||||
|
||||
def run_test(pins):
|
||||
|
||||
# Look for pins with battery monitoring names
|
||||
monitor_pins = list(set(pins).intersection(set(VOLTAGE_MONITOR_PIN_NAMES)))
|
||||
|
||||
# Print out voltage found on these pins
|
||||
if monitor_pins:
|
||||
|
||||
# Print out the monitor pins found
|
||||
print("Voltage monitor pins found:", end=' ')
|
||||
for p in monitor_pins:
|
||||
print(p, end=' ')
|
||||
print('\n')
|
||||
|
||||
# Print out the voltage found on each pin
|
||||
for p in monitor_pins:
|
||||
monitor = analogio.AnalogIn(getattr(board, p))
|
||||
voltage = (monitor.value * ANALOG_REF) / (2**ANALOGIN_BITS)
|
||||
print(p + ": {:.2f}".format(voltage) + " V")
|
||||
monitor.deinit()
|
||||
print()
|
||||
|
||||
# Ask the user to check these voltages
|
||||
print("Use a multimeter to verify these voltages.")
|
||||
print("Note that some battery monitor pins might have onboard " +
|
||||
"voltage dividers.")
|
||||
print("Do the values look reasonable? [y/n]")
|
||||
if input() == 'y':
|
||||
return PASS, monitor_pins
|
||||
else:
|
||||
return FAIL, monitor_pins
|
||||
|
||||
else:
|
||||
print("No battery monitor pins found")
|
||||
return NA, []
|
||||
|
||||
def _main():
|
||||
|
||||
# List out all the pins available to us
|
||||
pins = [p for p in dir(board)]
|
||||
print()
|
||||
print("All pins found:", end=' ')
|
||||
|
||||
# Print pins
|
||||
for p in pins:
|
||||
print(p, end=' ')
|
||||
print('\n')
|
||||
|
||||
# Run test
|
||||
result = run_test(pins)
|
||||
print()
|
||||
print(result[0])
|
||||
print("Pins tested: " + str(result[1]))
|
||||
|
||||
# Execute only if run as main.py or code.py
|
||||
if __name__ == "__main__":
|
||||
_main()
|
Loading…
Reference in New Issue
Block a user