From bdbbfd03dd52d57229cc66d5685f6af4b6903ee6 Mon Sep 17 00:00:00 2001 From: Alex Tereschenko Date: Wed, 17 Aug 2016 21:02:24 +0200 Subject: [PATCH] mraa mock: Add SPI functionality Signed-off-by: Alex Tereschenko Signed-off-by: Brendan Le Foll --- docs/mock.md | 8 ++ include/mock/mock_board.h | 2 +- include/mock/mock_board_spi.h | 73 +++++++++++ src/CMakeLists.txt | 1 + src/mock/mock_board.c | 44 ++++++- src/mock/mock_board_spi.c | 177 ++++++++++++++++++++++++++ tests/mock/CMakeLists.txt | 15 +++ tests/mock/platform_checks.py | 2 +- tests/mock/spi_checks_bit_per_word.py | 48 +++++++ tests/mock/spi_checks_freq.py | 56 ++++++++ tests/mock/spi_checks_lsbmode.py | 55 ++++++++ tests/mock/spi_checks_mode.py | 74 +++++++++++ tests/mock/spi_checks_shared.py | 28 ++++ tests/mock/spi_checks_write.py | 45 +++++++ tests/mock/spi_checks_write_byte.py | 52 ++++++++ tests/mock/spi_checks_write_word.py | 52 ++++++++ 16 files changed, 729 insertions(+), 3 deletions(-) create mode 100644 include/mock/mock_board_spi.h create mode 100644 src/mock/mock_board_spi.c create mode 100644 tests/mock/spi_checks_bit_per_word.py create mode 100644 tests/mock/spi_checks_freq.py create mode 100644 tests/mock/spi_checks_lsbmode.py create mode 100644 tests/mock/spi_checks_mode.py create mode 100644 tests/mock/spi_checks_shared.py create mode 100644 tests/mock/spi_checks_write.py create mode 100644 tests/mock/spi_checks_write_byte.py create mode 100644 tests/mock/spi_checks_write_word.py diff --git a/docs/mock.md b/docs/mock.md index 0d8080c..6c71af9 100644 --- a/docs/mock.md +++ b/docs/mock.md @@ -19,6 +19,10 @@ Right now we simulate a single generic board with: which can be read or written in bytes or words (big-endian). Technically those registers are just an array of `uint8_t`, so you can treat them as 10 single-byte registers or 5 single-word ones or a mix thereof. +* Single SPI bus with one Chip Select. All write functions are supported, received +data items (words or bytes) are calculated from the sent ones using +`sent_byte (or word) XOR constant` formula. +See [SPI mock header](../include/mock/mock_board_spi.h#L38-L39) for constant values. We plan to develop it further and all [contributions](../CONTRIBUTING.md) are more than welcome. @@ -30,6 +34,10 @@ See the table below for pin layout and features | 1 | ADC0 | AIO pin, returns random value on read | | 2 | I2C0SDA | SDA pin for I2C0 bus | | 3 | I2C0SCL | SCL pin for I2C0 bus | +| 4 | SPI0CS | CS pin for SPI0 bus | +| 5 | SPI0MOSI | MOSI pin for SPI0 bus | +| 6 | SPI0MISO | MISO pin for SPI0 bus | +| 7 | SPI0SCLK | SCLK pin for SPI0 bus | Building -------- diff --git a/include/mock/mock_board.h b/include/mock/mock_board.h index b60cf86..b6e8a14 100644 --- a/include/mock/mock_board.h +++ b/include/mock/mock_board.h @@ -30,7 +30,7 @@ extern "C" { #include "mraa_internal.h" -#define MRAA_MOCK_PINCOUNT 4 +#define MRAA_MOCK_PINCOUNT 8 mraa_board_t* mraa_mock_board(); diff --git a/include/mock/mock_board_spi.h b/include/mock/mock_board_spi.h new file mode 100644 index 0000000..1320158 --- /dev/null +++ b/include/mock/mock_board_spi.h @@ -0,0 +1,73 @@ +/* + * Author: Alex Tereschenko + * Copyright (c) 2016 Alex Tereschenko. + * + * 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. + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mraa_internal.h" + +#define MOCK_SPI_DEFAULT_FREQ 4000000 +#define MOCK_SPI_DEFAULT_MODE MRAA_SPI_MODE0 +#define MOCK_SPI_DEFAULT_LSBMODE 0 +#define MOCK_SPI_DEFAULT_BIT_PER_WORD 8 +// This is XORed with each byte/word of the transmitted message to get the received one +#define MOCK_SPI_REPLY_DATA_MODIFIER_BYTE 0xAB +#define MOCK_SPI_REPLY_DATA_MODIFIER_WORD 0xABBA + +mraa_result_t +mraa_mock_spi_init_raw_replace(mraa_spi_context dev, unsigned int bus, unsigned int cs); + +mraa_result_t +mraa_mock_spi_stop_replace(mraa_spi_context dev); + +mraa_result_t +mraa_mock_spi_bit_per_word_replace(mraa_spi_context dev, unsigned int bits); + +mraa_result_t +mraa_mock_spi_lsbmode_replace(mraa_spi_context dev, mraa_boolean_t lsb); + +mraa_result_t +mraa_mock_spi_mode_replace(mraa_spi_context dev, mraa_spi_mode_t mode); + +mraa_result_t +mraa_mock_spi_frequency_replace(mraa_spi_context dev, int hz); + +int +mraa_mock_spi_write_replace(mraa_spi_context dev, uint8_t data); + +int +mraa_mock_spi_write_word_replace(mraa_spi_context dev, uint16_t data); + +mraa_result_t +mraa_mock_spi_transfer_buf_replace(mraa_spi_context dev, uint8_t* data, uint8_t* rxbuf, int length); + +mraa_result_t +mraa_mock_spi_transfer_buf_word_replace(mraa_spi_context dev, uint16_t* data, uint16_t* rxbuf, int length); + +#ifdef __cplusplus +} +#endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6b7a9f8..d1c96b3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -90,6 +90,7 @@ set (mraa_LIB_MOCK_SRCS_NOAUTO ${PROJECT_SOURCE_DIR}/src/mock/mock_board_gpio.c ${PROJECT_SOURCE_DIR}/src/mock/mock_board_aio.c ${PROJECT_SOURCE_DIR}/src/mock/mock_board_i2c.c + ${PROJECT_SOURCE_DIR}/src/mock/mock_board_spi.c ) if (JSONPLAT) diff --git a/src/mock/mock_board.c b/src/mock/mock_board.c index 7686441..56f4008 100644 --- a/src/mock/mock_board.c +++ b/src/mock/mock_board.c @@ -30,6 +30,7 @@ #include "mock/mock_board_gpio.h" #include "mock/mock_board_aio.h" #include "mock/mock_board_i2c.h" +#include "mock/mock_board_spi.h" #define PLATFORM_NAME "MRAA mock platform" @@ -55,7 +56,14 @@ mraa_mock_board() b->i2c_bus[0].scl = 3; b->def_i2c_bus = b->i2c_bus[0].bus_id; - b->spi_bus_count = 0; + b->spi_bus_count = 1; + b->def_spi_bus = 0; + b->spi_bus[0].bus_id = 0; + b->spi_bus[0].slave_s = 0; + b->spi_bus[0].cs = 4; + b->spi_bus[0].mosi = 5; + b->spi_bus[0].miso = 6; + b->spi_bus[0].sclk = 7; b->pwm_default_period = 0; b->pwm_max_period = 0; @@ -99,6 +107,16 @@ mraa_mock_board() b->adv_func->i2c_write_byte_replace = &mraa_mock_i2c_write_byte_replace; b->adv_func->i2c_write_byte_data_replace = &mraa_mock_i2c_write_byte_data_replace; b->adv_func->i2c_write_word_data_replace = &mraa_mock_i2c_write_word_data_replace; + b->adv_func->spi_init_raw_replace = &mraa_mock_spi_init_raw_replace; + b->adv_func->spi_stop_replace = &mraa_mock_spi_stop_replace; + b->adv_func->spi_bit_per_word_replace = &mraa_mock_spi_bit_per_word_replace; + b->adv_func->spi_lsbmode_replace = &mraa_mock_spi_lsbmode_replace; + b->adv_func->spi_mode_replace = &mraa_mock_spi_mode_replace; + b->adv_func->spi_frequency_replace = &mraa_mock_spi_frequency_replace; + b->adv_func->spi_write_replace = &mraa_mock_spi_write_replace; + b->adv_func->spi_write_word_replace = &mraa_mock_spi_write_word_replace; + b->adv_func->spi_transfer_buf_replace = &mraa_mock_spi_transfer_buf_replace; + b->adv_func->spi_transfer_buf_word_replace = &mraa_mock_spi_transfer_buf_word_replace; // Pin definitions int pos = 0; @@ -127,6 +145,30 @@ mraa_mock_board() b->pins[pos].i2c.pinmap = 0; pos++; + strncpy(b->pins[pos].name, "SPI0CS", 8); + b->pins[pos].capabilities = (mraa_pincapabilities_t){ 1, 0, 0, 0, 1, 0, 0, 0 }; + b->pins[pos].spi.mux_total = 0; + b->pins[pos].spi.pinmap = 0; + pos++; + + strncpy(b->pins[pos].name, "SPI0MOSI", 8); + b->pins[pos].capabilities = (mraa_pincapabilities_t){ 1, 0, 0, 0, 1, 0, 0, 0 }; + b->pins[pos].spi.mux_total = 0; + b->pins[pos].spi.pinmap = 0; + pos++; + + strncpy(b->pins[pos].name, "SPI0MISO", 8); + b->pins[pos].capabilities = (mraa_pincapabilities_t){ 1, 0, 0, 0, 1, 0, 0, 0 }; + b->pins[pos].spi.mux_total = 0; + b->pins[pos].spi.pinmap = 0; + pos++; + + strncpy(b->pins[pos].name, "SPI0SCLK", 8); + b->pins[pos].capabilities = (mraa_pincapabilities_t){ 1, 0, 0, 0, 1, 0, 0, 0 }; + b->pins[pos].spi.mux_total = 0; + b->pins[pos].spi.pinmap = 0; + pos++; + return b; error: diff --git a/src/mock/mock_board_spi.c b/src/mock/mock_board_spi.c new file mode 100644 index 0000000..a9d64d5 --- /dev/null +++ b/src/mock/mock_board_spi.c @@ -0,0 +1,177 @@ +/* + * Author: Alex Tereschenko + * Copyright (c) 2016 Alex Tereschenko. + * + * 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. + */ + +#include +#include + +#if defined(MSYS) +#define __USE_LINUX_IOCTL_DEFS +#endif +#include +#if defined(MSYS) +// There's no spidev.h on MSYS, so we need to provide our own, +// and only *after* including ioctl.h as that one contains prerequisites. +#include "linux/spi_kernel_headers.h" +#else +#include +#endif + +#include "common.h" +#include "mock/mock_board_spi.h" + +mraa_result_t +mraa_mock_spi_init_raw_replace(mraa_spi_context dev, unsigned int bus, unsigned int cs) +{ + dev->clock = MOCK_SPI_DEFAULT_FREQ; + + if ((mraa_spi_mode(dev, MOCK_SPI_DEFAULT_MODE) != MRAA_SUCCESS) || + (mraa_spi_lsbmode(dev, MOCK_SPI_DEFAULT_LSBMODE) != MRAA_SUCCESS) || + (mraa_spi_bit_per_word(dev, MOCK_SPI_DEFAULT_BIT_PER_WORD) != MRAA_SUCCESS)) { + return MRAA_ERROR_INVALID_RESOURCE; + } + + return MRAA_SUCCESS; +} + +mraa_result_t +mraa_mock_spi_stop_replace(mraa_spi_context dev) +{ + free(dev); + return MRAA_SUCCESS; +} + +mraa_result_t +mraa_mock_spi_bit_per_word_replace(mraa_spi_context dev, unsigned int bits) +{ + if (bits == 0) { + syslog(LOG_ERR, "spi: bit_per_word: Cannot set to zero"); + return MRAA_ERROR_INVALID_PARAMETER; + } + + dev->bpw = bits; + return MRAA_SUCCESS; +} + +mraa_result_t +mraa_mock_spi_lsbmode_replace(mraa_spi_context dev, mraa_boolean_t lsb) +{ + dev->lsb = lsb; + return MRAA_SUCCESS; +} + +mraa_result_t +mraa_mock_spi_mode_replace(mraa_spi_context dev, mraa_spi_mode_t mode) +{ + uint8_t spi_mode = 0; + + switch (mode) { + case MRAA_SPI_MODE0: + spi_mode = SPI_MODE_0; + break; + case MRAA_SPI_MODE1: + spi_mode = SPI_MODE_1; + break; + case MRAA_SPI_MODE2: + spi_mode = SPI_MODE_2; + break; + case MRAA_SPI_MODE3: + spi_mode = SPI_MODE_3; + break; + default: + syslog(LOG_ERR, "spi: mode: Invalid SPI mode selected", mode); + return MRAA_ERROR_INVALID_PARAMETER; + } + + dev->mode = spi_mode; + return MRAA_SUCCESS; +} + +mraa_result_t +mraa_mock_spi_frequency_replace(mraa_spi_context dev, int hz) +{ + if (hz <= 0) { + syslog(LOG_ERR, "spi: frequency: Cannot set to zero or negative"); + return MRAA_ERROR_INVALID_PARAMETER; + } + + dev->clock = hz; + return MRAA_SUCCESS; +} + +int +mraa_mock_spi_write_replace(mraa_spi_context dev, uint8_t data) +{ + return (int) (data ^ MOCK_SPI_REPLY_DATA_MODIFIER_BYTE); +} + +int +mraa_mock_spi_write_word_replace(mraa_spi_context dev, uint16_t data) +{ + return (int) (data ^ MOCK_SPI_REPLY_DATA_MODIFIER_WORD); +} + +mraa_result_t +mraa_mock_spi_transfer_buf_replace(mraa_spi_context dev, uint8_t* data, uint8_t* rxbuf, int length) +{ + if (data == NULL) { + syslog(LOG_ERR, "spi: transfer_buf: Incoming data is null, cannot proceed"); + return MRAA_ERROR_INVALID_PARAMETER; + } + + if (length <= 0) { + syslog(LOG_ERR, "spi: transfer_buf: Length given is equal to or less than zero, cannot proceed"); + return MRAA_ERROR_INVALID_PARAMETER; + } + + if (rxbuf != NULL) { + for (int i = 0; i < length; ++i) { + rxbuf[i] = data[i] ^ MOCK_SPI_REPLY_DATA_MODIFIER_BYTE; + } + } + + return MRAA_SUCCESS; +} + +mraa_result_t +mraa_mock_spi_transfer_buf_word_replace(mraa_spi_context dev, uint16_t* data, uint16_t* rxbuf, int length) +{ + if (data == NULL) { + syslog(LOG_ERR, "spi: transfer_buf_word: Incoming data is null, cannot proceed"); + return MRAA_ERROR_INVALID_PARAMETER; + } + + if (length <= 0) { + syslog(LOG_ERR, "spi: transfer_buf_word: Length given is equal to or less than zero, cannot proceed"); + return MRAA_ERROR_INVALID_PARAMETER; + } + + if (rxbuf != NULL) { + // length is given in bytes, but arrays are comprised of words + for (int i = 0; i < (length / 2); ++i) { + rxbuf[i] = data[i] ^ MOCK_SPI_REPLY_DATA_MODIFIER_WORD; + } + } + + return MRAA_SUCCESS; +} diff --git a/tests/mock/CMakeLists.txt b/tests/mock/CMakeLists.txt index 4de877a..98dd57c 100644 --- a/tests/mock/CMakeLists.txt +++ b/tests/mock/CMakeLists.txt @@ -22,6 +22,14 @@ add_test (NAME py_i2c_read_bytes_data COMMAND ${PYTHON_DEFAULT_EXECUTABLE} ${CMA add_test (NAME py_i2c_read_word_data COMMAND ${PYTHON_DEFAULT_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/i2c_checks_read_word_data.py) add_test (NAME py_i2c_write_word_data COMMAND ${PYTHON_DEFAULT_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/i2c_checks_write_word_data.py) +add_test (NAME py_spi_bit_per_word COMMAND ${PYTHON_DEFAULT_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/spi_checks_bit_per_word.py) +add_test (NAME py_spi_checks_lsbmode COMMAND ${PYTHON_DEFAULT_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/spi_checks_lsbmode.py) +add_test (NAME py_spi_checks_mode COMMAND ${PYTHON_DEFAULT_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/spi_checks_mode.py) +add_test (NAME py_spi_checks_freq COMMAND ${PYTHON_DEFAULT_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/spi_checks_freq.py) +add_test (NAME py_spi_checks_write_byte COMMAND ${PYTHON_DEFAULT_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/spi_checks_write_byte.py) +add_test (NAME py_spi_checks_write_word COMMAND ${PYTHON_DEFAULT_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/spi_checks_write_word.py) +add_test (NAME py_spi_checks_write COMMAND ${PYTHON_DEFAULT_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/spi_checks_write.py) + set_tests_properties(py_general py_platform py_gpio_basic @@ -42,4 +50,11 @@ set_tests_properties(py_general py_i2c_read_bytes_data py_i2c_read_word_data py_i2c_write_word_data + py_spi_bit_per_word + py_spi_checks_lsbmode + py_spi_checks_mode + py_spi_checks_freq + py_spi_checks_write_byte + py_spi_checks_write_word + py_spi_checks_write PROPERTIES ENVIRONMENT "PYTHONPATH=${PYTHON_DEFAULT_PYTHONPATH}") diff --git a/tests/mock/platform_checks.py b/tests/mock/platform_checks.py index f969477..dce6742 100755 --- a/tests/mock/platform_checks.py +++ b/tests/mock/platform_checks.py @@ -27,7 +27,7 @@ import mraa as m import unittest as u -PLATFORM_PINCOUNT = 4 +PLATFORM_PINCOUNT = 8 PLATFORM_STD_ADC_RES_BITS = 10 PLATFORM_MAX_ADC_RES_BITS = 12 diff --git a/tests/mock/spi_checks_bit_per_word.py b/tests/mock/spi_checks_bit_per_word.py new file mode 100644 index 0000000..f0ef1da --- /dev/null +++ b/tests/mock/spi_checks_bit_per_word.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python + +# Author: Alex Tereschenko +# Copyright (c) 2016 Alex Tereschenko. +# +# 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. + +import mraa as m +import unittest as u + +from spi_checks_shared import * + +class SpiChecksBitPerWord(u.TestCase): + def setUp(self): + self.spi = m.Spi(MRAA_SPI_BUS_NUM) + + def tearDown(self): + del self.spi + + def test_spi_bit_per_word(self): + TEST_BIT_PER_WORD = 16 + self.assertEqual(self.spi.bitPerWord(TEST_BIT_PER_WORD), + m.SUCCESS, + "Setting bit per word to %d did not return success" %TEST_BIT_PER_WORD) + + def test_i2c_frequency_invalid_smaller_than_min(self): + TEST_BIT_PER_WORD = -100 + self.assertRaises(OverflowError, self.spi.bitPerWord, TEST_BIT_PER_WORD) + +if __name__ == "__main__": + u.main() diff --git a/tests/mock/spi_checks_freq.py b/tests/mock/spi_checks_freq.py new file mode 100644 index 0000000..ec90a1a --- /dev/null +++ b/tests/mock/spi_checks_freq.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python + +# Author: Alex Tereschenko +# Copyright (c) 2016 Alex Tereschenko. +# +# 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. + +import mraa as m +import unittest as u + +from spi_checks_shared import * + +class SpiChecksFreq(u.TestCase): + def setUp(self): + self.spi = m.Spi(MRAA_SPI_BUS_NUM) + + def tearDown(self): + del self.spi + + def test_spi_set_freq(self): + TEST_FREQ = 20000000 + self.assertEqual(self.spi.frequency(TEST_FREQ), + m.SUCCESS, + "Setting SPI frequency to %d did not return success" %TEST_FREQ) + + def test_spi_set_freq_invalid_smaller_than_min_zero(self): + TEST_FREQ = 0 + self.assertEqual(self.spi.frequency(TEST_FREQ), + m.ERROR_INVALID_PARAMETER, + "Setting SPI frequency to %d did not return error" %TEST_FREQ) + + def test_spi_set_freq_invalid_smaller_than_min_negative(self): + TEST_FREQ = -10 + self.assertEqual(self.spi.frequency(TEST_FREQ), + m.ERROR_INVALID_PARAMETER, + "Setting SPI frequency to %d did not return error" %TEST_FREQ) + +if __name__ == "__main__": + u.main() diff --git a/tests/mock/spi_checks_lsbmode.py b/tests/mock/spi_checks_lsbmode.py new file mode 100644 index 0000000..f70f328 --- /dev/null +++ b/tests/mock/spi_checks_lsbmode.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python + +# Author: Alex Tereschenko +# Copyright (c) 2016 Alex Tereschenko. +# +# 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. + +import mraa as m +import unittest as u + +from spi_checks_shared import * + +class SpiChecksLsbmode(u.TestCase): + def setUp(self): + self.spi = m.Spi(MRAA_SPI_BUS_NUM) + + def tearDown(self): + del self.spi + + def test_spi_set_lsbmode_false(self): + TEST_LSBMODE = False + self.assertEqual(self.spi.lsbmode(TEST_LSBMODE), + m.SUCCESS, + "Setting LSB mode to %s did not return success" %TEST_LSBMODE) + + def test_spi_set_lsbmode_true(self): + TEST_LSBMODE = True + self.assertEqual(self.spi.lsbmode(TEST_LSBMODE), + m.SUCCESS, + "Setting LSB mode to %s did not return success" %TEST_LSBMODE) + + def test_spi_set_lsbmode_invalid(self): + TEST_LSBMODE = 10 + self.assertRaises(TypeError, self.spi.lsbmode, TEST_LSBMODE) + + +if __name__ == "__main__": + u.main() diff --git a/tests/mock/spi_checks_mode.py b/tests/mock/spi_checks_mode.py new file mode 100644 index 0000000..c680508 --- /dev/null +++ b/tests/mock/spi_checks_mode.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python + +# Author: Alex Tereschenko +# Copyright (c) 2016 Alex Tereschenko. +# +# 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. + +import mraa as m +import unittest as u + +from spi_checks_shared import * + +class SpiChecksMode(u.TestCase): + def setUp(self): + self.spi = m.Spi(MRAA_SPI_BUS_NUM) + + def tearDown(self): + del self.spi + + def test_spi_set_mode_MODE0(self): + TEST_MODE = m.SPI_MODE0 + self.assertEqual(self.spi.mode(TEST_MODE), + m.SUCCESS, + "Setting SPI mode to %d did not return success" %TEST_MODE) + + def test_spi_set_mode_MODE1(self): + TEST_MODE = m.SPI_MODE1 + self.assertEqual(self.spi.mode(TEST_MODE), + m.SUCCESS, + "Setting SPI mode to %d did not return success" %TEST_MODE) + + def test_spi_set_mode_MODE2(self): + TEST_MODE = m.SPI_MODE2 + self.assertEqual(self.spi.mode(TEST_MODE), + m.SUCCESS, + "Setting SPI mode to %d did not return success" %TEST_MODE) + + def test_spi_set_mode_MODE3(self): + TEST_MODE = m.SPI_MODE3 + self.assertEqual(self.spi.mode(TEST_MODE), + m.SUCCESS, + "Setting SPI mode to %d did not return success" %TEST_MODE) + + def test_spi_set_mode_invalid_smaller_than_min(self): + TEST_MODE = -10 + self.assertEqual(self.spi.mode(TEST_MODE), + m.ERROR_INVALID_PARAMETER, + "Setting SPI mode to %d did not return error" %TEST_MODE) + + def test_spi_set_mode_invalid_bigger_than_max(self): + TEST_MODE = 150 + self.assertEqual(self.spi.mode(TEST_MODE), + m.ERROR_INVALID_PARAMETER, + "Setting SPI mode to %d did not return error" %TEST_MODE) + +if __name__ == "__main__": + u.main() diff --git a/tests/mock/spi_checks_shared.py b/tests/mock/spi_checks_shared.py new file mode 100644 index 0000000..7564893 --- /dev/null +++ b/tests/mock/spi_checks_shared.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python + +# Author: Alex Tereschenko +# Copyright (c) 2016 Alex Tereschenko. +# +# 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. + +MRAA_SPI_BUS_NUM = 0 +MOCK_SPI_REPLY_DATA_MODIFIER_BYTE = 0xAB +MOCK_SPI_REPLY_DATA_MODIFIER_WORD = 0xABBA +MOCK_SPI_TEST_DATA_LEN = 5 diff --git a/tests/mock/spi_checks_write.py b/tests/mock/spi_checks_write.py new file mode 100644 index 0000000..717383b --- /dev/null +++ b/tests/mock/spi_checks_write.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python + +# Author: Alex Tereschenko +# Copyright (c) 2016 Alex Tereschenko. +# +# 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. + +import mraa as m +import unittest as u + +from spi_checks_shared import * + +class SpiChecksWrite(u.TestCase): + def setUp(self): + self.spi = m.Spi(MRAA_SPI_BUS_NUM) + + def tearDown(self): + del self.spi + + def test_spi_write(self): + DATA_TO_WRITE = bytearray([0xEE for i in range(MOCK_SPI_TEST_DATA_LEN)]) + DATA_TO_EXPECT = bytearray([0xEE ^ MOCK_SPI_REPLY_DATA_MODIFIER_BYTE for i in range(MOCK_SPI_TEST_DATA_LEN)]) + self.assertEqual(self.spi.write(DATA_TO_WRITE), + DATA_TO_EXPECT, + "SPI write() returned unexpected data") + +if __name__ == "__main__": + u.main() diff --git a/tests/mock/spi_checks_write_byte.py b/tests/mock/spi_checks_write_byte.py new file mode 100644 index 0000000..92d1816 --- /dev/null +++ b/tests/mock/spi_checks_write_byte.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python + +# Author: Alex Tereschenko +# Copyright (c) 2016 Alex Tereschenko. +# +# 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. + +import mraa as m +import unittest as u + +from spi_checks_shared import * + +class SpiChecksWriteByte(u.TestCase): + def setUp(self): + self.spi = m.Spi(MRAA_SPI_BUS_NUM) + + def tearDown(self): + del self.spi + + def test_spi_write_byte(self): + TEST_BYTE = 0xEE + self.assertEqual(self.spi.writeByte(TEST_BYTE), + TEST_BYTE ^ MOCK_SPI_REPLY_DATA_MODIFIER_BYTE, + "SPI writeByte() returned unexpected data") + + def test_spi_write_byte_invalid_bigger_than_max(self): + TEST_VALUE = 0xEEFF + self.assertRaises(OverflowError, self.spi.writeByte, TEST_VALUE) + + def test_spi_write_byte_invalid_smaller_than_min(self): + TEST_VALUE = -1 + self.assertRaises(OverflowError, self.spi.writeByte, TEST_VALUE) + +if __name__ == "__main__": + u.main() diff --git a/tests/mock/spi_checks_write_word.py b/tests/mock/spi_checks_write_word.py new file mode 100644 index 0000000..7d17e23 --- /dev/null +++ b/tests/mock/spi_checks_write_word.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python + +# Author: Alex Tereschenko +# Copyright (c) 2016 Alex Tereschenko. +# +# 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. + +import mraa as m +import unittest as u + +from spi_checks_shared import * + +class SpiChecksWriteWord(u.TestCase): + def setUp(self): + self.spi = m.Spi(MRAA_SPI_BUS_NUM) + + def tearDown(self): + del self.spi + + def test_spi_write_word(self): + TEST_WORD = 0xAAEE + self.assertEqual(self.spi.writeWord(TEST_WORD), + TEST_WORD ^ MOCK_SPI_REPLY_DATA_MODIFIER_WORD, + "SPI writeWord() returned unexpected data") + + def test_spi_write_word_invalid_bigger_than_max(self): + TEST_VALUE = 0xEEFFEE + self.assertRaises(OverflowError, self.spi.writeWord, TEST_VALUE) + + def test_spi_write_word_invalid_smaller_than_min(self): + TEST_VALUE = -1 + self.assertRaises(OverflowError, self.spi.writeWord, TEST_VALUE) + +if __name__ == "__main__": + u.main()