From c87bc66a8348a46d3632f59ae9b7c9e232f1447e Mon Sep 17 00:00:00 2001 From: AnthonyQ619 <68413443+AnthonyQ619@users.noreply.github.com> Date: Fri, 16 Jul 2021 14:58:49 -0700 Subject: [PATCH 01/49] adding ci-tests --- examples/ci-tests/ble/Makefile | 17 +++ examples/ci-tests/ble/README.md | 15 +++ examples/ci-tests/ble/main.c | 74 ++++++++++++ examples/ci-tests/ble/test.py | 88 ++++++++++++++ examples/ci-tests/gpio/Makefile | 11 ++ examples/ci-tests/gpio/README.md | 20 ++++ examples/ci-tests/gpio/main.c | 89 +++++++++++++++ examples/ci-tests/gpio/test.py | 184 ++++++++++++++++++++++++++++++ examples/ci-tests/uart/Makefile | 11 ++ examples/ci-tests/uart/main.c | 40 +++++++ examples/ci-tests/uart/test.py | 56 +++++++++ examples/ci-tests/uartrt/Makefile | 11 ++ examples/ci-tests/uartrt/main.c | 54 +++++++++ examples/ci-tests/uartrt/test.py | 57 +++++++++ 14 files changed, 727 insertions(+) create mode 100644 examples/ci-tests/ble/Makefile create mode 100644 examples/ci-tests/ble/README.md create mode 100644 examples/ci-tests/ble/main.c create mode 100644 examples/ci-tests/ble/test.py create mode 100644 examples/ci-tests/gpio/Makefile create mode 100644 examples/ci-tests/gpio/README.md create mode 100644 examples/ci-tests/gpio/main.c create mode 100644 examples/ci-tests/gpio/test.py create mode 100644 examples/ci-tests/uart/Makefile create mode 100644 examples/ci-tests/uart/main.c create mode 100644 examples/ci-tests/uart/test.py create mode 100644 examples/ci-tests/uartrt/Makefile create mode 100644 examples/ci-tests/uartrt/main.c create mode 100644 examples/ci-tests/uartrt/test.py diff --git a/examples/ci-tests/ble/Makefile b/examples/ci-tests/ble/Makefile new file mode 100644 index 000000000..35dae882c --- /dev/null +++ b/examples/ci-tests/ble/Makefile @@ -0,0 +1,17 @@ +# Makefile for user application + +# Specify this directory relative to the current application. +TOCK_USERLAND_BASE_DIR = ../../.. + +# Which files to compile. +C_SRCS := $(wildcard *.c) + +# External libraries used +EXTERN_LIBS += $(TOCK_USERLAND_BASE_DIR)/simple-ble + +# Include userland master makefile. Contains rules and flags for actually +# building the application. +include $(TOCK_USERLAND_BASE_DIR)/AppMakefile.mk + +# Include simple-ble's Makefile so it's rebuilt automatically +include $(TOCK_USERLAND_BASE_DIR)/simple-ble/Makefile diff --git a/examples/ci-tests/ble/README.md b/examples/ci-tests/ble/README.md new file mode 100644 index 000000000..fd2e049a4 --- /dev/null +++ b/examples/ci-tests/ble/README.md @@ -0,0 +1,15 @@ +# Hardware CI Tests + +## Run Python Test + +To run the test, +```bash +sudo python3 test.py Nrf52840GpioTest +``` + +Switch board name to the test you intend to run. Otherwise, python unittest +will attempt to run all tests. + +Board | Test Name +------|---------- +nrf52840dk | Nrf52840Test diff --git a/examples/ci-tests/ble/main.c b/examples/ci-tests/ble/main.c new file mode 100644 index 000000000..9b4b0a5d1 --- /dev/null +++ b/examples/ci-tests/ble/main.c @@ -0,0 +1,74 @@ +#include +#include +#include +#include +#include + +// Sizes in bytes +#define DEVICE_NAME_SIZE 6 +#define UUIDS_SIZE 4 +#define MANUFACTURER_DATA_SIZE 2 +#define FAKE_TEMPERATURE_DATA_SIZE 2 + +/******************************************************************************* + * MAIN + ******************************************************************************/ + +int main(void) { + int err; + printf("[Tutorial] BLE Advertising\n"); + + // declarations of variables to be used in this BLE example application + uint16_t advertising_interval_ms = 20; + uint8_t device_name[] = "TockOS"; + uint16_t uuids[] = {0x1800, 0x1809}; + uint8_t manufacturer_data[] = {0x13, 0x37}; + uint8_t fake_temperature_data[] = {0x00, 0x00}; + + static uint8_t adv_data_buf[ADV_DATA_MAX_SIZE]; + + // configure advertisement interval to 300ms + // configure LE only and discoverable + printf(" - Initializing BLE... %s\n", device_name); + AdvData_t adv_data = gap_adv_data_new(adv_data_buf, sizeof(adv_data_buf)); + + gap_add_flags(&adv_data, LE_GENERAL_DISCOVERABLE | BREDR_NOT_SUPPORTED); + + // configure device name as TockOS + printf(" - Setting the device name... %s\n", device_name); + err = gap_add_device_name(&adv_data, device_name, DEVICE_NAME_SIZE); + if (err < RETURNCODE_SUCCESS) + printf("ble_advertise_name, error: %s\r\n", tock_strrcode(err)); + + // configure list of UUIDs */ + printf(" - Setting the device UUID...\n"); + err = gap_add_service_uuid16(&adv_data, uuids, UUIDS_SIZE); + if (err < RETURNCODE_SUCCESS) + printf("ble_advertise_uuid16, error: %s\r\n", tock_strrcode(err)); + + // configure manufacturer data + printf(" - Setting manufacturer data...\n"); + err = gap_add_manufacturer_specific_data(&adv_data, manufacturer_data, + MANUFACTURER_DATA_SIZE); + if (err < RETURNCODE_SUCCESS) + printf("ble_advertise_manufacturer_specific_data, error: %s\r\n", + tock_strrcode(err)); + + // configure service data + printf(" - Setting service data...\n"); + err = gap_add_service_data(&adv_data, uuids[1], fake_temperature_data, + FAKE_TEMPERATURE_DATA_SIZE); + if (err < RETURNCODE_SUCCESS) + printf("ble_advertise_service_data, error: %s\r\n", tock_strrcode(err)); + + // start advertising + printf(" - Begin advertising! %s\n", device_name); + err = ble_start_advertising(ADV_NONCONN_IND, adv_data.buf, adv_data.offset, advertising_interval_ms); + if (err < RETURNCODE_SUCCESS) + printf("ble_start_advertising, error: %s\r\n", tock_strrcode(err)); + + // configuration complete + printf("Now advertising every %d ms as '%s'\n", advertising_interval_ms, + device_name); + return 0; +} diff --git a/examples/ci-tests/ble/test.py b/examples/ci-tests/ble/test.py new file mode 100644 index 000000000..422977a15 --- /dev/null +++ b/examples/ci-tests/ble/test.py @@ -0,0 +1,88 @@ +# BLE Test +# This tester corresponds to libtock-c/examples/ci-tests/ble test. + +import logging +import time +import unittest +import os + +################################################################################ +# Helper classes and functions +################################################################################ + +def time_gap(start_time): + """Return time gap between current time and start_time + + Argument: + start_time - Start time + """ + return "{:.6f}".format(time.time() - start_time) + +# END + +################################################################################ +# Start test and logger +################################################################################ + +# Test Start Time +TEST_START_TIME = time.time() + +# Logger set format +LOG_FORMAT = "%(timegap)s %(levelname)s -- %(message)s" +logging.basicConfig(format=LOG_FORMAT) + +# Logger add formatter +logger = logging.getLogger('BLE Test') +logger.setLevel('INFO') + +logger.info('Initiating BLE test...', + extra={'timegap': time_gap(TEST_START_TIME)}) + +# END + +################################################################################ +# Test Case Module +################################################################################ + +class BleTest(unittest.TestCase): + def test_ble_advertise(self): + """Check if the advertised device name can be found""" + # Change line from docs to logging info + print() + + logger.info('Bluetooth Status on RPi Harness\n', + extra={'timegap': time_gap(TEST_START_TIME)}) + os.system('sudo systemctl status bluetooth') + print() # Line change + os.system('sudo systemctl status hciuart') + print() # Line change + os.system('sudo timeout 5 stdbuf -oL hcitool lescan') + print() # Line change + logger.info('BLE scan ended.', + extra={'timegap': time_gap(TEST_START_TIME)}) + + # Restart bluetooth + # Note: the scanning process is corrupted whenever we try to kill it, so + # for now, we resort to restarting bluetooth every test, but if + # there is a better implementation, feel free to change this. + os.system('sudo hciconfig hci0 down; sudo hciconfig hci0 up') + +# END + +################################################################################ +# Test Case Setup +################################################################################ + +class Nrf52840Test(BleTest): + def setUp(self): + logger.info('Setting up for nrf52840dk BLE test...', + extra={'timegap': time_gap(TEST_START_TIME)}) + +# END + +################################################################################ +# Main +################################################################################ + +if __name__ == '__main__': + unittest.main() diff --git a/examples/ci-tests/gpio/Makefile b/examples/ci-tests/gpio/Makefile new file mode 100644 index 000000000..54d6a7969 --- /dev/null +++ b/examples/ci-tests/gpio/Makefile @@ -0,0 +1,11 @@ +# Makefile for user application + +# Specify this directory relative to the current application. +TOCK_USERLAND_BASE_DIR = ../../.. + +# Which files to compile. +C_SRCS := $(wildcard *.c) + +# Include userland master makefile. Contains rules and flags for actually +# building the application. +include $(TOCK_USERLAND_BASE_DIR)/AppMakefile.mk diff --git a/examples/ci-tests/gpio/README.md b/examples/ci-tests/gpio/README.md new file mode 100644 index 000000000..2e931f28b --- /dev/null +++ b/examples/ci-tests/gpio/README.md @@ -0,0 +1,20 @@ +# Hardware CI Tests + +## Run Python Test + +`test.py` provides basic tests that polls the pin output every 500 +milliseconds, and it monitors whether a toggle of the pin has occurred. If it +has occurred, it records the period to toggle the pin. The expected period +should be around 1 seconds with a margin of error within 1 millisecond. + +To run the test, +```bash +python3 test.py Nrf52840Test +``` + +Switch board name to the test you intend to run. Otherwise, python unittest +will attempt to run all tests. + +Board | Test Name +------|---------- +nrf52840dk | Nrf52840Test diff --git a/examples/ci-tests/gpio/main.c b/examples/ci-tests/gpio/main.c new file mode 100644 index 000000000..6573247b0 --- /dev/null +++ b/examples/ci-tests/gpio/main.c @@ -0,0 +1,89 @@ +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* The gpio pin gets toggled every 1000 ms */ +#define TOGGLE_PERIOD 1000 + +/* The number of toggle for each pin */ +#define TOGGLE_COUNT 4 + +/* Amount of cycle until timeout is claimed */ +#define TIMEOUT 1 + +/* Maximum GPIO pin number */ +#define MAX_PIN_NO 15 + +/* Prototype */ +uint8_t test_pin(bool *); +void set_gpios(void); + + +int callback_count = 0; +// callback for timers +static void timer_cb (__attribute__ ((unused)) int arg0, + __attribute__ ((unused)) int arg1, + __attribute__ ((unused)) int arg2, + __attribute__ ((unused)) void* userdata) { + callback_count = callback_count + 1; + *((bool*)userdata) = 1; +} + +void set_gpios(void) { + GPIO_Pin_t i = 0; + + for (; i <= MAX_PIN_NO; i++) { + gpio_enable_output(i); + } + + /* Set pin to high */ + for (i = 0; i <= MAX_PIN_NO; i++) { + gpio_set(i); + } +} + +uint8_t test_pin(bool * int_flag) { + uint8_t attempt_count = 0; + + while (attempt_count < TIMEOUT) { + + for (uint8_t i = 0; i < TOGGLE_COUNT; i++) { + yield_for(int_flag); + *int_flag = 0; /* Reset indicator */ + for (GPIO_Pin_t j = 0; j <= MAX_PIN_NO; j++) { + gpio_toggle(j); + } + } + + attempt_count++; + } + + return 1; +} + +static void gpio_test(void) { + tock_timer_t timer; /* Timer object */ + static bool int_flag = 0; /* Toggle trigger */ + + /* Initiate repeating timer */ + timer_every(TOGGLE_PERIOD, timer_cb, &int_flag, &timer); + + set_gpios(); + + /* Main loop */ + while (1) { + test_pin(&int_flag); + } +} + +int main(void) { + gpio_test(); + return 0; +} diff --git a/examples/ci-tests/gpio/test.py b/examples/ci-tests/gpio/test.py new file mode 100644 index 000000000..dc439c8db --- /dev/null +++ b/examples/ci-tests/gpio/test.py @@ -0,0 +1,184 @@ +# GPIO Test +# This tester corresponds to libtock-c/examples/ci-tests/gpio test. + +import logging +import time +import unittest +from gpiozero import InputDevice + +################################################################################ +# Helper classes and functions +################################################################################ + +def time_gap(start_time): + """Return time gap between current time and start_time + + Argument: + start_time - Start time + """ + return "{:.6f}".format(time.time() - start_time) + +class Pin: + """Pin object""" + def __init__(self, pin_no, pin_name = None): + # Set initial variables to invalid value + self.pin = InputDevice(pin_no) + + # Monitor variable + self.prev_state = -1 + self.prev_toggle_time = -1 + self.toggle_period = -1 + + # Test variable + self.has_toggled = False + + def read_pin(self): + """Reads input state and record toggle if a toggle of pin has been + observed. + + Argument: + state (boolean) - Input state of pin + """ + + # Check current pin state + if self.pin.value: + if self.prev_state == 0: + # Toggle appeared + if self.prev_toggle_time > 0: + self.toggle_period = time.time() - self.prev_toggle_time + self.has_toggled = True + + self.prev_toggle_time = time.time() + + self.prev_state = 1 + + else: + if self.prev_state == 1: + # Toggle appeared + if self.prev_toggle_time > 0: + self.toggle_period = time.time() - self.prev_toggle_time + self.has_toggled = True + + self.prev_toggle_time = time.time() + + self.prev_state = 0 + + def reset(self): + """Reset will only reset value of toggle_period by design""" + self.toggle_period = -1 + + def is_toggled(self): + """Check if the pin has been toggled in the past cycle""" + return self.toggle_period > 0 + +# END + +################################################################################ +# Start test and logger +################################################################################ + +# Test Start Time +TEST_START_TIME = time.time() + +# Logger set format +LOG_FORMAT = "%(timegap)s %(levelname)s -- %(message)s" +logging.basicConfig(format=LOG_FORMAT) + +# Logger add formatter +logger = logging.getLogger('GPIO Test') +logger.setLevel('INFO') + +logger.info('Initiating GPIO test...', + extra={'timegap': time_gap(TEST_START_TIME)}) + +# END + +################################################################################ +# Test Case Module +################################################################################ + +class GpioTest(unittest.TestCase): + def within_margin_error(self, value, target, margin_err): + """Check if the value is within the given margin of error""" + return value < target + margin_err and value > target - margin_err + + # Since the test toggles pin 0 every 1 second, the tester shall poll the pin + # state twice the output rate to capture the changes. + def test_sync_toggle(self): + """Monitoring pin state every 500 ms + + Note: Since the test toggles pin every 1 second, the tester shall poll + the pin state twice the output rate to capture the changes. + """ + # Change line from docs to logging info + print() + + TEST_CYCLE_TIME = 8 + EXPECTED_TIME_PERIOD = 1 + MOE = 0.01 + MAX_PIN_NO = 5 + + for pin_no in range(0, MAX_PIN_NO): + # If pin exists + if hasattr(self, f'P{pin_no}'): + pin_wrapper = getattr(self, f'P{pin_no}') + + # Monitor pin over cycle count + for n in range(TEST_CYCLE_TIME): + + # Log pin state + logger.info( + (f'P{pin_no} state: high' + if pin_wrapper.pin.value + else f'P{pin_no} state: low'), + extra={'timegap': time_gap(TEST_START_TIME)}) + + pin_wrapper.read_pin() + + # If pin just toggled + if pin_wrapper.is_toggled(): + logger.info( + (f'P{pin_no} state toggled in ' + + f'{pin_wrapper.toggle_period}s'), + extra={'timegap': time_gap(TEST_START_TIME)}) + + # ASSERT toggle period around 1 second + self.assertTrue( + self.within_margin_error(pin_wrapper.toggle_period, + EXPECTED_TIME_PERIOD, + MOE)) + + pin_wrapper.reset() + + # End of cycle, go to sleep + time.sleep(0.5) + + # Ensure pin has toggled + self.assertTrue(pin_wrapper.has_toggled) + +# END + +################################################################################ +# Test Case Setup +################################################################################ + +class Nrf52840Test(GpioTest): + def setUp(self): + logger.info('Setting up for nrf52840dk GPIO test...', + extra={'timegap': time_gap(TEST_START_TIME)}) + + # Assign input pins + self.P0 = Pin(5) + self.P1 = Pin(6) + self.P2 = Pin(13) + self.P3 = Pin(19) + self.P4 = Pin(26) + +# END + +################################################################################ +# Main +################################################################################ + +if __name__ == '__main__': + unittest.main() diff --git a/examples/ci-tests/uart/Makefile b/examples/ci-tests/uart/Makefile new file mode 100644 index 000000000..a38de484d --- /dev/null +++ b/examples/ci-tests/uart/Makefile @@ -0,0 +1,11 @@ +# Makefile for user application + +# Specify this directory relative to the current application. +TOCK_USERLAND_BASE_DIR = ../../.. + +# Which files to compile. +C_SRCS := $(wildcard *.c) + +# Include userland master makefile. Contains rules and flags for actually +# building the application. +include $(TOCK_USERLAND_BASE_DIR)/AppMakefile.mk \ No newline at end of file diff --git a/examples/ci-tests/uart/main.c b/examples/ci-tests/uart/main.c new file mode 100644 index 000000000..c8bdcaa46 --- /dev/null +++ b/examples/ci-tests/uart/main.c @@ -0,0 +1,40 @@ +#include +#include +#include +#include +#include +#include + +#define TARGET_INCOMING_MESSGAE "yeah" +char* message_received = ""; +int main(void){ + while(true){ + // Send Greeting Message + const char* message_sent = "cse145 is cool"; + putnstr(message_sent, (strlen(message_sent))); + // delay_ms(3000); + + // Expected Receive Message + + size_t len = 4; + getnstr(message_received, len); + delay_ms(3000); + // printf("hahaha\n"); + // printf("This is string received"); + // printf(message_received); + // printf("%d", strcmp(message_received, "")); + if(strcmp(message_received, "") != 0){ + break; + } + delay_ms(2000); + } + + printf("left while loop\n"); + while(true){ + // Send Acknowledgement + const char* ack = "true"; + putnstr(ack, (strlen(ack))); + } + + return 0; +} \ No newline at end of file diff --git a/examples/ci-tests/uart/test.py b/examples/ci-tests/uart/test.py new file mode 100644 index 000000000..a27e8747a --- /dev/null +++ b/examples/ci-tests/uart/test.py @@ -0,0 +1,56 @@ +import serial +import time + +TARGET_RECEIVED_MESSAGE = "cse145 is cool" +TARGET_ACKNOWLEDGEMENT = "true" + +sp = serial.Serial(port="/dev/ttyACM0", baudrate=115200, bytesize=8, timeout=2) +print("Starting Uart Test...") +while(True): + # print("B") + if(sp.in_waiting > 0): + message_received = sp.readline() + message_received = message_received.decode("Ascii") + # print(message_received) + # print("A") + + if(message_received == TARGET_RECEIVED_MESSAGE): + print("Correct Serial Communication Message Received") + break + +print("Uart Read Test Passes") +sp.close() +sp.open() +time.sleep(5) +# print("C") +sp.write(b"yeah") + +# while(True): +# # print("D") +# if(sp.in_waiting > 0): +# message_received = sp.readline().decode("Ascii") +# # print("This is python: ", message_received) +# # print("E") + +# if(message_received == TARGET_ACKNOWLEDGEMENT): +# print("Correct Acknowledgement Received") +# break + + +# sp.write(b"hihi") + +# while(True): +# print("D") +# if(sp.in_waiting > 0): +# message_received = sp.readline() +# message_received = message_received.decode("Ascii") +# print(message_received) +# print("E") + +# if(message_received == TARGET_ACKNOWLEDGEMENT): +# print("Correct Acknowledgement Received") +# break + + + + diff --git a/examples/ci-tests/uartrt/Makefile b/examples/ci-tests/uartrt/Makefile new file mode 100644 index 000000000..a38de484d --- /dev/null +++ b/examples/ci-tests/uartrt/Makefile @@ -0,0 +1,11 @@ +# Makefile for user application + +# Specify this directory relative to the current application. +TOCK_USERLAND_BASE_DIR = ../../.. + +# Which files to compile. +C_SRCS := $(wildcard *.c) + +# Include userland master makefile. Contains rules and flags for actually +# building the application. +include $(TOCK_USERLAND_BASE_DIR)/AppMakefile.mk \ No newline at end of file diff --git a/examples/ci-tests/uartrt/main.c b/examples/ci-tests/uartrt/main.c new file mode 100644 index 000000000..077347a67 --- /dev/null +++ b/examples/ci-tests/uartrt/main.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include +#include +#include + +char* echo_message = ""; +int main(void) { + + while (1) { + int c = getch(); + + /*if (c == RETURNCODE_FAIL) { + printf("\ngetch() failed!\n"); + } else { + printf("\n%c\n", (char) c); + }*/ + + //delay_ms(3000); + char m = (char) c; + + char message[3]; + + message[0] = 'r'; + message[1] = m; + message[2] = '\0'; + + printf("\n"); + delay_ms(1000); + + putnstr(message, (strlen(message))); + + //size_t len = 4; + //getnstr(echo_message, len); + //printf("%s", echo_message); + + delay_ms(3000); + /*if(strcmp(echo_message, "") != 0){ + printf("\n Finishing loop"); + break; + }*/ + delay_ms(2000); + } + + + /*while(true){ + // Send Acknowledgement + const char* ack = "true"; + putnstr(ack, (strlen(ack))); + } + return 0;*/ +} diff --git a/examples/ci-tests/uartrt/test.py b/examples/ci-tests/uartrt/test.py new file mode 100644 index 000000000..cf7b73cf8 --- /dev/null +++ b/examples/ci-tests/uartrt/test.py @@ -0,0 +1,57 @@ +import serial +import time +import random +import struct + +TARGET_ACKNOWLEDGEMENT = "" + +sp = serial.Serial(port="/dev/ttyACM0", baudrate=115200, bytesize=8, timeout=2) +ser = serial.Serial(port="/dev/ttyS0", baudrate=115200, bytesize=8, parity="N", stopbits=1); +print("Starting Uart Rx/TX Test...\n") +#replace with true +while(1): + c = random.randint(65, 90) + #c = "H" + #time.sleep(5) + message = chr(c) + ser.write(struct.pack(' 0): + # print("A") + print("Message sent: " + message) + #time.sleep(5) + sp.readline() + if(sp.in_waiting > 0): + message_received = sp.readline() + message_received = message_received.decode("Ascii") + print("Message: " + message_received) + char_received = message_received[-1] + print("Echoed: " + char_received + "\n") + if(char_received == message): + print("Correct Serial Communication Message Received") + break + + #print("Message sent: " + message) + #time.sleep(5) + #message_received = sp.readline() + #message_received = message_received.decode("Ascii") + #print("Message: " + message_received + "\n") + #char_received = message_received[0] + #print("Echoed: " + char_received) + + #if(char_received == message): + #print("Correct Serial Communication Message Received") + #break + + + +print("Uart Rx/Tx Test Passes") +sp.close() +ser.close() +sp.open() +ser.open() +time.sleep(4) +# print("C") +ser.write(b"yeah") From ab2541496d5e3a24fd4122354e2898aab881c1ca Mon Sep 17 00:00:00 2001 From: AnthonyQ619 <68413443+AnthonyQ619@users.noreply.github.com> Date: Fri, 16 Jul 2021 15:11:29 -0700 Subject: [PATCH 02/49] adding ci-tests --- examples/ci-tests/uart/test.py | 27 --------------------------- examples/ci-tests/uartrt/test.py | 19 +------------------ 2 files changed, 1 insertion(+), 45 deletions(-) diff --git a/examples/ci-tests/uart/test.py b/examples/ci-tests/uart/test.py index a27e8747a..3378574c8 100644 --- a/examples/ci-tests/uart/test.py +++ b/examples/ci-tests/uart/test.py @@ -22,35 +22,8 @@ sp.close() sp.open() time.sleep(5) -# print("C") sp.write(b"yeah") -# while(True): -# # print("D") -# if(sp.in_waiting > 0): -# message_received = sp.readline().decode("Ascii") -# # print("This is python: ", message_received) -# # print("E") - -# if(message_received == TARGET_ACKNOWLEDGEMENT): -# print("Correct Acknowledgement Received") -# break - - -# sp.write(b"hihi") - -# while(True): -# print("D") -# if(sp.in_waiting > 0): -# message_received = sp.readline() -# message_received = message_received.decode("Ascii") -# print(message_received) -# print("E") - -# if(message_received == TARGET_ACKNOWLEDGEMENT): -# print("Correct Acknowledgement Received") -# break - diff --git a/examples/ci-tests/uartrt/test.py b/examples/ci-tests/uartrt/test.py index cf7b73cf8..8f7ebe184 100644 --- a/examples/ci-tests/uartrt/test.py +++ b/examples/ci-tests/uartrt/test.py @@ -8,14 +8,11 @@ sp = serial.Serial(port="/dev/ttyACM0", baudrate=115200, bytesize=8, timeout=2) ser = serial.Serial(port="/dev/ttyS0", baudrate=115200, bytesize=8, parity="N", stopbits=1); print("Starting Uart Rx/TX Test...\n") -#replace with true while(1): c = random.randint(65, 90) - #c = "H" - #time.sleep(5) message = chr(c) ser.write(struct.pack(' 0): @@ -33,19 +30,6 @@ print("Correct Serial Communication Message Received") break - #print("Message sent: " + message) - #time.sleep(5) - #message_received = sp.readline() - #message_received = message_received.decode("Ascii") - #print("Message: " + message_received + "\n") - #char_received = message_received[0] - #print("Echoed: " + char_received) - - #if(char_received == message): - #print("Correct Serial Communication Message Received") - #break - - print("Uart Rx/Tx Test Passes") sp.close() @@ -53,5 +37,4 @@ sp.open() ser.open() time.sleep(4) -# print("C") ser.write(b"yeah") From 86bca3a9db5d313398e7d90b0050b64335f2f5e0 Mon Sep 17 00:00:00 2001 From: Hector Quiroga Date: Thu, 22 Jul 2021 22:10:31 -0700 Subject: [PATCH 03/49] New i2c tests --- examples/sampletests/i2cexamples/Makefile | 11 ++++++++ examples/sampletests/i2cexamples/main.c | 31 +++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 examples/sampletests/i2cexamples/Makefile create mode 100644 examples/sampletests/i2cexamples/main.c diff --git a/examples/sampletests/i2cexamples/Makefile b/examples/sampletests/i2cexamples/Makefile new file mode 100644 index 000000000..c13e35823 --- /dev/null +++ b/examples/sampletests/i2cexamples/Makefile @@ -0,0 +1,11 @@ +# Makefile for user application + +# Specify this directory relative to the current application. +TOCK_USERLAND_BASE_DIR = ../../../../ + +# Which files to compile. +C_SRCS := $(wildcard *.c) + +# Include userland master makefile. Contains rules and flags for actually +# building the application. +include $(TOCK_USERLAND_BASE_DIR)/AppMakefile.mk \ No newline at end of file diff --git a/examples/sampletests/i2cexamples/main.c b/examples/sampletests/i2cexamples/main.c new file mode 100644 index 000000000..10044a323 --- /dev/null +++ b/examples/sampletests/i2cexamples/main.c @@ -0,0 +1,31 @@ +#include +#include + +#include +#include +#include + +#define BUF_SIZE 16 +#define LEADER_ADDRESS 0x40 +#define FOLLOW_ADDRESS 0x41 + +uint8_t slave_write_buf[BUF_SIZE]; +uint8_t slave_read_buf[BUF_SIZE]; + +int main(void) { + printf("I2C Slave Read \n"); + + // Prepare buffers + + // Set up I2C peripheral + //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_callback(i2c_callback, NULL)); + //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_master_write_buffer(master_write_buf, BUF_SIZE)); + //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_master_read_buffer(master_read_buf, BUF_SIZE)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_enable_slave_read(BUF_SIZE)); + + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_write_buffer(slave_write_buf, BUF_SIZE)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_read_buffer(slave_read_buf, BUF_SIZE)); + + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_address(FOLLOW_ADDRESS)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_listen()); +} From 53aac3f74c908d6f10b70beedfe96f305a7db42d Mon Sep 17 00:00:00 2001 From: Hector Quiroga Date: Fri, 23 Jul 2021 12:58:56 -0700 Subject: [PATCH 04/49] updated example apps --- examples/sampletests/i2cexamples/Makefile | 2 +- examples/sampletests/i2cexamples/main.c | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/examples/sampletests/i2cexamples/Makefile b/examples/sampletests/i2cexamples/Makefile index c13e35823..bc0885323 100644 --- a/examples/sampletests/i2cexamples/Makefile +++ b/examples/sampletests/i2cexamples/Makefile @@ -1,7 +1,7 @@ # Makefile for user application # Specify this directory relative to the current application. -TOCK_USERLAND_BASE_DIR = ../../../../ +TOCK_USERLAND_BASE_DIR = ../../../ # Which files to compile. C_SRCS := $(wildcard *.c) diff --git a/examples/sampletests/i2cexamples/main.c b/examples/sampletests/i2cexamples/main.c index 10044a323..62fd8d099 100644 --- a/examples/sampletests/i2cexamples/main.c +++ b/examples/sampletests/i2cexamples/main.c @@ -12,15 +12,34 @@ uint8_t slave_write_buf[BUF_SIZE]; uint8_t slave_read_buf[BUF_SIZE]; +// In response to a +static void i2c_callback(int callback_type, + __attribute__ ((unused)) int length, + __attribute__ ((unused)) int arg2, + __attribute__ ((unused)) void* userdata) { + if (callback_type == TOCK_I2C_CB_MASTER_WRITE) { + printf("CB: Master write\n"); + } else if (callback_type == TOCK_I2C_CB_SLAVE_WRITE) { + printf("CB: Slave write\n"); + } else { + printf("ERROR: Unexepected callback: type %d\n", callback_type); + } +} + int main(void) { printf("I2C Slave Read \n"); + + strncpy(slave_write_buf, "0123456789ABCDEF", BUF_SIZE); + printf("Buffer is >%.*s<\n", BUF_SIZE, slave_write_buf); // Prepare buffers // Set up I2C peripheral //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_callback(i2c_callback, NULL)); //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_master_write_buffer(master_write_buf, BUF_SIZE)); //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_master_read_buffer(master_read_buf, BUF_SIZE)); + + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_callback(i2c_callback, NULL)); TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_enable_slave_read(BUF_SIZE)); TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_write_buffer(slave_write_buf, BUF_SIZE)); From 909cdeb3a7c62bc12522ddaeadffa2688b6118f6 Mon Sep 17 00:00:00 2001 From: AnthonyQ619 <68413443+AnthonyQ619@users.noreply.github.com> Date: Mon, 26 Jul 2021 21:55:14 -0700 Subject: [PATCH 05/49] Update test.py --- examples/ci-tests/uartrt/test.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/examples/ci-tests/uartrt/test.py b/examples/ci-tests/uartrt/test.py index 8f7ebe184..4d2f19c60 100644 --- a/examples/ci-tests/uartrt/test.py +++ b/examples/ci-tests/uartrt/test.py @@ -38,3 +38,9 @@ ser.open() time.sleep(4) ser.write(b"yeah") + + +class Nrf52840Test(UartTest): + def setUp(self): + logger.info('Setting up for nrf52840dk Uart Rx/Tx test...', + extra={'timegap': time_gap(TEST_START_TIME)}) From fdedb3152459beeef5444a576d8f3a2c1f721b62 Mon Sep 17 00:00:00 2001 From: AnthonyQ619 <68413443+AnthonyQ619@users.noreply.github.com> Date: Tue, 27 Jul 2021 12:19:29 -0700 Subject: [PATCH 06/49] Update test.py --- examples/ci-tests/uartrt/test.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/examples/ci-tests/uartrt/test.py b/examples/ci-tests/uartrt/test.py index 4d2f19c60..e787b976d 100644 --- a/examples/ci-tests/uartrt/test.py +++ b/examples/ci-tests/uartrt/test.py @@ -39,6 +39,33 @@ time.sleep(4) ser.write(b"yeah") +class UartTest(unittest.TestCase): + def test_uart_rx_tx: + while(1): + c = random.randint(65, 90) + message = chr(c) + ser.write(struct.pack(' 0): + # print("A") + print("Message sent: " + message) + #time.sleep(5) + sp.readline() + if(sp.in_waiting > 0): + message_received = sp.readline() + message_received = message_received.decode("Ascii") + print("Message: " + message_received) + char_received = message_received[-1] + print("Echoed: " + char_received + "\n") + if(char_received == message): + print("Correct Serial Communication Message Received") + self.assertTrue(true) + break + + + class Nrf52840Test(UartTest): def setUp(self): From e77afbf976ad0d16c2aff35a06b0fc9bebe0a771 Mon Sep 17 00:00:00 2001 From: AnthonyQ619 <68413443+AnthonyQ619@users.noreply.github.com> Date: Tue, 27 Jul 2021 21:39:14 -0700 Subject: [PATCH 07/49] Update test.py --- examples/ci-tests/uartrt/test.py | 126 ++++++++++++++++++++++--------- 1 file changed, 90 insertions(+), 36 deletions(-) diff --git a/examples/ci-tests/uartrt/test.py b/examples/ci-tests/uartrt/test.py index e787b976d..6e30023fe 100644 --- a/examples/ci-tests/uartrt/test.py +++ b/examples/ci-tests/uartrt/test.py @@ -8,66 +8,120 @@ sp = serial.Serial(port="/dev/ttyACM0", baudrate=115200, bytesize=8, timeout=2) ser = serial.Serial(port="/dev/ttyS0", baudrate=115200, bytesize=8, parity="N", stopbits=1); print("Starting Uart Rx/TX Test...\n") -while(1): - c = random.randint(65, 90) - message = chr(c) - ser.write(struct.pack(' 0): +# # print("A") +# print("Message sent: " + message) +# #time.sleep(5) +# sp.readline() +# if(sp.in_waiting > 0): +# message_received = sp.readline() +# message_received = message_received.decode("Ascii") +# print("Message: " + message_received) +# char_received = message_received[-1] +# print("Echoed: " + char_received + "\n") +# if(char_received == message): +# print("Correct Serial Communication Message Received") +# break +# - - time.sleep(5) - if(sp.in_waiting > 0): - # print("A") - print("Message sent: " + message) - #time.sleep(5) - sp.readline() - if(sp.in_waiting > 0): - message_received = sp.readline() - message_received = message_received.decode("Ascii") - print("Message: " + message_received) - char_received = message_received[-1] - print("Echoed: " + char_received + "\n") - if(char_received == message): - print("Correct Serial Communication Message Received") - break - - -print("Uart Rx/Tx Test Passes") -sp.close() -ser.close() -sp.open() -ser.open() -time.sleep(4) -ser.write(b"yeah") +#print("Uart Rx/Tx Test Passes") +#sp.close() +#ser.close() +#sp.open() +#ser.open() +#time.sleep(4) +#ser.write(b"yeah") + +################################################################################ +# Helper Functions +################################################################################ + +def time_gap(start_time): + """Return time gap between current time and start_time + Argument: + start_time - Start time + """ + return "{:.6f}".format(time.time() - start_time) +# END + +################################################################################ +# Start test and logger +################################################################################ + +# Test Start Time +TEST_START_TIME = time.time() + +# Logger set format +LOG_FORMAT = "%(timegap)s %(levelname)s -- %(message)s" +logging.basicConfig(format=LOG_FORMAT) + +# Logger add formatter +logger = logging.getLogger('UART Test') +logger.setLevel('INFO') + +logger.info('Initiating UART test...', + extra={'timegap': time_gap(TEST_START_TIME)}) + +# END + +################################################################################ +# Test Case Module +################################################################################ class UartTest(unittest.TestCase): def test_uart_rx_tx: while(1): c = random.randint(65, 90) - message = chr(c) + TARGET_ACKNOWLEDGEMENT = chr(c) ser.write(struct.pack(' 0): # print("A") - print("Message sent: " + message) + logger.info('Message sent: ' + TARGET_ACKNNOWLEDGEMENT, + extra={'timegap': time_gap(TEST_START_TIME)}) #time.sleep(5) sp.readline() if(sp.in_waiting > 0): message_received = sp.readline() message_received = message_received.decode("Ascii") - print("Message: " + message_received) + #print("Message: " + message_received) char_received = message_received[-1] - print("Echoed: " + char_received + "\n") - if(char_received == message): + #print("Echoed: " + char_received + "\n") + if(char_received == TARGET_ACKNOWLEDGEMENT): + print("Message Received (r[character]): " + message_received) + print("Echoed: " + char_received + "\n") print("Correct Serial Communication Message Received") self.assertTrue(true) break - +# END + +################################################################################ +# Test Case Setup +################################################################################ class Nrf52840Test(UartTest): def setUp(self): logger.info('Setting up for nrf52840dk Uart Rx/Tx test...', extra={'timegap': time_gap(TEST_START_TIME)}) + +# END + +################################################################################ +# Main +################################################################################ + +if __name__ == '__main__': + unittest.main() From 3ca593c2c6fa2739ad5a044c811373b6f53c8c3c Mon Sep 17 00:00:00 2001 From: AnthonyQ619 Date: Wed, 28 Jul 2021 05:55:34 +0000 Subject: [PATCH 08/49] Fixed uartrt test.py --- examples/ci-tests/uartrt/test.py | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/examples/ci-tests/uartrt/test.py b/examples/ci-tests/uartrt/test.py index 6e30023fe..77a6fb57c 100644 --- a/examples/ci-tests/uartrt/test.py +++ b/examples/ci-tests/uartrt/test.py @@ -1,3 +1,5 @@ +import logging +import unittest import serial import time import random @@ -76,8 +78,15 @@ def time_gap(start_time): ################################################################################ class UartTest(unittest.TestCase): - def test_uart_rx_tx: + def test_uart_rx_tx(self): while(1): + logger.info('Waiting for message...', + extra={'timegap': time_gap(TEST_START_TIME)}) + + buffer_period = float(time_gap(TEST_START_TIME)) + if(buffer_period > 45.0): + self.assertTrue(False) + c = random.randint(65, 90) TARGET_ACKNOWLEDGEMENT = chr(c) ser.write(struct.pack(' 0): # print("A") - logger.info('Message sent: ' + TARGET_ACKNNOWLEDGEMENT, + logger.info('Message sent: ' + TARGET_ACKNOWLEDGEMENT, extra={'timegap': time_gap(TEST_START_TIME)}) #time.sleep(5) sp.readline() @@ -99,10 +108,14 @@ def test_uart_rx_tx: char_received = message_received[-1] #print("Echoed: " + char_received + "\n") if(char_received == TARGET_ACKNOWLEDGEMENT): - print("Message Received (r[character]): " + message_received) - print("Echoed: " + char_received + "\n") + logger.info("Message Received (r[character]): " + message_received, + extra={'timegap': time_gap(TEST_START_TIME)}) + logger.info("Echoed: " + char_received, + extra={'timegap': time_gap(TEST_START_TIME)}) print("Correct Serial Communication Message Received") - self.assertTrue(true) + self.assertTrue(True) + sp.close() + ser.close() break # END From 622835e8add36d87b34097dffbc30d10edc4cc9a Mon Sep 17 00:00:00 2001 From: Hector Quiroga Date: Wed, 28 Jul 2021 19:38:37 -0700 Subject: [PATCH 09/49] New test added --- examples/ci-tests/i2c/Makefile | 11 +++ examples/ci-tests/i2c/main.c | 47 ++++++++++ examples/ci-tests/i2c/test.py | 118 ++++++++++++++++++++++++ examples/sampletests/i2cexamples/main.c | 10 +- 4 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 examples/ci-tests/i2c/Makefile create mode 100644 examples/ci-tests/i2c/main.c create mode 100644 examples/ci-tests/i2c/test.py diff --git a/examples/ci-tests/i2c/Makefile b/examples/ci-tests/i2c/Makefile new file mode 100644 index 000000000..a38de484d --- /dev/null +++ b/examples/ci-tests/i2c/Makefile @@ -0,0 +1,11 @@ +# Makefile for user application + +# Specify this directory relative to the current application. +TOCK_USERLAND_BASE_DIR = ../../.. + +# Which files to compile. +C_SRCS := $(wildcard *.c) + +# Include userland master makefile. Contains rules and flags for actually +# building the application. +include $(TOCK_USERLAND_BASE_DIR)/AppMakefile.mk \ No newline at end of file diff --git a/examples/ci-tests/i2c/main.c b/examples/ci-tests/i2c/main.c new file mode 100644 index 000000000..8bedb2995 --- /dev/null +++ b/examples/ci-tests/i2c/main.c @@ -0,0 +1,47 @@ +#include +#include + +#include +#include +#include + +#define BUF_SIZE 17 +#define LEADER_ADDRESS 0x40 +#define FOLLOW_ADDRESS 0x41 + +uint8_t slave_write_buf[BUF_SIZE]; +uint8_t slave_read_buf[BUF_SIZE]; + +// In response to a +static void i2c_callback(int callback_type, + __attribute__ ((unused)) int length, + __attribute__ ((unused)) int arg2, + __attribute__ ((unused)) void* userdata) { + + if (callback_type == TOCK_I2C_CB_SLAVE_WRITE) { + printf("CB: Slave write\n"); + printf("Write Buffer v2 is >%.*s<\n", BUF_SIZE, slave_write_buf); + } else { + printf("ERROR: Unexepected callback: type %d\n", callback_type); + } +} + +int main(void) { + printf("I2C Slave Read \n"); + + //Preparing buffer + strncpy(slave_write_buf, "0123456789ABCDEFG", BUF_SIZE); + printf("Buffer is >%.*s<\n", BUF_SIZE, slave_write_buf); + + // Set up I2C peripheral + + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_callback(i2c_callback, NULL)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_enable_slave_read(BUF_SIZE)); + + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_write_buffer(slave_write_buf, BUF_SIZE)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_read_buffer(slave_read_buf, BUF_SIZE)); + + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_address(FOLLOW_ADDRESS)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_listen()); + +} \ No newline at end of file diff --git a/examples/ci-tests/i2c/test.py b/examples/ci-tests/i2c/test.py new file mode 100644 index 000000000..8f4bfdfc6 --- /dev/null +++ b/examples/ci-tests/i2c/test.py @@ -0,0 +1,118 @@ +from smbus import SMBus +import time +import os +import logging +import subprocess +import unittest +import serial + +ADDRESS = 0x41 # bus address to the Slave Device +MASTER = 0x40 # Raspberry Pi Master Address +MESSAGE = "Hello I'm Master" # Message to send to slave +bus = SMBus(1) # indicates /dev/ic2-1 + + +################################################################################ +# Helper Functions +################################################################################ + +def time_gap(start_time): + """Return time gap between current time and start_time + Argument: + start_time - Start time + """ + return "{:.6f}".format(time.time() - start_time) + +def message_converter(message): + """Return list of ascii values for each character in message + Argument: + string I2C_message + """ + encoded = [] # Encoded message for ascii values + chars = list(message) # Spliting the string message into characters + + for items in char: + encoded.append(ord(items)) # Filling encoded with ascii values of characters + + return encoded + +# END + +################################################################################ +# Start test and logger +################################################################################ + +# Test Start Time +TEST_START_TIME = time.time() + +# Logger set format +LOG_FORMAT = "%(timegap)s %(levelname)s -- %(message)s" +logging.basicConfig(format=LOG_FORMAT) + +# Logger add formatter +logger = logging.getLogger('I2C Rx Test') +logger.setLevel('INFO') + +logger.info('Initiating I2C Rx test...', + extra={'timegap': time_gap(TEST_START_TIME)}) + +# END + +################################################################################ +# Test Case Module +################################################################################ + +class I2CRxTest: + def test_i2c_slave_configuration(self): + + print() + logger.info('Sending I2C Message: ' + , + extra={'timegap': time_gap(TEST_START_TIME)}) + + received = False + + message_to_send = message_converter(MESSAGE) + + try: + bus.write_i2c_block_data(ADDRESS, MASTER, message_to_send) + + logger.info('Message sent Sucessfully: {MESSAGE}\n' + scan_result_str, + extra={'timegap': time_gap(TEST_START_TIME)}) + + received = True + except OSError: + print("OS error: {0}".format(err)) + + logger.info('Test failed...' + scan_result_str, + extra={'timegap': time_gap(TEST_START_TIME)}) + print() + except TimeoutError: + logger.info('Connection is poor: Time out error...\n' + scan_result_str, + extra={'timegap': time_gap(TEST_START_TIME)}) + + logger.info('Test failed...' + scan_result_str, + extra={'timegap': time_gap(TEST_START_TIME)}) + print() + finally: + logger.info('I2C Communication Ended...' + scan_result_str, + extra={'timegap': time_gap(TEST_START_TIME)}) + self.assertTrue(received) +# END + +################################################################################ +# Test Case Setup +################################################################################ + +class Nrf52840Test(I2CRxTest): + def setUp(self): + logger.info('Setting up for nrf52840dk I2C Rx test...', + extra={'timegap': time_gap(TEST_START_TIME)}) + +# END + +################################################################################ +# Main +################################################################################ + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/examples/sampletests/i2cexamples/main.c b/examples/sampletests/i2cexamples/main.c index 62fd8d099..dd445ff18 100644 --- a/examples/sampletests/i2cexamples/main.c +++ b/examples/sampletests/i2cexamples/main.c @@ -5,7 +5,7 @@ #include #include -#define BUF_SIZE 16 +#define BUF_SIZE 17 #define LEADER_ADDRESS 0x40 #define FOLLOW_ADDRESS 0x41 @@ -17,10 +17,14 @@ static void i2c_callback(int callback_type, __attribute__ ((unused)) int length, __attribute__ ((unused)) int arg2, __attribute__ ((unused)) void* userdata) { + + printf("callback Num: %d\n", callback_type); if (callback_type == TOCK_I2C_CB_MASTER_WRITE) { printf("CB: Master write\n"); } else if (callback_type == TOCK_I2C_CB_SLAVE_WRITE) { printf("CB: Slave write\n"); + printf("Read Buffer v2 is >%.*s<\n", BUF_SIZE, slave_read_buf); + printf("Write Buffer v2 is >%.*s<\n", BUF_SIZE, slave_write_buf); } else { printf("ERROR: Unexepected callback: type %d\n", callback_type); } @@ -47,4 +51,8 @@ int main(void) { TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_address(FOLLOW_ADDRESS)); TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_listen()); + //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_enable_slave_read(BUF_SIZE)); + + printf("Read Buffer is >%.*s<\n", BUF_SIZE, slave_read_buf); + printf("Write Buffer is >%.*s<\n", BUF_SIZE, slave_write_buf); } From 79ae206470f54a6c1119faf096abfd22af995972 Mon Sep 17 00:00:00 2001 From: AnthonyQ619 Date: Thu, 29 Jul 2021 06:31:16 +0000 Subject: [PATCH 10/49] Fixed test.py bugs --- examples/ci-tests/i2c/test.py | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/examples/ci-tests/i2c/test.py b/examples/ci-tests/i2c/test.py index 8f4bfdfc6..66f94f77d 100644 --- a/examples/ci-tests/i2c/test.py +++ b/examples/ci-tests/i2c/test.py @@ -1,8 +1,6 @@ from smbus import SMBus import time -import os import logging -import subprocess import unittest import serial @@ -31,7 +29,7 @@ def message_converter(message): encoded = [] # Encoded message for ascii values chars = list(message) # Spliting the string message into characters - for items in char: + for items in chars: encoded.append(ord(items)) # Filling encoded with ascii values of characters return encoded @@ -62,40 +60,47 @@ def message_converter(message): # Test Case Module ################################################################################ -class I2CRxTest: +class I2CRxTest(unittest.TestCase): def test_i2c_slave_configuration(self): print() - logger.info('Sending I2C Message: ' + , + logger.info('Sending I2C Message: ' + MESSAGE, extra={'timegap': time_gap(TEST_START_TIME)}) received = False message_to_send = message_converter(MESSAGE) + time.sleep(1) try: bus.write_i2c_block_data(ADDRESS, MASTER, message_to_send) - logger.info('Message sent Sucessfully: {MESSAGE}\n' + scan_result_str, + logger.info('Message Sent Sucessfully.\n', extra={'timegap': time_gap(TEST_START_TIME)}) - + time.sleep(1) received = True except OSError: print("OS error: {0}".format(err)) - logger.info('Test failed...' + scan_result_str, + logger.info('Test failed...', extra={'timegap': time_gap(TEST_START_TIME)}) print() + + time.sleep(1) except TimeoutError: - logger.info('Connection is poor: Time out error...\n' + scan_result_str, + logger.info('Connection is poor: Time out error...\n', extra={'timegap': time_gap(TEST_START_TIME)}) - logger.info('Test failed...' + scan_result_str, + logger.info('Test failed...', extra={'timegap': time_gap(TEST_START_TIME)}) print() + + time.sleep(1) finally: - logger.info('I2C Communication Ended...' + scan_result_str, + logger.info('I2C Communication Ended...', extra={'timegap': time_gap(TEST_START_TIME)}) + + time.sleep(1) self.assertTrue(received) # END @@ -115,4 +120,4 @@ def setUp(self): ################################################################################ if __name__ == '__main__': - unittest.main() \ No newline at end of file + unittest.main() From 0eb25965259de6928ea6522f7f1a52c1486fe961 Mon Sep 17 00:00:00 2001 From: Hector Quiroga Date: Thu, 29 Jul 2021 20:20:20 -0700 Subject: [PATCH 11/49] New I2C examples --- examples/sampletests/i2cexamples/main.c | 18 +++- .../sampletests/i2cexamples/masterex/Makefile | 11 ++ .../sampletests/i2cexamples/masterex/main.c | 100 +++++++++++++++++ .../i2cexamples/masterread/Makefile | 11 ++ .../sampletests/i2cexamples/masterread/main.c | 101 ++++++++++++++++++ 5 files changed, 236 insertions(+), 5 deletions(-) create mode 100644 examples/sampletests/i2cexamples/masterex/Makefile create mode 100644 examples/sampletests/i2cexamples/masterex/main.c create mode 100644 examples/sampletests/i2cexamples/masterread/Makefile create mode 100644 examples/sampletests/i2cexamples/masterread/main.c diff --git a/examples/sampletests/i2cexamples/main.c b/examples/sampletests/i2cexamples/main.c index dd445ff18..619d22d0e 100644 --- a/examples/sampletests/i2cexamples/main.c +++ b/examples/sampletests/i2cexamples/main.c @@ -5,7 +5,7 @@ #include #include -#define BUF_SIZE 17 +#define BUF_SIZE 6 #define LEADER_ADDRESS 0x40 #define FOLLOW_ADDRESS 0x41 @@ -23,7 +23,13 @@ static void i2c_callback(int callback_type, printf("CB: Master write\n"); } else if (callback_type == TOCK_I2C_CB_SLAVE_WRITE) { printf("CB: Slave write\n"); - printf("Read Buffer v2 is >%.*s<\n", BUF_SIZE, slave_read_buf); + //printf("Read Buffer v2 is >%.*s<\n", BUF_SIZE, slave_read_buf); + //printf("Write Buffer v2 is >%.*s<\n", BUF_SIZE, slave_write_buf); + + delay_ms(2500); + + printf("%s sending\n", FOLLOW_ADDRESS); + //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(LEADER_ADDRESS, BUF_SIZE)); printf("Write Buffer v2 is >%.*s<\n", BUF_SIZE, slave_write_buf); } else { printf("ERROR: Unexepected callback: type %d\n", callback_type); @@ -34,7 +40,8 @@ int main(void) { printf("I2C Slave Read \n"); - strncpy(slave_write_buf, "0123456789ABCDEF", BUF_SIZE); + strncpy(slave_write_buf, "012345", BUF_SIZE); + int buffer_to_write = {0,1,2,3,4,5}; printf("Buffer is >%.*s<\n", BUF_SIZE, slave_write_buf); // Prepare buffers @@ -43,14 +50,15 @@ int main(void) { //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_master_write_buffer(master_write_buf, BUF_SIZE)); //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_master_read_buffer(master_read_buf, BUF_SIZE)); - TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_callback(i2c_callback, NULL)); - TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_enable_slave_read(BUF_SIZE)); + //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_callback(i2c_callback, NULL)); + //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_enable_slave_read(BUF_SIZE)); TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_write_buffer(slave_write_buf, BUF_SIZE)); TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_read_buffer(slave_read_buf, BUF_SIZE)); TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_address(FOLLOW_ADDRESS)); TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_listen()); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write_sync(LEADER_ADDRESS, BUF_SIZE, buffer_to_write)); //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_enable_slave_read(BUF_SIZE)); printf("Read Buffer is >%.*s<\n", BUF_SIZE, slave_read_buf); diff --git a/examples/sampletests/i2cexamples/masterex/Makefile b/examples/sampletests/i2cexamples/masterex/Makefile new file mode 100644 index 000000000..c13e35823 --- /dev/null +++ b/examples/sampletests/i2cexamples/masterex/Makefile @@ -0,0 +1,11 @@ +# Makefile for user application + +# Specify this directory relative to the current application. +TOCK_USERLAND_BASE_DIR = ../../../../ + +# Which files to compile. +C_SRCS := $(wildcard *.c) + +# Include userland master makefile. Contains rules and flags for actually +# building the application. +include $(TOCK_USERLAND_BASE_DIR)/AppMakefile.mk \ No newline at end of file diff --git a/examples/sampletests/i2cexamples/masterex/main.c b/examples/sampletests/i2cexamples/masterex/main.c new file mode 100644 index 000000000..87b95adcb --- /dev/null +++ b/examples/sampletests/i2cexamples/masterex/main.c @@ -0,0 +1,100 @@ +#include +#include + +#include +#include +#include + +#define BUF_SIZE 16 +#define LEADER_ADDRESS 0x40 +#define FOLLOW_ADDRESS 0x41 + +uint8_t master_write_buf[BUF_SIZE]; +uint8_t master_read_buf[BUF_SIZE]; +bool is_leader = false; + + +// In response to a +static void i2c_callback(int callback_type, + __attribute__ ((unused)) int length, + __attribute__ ((unused)) int arg2, + __attribute__ ((unused)) void* userdata) { + // Watching for GPIO interrupts holds us in a higher power state, so stop + // doing that once we don't care about button presses any more (the first + // time having sent or received a message) + static bool any_message = false; + if (!any_message) { + int nbuttons; + button_count(&nbuttons); + int j; + for (j = 0; j < nbuttons; j++) { + button_disable_interrupt(j); + } + } + + if (callback_type == TOCK_I2C_CB_MASTER_WRITE) { + printf("CB: Master write\n"); + + delay_ms(2500); + + printf("%s sending\n", is_leader ? "Leader" : "Follower"); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(is_leader ? FOLLOW_ADDRESS : LEADER_ADDRESS, BUF_SIZE)); + } else { + printf("ERROR: Unexepected callback: type %d\n", callback_type); + } +} + +// This is the callback for the button press. +// A button press indicates that this device should start the ping-pong +// exchange. First, change the address to the BUTTON_ADDRESS to avoid +// conflict with the other node, then send a message. +static void button_cb(__attribute__((unused)) int btn_num, + __attribute__ ((unused)) int arg1, + __attribute__ ((unused)) int arg2, + __attribute__ ((unused)) void* userdata) { + // Only the first press is meaningfull + static bool pressed = false; + + if (!pressed) { + pressed = true; + is_leader = true; + + printf("Switching to master\n"); + + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(FOLLOW_ADDRESS, BUF_SIZE)); + printf("Switched\n"); + } +} + +// This function sets up the I2C peripheral with needed buffers and prepares +// callbacks for I2C and button presses. Normal operation of this test takes +// place in the subsequent callbacks. +int main(void) { + printf("I2C Master Write App!\n"); + + // Prepare buffers + strcpy((char*) master_write_buf, "Hello friend.\n"); + + // Set up I2C peripheral + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_callback(i2c_callback, NULL)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_master_write_buffer(master_write_buf, BUF_SIZE)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_master_read_buffer(master_read_buf, BUF_SIZE)); + + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_address(LEADER_ADDRESS)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_listen()); + + // Set up button peripheral to grab any button press + TOCK_EXPECT(RETURNCODE_SUCCESS, button_subscribe(button_cb, NULL)); + + int nbuttons; + button_count(&nbuttons); + if (nbuttons < 1) { + printf("ERROR: This app requires that a board have at least one button.\n"); + exit(-1); + } + + int j; + for (j = 0; j < nbuttons; j++) { + TOCK_EXPECT(RETURNCODE_SUCCESS, button_enable_interrupt(j)); + } +} \ No newline at end of file diff --git a/examples/sampletests/i2cexamples/masterread/Makefile b/examples/sampletests/i2cexamples/masterread/Makefile new file mode 100644 index 000000000..c13e35823 --- /dev/null +++ b/examples/sampletests/i2cexamples/masterread/Makefile @@ -0,0 +1,11 @@ +# Makefile for user application + +# Specify this directory relative to the current application. +TOCK_USERLAND_BASE_DIR = ../../../../ + +# Which files to compile. +C_SRCS := $(wildcard *.c) + +# Include userland master makefile. Contains rules and flags for actually +# building the application. +include $(TOCK_USERLAND_BASE_DIR)/AppMakefile.mk \ No newline at end of file diff --git a/examples/sampletests/i2cexamples/masterread/main.c b/examples/sampletests/i2cexamples/masterread/main.c new file mode 100644 index 000000000..6e7dc2435 --- /dev/null +++ b/examples/sampletests/i2cexamples/masterread/main.c @@ -0,0 +1,101 @@ +#include +#include + +#include +#include +#include + +#define BUF_SIZE 16 +#define LEADER_ADDRESS 0x40 +#define FOLLOW_ADDRESS 0x41 + +uint8_t master_write_buf[BUF_SIZE]; +uint8_t master_read_buf[BUF_SIZE]; + +bool is_leader = false; + + +// In response to a +static void i2c_callback(int callback_type, + __attribute__ ((unused)) int length, + __attribute__ ((unused)) int arg2, + __attribute__ ((unused)) void* userdata) { + // Watching for GPIO interrupts holds us in a higher power state, so stop + // doing that once we don't care about button presses any more (the first + // time having sent or received a message) + static bool any_message = false; + if (!any_message) { + int nbuttons; + button_count(&nbuttons); + int j; + for (j = 0; j < nbuttons; j++) { + button_disable_interrupt(j); + } + } + + if (callback_type == TOCK_I2C_CB_MASTER_READ) { + printf("Master Reader: \n"); + delay_ms(2500); + + printf("Read Buffer After: >%.*s<\n", BUF_SIZE, master_read_buf); + } else { + printf("ERROR: Unexepected callback: type %d\n", callback_type); + } +} + +// This is the callback for the button press. +// A button press indicates that this device should start the ping-pong +// exchange. First, change the address to the BUTTON_ADDRESS to avoid +// conflict with the other node, then send a message. +static void button_cb(__attribute__((unused)) int btn_num, + __attribute__ ((unused)) int arg1, + __attribute__ ((unused)) int arg2, + __attribute__ ((unused)) void* userdata) { + // Only the first press is meaningfull + static bool pressed = false; + + if (!pressed) { + pressed = true; + is_leader = true; + + printf("Getting Message\n"); + + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_read(FOLLOW_ADDRESS, BUF_SIZE)); + } +} + +// This function sets up the I2C peripheral with needed buffers and prepares +// callbacks for I2C and button presses. Normal operation of this test takes +// place in the subsequent callbacks. +int main(void) { + printf("I2C Master Read Test\n"); + + // Prepare buffers + strcpy((char*) master_write_buf, "Hello friend.\n"); + strcpy((char*) master_read_buf, "Nothing,Nowhere"); + + // Set up I2C peripheral + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_callback(i2c_callback, NULL)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_master_write_buffer(master_write_buf, BUF_SIZE)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_master_read_buffer(master_read_buf, BUF_SIZE)); + + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_address(LEADER_ADDRESS)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_listen()); + + // Set up button peripheral to grab any button press + TOCK_EXPECT(RETURNCODE_SUCCESS, button_subscribe(button_cb, NULL)); + printf("Read Buffer Before: >%.*s<\n", BUF_SIZE, master_read_buf); + + + int nbuttons; + button_count(&nbuttons); + if (nbuttons < 1) { + printf("ERROR: This app requires that a board have at least one button.\n"); + exit(-1); + } + + int j; + for (j = 0; j < nbuttons; j++) { + TOCK_EXPECT(RETURNCODE_SUCCESS, button_enable_interrupt(j)); + } +} \ No newline at end of file From 92033d10d018d92fc686eeb00e60d47042b8c5a1 Mon Sep 17 00:00:00 2001 From: Hector Quiroga Date: Fri, 30 Jul 2021 12:20:08 -0700 Subject: [PATCH 12/49] Update --- .../i2cexamples/slavewrite/Makefile | 11 ++ .../sampletests/i2cexamples/slavewrite/main.c | 107 ++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 examples/sampletests/i2cexamples/slavewrite/Makefile create mode 100644 examples/sampletests/i2cexamples/slavewrite/main.c diff --git a/examples/sampletests/i2cexamples/slavewrite/Makefile b/examples/sampletests/i2cexamples/slavewrite/Makefile new file mode 100644 index 000000000..c13e35823 --- /dev/null +++ b/examples/sampletests/i2cexamples/slavewrite/Makefile @@ -0,0 +1,11 @@ +# Makefile for user application + +# Specify this directory relative to the current application. +TOCK_USERLAND_BASE_DIR = ../../../../ + +# Which files to compile. +C_SRCS := $(wildcard *.c) + +# Include userland master makefile. Contains rules and flags for actually +# building the application. +include $(TOCK_USERLAND_BASE_DIR)/AppMakefile.mk \ No newline at end of file diff --git a/examples/sampletests/i2cexamples/slavewrite/main.c b/examples/sampletests/i2cexamples/slavewrite/main.c new file mode 100644 index 000000000..46db1b9e1 --- /dev/null +++ b/examples/sampletests/i2cexamples/slavewrite/main.c @@ -0,0 +1,107 @@ +#include +#include + +#include +#include +#include + +#define BUF_SIZE 16 +#define LEADER_ADDRESS 0x40 +#define FOLLOW_ADDRESS 0x41 + +uint8_t master_write_buf[BUF_SIZE]; +uint8_t master_read_buf[BUF_SIZE]; +uint8_t slave_write_buf[BUF_SIZE]; +uint8_t slave_read_buf[BUF_SIZE]; +bool is_leader = false; + + +// In response to a +static void i2c_callback(int callback_type, + __attribute__ ((unused)) int length, + __attribute__ ((unused)) int arg2, + __attribute__ ((unused)) void* userdata) { + // Watching for GPIO interrupts holds us in a higher power state, so stop + // doing that once we don't care about button presses any more (the first + // time having sent or received a message) + static bool any_message = false; + if (!any_message) { + int nbuttons; + button_count(&nbuttons); + int j; + for (j = 0; j < nbuttons; j++) { + button_disable_interrupt(j); + } + } + + printf("Inside Callback"); + if (callback_type == TOCK_I2C_CB_MASTER_WRITE) { + printf("CB: Master write\n"); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_listen()); + } else if (callback_type == TOCK_I2C_CB_SLAVE_WRITE) { + printf("CB: Slave write\n"); + delay_ms(2500); + + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(LEADER_ADDRESS, BUF_SIZE)); + } else { + printf("ERROR: Unexepected callback: type %d\n", callback_type); + } +} + +// This is the callback for the button press. +// A button press indicates that this device should start the ping-pong +// exchange. First, change the address to the BUTTON_ADDRESS to avoid +// conflict with the other node, then send a message. +static void button_cb(__attribute__((unused)) int btn_num, + __attribute__ ((unused)) int arg1, + __attribute__ ((unused)) int arg2, + __attribute__ ((unused)) void* userdata) { + // Only the first press is meaningfull + static bool pressed = false; + + if (!pressed) { + pressed = true; + is_leader = true; + + printf("Sending to master\n"); + + //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_address(LEADER_ADDRESS)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(LEADER_ADDRESS, BUF_SIZE)); + //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_listen()); + } +} + +// This function sets up the I2C peripheral with needed buffers and prepares +// callbacks for I2C and button presses. Normal operation of this test takes +// place in the subsequent callbacks. +int main(void) { + printf("I2C Slave Sender\n"); + + // Prepare buffers + strcpy((char*) slave_write_buf, "Hello friend.\n"); + + // Set up I2C peripheral + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_callback(i2c_callback, NULL)); + //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_master_write_buffer(master_write_buf, BUF_SIZE)); + //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_master_read_buffer(master_read_buf, BUF_SIZE)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_write_buffer(slave_write_buf, BUF_SIZE)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_read_buffer(slave_read_buf, BUF_SIZE)); + + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_address(FOLLOW_ADDRESS)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_listen()); + + // Set up button peripheral to grab any button press + TOCK_EXPECT(RETURNCODE_SUCCESS, button_subscribe(button_cb, NULL)); + + int nbuttons; + button_count(&nbuttons); + if (nbuttons < 1) { + printf("ERROR: This app requires that a board have at least one button.\n"); + exit(-1); + } + + int j; + for (j = 0; j < nbuttons; j++) { + TOCK_EXPECT(RETURNCODE_SUCCESS, button_enable_interrupt(j)); + } +} \ No newline at end of file From f7c23c98a234204d060675e850216fafc2c89349 Mon Sep 17 00:00:00 2001 From: Hector Quiroga Date: Fri, 30 Jul 2021 22:19:01 -0700 Subject: [PATCH 13/49] Fixing apps --- .../sampletests/i2cexamples/masterex/main.c | 2 +- .../sampletests/i2cexamples/slavewrite/main.c | 20 ++++++------------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/examples/sampletests/i2cexamples/masterex/main.c b/examples/sampletests/i2cexamples/masterex/main.c index 87b95adcb..b719e9cb1 100644 --- a/examples/sampletests/i2cexamples/masterex/main.c +++ b/examples/sampletests/i2cexamples/masterex/main.c @@ -37,7 +37,7 @@ static void i2c_callback(int callback_type, delay_ms(2500); - printf("%s sending\n", is_leader ? "Leader" : "Follower"); + printf("Sending: Hello friend.\n"); TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(is_leader ? FOLLOW_ADDRESS : LEADER_ADDRESS, BUF_SIZE)); } else { printf("ERROR: Unexepected callback: type %d\n", callback_type); diff --git a/examples/sampletests/i2cexamples/slavewrite/main.c b/examples/sampletests/i2cexamples/slavewrite/main.c index 46db1b9e1..87b017e3a 100644 --- a/examples/sampletests/i2cexamples/slavewrite/main.c +++ b/examples/sampletests/i2cexamples/slavewrite/main.c @@ -6,7 +6,6 @@ #include #define BUF_SIZE 16 -#define LEADER_ADDRESS 0x40 #define FOLLOW_ADDRESS 0x41 uint8_t master_write_buf[BUF_SIZE]; @@ -34,15 +33,11 @@ static void i2c_callback(int callback_type, } } - printf("Inside Callback"); if (callback_type == TOCK_I2C_CB_MASTER_WRITE) { - printf("CB: Master write\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_listen()); - } else if (callback_type == TOCK_I2C_CB_SLAVE_WRITE) { printf("CB: Slave write\n"); + delay_ms(2500); - - TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(LEADER_ADDRESS, BUF_SIZE)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(FOLLOW_ADDRESS, BUF_SIZE)); } else { printf("ERROR: Unexepected callback: type %d\n", callback_type); } @@ -65,9 +60,7 @@ static void button_cb(__attribute__((unused)) int btn_num, printf("Sending to master\n"); - //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_address(LEADER_ADDRESS)); - TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(LEADER_ADDRESS, BUF_SIZE)); - //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_listen()); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(FOLLOW_ADDRESS, BUF_SIZE)); } } @@ -75,15 +68,14 @@ static void button_cb(__attribute__((unused)) int btn_num, // callbacks for I2C and button presses. Normal operation of this test takes // place in the subsequent callbacks. int main(void) { - printf("I2C Slave Sender\n"); + printf("I2C Master/Slave Ping-Pong\n"); // Prepare buffers - strcpy((char*) slave_write_buf, "Hello friend.\n"); + strcpy((char*) master_write_buf, "Hello friend.\n"); // Set up I2C peripheral TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_callback(i2c_callback, NULL)); - //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_master_write_buffer(master_write_buf, BUF_SIZE)); - //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_master_read_buffer(master_read_buf, BUF_SIZE)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_master_write_buffer(master_write_buf, BUF_SIZE)); TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_write_buffer(slave_write_buf, BUF_SIZE)); TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_read_buffer(slave_read_buf, BUF_SIZE)); From 128d2ff32f34f55e9d19cf3161a7b2c9b4ecf645 Mon Sep 17 00:00:00 2001 From: Hector Quiroga Date: Tue, 3 Aug 2021 09:31:42 -0700 Subject: [PATCH 14/49] Fixed master read --- examples/sampletests/i2cexamples/masterread/main.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/examples/sampletests/i2cexamples/masterread/main.c b/examples/sampletests/i2cexamples/masterread/main.c index 6e7dc2435..db604ed96 100644 --- a/examples/sampletests/i2cexamples/masterread/main.c +++ b/examples/sampletests/i2cexamples/masterread/main.c @@ -34,10 +34,19 @@ static void i2c_callback(int callback_type, } if (callback_type == TOCK_I2C_CB_MASTER_READ) { - printf("Master Reader: \n"); + printf("Master Reader\n"); delay_ms(2500); printf("Read Buffer After: >%.*s<\n", BUF_SIZE, master_read_buf); + memcpy((char*) master_write_buf, (char*) master_read_buf, BUF_SIZE); + //master_write_buf[BUF_SIZE - 1] = '\0'; + printf("Write Buf Now: >%.*s<\n", BUF_SIZE, master_write_buf); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(FOLLOW_ADDRESS, BUF_SIZE)); + } else if (callback_type == TOCK_I2C_CB_MASTER_WRITE) { + delay_ms(1500); + + printf("Sending; >%.*s<\n", BUF_SIZE, master_write_buf); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(FOLLOW_ADDRESS, BUF_SIZE)); } else { printf("ERROR: Unexepected callback: type %d\n", callback_type); } @@ -72,7 +81,7 @@ int main(void) { // Prepare buffers strcpy((char*) master_write_buf, "Hello friend.\n"); - strcpy((char*) master_read_buf, "Nothing,Nowhere"); + strcpy((char*) master_read_buf, "Hello I Master\n"); // Set up I2C peripheral TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_callback(i2c_callback, NULL)); From c5d3ee396a3c4841b00bfd4ea0074f879fc5d5fc Mon Sep 17 00:00:00 2001 From: Hector Quiroga Date: Wed, 4 Aug 2021 14:40:17 -0700 Subject: [PATCH 15/49] new tests added --- .../ci-tests/{i2c => i2c-master-rx}/Makefile | 0 examples/ci-tests/i2c-master-rx/main.c | 110 ++++++++++ examples/ci-tests/i2c-master-rx/test.py | 0 examples/ci-tests/i2c-master-tx/Makefile | 11 + examples/ci-tests/i2c-master-tx/main.c | 101 +++++++++ examples/ci-tests/i2c-master-tx/test.py | 199 ++++++++++++++++++ examples/ci-tests/i2c-slave-rx/Makefile | 11 + .../ci-tests/{i2c => i2c-slave-rx}/main.c | 0 .../ci-tests/{i2c => i2c-slave-rx}/test.py | 0 .../sampletests/i2cexamples/masterex/main.c | 2 +- .../sampletests/i2cexamples/slavewrite/main.c | 8 +- 11 files changed, 439 insertions(+), 3 deletions(-) rename examples/ci-tests/{i2c => i2c-master-rx}/Makefile (100%) create mode 100644 examples/ci-tests/i2c-master-rx/main.c create mode 100644 examples/ci-tests/i2c-master-rx/test.py create mode 100644 examples/ci-tests/i2c-master-tx/Makefile create mode 100644 examples/ci-tests/i2c-master-tx/main.c create mode 100644 examples/ci-tests/i2c-master-tx/test.py create mode 100644 examples/ci-tests/i2c-slave-rx/Makefile rename examples/ci-tests/{i2c => i2c-slave-rx}/main.c (100%) rename examples/ci-tests/{i2c => i2c-slave-rx}/test.py (100%) diff --git a/examples/ci-tests/i2c/Makefile b/examples/ci-tests/i2c-master-rx/Makefile similarity index 100% rename from examples/ci-tests/i2c/Makefile rename to examples/ci-tests/i2c-master-rx/Makefile diff --git a/examples/ci-tests/i2c-master-rx/main.c b/examples/ci-tests/i2c-master-rx/main.c new file mode 100644 index 000000000..8002696f6 --- /dev/null +++ b/examples/ci-tests/i2c-master-rx/main.c @@ -0,0 +1,110 @@ +#include +#include + +#include +#include +#include + +#define BUF_SIZE 16 +#define LEADER_ADDRESS 0x40 +#define FOLLOW_ADDRESS 0x41 + +uint8_t master_write_buf[BUF_SIZE]; +uint8_t master_read_buf[BUF_SIZE]; + +bool is_leader = false; + + +// In response to a +static void i2c_callback(int callback_type, + __attribute__ ((unused)) int length, + __attribute__ ((unused)) int arg2, + __attribute__ ((unused)) void* userdata) { + // Watching for GPIO interrupts holds us in a higher power state, so stop + // doing that once we don't care about button presses any more (the first + // time having sent or received a message) + static bool any_message = false; + if (!any_message) { + int nbuttons; + button_count(&nbuttons); + int j; + for (j = 0; j < nbuttons; j++) { + button_disable_interrupt(j); + } + } + + if (callback_type == TOCK_I2C_CB_MASTER_READ) { + printf("Master Reader\n"); + delay_ms(2500); + + printf("Read Buffer After: >%.*s<\n", BUF_SIZE, master_read_buf); + memcpy((char*) master_write_buf, (char*) master_read_buf, BUF_SIZE); + //master_write_buf[BUF_SIZE - 1] = '\0'; + printf("Write Buf Now: >%.*s<\n", BUF_SIZE, master_write_buf); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(FOLLOW_ADDRESS, BUF_SIZE)); + } else if (callback_type == TOCK_I2C_CB_MASTER_WRITE) { + delay_ms(1500); + + printf("Sending; >%.*s<\n", BUF_SIZE, master_write_buf); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(FOLLOW_ADDRESS, BUF_SIZE)); + } else { + printf("ERROR: Unexepected callback: type %d\n", callback_type); + } +} + +// This is the callback for the button press. +// A button press indicates that this device should start the ping-pong +// exchange. First, change the address to the BUTTON_ADDRESS to avoid +// conflict with the other node, then send a message. +static void button_cb(__attribute__((unused)) int btn_num, + __attribute__ ((unused)) int arg1, + __attribute__ ((unused)) int arg2, + __attribute__ ((unused)) void* userdata) { + // Only the first press is meaningfull + static bool pressed = false; + + if (!pressed) { + pressed = true; + is_leader = true; + + printf("Getting Message\n"); + + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_read(FOLLOW_ADDRESS, BUF_SIZE)); + } +} + +// This function sets up the I2C peripheral with needed buffers and prepares +// callbacks for I2C and button presses. Normal operation of this test takes +// place in the subsequent callbacks. +int main(void) { + printf("I2C Master Read Test\n"); + + // Prepare buffers + strcpy((char*) master_write_buf, "Hello friend.\n"); + strcpy((char*) master_read_buf, "Hello am Master\n"); + + // Set up I2C peripheral + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_callback(i2c_callback, NULL)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_master_write_buffer(master_write_buf, BUF_SIZE)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_master_read_buffer(master_read_buf, BUF_SIZE)); + + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_address(LEADER_ADDRESS)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_listen()); + + // Set up button peripheral to grab any button press + TOCK_EXPECT(RETURNCODE_SUCCESS, button_subscribe(button_cb, NULL)); + printf("Read Buffer Before: >%.*s<\n", BUF_SIZE, master_read_buf); + + + int nbuttons; + button_count(&nbuttons); + if (nbuttons < 1) { + printf("ERROR: This app requires that a board have at least one button.\n"); + exit(-1); + } + + int j; + for (j = 0; j < nbuttons; j++) { + TOCK_EXPECT(RETURNCODE_SUCCESS, button_enable_interrupt(j)); + } +} \ No newline at end of file diff --git a/examples/ci-tests/i2c-master-rx/test.py b/examples/ci-tests/i2c-master-rx/test.py new file mode 100644 index 000000000..e69de29bb diff --git a/examples/ci-tests/i2c-master-tx/Makefile b/examples/ci-tests/i2c-master-tx/Makefile new file mode 100644 index 000000000..a38de484d --- /dev/null +++ b/examples/ci-tests/i2c-master-tx/Makefile @@ -0,0 +1,11 @@ +# Makefile for user application + +# Specify this directory relative to the current application. +TOCK_USERLAND_BASE_DIR = ../../.. + +# Which files to compile. +C_SRCS := $(wildcard *.c) + +# Include userland master makefile. Contains rules and flags for actually +# building the application. +include $(TOCK_USERLAND_BASE_DIR)/AppMakefile.mk \ No newline at end of file diff --git a/examples/ci-tests/i2c-master-tx/main.c b/examples/ci-tests/i2c-master-tx/main.c new file mode 100644 index 000000000..0cf317a9f --- /dev/null +++ b/examples/ci-tests/i2c-master-tx/main.c @@ -0,0 +1,101 @@ +#include +#include + +#include +#include +#include + +#define BUF_SIZE 16 +#define LEADER_ADDRESS 0x40 +#define FOLLOW_ADDRESS 0x41 + +uint8_t master_write_buf[BUF_SIZE]; +uint8_t master_read_buf[BUF_SIZE]; +bool is_leader = false; + + +// In response to a +static void i2c_callback(int callback_type, + __attribute__ ((unused)) int length, + __attribute__ ((unused)) int arg2, + __attribute__ ((unused)) void* userdata) { + // Watching for GPIO interrupts holds us in a higher power state, so stop + // doing that once we don't care about button presses any more (the first + // time having sent or received a message) + static bool any_message = false; + if (!any_message) { + int nbuttons; + button_count(&nbuttons); + int j; + for (j = 0; j < nbuttons; j++) { + button_disable_interrupt(j); + } + } + + if (callback_type == TOCK_I2C_CB_MASTER_WRITE) { + printf("CB: Master write\n"); + + delay_ms(2500); + + printf("Sending: Hello friend.\n"); + //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(FOLLOW_ADDRESS, BUF_SIZE)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(FOLLOW_ADDRESS, BUF_SIZE)); + } else { + printf("ERROR: Unexepected callback: type %d\n", callback_type); + } +} + +// This is the callback for the button press. +// A button press indicates that this device should start the ping-pong +// exchange. First, change the address to the BUTTON_ADDRESS to avoid +// conflict with the other node, then send a message. +static void button_cb(__attribute__((unused)) int btn_num, + __attribute__ ((unused)) int arg1, + __attribute__ ((unused)) int arg2, + __attribute__ ((unused)) void* userdata) { + // Only the first press is meaningfull + static bool pressed = false; + + if (!pressed) { + pressed = true; + is_leader = true; + + printf("Switching to master\n"); + + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(FOLLOW_ADDRESS, BUF_SIZE)); + printf("Switched\n"); + } +} + +// This function sets up the I2C peripheral with needed buffers and prepares +// callbacks for I2C and button presses. Normal operation of this test takes +// place in the subsequent callbacks. +int main(void) { + printf("I2C Master Write App!\n"); + + // Prepare buffers + strcpy((char*) master_write_buf, "Hello friend.\n"); + + // Set up I2C peripheral + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_callback(i2c_callback, NULL)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_master_write_buffer(master_write_buf, BUF_SIZE)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_master_read_buffer(master_read_buf, BUF_SIZE)); + + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_address(LEADER_ADDRESS)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_listen()); + + // Set up button peripheral to grab any button press + TOCK_EXPECT(RETURNCODE_SUCCESS, button_subscribe(button_cb, NULL)); + + int nbuttons; + button_count(&nbuttons); + if (nbuttons < 1) { + printf("ERROR: This app requires that a board have at least one button.\n"); + exit(-1); + } + + int j; + for (j = 0; j < nbuttons; j++) { + TOCK_EXPECT(RETURNCODE_SUCCESS, button_enable_interrupt(j)); + } +} \ No newline at end of file diff --git a/examples/ci-tests/i2c-master-tx/test.py b/examples/ci-tests/i2c-master-tx/test.py new file mode 100644 index 000000000..631b4f32e --- /dev/null +++ b/examples/ci-tests/i2c-master-tx/test.py @@ -0,0 +1,199 @@ +import time +import logging +import unittest +import RPi.GPIO as GPIO +import os + +MESSAGE = "Hello friend." # Message Master sends to slave +MESSAGE_RECEIVED = "" +FIRST_RX = 0 + +SDA = 10 # Broadcom pin 10 (P1 pin 19) +SCL = 11 # Broadcom pin 11 (P1 pin 23) +RESET = 21 # Broadcom pin 21 (P1 pin 40) +BUTTON_1 = 20 # Broadcom pin 20 (P1 pin 38) + +I2C_ADDR = 0x41 # Raspberry Pi Address + +GPIO.setwarnings(False) +GPIO.setmode(GPIO.BCM) +GPIO.setup(RESET, GPIO.OUT) # RESET pin set as output +GPIO.setup(BUTTON_1, GPIO.OUT) # BUTTON_1 pin set as output + +# Set up PiGPIO properly by configuring it on pi then importing library +os.system('sudo pigpiod') +import pigpio +# PiGPIO configured. + +################################################################################ +# Helper Functions +################################################################################ + +def time_gap(start_time): + """Return time gap between current time and start_time + Argument: + start_time - Start time + """ + return "{:.6f}".format(time.time() - start_time) + +def reset(): + global RESET + """Button is Reset""" + + GPIO.output(RESET, GPIO.LOW) + time.sleep(1) + GPIO.output(RESET, GPIO.HIGH) + print("finished reset") + +def press_button(): + global BUTTON_1 + """Button is one of User Buttons""" + + GPIO.output(BUTTON_1, GPIO.HIGH) + time.sleep(1) + GPIO.output(BUTTON_1, GPIO.LOW) + print("finished button press") + +def i2c(id, tick): + global pi + global FIRST_RX + global MESSAGE_RECEIVED + global I2C_ADDR + + s, b, d = pi.bsc_i2c(I2C_ADDR) + + if b: + logger.info('Messsage Received: ' + d[:-1], + extra={'timegap': time_gap(TEST_START_TIME)}) + + if(f < 1): + MESSAGE_RECEIVED = d.decode() + FIRST_RX += 1 + +# END + +################################################################################ +# Start test and logger +################################################################################ + +# Test Start Time +TEST_START_TIME = time.time() + +# Logger set format +LOG_FORMAT = "%(timegap)s %(levelname)s -- %(message)s" +logging.basicConfig(format=LOG_FORMAT) + +# Logger add formatter +logger = logging.getLogger('I2C Master Tx Test') +logger.setLevel('INFO') + +logger.info('Initiating I2C Master Tx Test...', + extra={'timegap': time_gap(TEST_START_TIME)}) + +# END + +################################################################################ +# Test Case Module +################################################################################ + +class I2CMasterTxTest(unittest.TestCase): + def test_i2c_master_tx_configuration(self): + """ Set up for Raspberry Pi configuration """ + + print() + logger.info('Receiving Message As Slave... ', + extra={'timegap': time_gap(TEST_START_TIME)}) + + received = False + + # Pi Slave setup + pi = pigpio.pi() + + if not pi.connected: + exit() + + press_button() # Used to press on of the user buttons on the board + + # Add pull-ups in case external pull-ups haven't been added (For Raspberry Pi) + + pi.set_pull_up_down(SDA, pigpio.PUD_UP) + pi.set_pull_up_down(SCL, pigpio.PUD_UP) + + # Respond to BSC slave activity + e = pi.event_callback(pigpio.EVENT_BSC, i2c) + + pi.bsc_i2c(I2C_ADDR) # Configure BSC as I2C slave + + print() + logger.info('Initiating Reception of Messages...', + extra={'timegap': time_gap(TEST_START_TIME)}) + + time.sleep(12) # Time to wait for messages to be sent (Should see four messages logged) + + MESSAGE_RECEIVED = MESSAGE_RECEIVED.strip() + + logger.info('Expected Message: ' + MESSAGE, + extra={'timegap': time_gap(TEST_START_TIME)}) + + logger.info('Message Received: ' + MESSAGE_RECEIVED, + extra={'timegap': time_gap(TEST_START_TIME)}) + + if (MESSAGE_RECEIVED == MESSAGE): + + logger.info('Connection Satisfied.', + extra={'timegap': time_gap(TEST_START_TIME)}) + + # Close setup + e.cancel() + + pi.bsc_i2c(0) # Disable BSC peripheral + + GPIO.cleanup() + + pi.stop() + + logger.info('I2C Master Tx Test has ended.', + extra={'timegap': time_gap(TEST_START_TIME)}) + self.assertTrue(received) + + else: + + logger.info('Connection was not Satisfied. Wrong/No message received.', + extra={'timegap': time_gap(TEST_START_TIME)}) + + e.cancel() + + pi.bsc_i2c(0) # Disable BSC peripheral + + PIO.cleanup() + + pi.stop() + + logger.info('I2C Master Tx Test has ended.', + extra={'timegap': time_gap(TEST_START_TIME)}) + self.assertTrue(received) + + +# END + +################################################################################ +# Test Case Setup +################################################################################ + +class Nrf52840Test(I2CMasterTxTest): + def setUp(self): + + reset() # Used to activate the reset button on board + + logger.info('Setting up for nrf52840dk I2C Master Tx test...', + extra={'timegap': time_gap(TEST_START_TIME)}) + + +# END + +################################################################################ +# Main +################################################################################ + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/examples/ci-tests/i2c-slave-rx/Makefile b/examples/ci-tests/i2c-slave-rx/Makefile new file mode 100644 index 000000000..a38de484d --- /dev/null +++ b/examples/ci-tests/i2c-slave-rx/Makefile @@ -0,0 +1,11 @@ +# Makefile for user application + +# Specify this directory relative to the current application. +TOCK_USERLAND_BASE_DIR = ../../.. + +# Which files to compile. +C_SRCS := $(wildcard *.c) + +# Include userland master makefile. Contains rules and flags for actually +# building the application. +include $(TOCK_USERLAND_BASE_DIR)/AppMakefile.mk \ No newline at end of file diff --git a/examples/ci-tests/i2c/main.c b/examples/ci-tests/i2c-slave-rx/main.c similarity index 100% rename from examples/ci-tests/i2c/main.c rename to examples/ci-tests/i2c-slave-rx/main.c diff --git a/examples/ci-tests/i2c/test.py b/examples/ci-tests/i2c-slave-rx/test.py similarity index 100% rename from examples/ci-tests/i2c/test.py rename to examples/ci-tests/i2c-slave-rx/test.py diff --git a/examples/sampletests/i2cexamples/masterex/main.c b/examples/sampletests/i2cexamples/masterex/main.c index b719e9cb1..495228598 100644 --- a/examples/sampletests/i2cexamples/masterex/main.c +++ b/examples/sampletests/i2cexamples/masterex/main.c @@ -38,7 +38,7 @@ static void i2c_callback(int callback_type, delay_ms(2500); printf("Sending: Hello friend.\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(is_leader ? FOLLOW_ADDRESS : LEADER_ADDRESS, BUF_SIZE)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(FOLLOW_ADDRESS, BUF_SIZE)); } else { printf("ERROR: Unexepected callback: type %d\n", callback_type); } diff --git a/examples/sampletests/i2cexamples/slavewrite/main.c b/examples/sampletests/i2cexamples/slavewrite/main.c index 87b017e3a..dc9c36fdd 100644 --- a/examples/sampletests/i2cexamples/slavewrite/main.c +++ b/examples/sampletests/i2cexamples/slavewrite/main.c @@ -7,6 +7,7 @@ #define BUF_SIZE 16 #define FOLLOW_ADDRESS 0x41 +#define LEADER_ADDRESS 0x40 uint8_t master_write_buf[BUF_SIZE]; uint8_t master_read_buf[BUF_SIZE]; @@ -37,7 +38,8 @@ static void i2c_callback(int callback_type, printf("CB: Slave write\n"); delay_ms(2500); - TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(FOLLOW_ADDRESS, BUF_SIZE)); + //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(FOLLOW_ADDRESS, BUF_SIZE)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(LEADER_ADDRESS, BUF_SIZE)); } else { printf("ERROR: Unexepected callback: type %d\n", callback_type); } @@ -60,7 +62,8 @@ static void button_cb(__attribute__((unused)) int btn_num, printf("Sending to master\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(FOLLOW_ADDRESS, BUF_SIZE)); + //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(FOLLOW_ADDRESS, BUF_SIZE)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(LEADER_ADDRESS, BUF_SIZE)); } } @@ -72,6 +75,7 @@ int main(void) { // Prepare buffers strcpy((char*) master_write_buf, "Hello friend.\n"); + strcpy((char*) slave_write_buf, "Hello friend.\n"); // Set up I2C peripheral TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_callback(i2c_callback, NULL)); From 1d847e01fdba82eda1e4d592a66e89a365053303 Mon Sep 17 00:00:00 2001 From: Hector Quiroga Date: Wed, 4 Aug 2021 15:52:10 -0700 Subject: [PATCH 16/49] update test for i2c --- examples/ci-tests/i2c-master-tx/test.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/ci-tests/i2c-master-tx/test.py b/examples/ci-tests/i2c-master-tx/test.py index 631b4f32e..5d40413f4 100644 --- a/examples/ci-tests/i2c-master-tx/test.py +++ b/examples/ci-tests/i2c-master-tx/test.py @@ -23,6 +23,8 @@ # Set up PiGPIO properly by configuring it on pi then importing library os.system('sudo pigpiod') import pigpio + +pi = pigpio.pi() # Configure the Raspberry Pi as slave # PiGPIO configured. ################################################################################ @@ -99,7 +101,8 @@ def i2c(id, tick): class I2CMasterTxTest(unittest.TestCase): def test_i2c_master_tx_configuration(self): """ Set up for Raspberry Pi configuration """ - + global pi + print() logger.info('Receiving Message As Slave... ', extra={'timegap': time_gap(TEST_START_TIME)}) @@ -107,7 +110,7 @@ def test_i2c_master_tx_configuration(self): received = False # Pi Slave setup - pi = pigpio.pi() + # pi = pigpio.pi() if not pi.connected: exit() From 5dad320dcd9704108e9d43472cbc3dab00e79ccb Mon Sep 17 00:00:00 2001 From: AnthonyQ619 Date: Thu, 5 Aug 2021 00:02:50 +0000 Subject: [PATCH 17/49] Fixed test.py --- examples/ci-tests/i2c-master-tx/test.py | 35 ++++++++++++++++++------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/examples/ci-tests/i2c-master-tx/test.py b/examples/ci-tests/i2c-master-tx/test.py index 5d40413f4..4cf7d3baf 100644 --- a/examples/ci-tests/i2c-master-tx/test.py +++ b/examples/ci-tests/i2c-master-tx/test.py @@ -4,8 +4,8 @@ import RPi.GPIO as GPIO import os -MESSAGE = "Hello friend." # Message Master sends to slave -MESSAGE_RECEIVED = "" +MESSAGE = 'Hello friend.' # Message Master sends to slave +MESSAGE_RECEIVED = '' FIRST_RX = 0 SDA = 10 # Broadcom pin 10 (P1 pin 19) @@ -45,7 +45,7 @@ def reset(): GPIO.output(RESET, GPIO.LOW) time.sleep(1) GPIO.output(RESET, GPIO.HIGH) - print("finished reset") + #print("finished reset") def press_button(): global BUTTON_1 @@ -54,7 +54,7 @@ def press_button(): GPIO.output(BUTTON_1, GPIO.HIGH) time.sleep(1) GPIO.output(BUTTON_1, GPIO.LOW) - print("finished button press") + #print("finished button press") def i2c(id, tick): global pi @@ -65,11 +65,14 @@ def i2c(id, tick): s, b, d = pi.bsc_i2c(I2C_ADDR) if b: - logger.info('Messsage Received: ' + d[:-1], + array = str(d[:-1]) + logger.info('Messsage Received: ' + array, extra={'timegap': time_gap(TEST_START_TIME)}) - if(f < 1): - MESSAGE_RECEIVED = d.decode() + if(FIRST_RX < 1): + string_received = d.decode() + string_split = string_received.splitlines() + MESSAGE_RECEIVED = string_split[0] FIRST_RX += 1 # END @@ -102,7 +105,8 @@ class I2CMasterTxTest(unittest.TestCase): def test_i2c_master_tx_configuration(self): """ Set up for Raspberry Pi configuration """ global pi - + global MESSAGE_RECEIVED + print() logger.info('Receiving Message As Slave... ', extra={'timegap': time_gap(TEST_START_TIME)}) @@ -133,6 +137,7 @@ def test_i2c_master_tx_configuration(self): time.sleep(12) # Time to wait for messages to be sent (Should see four messages logged) + MESSAGE_RECEIVED = str(MESSAGE_RECEIVED) MESSAGE_RECEIVED = MESSAGE_RECEIVED.strip() logger.info('Expected Message: ' + MESSAGE, @@ -143,6 +148,10 @@ def test_i2c_master_tx_configuration(self): if (MESSAGE_RECEIVED == MESSAGE): + reset() # Reset application to stop sending messages + + time.sleep(1) + logger.info('Connection Satisfied.', extra={'timegap': time_gap(TEST_START_TIME)}) @@ -155,6 +164,10 @@ def test_i2c_master_tx_configuration(self): pi.stop() + received = True + + time.sleep(1) + logger.info('I2C Master Tx Test has ended.', extra={'timegap': time_gap(TEST_START_TIME)}) self.assertTrue(received) @@ -168,10 +181,12 @@ def test_i2c_master_tx_configuration(self): pi.bsc_i2c(0) # Disable BSC peripheral - PIO.cleanup() + GPIO.cleanup() pi.stop() + time.sleep(2) + logger.info('I2C Master Tx Test has ended.', extra={'timegap': time_gap(TEST_START_TIME)}) self.assertTrue(received) @@ -199,4 +214,4 @@ def setUp(self): ################################################################################ if __name__ == '__main__': - unittest.main() \ No newline at end of file + unittest.main() From 861f6eabf2e8535090139f9085540ce327e55666 Mon Sep 17 00:00:00 2001 From: Hector Quiroga Date: Wed, 4 Aug 2021 22:48:31 -0700 Subject: [PATCH 18/49] Updated tests --- examples/ci-tests/i2c-master-rx/test.py | 218 ++++++++++++++++++++++++ examples/ci-tests/i2c-master-tx/test.py | 36 ++-- 2 files changed, 236 insertions(+), 18 deletions(-) diff --git a/examples/ci-tests/i2c-master-rx/test.py b/examples/ci-tests/i2c-master-rx/test.py index e69de29bb..0381dea52 100644 --- a/examples/ci-tests/i2c-master-rx/test.py +++ b/examples/ci-tests/i2c-master-rx/test.py @@ -0,0 +1,218 @@ +import time +import logging +import unittest +import RPi.GPIO as GPIO +import os + +MESSAGE_SENT = "Hello I'm Slave" # Message Master sends to slave +MESSAGE_CONFIRMATION= '' +FIRST_RX = 0 + +SDA = 10 # Broadcom pin 10 (P1 pin 19) +SCL = 11 # Broadcom pin 11 (P1 pin 23) +RESET = 21 # Broadcom pin 21 (P1 pin 40) +BUTTON_1 = 20 # Broadcom pin 20 (P1 pin 38) + +I2C_ADDR = 0x41 # Raspberry Pi Address + +GPIO.setwarnings(False) +GPIO.setmode(GPIO.BCM) +GPIO.setup(RESET, GPIO.OUT) # RESET pin set as output +GPIO.setup(BUTTON_1, GPIO.OUT) # BUTTON_1 pin set as output + +# Set up PiGPIO properly by configuring it on pi then importing library +os.system('sudo pigpiod') +import pigpio + +pi = pigpio.pi() # Configure the Raspberry Pi as slave +# PiGPIO configured. + +################################################################################ +# Helper Functions +################################################################################ + +def time_gap(start_time): + """Return time gap between current time and start_time + Argument: + start_time - Start time + """ + return "{:.6f}".format(time.time() - start_time) + +def reset(): + global RESET + """Button is Reset""" + + GPIO.output(RESET, GPIO.LOW) + time.sleep(1) + GPIO.output(RESET, GPIO.HIGH) + +def press_button(): + global BUTTON_1 + """Button is one of User Buttons""" + + GPIO.output(BUTTON_1, GPIO.HIGH) + time.sleep(1) + GPIO.output(BUTTON_1, GPIO.LOW) + +def i2c(id, tick): + global pi + global FIRST_RX + global MESSAGE_RECEIVED + global I2C_ADDR + + s, b, d = pi.bsc_i2c(I2C_ADDR, b"\nHello I'm Slave\n") + + if b: + array = str(d[:-1]) + logger.info('Messsage Call Back From Master: ' + array, + extra={'timegap': time_gap(TEST_START_TIME)}) + + if(FIRST_RX < 1): + string_received = d.decode() + string_split = string_received.splitlines() + MESSAGE_CONFIRMATION = string_split[0] + FIRST_RX += 1 + +# END + +################################################################################ +# Start test and logger +################################################################################ + +# Test Start Time +TEST_START_TIME = time.time() + +# Logger set format +LOG_FORMAT = "%(timegap)s %(levelname)s -- %(message)s" +logging.basicConfig(format=LOG_FORMAT) + +# Logger add formatter +logger = logging.getLogger('I2C Master Rx Test') +logger.setLevel('INFO') + +logger.info('Initiating I2C Master Rx Test...', + extra={'timegap': time_gap(TEST_START_TIME)}) + +# END + +################################################################################ +# Test Case Module +################################################################################ + +class I2CMasterRxTest(unittest.TestCase): + def test_i2c_master_rx_configuration(self): + """ Set up for Raspberry Pi configuration """ + global pi + global MESSAGE_CONFIRMATION + + print() + logger.info('Sending Messages As Slave... ', + extra={'timegap': time_gap(TEST_START_TIME)}) + + received = False + + if not pi.connected: + exit() + + press_button() # Used to press on of the user buttons on the board + + # Add pull-ups in case external pull-ups haven't been added (For Raspberry Pi) + + pi.set_pull_up_down(SDA, pigpio.PUD_UP) + pi.set_pull_up_down(SCL, pigpio.PUD_UP) + + # Respond to BSC slave activity + e = pi.event_callback(pigpio.EVENT_BSC, i2c) + + pi.bsc_i2c(I2C_ADDR) # Configure BSC as I2C slave + + print() + logger.info('Initiating Transmission of Messages...', + extra={'timegap': time_gap(TEST_START_TIME)}) + + time.sleep(12) # Time to wait for messages to be sent (Should see four messages logged) + + MESSAGE_CONFIRMATION = str(MESSAGE_CONFIRMATION) + MESSAGE_CONFIRMATION = MESSAGE_CONFIRMATION.strip() + + logger.info('Message Sent: ' + MESSAGE_SENT, + extra={'timegap': time_gap(TEST_START_TIME)}) + + logger.info('Message Called Back from Master: ' + MESSAGE_CONFIRMATION, + extra={'timegap': time_gap(TEST_START_TIME)}) + + if (MESSAGE_CONFIRMATION == MESSAGE_SENT): + + # Close setup + e.cancel() + + pi.bsc_i2c(0) # Disable BSC peripheral + + GPIO.cleanup() + + pi.stop() + + reset() # Reset application to stop sending messages + + time.sleep(1) + + logger.info('Connection Satisfied.', + extra={'timegap': time_gap(TEST_START_TIME)}) + + received = True + + time.sleep(1) + + logger.info('I2C Master Rx Test has ended.', + extra={'timegap': time_gap(TEST_START_TIME)}) + self.assertTrue(received) + + else: + + #Close setup + + e.cancel() + + pi.bsc_i2c(0) # Disable BSC peripheral + + GPIO.cleanup() + + pi.stop() + + reset() # Reset application to stop sending messages + + time.sleep(1) + + logger.info('Connection was not Satisfied. Wrong/No message was sent.', + extra={'timegap': time_gap(TEST_START_TIME)}) + + time.sleep(1) + + logger.info('I2C Master Rx Test has ended.', + extra={'timegap': time_gap(TEST_START_TIME)}) + self.assertTrue(received) + + +# END + +################################################################################ +# Test Case Setup +################################################################################ + +class Nrf52840Test(I2CMasterRxTest): + def setUp(self): + + reset() # Used to activate the reset button on board + + logger.info('Setting up for nrf52840dk I2C Master Rx test...', + extra={'timegap': time_gap(TEST_START_TIME)}) + + +# END + +################################################################################ +# Main +################################################################################ + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/examples/ci-tests/i2c-master-tx/test.py b/examples/ci-tests/i2c-master-tx/test.py index 4cf7d3baf..67925f886 100644 --- a/examples/ci-tests/i2c-master-tx/test.py +++ b/examples/ci-tests/i2c-master-tx/test.py @@ -45,7 +45,6 @@ def reset(): GPIO.output(RESET, GPIO.LOW) time.sleep(1) GPIO.output(RESET, GPIO.HIGH) - #print("finished reset") def press_button(): global BUTTON_1 @@ -54,7 +53,6 @@ def press_button(): GPIO.output(BUTTON_1, GPIO.HIGH) time.sleep(1) GPIO.output(BUTTON_1, GPIO.LOW) - #print("finished button press") def i2c(id, tick): global pi @@ -112,9 +110,6 @@ def test_i2c_master_tx_configuration(self): extra={'timegap': time_gap(TEST_START_TIME)}) received = False - - # Pi Slave setup - # pi = pigpio.pi() if not pi.connected: exit() @@ -148,13 +143,6 @@ def test_i2c_master_tx_configuration(self): if (MESSAGE_RECEIVED == MESSAGE): - reset() # Reset application to stop sending messages - - time.sleep(1) - - logger.info('Connection Satisfied.', - extra={'timegap': time_gap(TEST_START_TIME)}) - # Close setup e.cancel() @@ -164,6 +152,12 @@ def test_i2c_master_tx_configuration(self): pi.stop() + reset() # Reset application to stop sending messages + + time.sleep(1) + + logger.info('Connection Satisfied.', + extra={'timegap': time_gap(TEST_START_TIME)}) received = True time.sleep(1) @@ -173,19 +167,25 @@ def test_i2c_master_tx_configuration(self): self.assertTrue(received) else: - - logger.info('Connection was not Satisfied. Wrong/No message received.', - extra={'timegap': time_gap(TEST_START_TIME)}) + + #Close setup e.cancel() - pi.bsc_i2c(0) # Disable BSC peripheral + pi.bsc_i2c(0) # Disable BSC peripheral GPIO.cleanup() pi.stop() - time.sleep(2) + reset() # Reset application to stop sending messages + + time.sleep(1) + + logger.info('Connection was not Satisfied. Wrong/No message received.', + extra={'timegap': time_gap(TEST_START_TIME)}) + + time.sleep(1) logger.info('I2C Master Tx Test has ended.', extra={'timegap': time_gap(TEST_START_TIME)}) @@ -214,4 +214,4 @@ def setUp(self): ################################################################################ if __name__ == '__main__': - unittest.main() + unittest.main() \ No newline at end of file From 751b6c4cab5d51d89148601c586771daa6841fdd Mon Sep 17 00:00:00 2001 From: Hector Quiroga Date: Wed, 4 Aug 2021 22:56:27 -0700 Subject: [PATCH 19/49] Updated tests --- examples/ci-tests/i2c-master-rx/test.py | 8 ++++---- examples/ci-tests/i2c-master-tx/test.py | 15 +++++++-------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/examples/ci-tests/i2c-master-rx/test.py b/examples/ci-tests/i2c-master-rx/test.py index 0381dea52..d24f9b344 100644 --- a/examples/ci-tests/i2c-master-rx/test.py +++ b/examples/ci-tests/i2c-master-rx/test.py @@ -148,12 +148,12 @@ def test_i2c_master_rx_configuration(self): pi.bsc_i2c(0) # Disable BSC peripheral - GPIO.cleanup() - pi.stop() reset() # Reset application to stop sending messages + GPIO.cleanup() + time.sleep(1) logger.info('Connection Satisfied.', @@ -175,12 +175,12 @@ def test_i2c_master_rx_configuration(self): pi.bsc_i2c(0) # Disable BSC peripheral - GPIO.cleanup() - pi.stop() reset() # Reset application to stop sending messages + GPIO.cleanup() + time.sleep(1) logger.info('Connection was not Satisfied. Wrong/No message was sent.', diff --git a/examples/ci-tests/i2c-master-tx/test.py b/examples/ci-tests/i2c-master-tx/test.py index 67925f886..2cd895b86 100644 --- a/examples/ci-tests/i2c-master-tx/test.py +++ b/examples/ci-tests/i2c-master-tx/test.py @@ -148,12 +148,12 @@ def test_i2c_master_tx_configuration(self): pi.bsc_i2c(0) # Disable BSC peripheral - GPIO.cleanup() - pi.stop() reset() # Reset application to stop sending messages + GPIO.cleanup() + time.sleep(1) logger.info('Connection Satisfied.', @@ -168,17 +168,16 @@ def test_i2c_master_tx_configuration(self): else: - #Close setup - + # Close setup e.cancel() - pi.bsc_i2c(0) # Disable BSC peripheral - - GPIO.cleanup() + pi.bsc_i2c(0) # Disable BSC peripheral pi.stop() - reset() # Reset application to stop sending messages + reset() # Reset application to stop sending messages + + GPIO.cleanup() time.sleep(1) From 187dbf580a1f4f1c52185a7a51bc71d8e7501894 Mon Sep 17 00:00:00 2001 From: Hector Quiroga Date: Wed, 4 Aug 2021 23:17:08 -0700 Subject: [PATCH 20/49] update --- examples/ci-tests/i2c-master-rx/main.c | 2 +- examples/ci-tests/i2c-master-rx/test.py | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/examples/ci-tests/i2c-master-rx/main.c b/examples/ci-tests/i2c-master-rx/main.c index 8002696f6..b79a41ffa 100644 --- a/examples/ci-tests/i2c-master-rx/main.c +++ b/examples/ci-tests/i2c-master-rx/main.c @@ -81,7 +81,7 @@ int main(void) { // Prepare buffers strcpy((char*) master_write_buf, "Hello friend.\n"); - strcpy((char*) master_read_buf, "Hello am Master\n"); + strcpy((char*) master_read_buf, "Hello friend.\n"); // Set up I2C peripheral TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_callback(i2c_callback, NULL)); diff --git a/examples/ci-tests/i2c-master-rx/test.py b/examples/ci-tests/i2c-master-rx/test.py index d24f9b344..cd9be7d3d 100644 --- a/examples/ci-tests/i2c-master-rx/test.py +++ b/examples/ci-tests/i2c-master-rx/test.py @@ -68,10 +68,8 @@ def i2c(id, tick): extra={'timegap': time_gap(TEST_START_TIME)}) if(FIRST_RX < 1): - string_received = d.decode() - string_split = string_received.splitlines() - MESSAGE_CONFIRMATION = string_split[0] - FIRST_RX += 1 + MESSAGE_CONFIRMATION = d.decode() + FIRST_RX += 1 # END From 72f61e06034a5db0fd978f99ad7f8e9a56598e9a Mon Sep 17 00:00:00 2001 From: AnthonyQ619 Date: Thu, 5 Aug 2021 06:37:23 +0000 Subject: [PATCH 21/49] Update --- examples/ci-tests/i2c-master-rx/test.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/ci-tests/i2c-master-rx/test.py b/examples/ci-tests/i2c-master-rx/test.py index cd9be7d3d..50975764d 100644 --- a/examples/ci-tests/i2c-master-rx/test.py +++ b/examples/ci-tests/i2c-master-rx/test.py @@ -57,20 +57,20 @@ def press_button(): def i2c(id, tick): global pi global FIRST_RX - global MESSAGE_RECEIVED + global MESSAGE_CONFIRMATION global I2C_ADDR s, b, d = pi.bsc_i2c(I2C_ADDR, b"\nHello I'm Slave\n") if b: - array = str(d[:-1]) - logger.info('Messsage Call Back From Master: ' + array, - extra={'timegap': time_gap(TEST_START_TIME)}) - if(FIRST_RX < 1): MESSAGE_CONFIRMATION = d.decode() FIRST_RX += 1 + array = str(d[:-1]) + logger.info('Messsage Call Back From Master: ' + array, + extra={'timegap': time_gap(TEST_START_TIME)}) + # END ################################################################################ @@ -213,4 +213,4 @@ def setUp(self): ################################################################################ if __name__ == '__main__': - unittest.main() \ No newline at end of file + unittest.main() From 9f15c695961382184dba839367806d4f3e25db09 Mon Sep 17 00:00:00 2001 From: Hector Quiroga Date: Mon, 16 Aug 2021 18:11:42 -0700 Subject: [PATCH 22/49] New Tests added --- examples/ci-tests/i2c-slave-rx/test.py | 1 - examples/ci-tests/i2c-slave-tx/Makefile | 11 ++ examples/ci-tests/i2c-slave-tx/main.c | 104 +++++++++++ examples/ci-tests/i2c-slave-tx/test.py | 168 ++++++++++++++++++ .../sampletests/i2cexamples/slavewrite/main.c | 56 ++++-- .../i2cexamples/slavewritev2/Makefile | 11 ++ .../i2cexamples/slavewritev2/main.c | 109 ++++++++++++ 7 files changed, 449 insertions(+), 11 deletions(-) create mode 100644 examples/ci-tests/i2c-slave-tx/Makefile create mode 100644 examples/ci-tests/i2c-slave-tx/main.c create mode 100644 examples/ci-tests/i2c-slave-tx/test.py create mode 100644 examples/sampletests/i2cexamples/slavewritev2/Makefile create mode 100644 examples/sampletests/i2cexamples/slavewritev2/main.c diff --git a/examples/ci-tests/i2c-slave-rx/test.py b/examples/ci-tests/i2c-slave-rx/test.py index 66f94f77d..ed1d621fa 100644 --- a/examples/ci-tests/i2c-slave-rx/test.py +++ b/examples/ci-tests/i2c-slave-rx/test.py @@ -2,7 +2,6 @@ import time import logging import unittest -import serial ADDRESS = 0x41 # bus address to the Slave Device MASTER = 0x40 # Raspberry Pi Master Address diff --git a/examples/ci-tests/i2c-slave-tx/Makefile b/examples/ci-tests/i2c-slave-tx/Makefile new file mode 100644 index 000000000..a38de484d --- /dev/null +++ b/examples/ci-tests/i2c-slave-tx/Makefile @@ -0,0 +1,11 @@ +# Makefile for user application + +# Specify this directory relative to the current application. +TOCK_USERLAND_BASE_DIR = ../../.. + +# Which files to compile. +C_SRCS := $(wildcard *.c) + +# Include userland master makefile. Contains rules and flags for actually +# building the application. +include $(TOCK_USERLAND_BASE_DIR)/AppMakefile.mk \ No newline at end of file diff --git a/examples/ci-tests/i2c-slave-tx/main.c b/examples/ci-tests/i2c-slave-tx/main.c new file mode 100644 index 000000000..4e6c304ff --- /dev/null +++ b/examples/ci-tests/i2c-slave-tx/main.c @@ -0,0 +1,104 @@ +#include +#include + +#include +#include +#include + +#define BUF_SIZE 16 +//#define LEADER_ADDRESS 0x40 +#define FOLLOW_ADDRESS 0x41 + +uint8_t master_write_buf[BUF_SIZE]; +uint8_t master_read_buf[BUF_SIZE]; +uint8_t slave_write_buf[BUF_SIZE]; +uint8_t slave_read_buf[BUF_SIZE]; +bool is_leader = false; + + +// In response to a +static void i2c_callback(int callback_type, + __attribute__ ((unused)) int length, + __attribute__ ((unused)) int arg2, + __attribute__ ((unused)) void* userdata) { + // Watching for GPIO interrupts holds us in a higher power state, so stop + // doing that once we don't care about button presses any more (the first + // time having sent or received a message) + static bool any_message = false; + if (!any_message) { + int nbuttons; + button_count(&nbuttons); + int j; + for (j = 0; j < nbuttons; j++) { + button_disable_interrupt(j); + } + } + + if (callback_type == TOCK_I2C_CB_SLAVE_WRITE) { + printf("CB: Slave write\n"); + + printf("%s sending\n", is_leader ? "Leader" : "Follower"); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_enable_slave_read(BUF_SIZE)); + printf("Message Sent...\n"); + } else { + printf("ERROR: Unexepected callback: type %d\n", callback_type); + } +} + + +// This is the callback for the button press. +// A button press indicates that this device should start the ping-pong +// exchange. First, change the address to the BUTTON_ADDRESS to avoid +// conflict with the other node, then send a message. +static void button_cb(__attribute__((unused)) int btn_num, + __attribute__ ((unused)) int arg1, + __attribute__ ((unused)) int arg2, + __attribute__ ((unused)) void* userdata) { + // Only the first press is meaningfull + static bool pressed = false; + + if (!pressed) { + pressed = true; + is_leader = true; + + printf("Sending to master\n"); + + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_enable_slave_read(BUF_SIZE)); + } +} + +// This function sets up the I2C peripheral with needed buffers and prepares +// callbacks for I2C and button presses. Normal operation of this test takes +// place in the subsequent callbacks. +int main(void) { + printf("I2C Master/Slave Ping-Pong\n"); + + // Prepare buffers + strcpy((char*) master_write_buf, "Hello friend.\n"); + strcpy((char*) slave_read_buf, "Hello friend.\n"); + + // Set up I2C peripheral + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_callback(i2c_callback, NULL)); + //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_master_write_buffer(master_write_buf, BUF_SIZE)); + //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_master_read_buffer(master_read_buf, BUF_SIZE)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_write_buffer(slave_write_buf, BUF_SIZE)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_read_buffer(slave_read_buf, BUF_SIZE)); + + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_address(FOLLOW_ADDRESS)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_listen()); + + // Set up button peripheral to grab any button press + TOCK_EXPECT(RETURNCODE_SUCCESS, button_subscribe(button_cb, NULL)); + + int nbuttons; + button_count(&nbuttons); + if (nbuttons < 1) { + printf("ERROR: This app requires that a board have at least one button.\n"); + exit(-1); + } + + int j; + for (j = 0; j < nbuttons; j++) { + TOCK_EXPECT(RETURNCODE_SUCCESS, button_enable_interrupt(j)); + } +} \ No newline at end of file diff --git a/examples/ci-tests/i2c-slave-tx/test.py b/examples/ci-tests/i2c-slave-tx/test.py new file mode 100644 index 000000000..7fa7a227b --- /dev/null +++ b/examples/ci-tests/i2c-slave-tx/test.py @@ -0,0 +1,168 @@ +from smbus import SMBus +import time +import os +import logging +import unittest +import RPi.GPIO as GPIO + +RESET = 21 # Broadcom pin 21 (P1 pin 40) +BUTTON_1 = 20 # Broadcom pin 20 (P1 pin 38) + +GPIO.setwarnings(False) +GPIO.setmode(GPIO.BCM) +GPIO.setup(RESET, GPIO.OUT) # RESET pin set as output +GPIO.setup(BUTTON_1, GPIO.OUT) # BUTTON_1 pin set as output + +ADDRESS = 0x41 # bus address to the Slave Device +MASTER = 0x40 # Raspberry Pi Master Address +MESSAGE = "Hello friend." # Message sent from slave +BUF_SIZE = 16 +bus = SMBus(1) # indicates /dev/ic2-1 + +################################################################################ +# Helper Functions +################################################################################ + +def time_gap(start_time): + """Return time gap between current time and start_time + Argument: + start_time - Start time + """ + return "{:.6f}".format(time.time() - start_time) + +def reset(): + global RESET + """Button is Reset""" + + GPIO.output(RESET, GPIO.LOW) + time.sleep(1) + GPIO.output(RESET, GPIO.HIGH) + +def press_button(): + global BUTTON_1 + """Button is one of User Buttons""" + + GPIO.output(BUTTON_1, GPIO.HIGH) + time.sleep(1) + GPIO.output(BUTTON_1, GPIO.LOW) + +def message_decoder(data): + string = '' + for item in data: + string += chr(item) + return string + +# END + +################################################################################ +# Start test and logger +################################################################################ + +# Test Start Time +TEST_START_TIME = time.time() + +# Logger set format +LOG_FORMAT = "%(timegap)s %(levelname)s -- %(message)s" +logging.basicConfig(format=LOG_FORMAT) + +# Logger add formatter +logger = logging.getLogger('I2C Rx Test') +logger.setLevel('INFO') + +logger.info('Initiating I2C Rx test...', + extra={'timegap': time_gap(TEST_START_TIME)}) + +# END + +################################################################################ +# Test Case Module +################################################################################ + +class I2CRxTest(unittest.TestCase): + def test_i2c_slave_configuration(self): + + print() + logger.info('Communicating with I2C Device to Receive Message: ' + MESSAGE, + extra={'timegap': time_gap(TEST_START_TIME)}) + + received = False + + press_button() + + try: + dataM = bus.read_i2c_block_data(ADDRESS, MASTER, BUF_SIZE) + message = message_decoder(dataM) + message = str(message) + message_stripped = message.splitlines() + message_received = message_stripped[0] + + if(MESSAGE == message_received): + + logger.info('Message Received: ' + message_received, + extra={'timegap': time_gap(TEST_START_TIME)}) + time.sleep(1) + logger.info('Message Sent Successfully from Slave\n', + extra={'timegap': time_gap(TEST_START_TIME)}) + received = True + + except OSError: + print("OS error: {0}".format(err)) + + logger.info('Test failed...', + extra={'timegap': time_gap(TEST_START_TIME)}) + print() + + time.sleep(1) + except TimeoutError: + logger.info('Connection is poor: Time out error...\n', + extra={'timegap': time_gap(TEST_START_TIME)}) + + logger.info('Test failed...', + extra={'timegap': time_gap(TEST_START_TIME)}) + print() + + time.sleep(1) + finally: + logger.info('I2C Communication Ended...', + extra={'timegap': time_gap(TEST_START_TIME)}) + + reset() # Reset application to stop sending messages + + # Close Setup + GPIO.cleanup() + + bus.close() + + time.sleep(1) + + logger.info('Connection Satisfied.', + extra={'timegap': time_gap(TEST_START_TIME)}) + received = True + + time.sleep(1) + + logger.info('I2C Slave Tx Test has ended.\n', + extra={'timegap': time_gap(TEST_START_TIME)}) + + self.assertTrue(received) +# END + +################################################################################ +# Test Case Setup +################################################################################ + +class Nrf52840Test(I2CRxTest): + def setUp(self): + logger.info('Setting up for nrf52840dk I2C Rx test...', + extra={'timegap': time_gap(TEST_START_TIME)}) + + reset() + +# END + +################################################################################ +# Main +################################################################################ + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/examples/sampletests/i2cexamples/slavewrite/main.c b/examples/sampletests/i2cexamples/slavewrite/main.c index dc9c36fdd..f839cb69c 100644 --- a/examples/sampletests/i2cexamples/slavewrite/main.c +++ b/examples/sampletests/i2cexamples/slavewrite/main.c @@ -5,7 +5,7 @@ #include #include -#define BUF_SIZE 16 +#define BUF_SIZE 6 #define FOLLOW_ADDRESS 0x41 #define LEADER_ADDRESS 0x40 @@ -35,12 +35,36 @@ static void i2c_callback(int callback_type, } if (callback_type == TOCK_I2C_CB_MASTER_WRITE) { - printf("CB: Slave write\n"); + printf("CB: Slave Read\n"); - delay_ms(2500); + delay_ms(1000); + //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(FOLLOW_ADDRESS, BUF_SIZE)); + //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(LEADER_ADDRESS, BUF_SIZE)); + //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_listen()); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write_read(FOLLOW_ADDRESS, BUF_SIZE, BUF_SIZE)); + } else if (callback_type == TOCK_I2C_CB_SLAVE_WRITE) { + printf("CB: Slave write\n"); + //delay_ms(2500); + + printf("Write Buffer v2 is >%.*s<\n", BUF_SIZE, slave_write_buf); + //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_listen()); //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(FOLLOW_ADDRESS, BUF_SIZE)); - TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(LEADER_ADDRESS, BUF_SIZE)); - } else { + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write_read(FOLLOW_ADDRESS, BUF_SIZE, BUF_SIZE)); + } else if (callback_type == TOCK_I2C_CB_SLAVE_READ_REQUEST) { + printf("CB: Slave write\n"); + delay_ms(2500); + + printf("%s sending\n", is_leader ? "Leader" : "Follower"); + //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(LEADER_ADDRESS, BUF_SIZE)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(FOLLOW_ADDRESS, BUF_SIZE)); + } else if (callback_type == 7) { + printf("CB: Slave write 7\n"); + //delay_ms(2500); + + printf("Write Buffer v2 is >%.*s<\n", BUF_SIZE, slave_write_buf); + //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_listen()); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(FOLLOW_ADDRESS, BUF_SIZE)); + } else { printf("ERROR: Unexepected callback: type %d\n", callback_type); } } @@ -62,8 +86,10 @@ static void button_cb(__attribute__((unused)) int btn_num, printf("Sending to master\n"); - //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(FOLLOW_ADDRESS, BUF_SIZE)); - TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(LEADER_ADDRESS, BUF_SIZE)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(FOLLOW_ADDRESS, BUF_SIZE)); + //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_listen()); + //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(LEADER_ADDRESS, BUF_SIZE)); + //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write_read(FOLLOW_ADDRESS, BUF_SIZE, BUF_SIZE)); } } @@ -71,18 +97,28 @@ static void button_cb(__attribute__((unused)) int btn_num, // callbacks for I2C and button presses. Normal operation of this test takes // place in the subsequent callbacks. int main(void) { - printf("I2C Master/Slave Ping-Pong\n"); + printf("I2C Slave Sender"); // Prepare buffers - strcpy((char*) master_write_buf, "Hello friend.\n"); - strcpy((char*) slave_write_buf, "Hello friend.\n"); + // BUF_SIZE = 16 + //strcpy((char*) master_write_buf, "Hello friend.\n"); + //strcpy((char*) slave_write_buf, "Hello friend.\n"); + + // BUF_SIZE = 6 BELOW + strcpy((char*) master_write_buf, "Hello"); + strcpy((char*) slave_write_buf, "Hello"); + strcpy((char*) slave_read_buf, "Hello"); + + printf("Buffer is >%.*s<\n", BUF_SIZE, slave_write_buf); // Set up I2C peripheral TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_callback(i2c_callback, NULL)); + //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_enable_slave_read(BUF_SIZE)); TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_master_write_buffer(master_write_buf, BUF_SIZE)); TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_write_buffer(slave_write_buf, BUF_SIZE)); TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_read_buffer(slave_read_buf, BUF_SIZE)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_address(FOLLOW_ADDRESS)); TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_listen()); diff --git a/examples/sampletests/i2cexamples/slavewritev2/Makefile b/examples/sampletests/i2cexamples/slavewritev2/Makefile new file mode 100644 index 000000000..c13e35823 --- /dev/null +++ b/examples/sampletests/i2cexamples/slavewritev2/Makefile @@ -0,0 +1,11 @@ +# Makefile for user application + +# Specify this directory relative to the current application. +TOCK_USERLAND_BASE_DIR = ../../../../ + +# Which files to compile. +C_SRCS := $(wildcard *.c) + +# Include userland master makefile. Contains rules and flags for actually +# building the application. +include $(TOCK_USERLAND_BASE_DIR)/AppMakefile.mk \ No newline at end of file diff --git a/examples/sampletests/i2cexamples/slavewritev2/main.c b/examples/sampletests/i2cexamples/slavewritev2/main.c new file mode 100644 index 000000000..41d5bd443 --- /dev/null +++ b/examples/sampletests/i2cexamples/slavewritev2/main.c @@ -0,0 +1,109 @@ +#include +#include + +#include +#include +#include + +#define BUF_SIZE 16 +#define LEADER_ADDRESS 0x40 +#define FOLLOW_ADDRESS 0x41 + +uint8_t master_write_buf[BUF_SIZE]; +uint8_t master_read_buf[BUF_SIZE]; +uint8_t slave_write_buf[BUF_SIZE]; +uint8_t slave_read_buf[BUF_SIZE]; +bool is_leader = false; + + +// In response to a +static void i2c_callback(int callback_type, + __attribute__ ((unused)) int length, + __attribute__ ((unused)) int arg2, + __attribute__ ((unused)) void* userdata) { + // Watching for GPIO interrupts holds us in a higher power state, so stop + // doing that once we don't care about button presses any more (the first + // time having sent or received a message) + static bool any_message = false; + if (!any_message) { + int nbuttons; + button_count(&nbuttons); + int j; + for (j = 0; j < nbuttons; j++) { + button_disable_interrupt(j); + } + } + + if (callback_type == TOCK_I2C_CB_MASTER_WRITE) { + printf("CB: Master write\n"); + //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_listen()); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_enable_slave_read(BUF_SIZE)); + } else if (callback_type == TOCK_I2C_CB_SLAVE_WRITE) { + printf("CB: Slave write\n"); + //delay_ms(300); + + printf("%s sending\n", is_leader ? "Leader" : "Follower"); + //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(is_leader ? FOLLOW_ADDRESS : LEADER_ADDRESS, BUF_SIZE)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_enable_slave_read(BUF_SIZE)); + } else { + printf("ERROR: Unexepected callback: type %d\n", callback_type); + } +} + +// This is the callback for the button press. +// A button press indicates that this device should start the ping-pong +// exchange. First, change the address to the BUTTON_ADDRESS to avoid +// conflict with the other node, then send a message. +static void button_cb(__attribute__((unused)) int btn_num, + __attribute__ ((unused)) int arg1, + __attribute__ ((unused)) int arg2, + __attribute__ ((unused)) void* userdata) { + // Only the first press is meaningfull + static bool pressed = false; + + if (!pressed) { + pressed = true; + is_leader = true; + + printf("Sending to master\n"); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_enable_slave_read(BUF_SIZE)); + //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_address(LEADER_ADDRESS)); + //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(FOLLOW_ADDRESS, BUF_SIZE)); + } +} + +// This function sets up the I2C peripheral with needed buffers and prepares +// callbacks for I2C and button presses. Normal operation of this test takes +// place in the subsequent callbacks. +int main(void) { + printf("I2C Master/Slave Ping-Pong\n"); + + // Prepare buffers + strcpy((char*) master_write_buf, "Hello friend.\n"); + strcpy((char*) slave_read_buf, "Hello friend.\n"); + + // Set up I2C peripheral + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_callback(i2c_callback, NULL)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_master_write_buffer(master_write_buf, BUF_SIZE)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_master_read_buffer(master_read_buf, BUF_SIZE)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_write_buffer(slave_write_buf, BUF_SIZE)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_read_buffer(slave_read_buf, BUF_SIZE)); + + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_address(FOLLOW_ADDRESS)); + TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_listen()); + + // Set up button peripheral to grab any button press + TOCK_EXPECT(RETURNCODE_SUCCESS, button_subscribe(button_cb, NULL)); + + int nbuttons; + button_count(&nbuttons); + if (nbuttons < 1) { + printf("ERROR: This app requires that a board have at least one button.\n"); + exit(-1); + } + + int j; + for (j = 0; j < nbuttons; j++) { + TOCK_EXPECT(RETURNCODE_SUCCESS, button_enable_interrupt(j)); + } +} \ No newline at end of file From e23a51b97cccca12625410df27b0be0d21100d70 Mon Sep 17 00:00:00 2001 From: AnthonyQ619 Date: Mon, 16 Aug 2021 18:46:43 -0700 Subject: [PATCH 23/49] small updates --- examples/ci-tests/i2c-slave-rx/test.py | 22 +++++++++++++++++++++- examples/ci-tests/i2c-slave-tx/test.py | 2 +- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/examples/ci-tests/i2c-slave-rx/test.py b/examples/ci-tests/i2c-slave-rx/test.py index ed1d621fa..cdfc2536c 100644 --- a/examples/ci-tests/i2c-slave-rx/test.py +++ b/examples/ci-tests/i2c-slave-rx/test.py @@ -60,7 +60,7 @@ def message_converter(message): ################################################################################ class I2CRxTest(unittest.TestCase): - def test_i2c_slave_configuration(self): + def test_i2c_slave_rx_configuration(self): print() logger.info('Sending I2C Message: ' + MESSAGE, @@ -99,7 +99,27 @@ def test_i2c_slave_configuration(self): logger.info('I2C Communication Ended...', extra={'timegap': time_gap(TEST_START_TIME)}) + logger.info('I2C Communication Ended...', + extra={'timegap': time_gap(TEST_START_TIME)}) + + reset() # Reset application to stop sending messages + + # Close Setup + GPIO.cleanup() + + bus.close() + time.sleep(1) + + logger.info('Connection Satisfied.', + extra={'timegap': time_gap(TEST_START_TIME)}) + received = True + + time.sleep(1) + + logger.info('I2C Slave Rx Test has ended.', + extra={'timegap': time_gap(TEST_START_TIME)}) + self.assertTrue(received) # END diff --git a/examples/ci-tests/i2c-slave-tx/test.py b/examples/ci-tests/i2c-slave-tx/test.py index 7fa7a227b..d0c658b64 100644 --- a/examples/ci-tests/i2c-slave-tx/test.py +++ b/examples/ci-tests/i2c-slave-tx/test.py @@ -79,7 +79,7 @@ def message_decoder(data): ################################################################################ class I2CRxTest(unittest.TestCase): - def test_i2c_slave_configuration(self): + def test_i2c_slave_tx_configuration(self): print() logger.info('Communicating with I2C Device to Receive Message: ' + MESSAGE, From 26457c9e87dbda1703f0d7163adab18eaa4f5a28 Mon Sep 17 00:00:00 2001 From: AnthonyQ619 Date: Mon, 16 Aug 2021 21:08:28 -0700 Subject: [PATCH 24/49] Updated --- examples/ci-tests/i2c-slave-rx/test.py | 1 - examples/ci-tests/i2c-slave-tx/test.py | 9 +++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/ci-tests/i2c-slave-rx/test.py b/examples/ci-tests/i2c-slave-rx/test.py index cdfc2536c..af6ce1ddc 100644 --- a/examples/ci-tests/i2c-slave-rx/test.py +++ b/examples/ci-tests/i2c-slave-rx/test.py @@ -105,7 +105,6 @@ def test_i2c_slave_rx_configuration(self): reset() # Reset application to stop sending messages # Close Setup - GPIO.cleanup() bus.close() diff --git a/examples/ci-tests/i2c-slave-tx/test.py b/examples/ci-tests/i2c-slave-tx/test.py index d0c658b64..53162364a 100644 --- a/examples/ci-tests/i2c-slave-tx/test.py +++ b/examples/ci-tests/i2c-slave-tx/test.py @@ -66,10 +66,10 @@ def message_decoder(data): logging.basicConfig(format=LOG_FORMAT) # Logger add formatter -logger = logging.getLogger('I2C Rx Test') +logger = logging.getLogger('I2C Tx Test') logger.setLevel('INFO') -logger.info('Initiating I2C Rx test...', +logger.info('Initiating I2C Tx test...', extra={'timegap': time_gap(TEST_START_TIME)}) # END @@ -153,10 +153,11 @@ def test_i2c_slave_tx_configuration(self): class Nrf52840Test(I2CRxTest): def setUp(self): - logger.info('Setting up for nrf52840dk I2C Rx test...', + reset() + + logger.info('Setting up for nrf52840dk I2C Tx test...', extra={'timegap': time_gap(TEST_START_TIME)}) - reset() # END From 0db9df4667cb681177dd64ade50aaadb3b8b99ce Mon Sep 17 00:00:00 2001 From: AnthonyQ619 Date: Mon, 16 Aug 2021 21:17:12 -0700 Subject: [PATCH 25/49] Updated --- examples/ci-tests/i2c-slave-rx/test.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/ci-tests/i2c-slave-rx/test.py b/examples/ci-tests/i2c-slave-rx/test.py index af6ce1ddc..e7bcfade4 100644 --- a/examples/ci-tests/i2c-slave-rx/test.py +++ b/examples/ci-tests/i2c-slave-rx/test.py @@ -102,8 +102,6 @@ def test_i2c_slave_rx_configuration(self): logger.info('I2C Communication Ended...', extra={'timegap': time_gap(TEST_START_TIME)}) - reset() # Reset application to stop sending messages - # Close Setup bus.close() From 3958f0e66a568e3747789d174aace14ce7b35a5a Mon Sep 17 00:00:00 2001 From: AnthonyQ619 Date: Mon, 16 Aug 2021 21:23:23 -0700 Subject: [PATCH 26/49] Updated --- examples/ci-tests/i2c-slave-rx/main.c | 2 +- examples/ci-tests/i2c-slave-rx/test.py | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/examples/ci-tests/i2c-slave-rx/main.c b/examples/ci-tests/i2c-slave-rx/main.c index 8bedb2995..373de6704 100644 --- a/examples/ci-tests/i2c-slave-rx/main.c +++ b/examples/ci-tests/i2c-slave-rx/main.c @@ -30,7 +30,7 @@ int main(void) { printf("I2C Slave Read \n"); //Preparing buffer - strncpy(slave_write_buf, "0123456789ABCDEFG", BUF_SIZE); + strncpy(slave_write_buf, "0123456789ABCDEF", BUF_SIZE); printf("Buffer is >%.*s<\n", BUF_SIZE, slave_write_buf); // Set up I2C peripheral diff --git a/examples/ci-tests/i2c-slave-rx/test.py b/examples/ci-tests/i2c-slave-rx/test.py index e7bcfade4..99bfd0744 100644 --- a/examples/ci-tests/i2c-slave-rx/test.py +++ b/examples/ci-tests/i2c-slave-rx/test.py @@ -99,9 +99,6 @@ def test_i2c_slave_rx_configuration(self): logger.info('I2C Communication Ended...', extra={'timegap': time_gap(TEST_START_TIME)}) - logger.info('I2C Communication Ended...', - extra={'timegap': time_gap(TEST_START_TIME)}) - # Close Setup bus.close() From 1b41d0455b240b0caced2948e25978d9540cf5e9 Mon Sep 17 00:00:00 2001 From: AnthonyQ619 Date: Mon, 16 Aug 2021 21:36:48 -0700 Subject: [PATCH 27/49] Updated --- examples/ci-tests/i2c-slave-rx/main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/ci-tests/i2c-slave-rx/main.c b/examples/ci-tests/i2c-slave-rx/main.c index 373de6704..757a4f106 100644 --- a/examples/ci-tests/i2c-slave-rx/main.c +++ b/examples/ci-tests/i2c-slave-rx/main.c @@ -6,7 +6,6 @@ #include #define BUF_SIZE 17 -#define LEADER_ADDRESS 0x40 #define FOLLOW_ADDRESS 0x41 uint8_t slave_write_buf[BUF_SIZE]; @@ -30,7 +29,7 @@ int main(void) { printf("I2C Slave Read \n"); //Preparing buffer - strncpy(slave_write_buf, "0123456789ABCDEF", BUF_SIZE); + strncpy((char*) slave_write_buf, "0123456789ABCDEF", BUF_SIZE); printf("Buffer is >%.*s<\n", BUF_SIZE, slave_write_buf); // Set up I2C peripheral From f68d47d1f77eebc5ef11eeb886e3490ad5e308fd Mon Sep 17 00:00:00 2001 From: AnthonyQ619 Date: Tue, 17 Aug 2021 11:46:56 -0700 Subject: [PATCH 28/49] New Readme's --- examples/ci-tests/i2c-master-rx/README.md | 22 ++++++++++++++++++++++ examples/ci-tests/i2c-master-tx/README.md | 22 ++++++++++++++++++++++ examples/ci-tests/i2c-slave-rx/README.md | 20 ++++++++++++++++++++ examples/ci-tests/i2c-slave-tx/README.md | 22 ++++++++++++++++++++++ examples/ci-tests/uartrt/README.md | 17 +++++++++++++++++ 5 files changed, 103 insertions(+) create mode 100644 examples/ci-tests/i2c-master-rx/README.md create mode 100644 examples/ci-tests/i2c-master-tx/README.md create mode 100644 examples/ci-tests/i2c-slave-rx/README.md create mode 100644 examples/ci-tests/i2c-slave-tx/README.md create mode 100644 examples/ci-tests/uartrt/README.md diff --git a/examples/ci-tests/i2c-master-rx/README.md b/examples/ci-tests/i2c-master-rx/README.md new file mode 100644 index 000000000..13f0af555 --- /dev/null +++ b/examples/ci-tests/i2c-master-rx/README.md @@ -0,0 +1,22 @@ +# Hardware CI Tests + +## Run Python Test + +`test.py` provides basic test that sends message from slave to master, and waits for master to send message containing the slave message. This is essentially a Rx/Tx test, but we are primarily focusing on the reception of master here. The message sent from master will be printed over a 12 second period. If message sent from master is the exact same from message sent from slave, the test will pass. + +To run the test, +```bash +sudo python3 test.py Nrf52840GpioTest +``` + +Switch board name to the test you intend to run. Otherwise, python unittest +will attempt to run all tests. + +Board | Test Name +------|---------- +nrf52840dk | Nrf52840Test + +**NOTE** +This test requires the Raspberry Pi to be set as slave. Thus, you must use Broadcom Pins 10 & 11 (SDA & SCL resepectively) or GPIO pin 19 and 23. You must also download the open source python library "pigpio" which enables slave access on the Raspberry Pi. How to download the library is done here on **CI Hardware Documentation - Raspberry Pi setup** + +This test requires button activation on tested boards. Two jumpers are required for the activation of the reset button and user button on boards. Broadcom Pins on Raspberry PI used are pins 20 & 21 (GPIO Pins 38 & 40) which are used for user button and reset respectively. \ No newline at end of file diff --git a/examples/ci-tests/i2c-master-tx/README.md b/examples/ci-tests/i2c-master-tx/README.md new file mode 100644 index 000000000..1450b5a62 --- /dev/null +++ b/examples/ci-tests/i2c-master-tx/README.md @@ -0,0 +1,22 @@ +# Hardware CI Tests + +## Run Python Test + +`test.py` provides basic test that sends message from master to slave, and waits for a 12 second period of master sending messages, but captures the first message sent. The message sent from master will be printed over a 12 second period. If message sent from master is the same as the expected message to be sent, then test will pass. + +To run the test, +```bash +sudo python3 test.py Nrf52840GpioTest +``` + +Switch board name to the test you intend to run. Otherwise, python unittest +will attempt to run all tests. + +Board | Test Name +------|---------- +nrf52840dk | Nrf52840Test + +**NOTE** +This test requires the Raspberry Pi to be set as slave. Thus, you must use Broadcom Pins 10 & 11 (SDA & SCL resepectively) or GPIO pin 19 and 23. You must also download the open source python library "pigpio" which enables slave access on the Raspberry Pi. How to download the library is done here on **CI Hardware Documentation - Raspberry Pi setup** + +This test requires button activation on tested boards. Two jumpers are required for the activation of the reset button and user button on boards. Broadcom Pins on Raspberry PI used are pins 20 & 21 (GPIO Pins 38 & 40) which are used for user button and reset respectively. The user button and reset button depend on board tested. \ No newline at end of file diff --git a/examples/ci-tests/i2c-slave-rx/README.md b/examples/ci-tests/i2c-slave-rx/README.md new file mode 100644 index 000000000..a754ce6f4 --- /dev/null +++ b/examples/ci-tests/i2c-slave-rx/README.md @@ -0,0 +1,20 @@ +# Hardware CI Tests + +## Run Python Test + +`test.py` provides basic test that sends message from master to slave. Tests if slave receives message through proper connection with specific function. If function fails, and throws out exception, then test fails. Otherwise, test will pass if connection is satisfied. + +To run the test, +```bash +sudo python3 test.py Nrf52840GpioTest +``` + +Switch board name to the test you intend to run. Otherwise, python unittest +will attempt to run all tests. + +Board | Test Name +------|---------- +nrf52840dk | Nrf52840Test + +**NOTE** +This test requires the Raspberry Pi to be set as Master. Thus, you must use Broadcom Pins 2 & 3 (SDA & SCL resepectively) or GPIO pin 3 and 5. \ No newline at end of file diff --git a/examples/ci-tests/i2c-slave-tx/README.md b/examples/ci-tests/i2c-slave-tx/README.md new file mode 100644 index 000000000..391670e40 --- /dev/null +++ b/examples/ci-tests/i2c-slave-tx/README.md @@ -0,0 +1,22 @@ +# Hardware CI Tests + +## Run Python Test + +`test.py` provides basic test that sends message from slave to master, and master checks if message has been sent through a specific function. If function has been called with proper connection, then check if message sent is what's expected. If so, test passes. Otherwise, test will fail due to poor connection or exception thrown from function, or message sent was not the expected message. + +To run the test, +```bash +sudo python3 test.py Nrf52840GpioTest +``` + +Switch board name to the test you intend to run. Otherwise, python unittest +will attempt to run all tests. + +Board | Test Name +------|---------- +nrf52840dk | Nrf52840Test + +**NOTE** +This test requires the Raspberry Pi to be set as Master. Thus, you must use Broadcom Pins 2 & 3 (SDA & SCL resepectively) or GPIO pin 3 and 5. + +This test requires button activation on tested boards. Two jumpers are required for the activation of the reset button and user button on boards. Broadcom Pins on Raspberry PI used are pins 20 & 21 (GPIO Pins 38 & 40) which are used for user button and reset respectively. \ No newline at end of file diff --git a/examples/ci-tests/uartrt/README.md b/examples/ci-tests/uartrt/README.md new file mode 100644 index 000000000..5ac5ce55d --- /dev/null +++ b/examples/ci-tests/uartrt/README.md @@ -0,0 +1,17 @@ +# Hardware CI Tests + +## Run Python Test + +`test.py` provides basic test that send character over uart connection, and same expects character to be returned. Provides this test over a course of 45 seconds. If character returned was not the same in this buffer period, test will fail. Otherwise, correct character was returned and test will pass. + +To run the test, +```bash +sudo python3 test.py Nrf52840GpioTest +``` + +Switch board name to the test you intend to run. Otherwise, python unittest +will attempt to run all tests. + +Board | Test Name +------|---------- +nrf52840dk | Nrf52840Test \ No newline at end of file From b751a7ce35330543ed746d680427ea1d5770909d Mon Sep 17 00:00:00 2001 From: AnthonyQ619 Date: Wed, 18 Aug 2021 15:20:05 -0700 Subject: [PATCH 29/49] Fixed Readme's --- examples/ci-tests/i2c-master-rx/README.md | 2 +- examples/ci-tests/i2c-master-tx/README.md | 2 +- examples/ci-tests/i2c-slave-rx/README.md | 2 +- examples/ci-tests/i2c-slave-tx/README.md | 2 +- examples/ci-tests/uartrt/README.md | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/ci-tests/i2c-master-rx/README.md b/examples/ci-tests/i2c-master-rx/README.md index 13f0af555..d8da3e97f 100644 --- a/examples/ci-tests/i2c-master-rx/README.md +++ b/examples/ci-tests/i2c-master-rx/README.md @@ -6,7 +6,7 @@ To run the test, ```bash -sudo python3 test.py Nrf52840GpioTest +sudo python3 test.py Nrf52840Test ``` Switch board name to the test you intend to run. Otherwise, python unittest diff --git a/examples/ci-tests/i2c-master-tx/README.md b/examples/ci-tests/i2c-master-tx/README.md index 1450b5a62..8e29cff36 100644 --- a/examples/ci-tests/i2c-master-tx/README.md +++ b/examples/ci-tests/i2c-master-tx/README.md @@ -6,7 +6,7 @@ To run the test, ```bash -sudo python3 test.py Nrf52840GpioTest +sudo python3 test.py Nrf52840Test ``` Switch board name to the test you intend to run. Otherwise, python unittest diff --git a/examples/ci-tests/i2c-slave-rx/README.md b/examples/ci-tests/i2c-slave-rx/README.md index a754ce6f4..1df866752 100644 --- a/examples/ci-tests/i2c-slave-rx/README.md +++ b/examples/ci-tests/i2c-slave-rx/README.md @@ -6,7 +6,7 @@ To run the test, ```bash -sudo python3 test.py Nrf52840GpioTest +sudo python3 test.py Nrf52840Test ``` Switch board name to the test you intend to run. Otherwise, python unittest diff --git a/examples/ci-tests/i2c-slave-tx/README.md b/examples/ci-tests/i2c-slave-tx/README.md index 391670e40..c1b42c14e 100644 --- a/examples/ci-tests/i2c-slave-tx/README.md +++ b/examples/ci-tests/i2c-slave-tx/README.md @@ -6,7 +6,7 @@ To run the test, ```bash -sudo python3 test.py Nrf52840GpioTest +sudo python3 test.py Nrf52840Test ``` Switch board name to the test you intend to run. Otherwise, python unittest diff --git a/examples/ci-tests/uartrt/README.md b/examples/ci-tests/uartrt/README.md index 5ac5ce55d..0845dc970 100644 --- a/examples/ci-tests/uartrt/README.md +++ b/examples/ci-tests/uartrt/README.md @@ -6,7 +6,7 @@ To run the test, ```bash -sudo python3 test.py Nrf52840GpioTest +sudo python3 test.py Nrf52840Test ``` Switch board name to the test you intend to run. Otherwise, python unittest From e6d4327fe62b2a8c7401b09cf36477dcf3de0d1f Mon Sep 17 00:00:00 2001 From: AnthonyQ619 Date: Mon, 23 Aug 2021 04:51:39 +0000 Subject: [PATCH 30/49] Updated i2c Tests --- examples/ci-tests/i2c-master-rx/test.py | 71 ++++++++++++++++++++++--- examples/ci-tests/i2c-master-tx/test.py | 11 +++- examples/ci-tests/uartrt/test.py | 50 ++++++----------- 3 files changed, 90 insertions(+), 42 deletions(-) diff --git a/examples/ci-tests/i2c-master-rx/test.py b/examples/ci-tests/i2c-master-rx/test.py index 50975764d..5a3ef0277 100644 --- a/examples/ci-tests/i2c-master-rx/test.py +++ b/examples/ci-tests/i2c-master-rx/test.py @@ -7,6 +7,8 @@ MESSAGE_SENT = "Hello I'm Slave" # Message Master sends to slave MESSAGE_CONFIRMATION= '' FIRST_RX = 0 +dummy = False #Setup for dummy transaction (Buffer takes one transaction session to update) + SDA = 10 # Broadcom pin 10 (P1 pin 19) SCL = 11 # Broadcom pin 11 (P1 pin 23) @@ -22,6 +24,8 @@ # Set up PiGPIO properly by configuring it on pi then importing library os.system('sudo pigpiod') +time.sleep(1) + import pigpio pi = pigpio.pi() # Configure the Raspberry Pi as slave @@ -59,17 +63,58 @@ def i2c(id, tick): global FIRST_RX global MESSAGE_CONFIRMATION global I2C_ADDR + global dummy s, b, d = pi.bsc_i2c(I2C_ADDR, b"\nHello I'm Slave\n") + if not dummy: + if b: + if(FIRST_RX < 1): + MESSAGE_CONFIRMATION = d.decode() + FIRST_RX += 1 - if b: - if(FIRST_RX < 1): - MESSAGE_CONFIRMATION = d.decode() - FIRST_RX += 1 + array = str(d[:-1]) + logger.info('Messsage Call Back From Master: ' + array, + extra={'timegap': time_gap(TEST_START_TIME)}) - array = str(d[:-1]) - logger.info('Messsage Call Back From Master: ' + array, - extra={'timegap': time_gap(TEST_START_TIME)}) + +def dummy_transaction(): + global pi + global I2C_ADDR + global dummy + """ + This function is used to conteract the update delay + on the i2c slave buffer. The delay occurs when the buffer is + updated and requires the bus to enact a transcation before the + update actually takes place. This function, then, initiates + that transaction to occur, and update the buffer in proper time. + """ + + dummy = True # Update to initiate the dummy transaction properly + + if not pi.connected: + exit() + + press_button() + + # Add pull-ups in case external pull-ups haven't been added (For Raspberry Pi) + + pi.set_pull_up_down(SDA, pigpio.PUD_UP) + pi.set_pull_up_down(SCL, pigpio.PUD_UP) + + # Respond to BSC slave activity + e = pi.event_callback(pigpio.EVENT_BSC, i2c) + + pi.bsc_i2c(I2C_ADDR) + + time.sleep(4) + + e.cancel() + + pi.bsc_i2c(0) + + reset() + + dummy = False # Return to normal, so proper testing is conducted # END @@ -103,10 +148,12 @@ def test_i2c_master_rx_configuration(self): global pi global MESSAGE_CONFIRMATION + dummy_transaction() # Initiate the dummy transaction (updates buffer in proper time) + print() logger.info('Sending Messages As Slave... ', extra={'timegap': time_gap(TEST_START_TIME)}) - + received = False if not pi.connected: @@ -163,6 +210,10 @@ def test_i2c_master_rx_configuration(self): logger.info('I2C Master Rx Test has ended.', extra={'timegap': time_gap(TEST_START_TIME)}) + + os.system('sudo killall pigpiod') + time.sleep(1) + self.assertTrue(received) else: @@ -188,6 +239,10 @@ def test_i2c_master_rx_configuration(self): logger.info('I2C Master Rx Test has ended.', extra={'timegap': time_gap(TEST_START_TIME)}) + + os.system('sudo killall pigpiod') + time.sleep(1) + self.assertTrue(received) diff --git a/examples/ci-tests/i2c-master-tx/test.py b/examples/ci-tests/i2c-master-tx/test.py index 2cd895b86..f4893b380 100644 --- a/examples/ci-tests/i2c-master-tx/test.py +++ b/examples/ci-tests/i2c-master-tx/test.py @@ -22,6 +22,7 @@ # Set up PiGPIO properly by configuring it on pi then importing library os.system('sudo pigpiod') +time.sleep(1) import pigpio pi = pigpio.pi() # Configure the Raspberry Pi as slave @@ -164,6 +165,10 @@ def test_i2c_master_tx_configuration(self): logger.info('I2C Master Tx Test has ended.', extra={'timegap': time_gap(TEST_START_TIME)}) + + os.system('sudo killall pigpiod') + time.sleep(1) + self.assertTrue(received) else: @@ -188,6 +193,10 @@ def test_i2c_master_tx_configuration(self): logger.info('I2C Master Tx Test has ended.', extra={'timegap': time_gap(TEST_START_TIME)}) + + os.system('sudo killall pigpiod') + time.sleep(1) + self.assertTrue(received) @@ -213,4 +222,4 @@ def setUp(self): ################################################################################ if __name__ == '__main__': - unittest.main() \ No newline at end of file + unittest.main() diff --git a/examples/ci-tests/uartrt/test.py b/examples/ci-tests/uartrt/test.py index 77a6fb57c..e30c04cad 100644 --- a/examples/ci-tests/uartrt/test.py +++ b/examples/ci-tests/uartrt/test.py @@ -6,40 +6,11 @@ import struct TARGET_ACKNOWLEDGEMENT = "" - -sp = serial.Serial(port="/dev/ttyACM0", baudrate=115200, bytesize=8, timeout=2) +sp = None +#sp = serial.Serial(port="/dev/ttyACM0", baudrate=115200, bytesize=8, timeout=2) +#sp = serial.Serial(port="/dev/ttyUSB0", baudrate=115200, bytesize=8, timeout=2) ser = serial.Serial(port="/dev/ttyS0", baudrate=115200, bytesize=8, parity="N", stopbits=1); print("Starting Uart Rx/TX Test...\n") -#while(1): -# c = random.randint(65, 90) -# message = chr(c) -# ser.write(struct.pack(' 0): -# # print("A") -# print("Message sent: " + message) -# #time.sleep(5) -# sp.readline() -# if(sp.in_waiting > 0): -# message_received = sp.readline() -# message_received = message_received.decode("Ascii") -# print("Message: " + message_received) -# char_received = message_received[-1] -# print("Echoed: " + char_received + "\n") -# if(char_received == message): -# print("Correct Serial Communication Message Received") -# break -# - -#print("Uart Rx/Tx Test Passes") -#sp.close() -#ser.close() -#sp.open() -#ser.open() -#time.sleep(4) -#ser.write(b"yeah") ################################################################################ # Helper Functions @@ -85,6 +56,8 @@ def test_uart_rx_tx(self): buffer_period = float(time_gap(TEST_START_TIME)) if(buffer_period > 45.0): + sp.close() + ser.close() self.assertTrue(False) c = random.randint(65, 90) @@ -96,7 +69,7 @@ def test_uart_rx_tx(self): time.sleep(5) if(sp.in_waiting > 0): - # print("A") + print("A") logger.info('Message sent: ' + TARGET_ACKNOWLEDGEMENT, extra={'timegap': time_gap(TEST_START_TIME)}) #time.sleep(5) @@ -127,9 +100,20 @@ def test_uart_rx_tx(self): class Nrf52840Test(UartTest): def setUp(self): + global sp + + sp = serial.Serial(port="/dev/ttyACM0", baudrate=115200, bytesize=8, timeout=2) logger.info('Setting up for nrf52840dk Uart Rx/Tx test...', extra={'timegap': time_gap(TEST_START_TIME)}) +class HailTest(UartTest): + def setUp(self): + global sp + + sp = serial.Serial(port="/dev/ttyUSB0", baudrate=115200, bytesize=8, parity="N", stopbits=1); + logger.info('Setting up for hail Uart Rx/Tx test...', + extra={'timegap': time_gap(TEST_START_TIME)}) + # END ################################################################################ From 57f0421f01cc2df1cc7978669a74cbc96f1721b5 Mon Sep 17 00:00:00 2001 From: AnthonyQ619 Date: Tue, 24 Aug 2021 06:09:37 +0000 Subject: [PATCH 31/49] update to tests --- examples/ci-tests/i2c-master-rx/README.md | 4 +++- examples/ci-tests/i2c-master-tx/main.c | 3 +-- examples/ci-tests/i2c-slave-rx/test.py | 6 +++--- examples/ci-tests/i2c-slave-tx/main.c | 5 +---- examples/ci-tests/i2c-slave-tx/test.py | 26 ++++++++++++----------- examples/ci-tests/uartrt/test.py | 3 +-- 6 files changed, 23 insertions(+), 24 deletions(-) diff --git a/examples/ci-tests/i2c-master-rx/README.md b/examples/ci-tests/i2c-master-rx/README.md index d8da3e97f..bea9daee6 100644 --- a/examples/ci-tests/i2c-master-rx/README.md +++ b/examples/ci-tests/i2c-master-rx/README.md @@ -19,4 +19,6 @@ nrf52840dk | Nrf52840Test **NOTE** This test requires the Raspberry Pi to be set as slave. Thus, you must use Broadcom Pins 10 & 11 (SDA & SCL resepectively) or GPIO pin 19 and 23. You must also download the open source python library "pigpio" which enables slave access on the Raspberry Pi. How to download the library is done here on **CI Hardware Documentation - Raspberry Pi setup** -This test requires button activation on tested boards. Two jumpers are required for the activation of the reset button and user button on boards. Broadcom Pins on Raspberry PI used are pins 20 & 21 (GPIO Pins 38 & 40) which are used for user button and reset respectively. \ No newline at end of file +This test requires button activation on tested boards. Two jumpers are required for the activation of the reset button and user button on boards. Broadcom Pins on Raspberry PI used are pins 20 & 21 (GPIO Pins 38 & 40) which are used for user button and reset respectively. + +This test utilizes the pigpio open source library, but the function utilized, `bsc_i2c` , has a delay when updated the buffer. This delay, to be specific, takes a an i2c transaction to update between the board and the RPi. This is a limitation of the RPi slave configuration, not the board being tested i2c configuration. To combat this, we utilize a dummy transaction that runs a i2c transaction of sending messages for 4 seconds, then reopens a transaction (the transacton being tested) with the updated buffer properly timed. For more information, check the code `test.py` and the function `dummy_transaction`. diff --git a/examples/ci-tests/i2c-master-tx/main.c b/examples/ci-tests/i2c-master-tx/main.c index 0cf317a9f..613bda123 100644 --- a/examples/ci-tests/i2c-master-tx/main.c +++ b/examples/ci-tests/i2c-master-tx/main.c @@ -38,7 +38,6 @@ static void i2c_callback(int callback_type, delay_ms(2500); printf("Sending: Hello friend.\n"); - //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(FOLLOW_ADDRESS, BUF_SIZE)); TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(FOLLOW_ADDRESS, BUF_SIZE)); } else { printf("ERROR: Unexepected callback: type %d\n", callback_type); @@ -98,4 +97,4 @@ int main(void) { for (j = 0; j < nbuttons; j++) { TOCK_EXPECT(RETURNCODE_SUCCESS, button_enable_interrupt(j)); } -} \ No newline at end of file +} diff --git a/examples/ci-tests/i2c-slave-rx/test.py b/examples/ci-tests/i2c-slave-rx/test.py index 99bfd0744..3ce70ce8d 100644 --- a/examples/ci-tests/i2c-slave-rx/test.py +++ b/examples/ci-tests/i2c-slave-rx/test.py @@ -59,7 +59,7 @@ def message_converter(message): # Test Case Module ################################################################################ -class I2CRxTest(unittest.TestCase): +class I2CSlaveRxTest(unittest.TestCase): def test_i2c_slave_rx_configuration(self): print() @@ -121,9 +121,9 @@ def test_i2c_slave_rx_configuration(self): # Test Case Setup ################################################################################ -class Nrf52840Test(I2CRxTest): +class Nrf52840Test(I2CSlaveRxTest): def setUp(self): - logger.info('Setting up for nrf52840dk I2C Rx test...', + logger.info('Setting up for nrf52840dk I2C Slave Rx test...', extra={'timegap': time_gap(TEST_START_TIME)}) # END diff --git a/examples/ci-tests/i2c-slave-tx/main.c b/examples/ci-tests/i2c-slave-tx/main.c index 4e6c304ff..616a88c8d 100644 --- a/examples/ci-tests/i2c-slave-tx/main.c +++ b/examples/ci-tests/i2c-slave-tx/main.c @@ -6,7 +6,6 @@ #include #define BUF_SIZE 16 -//#define LEADER_ADDRESS 0x40 #define FOLLOW_ADDRESS 0x41 uint8_t master_write_buf[BUF_SIZE]; @@ -79,8 +78,6 @@ int main(void) { // Set up I2C peripheral TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_callback(i2c_callback, NULL)); - //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_master_write_buffer(master_write_buf, BUF_SIZE)); - //TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_master_read_buffer(master_read_buf, BUF_SIZE)); TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_write_buffer(slave_write_buf, BUF_SIZE)); TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_read_buffer(slave_read_buf, BUF_SIZE)); @@ -101,4 +98,4 @@ int main(void) { for (j = 0; j < nbuttons; j++) { TOCK_EXPECT(RETURNCODE_SUCCESS, button_enable_interrupt(j)); } -} \ No newline at end of file +} diff --git a/examples/ci-tests/i2c-slave-tx/test.py b/examples/ci-tests/i2c-slave-tx/test.py index 53162364a..589192c7e 100644 --- a/examples/ci-tests/i2c-slave-tx/test.py +++ b/examples/ci-tests/i2c-slave-tx/test.py @@ -66,10 +66,10 @@ def message_decoder(data): logging.basicConfig(format=LOG_FORMAT) # Logger add formatter -logger = logging.getLogger('I2C Tx Test') +logger = logging.getLogger('I2C Slave Tx Test') logger.setLevel('INFO') -logger.info('Initiating I2C Tx test...', +logger.info('Initiating I2C Slave Tx test...', extra={'timegap': time_gap(TEST_START_TIME)}) # END @@ -78,7 +78,7 @@ def message_decoder(data): # Test Case Module ################################################################################ -class I2CRxTest(unittest.TestCase): +class I2CSlaveTxTest(unittest.TestCase): def test_i2c_slave_tx_configuration(self): print() @@ -100,9 +100,17 @@ def test_i2c_slave_tx_configuration(self): logger.info('Message Received: ' + message_received, extra={'timegap': time_gap(TEST_START_TIME)}) + time.sleep(1) + logger.info('Message Sent Successfully from Slave\n', extra={'timegap': time_gap(TEST_START_TIME)}) + + logger.info('Connection Satisfied.', + extra={'timegap': time_gap(TEST_START_TIME)}) + + time.sleep(1) + received = True except OSError: @@ -135,12 +143,6 @@ def test_i2c_slave_tx_configuration(self): time.sleep(1) - logger.info('Connection Satisfied.', - extra={'timegap': time_gap(TEST_START_TIME)}) - received = True - - time.sleep(1) - logger.info('I2C Slave Tx Test has ended.\n', extra={'timegap': time_gap(TEST_START_TIME)}) @@ -151,11 +153,11 @@ def test_i2c_slave_tx_configuration(self): # Test Case Setup ################################################################################ -class Nrf52840Test(I2CRxTest): +class Nrf52840Test(I2CSlaveTxTest): def setUp(self): reset() - logger.info('Setting up for nrf52840dk I2C Tx test...', + logger.info('Setting up for nrf52840dk I2C Slave Tx test...', extra={'timegap': time_gap(TEST_START_TIME)}) @@ -166,4 +168,4 @@ def setUp(self): ################################################################################ if __name__ == '__main__': - unittest.main() \ No newline at end of file + unittest.main() diff --git a/examples/ci-tests/uartrt/test.py b/examples/ci-tests/uartrt/test.py index e30c04cad..b2d4df281 100644 --- a/examples/ci-tests/uartrt/test.py +++ b/examples/ci-tests/uartrt/test.py @@ -9,7 +9,7 @@ sp = None #sp = serial.Serial(port="/dev/ttyACM0", baudrate=115200, bytesize=8, timeout=2) #sp = serial.Serial(port="/dev/ttyUSB0", baudrate=115200, bytesize=8, timeout=2) -ser = serial.Serial(port="/dev/ttyS0", baudrate=115200, bytesize=8, parity="N", stopbits=1); +ser = serial.Serial(port="/dev/ttyS0", baudrate=115200, bytesize=8, parity="N", stopbits=1) print("Starting Uart Rx/TX Test...\n") ################################################################################ @@ -69,7 +69,6 @@ def test_uart_rx_tx(self): time.sleep(5) if(sp.in_waiting > 0): - print("A") logger.info('Message sent: ' + TARGET_ACKNOWLEDGEMENT, extra={'timegap': time_gap(TEST_START_TIME)}) #time.sleep(5) From 16dc1d457e5c311b92609dabf8605973962cc7f6 Mon Sep 17 00:00:00 2001 From: AnthonyQ619 Date: Mon, 23 Aug 2021 23:19:56 -0700 Subject: [PATCH 32/49] quick updates --- examples/ci-tests/i2c-master-rx/README.md | 2 +- examples/ci-tests/i2c-master-rx/test.py | 16 +++++++++------- examples/ci-tests/i2c-master-tx/test.py | 2 +- examples/ci-tests/i2c-slave-tx/test.py | 4 ++-- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/examples/ci-tests/i2c-master-rx/README.md b/examples/ci-tests/i2c-master-rx/README.md index bea9daee6..1aacaaab7 100644 --- a/examples/ci-tests/i2c-master-rx/README.md +++ b/examples/ci-tests/i2c-master-rx/README.md @@ -21,4 +21,4 @@ This test requires the Raspberry Pi to be set as slave. Thus, you must use Broad This test requires button activation on tested boards. Two jumpers are required for the activation of the reset button and user button on boards. Broadcom Pins on Raspberry PI used are pins 20 & 21 (GPIO Pins 38 & 40) which are used for user button and reset respectively. -This test utilizes the pigpio open source library, but the function utilized, `bsc_i2c` , has a delay when updated the buffer. This delay, to be specific, takes a an i2c transaction to update between the board and the RPi. This is a limitation of the RPi slave configuration, not the board being tested i2c configuration. To combat this, we utilize a dummy transaction that runs a i2c transaction of sending messages for 4 seconds, then reopens a transaction (the transacton being tested) with the updated buffer properly timed. For more information, check the code `test.py` and the function `dummy_transaction`. +This test utilizes the pigpio open source library, but the function utilized, `bsc_i2c` , has a delay when updating the buffer. This delay, to be specific, takes a an i2c transaction to update between the board and the RPi. This is a limitation of the RPi slave configuration, not the board being tested i2c configuration. To combat this, we utilize a dummy transaction that runs a i2c transaction of sending messages for 4 seconds, then reopens a transaction (the transacton being tested) with the updated buffer properly timed. For more information, check the code `test.py` and the function `dummy_transaction`. diff --git a/examples/ci-tests/i2c-master-rx/test.py b/examples/ci-tests/i2c-master-rx/test.py index 5a3ef0277..b8fa531cf 100644 --- a/examples/ci-tests/i2c-master-rx/test.py +++ b/examples/ci-tests/i2c-master-rx/test.py @@ -7,7 +7,7 @@ MESSAGE_SENT = "Hello I'm Slave" # Message Master sends to slave MESSAGE_CONFIRMATION= '' FIRST_RX = 0 -dummy = False #Setup for dummy transaction (Buffer takes one transaction session to update) +dummy = False #Setup for dummy transaction (Buffer takes one transaction session to update properly) SDA = 10 # Broadcom pin 10 (P1 pin 19) @@ -66,6 +66,8 @@ def i2c(id, tick): global dummy s, b, d = pi.bsc_i2c(I2C_ADDR, b"\nHello I'm Slave\n") + + # Check if dummy transaction is occuring, if not, test has started. if not dummy: if b: if(FIRST_RX < 1): @@ -85,11 +87,11 @@ def dummy_transaction(): This function is used to conteract the update delay on the i2c slave buffer. The delay occurs when the buffer is updated and requires the bus to enact a transcation before the - update actually takes place. This function, then, initiates - that transaction to occur, and update the buffer in proper time. + update to the buffer actually takes place. This function, then, + initiates that transaction to occur, and update the buffer in proper time. """ - dummy = True # Update to initiate the dummy transaction properly + dummy = True # Update to initiate the dummy transaction properly on the i2c function if not pi.connected: exit() @@ -114,7 +116,7 @@ def dummy_transaction(): reset() - dummy = False # Return to normal, so proper testing is conducted + dummy = False # End dummy transaction, so proper testing is conducted on i2c function # END @@ -148,7 +150,7 @@ def test_i2c_master_rx_configuration(self): global pi global MESSAGE_CONFIRMATION - dummy_transaction() # Initiate the dummy transaction (updates buffer in proper time) + dummy_transaction() # Initiate the dummy transaction to update buffer in proper time print() logger.info('Sending Messages As Slave... ', @@ -159,7 +161,7 @@ def test_i2c_master_rx_configuration(self): if not pi.connected: exit() - press_button() # Used to press on of the user buttons on the board + press_button() # Used to press one of the user buttons on the board # Add pull-ups in case external pull-ups haven't been added (For Raspberry Pi) diff --git a/examples/ci-tests/i2c-master-tx/test.py b/examples/ci-tests/i2c-master-tx/test.py index f4893b380..d4a210a3e 100644 --- a/examples/ci-tests/i2c-master-tx/test.py +++ b/examples/ci-tests/i2c-master-tx/test.py @@ -115,7 +115,7 @@ def test_i2c_master_tx_configuration(self): if not pi.connected: exit() - press_button() # Used to press on of the user buttons on the board + press_button() # Used to press one of the user buttons on the board # Add pull-ups in case external pull-ups haven't been added (For Raspberry Pi) diff --git a/examples/ci-tests/i2c-slave-tx/test.py b/examples/ci-tests/i2c-slave-tx/test.py index 589192c7e..64cbe7e47 100644 --- a/examples/ci-tests/i2c-slave-tx/test.py +++ b/examples/ci-tests/i2c-slave-tx/test.py @@ -87,7 +87,7 @@ def test_i2c_slave_tx_configuration(self): received = False - press_button() + press_button() # Used to press one of the user buttons on the board try: dataM = bus.read_i2c_block_data(ADDRESS, MASTER, BUF_SIZE) @@ -155,7 +155,7 @@ def test_i2c_slave_tx_configuration(self): class Nrf52840Test(I2CSlaveTxTest): def setUp(self): - reset() + reset() # Used to activate the reset button on board logger.info('Setting up for nrf52840dk I2C Slave Tx test...', extra={'timegap': time_gap(TEST_START_TIME)}) From b57f9b2f64484ccc5f7e1752e1a93b10af93c748 Mon Sep 17 00:00:00 2001 From: AnthonyQ619 Date: Tue, 24 Aug 2021 10:44:02 -0700 Subject: [PATCH 33/49] Update reademe --- examples/ci-tests/i2c-master-rx/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ci-tests/i2c-master-rx/README.md b/examples/ci-tests/i2c-master-rx/README.md index 1aacaaab7..def9ac9af 100644 --- a/examples/ci-tests/i2c-master-rx/README.md +++ b/examples/ci-tests/i2c-master-rx/README.md @@ -21,4 +21,4 @@ This test requires the Raspberry Pi to be set as slave. Thus, you must use Broad This test requires button activation on tested boards. Two jumpers are required for the activation of the reset button and user button on boards. Broadcom Pins on Raspberry PI used are pins 20 & 21 (GPIO Pins 38 & 40) which are used for user button and reset respectively. -This test utilizes the pigpio open source library, but the function utilized, `bsc_i2c` , has a delay when updating the buffer. This delay, to be specific, takes a an i2c transaction to update between the board and the RPi. This is a limitation of the RPi slave configuration, not the board being tested i2c configuration. To combat this, we utilize a dummy transaction that runs a i2c transaction of sending messages for 4 seconds, then reopens a transaction (the transacton being tested) with the updated buffer properly timed. For more information, check the code `test.py` and the function `dummy_transaction`. +This test utilizes the pigpio open source library, but the function utilized, `bsc_i2c` , has a delay when updating the buffer. This delay, to be specific, is that it takes an i2c transaction between master and slave to update the buffer properly. This is a limitation of the RPi slave configuration, not the board being tested i2c configuration. To combat this, we utilize a dummy transaction that runs a i2c transaction of sending messages for 4 seconds, then reopens a transaction (the transacton being tested) with the updated buffer properly timed. For more information about this delay and what exactly is happening to handle it, check the code `test.py` and the function `dummy_transaction`. From 27e478210286077b91c2b8f154f11ac10f368f51 Mon Sep 17 00:00:00 2001 From: AnthonyQ619 Date: Tue, 24 Aug 2021 10:46:56 -0700 Subject: [PATCH 34/49] Update reademe --- examples/ci-tests/i2c-master-rx/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ci-tests/i2c-master-rx/README.md b/examples/ci-tests/i2c-master-rx/README.md index def9ac9af..f040937d3 100644 --- a/examples/ci-tests/i2c-master-rx/README.md +++ b/examples/ci-tests/i2c-master-rx/README.md @@ -21,4 +21,4 @@ This test requires the Raspberry Pi to be set as slave. Thus, you must use Broad This test requires button activation on tested boards. Two jumpers are required for the activation of the reset button and user button on boards. Broadcom Pins on Raspberry PI used are pins 20 & 21 (GPIO Pins 38 & 40) which are used for user button and reset respectively. -This test utilizes the pigpio open source library, but the function utilized, `bsc_i2c` , has a delay when updating the buffer. This delay, to be specific, is that it takes an i2c transaction between master and slave to update the buffer properly. This is a limitation of the RPi slave configuration, not the board being tested i2c configuration. To combat this, we utilize a dummy transaction that runs a i2c transaction of sending messages for 4 seconds, then reopens a transaction (the transacton being tested) with the updated buffer properly timed. For more information about this delay and what exactly is happening to handle it, check the code `test.py` and the function `dummy_transaction`. +This test utilizes the pigpio open source library, but the function utilized, `bsc_i2c` , has a delay when updating the slave buffer being sent to master. This delay, to be specific, is that it takes an i2c transaction between master and slave to update the slave buffer properly. This is a limitation of the RPi slave configuration, not the board being tested i2c configuration. To combat this, we utilize a dummy transaction that runs a i2c transaction of sending messages for 4 seconds to master from slave, then reopens a transaction (the transacton being tested) with the updated slave buffer properly timed. For more information about this delay and what exactly is happening to handle it, check the code `test.py` and the function `dummy_transaction`. From e2db0c59e151e94061730717e37bb05052d2344f Mon Sep 17 00:00:00 2001 From: AnthonyQ619 Date: Tue, 24 Aug 2021 12:11:05 -0700 Subject: [PATCH 35/49] Update Uart Rx/Tx --- examples/ci-tests/uartrt/main.c | 18 ------------------ examples/ci-tests/uartrt/test.py | 14 +++++++------- 2 files changed, 7 insertions(+), 25 deletions(-) diff --git a/examples/ci-tests/uartrt/main.c b/examples/ci-tests/uartrt/main.c index 077347a67..341620648 100644 --- a/examples/ci-tests/uartrt/main.c +++ b/examples/ci-tests/uartrt/main.c @@ -12,13 +12,6 @@ int main(void) { while (1) { int c = getch(); - /*if (c == RETURNCODE_FAIL) { - printf("\ngetch() failed!\n"); - } else { - printf("\n%c\n", (char) c); - }*/ - - //delay_ms(3000); char m = (char) c; char message[3]; @@ -31,10 +24,6 @@ int main(void) { delay_ms(1000); putnstr(message, (strlen(message))); - - //size_t len = 4; - //getnstr(echo_message, len); - //printf("%s", echo_message); delay_ms(3000); /*if(strcmp(echo_message, "") != 0){ @@ -44,11 +33,4 @@ int main(void) { delay_ms(2000); } - - /*while(true){ - // Send Acknowledgement - const char* ack = "true"; - putnstr(ack, (strlen(ack))); - } - return 0;*/ } diff --git a/examples/ci-tests/uartrt/test.py b/examples/ci-tests/uartrt/test.py index b2d4df281..86f3db51e 100644 --- a/examples/ci-tests/uartrt/test.py +++ b/examples/ci-tests/uartrt/test.py @@ -6,10 +6,10 @@ import struct TARGET_ACKNOWLEDGEMENT = "" -sp = None -#sp = serial.Serial(port="/dev/ttyACM0", baudrate=115200, bytesize=8, timeout=2) -#sp = serial.Serial(port="/dev/ttyUSB0", baudrate=115200, bytesize=8, timeout=2) +sp = None # Serial port for specific boards to read the echo of messages ser = serial.Serial(port="/dev/ttyS0", baudrate=115200, bytesize=8, parity="N", stopbits=1) + + print("Starting Uart Rx/TX Test...\n") ################################################################################ @@ -69,17 +69,17 @@ def test_uart_rx_tx(self): time.sleep(5) if(sp.in_waiting > 0): + logger.info('Message sent: ' + TARGET_ACKNOWLEDGEMENT, extra={'timegap': time_gap(TEST_START_TIME)}) - #time.sleep(5) sp.readline() if(sp.in_waiting > 0): + message_received = sp.readline() message_received = message_received.decode("Ascii") - #print("Message: " + message_received) char_received = message_received[-1] - #print("Echoed: " + char_received + "\n") if(char_received == TARGET_ACKNOWLEDGEMENT): + logger.info("Message Received (r[character]): " + message_received, extra={'timegap': time_gap(TEST_START_TIME)}) logger.info("Echoed: " + char_received, @@ -109,7 +109,7 @@ class HailTest(UartTest): def setUp(self): global sp - sp = serial.Serial(port="/dev/ttyUSB0", baudrate=115200, bytesize=8, parity="N", stopbits=1); + sp = serial.Serial(port="/dev/ttyUSB0", baudrate=115200, bytesize=8, parity="N", stopbits=1) logger.info('Setting up for hail Uart Rx/Tx test...', extra={'timegap': time_gap(TEST_START_TIME)}) From 646746e06c2a705851cffdc1c8748c9cc01b00a3 Mon Sep 17 00:00:00 2001 From: AnthonyQ619 Date: Tue, 24 Aug 2021 18:28:14 -0700 Subject: [PATCH 36/49] Update test.py comments --- examples/ci-tests/ble/test.py | 70 +++++++++++++++++++++---- examples/ci-tests/gpio/test.py | 12 +++++ examples/ci-tests/i2c-master-rx/test.py | 3 ++ examples/ci-tests/i2c-master-tx/test.py | 3 ++ examples/ci-tests/i2c-slave-rx/test.py | 3 ++ examples/ci-tests/i2c-slave-tx/test.py | 3 ++ 6 files changed, 83 insertions(+), 11 deletions(-) diff --git a/examples/ci-tests/ble/test.py b/examples/ci-tests/ble/test.py index 422977a15..dccbdfa0a 100644 --- a/examples/ci-tests/ble/test.py +++ b/examples/ci-tests/ble/test.py @@ -5,6 +5,9 @@ import time import unittest import os +import subprocess + +TARGET_NAME = 'TockOS' ################################################################################ # Helper classes and functions @@ -12,7 +15,6 @@ def time_gap(start_time): """Return time gap between current time and start_time - Argument: start_time - Start time """ @@ -56,16 +58,62 @@ def test_ble_advertise(self): print() # Line change os.system('sudo systemctl status hciuart') print() # Line change - os.system('sudo timeout 5 stdbuf -oL hcitool lescan') - print() # Line change - logger.info('BLE scan ended.', - extra={'timegap': time_gap(TEST_START_TIME)}) - - # Restart bluetooth - # Note: the scanning process is corrupted whenever we try to kill it, so - # for now, we resort to restarting bluetooth every test, but if - # there is a better implementation, feel free to change this. - os.system('sudo hciconfig hci0 down; sudo hciconfig hci0 up') + # os.system('sudo timeout 5 stdbuf -oL hcitool lescan') + # print() # Line change + scan_cmd = 'sudo timeout 5 stdbuf -oL hcitool lescan' + + # BLE scan flag + found = False + + try: + scan_result = subprocess.check_output(scan_cmd, + stderr=subprocess.STDOUT, + shell=True) + scan_result_str = scan_result.decode('ascii') + logger.info('Scan result:\n' + scan_result_str, + extra={'timegap': time_gap(TEST_START_TIME)}) + + # Search for target board name + scan_entries = scan_result_str.split('\n') + print(scan_entries) + + for entry in scan_entries: + mac_addr, name = entry.split(' ') + print(name) + + if name == TARGET_NAME: + found = True + + except subprocess.CalledProcessError as err: + # Print error + scan_result_str = err.output.decode('ascii') + + logger.info('Scan result error:\n' + scan_result_str, + extra={'timegap': time_gap(TEST_START_TIME)}) + + # Search for target board name + scan_entries = scan_result_str.split('\n') + + for entry in scan_entries: + if entry != '': + mac_addr, name = entry.split(' ', 1) + + if name == TARGET_NAME: + found = True + + finally: + logger.info('BLE scan ended.', + extra={'timegap': time_gap(TEST_START_TIME)}) + + # Restart bluetooth + # Note: the scanning process is corrupted whenever we try to kill it, so + # for now, we resort to restarting bluetooth every test, but if + # there is a better implementation, feel free to change this. + logger.info('Restarting test harness bluetooth.', + extra={'timegap': time_gap(TEST_START_TIME)}) + os.system('sudo hciconfig hci0 down; sudo hciconfig hci0 up') + + self.assertTrue(found) # END diff --git a/examples/ci-tests/gpio/test.py b/examples/ci-tests/gpio/test.py index dc439c8db..f54d877f2 100644 --- a/examples/ci-tests/gpio/test.py +++ b/examples/ci-tests/gpio/test.py @@ -174,6 +174,18 @@ def setUp(self): self.P3 = Pin(19) self.P4 = Pin(26) +class HailTest(GpioTest): + def setUp(self): + logger.info('Setting up for Hail GPIO test...', + extra={'timegap': time_gap(TEST_START_TIME)}) + + # Assign input pins + self.P0 = Pin(5) + self.P1 = Pin(6) + self.P2 = Pin(13) + self.P3 = Pin(19) + + # END ################################################################################ diff --git a/examples/ci-tests/i2c-master-rx/test.py b/examples/ci-tests/i2c-master-rx/test.py index b8fa531cf..a72e31448 100644 --- a/examples/ci-tests/i2c-master-rx/test.py +++ b/examples/ci-tests/i2c-master-rx/test.py @@ -1,3 +1,6 @@ +# I2C Master Rx Test +# This tester corresponds to libtock-c/examples/ci-tests/i2c-master-rx test. + import time import logging import unittest diff --git a/examples/ci-tests/i2c-master-tx/test.py b/examples/ci-tests/i2c-master-tx/test.py index d4a210a3e..d8f556566 100644 --- a/examples/ci-tests/i2c-master-tx/test.py +++ b/examples/ci-tests/i2c-master-tx/test.py @@ -1,3 +1,6 @@ +# I2C Master Tx Test +# This tester corresponds to libtock-c/examples/ci-tests/i2c-master-tx test. + import time import logging import unittest diff --git a/examples/ci-tests/i2c-slave-rx/test.py b/examples/ci-tests/i2c-slave-rx/test.py index 3ce70ce8d..86f4a0b2d 100644 --- a/examples/ci-tests/i2c-slave-rx/test.py +++ b/examples/ci-tests/i2c-slave-rx/test.py @@ -1,3 +1,6 @@ +# I2C Slave Rx Test +# This tester corresponds to libtock-c/examples/ci-tests/i2c-slave-rx test. + from smbus import SMBus import time import logging diff --git a/examples/ci-tests/i2c-slave-tx/test.py b/examples/ci-tests/i2c-slave-tx/test.py index 64cbe7e47..70964eda4 100644 --- a/examples/ci-tests/i2c-slave-tx/test.py +++ b/examples/ci-tests/i2c-slave-tx/test.py @@ -1,3 +1,6 @@ +# I2C Slave Tx Test +# This tester corresponds to libtock-c/examples/ci-tests/i2c-slave-tx test. + from smbus import SMBus import time import os From f941ab1a6b32dc3a1845f716ae36f4940b2113cd Mon Sep 17 00:00:00 2001 From: AnthonyQ619 Date: Mon, 29 Nov 2021 07:39:38 +0000 Subject: [PATCH 37/49] updates --- examples/ci-tests/ble/test.py | 5 +++ examples/ci-tests/i2c-master-rx/test.py | 29 +++++++------- examples/ci-tests/i2c-master-tx/test.py | 28 ++++++------- examples/ci-tests/i2c-slave-rx/test.py | 50 ++++++++++++++++++++++-- examples/ci-tests/i2c-slave-tx/test.py | 34 +++++++++------- examples/ci-tests/uart/test.py | 2 +- simple-ble/build/cortex-m0/simple-ble.a | Bin 16274 -> 17394 bytes simple-ble/build/cortex-m3/simple-ble.a | Bin 16026 -> 17026 bytes simple-ble/build/cortex-m4/simple-ble.a | Bin 16030 -> 17026 bytes simple-ble/build/cortex-m7/simple-ble.a | Bin 17538 -> 17026 bytes 10 files changed, 99 insertions(+), 49 deletions(-) diff --git a/examples/ci-tests/ble/test.py b/examples/ci-tests/ble/test.py index dccbdfa0a..cdc3768aa 100644 --- a/examples/ci-tests/ble/test.py +++ b/examples/ci-tests/ble/test.py @@ -126,6 +126,11 @@ def setUp(self): logger.info('Setting up for nrf52840dk BLE test...', extra={'timegap': time_gap(TEST_START_TIME)}) +class HailTest(BleTest): + def setUp(self): + logger.info('Setting up for nrf52840dk BLE test...', + extra={'timegap': time_gap(TEST_START_TIME)}) + # END ################################################################################ diff --git a/examples/ci-tests/i2c-master-rx/test.py b/examples/ci-tests/i2c-master-rx/test.py index a72e31448..0230f80c7 100644 --- a/examples/ci-tests/i2c-master-rx/test.py +++ b/examples/ci-tests/i2c-master-rx/test.py @@ -4,7 +4,8 @@ import time import logging import unittest -import RPi.GPIO as GPIO +from gpiozero import InputDevice +from gpiozero import OutputDevice import os MESSAGE_SENT = "Hello I'm Slave" # Message Master sends to slave @@ -20,10 +21,8 @@ I2C_ADDR = 0x41 # Raspberry Pi Address -GPIO.setwarnings(False) -GPIO.setmode(GPIO.BCM) -GPIO.setup(RESET, GPIO.OUT) # RESET pin set as output -GPIO.setup(BUTTON_1, GPIO.OUT) # BUTTON_1 pin set as output +button = OutputDevice(BUTTON_1) +reset_button = OutputDevice(RESET) # Set up PiGPIO properly by configuring it on pi then importing library os.system('sudo pigpiod') @@ -49,17 +48,19 @@ def reset(): global RESET """Button is Reset""" - GPIO.output(RESET, GPIO.LOW) - time.sleep(1) - GPIO.output(RESET, GPIO.HIGH) + reset_button.off() + time.sleep(1.1) + reset_button.on() + time.sleep(0.5) def press_button(): global BUTTON_1 """Button is one of User Buttons""" - GPIO.output(BUTTON_1, GPIO.HIGH) - time.sleep(1) - GPIO.output(BUTTON_1, GPIO.LOW) + button.on() + time.sleep(1.1) + button.off() + time.sleep(0.5) def i2c(id, tick): global pi @@ -164,6 +165,8 @@ def test_i2c_master_rx_configuration(self): if not pi.connected: exit() + time.sleep(2) # Wait until app has fully reset + press_button() # Used to press one of the user buttons on the board # Add pull-ups in case external pull-ups haven't been added (For Raspberry Pi) @@ -202,8 +205,6 @@ def test_i2c_master_rx_configuration(self): reset() # Reset application to stop sending messages - GPIO.cleanup() - time.sleep(1) logger.info('Connection Satisfied.', @@ -233,8 +234,6 @@ def test_i2c_master_rx_configuration(self): reset() # Reset application to stop sending messages - GPIO.cleanup() - time.sleep(1) logger.info('Connection was not Satisfied. Wrong/No message was sent.', diff --git a/examples/ci-tests/i2c-master-tx/test.py b/examples/ci-tests/i2c-master-tx/test.py index d8f556566..bdb7a3d8a 100644 --- a/examples/ci-tests/i2c-master-tx/test.py +++ b/examples/ci-tests/i2c-master-tx/test.py @@ -6,6 +6,8 @@ import unittest import RPi.GPIO as GPIO import os +from gpiozero import InputDevice +from gpiozero import OutputDevice MESSAGE = 'Hello friend.' # Message Master sends to slave MESSAGE_RECEIVED = '' @@ -18,10 +20,8 @@ I2C_ADDR = 0x41 # Raspberry Pi Address -GPIO.setwarnings(False) -GPIO.setmode(GPIO.BCM) -GPIO.setup(RESET, GPIO.OUT) # RESET pin set as output -GPIO.setup(BUTTON_1, GPIO.OUT) # BUTTON_1 pin set as output +button = OutputDevice(BUTTON_1) +reset_button = OutputDevice(RESET) # Set up PiGPIO properly by configuring it on pi then importing library os.system('sudo pigpiod') @@ -46,17 +46,19 @@ def reset(): global RESET """Button is Reset""" - GPIO.output(RESET, GPIO.LOW) - time.sleep(1) - GPIO.output(RESET, GPIO.HIGH) + reset_button.off() + time.sleep(1.1) + reset_button.on() + time.sleep(0.5) def press_button(): global BUTTON_1 """Button is one of User Buttons""" - GPIO.output(BUTTON_1, GPIO.HIGH) - time.sleep(1) - GPIO.output(BUTTON_1, GPIO.LOW) + button.on() + time.sleep(1.1) + button.off() + time.sleep(0.5) def i2c(id, tick): global pi @@ -118,6 +120,8 @@ def test_i2c_master_tx_configuration(self): if not pi.connected: exit() + time.sleep(2) # Wait until app has fully reset + press_button() # Used to press one of the user buttons on the board # Add pull-ups in case external pull-ups haven't been added (For Raspberry Pi) @@ -156,8 +160,6 @@ def test_i2c_master_tx_configuration(self): reset() # Reset application to stop sending messages - GPIO.cleanup() - time.sleep(1) logger.info('Connection Satisfied.', @@ -185,8 +187,6 @@ def test_i2c_master_tx_configuration(self): reset() # Reset application to stop sending messages - GPIO.cleanup() - time.sleep(1) logger.info('Connection was not Satisfied. Wrong/No message received.', diff --git a/examples/ci-tests/i2c-slave-rx/test.py b/examples/ci-tests/i2c-slave-rx/test.py index 86f4a0b2d..ee81aa2b4 100644 --- a/examples/ci-tests/i2c-slave-rx/test.py +++ b/examples/ci-tests/i2c-slave-rx/test.py @@ -5,12 +5,22 @@ import time import logging import unittest +from gpiozero import InputDevice +from gpiozero import OutputDevice ADDRESS = 0x41 # bus address to the Slave Device MASTER = 0x40 # Raspberry Pi Master Address +SDA = 10 # Broadcom pin 10 (P1 pin 19) +SCL = 11 # Broadcom pin 11 (P1 pin 23) MESSAGE = "Hello I'm Master" # Message to send to slave bus = SMBus(1) # indicates /dev/ic2-1 +pin_1 = InputDevice(10) +pin_2 = InputDevice(11) + +RESET = 21 # Broadcom pin 21 (P1 pin 40) + +reset_button = OutputDevice(RESET) ################################################################################ # Helper Functions @@ -23,6 +33,15 @@ def time_gap(start_time): """ return "{:.6f}".format(time.time() - start_time) +def reset(): + global RESET + """Button is Reset""" + + reset_button.off() + time.sleep(1.1) + reset_button.on() + time.sleep(0.5) + def message_converter(message): """Return list of ascii values for each character in message Argument: @@ -64,7 +83,9 @@ def message_converter(message): class I2CSlaveRxTest(unittest.TestCase): def test_i2c_slave_rx_configuration(self): - +# gpio_reset() # Reset gpio output of pins +# pi_daemon_reset() + print() logger.info('Sending I2C Message: ' + MESSAGE, extra={'timegap': time_gap(TEST_START_TIME)}) @@ -81,7 +102,7 @@ def test_i2c_slave_rx_configuration(self): extra={'timegap': time_gap(TEST_START_TIME)}) time.sleep(1) received = True - except OSError: + except OSError as err: print("OS error: {0}".format(err)) logger.info('Test failed...', @@ -89,15 +110,32 @@ def test_i2c_slave_rx_configuration(self): print() time.sleep(1) - except TimeoutError: + + reset() + + received = False + + self.assertTrue(received) + + except TimeoutError as err: + print("TimeOut error: {0}".format(err)) + logger.info('Connection is poor: Time out error...\n', extra={'timegap': time_gap(TEST_START_TIME)}) logger.info('Test failed...', extra={'timegap': time_gap(TEST_START_TIME)}) + print() time.sleep(1) + + reset() + + received = False + + self.assertTrue(received) + finally: logger.info('I2C Communication Ended...', extra={'timegap': time_gap(TEST_START_TIME)}) @@ -116,7 +154,9 @@ def test_i2c_slave_rx_configuration(self): logger.info('I2C Slave Rx Test has ended.', extra={'timegap': time_gap(TEST_START_TIME)}) - + + reset() + self.assertTrue(received) # END @@ -126,6 +166,8 @@ def test_i2c_slave_rx_configuration(self): class Nrf52840Test(I2CSlaveRxTest): def setUp(self): + reset() + logger.info('Setting up for nrf52840dk I2C Slave Rx test...', extra={'timegap': time_gap(TEST_START_TIME)}) diff --git a/examples/ci-tests/i2c-slave-tx/test.py b/examples/ci-tests/i2c-slave-tx/test.py index 70964eda4..80d123cbf 100644 --- a/examples/ci-tests/i2c-slave-tx/test.py +++ b/examples/ci-tests/i2c-slave-tx/test.py @@ -6,15 +6,14 @@ import os import logging import unittest -import RPi.GPIO as GPIO +from gpiozero import InputDevice +from gpiozero import OutputDevice RESET = 21 # Broadcom pin 21 (P1 pin 40) BUTTON_1 = 20 # Broadcom pin 20 (P1 pin 38) -GPIO.setwarnings(False) -GPIO.setmode(GPIO.BCM) -GPIO.setup(RESET, GPIO.OUT) # RESET pin set as output -GPIO.setup(BUTTON_1, GPIO.OUT) # BUTTON_1 pin set as output +button = OutputDevice(BUTTON_1) +reset_button = OutputDevice(RESET) ADDRESS = 0x41 # bus address to the Slave Device MASTER = 0x40 # Raspberry Pi Master Address @@ -22,6 +21,10 @@ BUF_SIZE = 16 bus = SMBus(1) # indicates /dev/ic2-1 +# cancelling slave configuration pins +pin_1 = InputDevice(10) +pin_2 = InputDevice(11) + ################################################################################ # Helper Functions ################################################################################ @@ -37,17 +40,19 @@ def reset(): global RESET """Button is Reset""" - GPIO.output(RESET, GPIO.LOW) - time.sleep(1) - GPIO.output(RESET, GPIO.HIGH) + reset_button.off() + time.sleep(1.1) + reset_button.on() + time.sleep(0.5) def press_button(): global BUTTON_1 """Button is one of User Buttons""" - GPIO.output(BUTTON_1, GPIO.HIGH) - time.sleep(1) - GPIO.output(BUTTON_1, GPIO.LOW) + button.on() + time.sleep(1.1) + button.off() + time.sleep(0.5) def message_decoder(data): string = '' @@ -90,6 +95,8 @@ def test_i2c_slave_tx_configuration(self): received = False + time.sleep(2) # Wait until app has fully reset + press_button() # Used to press one of the user buttons on the board try: @@ -116,7 +123,7 @@ def test_i2c_slave_tx_configuration(self): received = True - except OSError: + except OSError as err: print("OS error: {0}".format(err)) logger.info('Test failed...', @@ -139,9 +146,6 @@ def test_i2c_slave_tx_configuration(self): reset() # Reset application to stop sending messages - # Close Setup - GPIO.cleanup() - bus.close() time.sleep(1) diff --git a/examples/ci-tests/uart/test.py b/examples/ci-tests/uart/test.py index 3378574c8..0594f374d 100644 --- a/examples/ci-tests/uart/test.py +++ b/examples/ci-tests/uart/test.py @@ -4,7 +4,7 @@ TARGET_RECEIVED_MESSAGE = "cse145 is cool" TARGET_ACKNOWLEDGEMENT = "true" -sp = serial.Serial(port="/dev/ttyACM0", baudrate=115200, bytesize=8, timeout=2) +sp = serial.Serial(port="/dev/ttyUSB0", baudrate=115200, bytesize=8, timeout=2) print("Starting Uart Test...") while(True): # print("B") diff --git a/simple-ble/build/cortex-m0/simple-ble.a b/simple-ble/build/cortex-m0/simple-ble.a index f2ea512ae3ea2a053ec0a53dedf76fb335e95769..9ff08cb60f2d3c1e8488c49d5e110ade0815fb92 100644 GIT binary patch literal 17394 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 literal 16274 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 diff --git a/simple-ble/build/cortex-m3/simple-ble.a b/simple-ble/build/cortex-m3/simple-ble.a index c98476bd3423ed49ce269df767fec988c3aea1c9..e68e791cae0343fc95345dbbc30bb2f2c12535e5 100644 GIT binary patch literal 17026 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 H=Vt#G1kUiY diff --git a/simple-ble/build/cortex-m4/simple-ble.a b/simple-ble/build/cortex-m4/simple-ble.a index 4928227b9e8d6a3f90983a7abcdc272149126d6c..6eb90d73556223621fa552071fe0e1e4c05dbc80 100644 GIT binary patch literal 17026 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 N0{=ei7NX3({BJJ>Q$GLz literal 16030 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 G+5ZI|`|^tb diff --git a/simple-ble/build/cortex-m7/simple-ble.a b/simple-ble/build/cortex-m7/simple-ble.a index 0e299ce0bfd86e6325eb1f2521e5c134ec1ea5d8..2a41bcdb8031fd300874b749e6692dda8338aac6 100644 GIT binary patch delta 6378 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 delta 6906 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 From b71afd501d1cce96cb9833ec862c6bf6b96b2ee4 Mon Sep 17 00:00:00 2001 From: AnthonyQ619 <68413443+AnthonyQ619@users.noreply.github.com> Date: Sun, 28 Nov 2021 23:45:16 -0800 Subject: [PATCH 38/49] Update test.py --- examples/ci-tests/i2c-slave-rx/test.py | 50 +++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/examples/ci-tests/i2c-slave-rx/test.py b/examples/ci-tests/i2c-slave-rx/test.py index 86f4a0b2d..ee81aa2b4 100644 --- a/examples/ci-tests/i2c-slave-rx/test.py +++ b/examples/ci-tests/i2c-slave-rx/test.py @@ -5,12 +5,22 @@ import time import logging import unittest +from gpiozero import InputDevice +from gpiozero import OutputDevice ADDRESS = 0x41 # bus address to the Slave Device MASTER = 0x40 # Raspberry Pi Master Address +SDA = 10 # Broadcom pin 10 (P1 pin 19) +SCL = 11 # Broadcom pin 11 (P1 pin 23) MESSAGE = "Hello I'm Master" # Message to send to slave bus = SMBus(1) # indicates /dev/ic2-1 +pin_1 = InputDevice(10) +pin_2 = InputDevice(11) + +RESET = 21 # Broadcom pin 21 (P1 pin 40) + +reset_button = OutputDevice(RESET) ################################################################################ # Helper Functions @@ -23,6 +33,15 @@ def time_gap(start_time): """ return "{:.6f}".format(time.time() - start_time) +def reset(): + global RESET + """Button is Reset""" + + reset_button.off() + time.sleep(1.1) + reset_button.on() + time.sleep(0.5) + def message_converter(message): """Return list of ascii values for each character in message Argument: @@ -64,7 +83,9 @@ def message_converter(message): class I2CSlaveRxTest(unittest.TestCase): def test_i2c_slave_rx_configuration(self): - +# gpio_reset() # Reset gpio output of pins +# pi_daemon_reset() + print() logger.info('Sending I2C Message: ' + MESSAGE, extra={'timegap': time_gap(TEST_START_TIME)}) @@ -81,7 +102,7 @@ def test_i2c_slave_rx_configuration(self): extra={'timegap': time_gap(TEST_START_TIME)}) time.sleep(1) received = True - except OSError: + except OSError as err: print("OS error: {0}".format(err)) logger.info('Test failed...', @@ -89,15 +110,32 @@ def test_i2c_slave_rx_configuration(self): print() time.sleep(1) - except TimeoutError: + + reset() + + received = False + + self.assertTrue(received) + + except TimeoutError as err: + print("TimeOut error: {0}".format(err)) + logger.info('Connection is poor: Time out error...\n', extra={'timegap': time_gap(TEST_START_TIME)}) logger.info('Test failed...', extra={'timegap': time_gap(TEST_START_TIME)}) + print() time.sleep(1) + + reset() + + received = False + + self.assertTrue(received) + finally: logger.info('I2C Communication Ended...', extra={'timegap': time_gap(TEST_START_TIME)}) @@ -116,7 +154,9 @@ def test_i2c_slave_rx_configuration(self): logger.info('I2C Slave Rx Test has ended.', extra={'timegap': time_gap(TEST_START_TIME)}) - + + reset() + self.assertTrue(received) # END @@ -126,6 +166,8 @@ def test_i2c_slave_rx_configuration(self): class Nrf52840Test(I2CSlaveRxTest): def setUp(self): + reset() + logger.info('Setting up for nrf52840dk I2C Slave Rx test...', extra={'timegap': time_gap(TEST_START_TIME)}) From 3f97e526280ae096cfab38bf44f0326684e9b963 Mon Sep 17 00:00:00 2001 From: AnthonyQ619 <68413443+AnthonyQ619@users.noreply.github.com> Date: Sun, 28 Nov 2021 23:46:55 -0800 Subject: [PATCH 39/49] Update test.py --- examples/ci-tests/i2c-slave-tx/test.py | 34 ++++++++++++++------------ 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/examples/ci-tests/i2c-slave-tx/test.py b/examples/ci-tests/i2c-slave-tx/test.py index 70964eda4..80d123cbf 100644 --- a/examples/ci-tests/i2c-slave-tx/test.py +++ b/examples/ci-tests/i2c-slave-tx/test.py @@ -6,15 +6,14 @@ import os import logging import unittest -import RPi.GPIO as GPIO +from gpiozero import InputDevice +from gpiozero import OutputDevice RESET = 21 # Broadcom pin 21 (P1 pin 40) BUTTON_1 = 20 # Broadcom pin 20 (P1 pin 38) -GPIO.setwarnings(False) -GPIO.setmode(GPIO.BCM) -GPIO.setup(RESET, GPIO.OUT) # RESET pin set as output -GPIO.setup(BUTTON_1, GPIO.OUT) # BUTTON_1 pin set as output +button = OutputDevice(BUTTON_1) +reset_button = OutputDevice(RESET) ADDRESS = 0x41 # bus address to the Slave Device MASTER = 0x40 # Raspberry Pi Master Address @@ -22,6 +21,10 @@ BUF_SIZE = 16 bus = SMBus(1) # indicates /dev/ic2-1 +# cancelling slave configuration pins +pin_1 = InputDevice(10) +pin_2 = InputDevice(11) + ################################################################################ # Helper Functions ################################################################################ @@ -37,17 +40,19 @@ def reset(): global RESET """Button is Reset""" - GPIO.output(RESET, GPIO.LOW) - time.sleep(1) - GPIO.output(RESET, GPIO.HIGH) + reset_button.off() + time.sleep(1.1) + reset_button.on() + time.sleep(0.5) def press_button(): global BUTTON_1 """Button is one of User Buttons""" - GPIO.output(BUTTON_1, GPIO.HIGH) - time.sleep(1) - GPIO.output(BUTTON_1, GPIO.LOW) + button.on() + time.sleep(1.1) + button.off() + time.sleep(0.5) def message_decoder(data): string = '' @@ -90,6 +95,8 @@ def test_i2c_slave_tx_configuration(self): received = False + time.sleep(2) # Wait until app has fully reset + press_button() # Used to press one of the user buttons on the board try: @@ -116,7 +123,7 @@ def test_i2c_slave_tx_configuration(self): received = True - except OSError: + except OSError as err: print("OS error: {0}".format(err)) logger.info('Test failed...', @@ -139,9 +146,6 @@ def test_i2c_slave_tx_configuration(self): reset() # Reset application to stop sending messages - # Close Setup - GPIO.cleanup() - bus.close() time.sleep(1) From 46289696e7c2b19d41e809f2ca27fe1a021841aa Mon Sep 17 00:00:00 2001 From: AnthonyQ619 <68413443+AnthonyQ619@users.noreply.github.com> Date: Sun, 28 Nov 2021 23:53:16 -0800 Subject: [PATCH 40/49] Update test.py --- examples/ci-tests/i2c-master-tx/test.py | 28 ++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/examples/ci-tests/i2c-master-tx/test.py b/examples/ci-tests/i2c-master-tx/test.py index d8f556566..bdb7a3d8a 100644 --- a/examples/ci-tests/i2c-master-tx/test.py +++ b/examples/ci-tests/i2c-master-tx/test.py @@ -6,6 +6,8 @@ import unittest import RPi.GPIO as GPIO import os +from gpiozero import InputDevice +from gpiozero import OutputDevice MESSAGE = 'Hello friend.' # Message Master sends to slave MESSAGE_RECEIVED = '' @@ -18,10 +20,8 @@ I2C_ADDR = 0x41 # Raspberry Pi Address -GPIO.setwarnings(False) -GPIO.setmode(GPIO.BCM) -GPIO.setup(RESET, GPIO.OUT) # RESET pin set as output -GPIO.setup(BUTTON_1, GPIO.OUT) # BUTTON_1 pin set as output +button = OutputDevice(BUTTON_1) +reset_button = OutputDevice(RESET) # Set up PiGPIO properly by configuring it on pi then importing library os.system('sudo pigpiod') @@ -46,17 +46,19 @@ def reset(): global RESET """Button is Reset""" - GPIO.output(RESET, GPIO.LOW) - time.sleep(1) - GPIO.output(RESET, GPIO.HIGH) + reset_button.off() + time.sleep(1.1) + reset_button.on() + time.sleep(0.5) def press_button(): global BUTTON_1 """Button is one of User Buttons""" - GPIO.output(BUTTON_1, GPIO.HIGH) - time.sleep(1) - GPIO.output(BUTTON_1, GPIO.LOW) + button.on() + time.sleep(1.1) + button.off() + time.sleep(0.5) def i2c(id, tick): global pi @@ -118,6 +120,8 @@ def test_i2c_master_tx_configuration(self): if not pi.connected: exit() + time.sleep(2) # Wait until app has fully reset + press_button() # Used to press one of the user buttons on the board # Add pull-ups in case external pull-ups haven't been added (For Raspberry Pi) @@ -156,8 +160,6 @@ def test_i2c_master_tx_configuration(self): reset() # Reset application to stop sending messages - GPIO.cleanup() - time.sleep(1) logger.info('Connection Satisfied.', @@ -185,8 +187,6 @@ def test_i2c_master_tx_configuration(self): reset() # Reset application to stop sending messages - GPIO.cleanup() - time.sleep(1) logger.info('Connection was not Satisfied. Wrong/No message received.', From 72a4e14dc644a60396c304f1e73b27cf348c0497 Mon Sep 17 00:00:00 2001 From: AnthonyQ619 <68413443+AnthonyQ619@users.noreply.github.com> Date: Sun, 28 Nov 2021 23:54:58 -0800 Subject: [PATCH 41/49] Update test.py --- examples/ci-tests/i2c-master-rx/test.py | 29 ++++++++++++------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/examples/ci-tests/i2c-master-rx/test.py b/examples/ci-tests/i2c-master-rx/test.py index a72e31448..0230f80c7 100644 --- a/examples/ci-tests/i2c-master-rx/test.py +++ b/examples/ci-tests/i2c-master-rx/test.py @@ -4,7 +4,8 @@ import time import logging import unittest -import RPi.GPIO as GPIO +from gpiozero import InputDevice +from gpiozero import OutputDevice import os MESSAGE_SENT = "Hello I'm Slave" # Message Master sends to slave @@ -20,10 +21,8 @@ I2C_ADDR = 0x41 # Raspberry Pi Address -GPIO.setwarnings(False) -GPIO.setmode(GPIO.BCM) -GPIO.setup(RESET, GPIO.OUT) # RESET pin set as output -GPIO.setup(BUTTON_1, GPIO.OUT) # BUTTON_1 pin set as output +button = OutputDevice(BUTTON_1) +reset_button = OutputDevice(RESET) # Set up PiGPIO properly by configuring it on pi then importing library os.system('sudo pigpiod') @@ -49,17 +48,19 @@ def reset(): global RESET """Button is Reset""" - GPIO.output(RESET, GPIO.LOW) - time.sleep(1) - GPIO.output(RESET, GPIO.HIGH) + reset_button.off() + time.sleep(1.1) + reset_button.on() + time.sleep(0.5) def press_button(): global BUTTON_1 """Button is one of User Buttons""" - GPIO.output(BUTTON_1, GPIO.HIGH) - time.sleep(1) - GPIO.output(BUTTON_1, GPIO.LOW) + button.on() + time.sleep(1.1) + button.off() + time.sleep(0.5) def i2c(id, tick): global pi @@ -164,6 +165,8 @@ def test_i2c_master_rx_configuration(self): if not pi.connected: exit() + time.sleep(2) # Wait until app has fully reset + press_button() # Used to press one of the user buttons on the board # Add pull-ups in case external pull-ups haven't been added (For Raspberry Pi) @@ -202,8 +205,6 @@ def test_i2c_master_rx_configuration(self): reset() # Reset application to stop sending messages - GPIO.cleanup() - time.sleep(1) logger.info('Connection Satisfied.', @@ -233,8 +234,6 @@ def test_i2c_master_rx_configuration(self): reset() # Reset application to stop sending messages - GPIO.cleanup() - time.sleep(1) logger.info('Connection was not Satisfied. Wrong/No message was sent.', From 100535de624de89988e5a37d7ece09dc174c70cb Mon Sep 17 00:00:00 2001 From: AnthonyQ619 Date: Fri, 21 Jan 2022 09:10:29 +0000 Subject: [PATCH 42/49] Updating I2C master tests --- examples/ci-tests/i2c-master-rx/test.py | 74 ++++++++++++------------- examples/ci-tests/i2c-master-tx/test.py | 53 ++++++++++-------- 2 files changed, 63 insertions(+), 64 deletions(-) diff --git a/examples/ci-tests/i2c-master-rx/test.py b/examples/ci-tests/i2c-master-rx/test.py index 0230f80c7..0e26d507c 100644 --- a/examples/ci-tests/i2c-master-rx/test.py +++ b/examples/ci-tests/i2c-master-rx/test.py @@ -44,23 +44,21 @@ def time_gap(start_time): """ return "{:.6f}".format(time.time() - start_time) -def reset(): - global RESET - """Button is Reset""" - - reset_button.off() - time.sleep(1.1) - reset_button.on() - time.sleep(0.5) - def press_button(): global BUTTON_1 """Button is one of User Buttons""" button.on() - time.sleep(1.1) + time.sleep(1.5) button.off() - time.sleep(0.5) + +def reset(): + global RESET + + reset_button.on() + time.sleep(1.1) + reset_button.off() + reset_button.toggle() # Set Pin to tri-state def i2c(id, tick): global pi @@ -72,7 +70,7 @@ def i2c(id, tick): s, b, d = pi.bsc_i2c(I2C_ADDR, b"\nHello I'm Slave\n") # Check if dummy transaction is occuring, if not, test has started. - if not dummy: + if dummy: if b: if(FIRST_RX < 1): MESSAGE_CONFIRMATION = d.decode() @@ -82,7 +80,6 @@ def i2c(id, tick): logger.info('Messsage Call Back From Master: ' + array, extra={'timegap': time_gap(TEST_START_TIME)}) - def dummy_transaction(): global pi global I2C_ADDR @@ -95,8 +92,6 @@ def dummy_transaction(): initiates that transaction to occur, and update the buffer in proper time. """ - dummy = True # Update to initiate the dummy transaction properly on the i2c function - if not pi.connected: exit() @@ -114,15 +109,18 @@ def dummy_transaction(): time.sleep(4) - e.cancel() + # Reset Operation + time.sleep(1) + reset() + time.sleep(1) - pi.bsc_i2c(0) - reset() +def close(): + time.sleep(5) - dummy = False # End dummy transaction, so proper testing is conducted on i2c function + pi.stop() + os.system('sudo killall pigpiod') -# END ################################################################################ # Start test and logger @@ -153,8 +151,10 @@ def test_i2c_master_rx_configuration(self): """ Set up for Raspberry Pi configuration """ global pi global MESSAGE_CONFIRMATION + global dummy dummy_transaction() # Initiate the dummy transaction to update buffer in proper time + dummy = True # Update to initiate the dummy transaction properly on the i2c function print() logger.info('Sending Messages As Slave... ', @@ -184,24 +184,20 @@ def test_i2c_master_rx_configuration(self): extra={'timegap': time_gap(TEST_START_TIME)}) time.sleep(12) # Time to wait for messages to be sent (Should see four messages logged) - + MESSAGE_CONFIRMATION = str(MESSAGE_CONFIRMATION) MESSAGE_CONFIRMATION = MESSAGE_CONFIRMATION.strip() - logger.info('Message Sent: ' + MESSAGE_SENT, - extra={'timegap': time_gap(TEST_START_TIME)}) - - logger.info('Message Called Back from Master: ' + MESSAGE_CONFIRMATION, - extra={'timegap': time_gap(TEST_START_TIME)}) - if (MESSAGE_CONFIRMATION == MESSAGE_SENT): # Close setup - e.cancel() + close() - pi.bsc_i2c(0) # Disable BSC peripheral + logger.info('Message Sent: ' + MESSAGE_SENT, + extra={'timegap': time_gap(TEST_START_TIME)}) - pi.stop() + logger.info('Message Called Back from Master: ' + MESSAGE_CONFIRMATION, + extra={'timegap': time_gap(TEST_START_TIME)}) reset() # Reset application to stop sending messages @@ -217,20 +213,19 @@ def test_i2c_master_rx_configuration(self): logger.info('I2C Master Rx Test has ended.', extra={'timegap': time_gap(TEST_START_TIME)}) - os.system('sudo killall pigpiod') - time.sleep(1) - self.assertTrue(received) else: - #Close setup + # Close setup - e.cancel() + close() - pi.bsc_i2c(0) # Disable BSC peripheral + logger.info('Message Sent: ' + MESSAGE_SENT, + extra={'timegap': time_gap(TEST_START_TIME)}) - pi.stop() + logger.info('Message Called Back from Master: ' + MESSAGE_CONFIRMATION, + extra={'timegap': time_gap(TEST_START_TIME)}) reset() # Reset application to stop sending messages @@ -244,9 +239,6 @@ def test_i2c_master_rx_configuration(self): logger.info('I2C Master Rx Test has ended.', extra={'timegap': time_gap(TEST_START_TIME)}) - os.system('sudo killall pigpiod') - time.sleep(1) - self.assertTrue(received) @@ -259,7 +251,9 @@ def test_i2c_master_rx_configuration(self): class Nrf52840Test(I2CMasterRxTest): def setUp(self): + time.sleep(1) reset() # Used to activate the reset button on board + time.sleep(1) logger.info('Setting up for nrf52840dk I2C Master Rx test...', extra={'timegap': time_gap(TEST_START_TIME)}) diff --git a/examples/ci-tests/i2c-master-tx/test.py b/examples/ci-tests/i2c-master-tx/test.py index bdb7a3d8a..9af4c9ca7 100644 --- a/examples/ci-tests/i2c-master-tx/test.py +++ b/examples/ci-tests/i2c-master-tx/test.py @@ -42,23 +42,22 @@ def time_gap(start_time): """ return "{:.6f}".format(time.time() - start_time) -def reset(): - global RESET - """Button is Reset""" - - reset_button.off() - time.sleep(1.1) - reset_button.on() - time.sleep(0.5) - def press_button(): global BUTTON_1 """Button is one of User Buttons""" button.on() - time.sleep(1.1) + time.sleep(1.5) button.off() - time.sleep(0.5) + +def reset(): + global RESET + """Button used to reset the app""" + + reset_button.on() + time.sleep(1.1) + reset_button.off() + reset_button.toggle() # Set Pin to tri-state def i2c(id, tick): global pi @@ -79,6 +78,12 @@ def i2c(id, tick): MESSAGE_RECEIVED = string_split[0] FIRST_RX += 1 +def close(): + time.sleep(5) + + pi.stop() + os.system('sudo killall pigpiod') + # END ################################################################################ @@ -143,20 +148,16 @@ def test_i2c_master_tx_configuration(self): MESSAGE_RECEIVED = str(MESSAGE_RECEIVED) MESSAGE_RECEIVED = MESSAGE_RECEIVED.strip() - logger.info('Expected Message: ' + MESSAGE, - extra={'timegap': time_gap(TEST_START_TIME)}) - - logger.info('Message Received: ' + MESSAGE_RECEIVED, - extra={'timegap': time_gap(TEST_START_TIME)}) - if (MESSAGE_RECEIVED == MESSAGE): # Close setup - e.cancel() + close() - pi.bsc_i2c(0) # Disable BSC peripheral + logger.info('Expected Message: ' + MESSAGE, + extra={'timegap': time_gap(TEST_START_TIME)}) - pi.stop() + logger.info('Message Received: ' + MESSAGE_RECEIVED, + extra={'timegap': time_gap(TEST_START_TIME)}) reset() # Reset application to stop sending messages @@ -179,11 +180,13 @@ def test_i2c_master_tx_configuration(self): else: # Close setup - e.cancel() + close() - pi.bsc_i2c(0) # Disable BSC peripheral + logger.info('Expected Message: ' + MESSAGE, + extra={'timegap': time_gap(TEST_START_TIME)}) - pi.stop() + logger.info('Message Received: ' + MESSAGE_RECEIVED, + extra={'timegap': time_gap(TEST_START_TIME)}) reset() # Reset application to stop sending messages @@ -211,8 +214,10 @@ def test_i2c_master_tx_configuration(self): class Nrf52840Test(I2CMasterTxTest): def setUp(self): - + + time.sleep(1) reset() # Used to activate the reset button on board + time.sleep(1) logger.info('Setting up for nrf52840dk I2C Master Tx test...', extra={'timegap': time_gap(TEST_START_TIME)}) From 61837a4fd1ad7aa8ab32b1a238da63297e415dcd Mon Sep 17 00:00:00 2001 From: AnthonyQ619 Date: Thu, 1 Sep 2022 05:09:40 +0000 Subject: [PATCH 43/49] updated gpio and uart tests --- examples/ci-tests/gpio/test.py | 9 +++++++++ examples/ci-tests/uartrt/test.py | 8 ++++++++ simple-ble/build/cortex-m0/simple-ble.a | Bin 17394 -> 17394 bytes simple-ble/build/cortex-m3/simple-ble.a | Bin 17026 -> 17026 bytes simple-ble/build/cortex-m4/simple-ble.a | Bin 17026 -> 17026 bytes simple-ble/build/cortex-m7/simple-ble.a | Bin 17026 -> 17026 bytes 6 files changed, 17 insertions(+) diff --git a/examples/ci-tests/gpio/test.py b/examples/ci-tests/gpio/test.py index f54d877f2..fd258a223 100644 --- a/examples/ci-tests/gpio/test.py +++ b/examples/ci-tests/gpio/test.py @@ -185,7 +185,16 @@ def setUp(self): self.P2 = Pin(13) self.P3 = Pin(19) +class Nrf52dkTest(GpioTest): + def setUp(self): + logger.info('Setting up for nrf52dk GPIO test...', + extra={'timegap': time_gap(TEST_START_TIME)}) + # Assign input pins + self.P0 = Pin(5) + self.P1 = Pin(6) + self.P2 = Pin(13) + self.P3 = Pin(19) # END ################################################################################ diff --git a/examples/ci-tests/uartrt/test.py b/examples/ci-tests/uartrt/test.py index 86f3db51e..e649db37b 100644 --- a/examples/ci-tests/uartrt/test.py +++ b/examples/ci-tests/uartrt/test.py @@ -113,6 +113,14 @@ def setUp(self): logger.info('Setting up for hail Uart Rx/Tx test...', extra={'timegap': time_gap(TEST_START_TIME)}) +class Nrf52dkTest(UartTest): + def setUp(self): + global sp + + sp = serial.Serial(port="/dev/ttyACM0", baudrate=115200, bytesize=8, timeout=2) + logger.info('Setting up for nrf52dk Uart Rx/Tx test...', + extra={'timegap': time_gap(TEST_START_TIME)}) + # END ################################################################################ diff --git a/simple-ble/build/cortex-m0/simple-ble.a b/simple-ble/build/cortex-m0/simple-ble.a index 9ff08cb60f2d3c1e8488c49d5e110ade0815fb92..31ee42c5b193180f15566a7e77a1049ef3383489 100644 GIT binary patch delta 87 zcmey=&iJXFae@?wiIIhofrYWfM5T9d_GSsjJ4}<=S!^eNVHTbo&XPX)G|S@2HLOOH lomoW0bMn(OlM{1v^9vYs!%K=1a|`lwGV@Y5uV!_(0|3w*9P0o8 delta 86 zcmey=&iJXFae@?wk)?&HxuKcaM5T9d_GSsjJ4}-eS%fElVYZ#z$SOS9g(aOUCqF$i kIWb2!zhLqTmSx-}MTxlu`8k<+sl}7MSxq;uV|B3u0KViL@c;k- diff --git a/simple-ble/build/cortex-m3/simple-ble.a b/simple-ble/build/cortex-m3/simple-ble.a index e68e791cae0343fc95345dbbc30bb2f2c12535e5..2d52a6b6d7ed5f8c0a4f24a96c863e4e9d62e0b7 100644 GIT binary patch delta 87 zcmZo_Wo&9?oFK(vVq{@tU}0=IQRy9=y;*|sHq&G_7Td|6nT02Zv7}Ev#j<#EHLKBN lCl(R$oc#36T+3>t9bR0Ln4GO!TAY}kYHMU*V!@yro|B)RnVguTn_mFrloTcA7Ubt- M=A~|4!+OmI08CpZ(EtDd delta 86 zcmZo_Wo&9?oFK(vWNBe)ZfIscQRy9=y;*|sF4JTq7U9WXnQbRGu?kOiWl87C$xqKr kPR!BGFPOZNWf^x#QDSaEeokgyYVl+rR@2SvSufiF0CrFuqyPW_ diff --git a/simple-ble/build/cortex-m7/simple-ble.a b/simple-ble/build/cortex-m7/simple-ble.a index 2a41bcdb8031fd300874b749e6692dda8338aac6..cc64e12f84e6901235efbfa7d5c20208549f7c40 100644 GIT binary patch delta 116 zcmZo_Wo&9?oFK(vVq{@tU}0h~QRy9=y;*|sF4JTV7F&U=(%b^w+|1(Q)MDMtyv&lx zp)6UG&#)|>T+3>t9bR0Ln4GO!TAY}kYHMU*V!@yro|B)RnVguTn_mFrloTcA7Ubt- M=A~|4!+OmI07iW#!2kdN delta 86 zcmZo_Wo&9?oFK(vWNBe)ZfIsPQRy9=y;*|sF4JTq7U9WXnQbRGu?kOiWl87C$xqKr kPR!BGFPOZNWf^x#QDSaEeokgyYVl+rR@2SvSufiF0CvzErT_o{ From 3a68ac5127a41f9061cf35522822294353b79cc0 Mon Sep 17 00:00:00 2001 From: AnthonyQ619 Date: Sun, 2 Oct 2022 02:56:21 +0000 Subject: [PATCH 44/49] Updated tests to most recent Tock updates --- examples/ci-tests/ble/test.py | 5 +++++ examples/ci-tests/i2c-master-rx/main.c | 4 +++- examples/ci-tests/i2c-master-rx/test.py | 11 ++++++++++- examples/ci-tests/i2c-master-tx/main.c | 2 ++ examples/ci-tests/i2c-slave-rx/main.c | 4 +++- examples/ci-tests/i2c-slave-tx/main.c | 2 ++ 6 files changed, 25 insertions(+), 3 deletions(-) diff --git a/examples/ci-tests/ble/test.py b/examples/ci-tests/ble/test.py index cdc3768aa..8100a9c03 100644 --- a/examples/ci-tests/ble/test.py +++ b/examples/ci-tests/ble/test.py @@ -131,6 +131,11 @@ def setUp(self): logger.info('Setting up for nrf52840dk BLE test...', extra={'timegap': time_gap(TEST_START_TIME)}) +class Nrf52Test(BleTest): + def setUp(self): + logger.info('Setting up for nrf52dk BLE test...', + extra={'timegap': time_gap(TEST_START_TIME)}) + # END ################################################################################ diff --git a/examples/ci-tests/i2c-master-rx/main.c b/examples/ci-tests/i2c-master-rx/main.c index b79a41ffa..bbdb8f3e6 100644 --- a/examples/ci-tests/i2c-master-rx/main.c +++ b/examples/ci-tests/i2c-master-rx/main.c @@ -1,5 +1,7 @@ #include #include +#include +#include #include #include @@ -107,4 +109,4 @@ int main(void) { for (j = 0; j < nbuttons; j++) { TOCK_EXPECT(RETURNCODE_SUCCESS, button_enable_interrupt(j)); } -} \ No newline at end of file +} diff --git a/examples/ci-tests/i2c-master-rx/test.py b/examples/ci-tests/i2c-master-rx/test.py index 0e26d507c..6195e5a6c 100644 --- a/examples/ci-tests/i2c-master-rx/test.py +++ b/examples/ci-tests/i2c-master-rx/test.py @@ -113,7 +113,7 @@ def dummy_transaction(): time.sleep(1) reset() time.sleep(1) - + close() def close(): time.sleep(5) @@ -153,9 +153,18 @@ def test_i2c_master_rx_configuration(self): global MESSAGE_CONFIRMATION global dummy + dummy_transaction() # Initiate the dummy transaction to update buffer in proper time dummy = True # Update to initiate the dummy transaction properly on the i2c function + # Set up pi gpio daemon again to clear buffer and reset transaction + time.sleep(1) + os.system('sudo pigpiod') + time.sleep(1) + + pi = pigpio.pi() + ################################################################### + print() logger.info('Sending Messages As Slave... ', extra={'timegap': time_gap(TEST_START_TIME)}) diff --git a/examples/ci-tests/i2c-master-tx/main.c b/examples/ci-tests/i2c-master-tx/main.c index 613bda123..b4bd5a571 100644 --- a/examples/ci-tests/i2c-master-tx/main.c +++ b/examples/ci-tests/i2c-master-tx/main.c @@ -1,5 +1,7 @@ #include #include +#include +#include #include #include diff --git a/examples/ci-tests/i2c-slave-rx/main.c b/examples/ci-tests/i2c-slave-rx/main.c index 757a4f106..45bca594e 100644 --- a/examples/ci-tests/i2c-slave-rx/main.c +++ b/examples/ci-tests/i2c-slave-rx/main.c @@ -1,5 +1,7 @@ #include #include +#include +#include #include #include @@ -43,4 +45,4 @@ int main(void) { TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_address(FOLLOW_ADDRESS)); TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_listen()); -} \ No newline at end of file +} diff --git a/examples/ci-tests/i2c-slave-tx/main.c b/examples/ci-tests/i2c-slave-tx/main.c index 616a88c8d..c91062ef5 100644 --- a/examples/ci-tests/i2c-slave-tx/main.c +++ b/examples/ci-tests/i2c-slave-tx/main.c @@ -1,5 +1,7 @@ #include #include +#include +#include #include #include From bce33e075c74f79a5d976a9076b834aff68b2fba Mon Sep 17 00:00:00 2001 From: AnthonyQ619 Date: Wed, 5 Oct 2022 21:22:39 +0000 Subject: [PATCH 45/49] Fixing up tests --- examples/ci-tests/i2c-master-rx/test.py | 3 +- examples/ci-tests/uart/Makefile | 11 ------- examples/ci-tests/uart/main.c | 40 ------------------------- examples/ci-tests/uart/test.py | 29 ------------------ 4 files changed, 2 insertions(+), 81 deletions(-) delete mode 100644 examples/ci-tests/uart/Makefile delete mode 100644 examples/ci-tests/uart/main.c delete mode 100644 examples/ci-tests/uart/test.py diff --git a/examples/ci-tests/i2c-master-rx/test.py b/examples/ci-tests/i2c-master-rx/test.py index 6195e5a6c..4536fe30f 100644 --- a/examples/ci-tests/i2c-master-rx/test.py +++ b/examples/ci-tests/i2c-master-rx/test.py @@ -26,9 +26,10 @@ # Set up PiGPIO properly by configuring it on pi then importing library os.system('sudo pigpiod') -time.sleep(1) +time.sleep(2) import pigpio +time.sleep(1) pi = pigpio.pi() # Configure the Raspberry Pi as slave # PiGPIO configured. diff --git a/examples/ci-tests/uart/Makefile b/examples/ci-tests/uart/Makefile deleted file mode 100644 index a38de484d..000000000 --- a/examples/ci-tests/uart/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# Makefile for user application - -# Specify this directory relative to the current application. -TOCK_USERLAND_BASE_DIR = ../../.. - -# Which files to compile. -C_SRCS := $(wildcard *.c) - -# Include userland master makefile. Contains rules and flags for actually -# building the application. -include $(TOCK_USERLAND_BASE_DIR)/AppMakefile.mk \ No newline at end of file diff --git a/examples/ci-tests/uart/main.c b/examples/ci-tests/uart/main.c deleted file mode 100644 index c8bdcaa46..000000000 --- a/examples/ci-tests/uart/main.c +++ /dev/null @@ -1,40 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#define TARGET_INCOMING_MESSGAE "yeah" -char* message_received = ""; -int main(void){ - while(true){ - // Send Greeting Message - const char* message_sent = "cse145 is cool"; - putnstr(message_sent, (strlen(message_sent))); - // delay_ms(3000); - - // Expected Receive Message - - size_t len = 4; - getnstr(message_received, len); - delay_ms(3000); - // printf("hahaha\n"); - // printf("This is string received"); - // printf(message_received); - // printf("%d", strcmp(message_received, "")); - if(strcmp(message_received, "") != 0){ - break; - } - delay_ms(2000); - } - - printf("left while loop\n"); - while(true){ - // Send Acknowledgement - const char* ack = "true"; - putnstr(ack, (strlen(ack))); - } - - return 0; -} \ No newline at end of file diff --git a/examples/ci-tests/uart/test.py b/examples/ci-tests/uart/test.py deleted file mode 100644 index 0594f374d..000000000 --- a/examples/ci-tests/uart/test.py +++ /dev/null @@ -1,29 +0,0 @@ -import serial -import time - -TARGET_RECEIVED_MESSAGE = "cse145 is cool" -TARGET_ACKNOWLEDGEMENT = "true" - -sp = serial.Serial(port="/dev/ttyUSB0", baudrate=115200, bytesize=8, timeout=2) -print("Starting Uart Test...") -while(True): - # print("B") - if(sp.in_waiting > 0): - message_received = sp.readline() - message_received = message_received.decode("Ascii") - # print(message_received) - # print("A") - - if(message_received == TARGET_RECEIVED_MESSAGE): - print("Correct Serial Communication Message Received") - break - -print("Uart Read Test Passes") -sp.close() -sp.open() -time.sleep(5) -sp.write(b"yeah") - - - - From cd295e70610fd577d235c50b51c94772e9e081a9 Mon Sep 17 00:00:00 2001 From: AnthonyQ619 Date: Wed, 5 Oct 2022 21:27:19 +0000 Subject: [PATCH 46/49] Edited Readme --- examples/ci-tests/i2c-master-rx/README.md | 2 ++ examples/ci-tests/i2c-master-tx/README.md | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/ci-tests/i2c-master-rx/README.md b/examples/ci-tests/i2c-master-rx/README.md index f040937d3..79f526091 100644 --- a/examples/ci-tests/i2c-master-rx/README.md +++ b/examples/ci-tests/i2c-master-rx/README.md @@ -22,3 +22,5 @@ This test requires the Raspberry Pi to be set as slave. Thus, you must use Broad This test requires button activation on tested boards. Two jumpers are required for the activation of the reset button and user button on boards. Broadcom Pins on Raspberry PI used are pins 20 & 21 (GPIO Pins 38 & 40) which are used for user button and reset respectively. This test utilizes the pigpio open source library, but the function utilized, `bsc_i2c` , has a delay when updating the slave buffer being sent to master. This delay, to be specific, is that it takes an i2c transaction between master and slave to update the slave buffer properly. This is a limitation of the RPi slave configuration, not the board being tested i2c configuration. To combat this, we utilize a dummy transaction that runs a i2c transaction of sending messages for 4 seconds to master from slave, then reopens a transaction (the transacton being tested) with the updated slave buffer properly timed. For more information about this delay and what exactly is happening to handle it, check the code `test.py` and the function `dummy_transaction`. + +After Raspberry Pi initial boot, test will fail to receieve a message from device-to-test, due to pigpio daemon not booting properly. Run test again for better measurment after booting RPi. diff --git a/examples/ci-tests/i2c-master-tx/README.md b/examples/ci-tests/i2c-master-tx/README.md index 8e29cff36..143fc704d 100644 --- a/examples/ci-tests/i2c-master-tx/README.md +++ b/examples/ci-tests/i2c-master-tx/README.md @@ -19,4 +19,6 @@ nrf52840dk | Nrf52840Test **NOTE** This test requires the Raspberry Pi to be set as slave. Thus, you must use Broadcom Pins 10 & 11 (SDA & SCL resepectively) or GPIO pin 19 and 23. You must also download the open source python library "pigpio" which enables slave access on the Raspberry Pi. How to download the library is done here on **CI Hardware Documentation - Raspberry Pi setup** -This test requires button activation on tested boards. Two jumpers are required for the activation of the reset button and user button on boards. Broadcom Pins on Raspberry PI used are pins 20 & 21 (GPIO Pins 38 & 40) which are used for user button and reset respectively. The user button and reset button depend on board tested. \ No newline at end of file +This test requires button activation on tested boards. Two jumpers are required for the activation of the reset button and user button on boards. Broadcom Pins on Raspberry PI used are pins 20 & 21 (GPIO Pins 38 & 40) which are used for user button and reset respectively. The user button and reset button depend on board tested. + +After Raspberry Pi initial Boot, test will always fail with a null character message being sent. Run test again for a more accurate measurement. From 0390ff0e5ed8e87ad74ec6c9627d90fcfcadae0e Mon Sep 17 00:00:00 2001 From: AnthonyQ619 Date: Wed, 21 Dec 2022 21:20:35 +0000 Subject: [PATCH 47/49] Created i2c on boot up script --- examples/ci-tests/boot-up/README.md | 26 +++ examples/ci-tests/boot-up/i2cboot.py | 291 +++++++++++++++++++++++++++ 2 files changed, 317 insertions(+) create mode 100644 examples/ci-tests/boot-up/README.md create mode 100644 examples/ci-tests/boot-up/i2cboot.py diff --git a/examples/ci-tests/boot-up/README.md b/examples/ci-tests/boot-up/README.md new file mode 100644 index 000000000..0983f021e --- /dev/null +++ b/examples/ci-tests/boot-up/README.md @@ -0,0 +1,26 @@ +# On Boot Up Scripts + +## Run Python i2cboot + +**Important:** This script is used to solve the cold-start problem the raspberry pi has on boot when running as slave. Currently, after booting the pi, the first i2c master test on a board (tests that require the RPi to act as a slave) will have an empty buffer, causing test to fail. However, after the first test script for master rx/tx is executed, the tests will now pass and buffer is filled properly. To solve this issue, we run this script on boot for the RPi whenever logged in from ssh to run the initial transaction for testing scripts to pass when necessary and not be affected by this cold-start issue. + +`i2cboot.py` provides basic test that sends message from slave to master, and waits for master to send message containing the slave message. This is essentially a Rx/Tx test, but we are primarily focusing on the reception of master here. The message sent from master will be printed over a 4 second period. If message sent from master is the exact same from message sent from slave, the script will pass - but this does not matter (Expected to fail) + +To run the test, +```bash +sudo python3 i2cboot.py +``` + +Boards supported. + +Board | +------| +nrf52840dk | + +**NOTE** +This script requires the Raspberry Pi to be set as slave. Thus, you must use Broadcom Pins 10 & 11 (SDA & SCL resepectively) or GPIO pin 19 and 23. You must also download the open source python library "pigpio" which enables slave access on the Raspberry Pi. How to download the library is done here on **CI Hardware Documentation - Raspberry Pi setup** + +This script requires button activation on tested boards. Two jumpers are required for the activation of the reset button and user button on boards. Broadcom Pins on Raspberry PI used are pins 20 & 21 (GPIO Pins 38 & 40) which are used for user button and reset respectively. + +This test utilizes the pigpio open source library, but the function utilized, `bsc_i2c` , has a delay when updating the slave buffer being sent to master. This delay, to be specific, is that it takes an i2c transaction between master and slave to update the slave buffer properly. This is a limitation of the RPi slave configuration, not the board being tested i2c configuration. To combat this, we utilize a dummy transaction that runs a i2c transaction of sending messages for 4 seconds to master from slave, then reopens a transaction (the transacton being tested) with the updated slave buffer properly timed. For more information about this delay and what exactly is happening to handle it, check the code `i2cboot.py` and the function `dummy_transaction`. + diff --git a/examples/ci-tests/boot-up/i2cboot.py b/examples/ci-tests/boot-up/i2cboot.py new file mode 100644 index 000000000..773927078 --- /dev/null +++ b/examples/ci-tests/boot-up/i2cboot.py @@ -0,0 +1,291 @@ +# I2C Master Rx Test +# This tester corresponds to libtock-c/examples/ci-tests/i2c-master-rx test. + +from pathlib import Path +import time +import logging +import toml +from gpiozero import InputDevice +from gpiozero import OutputDevice +import os + +CONFIG_FILE = f'{Path.home()}/tock/tools/tock-test-harness/config.toml' +MESSAGE_SENT = "Hello I'm Slave" # Message Master sends to slave +MESSAGE_CONFIRMATION= '' +FIRST_RX = 0 +dummy = False #Setup for dummy transaction (Buffer takes one transaction session to update properly) + + +SDA = 10 # Broadcom pin 10 (P1 pin 19) +SCL = 11 # Broadcom pin 11 (P1 pin 23) +RESET = 21 # Broadcom pin 21 (P1 pin 40) +BUTTON_1 = 20 # Broadcom pin 20 (P1 pin 38) + +I2C_ADDR = 0x41 # Raspberry Pi Address + +button = OutputDevice(BUTTON_1) +reset_button = OutputDevice(RESET) + +# Set up PiGPIO properly by configuring it on pi then importing library +os.system('sudo pigpiod') +time.sleep(2) + +import pigpio +time.sleep(1) + +pi = pigpio.pi() # Configure the Raspberry Pi as slave +# PiGPIO configured. + +################################################################################ +# Helper Functions +################################################################################ + +def time_gap(start_time): + """Return time gap between current time and start_time + Argument: + start_time - Start time + """ + return "{:.6f}".format(time.time() - start_time) + +def press_button(): + global BUTTON_1 + """Button is one of User Buttons""" + + button.on() + time.sleep(1.5) + button.off() + +def reset(): + global RESET + + reset_button.on() + time.sleep(1.1) + reset_button.off() + reset_button.toggle() # Set Pin to tri-state + +def i2c(id, tick): + global pi + global FIRST_RX + global MESSAGE_CONFIRMATION + global I2C_ADDR + global dummy + + s, b, d = pi.bsc_i2c(I2C_ADDR, b"\nHello I'm Slave\n") + + # Check if dummy transaction is occuring, if not, test has started. + if dummy: + if b: + if(FIRST_RX < 1): + MESSAGE_CONFIRMATION = d.decode() + FIRST_RX += 1 + + array = str(d[:-1]) + logger.info('Messsage Call Back From Master: ' + array, + extra={'timegap': time_gap(TEST_START_TIME)}) + +def dummy_transaction(): + global pi + global I2C_ADDR + global dummy + """ + This function is used to conteract the update delay + on the i2c slave buffer. The delay occurs when the buffer is + updated and requires the bus to enact a transcation before the + update to the buffer actually takes place. This function, then, + initiates that transaction to occur, and update the buffer in proper time. + """ + + if not pi.connected: + exit() + + press_button() + + # Add pull-ups in case external pull-ups haven't been added (For Raspberry Pi) + + pi.set_pull_up_down(SDA, pigpio.PUD_UP) + pi.set_pull_up_down(SCL, pigpio.PUD_UP) + + # Respond to BSC slave activity + e = pi.event_callback(pigpio.EVENT_BSC, i2c) + + pi.bsc_i2c(I2C_ADDR) + + time.sleep(3) + + # Reset Operation + time.sleep(1) + reset() + time.sleep(1) + close() + +def close(): + time.sleep(5) + + pi.stop() + os.system('sudo killall pigpiod') + + +################################################################################ +# Start test and logger +################################################################################ + +# Test Start Time +TEST_START_TIME = time.time() + +# Logger set format +LOG_FORMAT = "%(timegap)s %(levelname)s -- %(message)s" +logging.basicConfig(format=LOG_FORMAT) + +# Logger add formatter +logger = logging.getLogger('I2C Master Rx Boot Test') +logger.setLevel('INFO') + + +# END + +################################################################################ +# Test Case Module +################################################################################ + + +def main(): + """ Set up for Raspberry Pi configuration """ + global pi + global MESSAGE_CONFIRMATION + global dummy + + runTest = "" + with open(CONFIG_FILE, 'r') as config_toml: + config = toml.load(config_toml) + runTest = config['env']['i2c_on_boot'] + + if runTest == 'yes': + logger.info('Initiating I2C Master Rx Boot Test...', + extra={'timegap': time_gap(TEST_START_TIME)}) + + dummy_transaction() # Initiate the dummy transaction to update buffer in proper time + dummy = True # Update to initiate the dummy transaction properly on the i2c function + + # Set up pi gpio daemon again to clear buffer and reset transaction + time.sleep(1) + os.system('sudo pigpiod') + time.sleep(1) + + pi = pigpio.pi() + ################################################################### + + print() + logger.info('Sending Messages As Slave... ', + extra={'timegap': time_gap(TEST_START_TIME)}) + + received = False + + if not pi.connected: + exit() + + time.sleep(2) # Wait until app has fully reset + + press_button() # Used to press one of the user buttons on the board + + # Add pull-ups in case external pull-ups haven't been added (For Raspberry Pi) + + pi.set_pull_up_down(SDA, pigpio.PUD_UP) + pi.set_pull_up_down(SCL, pigpio.PUD_UP) + + # Respond to BSC slave activity + e = pi.event_callback(pigpio.EVENT_BSC, i2c) + + pi.bsc_i2c(I2C_ADDR) # Configure BSC as I2C slave + + print() + logger.info('Initiating Transmission of Messages...', + extra={'timegap': time_gap(TEST_START_TIME)}) + + time.sleep(4) # Time to wait for messages to be sent (Should see four messages logged) + + MESSAGE_CONFIRMATION = str(MESSAGE_CONFIRMATION) + MESSAGE_CONFIRMATION = MESSAGE_CONFIRMATION.strip() + + if (MESSAGE_CONFIRMATION == MESSAGE_SENT): + + # Close setup + close() + + logger.info('Message Sent: ' + MESSAGE_SENT, + extra={'timegap': time_gap(TEST_START_TIME)}) + + logger.info('Message Called Back from Master: ' + MESSAGE_CONFIRMATION, + extra={'timegap': time_gap(TEST_START_TIME)}) + + reset() # Reset application to stop sending messages + + time.sleep(1) + + logger.info('Connection Satisfied. (Not Expected - But Fine to continue)', + extra={'timegap': time_gap(TEST_START_TIME)}) + + received = True + + time.sleep(1) + + logger.info('I2C Master Rx Test has ended.', + extra={'timegap': time_gap(TEST_START_TIME)}) + + else: + + # Close setup + + close() + + logger.info('Message Sent: ' + MESSAGE_SENT, + extra={'timegap': time_gap(TEST_START_TIME)}) + + logger.info('Message Called Back from Master: ' + MESSAGE_CONFIRMATION, + extra={'timegap': time_gap(TEST_START_TIME)}) + + reset() # Reset application to stop sending messages + + time.sleep(1) + + logger.info('Connection was not Satisfied. Wrong/No message was sent. (Expected)', + extra={'timegap': time_gap(TEST_START_TIME)}) + + time.sleep(1) + + logger.info('I2C Master Rx Test has ended.', + extra={'timegap': time_gap(TEST_START_TIME)}) + else: + logger.info("Not Running I2C Boot Test...", + extra={'timegap': time_gap(TEST_START_TIME)}) + + #Closing App + close() + reset() +# END + +################################################################################ +# Test Case Setup +################################################################################ + +def startup(): + + time.sleep(1) + reset() # Used to activate the reset button on board + time.sleep(1) + + logger.info('Setting up for nrf52840dk I2C Master Rx test...', + extra={'timegap': time_gap(TEST_START_TIME)}) + + time.sleep(1) + + main() + + +# END + +################################################################################ +# Main +################################################################################ + +if __name__ == '__main__': + main() From b4f547571ee8e46ad13ffe382a4cf2cf242f1b86 Mon Sep 17 00:00:00 2001 From: AnthonyQ619 Date: Sun, 2 Apr 2023 16:37:10 -0700 Subject: [PATCH 48/49] Update test.py --- examples/ci-tests/uartrt/test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ci-tests/uartrt/test.py b/examples/ci-tests/uartrt/test.py index e649db37b..29e419370 100644 --- a/examples/ci-tests/uartrt/test.py +++ b/examples/ci-tests/uartrt/test.py @@ -113,7 +113,7 @@ def setUp(self): logger.info('Setting up for hail Uart Rx/Tx test...', extra={'timegap': time_gap(TEST_START_TIME)}) -class Nrf52dkTest(UartTest): +class Nrf52Test(UartTest): def setUp(self): global sp From d56854691680fc2fdf09fc0e8f1d2d27c17e5f91 Mon Sep 17 00:00:00 2001 From: AnthonyQ619 Date: Sun, 2 Apr 2023 16:37:35 -0700 Subject: [PATCH 49/49] Update test.py --- examples/ci-tests/gpio/test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ci-tests/gpio/test.py b/examples/ci-tests/gpio/test.py index fd258a223..0295ac51d 100644 --- a/examples/ci-tests/gpio/test.py +++ b/examples/ci-tests/gpio/test.py @@ -185,7 +185,7 @@ def setUp(self): self.P2 = Pin(13) self.P3 = Pin(19) -class Nrf52dkTest(GpioTest): +class Nrf52Test(GpioTest): def setUp(self): logger.info('Setting up for nrf52dk GPIO test...', extra={'timegap': time_gap(TEST_START_TIME)})