spi.c 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032
  1. /*
  2. * This file is part of the MicroPython project, http://micropython.org/
  3. *
  4. * The MIT License (MIT)
  5. *
  6. * Copyright (c) 2013, 2014 Damien P. George
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining a copy
  9. * of this software and associated documentation files (the "Software"), to deal
  10. * in the Software without restriction, including without limitation the rights
  11. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. * copies of the Software, and to permit persons to whom the Software is
  13. * furnished to do so, subject to the following conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be included in
  16. * all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24. * THE SOFTWARE.
  25. */
  26. #include <stdio.h>
  27. #include <string.h>
  28. #include "py/runtime.h"
  29. #include "py/mphal.h"
  30. #include "extmod/machine_spi.h"
  31. #include "irq.h"
  32. #include "pin.h"
  33. #include "bufhelper.h"
  34. #include "spi.h"
  35. /// \moduleref pyb
  36. /// \class SPI - a master-driven serial protocol
  37. ///
  38. /// SPI is a serial protocol that is driven by a master. At the physical level
  39. /// there are 3 lines: SCK, MOSI, MISO.
  40. ///
  41. /// See usage model of I2C; SPI is very similar. Main difference is
  42. /// parameters to init the SPI bus:
  43. ///
  44. /// from pyb import SPI
  45. /// spi = SPI(1, SPI.MASTER, baudrate=600000, polarity=1, phase=0, crc=0x7)
  46. ///
  47. /// Only required parameter is mode, SPI.MASTER or SPI.SLAVE. Polarity can be
  48. /// 0 or 1, and is the level the idle clock line sits at. Phase can be 0 or 1
  49. /// to sample data on the first or second clock edge respectively. Crc can be
  50. /// None for no CRC, or a polynomial specifier.
  51. ///
  52. /// Additional method for SPI:
  53. ///
  54. /// data = spi.send_recv(b'1234') # send 4 bytes and receive 4 bytes
  55. /// buf = bytearray(4)
  56. /// spi.send_recv(b'1234', buf) # send 4 bytes and receive 4 into buf
  57. /// spi.send_recv(buf, buf) # send/recv 4 bytes from/to buf
  58. // Possible DMA configurations for SPI busses:
  59. // SPI1_TX: DMA2_Stream3.CHANNEL_3 or DMA2_Stream5.CHANNEL_3
  60. // SPI1_RX: DMA2_Stream0.CHANNEL_3 or DMA2_Stream2.CHANNEL_3
  61. // SPI2_TX: DMA1_Stream4.CHANNEL_0
  62. // SPI2_RX: DMA1_Stream3.CHANNEL_0
  63. // SPI3_TX: DMA1_Stream5.CHANNEL_0 or DMA1_Stream7.CHANNEL_0
  64. // SPI3_RX: DMA1_Stream0.CHANNEL_0 or DMA1_Stream2.CHANNEL_0
  65. // SPI4_TX: DMA2_Stream4.CHANNEL_5 or DMA2_Stream1.CHANNEL_4
  66. // SPI4_RX: DMA2_Stream3.CHANNEL_5 or DMA2_Stream0.CHANNEL_4
  67. // SPI5_TX: DMA2_Stream4.CHANNEL_2 or DMA2_Stream6.CHANNEL_7
  68. // SPI5_RX: DMA2_Stream3.CHANNEL_2 or DMA2_Stream5.CHANNEL_7
  69. // SPI6_TX: DMA2_Stream5.CHANNEL_1
  70. // SPI6_RX: DMA2_Stream6.CHANNEL_1
  71. #if defined(MICROPY_HW_SPI1_SCK)
  72. SPI_HandleTypeDef SPIHandle1 = {.Instance = NULL};
  73. #endif
  74. #if defined(MICROPY_HW_SPI2_SCK)
  75. SPI_HandleTypeDef SPIHandle2 = {.Instance = NULL};
  76. #endif
  77. #if defined(MICROPY_HW_SPI3_SCK)
  78. SPI_HandleTypeDef SPIHandle3 = {.Instance = NULL};
  79. #endif
  80. #if defined(MICROPY_HW_SPI4_SCK)
  81. SPI_HandleTypeDef SPIHandle4 = {.Instance = NULL};
  82. #endif
  83. #if defined(MICROPY_HW_SPI5_SCK)
  84. SPI_HandleTypeDef SPIHandle5 = {.Instance = NULL};
  85. #endif
  86. #if defined(MICROPY_HW_SPI6_SCK)
  87. SPI_HandleTypeDef SPIHandle6 = {.Instance = NULL};
  88. #endif
  89. const spi_t spi_obj[6] = {
  90. #if defined(MICROPY_HW_SPI1_SCK)
  91. {&SPIHandle1, &dma_SPI_1_TX, &dma_SPI_1_RX},
  92. #else
  93. {NULL, NULL, NULL},
  94. #endif
  95. #if defined(MICROPY_HW_SPI2_SCK)
  96. {&SPIHandle2, &dma_SPI_2_TX, &dma_SPI_2_RX},
  97. #else
  98. {NULL, NULL, NULL},
  99. #endif
  100. #if defined(MICROPY_HW_SPI3_SCK)
  101. {&SPIHandle3, &dma_SPI_3_TX, &dma_SPI_3_RX},
  102. #else
  103. {NULL, NULL, NULL},
  104. #endif
  105. #if defined(MICROPY_HW_SPI4_SCK)
  106. {&SPIHandle4, &dma_SPI_4_TX, &dma_SPI_4_RX},
  107. #else
  108. {NULL, NULL, NULL},
  109. #endif
  110. #if defined(MICROPY_HW_SPI5_SCK)
  111. {&SPIHandle5, &dma_SPI_5_TX, &dma_SPI_5_RX},
  112. #else
  113. {NULL, NULL, NULL},
  114. #endif
  115. #if defined(MICROPY_HW_SPI6_SCK)
  116. {&SPIHandle6, &dma_SPI_6_TX, &dma_SPI_6_RX},
  117. #else
  118. {NULL, NULL, NULL},
  119. #endif
  120. };
  121. void spi_init0(void) {
  122. // Initialise the SPI handles.
  123. // The structs live on the BSS so all other fields will be zero after a reset.
  124. #if defined(MICROPY_HW_SPI1_SCK)
  125. SPIHandle1.Instance = SPI1;
  126. #endif
  127. #if defined(MICROPY_HW_SPI2_SCK)
  128. SPIHandle2.Instance = SPI2;
  129. #endif
  130. #if defined(MICROPY_HW_SPI3_SCK)
  131. SPIHandle3.Instance = SPI3;
  132. #endif
  133. #if defined(MICROPY_HW_SPI4_SCK)
  134. SPIHandle4.Instance = SPI4;
  135. #endif
  136. #if defined(MICROPY_HW_SPI5_SCK)
  137. SPIHandle5.Instance = SPI5;
  138. #endif
  139. #if defined(MICROPY_HW_SPI6_SCK)
  140. SPIHandle6.Instance = SPI6;
  141. #endif
  142. }
  143. STATIC int spi_find(mp_obj_t id) {
  144. if (MP_OBJ_IS_STR(id)) {
  145. // given a string id
  146. const char *port = mp_obj_str_get_str(id);
  147. if (0) {
  148. #ifdef MICROPY_HW_SPI1_NAME
  149. } else if (strcmp(port, MICROPY_HW_SPI1_NAME) == 0) {
  150. return 1;
  151. #endif
  152. #ifdef MICROPY_HW_SPI2_NAME
  153. } else if (strcmp(port, MICROPY_HW_SPI2_NAME) == 0) {
  154. return 2;
  155. #endif
  156. #ifdef MICROPY_HW_SPI3_NAME
  157. } else if (strcmp(port, MICROPY_HW_SPI3_NAME) == 0) {
  158. return 3;
  159. #endif
  160. #ifdef MICROPY_HW_SPI4_NAME
  161. } else if (strcmp(port, MICROPY_HW_SPI4_NAME) == 0) {
  162. return 4;
  163. #endif
  164. #ifdef MICROPY_HW_SPI5_NAME
  165. } else if (strcmp(port, MICROPY_HW_SPI5_NAME) == 0) {
  166. return 5;
  167. #endif
  168. #ifdef MICROPY_HW_SPI6_NAME
  169. } else if (strcmp(port, MICROPY_HW_SPI6_NAME) == 0) {
  170. return 6;
  171. #endif
  172. }
  173. nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
  174. "SPI(%s) doesn't exist", port));
  175. } else {
  176. // given an integer id
  177. int spi_id = mp_obj_get_int(id);
  178. if (spi_id >= 1 && spi_id <= MP_ARRAY_SIZE(spi_obj)
  179. && spi_obj[spi_id - 1].spi != NULL) {
  180. return spi_id;
  181. }
  182. nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
  183. "SPI(%d) doesn't exist", spi_id));
  184. }
  185. }
  186. // sets the parameters in the SPI_InitTypeDef struct
  187. // if an argument is -1 then the corresponding parameter is not changed
  188. STATIC void spi_set_params(const spi_t *spi_obj, uint32_t prescale, int32_t baudrate,
  189. int32_t polarity, int32_t phase, int32_t bits, int32_t firstbit) {
  190. SPI_HandleTypeDef *spi = spi_obj->spi;
  191. SPI_InitTypeDef *init = &spi->Init;
  192. if (prescale != 0xffffffff || baudrate != -1) {
  193. if (prescale == 0xffffffff) {
  194. // prescaler not given, so select one that yields at most the requested baudrate
  195. mp_uint_t spi_clock;
  196. #if defined(STM32F0)
  197. spi_clock = HAL_RCC_GetPCLK1Freq();
  198. #else
  199. if (spi->Instance == SPI2 || spi->Instance == SPI3) {
  200. // SPI2 and SPI3 are on APB1
  201. spi_clock = HAL_RCC_GetPCLK1Freq();
  202. } else {
  203. // SPI1, SPI4, SPI5 and SPI6 are on APB2
  204. spi_clock = HAL_RCC_GetPCLK2Freq();
  205. }
  206. #endif
  207. prescale = spi_clock / baudrate;
  208. }
  209. if (prescale <= 2) { init->BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; }
  210. else if (prescale <= 4) { init->BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; }
  211. else if (prescale <= 8) { init->BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; }
  212. else if (prescale <= 16) { init->BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; }
  213. else if (prescale <= 32) { init->BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32; }
  214. else if (prescale <= 64) { init->BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64; }
  215. else if (prescale <= 128) { init->BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128; }
  216. else { init->BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256; }
  217. }
  218. if (polarity != -1) {
  219. init->CLKPolarity = polarity == 0 ? SPI_POLARITY_LOW : SPI_POLARITY_HIGH;
  220. }
  221. if (phase != -1) {
  222. init->CLKPhase = phase == 0 ? SPI_PHASE_1EDGE : SPI_PHASE_2EDGE;
  223. }
  224. if (bits != -1) {
  225. init->DataSize = (bits == 16) ? SPI_DATASIZE_16BIT : SPI_DATASIZE_8BIT;
  226. }
  227. if (firstbit != -1) {
  228. init->FirstBit = firstbit;
  229. }
  230. }
  231. // TODO allow to take a list of pins to use
  232. void spi_init(const spi_t *self, bool enable_nss_pin) {
  233. SPI_HandleTypeDef *spi = self->spi;
  234. const pin_obj_t *pins[4] = { NULL, NULL, NULL, NULL };
  235. if (0) {
  236. #if defined(MICROPY_HW_SPI1_SCK)
  237. } else if (spi->Instance == SPI1) {
  238. #if defined(MICROPY_HW_SPI1_NSS)
  239. pins[0] = MICROPY_HW_SPI1_NSS;
  240. #endif
  241. pins[1] = MICROPY_HW_SPI1_SCK;
  242. #if defined(MICROPY_HW_SPI1_MISO)
  243. pins[2] = MICROPY_HW_SPI1_MISO;
  244. #endif
  245. pins[3] = MICROPY_HW_SPI1_MOSI;
  246. // enable the SPI clock
  247. __HAL_RCC_SPI1_CLK_ENABLE();
  248. #endif
  249. #if defined(MICROPY_HW_SPI2_SCK)
  250. } else if (spi->Instance == SPI2) {
  251. #if defined(MICROPY_HW_SPI2_NSS)
  252. pins[0] = MICROPY_HW_SPI2_NSS;
  253. #endif
  254. pins[1] = MICROPY_HW_SPI2_SCK;
  255. #if defined(MICROPY_HW_SPI2_MISO)
  256. pins[2] = MICROPY_HW_SPI2_MISO;
  257. #endif
  258. pins[3] = MICROPY_HW_SPI2_MOSI;
  259. // enable the SPI clock
  260. __HAL_RCC_SPI2_CLK_ENABLE();
  261. #endif
  262. #if defined(MICROPY_HW_SPI3_SCK)
  263. } else if (spi->Instance == SPI3) {
  264. #if defined(MICROPY_HW_SPI3_NSS)
  265. pins[0] = MICROPY_HW_SPI3_NSS;
  266. #endif
  267. pins[1] = MICROPY_HW_SPI3_SCK;
  268. #if defined(MICROPY_HW_SPI3_MISO)
  269. pins[2] = MICROPY_HW_SPI3_MISO;
  270. #endif
  271. pins[3] = MICROPY_HW_SPI3_MOSI;
  272. // enable the SPI clock
  273. __HAL_RCC_SPI3_CLK_ENABLE();
  274. #endif
  275. #if defined(MICROPY_HW_SPI4_SCK)
  276. } else if (spi->Instance == SPI4) {
  277. #if defined(MICROPY_HW_SPI4_NSS)
  278. pins[0] = MICROPY_HW_SPI4_NSS;
  279. #endif
  280. pins[1] = MICROPY_HW_SPI4_SCK;
  281. #if defined(MICROPY_HW_SPI4_MISO)
  282. pins[2] = MICROPY_HW_SPI4_MISO;
  283. #endif
  284. pins[3] = MICROPY_HW_SPI4_MOSI;
  285. // enable the SPI clock
  286. __HAL_RCC_SPI4_CLK_ENABLE();
  287. #endif
  288. #if defined(MICROPY_HW_SPI5_SCK)
  289. } else if (spi->Instance == SPI5) {
  290. #if defined(MICROPY_HW_SPI5_NSS)
  291. pins[0] = MICROPY_HW_SPI5_NSS;
  292. #endif
  293. pins[1] = MICROPY_HW_SPI5_SCK;
  294. #if defined(MICROPY_HW_SPI5_MISO)
  295. pins[2] = MICROPY_HW_SPI5_MISO;
  296. #endif
  297. pins[3] = MICROPY_HW_SPI5_MOSI;
  298. // enable the SPI clock
  299. __HAL_RCC_SPI5_CLK_ENABLE();
  300. #endif
  301. #if defined(MICROPY_HW_SPI6_SCK)
  302. } else if (spi->Instance == SPI6) {
  303. #if defined(MICROPY_HW_SPI6_NSS)
  304. pins[0] = MICROPY_HW_SPI6_NSS;
  305. #endif
  306. pins[1] = MICROPY_HW_SPI6_SCK;
  307. #if defined(MICROPY_HW_SPI6_MISO)
  308. pins[2] = MICROPY_HW_SPI6_MISO;
  309. #endif
  310. pins[3] = MICROPY_HW_SPI6_MOSI;
  311. // enable the SPI clock
  312. __HAL_RCC_SPI6_CLK_ENABLE();
  313. #endif
  314. } else {
  315. // SPI does not exist for this board (shouldn't get here, should be checked by caller)
  316. return;
  317. }
  318. // init the GPIO lines
  319. uint32_t mode = MP_HAL_PIN_MODE_ALT;
  320. uint32_t pull = spi->Init.CLKPolarity == SPI_POLARITY_LOW ? MP_HAL_PIN_PULL_DOWN : MP_HAL_PIN_PULL_UP;
  321. for (uint i = (enable_nss_pin ? 0 : 1); i < 4; i++) {
  322. if (pins[i] == NULL) {
  323. continue;
  324. }
  325. mp_hal_pin_config_alt(pins[i], mode, pull, AF_FN_SPI, (self - &spi_obj[0]) + 1);
  326. }
  327. // init the SPI device
  328. if (HAL_SPI_Init(spi) != HAL_OK) {
  329. // init error
  330. // TODO should raise an exception, but this function is not necessarily going to be
  331. // called via Python, so may not be properly wrapped in an NLR handler
  332. printf("OSError: HAL_SPI_Init failed\n");
  333. return;
  334. }
  335. // After calling HAL_SPI_Init() it seems that the DMA gets disconnected if
  336. // it was previously configured. So we invalidate the DMA channel to force
  337. // an initialisation the next time we use it.
  338. dma_invalidate_channel(self->tx_dma_descr);
  339. dma_invalidate_channel(self->rx_dma_descr);
  340. }
  341. void spi_deinit(const spi_t *spi_obj) {
  342. SPI_HandleTypeDef *spi = spi_obj->spi;
  343. HAL_SPI_DeInit(spi);
  344. if (0) {
  345. #if defined(MICROPY_HW_SPI1_SCK)
  346. } else if (spi->Instance == SPI1) {
  347. __HAL_RCC_SPI1_FORCE_RESET();
  348. __HAL_RCC_SPI1_RELEASE_RESET();
  349. __HAL_RCC_SPI1_CLK_DISABLE();
  350. #endif
  351. #if defined(MICROPY_HW_SPI2_SCK)
  352. } else if (spi->Instance == SPI2) {
  353. __HAL_RCC_SPI2_FORCE_RESET();
  354. __HAL_RCC_SPI2_RELEASE_RESET();
  355. __HAL_RCC_SPI2_CLK_DISABLE();
  356. #endif
  357. #if defined(MICROPY_HW_SPI3_SCK)
  358. } else if (spi->Instance == SPI3) {
  359. __HAL_RCC_SPI3_FORCE_RESET();
  360. __HAL_RCC_SPI3_RELEASE_RESET();
  361. __HAL_RCC_SPI3_CLK_DISABLE();
  362. #endif
  363. #if defined(MICROPY_HW_SPI4_SCK)
  364. } else if (spi->Instance == SPI4) {
  365. __HAL_RCC_SPI4_FORCE_RESET();
  366. __HAL_RCC_SPI4_RELEASE_RESET();
  367. __HAL_RCC_SPI4_CLK_DISABLE();
  368. #endif
  369. #if defined(MICROPY_HW_SPI5_SCK)
  370. } else if (spi->Instance == SPI5) {
  371. __HAL_RCC_SPI5_FORCE_RESET();
  372. __HAL_RCC_SPI5_RELEASE_RESET();
  373. __HAL_RCC_SPI5_CLK_DISABLE();
  374. #endif
  375. #if defined(MICROPY_HW_SPI6_SCK)
  376. } else if (spi->Instance == SPI6) {
  377. __HAL_RCC_SPI6_FORCE_RESET();
  378. __HAL_RCC_SPI6_RELEASE_RESET();
  379. __HAL_RCC_SPI6_CLK_DISABLE();
  380. #endif
  381. }
  382. }
  383. STATIC HAL_StatusTypeDef spi_wait_dma_finished(const spi_t *spi, uint32_t t_start, uint32_t timeout) {
  384. volatile HAL_SPI_StateTypeDef *state = &spi->spi->State;
  385. for (;;) {
  386. // Do an atomic check of the state; WFI will exit even if IRQs are disabled
  387. uint32_t irq_state = disable_irq();
  388. if (*state == HAL_SPI_STATE_READY) {
  389. enable_irq(irq_state);
  390. return HAL_OK;
  391. }
  392. __WFI();
  393. enable_irq(irq_state);
  394. if (HAL_GetTick() - t_start >= timeout) {
  395. return HAL_TIMEOUT;
  396. }
  397. }
  398. return HAL_OK;
  399. }
  400. // A transfer of "len" bytes should take len*8*1000/baudrate milliseconds.
  401. // To simplify the calculation we assume the baudrate is never less than 8kHz
  402. // and use that value for the baudrate in the formula, plus a small constant.
  403. #define SPI_TRANSFER_TIMEOUT(len) ((len) + 100)
  404. STATIC void spi_transfer(const spi_t *self, size_t len, const uint8_t *src, uint8_t *dest, uint32_t timeout) {
  405. // Note: there seems to be a problem sending 1 byte using DMA the first
  406. // time directly after the SPI/DMA is initialised. The cause of this is
  407. // unknown but we sidestep the issue by using polling for 1 byte transfer.
  408. // Note: DMA transfers are limited to 65535 bytes at a time.
  409. HAL_StatusTypeDef status;
  410. if (dest == NULL) {
  411. // send only
  412. if (len == 1 || query_irq() == IRQ_STATE_DISABLED) {
  413. status = HAL_SPI_Transmit(self->spi, (uint8_t*)src, len, timeout);
  414. } else {
  415. DMA_HandleTypeDef tx_dma;
  416. dma_init(&tx_dma, self->tx_dma_descr, self->spi);
  417. self->spi->hdmatx = &tx_dma;
  418. self->spi->hdmarx = NULL;
  419. MP_HAL_CLEAN_DCACHE(src, len);
  420. uint32_t t_start = HAL_GetTick();
  421. do {
  422. uint32_t l = MIN(len, 65535);
  423. status = HAL_SPI_Transmit_DMA(self->spi, (uint8_t*)src, l);
  424. if (status != HAL_OK) {
  425. break;
  426. }
  427. status = spi_wait_dma_finished(self, t_start, timeout);
  428. if (status != HAL_OK) {
  429. break;
  430. }
  431. len -= l;
  432. src += l;
  433. } while (len);
  434. dma_deinit(self->tx_dma_descr);
  435. }
  436. } else if (src == NULL) {
  437. // receive only
  438. if (len == 1 || query_irq() == IRQ_STATE_DISABLED) {
  439. status = HAL_SPI_Receive(self->spi, dest, len, timeout);
  440. } else {
  441. DMA_HandleTypeDef tx_dma, rx_dma;
  442. if (self->spi->Init.Mode == SPI_MODE_MASTER) {
  443. // in master mode the HAL actually does a TransmitReceive call
  444. dma_init(&tx_dma, self->tx_dma_descr, self->spi);
  445. self->spi->hdmatx = &tx_dma;
  446. } else {
  447. self->spi->hdmatx = NULL;
  448. }
  449. dma_init(&rx_dma, self->rx_dma_descr, self->spi);
  450. self->spi->hdmarx = &rx_dma;
  451. MP_HAL_CLEANINVALIDATE_DCACHE(dest, len);
  452. uint32_t t_start = HAL_GetTick();
  453. do {
  454. uint32_t l = MIN(len, 65535);
  455. status = HAL_SPI_Receive_DMA(self->spi, dest, l);
  456. if (status != HAL_OK) {
  457. break;
  458. }
  459. status = spi_wait_dma_finished(self, t_start, timeout);
  460. if (status != HAL_OK) {
  461. break;
  462. }
  463. len -= l;
  464. dest += l;
  465. } while (len);
  466. if (self->spi->hdmatx != NULL) {
  467. dma_deinit(self->tx_dma_descr);
  468. }
  469. dma_deinit(self->rx_dma_descr);
  470. }
  471. } else {
  472. // send and receive
  473. if (len == 1 || query_irq() == IRQ_STATE_DISABLED) {
  474. status = HAL_SPI_TransmitReceive(self->spi, (uint8_t*)src, dest, len, timeout);
  475. } else {
  476. DMA_HandleTypeDef tx_dma, rx_dma;
  477. dma_init(&tx_dma, self->tx_dma_descr, self->spi);
  478. self->spi->hdmatx = &tx_dma;
  479. dma_init(&rx_dma, self->rx_dma_descr, self->spi);
  480. self->spi->hdmarx = &rx_dma;
  481. MP_HAL_CLEAN_DCACHE(src, len);
  482. MP_HAL_CLEANINVALIDATE_DCACHE(dest, len);
  483. uint32_t t_start = HAL_GetTick();
  484. do {
  485. uint32_t l = MIN(len, 65535);
  486. status = HAL_SPI_TransmitReceive_DMA(self->spi, (uint8_t*)src, dest, l);
  487. if (status != HAL_OK) {
  488. break;
  489. }
  490. status = spi_wait_dma_finished(self, t_start, timeout);
  491. if (status != HAL_OK) {
  492. break;
  493. }
  494. len -= l;
  495. src += l;
  496. dest += l;
  497. } while (len);
  498. dma_deinit(self->tx_dma_descr);
  499. dma_deinit(self->rx_dma_descr);
  500. }
  501. }
  502. if (status != HAL_OK) {
  503. mp_hal_raise(status);
  504. }
  505. }
  506. STATIC void spi_print(const mp_print_t *print, const spi_t *spi_obj, bool legacy) {
  507. SPI_HandleTypeDef *spi = spi_obj->spi;
  508. uint spi_num = 1; // default to SPI1
  509. if (spi->Instance == SPI2) { spi_num = 2; }
  510. #if defined(SPI3)
  511. else if (spi->Instance == SPI3) { spi_num = 3; }
  512. #endif
  513. #if defined(SPI4)
  514. else if (spi->Instance == SPI4) { spi_num = 4; }
  515. #endif
  516. #if defined(SPI5)
  517. else if (spi->Instance == SPI5) { spi_num = 5; }
  518. #endif
  519. #if defined(SPI6)
  520. else if (spi->Instance == SPI6) { spi_num = 6; }
  521. #endif
  522. mp_printf(print, "SPI(%u", spi_num);
  523. if (spi->State != HAL_SPI_STATE_RESET) {
  524. if (spi->Init.Mode == SPI_MODE_MASTER) {
  525. // compute baudrate
  526. uint spi_clock;
  527. #if defined(STM32F0)
  528. spi_clock = HAL_RCC_GetPCLK1Freq();
  529. #else
  530. if (spi->Instance == SPI2 || spi->Instance == SPI3) {
  531. // SPI2 and SPI3 are on APB1
  532. spi_clock = HAL_RCC_GetPCLK1Freq();
  533. } else {
  534. // SPI1, SPI4, SPI5 and SPI6 are on APB2
  535. spi_clock = HAL_RCC_GetPCLK2Freq();
  536. }
  537. #endif
  538. uint log_prescaler = (spi->Init.BaudRatePrescaler >> 3) + 1;
  539. uint baudrate = spi_clock >> log_prescaler;
  540. if (legacy) {
  541. mp_printf(print, ", SPI.MASTER");
  542. }
  543. mp_printf(print, ", baudrate=%u", baudrate);
  544. if (legacy) {
  545. mp_printf(print, ", prescaler=%u", 1 << log_prescaler);
  546. }
  547. } else {
  548. mp_printf(print, ", SPI.SLAVE");
  549. }
  550. mp_printf(print, ", polarity=%u, phase=%u, bits=%u", spi->Init.CLKPolarity == SPI_POLARITY_LOW ? 0 : 1, spi->Init.CLKPhase == SPI_PHASE_1EDGE ? 0 : 1, spi->Init.DataSize == SPI_DATASIZE_8BIT ? 8 : 16);
  551. if (spi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) {
  552. mp_printf(print, ", crc=0x%x", spi->Init.CRCPolynomial);
  553. }
  554. }
  555. mp_print_str(print, ")");
  556. }
  557. /******************************************************************************/
  558. /* MicroPython bindings for legacy pyb API */
  559. typedef struct _pyb_spi_obj_t {
  560. mp_obj_base_t base;
  561. const spi_t *spi;
  562. } pyb_spi_obj_t;
  563. STATIC const pyb_spi_obj_t pyb_spi_obj[] = {
  564. {{&pyb_spi_type}, &spi_obj[0]},
  565. {{&pyb_spi_type}, &spi_obj[1]},
  566. {{&pyb_spi_type}, &spi_obj[2]},
  567. {{&pyb_spi_type}, &spi_obj[3]},
  568. {{&pyb_spi_type}, &spi_obj[4]},
  569. {{&pyb_spi_type}, &spi_obj[5]},
  570. };
  571. STATIC void pyb_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
  572. pyb_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
  573. spi_print(print, self->spi, true);
  574. }
  575. /// \method init(mode, baudrate=328125, *, polarity=1, phase=0, bits=8, firstbit=SPI.MSB, ti=False, crc=None)
  576. ///
  577. /// Initialise the SPI bus with the given parameters:
  578. ///
  579. /// - `mode` must be either `SPI.MASTER` or `SPI.SLAVE`.
  580. /// - `baudrate` is the SCK clock rate (only sensible for a master).
  581. STATIC mp_obj_t pyb_spi_init_helper(const pyb_spi_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
  582. static const mp_arg_t allowed_args[] = {
  583. { MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
  584. { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 328125} },
  585. { MP_QSTR_prescaler, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0xffffffff} },
  586. { MP_QSTR_polarity, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
  587. { MP_QSTR_phase, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
  588. { MP_QSTR_dir, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = SPI_DIRECTION_2LINES} },
  589. { MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} },
  590. { MP_QSTR_nss, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = SPI_NSS_SOFT} },
  591. { MP_QSTR_firstbit, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = SPI_FIRSTBIT_MSB} },
  592. { MP_QSTR_ti, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
  593. { MP_QSTR_crc, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} },
  594. };
  595. // parse args
  596. mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
  597. mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
  598. // set the SPI configuration values
  599. SPI_InitTypeDef *init = &self->spi->spi->Init;
  600. init->Mode = args[0].u_int;
  601. spi_set_params(self->spi, args[2].u_int, args[1].u_int, args[3].u_int, args[4].u_int,
  602. args[6].u_int, args[8].u_int);
  603. init->Direction = args[5].u_int;
  604. init->NSS = args[7].u_int;
  605. init->TIMode = args[9].u_bool ? SPI_TIMODE_ENABLE : SPI_TIMODE_DISABLE;
  606. if (args[10].u_obj == mp_const_none) {
  607. init->CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  608. init->CRCPolynomial = 0;
  609. } else {
  610. init->CRCCalculation = SPI_CRCCALCULATION_ENABLE;
  611. init->CRCPolynomial = mp_obj_get_int(args[10].u_obj);
  612. }
  613. // init the SPI bus
  614. spi_init(self->spi, init->NSS != SPI_NSS_SOFT);
  615. return mp_const_none;
  616. }
  617. /// \classmethod \constructor(bus, ...)
  618. ///
  619. /// Construct an SPI object on the given bus. `bus` can be 1 or 2.
  620. /// With no additional parameters, the SPI object is created but not
  621. /// initialised (it has the settings from the last initialisation of
  622. /// the bus, if any). If extra arguments are given, the bus is initialised.
  623. /// See `init` for parameters of initialisation.
  624. ///
  625. /// The physical pins of the SPI busses are:
  626. ///
  627. /// - `SPI(1)` is on the X position: `(NSS, SCK, MISO, MOSI) = (X5, X6, X7, X8) = (PA4, PA5, PA6, PA7)`
  628. /// - `SPI(2)` is on the Y position: `(NSS, SCK, MISO, MOSI) = (Y5, Y6, Y7, Y8) = (PB12, PB13, PB14, PB15)`
  629. ///
  630. /// At the moment, the NSS pin is not used by the SPI driver and is free
  631. /// for other use.
  632. STATIC mp_obj_t pyb_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
  633. // check arguments
  634. mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
  635. // work out SPI bus
  636. int spi_id = spi_find(args[0]);
  637. // get SPI object
  638. const pyb_spi_obj_t *spi_obj = &pyb_spi_obj[spi_id - 1];
  639. if (n_args > 1 || n_kw > 0) {
  640. // start the peripheral
  641. mp_map_t kw_args;
  642. mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
  643. pyb_spi_init_helper(spi_obj, n_args - 1, args + 1, &kw_args);
  644. }
  645. return MP_OBJ_FROM_PTR(spi_obj);
  646. }
  647. STATIC mp_obj_t pyb_spi_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
  648. return pyb_spi_init_helper(MP_OBJ_TO_PTR(args[0]), n_args - 1, args + 1, kw_args);
  649. }
  650. STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_spi_init_obj, 1, pyb_spi_init);
  651. /// \method deinit()
  652. /// Turn off the SPI bus.
  653. STATIC mp_obj_t pyb_spi_deinit(mp_obj_t self_in) {
  654. pyb_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
  655. spi_deinit(self->spi);
  656. return mp_const_none;
  657. }
  658. STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_spi_deinit_obj, pyb_spi_deinit);
  659. /// \method send(send, *, timeout=5000)
  660. /// Send data on the bus:
  661. ///
  662. /// - `send` is the data to send (an integer to send, or a buffer object).
  663. /// - `timeout` is the timeout in milliseconds to wait for the send.
  664. ///
  665. /// Return value: `None`.
  666. STATIC mp_obj_t pyb_spi_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
  667. // TODO assumes transmission size is 8-bits wide
  668. static const mp_arg_t allowed_args[] = {
  669. { MP_QSTR_send, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
  670. { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5000} },
  671. };
  672. // parse args
  673. pyb_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
  674. mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
  675. mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
  676. // get the buffer to send from
  677. mp_buffer_info_t bufinfo;
  678. uint8_t data[1];
  679. pyb_buf_get_for_send(args[0].u_obj, &bufinfo, data);
  680. // send the data
  681. spi_transfer(self->spi, bufinfo.len, bufinfo.buf, NULL, args[1].u_int);
  682. return mp_const_none;
  683. }
  684. STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_spi_send_obj, 1, pyb_spi_send);
  685. /// \method recv(recv, *, timeout=5000)
  686. ///
  687. /// Receive data on the bus:
  688. ///
  689. /// - `recv` can be an integer, which is the number of bytes to receive,
  690. /// or a mutable buffer, which will be filled with received bytes.
  691. /// - `timeout` is the timeout in milliseconds to wait for the receive.
  692. ///
  693. /// Return value: if `recv` is an integer then a new buffer of the bytes received,
  694. /// otherwise the same buffer that was passed in to `recv`.
  695. STATIC mp_obj_t pyb_spi_recv(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
  696. // TODO assumes transmission size is 8-bits wide
  697. static const mp_arg_t allowed_args[] = {
  698. { MP_QSTR_recv, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
  699. { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5000} },
  700. };
  701. // parse args
  702. pyb_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
  703. mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
  704. mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
  705. // get the buffer to receive into
  706. vstr_t vstr;
  707. mp_obj_t o_ret = pyb_buf_get_for_recv(args[0].u_obj, &vstr);
  708. // receive the data
  709. spi_transfer(self->spi, vstr.len, NULL, (uint8_t*)vstr.buf, args[1].u_int);
  710. // return the received data
  711. if (o_ret != MP_OBJ_NULL) {
  712. return o_ret;
  713. } else {
  714. return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
  715. }
  716. }
  717. STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_spi_recv_obj, 1, pyb_spi_recv);
  718. /// \method send_recv(send, recv=None, *, timeout=5000)
  719. ///
  720. /// Send and receive data on the bus at the same time:
  721. ///
  722. /// - `send` is the data to send (an integer to send, or a buffer object).
  723. /// - `recv` is a mutable buffer which will be filled with received bytes.
  724. /// It can be the same as `send`, or omitted. If omitted, a new buffer will
  725. /// be created.
  726. /// - `timeout` is the timeout in milliseconds to wait for the receive.
  727. ///
  728. /// Return value: the buffer with the received bytes.
  729. STATIC mp_obj_t pyb_spi_send_recv(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
  730. // TODO assumes transmission size is 8-bits wide
  731. static const mp_arg_t allowed_args[] = {
  732. { MP_QSTR_send, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
  733. { MP_QSTR_recv, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
  734. { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5000} },
  735. };
  736. // parse args
  737. pyb_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
  738. mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
  739. mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
  740. // get buffers to send from/receive to
  741. mp_buffer_info_t bufinfo_send;
  742. uint8_t data_send[1];
  743. mp_buffer_info_t bufinfo_recv;
  744. vstr_t vstr_recv;
  745. mp_obj_t o_ret;
  746. if (args[0].u_obj == args[1].u_obj) {
  747. // same object for send and receive, it must be a r/w buffer
  748. mp_get_buffer_raise(args[0].u_obj, &bufinfo_send, MP_BUFFER_RW);
  749. bufinfo_recv = bufinfo_send;
  750. o_ret = args[0].u_obj;
  751. } else {
  752. // get the buffer to send from
  753. pyb_buf_get_for_send(args[0].u_obj, &bufinfo_send, data_send);
  754. // get the buffer to receive into
  755. if (args[1].u_obj == MP_OBJ_NULL) {
  756. // only send argument given, so create a fresh buffer of the send length
  757. vstr_init_len(&vstr_recv, bufinfo_send.len);
  758. bufinfo_recv.len = vstr_recv.len;
  759. bufinfo_recv.buf = vstr_recv.buf;
  760. o_ret = MP_OBJ_NULL;
  761. } else {
  762. // recv argument given
  763. mp_get_buffer_raise(args[1].u_obj, &bufinfo_recv, MP_BUFFER_WRITE);
  764. if (bufinfo_recv.len != bufinfo_send.len) {
  765. mp_raise_ValueError("recv must be same length as send");
  766. }
  767. o_ret = args[1].u_obj;
  768. }
  769. }
  770. // do the transfer
  771. spi_transfer(self->spi, bufinfo_send.len, bufinfo_send.buf, bufinfo_recv.buf, args[2].u_int);
  772. // return the received data
  773. if (o_ret != MP_OBJ_NULL) {
  774. return o_ret;
  775. } else {
  776. return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr_recv);
  777. }
  778. }
  779. STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_spi_send_recv_obj, 1, pyb_spi_send_recv);
  780. STATIC const mp_rom_map_elem_t pyb_spi_locals_dict_table[] = {
  781. // instance methods
  782. { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_spi_init_obj) },
  783. { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&pyb_spi_deinit_obj) },
  784. { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_machine_spi_read_obj) },
  785. { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_machine_spi_readinto_obj) },
  786. { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_machine_spi_write_obj) },
  787. { MP_ROM_QSTR(MP_QSTR_write_readinto), MP_ROM_PTR(&mp_machine_spi_write_readinto_obj) },
  788. // legacy methods
  789. { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&pyb_spi_send_obj) },
  790. { MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&pyb_spi_recv_obj) },
  791. { MP_ROM_QSTR(MP_QSTR_send_recv), MP_ROM_PTR(&pyb_spi_send_recv_obj) },
  792. // class constants
  793. /// \constant MASTER - for initialising the bus to master mode
  794. /// \constant SLAVE - for initialising the bus to slave mode
  795. /// \constant MSB - set the first bit to MSB
  796. /// \constant LSB - set the first bit to LSB
  797. { MP_ROM_QSTR(MP_QSTR_MASTER), MP_ROM_INT(SPI_MODE_MASTER) },
  798. { MP_ROM_QSTR(MP_QSTR_SLAVE), MP_ROM_INT(SPI_MODE_SLAVE) },
  799. { MP_ROM_QSTR(MP_QSTR_MSB), MP_ROM_INT(SPI_FIRSTBIT_MSB) },
  800. { MP_ROM_QSTR(MP_QSTR_LSB), MP_ROM_INT(SPI_FIRSTBIT_LSB) },
  801. /* TODO
  802. { MP_ROM_QSTR(MP_QSTR_DIRECTION_2LINES ((uint32_t)0x00000000)
  803. { MP_ROM_QSTR(MP_QSTR_DIRECTION_2LINES_RXONLY SPI_CR1_RXONLY
  804. { MP_ROM_QSTR(MP_QSTR_DIRECTION_1LINE SPI_CR1_BIDIMODE
  805. { MP_ROM_QSTR(MP_QSTR_NSS_SOFT SPI_CR1_SSM
  806. { MP_ROM_QSTR(MP_QSTR_NSS_HARD_INPUT ((uint32_t)0x00000000)
  807. { MP_ROM_QSTR(MP_QSTR_NSS_HARD_OUTPUT ((uint32_t)0x00040000)
  808. */
  809. };
  810. STATIC MP_DEFINE_CONST_DICT(pyb_spi_locals_dict, pyb_spi_locals_dict_table);
  811. STATIC void spi_transfer_machine(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest) {
  812. pyb_spi_obj_t *self = (pyb_spi_obj_t*)self_in;
  813. spi_transfer(self->spi, len, src, dest, SPI_TRANSFER_TIMEOUT(len));
  814. }
  815. STATIC const mp_machine_spi_p_t pyb_spi_p = {
  816. .transfer = spi_transfer_machine,
  817. };
  818. const mp_obj_type_t pyb_spi_type = {
  819. { &mp_type_type },
  820. .name = MP_QSTR_SPI,
  821. .print = pyb_spi_print,
  822. .make_new = pyb_spi_make_new,
  823. .protocol = &pyb_spi_p,
  824. .locals_dict = (mp_obj_dict_t*)&pyb_spi_locals_dict,
  825. };
  826. /******************************************************************************/
  827. // Implementation of hard SPI for machine module
  828. typedef struct _machine_hard_spi_obj_t {
  829. mp_obj_base_t base;
  830. const spi_t *spi;
  831. } machine_hard_spi_obj_t;
  832. STATIC const machine_hard_spi_obj_t machine_hard_spi_obj[] = {
  833. {{&machine_hard_spi_type}, &spi_obj[0]},
  834. {{&machine_hard_spi_type}, &spi_obj[1]},
  835. {{&machine_hard_spi_type}, &spi_obj[2]},
  836. {{&machine_hard_spi_type}, &spi_obj[3]},
  837. {{&machine_hard_spi_type}, &spi_obj[4]},
  838. {{&machine_hard_spi_type}, &spi_obj[5]},
  839. };
  840. STATIC void machine_hard_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
  841. machine_hard_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
  842. spi_print(print, self->spi, false);
  843. }
  844. mp_obj_t machine_hard_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
  845. enum { ARG_id, ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits, ARG_firstbit, ARG_sck, ARG_mosi, ARG_miso };
  846. static const mp_arg_t allowed_args[] = {
  847. { MP_QSTR_id, MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(-1)} },
  848. { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 500000} },
  849. { MP_QSTR_polarity, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
  850. { MP_QSTR_phase, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
  851. { MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} },
  852. { MP_QSTR_firstbit, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = SPI_FIRSTBIT_MSB} },
  853. { MP_QSTR_sck, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
  854. { MP_QSTR_mosi, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
  855. { MP_QSTR_miso, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
  856. };
  857. mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
  858. mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
  859. // get static peripheral object
  860. int spi_id = spi_find(args[ARG_id].u_obj);
  861. const machine_hard_spi_obj_t *self = &machine_hard_spi_obj[spi_id - 1];
  862. // here we would check the sck/mosi/miso pins and configure them, but it's not implemented
  863. if (args[ARG_sck].u_obj != MP_OBJ_NULL
  864. || args[ARG_mosi].u_obj != MP_OBJ_NULL
  865. || args[ARG_miso].u_obj != MP_OBJ_NULL) {
  866. mp_raise_ValueError("explicit choice of sck/mosi/miso is not implemented");
  867. }
  868. // set the SPI configuration values
  869. SPI_InitTypeDef *init = &self->spi->spi->Init;
  870. init->Mode = SPI_MODE_MASTER;
  871. // these parameters are not currently configurable
  872. init->Direction = SPI_DIRECTION_2LINES;
  873. init->NSS = SPI_NSS_SOFT;
  874. init->TIMode = SPI_TIMODE_DISABLE;
  875. init->CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  876. init->CRCPolynomial = 0;
  877. // set configurable paramaters
  878. spi_set_params(self->spi, 0xffffffff, args[ARG_baudrate].u_int,
  879. args[ARG_polarity].u_int, args[ARG_phase].u_int, args[ARG_bits].u_int,
  880. args[ARG_firstbit].u_int);
  881. // init the SPI bus
  882. spi_init(self->spi, false);
  883. return MP_OBJ_FROM_PTR(self);
  884. }
  885. STATIC void machine_hard_spi_init(mp_obj_base_t *self_in, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
  886. machine_hard_spi_obj_t *self = (machine_hard_spi_obj_t*)self_in;
  887. enum { ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits, ARG_firstbit };
  888. static const mp_arg_t allowed_args[] = {
  889. { MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
  890. { MP_QSTR_polarity, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
  891. { MP_QSTR_phase, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
  892. { MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
  893. { MP_QSTR_firstbit, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
  894. };
  895. mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
  896. mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
  897. // set the SPI configuration values
  898. spi_set_params(self->spi, 0xffffffff, args[ARG_baudrate].u_int,
  899. args[ARG_polarity].u_int, args[ARG_phase].u_int, args[ARG_bits].u_int,
  900. args[ARG_firstbit].u_int);
  901. // re-init the SPI bus
  902. spi_init(self->spi, false);
  903. }
  904. STATIC void machine_hard_spi_deinit(mp_obj_base_t *self_in) {
  905. machine_hard_spi_obj_t *self = (machine_hard_spi_obj_t*)self_in;
  906. spi_deinit(self->spi);
  907. }
  908. STATIC void machine_hard_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest) {
  909. machine_hard_spi_obj_t *self = (machine_hard_spi_obj_t*)self_in;
  910. spi_transfer(self->spi, len, src, dest, SPI_TRANSFER_TIMEOUT(len));
  911. }
  912. STATIC const mp_machine_spi_p_t machine_hard_spi_p = {
  913. .init = machine_hard_spi_init,
  914. .deinit = machine_hard_spi_deinit,
  915. .transfer = machine_hard_spi_transfer,
  916. };
  917. const mp_obj_type_t machine_hard_spi_type = {
  918. { &mp_type_type },
  919. .name = MP_QSTR_SPI,
  920. .print = machine_hard_spi_print,
  921. .make_new = mp_machine_spi_make_new, // delegate to master constructor
  922. .protocol = &machine_hard_spi_p,
  923. .locals_dict = (mp_obj_dict_t*)&mp_machine_spi_locals_dict,
  924. };
  925. const spi_t *spi_from_mp_obj(mp_obj_t o) {
  926. if (MP_OBJ_IS_TYPE(o, &pyb_spi_type)) {
  927. pyb_spi_obj_t *self = MP_OBJ_TO_PTR(o);
  928. return self->spi;
  929. } else if (MP_OBJ_IS_TYPE(o, &machine_hard_spi_type)) {
  930. machine_hard_spi_obj_t *self = MP_OBJ_TO_PTR(o);
  931. return self->spi;
  932. } else {
  933. mp_raise_TypeError("expecting an SPI object");
  934. }
  935. }