Skip to content

Commit

Permalink
ports/psoc6: SPI fixes.
Browse files Browse the repository at this point in the history
Signed-off-by: NikhitaR-IFX <Nikhita.Rajasekhar@infineon.com>
  • Loading branch information
NikhitaR-IFX committed Apr 29, 2024
1 parent cd20fa2 commit e477eaa
Show file tree
Hide file tree
Showing 4 changed files with 260 additions and 35 deletions.
75 changes: 55 additions & 20 deletions ports/psoc6/machine_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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); \
}
Expand Down Expand Up @@ -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);
}


Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
37 changes: 22 additions & 15 deletions tests/psoc6/hw_ext/spi.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
####################################################
Expand Down Expand Up @@ -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)
Expand All @@ -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!")

Expand Down Expand Up @@ -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)
Expand All @@ -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
##########################
Expand All @@ -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,
Expand Down Expand Up @@ -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)"""
97 changes: 97 additions & 0 deletions tests/psoc6/hw_ext/spi_master.py
Original file line number Diff line number Diff line change
@@ -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)"""
86 changes: 86 additions & 0 deletions tests/psoc6/hw_ext/spi_slave.py
Original file line number Diff line number Diff line change
@@ -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)"""

0 comments on commit e477eaa

Please sign in to comment.