essl_spi.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. // Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include <string.h>
  15. #include <sys/param.h>
  16. #include "esp_log.h"
  17. #include "esp_check.h"
  18. #include "driver/spi_master.h"
  19. #include "driver/periph_ctrl.h"
  20. #include "essl_internal.h"
  21. #include "essl_spi.h"
  22. #include "essl_spi/esp32s2_defs.h"
  23. /**
  24. * Initialise device function list of SPI by this macro.
  25. */
  26. #define ESSL_SPI_DEFAULT_DEV_FUNC() (essl_dev_t) {\
  27. .get_tx_buffer_num = essl_spi_get_tx_buffer_num,\
  28. .update_tx_buffer_num = essl_spi_update_tx_buffer_num,\
  29. .get_rx_data_size = essl_spi_get_rx_data_size,\
  30. .update_rx_data_size = essl_spi_update_rx_data_size,\
  31. .send_packet = essl_spi_send_packet,\
  32. .get_packet = essl_spi_get_packet,\
  33. .write_reg = essl_spi_write_reg,\
  34. .read_reg = essl_spi_read_reg,\
  35. }
  36. static const char TAG[] = "essl_spi";
  37. typedef struct {
  38. spi_device_handle_t spi; // Pointer to SPI device handle.
  39. /* Master TX, Slave RX */
  40. struct {
  41. size_t sent_buf_num; // Number of TX buffers that has been sent out by the master.
  42. size_t slave_rx_buf_num; // Number of RX buffers laoded by the slave.
  43. uint16_t tx_buffer_size; /* Buffer size for Master TX / Slave RX direction.
  44. * Data with length within this size will still be regarded as one buffer.
  45. * E.g. 10 bytes data costs 2 buffers if the size is 8 bytes per buffer. */
  46. uint8_t tx_sync_reg; // The pre-negotiated register ID for Master-TX-SLAVE-RX synchronization. 1 word (4 Bytes) will be reserved for the synchronization.
  47. } master_out;
  48. /* Master RX, Slave TX */
  49. struct {
  50. size_t received_bytes; // Number of the RX bytes that has been received by the Master.
  51. size_t slave_tx_bytes; // Number of the TX bytes that has been loaded by the Slave
  52. uint8_t rx_sync_reg; // The pre-negotiated register ID for Master-RX-SLAVE-TX synchronization. 1 word (4 Bytes) will be reserved for the synchronization.
  53. } master_in;
  54. } essl_spi_context_t;
  55. static uint16_t get_hd_command(uint16_t cmd_i, uint32_t flags)
  56. {
  57. //have no prefixes
  58. if (cmd_i == CMD_HD_EN_QPI_REG) return cmd_i;
  59. //doesn't support 4-line commands
  60. if(flags & SPI_TRANS_MODE_QIO && flags & SPI_TRANS_MODE_DIOQIO_ADDR &&
  61. (cmd_i == CMD_HD_WR_END_REG || cmd_i == CMD_HD_INT0_REG ||
  62. cmd_i == CMD_HD_INT1_REG || cmd_i == CMD_HD_INT2_REG)) {
  63. //the transaction will be sent in corresponding 1/2/4 bit mode, without address and data.
  64. //the CMD will have no 0xA- prefix
  65. return cmd_i;
  66. }
  67. if (flags & SPI_TRANS_MODE_DIO) {
  68. if (flags & SPI_TRANS_MODE_DIOQIO_ADDR) {
  69. return cmd_i | CMD_HD_DIO_MODE;
  70. } else {
  71. return cmd_i | CMD_HD_DOUT_MODE;
  72. }
  73. } else if (flags & SPI_TRANS_MODE_QIO) {
  74. if (flags & SPI_TRANS_MODE_DIOQIO_ADDR) {
  75. return cmd_i | CMD_HD_QIO_MODE;
  76. } else {
  77. return cmd_i | CMD_HD_QOUT_MODE;
  78. }
  79. }
  80. return cmd_i | CMD_HD_ONEBIT_MODE;
  81. }
  82. static int get_hd_dummy_bits(uint32_t flags)
  83. {
  84. //dummy is always 4 cycles when dual or quad mode is enabled. Otherwise 8 cycles in normal mode.
  85. if (flags & (SPI_TRANS_MODE_DIO | SPI_TRANS_MODE_QIO)) {
  86. return 4;
  87. } else {
  88. return 8;
  89. }
  90. }
  91. esp_err_t essl_spi_rdbuf(spi_device_handle_t spi, uint8_t *out_data, int addr, int len, uint32_t flags)
  92. {
  93. spi_transaction_ext_t t = {
  94. .base = {
  95. .cmd = get_hd_command(CMD_HD_RDBUF_REG, flags),
  96. .addr = addr % 72,
  97. .rxlength = len * 8,
  98. .rx_buffer = out_data,
  99. .flags = flags | SPI_TRANS_VARIABLE_DUMMY,
  100. },
  101. .dummy_bits = get_hd_dummy_bits(flags),
  102. };
  103. return spi_device_transmit(spi, (spi_transaction_t*)&t);
  104. }
  105. esp_err_t essl_spi_rdbuf_polling(spi_device_handle_t spi, uint8_t *out_data, int addr, int len, uint32_t flags)
  106. {
  107. spi_transaction_ext_t t = {
  108. .base = {
  109. .cmd = get_hd_command(CMD_HD_RDBUF_REG, flags),
  110. .addr = addr % 72,
  111. .rxlength = len * 8,
  112. .rx_buffer = out_data,
  113. .flags = flags | SPI_TRANS_VARIABLE_DUMMY,
  114. },
  115. .dummy_bits = get_hd_dummy_bits(flags),
  116. };
  117. return spi_device_polling_transmit(spi, (spi_transaction_t*)&t);
  118. }
  119. esp_err_t essl_spi_wrbuf(spi_device_handle_t spi, const uint8_t *data, int addr, int len, uint32_t flags)
  120. {
  121. spi_transaction_ext_t t = {
  122. .base = {
  123. .cmd = get_hd_command(CMD_HD_WRBUF_REG, flags),
  124. .addr = addr % 72,
  125. .length = len * 8,
  126. .tx_buffer = data,
  127. .flags = flags | SPI_TRANS_VARIABLE_DUMMY,
  128. },
  129. .dummy_bits = get_hd_dummy_bits(flags),
  130. };
  131. return spi_device_transmit(spi, (spi_transaction_t*)&t);
  132. }
  133. esp_err_t essl_spi_wrbuf_polling(spi_device_handle_t spi, const uint8_t *data, int addr, int len, uint32_t flags)
  134. {
  135. spi_transaction_ext_t t = {
  136. .base = {
  137. .cmd = get_hd_command(CMD_HD_WRBUF_REG, flags),
  138. .addr = addr % 72,
  139. .length = len * 8,
  140. .tx_buffer = data,
  141. .flags = flags | SPI_TRANS_VARIABLE_DUMMY,
  142. },
  143. .dummy_bits = get_hd_dummy_bits(flags),
  144. };
  145. return spi_device_polling_transmit(spi, (spi_transaction_t*)&t);
  146. }
  147. esp_err_t essl_spi_rddma_seg(spi_device_handle_t spi, uint8_t *out_data, int seg_len, uint32_t flags)
  148. {
  149. spi_transaction_ext_t t = {
  150. .base = {
  151. .cmd = get_hd_command(CMD_HD_RDDMA_REG, flags),
  152. .rxlength = seg_len * 8,
  153. .rx_buffer = out_data,
  154. .flags = flags | SPI_TRANS_VARIABLE_DUMMY,
  155. },
  156. .dummy_bits = get_hd_dummy_bits(flags),
  157. };
  158. return spi_device_transmit(spi, (spi_transaction_t*)&t);
  159. }
  160. esp_err_t essl_spi_rddma_done(spi_device_handle_t spi, uint32_t flags)
  161. {
  162. spi_transaction_t end_t = {
  163. .cmd = get_hd_command(CMD_HD_INT0_REG, flags),
  164. .flags = flags,
  165. };
  166. return spi_device_transmit(spi, &end_t);
  167. }
  168. esp_err_t essl_spi_rddma(spi_device_handle_t spi, uint8_t *out_data, int len, int seg_len, uint32_t flags)
  169. {
  170. if (!esp_ptr_dma_capable(out_data) || ((intptr_t)out_data % 4) != 0) {
  171. return ESP_ERR_INVALID_ARG;
  172. }
  173. seg_len = (seg_len > 0)? seg_len : len;
  174. uint8_t* read_ptr = out_data;
  175. esp_err_t ret = ESP_OK;
  176. while (len > 0) {
  177. int send_len = MIN(seg_len, len);
  178. ret = essl_spi_rddma_seg(spi, read_ptr, send_len, flags);
  179. if (ret != ESP_OK) return ret;
  180. len -= send_len;
  181. read_ptr += send_len;
  182. }
  183. return essl_spi_rddma_done(spi, flags);
  184. }
  185. esp_err_t essl_spi_wrdma_seg(spi_device_handle_t spi, const uint8_t *data, int seg_len, uint32_t flags)
  186. {
  187. spi_transaction_ext_t t = {
  188. .base = {
  189. .cmd = get_hd_command(CMD_HD_WRDMA_REG, flags),
  190. .length = seg_len * 8,
  191. .tx_buffer = data,
  192. .flags = flags | SPI_TRANS_VARIABLE_DUMMY,
  193. },
  194. .dummy_bits = get_hd_dummy_bits(flags),
  195. };
  196. return spi_device_transmit(spi, (spi_transaction_t*)&t);
  197. }
  198. esp_err_t essl_spi_wrdma_done(spi_device_handle_t spi, uint32_t flags)
  199. {
  200. spi_transaction_t end_t = {
  201. .cmd = get_hd_command(CMD_HD_WR_END_REG, flags),
  202. .flags = flags,
  203. };
  204. return spi_device_transmit(spi, &end_t);
  205. }
  206. esp_err_t essl_spi_wrdma(spi_device_handle_t spi, const uint8_t *data, int len, int seg_len, uint32_t flags)
  207. {
  208. if (!esp_ptr_dma_capable(data)) {
  209. return ESP_ERR_INVALID_ARG;
  210. }
  211. seg_len = (seg_len > 0)? seg_len : len;
  212. while (len > 0) {
  213. int send_len = MIN(seg_len, len);
  214. esp_err_t ret = essl_spi_wrdma_seg(spi, data, send_len, flags);
  215. if (ret != ESP_OK) return ret;
  216. len -= send_len;
  217. data += send_len;
  218. }
  219. return essl_spi_wrdma_done(spi, flags);
  220. }
  221. esp_err_t essl_spi_int(spi_device_handle_t spi, int int_n, uint32_t flags)
  222. {
  223. spi_transaction_t end_t = {
  224. .cmd = get_hd_command(CMD_HD_INT0_REG + int_n, flags),
  225. .flags = flags,
  226. };
  227. return spi_device_transmit(spi, &end_t);
  228. }
  229. //------------------------------------ APPEND MODE ----------------------------------//
  230. static uint32_t essl_spi_get_rx_data_size(void *arg);
  231. static esp_err_t essl_spi_update_rx_data_size(void *arg, uint32_t wait_ms);
  232. static uint32_t essl_spi_get_tx_buffer_num(void *arg);
  233. static esp_err_t essl_spi_update_tx_buffer_num(void *arg, uint32_t wait_ms);
  234. esp_err_t essl_spi_init_dev(essl_handle_t *out_handle, const essl_spi_config_t *init_config)
  235. {
  236. ESP_RETURN_ON_FALSE(init_config->spi, ESP_ERR_INVALID_STATE, TAG, "Check SPI initialization first");
  237. ESP_RETURN_ON_FALSE(init_config->tx_sync_reg <= (SOC_SPI_MAXIMUM_BUFFER_SIZE - 1) * 4, ESP_ERR_INVALID_ARG, TAG, "GPSPI supports %d-byte-width internal registers", SOC_SPI_MAXIMUM_BUFFER_SIZE);
  238. ESP_RETURN_ON_FALSE(init_config->rx_sync_reg <= (SOC_SPI_MAXIMUM_BUFFER_SIZE - 1) * 4, ESP_ERR_INVALID_ARG, TAG, "GPSPI supports %d-byte-width internal registers", SOC_SPI_MAXIMUM_BUFFER_SIZE);
  239. ESP_RETURN_ON_FALSE(init_config->tx_sync_reg != init_config->rx_sync_reg, ESP_ERR_INVALID_ARG, TAG, "Should use different word of registers for synchronization");
  240. essl_spi_context_t *context = calloc(1, sizeof(essl_spi_context_t));
  241. essl_dev_t *dev = calloc(1, sizeof(essl_dev_t));
  242. if (!context || !dev) {
  243. free(context);
  244. free(dev);
  245. return ESP_ERR_NO_MEM;
  246. }
  247. *context = (essl_spi_context_t) {
  248. .spi = *init_config->spi,
  249. .master_out.tx_buffer_size = init_config->tx_buf_size,
  250. .master_out.tx_sync_reg = init_config->tx_sync_reg,
  251. .master_in.rx_sync_reg = init_config->rx_sync_reg
  252. };
  253. *dev = ESSL_SPI_DEFAULT_DEV_FUNC();
  254. dev->args = context;
  255. *out_handle = dev;
  256. return ESP_OK;
  257. }
  258. esp_err_t essl_spi_deinit_dev(essl_handle_t handle)
  259. {
  260. ESP_RETURN_ON_FALSE(handle, ESP_ERR_INVALID_STATE, TAG, "ESSL SPI is not in use");
  261. free(handle->args);
  262. free(handle);
  263. return ESP_OK;
  264. }
  265. void essl_spi_reset_cnt(void *arg)
  266. {
  267. essl_spi_context_t *ctx = arg;
  268. if (ctx) {
  269. ctx->master_out.sent_buf_num = 0;
  270. ctx->master_in.received_bytes = 0;
  271. }
  272. }
  273. //------------------------------------ RX ----------------------------------//
  274. esp_err_t essl_spi_read_reg(void *arg, uint8_t addr, uint8_t *out_value, uint32_t wait_ms)
  275. {
  276. essl_spi_context_t *ctx = arg;
  277. ESP_RETURN_ON_FALSE(arg, ESP_ERR_INVALID_STATE, TAG, "Check ESSL SPI initialization first");
  278. uint8_t reserved_1_head = ctx->master_out.tx_sync_reg < ctx->master_in.rx_sync_reg ? ctx->master_out.tx_sync_reg : ctx->master_in.rx_sync_reg;
  279. uint8_t reserved_1_tail = reserved_1_head + 3;
  280. uint8_t reserved_2_head = ctx->master_out.tx_sync_reg < ctx->master_in.rx_sync_reg ? ctx->master_in.rx_sync_reg : ctx->master_out.tx_sync_reg;
  281. uint8_t reserved_2_tail = reserved_2_head + 3;
  282. ESP_RETURN_ON_FALSE(addr < reserved_1_head || (addr > reserved_1_tail && addr < reserved_2_head) || addr > reserved_2_tail, ESP_ERR_INVALID_ARG, TAG, "Invalid address");
  283. return essl_spi_rdbuf(ctx->spi, out_value, addr, sizeof(uint8_t), 0);
  284. }
  285. static uint32_t essl_spi_get_rx_data_size(void *arg)
  286. {
  287. essl_spi_context_t *ctx = arg;
  288. ESP_LOGV(TAG, "slave tx buffer: %d bytes, master has read: %d bytes", ctx->master_in.slave_tx_bytes, ctx->master_in.received_bytes);
  289. return ctx->master_in.slave_tx_bytes - ctx->master_in.received_bytes;
  290. }
  291. static esp_err_t essl_spi_update_rx_data_size(void *arg, uint32_t wait_ms)
  292. {
  293. essl_spi_context_t *ctx = arg;
  294. uint32_t updated_size;
  295. uint32_t previous_size;
  296. esp_err_t ret;
  297. ret = essl_spi_rdbuf_polling(ctx->spi, (uint8_t *)&previous_size, ctx->master_in.rx_sync_reg, sizeof(uint32_t), 0);
  298. if (ret != ESP_OK) {
  299. return ret;
  300. }
  301. /**
  302. * Read until the last 2 reading result are same. Reason:
  303. * SPI transaction is carried on per 1 Byte. So when Master is reading the shared register, if the
  304. * register value is changed by Slave at this time, Master may get wrong data.
  305. */
  306. while (1) {
  307. ret = essl_spi_rdbuf_polling(ctx->spi, (uint8_t *)&updated_size, ctx->master_in.rx_sync_reg, sizeof(uint32_t), 0);
  308. if (ret != ESP_OK) {
  309. return ret;
  310. }
  311. if (updated_size == previous_size) {
  312. ctx->master_in.slave_tx_bytes = updated_size;
  313. ESP_LOGV(TAG, "updated: slave prepared tx buffer is: %d bytes", updated_size);
  314. return ret;
  315. }
  316. previous_size = updated_size;
  317. }
  318. }
  319. esp_err_t essl_spi_get_packet(void *arg, void *out_data, size_t size, uint32_t wait_ms)
  320. {
  321. ESP_RETURN_ON_FALSE(arg, ESP_ERR_INVALID_STATE, TAG, "Check ESSL SPI initialization first");
  322. if (!esp_ptr_dma_capable(out_data) || ((intptr_t)out_data % 4) != 0) {
  323. return ESP_ERR_INVALID_ARG;
  324. }
  325. essl_spi_context_t *ctx = arg;
  326. esp_err_t ret;
  327. if (essl_spi_get_rx_data_size(arg) < size) {
  328. /**
  329. * For realistic situation, usually there will be a large overhead (Slave will load large amount of data),
  330. * so here we only update the Slave's TX size when the last-updated size is smaller than what Master requires.
  331. */
  332. ret = essl_spi_update_rx_data_size(arg, wait_ms);
  333. if (ret != ESP_OK) {
  334. return ret;
  335. }
  336. //Slave still did not load enough size of buffer
  337. if (essl_spi_get_rx_data_size(arg) < size) {
  338. ESP_LOGV(TAG, "slave buffer: %d is not enough, %d is required", ctx->master_in.slave_tx_bytes, ctx->master_in.received_bytes + size);
  339. return ESP_ERR_NOT_FOUND;
  340. }
  341. }
  342. ESP_LOGV(TAG, "get_packet: size to read is: %d", size);
  343. ret = essl_spi_rddma_seg(ctx->spi, out_data, size, 0);
  344. if (ret != ESP_OK) {
  345. return ret;
  346. }
  347. ctx->master_in.received_bytes += size;
  348. return ESP_OK;
  349. }
  350. //------------------------------------ TX ----------------------------------//
  351. esp_err_t essl_spi_write_reg(void *arg, uint8_t addr, uint8_t value, uint8_t *out_value, uint32_t wait_ms)
  352. {
  353. essl_spi_context_t *ctx = arg;
  354. ESP_RETURN_ON_FALSE(arg, ESP_ERR_INVALID_STATE, TAG, "Check ESSL SPI initialization first");
  355. uint8_t reserved_1_head = ctx->master_out.tx_sync_reg < ctx->master_in.rx_sync_reg ? ctx->master_out.tx_sync_reg : ctx->master_in.rx_sync_reg;
  356. uint8_t reserved_1_tail = reserved_1_head + 3;
  357. uint8_t reserved_2_head = ctx->master_out.tx_sync_reg < ctx->master_in.rx_sync_reg ? ctx->master_in.rx_sync_reg : ctx->master_out.tx_sync_reg;
  358. uint8_t reserved_2_tail = reserved_2_head + 3;
  359. ESP_RETURN_ON_FALSE(addr < reserved_1_head || (addr > reserved_1_tail && addr < reserved_2_head) || addr > reserved_2_tail, ESP_ERR_INVALID_ARG, TAG, "Invalid address");
  360. ESP_RETURN_ON_FALSE(out_value == NULL, ESP_ERR_NOT_SUPPORTED, TAG, "This feature is not supported");
  361. return essl_spi_wrbuf(ctx->spi, &value, addr, sizeof(uint8_t), 0);
  362. }
  363. static uint32_t essl_spi_get_tx_buffer_num(void *arg)
  364. {
  365. essl_spi_context_t *ctx = arg;
  366. ESP_LOGV(TAG, "slave rx buffer: %d, master has sent: %d", ctx->master_out.slave_rx_buf_num, ctx->master_out.sent_buf_num);
  367. return ctx->master_out.slave_rx_buf_num - ctx->master_out.sent_buf_num;
  368. }
  369. static esp_err_t essl_spi_update_tx_buffer_num(void *arg, uint32_t wait_ms)
  370. {
  371. essl_spi_context_t *ctx = arg;
  372. uint32_t updated_num;
  373. uint32_t previous_size;
  374. esp_err_t ret;
  375. ret = essl_spi_rdbuf_polling(ctx->spi, (uint8_t *)&previous_size, ctx->master_out.tx_sync_reg, sizeof(uint32_t), 0);
  376. if (ret != ESP_OK) {
  377. return ret;
  378. }
  379. /**
  380. * Read until the last 2 reading result are same. Reason:
  381. * SPI transaction is carried on per 1 Byte. So when Master is reading the shared register, if the
  382. * register value is changed by Slave at this time, Master may get wrong data.
  383. */
  384. while (1) {
  385. ret = essl_spi_rdbuf_polling(ctx->spi, (uint8_t *)&updated_num, ctx->master_out.tx_sync_reg, sizeof(uint32_t), 0);
  386. if (ret != ESP_OK) {
  387. return ret;
  388. }
  389. if (updated_num == previous_size) {
  390. ctx->master_out.slave_rx_buf_num = updated_num;
  391. ESP_LOGV(TAG, "updated: slave prepared rx buffer: %d", updated_num);
  392. return ret;
  393. }
  394. previous_size = updated_num;
  395. }
  396. }
  397. esp_err_t essl_spi_send_packet(void *arg, const void *data, size_t size, uint32_t wait_ms)
  398. {
  399. ESP_RETURN_ON_FALSE(arg, ESP_ERR_INVALID_STATE, TAG, "Check ESSL SPI initialization first");
  400. if (!esp_ptr_dma_capable(data)) {
  401. return ESP_ERR_INVALID_ARG;
  402. }
  403. essl_spi_context_t *ctx = arg;
  404. esp_err_t ret;
  405. uint32_t buf_num_to_use = (size + ctx->master_out.tx_buffer_size - 1) / ctx->master_out.tx_buffer_size;
  406. if (essl_spi_get_tx_buffer_num(arg) < buf_num_to_use) {
  407. /**
  408. * For realistic situation, usually there will be a large overhead (Slave will load enough number of RX buffers),
  409. * so here we only update the Slave's RX buffer number when the last-updated number is smaller than what Master requires.
  410. */
  411. ret = essl_spi_update_tx_buffer_num(arg, wait_ms);
  412. if (ret != ESP_OK) {
  413. return ret;
  414. }
  415. //Slave still did not load a sufficient amount of buffers
  416. if (essl_spi_get_tx_buffer_num(arg) < buf_num_to_use) {
  417. ESP_LOGV(TAG, "slave buffer: %d is not enough, %d is required", ctx->master_out.slave_rx_buf_num, ctx->master_out.sent_buf_num + buf_num_to_use);
  418. return ESP_ERR_NOT_FOUND;
  419. }
  420. }
  421. ESP_LOGV(TAG, "send_packet: size to write is: %d", size);
  422. ret = essl_spi_wrdma_seg(ctx->spi, data, size, 0);
  423. if (ret != ESP_OK) {
  424. return ret;
  425. }
  426. ctx->master_out.sent_buf_num += buf_num_to_use;
  427. return essl_spi_wrdma_done(ctx->spi, 0);
  428. }