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