1.1 --- a/pkg/devices/lib/spi/src/gpio.cc Sun Nov 12 17:14:10 2023 +0100
1.2 +++ b/pkg/devices/lib/spi/src/gpio.cc Mon Nov 13 01:17:15 2023 +0100
1.3 @@ -40,6 +40,7 @@
1.4 _clock_device->setup(_clock_pin, Hw::Gpio_chip::Output, 1);
1.5 _data_device->setup(_data_pin, Hw::Gpio_chip::Output, 0);
1.6 _enable_device->setup(_enable_pin, Hw::Gpio_chip::Output, 1);
1.7 + _control_device->setup(_control_pin, Hw::Gpio_chip::Output, 0);
1.8 }
1.9
1.10 Spi_gpio::Spi_gpio(uint64_t frequency,
1.11 @@ -101,7 +102,7 @@
1.12 _clock_device->set(_clock_pin, 0);
1.13 _data_device->set(_data_pin, data[byte] & mask ? 1 : 0);
1.14
1.15 - if ((_control_device != NULL) && (dc != NULL))
1.16 + if ((_control_device != NULL) && (_control_pin >= 0) && (dc != NULL))
1.17 _control_device->set(_control_pin, dc[byte] ? 1 : 0);
1.18
1.19 if (_frequency)
1.20 @@ -128,34 +129,53 @@
1.21 uint32_t Spi_gpio::send_units(uint32_t bytes, const uint8_t data[],
1.22 uint8_t unit_size, uint8_t char_size)
1.23 {
1.24 - uint32_t count = bytes / unit_size;
1.25 - int dc[count];
1.26 + /* Obtain the data/command values for each unit. */
1.27 +
1.28 + uint32_t chars = bytes / unit_size;
1.29 + int dc[chars];
1.30 +
1.31 + /* Obtain the actual character bytes to be sent. */
1.32 +
1.33 + int char_unit_size = ((char_size ? char_size - 1 : 0) / 8) + 1;
1.34 + uint8_t char_data[char_unit_size * chars];
1.35
1.36 /* Traverse the byte sequence, extracting data/command bits for each unit. */
1.37
1.38 - for (uint32_t offset = 0, unit = 0; offset < bytes; offset += unit_size, unit++)
1.39 + for (uint32_t offset = 0, unit = 0, char_offset = 0; unit < chars;
1.40 + offset += unit_size, unit++, char_offset += char_unit_size)
1.41 {
1.42 + /* Obtain the unit value. */
1.43 +
1.44 + uint32_t value = 0;
1.45 +
1.46 + for (uint8_t byte = 0; byte < unit_size; byte++)
1.47 + value = (value << 8) | data[offset + byte];
1.48 +
1.49 /* The unit size must be greater than the character size for data/command
1.50 bits to be present. */
1.51
1.52 if (unit_size * 8 <= char_size)
1.53 dc[unit] = 0;
1.54 +
1.55 + /* Extract the data/command level. */
1.56 +
1.57 else
1.58 - {
1.59 - /* Obtain the unit value. */
1.60 -
1.61 - uint32_t value = 0;
1.62 + dc[unit] = value & (1 << char_size) ? 1 : 0;
1.63
1.64 - for (uint8_t byte = 0; byte < unit_size; byte++)
1.65 - value = (value << 8) | data[offset + byte];
1.66 + /* Obtain the actual character data from the input data, discarding the most
1.67 + significant bytes beyond the character and masking out any remaining
1.68 + superfluous bits, thus obtaining a whole number of bytes. */
1.69
1.70 - /* Extract the data/command level. */
1.71 + value = value & ((1 << char_size) - 1);
1.72
1.73 - dc[unit] = value & (1 << char_size) ? 1 : 0;
1.74 + for (uint8_t byte = char_unit_size; byte != 0; byte--)
1.75 + {
1.76 + char_data[char_offset + byte - 1] = value & 0xff;
1.77 + value >>= 8;
1.78 }
1.79 }
1.80
1.81 - return send_dc(bytes, data, dc);
1.82 + return send_dc(chars, char_data, dc);
1.83 }
1.84
1.85