diff --git a/.github/workflows/ports_psoc6.yml b/.github/workflows/ports_psoc6.yml index c9327ef2ba92..3696a31218a3 100644 --- a/.github/workflows/ports_psoc6.yml +++ b/.github/workflows/ports_psoc6.yml @@ -69,8 +69,8 @@ jobs: - name: Run psoc6 tests run: | devs=($(python tools/psoc6/get-devs.py port -b ${{ matrix.board }} -y tools/psoc6/${{ runner.name }}-devs.yml)) - devs0=($(python tools/psoc6/get-devs.py port -b ${{ matrix.board }} -y tools/psoc6/${{ runner.name }}-devs.yml --hw-ext 0.3.0.a)) - devs1=($(python tools/psoc6/get-devs.py port -b ${{ matrix.board }} -y tools/psoc6/${{ runner.name }}-devs.yml --hw-ext 0.3.0.b)) + devs0=($(python tools/psoc6/get-devs.py port -b ${{ matrix.board }} -y tools/psoc6/${{ runner.name }}-devs.yml --hw-ext 0.4.0.a)) + devs1=($(python tools/psoc6/get-devs.py port -b ${{ matrix.board }} -y tools/psoc6/${{ runner.name }}-devs.yml --hw-ext 0.4.0.b)) cd tests echo " >> Filesystem tests" ./psoc6/run_psoc6_tests.sh -c -v --dev0 ${devs[0]} @@ -79,7 +79,18 @@ jobs: echo " >> PSoC6 single board tests" ./psoc6/run_psoc6_tests.sh -c --psoc6 --dev0 ${devs[0]} echo " >> PSoC6 extended hardware tests" - ./psoc6/run_psoc6_tests.sh -c --psoc6-hwext --dev0 ${devs0[0]} + ./psoc6/run_psoc6_tests.sh -c --psoc6-hwext --dev0 ${devs0[0]} + echo " >> PSoC6 i2c tests" + if [ "${{ matrix.board }}" == "CY8CPROTO-062-4343W" ]; then + i2c_dev=${devs1[0]} + else + if [ "${{ matrix.board }}" == "CY8CPROTO-063-BLE" ]; then + i2c_dev=${devs0[0]} + fi + fi + ./psoc6/run_psoc6_tests.sh -c -u --dev0 ${i2c_dev} + echo " >> PSoC6 spi tests" + ./psoc6/run_psoc6_tests.sh -c -r --dev0 ${devs0[0]} --dev1 ${devs1[0]} echo " >> PSoC6 i2s tests" ./psoc6/run_psoc6_tests.sh -c -s --dev0 ${devs0[0]} --dev1 ${devs1[0]} echo " >> PSoC6 bitstream tests" diff --git a/docs/psoc6/quickref.rst b/docs/psoc6/quickref.rst index 32d40fc0cdda..d6f3a9524843 100644 --- a/docs/psoc6/quickref.rst +++ b/docs/psoc6/quickref.rst @@ -536,60 +536,19 @@ The constructor can be called by passing the required arguments. All initializat Software SPI bus ---------------- -Software SPI (using bit-banging) works on all pins, and is accessed via the -:ref:`machine.SoftSPI ` class:: - - from machine import Pin, SoftSPI - - # construct a SoftSPI bus on the given pins - # polarity is the idle state of SCK - # phase=0 means sample on the first edge of SCK, phase=1 means the second edge - spi = SoftSPI(baudrate=100_000, polarity=1, phase=0, sck='P0_2', mosi='P0_0', miso='P0_1') - - spi.init(baudrate=200000) # set the baudrate - - spi.read(10) # read 10 bytes on MISO - spi.read(10, 0xff) # read 10 bytes while outputting 0xff on MOSI - - buf = bytearray(50) # create a buffer - spi.readinto(buf) # read into the given buffer (reads 50 bytes in this case) - spi.readinto(buf, 0xff) # read into the given buffer and output 0xff on MOSI - - spi.write(b'12345') # write 5 bytes on MOSI - - buf = bytearray(4) # create a buffer - spi.write_readinto(b'1234', buf) # write to MOSI and read from MISO into the buffer - spi.write_readinto(buf, buf) # write buf to MOSI and read MISO back into buf - -.. Warning:: - Currently *all* of ``sck``, ``mosi`` and ``miso`` *must* be specified when - initialising Software SPI. +The :ref:`machine.SoftSPI ` class is **disabled** in this port. Hardware SPI bus ---------------- -Hardware SPI works on the following listed pair of SPI pins. - -===== =========== ============ ============ -\ Default -===== =========== ============ ============ -MOSI P9_0 P6_0 P10_0 -MISO P9_1 P6_1 P10_1 -SCK P9_2 P6_2 P10_2 -===== =========== ============ ============ - -.. - TODO: This is only applicable to the CY8CPROTO-062-4343W. This does not belong here. - TODO: Define approach on how the user gets to know the pinout diagram, alternate function of each board - - From board manual? - - From datasheet? - - To create a pinout diagram? - Refer `PSoC 6 MCU: CY8C62x8, CY8C62xA Datasheet `_ -for additional details regarding all the SPI capable pins. The pins ``sck``, ``mosi`` and ``miso`` *must* be specified when -initialising Software SPI. +for details regarding all the SPI capable pins. The pins ``sck``, ``mosi`` and ``miso`` *must* be specified when +initialising SPI. The driver is accessed via :ref:`machine.SPI ` +.. note:: + Slave selection should be done at application end. An example of how to do so is explained :ref:`here ` + The constructor ^^^^^^^^^^^^^^^ An instance of the :mod:`machine.SPI` class can be created by invoking the constructor with all the @@ -599,28 +558,74 @@ SPI object is created with default settings or settings of previous initializati :: from machine import SPI - spi = SPI(0, sck='P11_2', mosi='P11_0', miso='P11_1') # Default assignment: id=0, SCK=P11_2 ,MOSI=P11_0, MISO=P11_1 - spi.init() + spi = SPI(baudrate=1000000, polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck='P6_2', mosi='P6_0', miso='P6_1') -Management of a CS signal should happen in user code (via machine.Pin class). +Methods +^^^^^^^ +All the methods(functions) given in :ref:`machine.SPI ` class have been implemented in this port. -:: - - from machine import Pin - cs = Pin('P9_3', mode=Pin.OUT, value=1) # Create chip-select on pin P9_3 - cs(0) # select the peripheral +Hardware SPI bus slave +---------------------- -Here, ``id=0`` should be passed mandatorily which selects the ``master`` mode operation. -If the constructor is called with any additional parameters then SPI object is created & initialised. +The PSoC6™ port offers an additional class to implement an SPI slave device. The SPI master node connected to the slave can exchange data over SPI. -:: - - spi = SPI(0, sck='P11_2', mosi='P11_0', miso='P11_1', baudrate=2000000) #object is created & initialised with baudrate=2000000 & default parameters - spi = SPI(0, baudrate=1500000, polarity=1, phase=1, bits=8, firstbit=SPI.LSB, sck='P11_2', mosi='P11_0', miso='P11_1') +.. warning:: + This is not part of the core MicroPython libraries. Therefore, not mapping any existing machine class API and neither supported by other ports. + +The constructor +^^^^^^^^^^^^^^^ + +.. class:: SPISlave(baudrate, polarity, phase, bits, firstbit, ssel, sck, mosi, miso) + + Constructs and returns a new SPI slave object using the following parameters. + + Required arguments: + - *ssel* should be pin name supporting SSEL functionality. + - *sck* should be a pin name supporting the SCK functionality. + - *mosi* should be a pin name supporting the MOSI functionality. + - *miso* should be a pin name supporting the MISO functionality. + + Optional arguments: + - *baudrate* should be an integer which sets the clock rate. If not passed, by default is set to 1000000 Hz. + - *polarity* can be 0 or 1. Default is set to 0. + - *phase* can be 0 or 1. Default set to 0. + - *bits* is width in bits for each transfer. Only 8 is supported. + - *firstbit* can be SPI.MSB or SPI.LSB. Default is SPI.MSB. + + Example: + :: + + from machine import SPISlave + + spi_slave = spi = SPI(baudrate=1000000, polarity=0, phase=0, bits=8, firstbit=SPI.MSB, ssel="P6_3", sck='P6_2', mosi='P6_0', miso='P6_1') Methods ^^^^^^^ -All the methods(functions) given in :ref:`machine.SPI ` class have been implemented in this port. + +.. method:: SPISlave.deinit() + + Deinitialises the SPI slave. + + +.. method:: SPISlave.write(buf) + + Write the bytes contained in ``buf``. + + Required arguments: + - *buf* should be a buffer with bytes of data to be written. + + Returns ``None``. + + +.. method:: SPISlave.read(buf) + + Reads the data in SPI bus to ``buf``. + + Required arguments: + - *buf* should be a buffer where data from bus needs to be stored. + + Returns ``None``. + Timers ------ diff --git a/ports/psoc6/boards/make-pins-csv.py b/ports/psoc6/boards/make-pins-csv.py index 2f58d7e90b16..7f4d720eaf6a 100644 --- a/ports/psoc6/boards/make-pins-csv.py +++ b/ports/psoc6/boards/make-pins-csv.py @@ -1,4 +1,5 @@ from __future__ import print_function +from itertools import islice import argparse import sys import csv @@ -50,7 +51,11 @@ def generate_pins_csv(pin_package_filename, pins_csv_filename): with open("./" + pins_csv_filename, "w", newline="") as csv_file: csv_writer = csv.writer(csv_file) csv_writer.writerows( - [[value, value] for value in enum_values if value.startswith("P")] + [ + [value, value] + for value in enum_values + if value.startswith("P") or value.startswith("N") + ] ) print("// pins.csv generated successfully") else: @@ -75,11 +80,18 @@ def generate_af_pins_csv(pin_package_filename, pins_af_csv_filename): # Extract enum values using regex pin_name = re.findall(r"\b(?!NC\b)(\w+)\s*=", enum_content) + # pin_name = re.findall(r"\b(\w+)\s*=", enum_content) pin_def = re.findall(r"=\s*(.*?\))", enum_content) + # pin_def.insert(0, "255") + # print(pin_def) + # Write enum values to a CSV file with open("./" + pins_af_csv_filename, "w", newline="") as csv_file: + NC_pin = ["NC", 255, "CYHAL_GET_GPIO(CYHAL_PORT_31, 7)"] # non-existent port csv_writer = csv.writer(csv_file) + csv_writer.writerow(NC_pin) for pname, pdef in zip(pin_name, pin_def): + # for pname, pdef in zip(islice(pin_name, 1, None), pin_def): # if pin_name[pname].startswith('P'): val = get_pin_addr_helper(pdef) csv_writer.writerow([pname, val, pdef.strip('"')]) diff --git a/ports/psoc6/machine_spi.c b/ports/psoc6/machine_spi.c index dcab82a39dc5..ff6eb29c518a 100644 --- a/ports/psoc6/machine_spi.c +++ b/ports/psoc6/machine_spi.c @@ -24,16 +24,28 @@ #define DEFAULT_SPI_PHASE (0) #define DEFAULT_SPI_BITS (8) #define DEFAULT_SPI_FIRSTBIT (0) // msb +#define DEFAULT_SPI_SSEL_PIN (MP_ROM_QSTR(MP_QSTR_NC)) +#define MASTER_MODE (0) +#define SLAVE_MODE (1) +#define spi_assert_raise_val(msg, ret) if (ret != CY_RSLT_SUCCESS) { \ + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT(msg), ret); \ +} + +#define spi_alloc_msg(pin_name, pin_obj, msg) if (pin_obj == NULL) { \ + size_t slen; \ + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT(msg), mp_obj_str_get_data(pin_name, &slen)); \ +} + typedef struct _machine_spi_obj_t { mp_obj_base_t base; cyhal_spi_t spi_obj; - uint8_t spi_id; uint8_t polarity; uint8_t phase; uint8_t bits; uint8_t firstbit; + machine_pin_phy_obj_t *ssel; machine_pin_phy_obj_t *sck; machine_pin_phy_obj_t *mosi; machine_pin_phy_obj_t *miso; @@ -42,11 +54,54 @@ typedef struct _machine_spi_obj_t { machine_spi_obj_t *spi_obj[MAX_SPI] = { NULL }; -static inline machine_spi_obj_t *spi_obj_alloc() { +// Function to select the mode +static cyhal_spi_mode_t spi_mode_select(uint8_t firstbit, uint8_t polarity, uint8_t phase) { + + cyhal_spi_mode_t mode; + if (firstbit == 1) { + if (polarity == 0) { + if (phase == 0) { + mode = CYHAL_SPI_MODE_00_LSB; + } else { + mode = CYHAL_SPI_MODE_01_LSB; + } + } else { + if (phase == 0) { + mode = CYHAL_SPI_MODE_10_LSB; + } else { + mode = CYHAL_SPI_MODE_11_LSB; + } + } + } else { + if (polarity == 0) { + if (phase == 0) { + mode = CYHAL_SPI_MODE_00_MSB; + } else { + mode = CYHAL_SPI_MODE_01_MSB; + } + } else { + if (phase == 0) { + mode = CYHAL_SPI_MODE_10_MSB; + } else { + mode = CYHAL_SPI_MODE_11_MSB; + } + } + } + return mode; +} + +static inline machine_spi_obj_t *spi_obj_alloc(bool is_slave) { for (uint8_t i = 0; i < MAX_SPI; i++) { if (spi_obj[i] == NULL) { - spi_obj[i] = mp_obj_malloc(machine_spi_obj_t, &machine_spi_type); + + const mp_obj_type_t *obj_type; + if (is_slave) { + obj_type = &machine_spi_slave_type; + } else { + obj_type = &machine_spi_type; + } + spi_obj[i] = mp_obj_malloc(machine_spi_obj_t, obj_type); return spi_obj[i]; } } @@ -65,122 +120,84 @@ static inline void spi_obj_free(machine_spi_obj_t *spi_obj_ptr) { static inline void spi_sck_alloc(machine_spi_obj_t *spi_obj, mp_obj_t pin_name) { machine_pin_phy_obj_t *sck = pin_phy_realloc(pin_name, PIN_PHY_FUNC_SPI); - - if (sck == NULL) { - size_t slen; - mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("SCK pin (%s) not found !"), mp_obj_str_get_data(pin_name, &slen)); - } - + spi_alloc_msg(pin_name, sck, "SCK pin (%s) not found !"); spi_obj->sck = sck; } -static inline void spi_sck_free(machine_spi_obj_t *spi_obj) { - pin_phy_free(spi_obj->sck); +static inline void spi_ssel_alloc(machine_spi_obj_t *spi_obj, mp_obj_t pin_name) { + machine_pin_phy_obj_t *ssel = pin_phy_realloc(pin_name, PIN_PHY_FUNC_SPI); + spi_alloc_msg(pin_name, ssel, "SSEL pin (%s) not found !"); + spi_obj->ssel = ssel; } static inline void spi_mosi_alloc(machine_spi_obj_t *spi_obj, mp_obj_t pin_name) { machine_pin_phy_obj_t *mosi = pin_phy_realloc(pin_name, PIN_PHY_FUNC_SPI); - - if (mosi == NULL) { - size_t slen; - mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("MOSI pin (%s) not found !"), mp_obj_str_get_data(pin_name, &slen)); - } - + spi_alloc_msg(pin_name, mosi, "MOSI pin (%s) not found !"); spi_obj->mosi = mosi; } -static inline void spi_mosi_free(machine_spi_obj_t *spi_obj) { - pin_phy_free(spi_obj->mosi); -} - static inline void spi_miso_alloc(machine_spi_obj_t *spi_obj, mp_obj_t pin_name) { machine_pin_phy_obj_t *miso = pin_phy_realloc(pin_name, PIN_PHY_FUNC_SPI); - - if (miso == NULL) { - size_t slen; - mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("MISO pin (%s) not found !"), mp_obj_str_get_data(pin_name, &slen)); - } - + spi_alloc_msg(pin_name, miso, "MISO pin (%s) not found !"); spi_obj->miso = miso; } +static inline void spi_sck_free(machine_spi_obj_t *spi_obj) { + pin_phy_free(spi_obj->sck); +} +static inline void spi_ssel_free(machine_spi_obj_t *spi_obj) { + pin_phy_free(spi_obj->ssel); +} +static inline void spi_mosi_free(machine_spi_obj_t *spi_obj) { + pin_phy_free(spi_obj->mosi); +} static inline void spi_miso_free(machine_spi_obj_t *spi_obj) { pin_phy_free(spi_obj->miso); } -// Function to select the mode -static cyhal_spi_mode_t mode_select(uint8_t firstbit, uint8_t polarity, uint8_t phase) { - - cyhal_spi_mode_t mode; - if (firstbit == 1) { - if (polarity == 0) { - if (phase == 0) { - mode = CYHAL_SPI_MODE_00_LSB; - } else { - mode = CYHAL_SPI_MODE_01_LSB; - } - } else { - if (phase == 0) { - mode = CYHAL_SPI_MODE_10_LSB; - } else { - mode = CYHAL_SPI_MODE_11_LSB; - } - } - } else { - if (polarity == 0) { - if (phase == 0) { - mode = CYHAL_SPI_MODE_00_MSB; - } else { - mode = CYHAL_SPI_MODE_01_MSB; - } - } else { - if (phase == 0) { - mode = CYHAL_SPI_MODE_10_MSB; - } else { - mode = CYHAL_SPI_MODE_11_MSB; - } - } - } - return mode; +static inline void spi_init(machine_spi_obj_t *machine_spi_obj, int spi_mode) { + cyhal_spi_mode_t mode = spi_mode_select(machine_spi_obj->firstbit, machine_spi_obj->polarity, machine_spi_obj->phase); + // set the baudrate + cyhal_spi_set_frequency(&machine_spi_obj->spi_obj, machine_spi_obj->baudrate); + // Initialise the SPI peripheral if any arguments given, or it was not initialised previously. + cy_rslt_t result = cyhal_spi_init(&machine_spi_obj->spi_obj, machine_spi_obj->mosi->addr, machine_spi_obj->miso->addr, machine_spi_obj->sck->addr, machine_spi_obj->ssel->addr, NULL, machine_spi_obj->bits, mode, spi_mode); + spi_assert_raise_val("SPI initialisation failed with return code %x !", result); } static void machine_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { machine_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_printf(print, "SPI(id=%u, baudrate=%u, polarity=%u, phase=%u, bits=%u, firstbit=%u, sck=%d, mosi=%d, miso=%d)", - self->spi_id, self->baudrate, self->polarity, + mp_printf(print, "SPI(baudrate=%u, polarity=%u, phase=%u, bits=%u, firstbit=%u, ssel=%d, sck=%d, mosi=%d, miso=%d)", + self->baudrate, self->polarity, + self->phase, self->bits, self->firstbit, + self->ssel->addr, self->sck->addr, self->mosi->addr, self->miso->addr); +} + + +static void machine_spi_slave_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + machine_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_printf(print, "SPISlave(baudrate=%u, polarity=%u, phase=%u, bits=%u, firstbit=%u, ssel=%d, sck=%d, mosi=%d, miso=%d)", + self->baudrate, self->polarity, self->phase, self->bits, self->firstbit, - self->sck->addr, self->mosi->addr, self->miso->addr); + self->ssel->addr, self->sck->addr, self->mosi->addr, self->miso->addr); } -mp_obj_t machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - enum { ARG_id, ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits, ARG_firstbit, ARG_sck, ARG_mosi, ARG_miso }; +mp_obj_t machine_spi_init_helper(machine_spi_obj_t *self, int spi_mode, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits, ARG_firstbit, ARG_ssel, ARG_sck, ARG_mosi, ARG_miso }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_id, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = DEFAULT_SPI_BAUDRATE} }, { MP_QSTR_polarity, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = DEFAULT_SPI_POLARITY} }, { MP_QSTR_phase, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = DEFAULT_SPI_PHASE} }, { MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = DEFAULT_SPI_BITS} }, { MP_QSTR_firstbit, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = DEFAULT_SPI_FIRSTBIT} }, + { MP_QSTR_ssel, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = DEFAULT_SPI_SSEL_PIN}}, { MP_QSTR_sck, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, { MP_QSTR_mosi, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, { MP_QSTR_miso, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, }; - // Parse the arguments. mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - // Get the SPI bus id. - // There are no separate spi blocks. Now id is used to identify the master mode - int spi_id = mp_obj_get_int(args[ARG_id].u_obj); - - if (spi_id != 0) { - mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("SPI(%d) doesn't exist"), spi_id); - } - - // Get static peripheral object. - machine_spi_obj_t *self = spi_obj_alloc(); - // set baudrate if provided if (args[ARG_baudrate].u_int != -1) { self->baudrate = args[ARG_baudrate].u_int; @@ -206,7 +223,23 @@ mp_obj_t machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n self->firstbit = args[ARG_firstbit].u_int; } - // Set SCK/MOSI/MISO pins if configured. + // Set SSEL/SCK/MOSI/MISO pins if configured. + if (spi_mode == MASTER_MODE) { + if (args[ARG_ssel].u_obj != DEFAULT_SPI_SSEL_PIN) { + mp_raise_TypeError(MP_ERROR_TEXT("SSEL pin cannot be provided in master constructor!")); + } else { + spi_ssel_alloc(self, DEFAULT_SPI_SSEL_PIN); + } + } else if (spi_mode == SLAVE_MODE) { + if ((args[ARG_ssel].u_obj != DEFAULT_SPI_SSEL_PIN)) { + spi_ssel_alloc(self, args[ARG_ssel].u_obj); + } else { + mp_raise_TypeError(MP_ERROR_TEXT("SSEL pin must be provided in slave mode")); + } + } else { + mp_raise_TypeError(MP_ERROR_TEXT("SPI should either be in master or slave mode!")); + } + if (args[ARG_sck].u_obj != mp_const_none) { spi_sck_alloc(self, args[ARG_sck].u_obj); } else { @@ -226,99 +259,76 @@ mp_obj_t machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n } if (n_args > 1 || n_kw > 0) { - cyhal_spi_mode_t mode = mode_select(self->firstbit, self->polarity, self->phase); - // set the baudrate - cyhal_spi_set_frequency(&self->spi_obj, self->baudrate); - // Initialise the SPI peripheral if any arguments given, or it was not initialised previously. - cy_rslt_t result = cyhal_spi_init(&self->spi_obj, self->mosi->addr, self->miso->addr, self->sck->addr, NC, NULL, self->bits, mode, false); - if (result != CY_RSLT_SUCCESS) { - mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("SPI initialisation failed with return code %lx !"), result); - } + spi_init(self, spi_mode); } return MP_OBJ_FROM_PTR(self); } -static void machine_spi_init(mp_obj_base_t *self_in, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits, ARG_firstbit }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, - { MP_QSTR_polarity, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, - { MP_QSTR_phase, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, - { MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, - { MP_QSTR_firstbit, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, - }; - - // Parse the arguments. - machine_spi_obj_t *self = (machine_spi_obj_t *)self_in; - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - // Reconfigure the baudrate if requested. - if (args[ARG_baudrate].u_int != -1) { - self->baudrate = args[ARG_baudrate].u_int; - cyhal_spi_set_frequency(&self->spi_obj, self->baudrate); - } - - if (args[ARG_polarity].u_int != -1) { - self->polarity = args[ARG_polarity].u_int; - } - - if (args[ARG_phase].u_int != -1) { - self->phase = args[ARG_phase].u_int; - } - - if (args[ARG_bits].u_int != -1) { - self->bits = args[ARG_bits].u_int; +mp_obj_t machine_spi_master_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + machine_spi_obj_t *self = spi_obj_alloc(false); + if (n_kw > 1) { + machine_spi_init_helper(self, MASTER_MODE, n_args, n_kw, all_args); + } else { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Master init failed as all required arguments not passed!")); } + return MP_OBJ_FROM_PTR(self); +} - if (args[ARG_firstbit].u_int != -1) { - self->firstbit = args[ARG_firstbit].u_int; +mp_obj_t machine_spi_slave_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + machine_spi_obj_t *self = spi_obj_alloc(true); + if (n_kw > 1) { + machine_spi_init_helper(self, SLAVE_MODE, n_args, n_kw, all_args); + } else { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Slave init failed as all required arguments not passed!")); } + return MP_OBJ_FROM_PTR(self); +} - cyhal_spi_mode_t mode = mode_select(self->firstbit, self->polarity, self->phase); - - // since it's reinitialising, first it should be deinitialised & initilased with new parameters - cyhal_spi_free(&self->spi_obj); - - cy_rslt_t result = cyhal_spi_init(&self->spi_obj, self->mosi->addr, self->miso->addr, self->sck->addr, NC, NULL, self->bits, mode, false); - if (result != CY_RSLT_SUCCESS) { - mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("SPI initialisation failed with return code %lx !"), result); - } +static void machine_spi_init(mp_obj_base_t *self_in, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + 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]); - if (result != CY_RSLT_SUCCESS) { - mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("cyhal_spi_send 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)); - if (result != CY_RSLT_SUCCESS) { - mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("cyhal_spi_recv 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; + + cyhal_spi_clear(&self->spi_obj); + + // write + if (rx == NULL) { + tx_buf = tx; + memset(rx_temp_buf, 0x01, len * sizeof(uint8_t)); + rx_buf = rx_temp_buf; } else { - result = cyhal_spi_transfer(&self->spi_obj, src, len, dest, len, 0xFF); - if (result != CY_RSLT_SUCCESS) { - mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("cyhal_spi_transf failed with return code %lx !"), result); + // read(), readinto() and write_readinto() with tx and rx same buffers + 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]; + } + // write_readinto() with tx and rx different buffers + else { + tx_buf = tx; + rx_buf = rx; } } - + 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); } + static void machine_spi_deinit(mp_obj_base_t *self_in) { machine_spi_obj_t *self = (machine_spi_obj_t *)self_in; + cyhal_spi_clear(&self->spi_obj); cyhal_spi_free(&self->spi_obj); spi_sck_free(self); + spi_ssel_free(self); spi_mosi_free(self); spi_miso_free(self); spi_obj_free(self); @@ -334,12 +344,91 @@ MP_DEFINE_CONST_OBJ_TYPE( machine_spi_type, MP_QSTR_SPI, MP_TYPE_FLAG_NONE, - make_new, machine_spi_make_new, + make_new, machine_spi_master_make_new, print, machine_spi_print, protocol, &machine_spi_p, locals_dict, &mp_machine_spi_locals_dict ); +#if MICROPY_PY_MACHINE_SPI_SLAVE + +static mp_obj_t machine_spi_slave_deinit(mp_obj_t self_in) { + mp_obj_base_t *self = MP_OBJ_TO_PTR(self_in); + machine_spi_deinit(self); + return mp_const_none; +} +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) { + cy_rslt_t result; + 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_WRITE); + uint16_t len = bufinfo.len; + uint8_t tx_dummy[len]; + memset(tx_dummy, 0x02, len * sizeof(uint8_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); + +static mp_obj_t machine_spi_slave_write(mp_obj_t self_in, mp_obj_t buf_in) { + cy_rslt_t result; + 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); + uint16_t len = bufinfo.len; + uint8_t rx_dummy[len]; + memset(rx_dummy, 0x01, len * sizeof(uint8_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_WRITE); + 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) }, + // constants + { MP_ROM_QSTR(MP_QSTR_MSB), MP_ROM_INT(MICROPY_PY_MACHINE_SPISLAVE_MSB) }, + { MP_ROM_QSTR(MP_QSTR_LSB), MP_ROM_INT(MICROPY_PY_MACHINE_SPISLAVE_LSB) }, +}; +static MP_DEFINE_CONST_DICT(machine_spi_slave_locals_dict, machine_spi_slave_locals_dict_table); + + +MP_DEFINE_CONST_OBJ_TYPE( + machine_spi_slave_type, + MP_QSTR_SPISlave, + MP_TYPE_FLAG_NONE, + make_new, machine_spi_slave_make_new, + print, machine_spi_slave_print, + locals_dict, &machine_spi_slave_locals_dict + ); + +#endif + void mod_spi_deinit() { for (uint8_t i = 0; i < MAX_SPI; i++) { if (spi_obj[i] != NULL) { diff --git a/ports/psoc6/modmachine.c b/ports/psoc6/modmachine.c index d3d21d91e3ce..9fe706ea5b6c 100644 --- a/ports/psoc6/modmachine.c +++ b/ports/psoc6/modmachine.c @@ -321,20 +321,12 @@ MP_DEFINE_CONST_FUN_OBJ_0(machine_rng_obj, machine_rng); { MP_ROM_QSTR(MP_QSTR_PWRON_RESET), MP_ROM_INT(MACHINE_PWRON_RESET) }, \ \ /* Modules */ \ - { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_i2c_type) }, \ - { MP_ROM_QSTR(MP_QSTR_SoftI2C), MP_ROM_PTR(&mp_machine_soft_i2c_type) }, \ { MP_ROM_QSTR(MP_QSTR_I2CSlave), MP_ROM_PTR(&machine_i2c_slave_type) }, \ { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) }, \ - { MP_ROM_QSTR(MP_QSTR_Signal), MP_ROM_PTR(&machine_signal_type) }, \ { MP_ROM_QSTR(MP_QSTR_RTC), MP_ROM_PTR(&machine_rtc_type) }, \ - { MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&machine_pwm_type) }, \ - { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_spi_type) }, \ - { MP_ROM_QSTR(MP_QSTR_SoftSPI), MP_ROM_PTR(&mp_machine_soft_spi_type) }, \ + { MP_ROM_QSTR(MP_QSTR_SPISlave), MP_ROM_PTR(&machine_spi_slave_type) }, \ { MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&machine_timer_type) }, \ { MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&machine_adc_type) }, \ { MP_ROM_QSTR(MP_QSTR_ADCBlock), MP_ROM_PTR(&machine_adcblock_type) }, \ - { MP_ROM_QSTR(MP_QSTR_I2S), MP_ROM_PTR(&machine_i2s_type) }, \ - { MP_ROM_QSTR(MP_QSTR_WDT), MP_ROM_PTR(&machine_wdt_type) }, \ - #endif // MICROPY_PY_MACHINE diff --git a/ports/psoc6/modmachine.h b/ports/psoc6/modmachine.h index 10516bd03160..4e4567c5679e 100644 --- a/ports/psoc6/modmachine.h +++ b/ports/psoc6/modmachine.h @@ -12,6 +12,7 @@ extern const mp_obj_type_t machine_pin_type; extern const mp_obj_type_t machine_rtc_type; extern const mp_obj_type_t machine_pwm_type; extern const mp_obj_type_t machine_spi_type; +extern const mp_obj_type_t machine_spi_slave_type; extern const mp_obj_type_t machine_timer_type; extern const mp_obj_type_t machine_adc_type; extern const mp_obj_type_t machine_wdt_type; diff --git a/ports/psoc6/mpconfigport.h b/ports/psoc6/mpconfigport.h index a806391c1c5e..3f5edf264df9 100644 --- a/ports/psoc6/mpconfigport.h +++ b/ports/psoc6/mpconfigport.h @@ -127,9 +127,12 @@ #define MICROPY_PY_MACHINE_WDT_INCLUDEFILE "ports/psoc6/machine_wdt.c" #define MICROPY_PY_MACHINE_SPI (1) +#define MICROPY_PY_MACHINE_SPI_SLAVE (1) #define MICROPY_PY_MACHINE_SPI_MSB (0) #define MICROPY_PY_MACHINE_SPI_LSB (1) -#define MICROPY_PY_MACHINE_SOFTSPI (1) +#define MICROPY_PY_MACHINE_SPISLAVE_MSB (0) +#define MICROPY_PY_MACHINE_SPISLAVE_LSB (1) +#define MICROPY_PY_MACHINE_SOFTSPI (0) #define MICROPY_PY_MACHINE_I2S (1) #define MICROPY_PY_MACHINE_I2S_MCK (0) diff --git a/tests/psoc6/hw_ext/adc.py b/tests/psoc6/hw_ext/adc.py index 6a9355bd135b..4d5d9e18d4df 100644 --- a/tests/psoc6/hw_ext/adc.py +++ b/tests/psoc6/hw_ext/adc.py @@ -16,13 +16,15 @@ # Allocate pin based on board machine = os.uname().machine if "CY8CPROTO-062-4343W" in machine: - adc_pin_gnd = "P10_1" + adc_pin_gnd = "P10_4" adc_pin_mid = "P10_3" - adc_pin_max = "P10_0" + adc_mid_chan = 3 + adc_pin_max = "P10_2" adc_wrong_pin_name = "P13_7" elif "CY8CPROTO-063-BLE" in machine: adc_pin_gnd = "P10_2" adc_pin_mid = "P10_3" + adc_mid_chan = 3 adc_pin_max = "P10_4" adc_wrong_pin_name = "P13_7" @@ -72,7 +74,7 @@ def validate_adc_raw_value(adc_pin, exp_volt, act_volt): # ADCBlock.connect(channel,source) block = ADCBlock(0, bits=12) -adc1 = block.connect(3, adc_pin_mid) +adc1 = block.connect(adc_mid_chan, adc_pin_mid) adc2 = ADC(adc_pin_max, sample_ns=1000) diff --git a/tests/psoc6/hw_ext/i2c.py b/tests/psoc6/hw_ext/i2c.py index 0587baa015e1..52338cdcb656 100644 --- a/tests/psoc6/hw_ext/i2c.py +++ b/tests/psoc6/hw_ext/i2c.py @@ -11,8 +11,8 @@ # Allocate pin based on board machine = os.uname().machine if "CY8CPROTO-062-4343W" in machine: - scl_master_pin = "P6_0" - sda_master_pin = "P6_1" + scl_master_pin = "P10_0" + sda_master_pin = "P10_1" scl_master_soft_pin = "P9_5" sda_master_soft_pin = "P9_3" scl_slave_pin = "P9_0" diff --git a/tests/psoc6/hw_ext/img/cy8cproto-062-4343w-hil-test-diag.png b/tests/psoc6/hw_ext/img/cy8cproto-062-4343w-hil-test-diag.png index d4995962f89e..065499418feb 100644 Binary files a/tests/psoc6/hw_ext/img/cy8cproto-062-4343w-hil-test-diag.png and b/tests/psoc6/hw_ext/img/cy8cproto-062-4343w-hil-test-diag.png differ diff --git a/tests/psoc6/hw_ext/img/cy8cproto-063-ble-hil-test-diag.png b/tests/psoc6/hw_ext/img/cy8cproto-063-ble-hil-test-diag.png index d152188fb826..feccae7bec2e 100644 Binary files a/tests/psoc6/hw_ext/img/cy8cproto-063-ble-hil-test-diag.png and b/tests/psoc6/hw_ext/img/cy8cproto-063-ble-hil-test-diag.png differ diff --git a/tests/psoc6/bitstream/bitstream_rx.py b/tests/psoc6/hw_ext/multi_stub/bitstream_rx.py similarity index 100% rename from tests/psoc6/bitstream/bitstream_rx.py rename to tests/psoc6/hw_ext/multi_stub/bitstream_rx.py diff --git a/tests/psoc6/bitstream/bitstream_rx.py.exp b/tests/psoc6/hw_ext/multi_stub/bitstream_rx.py.exp similarity index 100% rename from tests/psoc6/bitstream/bitstream_rx.py.exp rename to tests/psoc6/hw_ext/multi_stub/bitstream_rx.py.exp diff --git a/tests/psoc6/bitstream/bitstream_tx.py b/tests/psoc6/hw_ext/multi_stub/bitstream_tx.py similarity index 100% rename from tests/psoc6/bitstream/bitstream_tx.py rename to tests/psoc6/hw_ext/multi_stub/bitstream_tx.py diff --git a/tests/psoc6/hw_ext/multi_blocking/i2s_rx.py b/tests/psoc6/hw_ext/multi_stub/i2s_rx.py similarity index 100% rename from tests/psoc6/hw_ext/multi_blocking/i2s_rx.py rename to tests/psoc6/hw_ext/multi_stub/i2s_rx.py diff --git a/tests/psoc6/hw_ext/multi_blocking/i2s_rx.py.exp b/tests/psoc6/hw_ext/multi_stub/i2s_rx.py.exp similarity index 100% rename from tests/psoc6/hw_ext/multi_blocking/i2s_rx.py.exp rename to tests/psoc6/hw_ext/multi_stub/i2s_rx.py.exp diff --git a/tests/psoc6/hw_ext/multi_blocking/i2s_tx.py b/tests/psoc6/hw_ext/multi_stub/i2s_tx.py similarity index 100% rename from tests/psoc6/hw_ext/multi_blocking/i2s_tx.py rename to tests/psoc6/hw_ext/multi_stub/i2s_tx.py diff --git a/tests/psoc6/hw_ext/multi_stub/spi_master.py b/tests/psoc6/hw_ext/multi_stub/spi_master.py new file mode 100644 index 000000000000..e6ce93ec3d3e --- /dev/null +++ b/tests/psoc6/hw_ext/multi_stub/spi_master.py @@ -0,0 +1,110 @@ +import binascii +import time +import os + +try: + from machine import Pin, SPI +except ImportError: + print("SKIP") + raise SystemExit + +machine = os.uname().machine +if "CY8CPROTO-062-4343W" in machine: + # 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" +if "CY8CPROTO-063-BLE" in machine: + # Allocate pin based on board + sck_master_pin = "P9_2" + mosi_master_pin = "P9_0" + miso_master_pin = "P9_1" + ssel_master_pin = "P9_3" + +# 0. Construct SPI object +spi_obj = SPI( + baudrate=1000000, + polarity=0, + phase=0, + bits=8, + firstbit=SPI.MSB, + sck=sck_master_pin, + mosi=mosi_master_pin, + miso=miso_master_pin, +) +cs = Pin(ssel_master_pin, Pin.OUT, value=1) + +# 1. write() read() validation +# - Master: write() a data set to the slave. +# - Slave: waits and read() data set. +# - Slave: increase all data set bytes by 1. +# - Slave: write() the modified data to the master. + +tx_buf = b"\x08\x06\x04\x02\x07\x05\x03\x01" + +cs.low() +spi_obj.write(tx_buf) +cs.high() + +time.sleep_ms(500) # ensure slave has replied +rx_buf = bytearray(8) +cs.low() +rx_buf = spi_obj.read(8) +cs.high() + +exp_rx = b"\t\x07\x05\x03\x08\x06\x04\x02" +print("master write() and read() (tx_buf + 1): ", exp_rx == rx_buf) + +# 2. readinto() validation +# - Slave: increase once again all data set bytes by 1. +# - Slave: write() the modified data set to the master. +# - Master: waits and readinto() the modified data set. + +time.sleep_ms(500) # ensure slave has replied +rx_buf = bytearray(8) +cs.low() +spi_obj.readinto(rx_buf) +cs.high() + +exp_rx = b"\n\x08\x06\x04\t\x07\x05\x03" +print("master readinto() (tx_buf + 2):", exp_rx == rx_buf) + +# 3. write_readinto() read validation +# - Slave: increase once again all data set bytes by 1. +# - Slave: write() the modified data set to the master. +# - Master: waits and readinto() the data set (written data set is not processed). + +time.sleep_ms(200) +rx_buf = bytearray(8) +cs.low() +spi_obj.write_readinto(tx_buf, rx_buf) +cs.high() + +exp_rx = b"\x0b\t\x07\x05\n\x08\x06\x04" +print("master write_readinto() (tx_buf + 3): ", exp_rx == rx_buf) + +# 4. write_readinto() write validation +# - Master: write_readinto() a data set to the slave (read data is ignored). +# - Slave: waits and read() data set. +# - Slave: decreases all data set bytes by 1. +# - Slave: write() the modified data set to the master. +# - Master: waits and read() the modified data set. + +tx_buf = b"\x01\x02\x03\x04\x05\x06\x07\x08" +cs.low() +spi_obj.write_readinto(tx_buf, rx_buf) +cs.high() + +time.sleep_ms(500) # ensure slave has replied +rx_buf = bytearray(8) +cs.low() +rx_buf = spi_obj.read(8) +cs.high() + +exp_rx = b"\x00\x01\x02\x03\x04\x05\x06\x07" +print("master write_readinto() and read() (tx_buf - 1): ", exp_rx == rx_buf) + +# 5. SPI object deinit +spi_obj.deinit() +cs.deinit diff --git a/tests/psoc6/hw_ext/multi_stub/spi_master.py.exp b/tests/psoc6/hw_ext/multi_stub/spi_master.py.exp new file mode 100644 index 000000000000..43f51d5b7567 --- /dev/null +++ b/tests/psoc6/hw_ext/multi_stub/spi_master.py.exp @@ -0,0 +1,4 @@ +master write() and read() (tx_buf + 1): True +master readinto() (tx_buf + 2): True +master write_readinto() (tx_buf + 3): True +master write_readinto() and read() (tx_buf - 1): True diff --git a/tests/psoc6/hw_ext/multi_stub/spi_slave.py b/tests/psoc6/hw_ext/multi_stub/spi_slave.py new file mode 100644 index 000000000000..e52f8a76b701 --- /dev/null +++ b/tests/psoc6/hw_ext/multi_stub/spi_slave.py @@ -0,0 +1,73 @@ +import binascii +import time +import os + +try: + from machine import Pin, SPI, SPISlave +except ImportError: + print("SKIP") + raise SystemExit + + # Allocate pin based on board +machine = os.uname().machine +if "CY8CPROTO-062-4343W" in machine: + sck_slave_pin = "P6_2" + mosi_slave_pin = "P6_0" + miso_slave_pin = "P6_1" + ssel_slave_pin = "P6_3" + +if "CY8CPROTO-063-BLE" in machine: + # Allocate pin based on board + sck_slave_pin = "P9_2" + mosi_slave_pin = "P9_0" + miso_slave_pin = "P9_1" + ssel_slave_pin = "P9_3" + + +def data_increase_by_one(buf): + for i in range(len(buf)): + buf[i] += 1 + + +def data_decrease_by_one(buf): + for i in range(len(buf)): + buf[i] -= 1 + + +# 0. Construct SPI Slave obj +spi_obj = SPISlave( + baudrate=1000000, + polarity=0, + phase=0, + bits=8, + firstbit=SPISlave.MSB, + ssel=ssel_slave_pin, + sck=sck_slave_pin, + mosi=mosi_slave_pin, + miso=miso_slave_pin, +) + +# 1. Reply for master write() read() validation +rx_buf = bytearray(8) +spi_obj.read(rx_buf) + +data_increase_by_one(rx_buf) +spi_obj.write(rx_buf) + +# 2. Reply for master readinto() validation +data_increase_by_one(rx_buf) +spi_obj.write(rx_buf) + +# 3. Reply for write_readinto() read validation +data_increase_by_one(rx_buf) +spi_obj.write(rx_buf) + +# 4. Reply write_readinto() write validation +rx_buf = bytearray(8) +spi_obj.read(rx_buf) + +data_decrease_by_one(rx_buf) +spi_obj.write(rx_buf) + +# 5. SPI Slave object deinit +spi_obj.deinit() diff --git a/tests/psoc6/run_psoc6_tests.sh b/tests/psoc6/run_psoc6_tests.sh index 6a711427ab4f..61aa8a8aeb31 100755 --- a/tests/psoc6/run_psoc6_tests.sh +++ b/tests/psoc6/run_psoc6_tests.sh @@ -20,6 +20,8 @@ usage() { echo " -v run virtual filesystem related tests. If followed by -x, runs advance tests too." echo " -b run bitsream script." echo " -s run i2s tests." + echo " -r run spi tests." + echo " -u run i2c tests." echo " --dev0 device to be used" echo " --dev1 second device to be used (for multi test)" echo " --psoc6 run only psoc6 port related tests" @@ -43,7 +45,7 @@ for arg in "$@"; do esac done -while getopts "abcd:e:fhimnpqtwvxs" o; do +while getopts "abcd:e:fhimnpqtuwvxspr" o; do case "${o}" in a) all=1 @@ -81,6 +83,9 @@ while getopts "abcd:e:fhimnpqtwvxs" o; do q) psoc6WdtOnly=1 ;; + r) + spi=1 + ;; w) wifi=1 ;; @@ -93,6 +98,9 @@ while getopts "abcd:e:fhimnpqtwvxs" o; do t) hwext=1 ;; + u) + i2c=1 + ;; s) i2s=1 ;; @@ -112,11 +120,11 @@ fi if [ -z "${device0}" ]; then - device0="/dev/ttyACM0" + device0="/dev/ttyACM7" fi if [ -z "${device1}" ]; then - device1="/dev/ttyACM1" + device1="/dev/ttyACM6" fi if [ -z "${failing}" ]; then @@ -166,10 +174,18 @@ if [ -z "${hwext}" ]; then hwext=0 fi +if [ -z "${i2c}" ]; then + i2c=0 +fi + if [ -z "${i2s}" ]; then i2s=0 fi +if [ -z "${spi}" ]; then + spi=0 +fi + resultsFile="psoc6_test_results.log" passResultsFile="psoc6_test_passed.log" @@ -468,6 +484,22 @@ if [ ${hwext} -eq 1 ]; then echo ./run-tests.py --target psoc6 --device ${device0} -d psoc6/hw_ext \ + \ + -e psoc6/hw_ext/i2c.py \ + | tee -a ${resultsFile} + + echo + echo " done." + echo + +fi + +if [ ${i2c} -eq 1 ]; then + + echo " running i2c extended tests ..." + echo + + ./run-tests.py --target psoc6 --device ${device0} psoc6/hw_ext/i2c.py \ | tee -a ${resultsFile} echo @@ -482,13 +514,30 @@ if [ ${bitstream} -eq 1 ]; then echo " running bitstream tests ... " echo - ../tools/mpremote/mpremote.py connect ${device1} run --no-follow psoc6/bitstream/bitstream_tx.py + ../tools/mpremote/mpremote.py connect ${device1} run --no-follow psoc6/hw_ext/multi_stub/bitstream_tx.py echo " running bitstream listen.." ./run-tests.py --target psoc6 --device ${device0} \ \ - psoc6/bitstream/bitstream_rx.py \ + psoc6/hw_ext/multi_stub/bitstream_rx.py \ + |tee -a ${resultsFile} + +fi + +if [ ${spi} -eq 1 ]; then + + echo " running spi tests ... " + echo + + echo " running spi slave device test..." + ../tools/mpremote/mpremote.py connect ${device1} run --no-follow psoc6/hw_ext/multi_stub/spi_slave.py + + echo " running spi master device test..." + + ./run-tests.py --target psoc6 --device ${device0} \ + \ + psoc6/hw_ext/multi_stub/spi_master.py \ |tee -a ${resultsFile} fi @@ -500,13 +549,13 @@ if [ ${i2s} -eq 1 ]; then echo " running stand-alone i2s tx" - ../tools/mpremote/mpremote.py connect ${device0} run --no-follow psoc6/hw_ext/multi_blocking/i2s_tx.py + ../tools/mpremote/mpremote.py connect ${device0} run --no-follow psoc6/hw_ext/multi_stub/i2s_tx.py echo " running i2s receive tests..." ./run-tests.py --target psoc6 --device ${device1} \ \ - psoc6/hw_ext/multi_blocking/i2s_rx.py \ + psoc6/hw_ext/multi_stub/i2s_rx.py \ |tee -a ${resultsFile} fi diff --git a/tests/psoc6/spi_hard.py b/tests/psoc6/spi_hard.py deleted file mode 100644 index ed27e30c29ae..000000000000 --- a/tests/psoc6/spi_hard.py +++ /dev/null @@ -1,4 +0,0 @@ -from machine import SPI - -spi = SPI(0, sck="P9_2", mosi="P9_0", miso="P9_1") -print(spi) diff --git a/tests/psoc6/spi_hard.py.exp b/tests/psoc6/spi_hard.py.exp deleted file mode 100644 index d2782f34b5f8..000000000000 --- a/tests/psoc6/spi_hard.py.exp +++ /dev/null @@ -1 +0,0 @@ -SPI(id=0, baudrate=1000000, polarity=0, phase=0, bits=8, firstbit=0, sck=74, mosi=72, miso=73) diff --git a/tests/psoc6/spi_soft.py b/tests/psoc6/spi_soft.py deleted file mode 100644 index fe94eadb4e52..000000000000 --- a/tests/psoc6/spi_soft.py +++ /dev/null @@ -1,19 +0,0 @@ -#### SoftSPI -import os -from machine import SoftSPI - -# Allocate pin based on board -machine = os.uname().machine -if "CY8CPROTO-062-4343W" in machine: - sck_pin = "P9_2" - mosi_pin = "P9_0" - miso_pin = "P9_1" -elif "CY8CPROTO-063-BLE" in machine: - sck_pin = "P9_2" - mosi_pin = "P9_0" - miso_pin = "P9_1" - -spi = SoftSPI(baudrate=100000, polarity=1, phase=0, sck=sck_pin, mosi=mosi_pin, miso=miso_pin) -print(spi) -spi.init(baudrate=200000) -print(spi) diff --git a/tests/psoc6/spi_soft.py.exp b/tests/psoc6/spi_soft.py.exp deleted file mode 100644 index 5f5eb05fd4e1..000000000000 --- a/tests/psoc6/spi_soft.py.exp +++ /dev/null @@ -1,2 +0,0 @@ -SoftSPI(baudrate=100000, polarity=1, phase=0, sck=74, mosi=72, miso=73) -SoftSPI(baudrate=166666, polarity=1, phase=0, sck=74, mosi=72, miso=73) diff --git a/tools/psoc6/ifx-mpy-hil-devs.yml b/tools/psoc6/ifx-mpy-hil-devs.yml index aa529a7c41d6..bcd32a46c9da 100644 --- a/tools/psoc6/ifx-mpy-hil-devs.yml +++ b/tools/psoc6/ifx-mpy-hil-devs.yml @@ -1,12 +1,12 @@ - board_type: CY8CPROTO-062-4343W board_list: - sn: 072002F302098400 - hw_ext: 0.3.0.a + hw_ext: 0.4.0.a - sn: 1C14031D03201400 - hw_ext: 0.3.0.b + hw_ext: 0.4.0.b - board_type: CY8CPROTO-063-BLE board_list: - sn: 100D0F1400052400 - hw_ext: 0.3.0.b + hw_ext: 0.4.0.b - sn: 03180F1400052400 - hw_ext: 0.3.0.a \ No newline at end of file + hw_ext: 0.4.0.a \ No newline at end of file