low level transfer function */
| 172 | low level transfer function |
| 173 | */ |
| 174 | bool SPIDevice::do_transfer(const uint8_t *send, uint8_t *recv, uint32_t len) |
| 175 | { |
| 176 | bool old_cs_forced = cs_forced; |
| 177 | |
| 178 | if (!set_chip_select(true)) { |
| 179 | return false; |
| 180 | } |
| 181 | |
| 182 | bool ret = true; |
| 183 | |
| 184 | #if defined(HAL_SPI_USE_POLLED) |
| 185 | for (uint32_t i=0; i<len; i++) { |
| 186 | const uint8_t b = spiPolledExchange(spi_devices[device_desc.bus].driver, send?send[i]:0); |
| 187 | if (recv) { |
| 188 | recv[i] = b; |
| 189 | } |
| 190 | } |
| 191 | #else |
| 192 | if (!bus.bouncebuffer_setup(send, len, recv, len)) { |
| 193 | set_chip_select(old_cs_forced); |
| 194 | return false; |
| 195 | } |
| 196 | osalSysLock(); |
| 197 | hal.util->persistent_data.spi_count++; |
| 198 | if (send == nullptr) { |
| 199 | spiStartReceiveI(spi_devices[device_desc.bus].driver, len, recv); |
| 200 | } else if (recv == nullptr) { |
| 201 | spiStartSendI(spi_devices[device_desc.bus].driver, len, send); |
| 202 | } else { |
| 203 | spiStartExchangeI(spi_devices[device_desc.bus].driver, len, send, recv); |
| 204 | } |
| 205 | // we allow SPI transfers to take a maximum of 20ms plus 32us per |
| 206 | // byte. This covers all use cases in ArduPilot. We don't ever |
| 207 | // expect this timeout to trigger unless there is a severe MCU |
| 208 | // error |
| 209 | const uint32_t timeout_us = 20000U + len * 32U; |
| 210 | msg_t msg = osalThreadSuspendTimeoutS(&spi_devices[device_desc.bus].driver->thread, TIME_US2I(timeout_us)); |
| 211 | osalSysUnlock(); |
| 212 | if (msg == MSG_TIMEOUT) { |
| 213 | ret = false; |
| 214 | if (!hal.scheduler->in_expected_delay()) { |
| 215 | INTERNAL_ERROR(AP_InternalError::error_t::spi_fail); |
| 216 | } |
| 217 | spiAbort(spi_devices[device_desc.bus].driver); |
| 218 | } |
| 219 | bus.bouncebuffer_finish(send, recv, len); |
| 220 | #endif |
| 221 | set_chip_select(old_cs_forced); |
| 222 | return ret; |
| 223 | } |
| 224 | |
| 225 | /* |
| 226 | this pulses the clock for n bytes. The data is ignored. |
nothing calls this directly
no test coverage detected