devices.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. /* devices.c
  2. *
  3. * Copyright (C) 2006-2023 wolfSSL Inc.
  4. *
  5. * This file is part of wolfSSL.
  6. *
  7. * wolfSSL is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * wolfSSL is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
  20. */
  21. /* Minimalist BSP for IoT-Safe example based on
  22. * ST P-L596G-CELL02 + Quectel BG96 modem
  23. */
  24. #include <stdint.h>
  25. #include <stdlib.h>
  26. #include <stdio.h>
  27. #include "devices.h"
  28. #define RTSCTS 0
  29. #define AUTOBR 0
  30. #define NVIC_UART1_IRQN (37)
  31. #define NVIC_UART2_IRQN (38)
  32. static char modem_rx_buf[256];
  33. static uint32_t modem_rx_idx = 0;
  34. static uint32_t modem_parser_idx = 0;
  35. static void usart1_init(void)
  36. {
  37. uint32_t reg;
  38. /* Enable PWR */
  39. RCC_APB1_ENR |= PWR_APB1_CLOCK_ER_VAL;
  40. /* Enable GPIOG */
  41. RCC_AHB2_ENR |= GPIOG_AHB2_CLOCK_ER_VAL;
  42. /* Enable VDDIO2 */
  43. while ((PWR_CR2 & PWR_CR2_IOSV) == 0) {
  44. PWR_CR2 |= PWR_CR2_IOSV;
  45. printf("Turning on VDDIO2\n");
  46. sleep_ms(1000);
  47. }
  48. /* Enable GPIOB */
  49. RCC_AHB2_ENR |= GPIOB_AHB2_CLOCK_ER_VAL;
  50. /* Set mode = AF */
  51. reg = GPIO_MODE(GPIOG_BASE) & ~(0x03 << (USART1_PIN_RX * 2));
  52. GPIO_MODE(GPIOG_BASE) = reg | (0x02 << (USART1_PIN_RX * 2));
  53. reg = GPIO_MODE(GPIOB_BASE) & ~(0x03 << (USART1_PIN_TX * 2));
  54. GPIO_MODE(GPIOB_BASE) = reg | (0x02 << (USART1_PIN_TX * 2));
  55. reg = GPIO_PUPD(GPIOG_BASE) & (0x03 << (USART1_PIN_RX * 2));
  56. reg = GPIO_PUPD(GPIOB_BASE) & (0x03 << (USART1_PIN_TX * 2));
  57. GPIO_PUPD(GPIOB_BASE) = reg | (0x01 << (USART1_PIN_TX * 2));
  58. #if RTSCTS
  59. reg = GPIO_MODE(GPIOG_BASE) & ~(0x03 << (USART1_PIN_RTS * 2));
  60. GPIO_MODE(GPIOG_BASE) = reg | (0x02 << (USART1_PIN_RTS * 2));
  61. GPIO_PUPD(GPIOG_BASE) &= (0x03 << (USART1_PIN_RTS * 2));
  62. reg = GPIO_MODE(GPIOG_BASE) & ~(0x03 << (USART1_PIN_CTS * 2));
  63. GPIO_MODE(GPIOG_BASE) = reg | (0x02 << (USART1_PIN_CTS * 2));
  64. GPIO_PUPD(GPIOG_BASE) &= (0x03 << (USART1_PIN_CTS * 2));
  65. #endif
  66. /* Set alternate functions */
  67. reg = GPIO_AFH(GPIOG_BASE) & ~(0xf << ((USART1_PIN_RX - 8) * 4));
  68. GPIO_AFH(GPIOG_BASE) = reg | (7 << ((USART1_PIN_RX - 8) * 4));
  69. reg = GPIO_AFL(GPIOB_BASE) & ~(0xf << ((USART1_PIN_TX) * 4));
  70. GPIO_AFL(GPIOB_BASE) = reg | (7 << ((USART1_PIN_TX) * 4));
  71. #if RTSCTS
  72. /* RTS/CTS alt fn */
  73. reg = GPIO_AFH(GPIOG_BASE) & ~(0xf << ((USART1_PIN_RTS - 8) * 4));
  74. GPIO_AFH(GPIOG_BASE) = reg | (USART1_AF << ((USART1_PIN_RTS - 8) * 4));
  75. reg = GPIO_AFH(GPIOG_BASE) & ~(0xf << ((USART1_PIN_CTS - 8) * 4));
  76. GPIO_AFH(GPIOG_BASE) = reg | (USART1_AF << ((USART1_PIN_CTS - 8) * 4));
  77. #endif
  78. /* Enable USART clock */
  79. RCC_APB2_ENR |= USART1_APB2_CLOCK_ER_VAL;
  80. }
  81. static void usart2_init(void)
  82. {
  83. uint32_t reg;
  84. RCC_AHB2_ENR |= GPIOD_AHB2_CLOCK_ER_VAL | GPIOA_AHB2_CLOCK_ER_VAL;
  85. /* Set mode = AF */
  86. reg = GPIO_MODE(GPIOD_BASE) & ~(0x03 << (USART2_PIN_RX * 2));
  87. GPIO_MODE(GPIOD_BASE) = reg | (0x02 << (USART2_PIN_RX * 2));
  88. reg = GPIO_MODE(GPIOA_BASE) & ~(0x03 << (USART2_PIN_TX * 2));
  89. GPIO_MODE(GPIOA_BASE) = reg | (0x02 << (USART2_PIN_TX * 2));
  90. /* Set alternate functions */
  91. reg = GPIO_AFL(GPIOD_BASE) & ~(0xf << ((USART2_PIN_RX) * 4));
  92. GPIO_AFL(GPIOD_BASE) = reg | (7 << ((USART2_PIN_RX) * 4));
  93. reg = GPIO_AFL(GPIOA_BASE) & ~(0xf << ((USART2_PIN_TX) * 4));
  94. GPIO_AFL(GPIOA_BASE) = reg | (7 << ((USART2_PIN_TX) * 4));
  95. /* Enable USART clock */
  96. RCC_APB1_ENR |= USART2_APB1_CLOCK_ER_VAL;
  97. }
  98. int usart_tx(uint32_t dev, const uint8_t c)
  99. {
  100. volatile uint32_t reg;
  101. do {
  102. reg = USART_ISR(dev);
  103. } while ((reg & USART_ISR_TXE) == 0);
  104. USART_TDR(dev) = c;
  105. return 1;
  106. }
  107. int usart_rx(uint32_t dev, uint8_t *c)
  108. {
  109. int ret = 0;
  110. if (dev == USART1_BASE) {
  111. if (modem_rx_idx > modem_parser_idx) {
  112. *c = (uint8_t)(modem_rx_buf[modem_parser_idx++]);
  113. if (modem_rx_idx == modem_parser_idx) {
  114. modem_rx_idx = 0;
  115. modem_parser_idx = 0;
  116. }
  117. ret = 1;
  118. }
  119. } else {
  120. volatile uint32_t reg = USART_ISR(dev);
  121. if ((reg & USART_ISR_RXNE) != 0) {
  122. reg = USART_RDR(dev);
  123. *c = (uint8_t)(reg & 0xff);
  124. ret = 1;
  125. }
  126. }
  127. return ret;
  128. }
  129. int usart_init(uint32_t dev, uint32_t bitrate, uint8_t data, char parity, uint8_t stop)
  130. {
  131. uint32_t reg;
  132. int rtscts = 0;
  133. if (dev == USART1_BASE) {
  134. usart1_init();
  135. #if RTSCTS
  136. rtscts = 1;
  137. #endif
  138. }
  139. else if (dev == USART2_BASE)
  140. usart2_init();
  141. else
  142. return -1;
  143. /* Turn off the device */
  144. USART_CR1(dev) &= ~(USART_CR1_ENABLE);
  145. /* Configure for TX + RX */
  146. USART_CR1(dev) |= (USART_CR1_TX_ENABLE | USART_CR1_RX_ENABLE);
  147. /* Configure clock */
  148. USART_BRR(dev) = CLOCK_SPEED / (bitrate);
  149. /* Configure data bits */
  150. if (data == 8)
  151. USART_CR1(dev) &= ~USART_CR1_SYMBOL_LEN;
  152. else
  153. USART_CR1(dev) |= USART_CR1_SYMBOL_LEN;
  154. /* Configure parity */
  155. switch (parity) {
  156. case 'O':
  157. USART_CR1(dev) |= USART_CR1_PARITY_ODD;
  158. /* fall through to enable parity */
  159. /* FALL THROUGH */
  160. case 'E':
  161. USART_CR1(dev) |= USART_CR1_PARITY_ENABLED;
  162. break;
  163. default:
  164. USART_CR1(dev) &= ~(USART_CR1_PARITY_ENABLED | USART_CR1_PARITY_ODD);
  165. }
  166. /* Set stop bits (not supported) */
  167. (void)stop;
  168. /* Set rtscts */
  169. if (rtscts)
  170. USART_CR3(dev) |= USART_CR3_CTSE | USART_CR3_RTSE;
  171. #if AUTOBR
  172. /* Enable ABR */
  173. USART_CR2(dev) |= USART_CR2_ABREN;
  174. #endif
  175. if (dev == USART1_BASE) {
  176. USART_CR1(dev) |= USART_CR1_RXNEIE | USART_CR1_PEIE;
  177. USART_CR3(dev) |= USART_CR3_EIE;
  178. nvic_irq_enable(NVIC_UART1_IRQN);
  179. nvic_irq_setprio(NVIC_UART1_IRQN, 0);
  180. }
  181. /* Turn on uart */
  182. USART_CR1(dev) |= USART_CR1_ENABLE;
  183. return 0;
  184. }
  185. /* STDOUT on USART2 */
  186. int _write(void *r, uint8_t *text, int len)
  187. {
  188. char *p = (char *)text;
  189. int i;
  190. (void)r;
  191. while(*p && (p < (char *)(text + len))) {
  192. usart_tx(USART2_BASE, *p);
  193. p++;
  194. }
  195. return len;
  196. }
  197. /* newlib backend calls */
  198. extern unsigned int _start_heap;
  199. void * _sbrk(unsigned int incr)
  200. {
  201. static unsigned char *heap = NULL;
  202. void *old_heap = heap;
  203. if (((incr >> 2) << 2) != incr)
  204. incr = ((incr >> 2) + 1) << 2;
  205. if (old_heap == NULL)
  206. old_heap = heap = (unsigned char *)&_start_heap;
  207. heap += incr;
  208. return old_heap;
  209. }
  210. void * _sbrk_r(unsigned int incr)
  211. {
  212. static unsigned char *heap = NULL;
  213. void *old_heap = heap;
  214. if (((incr >> 2) << 2) != incr)
  215. incr = ((incr >> 2) + 1) << 2;
  216. if (old_heap == NULL)
  217. old_heap = heap = (unsigned char *)&_start_heap;
  218. heap += incr;
  219. return old_heap;
  220. }
  221. int _close(int fd)
  222. {
  223. return -1;
  224. }
  225. int _fstat(int fd)
  226. {
  227. return -1;
  228. }
  229. int _lseek(int fd, int whence, int off)
  230. {
  231. return -1;
  232. }
  233. int _read(uint8_t *buf, int len)
  234. {
  235. return -1;
  236. }
  237. int _isatty(int fd)
  238. {
  239. return 1;
  240. }
  241. /* Clock + waitstates settings */
  242. static void flash_set_waitstates(unsigned int waitstates)
  243. {
  244. uint32_t reg = FLASH_ACR;
  245. if ((reg & FLASH_ACR_LATENCY_MASK) != waitstates)
  246. FLASH_ACR |= ((reg & ~FLASH_ACR_LATENCY_MASK) | waitstates);
  247. }
  248. void clock_pll_on(void)
  249. {
  250. uint32_t reg32;
  251. uint32_t cpu_freq;
  252. uint32_t hpre, ppre1, ppre2;
  253. uint32_t flash_waitstates;
  254. /* Select clock parameters (CPU Speed = 80MHz) */
  255. cpu_freq = 80000000;
  256. flash_waitstates = 4;
  257. flash_set_waitstates(flash_waitstates);
  258. /* Configure + enable internal high-speed oscillator. */
  259. RCC_CR = (RCC_CR & (~RCC_CR_MSIRANGE_Msk)) | RCC_CR_MSIRANGE_6;
  260. RCC_CR |= RCC_CR_MSIRGSEL;
  261. RCC_CR |= RCC_CR_MSION;
  262. DMB();
  263. while ((RCC_CR & RCC_CR_MSIRDY) == 0)
  264. ;
  265. /* Select MSI as SYSCLK source. */
  266. reg32 = RCC_CFGR;
  267. reg32 &= ~(RCC_CFGR_SW_MASK);
  268. RCC_CFGR = (reg32 | RCC_CFGR_SW_MSI);
  269. DMB();
  270. /*
  271. * Set prescalers
  272. */
  273. hpre = RCC_PRESCALER_DIV_NONE;
  274. ppre1 = RCC_PRESCALER_DIV_NONE;
  275. ppre2 = RCC_PRESCALER_DIV_NONE;
  276. reg32 = RCC_CFGR;
  277. reg32 &= ~(RCC_CFGR_HPRE_MASK << RCC_CFGR_HPRE_SHIFT);
  278. RCC_CFGR = (hpre & RCC_CFGR_HPRE_MASK) << RCC_CFGR_HPRE_SHIFT;
  279. DMB();
  280. reg32 = RCC_CFGR;
  281. reg32 &= ~(RCC_CFGR_PPRE1_MASK << RCC_CFGR_PPRE1_SHIFT);
  282. RCC_CFGR = (reg32 | (ppre1 << RCC_CFGR_PPRE1_SHIFT));
  283. DMB();
  284. reg32 &= ~(RCC_CFGR_PPRE2_MASK << RCC_CFGR_PPRE2_SHIFT);
  285. RCC_CFGR = (reg32 | (ppre2 << RCC_CFGR_PPRE2_SHIFT));
  286. DMB();
  287. /* Set PLLCFGR parameter */
  288. RCC_PLLCFGR = PLLCFGR_PLLM | PLLCFGR_PLLN |
  289. PLLCFGR_PLLP | PLLCFGR_PLLQ |
  290. PLLCFGR_PLLR | RCC_PLLCFGR_PLLP_EN |
  291. RCC_PLLCFGR_PLLQ_EN | RCC_PLLCFGR_PLLR_EN |
  292. RCC_PLLCFGR_PLLSRC_MSI;
  293. /* Enable PLL oscillator and wait for it to stabilize. */
  294. RCC_CR |= RCC_CR_PLLON;
  295. DMB();
  296. while ((RCC_CR & RCC_CR_PLLRDY) == 0)
  297. ;
  298. /* Select PLL as SYSCLK source. */
  299. reg32 = RCC_CFGR;
  300. reg32 &= ~(RCC_CFGR_SW_MASK);
  301. RCC_CFGR = (reg32 | RCC_CFGR_SW_PLL);
  302. DMB();
  303. /* Wait for PLL clock to be selected (via SWS, bits 3:2) */
  304. while (((RCC_CFGR >> 2) & RCC_CFGR_SW_MASK) != RCC_CFGR_SW_PLL)
  305. ;
  306. RCC_CCIPR |= (1 << 26);
  307. PWR_CR1 |= PWR_CR1_DBP;
  308. }
  309. /* Modem via STMod+ connector */
  310. static int stmod_en_init = 0;
  311. static void stmod_pin_init(void)
  312. {
  313. uint32_t reg;
  314. RCC_AHB2_ENR |=
  315. GPIOA_AHB2_CLOCK_ER_VAL |
  316. GPIOB_AHB2_CLOCK_ER_VAL |
  317. GPIOC_AHB2_CLOCK_ER_VAL |
  318. GPIOD_AHB2_CLOCK_ER_VAL |
  319. GPIOI_AHB2_CLOCK_ER_VAL;
  320. /* 'enable' pin */
  321. reg = GPIO_MODE(STMOD_EN_PORT) & ~(0x03 << (STMOD_EN_PIN * 2));
  322. GPIO_MODE(STMOD_EN_PORT) = reg | (0x01 << (STMOD_EN_PIN * 2));
  323. /* RST pin */
  324. reg = GPIO_MODE(STMOD_MODEM_RST_PORT) & ~(0x03 << (STMOD_MODEM_RST_PIN * 2));
  325. GPIO_MODE(STMOD_MODEM_RST_PORT) = reg | (0x01 << (STMOD_MODEM_RST_PIN * 2));
  326. /* DTR pin */
  327. reg = GPIO_MODE(STMOD_MODEM_DTR_PORT) & ~(0x03 << (STMOD_MODEM_DTR_PIN * 2));
  328. GPIO_MODE(STMOD_MODEM_DTR_PORT) = reg | (0x01 << (STMOD_MODEM_DTR_PIN * 2));
  329. /* Sim select pins */
  330. reg = GPIO_MODE(STMOD_SIM_SELECT0_PORT) & ~(0x03 << (STMOD_SIM_SELECT0_PIN * 2));
  331. GPIO_MODE(STMOD_SIM_SELECT0_PORT) = reg | (0x01 << (STMOD_SIM_SELECT0_PIN * 2));
  332. reg = GPIO_MODE(STMOD_SIM_SELECT1_PORT) & ~(0x03 << (STMOD_SIM_SELECT1_PIN * 2));
  333. GPIO_MODE(STMOD_SIM_SELECT1_PORT) = reg | (0x01 << (STMOD_SIM_SELECT1_PIN * 2));
  334. }
  335. void stmod_modem_enable(void)
  336. {
  337. if (!stmod_en_init) {
  338. stmod_pin_init();
  339. stmod_en_init = 1;
  340. }
  341. /* initial pin state */
  342. gpio_set(STMOD_EN_PORT, STMOD_EN_PIN);
  343. gpio_set(STMOD_MODEM_RST_PORT, STMOD_MODEM_RST_PIN);
  344. gpio_set(STMOD_MODEM_DTR_PORT, STMOD_MODEM_DTR_PIN);
  345. sleep_ms(200);
  346. gpio_clear(STMOD_MODEM_RST_PORT, STMOD_MODEM_RST_PIN);
  347. gpio_clear(STMOD_EN_PORT, STMOD_EN_PIN);
  348. sleep_ms(2500);
  349. /* ON/OFF sequence to clear state */
  350. gpio_set(STMOD_EN_PORT, STMOD_EN_PIN);
  351. sleep_ms(700);
  352. gpio_clear(STMOD_EN_PORT, STMOD_EN_PIN);
  353. sleep_ms(1000);
  354. gpio_set(STMOD_EN_PORT, STMOD_EN_PIN);
  355. sleep_ms(50);
  356. gpio_clear(STMOD_EN_PORT, STMOD_EN_PIN);
  357. sleep_ms(30);
  358. gpio_set(STMOD_EN_PORT, STMOD_EN_PIN); /* Modem is on. */
  359. printf("Modem booting...\n");
  360. sleep_ms(5000);
  361. printf("Modem is on.\r\n");
  362. }
  363. void stmod_modem_disable(void)
  364. {
  365. if (!stmod_en_init) {
  366. stmod_pin_init();
  367. stmod_en_init = 1;
  368. }
  369. gpio_clear(STMOD_EN_PORT, STMOD_EN_PIN);
  370. }
  371. extern volatile unsigned jiffies;
  372. void systick_enable(void)
  373. {
  374. SYSTICK_RVR = ((CLOCK_SPEED / 1000) - 1);
  375. SYSTICK_CVR = 0;
  376. SYSTICK_CSR |= 0x07;
  377. }
  378. void sleep_ms(unsigned ms)
  379. {
  380. unsigned end = jiffies + ms;
  381. while(jiffies < end)
  382. __asm__ volatile("wfi");
  383. }
  384. void isr_usart1(void)
  385. {
  386. uint32_t reg;
  387. reg = USART_ISR(USART1_BASE);
  388. if (reg & USART_ISR_RXNE) {
  389. modem_rx_buf[modem_rx_idx++] = (char)USART_RDR(USART1_BASE);
  390. } else {
  391. USART_ICR(USART1_BASE) |= 2 | USART_ICR_CMCF; /* FECF + CMCF*/
  392. }
  393. }