From e477eaaf46853021598cbd7ef83d46959ef4c3ca Mon Sep 17 00:00:00 2001 From: NikhitaR-IFX Date: Mon, 29 Apr 2024 15:45:36 +0530 Subject: [PATCH] ports/psoc6: SPI fixes. Signed-off-by: NikhitaR-IFX --- ports/psoc6/machine_spi.c | 75 +++++++++++++++++------- tests/psoc6/hw_ext/spi.py | 37 +++++++----- tests/psoc6/hw_ext/spi_master.py | 97 ++++++++++++++++++++++++++++++++ tests/psoc6/hw_ext/spi_slave.py | 86 ++++++++++++++++++++++++++++ 4 files changed, 260 insertions(+), 35 deletions(-) create mode 100644 tests/psoc6/hw_ext/spi_master.py create mode 100644 tests/psoc6/hw_ext/spi_slave.py diff --git a/ports/psoc6/machine_spi.c b/ports/psoc6/machine_spi.c index 4eb446306fc0b..01ae490bbf25a 100644 --- a/ports/psoc6/machine_spi.c +++ b/ports/psoc6/machine_spi.c @@ -25,6 +25,7 @@ #define DEFAULT_SPI_BITS (8) #define DEFAULT_SPI_FIRSTBIT (0) // msb + #define spi_assert_raise_val(msg, ret) if (ret != CY_RSLT_SUCCESS) { \ mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT(msg), ret); \ } @@ -276,27 +277,39 @@ static void machine_spi_init(mp_obj_base_t *self_in, size_t n_args, const mp_obj mp_raise_NotImplementedError(MP_ERROR_TEXT("Init not supported. Use the constructor to initialize.\n")); } -static void machine_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest) { +static void machine_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *tx, uint8_t *rx) { machine_spi_obj_t *self = (machine_spi_obj_t *)self_in; cy_rslt_t result; - - if (dest == NULL) { - for (int i = 0; i < len; i++) - { - result = cyhal_spi_send(&self->spi_obj, src[i]); - spi_assert_raise_val("SPI initialisation failed with return code %lx !", result); - } - } else if (src == NULL) { - for (int i = 0; i < len; i++) - { - result = cyhal_spi_recv(&self->spi_obj, (uint32_t *)(dest + i)); - spi_assert_raise_val("SPI initialisation failed with return code %lx !", result); + const uint8_t *tx_buf; + uint8_t *rx_buf; + uint8_t tx_temp_buf[len]; + uint8_t rx_temp_buf[len]; + uint8_t write_fill = 0xFF; + + // Case 1: rx is NULL - (write operation) + if (rx == NULL) { + tx_buf = tx; + memset(rx_temp_buf, 0x01, len * sizeof(uint8_t)); + rx_buf = rx_temp_buf; + // result = cyhal_spi_transfer(&self->spi_obj, tx, len, rx_temp_buf, len, write_fill); + // spi_assert_raise_val("SPI transfer failed with return code %lx !", result); + } + // Case 2: tx and rx equal --> read(), readinto() and write_readinto() with tx and rx same buffers + else { + if (tx == rx || tx == NULL) { + memcpy(tx_temp_buf, tx, len * sizeof(uint8_t)); + tx_buf = tx_temp_buf; + rx_buf = rx; + write_fill = tx_temp_buf[0]; + // result = cyhal_spi_transfer(&self->spi_obj, tx, len, rx, len, write_fill); + // spi_assert_raise_val("SPI read failed with return code %lx !", result); + } else { + tx_buf = tx; + rx_buf = rx; } - } else { - result = cyhal_spi_transfer(&self->spi_obj, src, len, dest, len, 0xFF); - spi_assert_raise_val("SPI initialisation failed with return code %lx !", result); } - + result = cyhal_spi_transfer(&self->spi_obj, tx_buf, len, rx_buf, len, write_fill); + spi_assert_raise_val("SPI read failed with return code %lx !", result); } @@ -337,10 +350,13 @@ MP_DEFINE_CONST_FUN_OBJ_1(machine_spi_slave_deinit_obj, machine_spi_slave_deinit static mp_obj_t machine_spi_slave_read(mp_obj_t self_in, mp_obj_t buf_in) { machine_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_buffer_info_t bufinfo; - mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); + mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_WRITE); uint16_t len = bufinfo.len; - cy_rslt_t result = cyhal_spi_slave_read(&self->spi_obj, bufinfo.buf, &len, 0); + uint8_t tx_dummy[len]; + memset(tx_dummy, 0x02, len * sizeof(uint8_t)); + cy_rslt_t result = cyhal_spi_transfer(&self->spi_obj, tx_dummy, len, bufinfo.buf, len, 0xFF); spi_assert_raise_val("SPI slave read failed with return code %lx !", result); + return mp_const_none; } static MP_DEFINE_CONST_FUN_OBJ_2(machine_spi_slave_read_obj, machine_spi_slave_read); @@ -350,17 +366,36 @@ static mp_obj_t machine_spi_slave_write(mp_obj_t self_in, mp_obj_t buf_in) { mp_buffer_info_t bufinfo; mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); uint16_t len = bufinfo.len; - cy_rslt_t result = cyhal_spi_slave_write(&self->spi_obj, bufinfo.buf, &len, 0); + uint8_t rx_dummy[len]; + memset(rx_dummy, 0x01, len * sizeof(uint8_t)); + cy_rslt_t result = cyhal_spi_transfer(&self->spi_obj, bufinfo.buf, len, rx_dummy, len, 0xFF); spi_assert_raise_val("SPI slave write failed with return code %lx !", result); return mp_const_none; } static MP_DEFINE_CONST_FUN_OBJ_2(machine_spi_slave_write_obj, machine_spi_slave_write); +static mp_obj_t machine_spi_slave_write_readinto(mp_obj_t self_in, mp_obj_t tx_buf_in, mp_obj_t rx_buf_in) { + machine_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_buffer_info_t tx_bufinfo; + mp_buffer_info_t rx_bufinfo; + mp_get_buffer_raise(tx_buf_in, &tx_bufinfo, MP_BUFFER_READ); + mp_get_buffer_raise(rx_buf_in, &rx_bufinfo, MP_BUFFER_READ); + uint16_t len = tx_bufinfo.len; + if (tx_bufinfo.len != rx_bufinfo.len) { + mp_raise_ValueError(MP_ERROR_TEXT("buffers must be the same length")); + } + cy_rslt_t result = cyhal_spi_transfer(&self->spi_obj, tx_bufinfo.buf, len, rx_bufinfo.buf, len, 0xFF); + spi_assert_raise_val("SPI slave write failed with return code %lx !", result); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_3(machine_spi_slave_write_readinto_obj, machine_spi_slave_write_readinto); + static const mp_rom_map_elem_t machine_spi_slave_locals_dict_table[] = { // Functions { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&machine_spi_slave_read_obj) }, { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&machine_spi_slave_write_obj) }, + { MP_ROM_QSTR(MP_QSTR_write_readinto), MP_ROM_PTR(&machine_spi_slave_write_readinto_obj) }, { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_spi_slave_deinit_obj) }, }; static MP_DEFINE_CONST_DICT(machine_spi_slave_locals_dict, machine_spi_slave_locals_dict_table); diff --git a/tests/psoc6/hw_ext/spi.py b/tests/psoc6/hw_ext/spi.py index 6fa85f65668fc..8b4028e1149af 100644 --- a/tests/psoc6/hw_ext/spi.py +++ b/tests/psoc6/hw_ext/spi.py @@ -29,6 +29,7 @@ master_to_slave_write = 0 master_to_slave_write_read = 1 slave_to_master_write = 2 +slave_to_master_write_multi_args = 3 # Test hardware setup #################################################### @@ -80,7 +81,8 @@ def transfer_data_and_validate(tx_buf, rx_buf, exp_recv_data, data_transfer_dir) print("slave writes: ", tx_slave_buf) spi_master.write_readinto(tx_buf, rx_buf) print("master received: ", rx_buf) - # spi_slave.read(rx_slave_buf) + spi_master.write_readinto(tx_buf, rx_buf) + spi_slave.read(rx_slave_buf) print("slave recvd: ", rx_slave_buf) print("Validate slave to master data transfer") _validate_data(tx_slave_buf, rx_buf) @@ -93,6 +95,13 @@ def transfer_data_and_validate(tx_buf, rx_buf, exp_recv_data, data_transfer_dir) print("received data by master: ", rx_buf) _validate_data(exp_recv_data, rx_buf) + elif data_transfer_dir == slave_to_master_write_multi_args: + spi_slave.write(tx_buf) + rx = bytearray(1) + rx_buf = spi_master.read(len(rx_buf), 0x11) + spi_slave.read(rx) + print("RX: ", rx) + else: print("Wrong data transfer direction!") @@ -129,7 +138,7 @@ def transfer_data_and_validate(tx_buf, rx_buf, exp_recv_data, data_transfer_dir) # 3. Master to slave 4-bytes data transfer ########################################### -tx_buf = b"\x88\x88\x11\x11" +"""tx_buf = b"\x88\x88\x11\x11" rx_buf = bytearray(4) print("\nWriting 4-bytes data from master to slave") transfer_data_and_validate(tx_buf, rx_buf, tx_buf, master_to_slave_write) @@ -139,7 +148,15 @@ def transfer_data_and_validate(tx_buf, rx_buf, exp_recv_data, data_transfer_dir) tx_buf = b"\x11\x11\x88\x88\x11\x11\x88\x88" rx_buf = bytearray(8) print("\nWriting 8-bytes data from slave to master") -transfer_data_and_validate(tx_buf, rx_buf, tx_buf, slave_to_master_write) +transfer_data_and_validate(tx_buf, rx_buf, tx_buf, slave_to_master_write)""" + +# 7. Write from master to slave and read concurrently +###################################################### +tx_buf = b"\x11\x11\x88\x88\x11\x11\x88\x88" +rx_buf = bytearray(8) +print("\nWriting 8-bytes data from slave to master") +transfer_data_and_validate(tx_buf, rx_buf, tx_buf, slave_to_master_write_multi_args) + # 5. Deinit SPI modules ########################## @@ -148,7 +165,7 @@ def transfer_data_and_validate(tx_buf, rx_buf, exp_recv_data, data_transfer_dir) # 6. Reconfigure firstbit and transfer data from master to slave ################################################################# -spi_master = SPI( +"""spi_master = SPI( baudrate=1000000, polarity=0, phase=0, @@ -176,14 +193,4 @@ def transfer_data_and_validate(tx_buf, rx_buf, exp_recv_data, data_transfer_dir) rx_buf = bytearray(8) tx_exp_buf = b"\x88\x88\x11\x11\x88\x88\x11\x11" print("\nWriting data from master to slave with firstbit as MSB (master) and LSB(slave)") -transfer_data_and_validate(tx_buf, rx_buf, tx_exp_buf, master_to_slave_write) - -# 7. Write from master to slave and read concurrently -###################################################### - -"""spi_master = SPI(baudrate=1000000, polarity=0, phase=0, bits=8, firstbit=SPI.LSB,ssel=ssel_master_pin, sck=sck_master_pin, mosi=mosi_master_pin, miso=miso_master_pin) -print(spi_master) -spi_slave = SPISlave(baudrate=1000000, polarity=0, phase=0, bits=8, firstbit=SPI.MSB, ssel=ssel_slave_pin, sck=sck_slave_pin, mosi=mosi_slave_pin, miso=miso_slave_pin) -print(spi_slave) -transfer_data() -#validate_data()""" +transfer_data_and_validate(tx_buf, rx_buf, tx_exp_buf, master_to_slave_write)""" diff --git a/tests/psoc6/hw_ext/spi_master.py b/tests/psoc6/hw_ext/spi_master.py new file mode 100644 index 0000000000000..1bfdd67378891 --- /dev/null +++ b/tests/psoc6/hw_ext/spi_master.py @@ -0,0 +1,97 @@ +import binascii +import time +import os + +try: + from machine import SPI, SPISlave +except ImportError: + print("SKIP") + raise SystemExit + +# Allocate pin based on board +sck_master_pin = "P6_2" +mosi_master_pin = "P6_0" +miso_master_pin = "P6_1" +ssel_master_pin = "P6_3" + +success = b"1" +failed = b"2" + + +def spi_master_configure(): + spi_obj = SPI( + baudrate=1000000, + polarity=0, + phase=0, + bits=8, + firstbit=SPI.MSB, + ssel=ssel_master_pin, + sck=sck_master_pin, + mosi=mosi_master_pin, + miso=miso_master_pin, + ) + print("\n", spi_obj) + return spi_obj + + +def _verify_test(test_case, actual_data, exp_data): + print("rx: ", actual_data) + if actual_data == exp_data: + print(test_case + ": successful") + else: + print(test_case + ": failed") + + +def spi_half_duplex_communication(spi_obj, tx, rx): + print("\n*** Half duplex communication ***") + status = bytearray(1) + print("1) master-->write and slave-->read") + spi_obj.write(tx) + print("tx: ", tx) + status = spi_obj.read(1) + _verify_test("master write", status, success) + + print("2) slave-->write and master-->read using readinto()") + spi_obj.readinto(rx) + _verify_test("master read ", rx, tx) + + print("3) slave-->write and master-->read using readinto by sending out a write_byte=0x12") + spi_obj.readinto(rx, 0x12) + _verify_test("master read ", rx, tx) + status = spi_obj.read(1) + _verify_test("write_byte received by slave correctly", status, success) + + +def spi_full_duplex_communication(spi_obj, tx, rx): + print("*** Full duplex communication ***") + exp_rx = b"\x06\x06\x05\x05" + print("1) master-->write and slave-->read continuously") + spi_obj.write_readinto(tx, rx) + _verify_test("read value is same as expected", rx, exp_rx) + + +"""def spi_master_read_verify(spi_obj,tx,rx): + rx = spi_obj.read(len(tx)) + print(rx) + rx = spi_obj.read(len(tx),0x11) + print(rx) + print("SPI master write followed by read is successful: ", rx==tx) + +def spi_master_readinto_verify(spi_obj,tx,rx): + spi_obj.write(tx) + print("SPI master write completed") + rx = spi_obj.read(len(tx)) + print(rx) + print("SPI master write followed by read is successful: ", rx==tx)""" + +print("*** SPI MASTER INSTANCE ***") + +spi_obj = spi_master_configure() + +tx_buf = b"\x08\x01\x08\x02" +rx_buf = bytearray(4) +spi_half_duplex_communication(spi_obj, tx_buf, rx_buf) + +"""tx_buf = b"\x06\x08\x05\x07" +rx_buf = bytearray(4) +spi_full_duplex_communication(spi_obj, tx_buf, rx_buf)""" diff --git a/tests/psoc6/hw_ext/spi_slave.py b/tests/psoc6/hw_ext/spi_slave.py new file mode 100644 index 0000000000000..3fd4b022dcfe4 --- /dev/null +++ b/tests/psoc6/hw_ext/spi_slave.py @@ -0,0 +1,86 @@ +import binascii +import time +import os + +try: + from machine import SPI, SPISlave +except ImportError: + print("SKIP") + raise SystemExit + +sck_slave_pin = "P13_2" +mosi_slave_pin = "P13_0" +miso_slave_pin = "P13_1" +ssel_slave_pin = "P13_3" + +success = b"1" +failed = b"2" + + +def spi_slave_configure(): + spi_obj = SPISlave( + baudrate=1000000, + polarity=0, + phase=0, + bits=8, + firstbit=SPI.MSB, + ssel=ssel_slave_pin, + sck=sck_slave_pin, + mosi=mosi_slave_pin, + miso=miso_slave_pin, + ) + print("\n", spi_obj) + return spi_obj + + +def _verify_test(rx, exp_data): + if rx == exp_data: + print("Successful") + spi_obj.write(success) + else: + print("Failed") + spi_obj.write(failed) + + +def spi_half_duplex_communication(spi_obj, tx, rx): + print("\n***Half duplex communication ***") + write_byte = "0x12" + write_byte_status = bytearray(1) + print("1) master-->write and slave-->read") + # 1) master-->write and slave-->read + spi_obj.read(rx) + print("rx: ", rx) + exp_data = tx + _verify_test(rx, exp_data) + + # 2) slave-->write and master-->read" + print("2) slave-->write and master-->read using readinto()") + spi_obj.write(tx) + + # 3) slave-->write and master-->read by sending a write_byte=0x12" + print("3) slave-->write and master-->read using readinto by sending out a write_byte=0x12") + spi_obj.write(tx) + spi_obj.read(write_byte_status) + _verify_test(write_byte_status, b"0x12") + + +def spi_full_duplex_communication(spi_obj, tx, rx): + print("*** Full duplex communication ***") + exp_rx = b"\x06\x08\x05\x07" + print("1) master-->write and slave-->read continuously") + spi_obj.write_readinto(tx, rx) + print(rx) + # _verify_test("") + + +print("*** SPI SLAVE INSTANCE ***") + +spi_obj = spi_slave_configure() + +tx_buf = b"\x08\x01\x08\x02" +rx_buf = bytearray(4) +spi_half_duplex_communication(spi_obj, tx_buf, rx_buf) + +"""tx_buf = b"\x06\x06\x05\x05" +rx_buf = bytearray(4) +spi_full_duplex_communication(spi_obj, tx_buf, rx_buf)"""