spi_common.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842
  1. // Copyright 2015-2019 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 "sdkconfig.h"
  16. #include "driver/spi_master.h"
  17. #include "soc/spi_periph.h"
  18. #include "esp_types.h"
  19. #include "esp_attr.h"
  20. #include "esp_log.h"
  21. #include "esp_err.h"
  22. #include "soc/soc.h"
  23. #include "soc/soc_caps.h"
  24. #include "soc/lldesc.h"
  25. #include "driver/gpio.h"
  26. #include "driver/periph_ctrl.h"
  27. #include "esp_heap_caps.h"
  28. #include "driver/spi_common_internal.h"
  29. #include "stdatomic.h"
  30. #include "hal/spi_hal.h"
  31. #include "hal/gpio_hal.h"
  32. #include "esp_rom_gpio.h"
  33. #if CONFIG_IDF_TARGET_ESP32
  34. #include "soc/dport_reg.h"
  35. #endif
  36. #if SOC_GDMA_SUPPORTED
  37. #include "esp_private/gdma.h"
  38. #endif
  39. static const char *SPI_TAG = "spi";
  40. #define SPI_CHECK(a, str, ret_val) do { \
  41. if (!(a)) { \
  42. ESP_LOGE(SPI_TAG,"%s(%d): %s", __FUNCTION__, __LINE__, str); \
  43. return (ret_val); \
  44. } \
  45. } while(0)
  46. #define SPI_CHECK_PIN(pin_num, pin_name, check_output) if (check_output) { \
  47. SPI_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(pin_num), pin_name" not valid", ESP_ERR_INVALID_ARG); \
  48. } else { \
  49. SPI_CHECK(GPIO_IS_VALID_GPIO(pin_num), pin_name" not valid", ESP_ERR_INVALID_ARG); \
  50. }
  51. #define SPI_MAIN_BUS_DEFAULT() { \
  52. .host_id = 0, \
  53. .bus_attr = { \
  54. .tx_dma_chan = 0, \
  55. .rx_dma_chan = 0, \
  56. .max_transfer_sz = SOC_SPI_MAXIMUM_BUFFER_SIZE, \
  57. .dma_desc_num= 0, \
  58. }, \
  59. }
  60. #define FUNC_GPIO PIN_FUNC_GPIO
  61. typedef struct {
  62. int host_id;
  63. spi_destroy_func_t destroy_func;
  64. void* destroy_arg;
  65. spi_bus_attr_t bus_attr;
  66. #if SOC_GDMA_SUPPORTED
  67. gdma_channel_handle_t tx_channel;
  68. gdma_channel_handle_t rx_channel;
  69. #endif
  70. } spicommon_bus_context_t;
  71. //Periph 1 is 'claimed' by SPI flash code.
  72. static atomic_bool spi_periph_claimed[SOC_SPI_PERIPH_NUM] = { ATOMIC_VAR_INIT(true), ATOMIC_VAR_INIT(false),
  73. #if (SOC_SPI_PERIPH_NUM >= 3)
  74. ATOMIC_VAR_INIT(false),
  75. #endif
  76. #if (SOC_SPI_PERIPH_NUM >= 4)
  77. ATOMIC_VAR_INIT(false),
  78. #endif
  79. };
  80. static const char* spi_claiming_func[3] = {NULL, NULL, NULL};
  81. static spicommon_bus_context_t s_mainbus = SPI_MAIN_BUS_DEFAULT();
  82. static spicommon_bus_context_t* bus_ctx[SOC_SPI_PERIPH_NUM] = {&s_mainbus};
  83. #if !SOC_GDMA_SUPPORTED
  84. //Each bit stands for 1 dma channel, BIT(0) should be used for SPI1
  85. static uint8_t spi_dma_chan_enabled = 0;
  86. static portMUX_TYPE spi_dma_spinlock = portMUX_INITIALIZER_UNLOCKED;
  87. #endif //#if !SOC_GDMA_SUPPORTED
  88. static inline bool is_valid_host(spi_host_device_t host)
  89. {
  90. #if (SOC_SPI_PERIPH_NUM == 2)
  91. return host >= SPI1_HOST && host <= SPI2_HOST;
  92. #elif (SOC_SPI_PERIPH_NUM == 3)
  93. return host >= SPI1_HOST && host <= SPI3_HOST;
  94. #endif
  95. }
  96. //----------------------------------------------------------alloc spi periph-------------------------------------------------------//
  97. //Returns true if this peripheral is successfully claimed, false if otherwise.
  98. bool spicommon_periph_claim(spi_host_device_t host, const char* source)
  99. {
  100. bool false_var = false;
  101. bool ret = atomic_compare_exchange_strong(&spi_periph_claimed[host], &false_var, true);
  102. if (ret) {
  103. spi_claiming_func[host] = source;
  104. periph_module_enable(spi_periph_signal[host].module);
  105. } else {
  106. ESP_EARLY_LOGE(SPI_TAG, "SPI%d already claimed by %s.", host+1, spi_claiming_func[host]);
  107. }
  108. return ret;
  109. }
  110. bool spicommon_periph_in_use(spi_host_device_t host)
  111. {
  112. return atomic_load(&spi_periph_claimed[host]);
  113. }
  114. //Returns true if this peripheral is successfully freed, false if otherwise.
  115. bool spicommon_periph_free(spi_host_device_t host)
  116. {
  117. bool true_var = true;
  118. bool ret = atomic_compare_exchange_strong(&spi_periph_claimed[host], &true_var, false);
  119. if (ret) periph_module_disable(spi_periph_signal[host].module);
  120. return ret;
  121. }
  122. int spicommon_irqsource_for_host(spi_host_device_t host)
  123. {
  124. return spi_periph_signal[host].irq;
  125. }
  126. int spicommon_irqdma_source_for_host(spi_host_device_t host)
  127. {
  128. return spi_periph_signal[host].irq_dma;
  129. }
  130. //----------------------------------------------------------alloc dma periph-------------------------------------------------------//
  131. #if !SOC_GDMA_SUPPORTED
  132. static inline periph_module_t get_dma_periph(int dma_chan)
  133. {
  134. assert(dma_chan >= 1 && dma_chan <= SOC_SPI_DMA_CHAN_NUM);
  135. #if CONFIG_IDF_TARGET_ESP32S2
  136. if (dma_chan == 1) {
  137. return PERIPH_SPI2_DMA_MODULE;
  138. } else if (dma_chan == 2) {
  139. return PERIPH_SPI3_DMA_MODULE;
  140. } else {
  141. abort();
  142. }
  143. #elif CONFIG_IDF_TARGET_ESP32
  144. return PERIPH_SPI_DMA_MODULE;
  145. #endif
  146. }
  147. static bool spicommon_dma_chan_claim(int dma_chan, uint32_t *out_actual_dma_chan)
  148. {
  149. bool ret = false;
  150. portENTER_CRITICAL(&spi_dma_spinlock);
  151. bool is_used = (BIT(dma_chan) & spi_dma_chan_enabled);
  152. if (!is_used) {
  153. spi_dma_chan_enabled |= BIT(dma_chan);
  154. periph_module_enable(get_dma_periph(dma_chan));
  155. *out_actual_dma_chan = dma_chan;
  156. ret = true;
  157. }
  158. portEXIT_CRITICAL(&spi_dma_spinlock);
  159. return ret;
  160. }
  161. static void spicommon_connect_spi_and_dma(spi_host_device_t host, int dma_chan)
  162. {
  163. #if CONFIG_IDF_TARGET_ESP32
  164. DPORT_SET_PERI_REG_BITS(DPORT_SPI_DMA_CHAN_SEL_REG, 3, dma_chan, (host * 2));
  165. #elif CONFIG_IDF_TARGET_ESP32S2
  166. //On ESP32S2, each SPI controller has its own DMA channel. So there is no need to connect them.
  167. #endif
  168. }
  169. static esp_err_t spicommon_dma_chan_alloc(spi_host_device_t host_id, spi_dma_chan_t dma_chan, uint32_t *out_actual_tx_dma_chan, uint32_t *out_actual_rx_dma_chan)
  170. {
  171. assert(is_valid_host(host_id));
  172. #if CONFIG_IDF_TARGET_ESP32
  173. assert(dma_chan > SPI_DMA_DISABLED && dma_chan <= SPI_DMA_CH_AUTO);
  174. #elif CONFIG_IDF_TARGET_ESP32S2
  175. assert(dma_chan == (int)host_id || dma_chan == SPI_DMA_CH_AUTO);
  176. #endif
  177. esp_err_t ret = ESP_OK;
  178. bool success = false;
  179. uint32_t actual_dma_chan = 0;
  180. if (dma_chan == SPI_DMA_CH_AUTO) {
  181. #if CONFIG_IDF_TARGET_ESP32
  182. for (int i = 1; i < SOC_SPI_DMA_CHAN_NUM+1; i++) {
  183. success = spicommon_dma_chan_claim(i, &actual_dma_chan);
  184. if (success) {
  185. break;
  186. }
  187. }
  188. #elif CONFIG_IDF_TARGET_ESP32S2
  189. //On ESP32S2, each SPI controller has its own DMA channel
  190. success = spicommon_dma_chan_claim(host_id, &actual_dma_chan);
  191. #endif //#if CONFIG_IDF_TARGET_XXX
  192. } else {
  193. success = spicommon_dma_chan_claim((int)dma_chan, &actual_dma_chan);
  194. }
  195. //On ESP32 and ESP32S2, actual_tx_dma_chan and actual_rx_dma_chan are always same
  196. *out_actual_tx_dma_chan = actual_dma_chan;
  197. *out_actual_rx_dma_chan = actual_dma_chan;
  198. if (!success) {
  199. SPI_CHECK(false, "no available dma channel", ESP_ERR_NOT_FOUND);
  200. }
  201. spicommon_connect_spi_and_dma(host_id, *out_actual_tx_dma_chan);
  202. return ret;
  203. }
  204. #else //SOC_GDMA_SUPPORTED
  205. static esp_err_t spicommon_dma_chan_alloc(spi_host_device_t host_id, spi_dma_chan_t dma_chan, uint32_t *out_actual_tx_dma_chan, uint32_t *out_actual_rx_dma_chan)
  206. {
  207. assert(is_valid_host(host_id));
  208. assert(dma_chan == SPI_DMA_CH_AUTO);
  209. esp_err_t ret = ESP_OK;
  210. spicommon_bus_context_t *ctx = bus_ctx[host_id];
  211. if (dma_chan == SPI_DMA_CH_AUTO) {
  212. gdma_channel_alloc_config_t tx_alloc_config = {
  213. .flags.reserve_sibling = 1,
  214. .direction = GDMA_CHANNEL_DIRECTION_TX,
  215. };
  216. ret = gdma_new_channel(&tx_alloc_config, &ctx->tx_channel);
  217. if (ret != ESP_OK) {
  218. return ret;
  219. }
  220. gdma_channel_alloc_config_t rx_alloc_config = {
  221. .direction = GDMA_CHANNEL_DIRECTION_RX,
  222. .sibling_chan = ctx->tx_channel,
  223. };
  224. ret = gdma_new_channel(&rx_alloc_config, &ctx->rx_channel);
  225. if (ret != ESP_OK) {
  226. return ret;
  227. }
  228. if (host_id == SPI2_HOST) {
  229. gdma_connect(ctx->rx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 2));
  230. gdma_connect(ctx->tx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 2));
  231. }
  232. #if (SOC_SPI_PERIPH_NUM >= 3)
  233. else if (host_id == SPI3_HOST) {
  234. gdma_connect(ctx->rx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 3));
  235. gdma_connect(ctx->tx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 3));
  236. }
  237. #endif
  238. gdma_get_channel_id(ctx->tx_channel, (int *)out_actual_tx_dma_chan);
  239. gdma_get_channel_id(ctx->rx_channel, (int *)out_actual_rx_dma_chan);
  240. }
  241. return ret;
  242. }
  243. #endif //#if !SOC_GDMA_SUPPORTED
  244. esp_err_t spicommon_slave_dma_chan_alloc(spi_host_device_t host_id, spi_dma_chan_t dma_chan, uint32_t *out_actual_tx_dma_chan, uint32_t *out_actual_rx_dma_chan)
  245. {
  246. assert(is_valid_host(host_id));
  247. #if CONFIG_IDF_TARGET_ESP32
  248. assert(dma_chan > SPI_DMA_DISABLED && dma_chan <= SPI_DMA_CH_AUTO);
  249. #elif CONFIG_IDF_TARGET_ESP32S2
  250. assert(dma_chan == (int)host_id || dma_chan == SPI_DMA_CH_AUTO);
  251. #endif
  252. esp_err_t ret = ESP_OK;
  253. uint32_t actual_tx_dma_chan = 0;
  254. uint32_t actual_rx_dma_chan = 0;
  255. spicommon_bus_context_t *ctx = (spicommon_bus_context_t *)calloc(1, sizeof(spicommon_bus_context_t));
  256. if (!ctx) {
  257. ret = ESP_ERR_NO_MEM;
  258. goto cleanup;
  259. }
  260. bus_ctx[host_id] = ctx;
  261. ctx->host_id = host_id;
  262. ret = spicommon_dma_chan_alloc(host_id, dma_chan, &actual_tx_dma_chan, &actual_rx_dma_chan);
  263. if (ret != ESP_OK) {
  264. goto cleanup;
  265. }
  266. ctx->bus_attr.tx_dma_chan = actual_tx_dma_chan;
  267. ctx->bus_attr.rx_dma_chan = actual_rx_dma_chan;
  268. *out_actual_tx_dma_chan = actual_tx_dma_chan;
  269. *out_actual_rx_dma_chan = actual_rx_dma_chan;
  270. return ret;
  271. cleanup:
  272. free(ctx);
  273. ctx = NULL;
  274. return ret;
  275. }
  276. //----------------------------------------------------------free dma periph-------------------------------------------------------//
  277. static esp_err_t spicommon_dma_chan_free(spi_host_device_t host_id)
  278. {
  279. assert(is_valid_host(host_id));
  280. spicommon_bus_context_t *ctx = bus_ctx[host_id];
  281. #if !SOC_GDMA_SUPPORTED
  282. //On ESP32S2, each SPI controller has its own DMA channel
  283. int dma_chan = ctx->bus_attr.tx_dma_chan;
  284. assert(spi_dma_chan_enabled & BIT(dma_chan));
  285. portENTER_CRITICAL(&spi_dma_spinlock);
  286. spi_dma_chan_enabled &= ~BIT(dma_chan);
  287. periph_module_disable(get_dma_periph(dma_chan));
  288. portEXIT_CRITICAL(&spi_dma_spinlock);
  289. #else //SOC_GDMA_SUPPORTED
  290. if (ctx->rx_channel) {
  291. gdma_disconnect(ctx->rx_channel);
  292. gdma_del_channel(ctx->rx_channel);
  293. }
  294. if (ctx->tx_channel) {
  295. gdma_disconnect(ctx->tx_channel);
  296. gdma_del_channel(ctx->tx_channel);
  297. }
  298. #endif
  299. return ESP_OK;
  300. }
  301. esp_err_t spicommon_slave_free_dma(spi_host_device_t host_id)
  302. {
  303. assert(is_valid_host(host_id));
  304. esp_err_t ret = spicommon_dma_chan_free(host_id);
  305. free(bus_ctx[host_id]);
  306. bus_ctx[host_id] = NULL;
  307. return ret;
  308. }
  309. //----------------------------------------------------------IO general-------------------------------------------------------//
  310. static bool bus_uses_iomux_pins(spi_host_device_t host, const spi_bus_config_t* bus_config)
  311. {
  312. if (bus_config->sclk_io_num>=0 &&
  313. bus_config->sclk_io_num != spi_periph_signal[host].spiclk_iomux_pin) {
  314. return false;
  315. }
  316. if (bus_config->quadwp_io_num>=0 &&
  317. bus_config->quadwp_io_num != spi_periph_signal[host].spiwp_iomux_pin) {
  318. return false;
  319. }
  320. if (bus_config->quadhd_io_num>=0 &&
  321. bus_config->quadhd_io_num != spi_periph_signal[host].spihd_iomux_pin) {
  322. return false;
  323. }
  324. if (bus_config->mosi_io_num >= 0 &&
  325. bus_config->mosi_io_num != spi_periph_signal[host].spid_iomux_pin) {
  326. return false;
  327. }
  328. if (bus_config->miso_io_num>=0 &&
  329. bus_config->miso_io_num != spi_periph_signal[host].spiq_iomux_pin) {
  330. return false;
  331. }
  332. return true;
  333. }
  334. /*
  335. Do the common stuff to hook up a SPI host to a bus defined by a bunch of GPIO pins. Feed it a host number and a
  336. bus config struct and it'll set up the GPIO matrix and enable the device. If a pin is set to non-negative value,
  337. it should be able to be initialized.
  338. */
  339. esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_config_t *bus_config, uint32_t flags, uint32_t* flags_o)
  340. {
  341. uint32_t temp_flag = 0;
  342. bool miso_need_output;
  343. bool mosi_need_output;
  344. bool sclk_need_output;
  345. if ((flags&SPICOMMON_BUSFLAG_MASTER) != 0) {
  346. //initial for master
  347. miso_need_output = ((flags&SPICOMMON_BUSFLAG_DUAL) != 0) ? true : false;
  348. mosi_need_output = true;
  349. sclk_need_output = true;
  350. } else {
  351. //initial for slave
  352. miso_need_output = true;
  353. mosi_need_output = ((flags&SPICOMMON_BUSFLAG_DUAL) != 0) ? true : false;
  354. sclk_need_output = false;
  355. }
  356. const bool wp_need_output = true;
  357. const bool hd_need_output = true;
  358. //check pin capabilities
  359. if (bus_config->sclk_io_num>=0) {
  360. temp_flag |= SPICOMMON_BUSFLAG_SCLK;
  361. SPI_CHECK_PIN(bus_config->sclk_io_num, "sclk", sclk_need_output);
  362. }
  363. if (bus_config->quadwp_io_num>=0) {
  364. SPI_CHECK_PIN(bus_config->quadwp_io_num, "wp", wp_need_output);
  365. }
  366. if (bus_config->quadhd_io_num>=0) {
  367. SPI_CHECK_PIN(bus_config->quadhd_io_num, "hd", hd_need_output);
  368. }
  369. //set flags for QUAD mode according to the existence of wp and hd
  370. if (bus_config->quadhd_io_num >= 0 && bus_config->quadwp_io_num >= 0) temp_flag |= SPICOMMON_BUSFLAG_WPHD;
  371. if (bus_config->mosi_io_num >= 0) {
  372. temp_flag |= SPICOMMON_BUSFLAG_MOSI;
  373. SPI_CHECK_PIN(bus_config->mosi_io_num, "mosi", mosi_need_output);
  374. }
  375. if (bus_config->miso_io_num>=0) {
  376. temp_flag |= SPICOMMON_BUSFLAG_MISO;
  377. SPI_CHECK_PIN(bus_config->miso_io_num, "miso", miso_need_output);
  378. }
  379. //set flags for DUAL mode according to output-capability of MOSI and MISO pins.
  380. if ( (bus_config->mosi_io_num < 0 || GPIO_IS_VALID_OUTPUT_GPIO(bus_config->mosi_io_num)) &&
  381. (bus_config->miso_io_num < 0 || GPIO_IS_VALID_OUTPUT_GPIO(bus_config->miso_io_num)) ) {
  382. temp_flag |= SPICOMMON_BUSFLAG_DUAL;
  383. }
  384. //check if the selected pins correspond to the iomux pins of the peripheral
  385. bool use_iomux = !(flags & SPICOMMON_BUSFLAG_GPIO_PINS) && bus_uses_iomux_pins(host, bus_config);
  386. if (use_iomux) {
  387. temp_flag |= SPICOMMON_BUSFLAG_IOMUX_PINS;
  388. } else {
  389. temp_flag |= SPICOMMON_BUSFLAG_GPIO_PINS;
  390. }
  391. uint32_t missing_flag = flags & ~temp_flag;
  392. missing_flag &= ~SPICOMMON_BUSFLAG_MASTER;//don't check this flag
  393. if (missing_flag != 0) {
  394. //check pins existence
  395. if (missing_flag & SPICOMMON_BUSFLAG_SCLK) ESP_LOGE(SPI_TAG, "sclk pin required.");
  396. if (missing_flag & SPICOMMON_BUSFLAG_MOSI) ESP_LOGE(SPI_TAG, "mosi pin required.");
  397. if (missing_flag & SPICOMMON_BUSFLAG_MISO) ESP_LOGE(SPI_TAG, "miso pin required.");
  398. if (missing_flag & SPICOMMON_BUSFLAG_DUAL) ESP_LOGE(SPI_TAG, "not both mosi and miso output capable");
  399. if (missing_flag & SPICOMMON_BUSFLAG_WPHD) ESP_LOGE(SPI_TAG, "both wp and hd required.");
  400. if (missing_flag & SPICOMMON_BUSFLAG_IOMUX_PINS) ESP_LOGE(SPI_TAG, "not using iomux pins");
  401. SPI_CHECK(missing_flag == 0, "not all required capabilities satisfied.", ESP_ERR_INVALID_ARG);
  402. }
  403. if (use_iomux) {
  404. //All SPI iomux pin selections resolve to 1, so we put that here instead of trying to figure
  405. //out which FUNC_GPIOx_xSPIxx to grab; they all are defined to 1 anyway.
  406. ESP_LOGD(SPI_TAG, "SPI%d use iomux pins.", host+1);
  407. if (bus_config->mosi_io_num >= 0) {
  408. gpio_iomux_in(bus_config->mosi_io_num, spi_periph_signal[host].spid_in);
  409. gpio_iomux_out(bus_config->mosi_io_num, spi_periph_signal[host].func, false);
  410. }
  411. if (bus_config->miso_io_num >= 0) {
  412. gpio_iomux_in(bus_config->miso_io_num, spi_periph_signal[host].spiq_in);
  413. gpio_iomux_out(bus_config->miso_io_num, spi_periph_signal[host].func, false);
  414. }
  415. if (bus_config->quadwp_io_num >= 0) {
  416. gpio_iomux_in(bus_config->quadwp_io_num, spi_periph_signal[host].spiwp_in);
  417. gpio_iomux_out(bus_config->quadwp_io_num, spi_periph_signal[host].func, false);
  418. }
  419. if (bus_config->quadhd_io_num >= 0) {
  420. gpio_iomux_in(bus_config->quadhd_io_num, spi_periph_signal[host].spihd_in);
  421. gpio_iomux_out(bus_config->quadhd_io_num, spi_periph_signal[host].func, false);
  422. }
  423. if (bus_config->sclk_io_num >= 0) {
  424. gpio_iomux_in(bus_config->sclk_io_num, spi_periph_signal[host].spiclk_in);
  425. gpio_iomux_out(bus_config->sclk_io_num, spi_periph_signal[host].func, false);
  426. }
  427. temp_flag |= SPICOMMON_BUSFLAG_IOMUX_PINS;
  428. } else {
  429. //Use GPIO matrix
  430. ESP_LOGD(SPI_TAG, "SPI%d use gpio matrix.", host+1);
  431. if (bus_config->mosi_io_num >= 0) {
  432. if (mosi_need_output || (temp_flag&SPICOMMON_BUSFLAG_DUAL)) {
  433. gpio_set_direction(bus_config->mosi_io_num, GPIO_MODE_INPUT_OUTPUT);
  434. esp_rom_gpio_connect_out_signal(bus_config->mosi_io_num, spi_periph_signal[host].spid_out, false, false);
  435. } else {
  436. gpio_set_direction(bus_config->mosi_io_num, GPIO_MODE_INPUT);
  437. }
  438. esp_rom_gpio_connect_in_signal(bus_config->mosi_io_num, spi_periph_signal[host].spid_in, false);
  439. #if CONFIG_IDF_TARGET_ESP32S2
  440. PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[bus_config->mosi_io_num]);
  441. #endif
  442. gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[bus_config->mosi_io_num], FUNC_GPIO);
  443. }
  444. if (bus_config->miso_io_num >= 0) {
  445. if (miso_need_output || (temp_flag&SPICOMMON_BUSFLAG_DUAL)) {
  446. gpio_set_direction(bus_config->miso_io_num, GPIO_MODE_INPUT_OUTPUT);
  447. esp_rom_gpio_connect_out_signal(bus_config->miso_io_num, spi_periph_signal[host].spiq_out, false, false);
  448. } else {
  449. gpio_set_direction(bus_config->miso_io_num, GPIO_MODE_INPUT);
  450. }
  451. esp_rom_gpio_connect_in_signal(bus_config->miso_io_num, spi_periph_signal[host].spiq_in, false);
  452. #if CONFIG_IDF_TARGET_ESP32S2
  453. PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[bus_config->miso_io_num]);
  454. #endif
  455. gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[bus_config->miso_io_num], FUNC_GPIO);
  456. }
  457. if (bus_config->quadwp_io_num >= 0) {
  458. gpio_set_direction(bus_config->quadwp_io_num, GPIO_MODE_INPUT_OUTPUT);
  459. esp_rom_gpio_connect_out_signal(bus_config->quadwp_io_num, spi_periph_signal[host].spiwp_out, false, false);
  460. esp_rom_gpio_connect_in_signal(bus_config->quadwp_io_num, spi_periph_signal[host].spiwp_in, false);
  461. #if CONFIG_IDF_TARGET_ESP32S2
  462. PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[bus_config->quadwp_io_num]);
  463. #endif
  464. gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[bus_config->quadwp_io_num], FUNC_GPIO);
  465. }
  466. if (bus_config->quadhd_io_num >= 0) {
  467. gpio_set_direction(bus_config->quadhd_io_num, GPIO_MODE_INPUT_OUTPUT);
  468. esp_rom_gpio_connect_out_signal(bus_config->quadhd_io_num, spi_periph_signal[host].spihd_out, false, false);
  469. esp_rom_gpio_connect_in_signal(bus_config->quadhd_io_num, spi_periph_signal[host].spihd_in, false);
  470. #if CONFIG_IDF_TARGET_ESP32S2
  471. PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[bus_config->quadhd_io_num]);
  472. #endif
  473. gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[bus_config->quadhd_io_num], FUNC_GPIO);
  474. }
  475. if (bus_config->sclk_io_num >= 0) {
  476. if (sclk_need_output) {
  477. gpio_set_direction(bus_config->sclk_io_num, GPIO_MODE_INPUT_OUTPUT);
  478. esp_rom_gpio_connect_out_signal(bus_config->sclk_io_num, spi_periph_signal[host].spiclk_out, false, false);
  479. } else {
  480. gpio_set_direction(bus_config->sclk_io_num, GPIO_MODE_INPUT);
  481. }
  482. esp_rom_gpio_connect_in_signal(bus_config->sclk_io_num, spi_periph_signal[host].spiclk_in, false);
  483. #if CONFIG_IDF_TARGET_ESP32S2
  484. PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[bus_config->sclk_io_num]);
  485. #endif
  486. gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[bus_config->sclk_io_num], FUNC_GPIO);
  487. }
  488. }
  489. if (flags_o) *flags_o = temp_flag;
  490. return ESP_OK;
  491. }
  492. esp_err_t spicommon_bus_free_io_cfg(const spi_bus_config_t *bus_cfg)
  493. {
  494. int pin_array[] = {
  495. bus_cfg->mosi_io_num,
  496. bus_cfg->miso_io_num,
  497. bus_cfg->sclk_io_num,
  498. bus_cfg->quadwp_io_num,
  499. bus_cfg->quadhd_io_num,
  500. };
  501. for (int i = 0; i < sizeof(pin_array)/sizeof(int); i ++) {
  502. const int io = pin_array[i];
  503. if (io >= 0 && GPIO_IS_VALID_GPIO(io)) gpio_reset_pin(io);
  504. }
  505. return ESP_OK;
  506. }
  507. void spicommon_cs_initialize(spi_host_device_t host, int cs_io_num, int cs_num, int force_gpio_matrix)
  508. {
  509. if (!force_gpio_matrix && cs_io_num == spi_periph_signal[host].spics0_iomux_pin && cs_num == 0) {
  510. //The cs0s for all SPI peripherals map to pin mux source 1, so we use that instead of a define.
  511. gpio_iomux_in(cs_io_num, spi_periph_signal[host].spics_in);
  512. gpio_iomux_out(cs_io_num, spi_periph_signal[host].func, false);
  513. } else {
  514. //Use GPIO matrix
  515. if (GPIO_IS_VALID_OUTPUT_GPIO(cs_io_num)) {
  516. gpio_set_direction(cs_io_num, GPIO_MODE_INPUT_OUTPUT);
  517. esp_rom_gpio_connect_out_signal(cs_io_num, spi_periph_signal[host].spics_out[cs_num], false, false);
  518. } else {
  519. gpio_set_direction(cs_io_num, GPIO_MODE_INPUT);
  520. }
  521. if (cs_num == 0) esp_rom_gpio_connect_in_signal(cs_io_num, spi_periph_signal[host].spics_in, false);
  522. PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[cs_io_num]);
  523. gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[cs_io_num], FUNC_GPIO);
  524. }
  525. }
  526. void spicommon_cs_free_io(int cs_gpio_num)
  527. {
  528. assert(cs_gpio_num>=0 && GPIO_IS_VALID_GPIO(cs_gpio_num));
  529. gpio_reset_pin(cs_gpio_num);
  530. }
  531. bool spicommon_bus_using_iomux(spi_host_device_t host)
  532. {
  533. #define CHECK_IOMUX_PIN(HOST, PIN_NAME) if (GPIO.func_in_sel_cfg[spi_periph_signal[(HOST)].PIN_NAME##_in].sig_in_sel) return false
  534. CHECK_IOMUX_PIN(host, spid);
  535. CHECK_IOMUX_PIN(host, spiq);
  536. CHECK_IOMUX_PIN(host, spiwp);
  537. CHECK_IOMUX_PIN(host, spihd);
  538. return true;
  539. }
  540. void spi_bus_main_set_lock(spi_bus_lock_handle_t lock)
  541. {
  542. bus_ctx[0]->bus_attr.lock = lock;
  543. }
  544. spi_bus_lock_handle_t spi_bus_lock_get_by_id(spi_host_device_t host_id)
  545. {
  546. return bus_ctx[host_id]->bus_attr.lock;
  547. }
  548. //----------------------------------------------------------master bus init-------------------------------------------------------//
  549. esp_err_t spi_bus_initialize(spi_host_device_t host_id, const spi_bus_config_t *bus_config, spi_dma_chan_t dma_chan)
  550. {
  551. esp_err_t err = ESP_OK;
  552. spicommon_bus_context_t *ctx = NULL;
  553. spi_bus_attr_t *bus_attr = NULL;
  554. uint32_t actual_tx_dma_chan = 0;
  555. uint32_t actual_rx_dma_chan = 0;
  556. SPI_CHECK(is_valid_host(host_id), "invalid host_id", ESP_ERR_INVALID_ARG);
  557. SPI_CHECK(bus_ctx[host_id] == NULL, "SPI bus already initialized.", ESP_ERR_INVALID_STATE);
  558. #ifdef CONFIG_IDF_TARGET_ESP32
  559. SPI_CHECK(dma_chan >= SPI_DMA_DISABLED && dma_chan <= SPI_DMA_CH_AUTO, "invalid dma channel", ESP_ERR_INVALID_ARG );
  560. #elif CONFIG_IDF_TARGET_ESP32S2
  561. SPI_CHECK( dma_chan == SPI_DMA_DISABLED || dma_chan == (int)host_id || dma_chan == SPI_DMA_CH_AUTO, "invalid dma channel", ESP_ERR_INVALID_ARG );
  562. #elif SOC_GDMA_SUPPORTED
  563. SPI_CHECK( dma_chan == SPI_DMA_DISABLED || dma_chan == SPI_DMA_CH_AUTO, "invalid dma channel, chip only support spi dma channel auto-alloc", ESP_ERR_INVALID_ARG );
  564. #endif
  565. SPI_CHECK((bus_config->intr_flags & (ESP_INTR_FLAG_HIGH|ESP_INTR_FLAG_EDGE|ESP_INTR_FLAG_INTRDISABLED))==0, "intr flag not allowed", ESP_ERR_INVALID_ARG);
  566. #ifndef CONFIG_SPI_MASTER_ISR_IN_IRAM
  567. SPI_CHECK((bus_config->intr_flags & ESP_INTR_FLAG_IRAM)==0, "ESP_INTR_FLAG_IRAM should be disabled when CONFIG_SPI_MASTER_ISR_IN_IRAM is not set.", ESP_ERR_INVALID_ARG);
  568. #endif
  569. bool spi_chan_claimed = spicommon_periph_claim(host_id, "spi master");
  570. SPI_CHECK(spi_chan_claimed, "host_id already in use", ESP_ERR_INVALID_STATE);
  571. //clean and initialize the context
  572. ctx = (spicommon_bus_context_t *)calloc(1, sizeof(spicommon_bus_context_t));
  573. if (!ctx) {
  574. err = ESP_ERR_NO_MEM;
  575. goto cleanup;
  576. }
  577. bus_ctx[host_id] = ctx;
  578. ctx->host_id = host_id;
  579. bus_attr = &ctx->bus_attr;
  580. bus_attr->bus_cfg = *bus_config;
  581. if (dma_chan != SPI_DMA_DISABLED) {
  582. bus_attr->dma_enabled = 1;
  583. err = spicommon_dma_chan_alloc(host_id, dma_chan, &actual_tx_dma_chan, &actual_rx_dma_chan);
  584. if (err != ESP_OK) {
  585. goto cleanup;
  586. }
  587. bus_attr->tx_dma_chan = actual_tx_dma_chan;
  588. bus_attr->rx_dma_chan = actual_rx_dma_chan;
  589. int dma_desc_ct = lldesc_get_required_num(bus_config->max_transfer_sz);
  590. if (dma_desc_ct == 0) dma_desc_ct = 1; //default to 4k when max is not given
  591. bus_attr->max_transfer_sz = dma_desc_ct * LLDESC_MAX_NUM_PER_DESC;
  592. bus_attr->dmadesc_tx = heap_caps_malloc(sizeof(lldesc_t) * dma_desc_ct, MALLOC_CAP_DMA);
  593. bus_attr->dmadesc_rx = heap_caps_malloc(sizeof(lldesc_t) * dma_desc_ct, MALLOC_CAP_DMA);
  594. if (bus_attr->dmadesc_tx == NULL || bus_attr->dmadesc_rx == NULL) {
  595. err = ESP_ERR_NO_MEM;
  596. goto cleanup;
  597. }
  598. bus_attr->dma_desc_num = dma_desc_ct;
  599. } else {
  600. bus_attr->dma_enabled = 0;
  601. bus_attr->max_transfer_sz = SOC_SPI_MAXIMUM_BUFFER_SIZE;
  602. bus_attr->dma_desc_num = 0;
  603. }
  604. spi_bus_lock_config_t lock_config = {
  605. .host_id = host_id,
  606. .cs_num = SOC_SPI_PERIPH_CS_NUM(host_id),
  607. };
  608. err = spi_bus_init_lock(&bus_attr->lock, &lock_config);
  609. if (err != ESP_OK) {
  610. goto cleanup;
  611. }
  612. #ifdef CONFIG_PM_ENABLE
  613. err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "spi_master",
  614. &bus_attr->pm_lock);
  615. if (err != ESP_OK) {
  616. goto cleanup;
  617. }
  618. #endif //CONFIG_PM_ENABLE
  619. err = spicommon_bus_initialize_io(host_id, bus_config, SPICOMMON_BUSFLAG_MASTER | bus_config->flags, &bus_attr->flags);
  620. if (err != ESP_OK) {
  621. goto cleanup;
  622. }
  623. return ESP_OK;
  624. cleanup:
  625. if (bus_attr) {
  626. #ifdef CONFIG_PM_ENABLE
  627. esp_pm_lock_delete(bus_attr->pm_lock);
  628. #endif
  629. if (bus_attr->lock) {
  630. spi_bus_deinit_lock(bus_attr->lock);
  631. }
  632. free(bus_attr->dmadesc_tx);
  633. free(bus_attr->dmadesc_rx);
  634. bus_attr->dmadesc_tx = NULL;
  635. bus_attr->dmadesc_rx = NULL;
  636. if (bus_attr->dma_enabled) {
  637. spicommon_dma_chan_free(host_id);
  638. }
  639. }
  640. spicommon_periph_free(host_id);
  641. free(bus_ctx[host_id]);
  642. bus_ctx[host_id] = NULL;
  643. return err;
  644. }
  645. const spi_bus_attr_t* spi_bus_get_attr(spi_host_device_t host_id)
  646. {
  647. if (bus_ctx[host_id] == NULL) return NULL;
  648. return &bus_ctx[host_id]->bus_attr;
  649. }
  650. esp_err_t spi_bus_free(spi_host_device_t host_id)
  651. {
  652. esp_err_t err = ESP_OK;
  653. spicommon_bus_context_t* ctx = bus_ctx[host_id];
  654. spi_bus_attr_t* bus_attr = &ctx->bus_attr;
  655. if (ctx->destroy_func) {
  656. err = ctx->destroy_func(ctx->destroy_arg);
  657. }
  658. spicommon_bus_free_io_cfg(&bus_attr->bus_cfg);
  659. #ifdef CONFIG_PM_ENABLE
  660. esp_pm_lock_delete(bus_attr->pm_lock);
  661. #endif
  662. spi_bus_deinit_lock(bus_attr->lock);
  663. free(bus_attr->dmadesc_rx);
  664. free(bus_attr->dmadesc_tx);
  665. bus_attr->dmadesc_tx = NULL;
  666. bus_attr->dmadesc_rx = NULL;
  667. if (bus_attr->dma_enabled > 0) {
  668. spicommon_dma_chan_free(host_id);
  669. }
  670. spicommon_periph_free(host_id);
  671. free(ctx);
  672. bus_ctx[host_id] = NULL;
  673. return err;
  674. }
  675. esp_err_t spi_bus_register_destroy_func(spi_host_device_t host_id,
  676. spi_destroy_func_t f, void *arg)
  677. {
  678. bus_ctx[host_id]->destroy_func = f;
  679. bus_ctx[host_id]->destroy_arg = arg;
  680. return ESP_OK;
  681. }
  682. /*
  683. Code for workaround for DMA issue in ESP32 v0/v1 silicon
  684. */
  685. #if CONFIG_IDF_TARGET_ESP32
  686. static volatile int dmaworkaround_channels_busy[2] = {0, 0};
  687. static dmaworkaround_cb_t dmaworkaround_cb;
  688. static void *dmaworkaround_cb_arg;
  689. static portMUX_TYPE dmaworkaround_mux = portMUX_INITIALIZER_UNLOCKED;
  690. static int dmaworkaround_waiting_for_chan = 0;
  691. #endif
  692. bool IRAM_ATTR spicommon_dmaworkaround_req_reset(int dmachan, dmaworkaround_cb_t cb, void *arg)
  693. {
  694. #if CONFIG_IDF_TARGET_ESP32
  695. int otherchan = (dmachan == 1) ? 2 : 1;
  696. bool ret;
  697. portENTER_CRITICAL_ISR(&dmaworkaround_mux);
  698. if (dmaworkaround_channels_busy[otherchan-1]) {
  699. //Other channel is busy. Call back when it's done.
  700. dmaworkaround_cb = cb;
  701. dmaworkaround_cb_arg = arg;
  702. dmaworkaround_waiting_for_chan = otherchan;
  703. ret = false;
  704. } else {
  705. //Reset DMA
  706. periph_module_reset( PERIPH_SPI_DMA_MODULE );
  707. ret = true;
  708. }
  709. portEXIT_CRITICAL_ISR(&dmaworkaround_mux);
  710. return ret;
  711. #else
  712. //no need to reset
  713. return true;
  714. #endif
  715. }
  716. bool IRAM_ATTR spicommon_dmaworkaround_reset_in_progress(void)
  717. {
  718. #if CONFIG_IDF_TARGET_ESP32
  719. return (dmaworkaround_waiting_for_chan != 0);
  720. #else
  721. return false;
  722. #endif
  723. }
  724. void IRAM_ATTR spicommon_dmaworkaround_idle(int dmachan)
  725. {
  726. #if CONFIG_IDF_TARGET_ESP32
  727. portENTER_CRITICAL_ISR(&dmaworkaround_mux);
  728. dmaworkaround_channels_busy[dmachan-1] = 0;
  729. if (dmaworkaround_waiting_for_chan == dmachan) {
  730. //Reset DMA
  731. periph_module_reset( PERIPH_SPI_DMA_MODULE );
  732. dmaworkaround_waiting_for_chan = 0;
  733. //Call callback
  734. dmaworkaround_cb(dmaworkaround_cb_arg);
  735. }
  736. portEXIT_CRITICAL_ISR(&dmaworkaround_mux);
  737. #endif
  738. }
  739. void IRAM_ATTR spicommon_dmaworkaround_transfer_active(int dmachan)
  740. {
  741. #if CONFIG_IDF_TARGET_ESP32
  742. portENTER_CRITICAL_ISR(&dmaworkaround_mux);
  743. dmaworkaround_channels_busy[dmachan-1] = 1;
  744. portEXIT_CRITICAL_ISR(&dmaworkaround_mux);
  745. #endif
  746. }