1.1 --- a/pkg/devices/lib/spi/src/jz4780.cc Tue Nov 07 19:20:32 2023 +0100
1.2 +++ b/pkg/devices/lib/spi/src/jz4780.cc Thu Nov 09 18:40:31 2023 +0100
1.3 @@ -269,12 +269,48 @@
1.4 Spi_clock_assert_drive | Spi_clock_idle_high_level;
1.5 }
1.6
1.7 -/* Transfer the given number of bytes from a buffer using the given unit size in
1.8 - bytes and character size in bits. */
1.9 +/* Transfer the given number of bytes from a buffer. */
1.10 +
1.11 +uint32_t
1.12 +Spi_jz4780_channel::send(uint32_t bytes, const uint8_t data[])
1.13 +{
1.14 + return send_units(bytes, data, 1, 8);
1.15 +}
1.16 +
1.17 +/* Transfer the given number of bytes from a buffer together with control values. */
1.18
1.19 uint32_t
1.20 -Spi_jz4780_channel::send(uint32_t bytes, const uint8_t data[], uint8_t unit_size,
1.21 - uint8_t char_size)
1.22 +Spi_jz4780_channel::send_dc(uint32_t bytes, const uint8_t data[],
1.23 + const int dc[])
1.24 +{
1.25 + configure_transfer(8);
1.26 +
1.27 + uint32_t transferred;
1.28 +
1.29 + for (transferred = 0; transferred < bytes; transferred++)
1.30 + {
1.31 + /* Relocate the data/command level to bit 16. */
1.32 +
1.33 + uint32_t command = dc[transferred] ? (1 << 16) : 0;
1.34 + uint32_t value = data[transferred];
1.35 +
1.36 + /* Combine the character with the data/command bit. */
1.37 +
1.38 + _regs[Ssi_data] = value | command;
1.39 + }
1.40 +
1.41 + wait_busy();
1.42 +
1.43 + return transferred;
1.44 +}
1.45 +
1.46 +/* Transfer the given number of bytes from a buffer using the given unit size in
1.47 + bytes and character size in bits. The bytes are stored in a big endian
1.48 + arrangement. */
1.49 +
1.50 +uint32_t
1.51 +Spi_jz4780_channel::send_units(uint32_t bytes, const uint8_t data[],
1.52 + uint8_t unit_size, uint8_t char_size)
1.53 {
1.54 configure_transfer(char_size);
1.55
1.56 @@ -292,15 +328,13 @@
1.57
1.58 uint32_t command = (char_size < 16) && (value & (1 << char_size)) ? (1 << 16) : 0;
1.59
1.60 - /* Combine the significant portion of the character with the command. */
1.61 + /* Combine the character portion of the unit with the command. */
1.62
1.63 value = (value & char_mask) | command;
1.64 _regs[Ssi_data] = value;
1.65 }
1.66
1.67 - /* Wait for the busy condition to clear or for a limited period. */
1.68 -
1.69 - for (unsigned int i = 0; i < (1 << 20) && (_regs[Ssi_status] & Ssi_trans_busy); i++);
1.70 + wait_busy();
1.71
1.72 return transferred;
1.73 }
1.74 @@ -308,9 +342,10 @@
1.75 /* Transfer the given number of bytes from a DMA region using the given
1.76 unit size in bytes and character size in bits. */
1.77
1.78 -uint32_t Spi_jz4780_channel::transfer(l4re_dma_space_dma_addr_t paddr,
1.79 - uint32_t count, uint8_t unit_size,
1.80 - uint8_t char_size)
1.81 +uint32_t
1.82 +Spi_jz4780_channel::transfer(l4re_dma_space_dma_addr_t paddr,
1.83 + uint32_t count, uint8_t unit_size,
1.84 + uint8_t char_size)
1.85 {
1.86 configure_transfer(char_size);
1.87
1.88 @@ -324,13 +359,19 @@
1.89 if (to_transfer)
1.90 transferred = to_transfer ? (unit_count - _dma->wait()) * unit_size : 0;
1.91
1.92 - /* Wait for the busy condition to clear or for a limited period. */
1.93 -
1.94 - for (unsigned int i = 0; i < (1 << 20) && (_regs[Ssi_status] & Ssi_trans_busy); i++);
1.95 + wait_busy();
1.96
1.97 return transferred;
1.98 }
1.99
1.100 +/* Wait for the busy condition to clear or for a limited period. */
1.101 +
1.102 +void
1.103 +Spi_jz4780_channel::wait_busy()
1.104 +{
1.105 + for (unsigned int i = 0; i < (1 << 20) && (_regs[Ssi_status] & Ssi_trans_busy); i++);
1.106 +}
1.107 +
1.108
1.109
1.110 /* Initialise the peripheral abstraction. */
1.111 @@ -374,14 +415,28 @@
1.112 static_cast<Dma_jz4780_channel *>(dma), frequency);
1.113 }
1.114
1.115 -uint32_t jz4780_spi_send(void *channel, uint32_t bytes, const uint8_t data[],
1.116 - uint8_t unit_size, uint8_t char_size)
1.117 +uint32_t jz4780_spi_send(void *channel, uint32_t bytes, const uint8_t data[])
1.118 +{
1.119 + return static_cast<Spi_jz4780_channel *>(channel)->send(bytes, data);
1.120 +}
1.121 +
1.122 +uint32_t jz4780_spi_send_dc(void *channel, uint32_t bytes, const uint8_t data[],
1.123 + const int dc[])
1.124 {
1.125 - return static_cast<Spi_jz4780_channel *>(channel)->send(bytes, data, unit_size, char_size);
1.126 + return static_cast<Spi_jz4780_channel *>(channel)->send_dc(bytes, data, dc);
1.127 +}
1.128 +
1.129 +uint32_t jz4780_spi_send_units(void *channel, uint32_t bytes, const uint8_t data[],
1.130 + uint8_t unit_size, uint8_t char_size)
1.131 +{
1.132 + return static_cast<Spi_jz4780_channel *>(channel)->send_units(bytes, data,
1.133 + unit_size, char_size);
1.134 }
1.135
1.136 uint32_t jz4780_spi_transfer(void *channel, l4re_dma_space_dma_addr_t paddr,
1.137 - uint32_t count, uint8_t unit_size, uint8_t char_size)
1.138 + uint32_t count, uint8_t unit_size,
1.139 + uint8_t char_size)
1.140 {
1.141 - return static_cast<Spi_jz4780_channel *>(channel)->transfer(paddr, count, unit_size, char_size);
1.142 + return static_cast<Spi_jz4780_channel *>(channel)->transfer(paddr, count,
1.143 + unit_size, char_size);
1.144 }