1+ #include <stdio.h>
12#include <stm32f4xx_rcc.h>
23#include <stm32f4xx_gpio.h>
34#include <stm32f4xx_usart.h>
45
56#include "misc.h"
7+ #include "mpconfig.h"
8+ #include "obj.h"
69#include "usart.h"
710
811static bool is_enabled ;
912
10- // USART6 on PC6 (TX), PC7 (RX)
11- void usart_init (void ) {
12- RCC_APB2PeriphClockCmd (RCC_APB2Periph_USART6 , ENABLE );
13+ typedef enum {
14+ PYB_USART_1 = 1 ,
15+ PYB_USART_2 = 2 ,
16+ PYB_USART_3 = 3 ,
17+ PYB_USART_6 = 4 ,
18+ PYB_USART_MAX = 4 ,
19+ } pyb_usart_t ;
1320
14- GPIO_PinAFConfig (GPIOC , GPIO_PinSource6 , GPIO_AF_USART6 );
15- GPIO_PinAFConfig (GPIOC , GPIO_PinSource7 , GPIO_AF_USART6 );
21+ static USART_TypeDef * usart_get_base (pyb_usart_t usart_id ) {
22+ USART_TypeDef * USARTx = NULL ;
23+
24+ switch (usart_id ) {
25+ case PYB_USART_1 :
26+ USARTx = USART1 ;
27+ break ;
28+ case PYB_USART_2 :
29+ USARTx = USART2 ;
30+ break ;
31+ case PYB_USART_3 :
32+ USARTx = USART3 ;
33+ break ;
34+ case PYB_USART_6 :
35+ USARTx = USART6 ;
36+ break ;
37+ }
38+
39+ return USARTx ;
40+ }
41+
42+ void usart_init (pyb_usart_t usart_id , uint32_t baudrate ) {
43+ USART_TypeDef * USARTx = NULL ;
44+
45+ uint32_t GPIO_Pin = 0 ;
46+ uint8_t GPIO_AF_USARTx = 0 ;
47+ GPIO_TypeDef * GPIO_Port = NULL ;
48+ uint16_t GPIO_PinSource_TX = 0 ;
49+ uint16_t GPIO_PinSource_RX = 0 ;
50+
51+ uint32_t RCC_APBxPeriph = 0 ;
52+ void (* RCC_APBxPeriphClockCmd )(uint32_t , FunctionalState )= NULL ;
53+
54+ switch (usart_id ) {
55+ case PYB_USART_1 :
56+ USARTx = USART1 ;
57+
58+ GPIO_Port = GPIOA ;
59+ GPIO_AF_USARTx = GPIO_AF_USART1 ;
60+ GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10 ;
61+ GPIO_PinSource_TX = GPIO_PinSource9 ;
62+ GPIO_PinSource_RX = GPIO_PinSource10 ;
63+
64+ RCC_APBxPeriph = RCC_APB2Periph_USART1 ;
65+ RCC_APBxPeriphClockCmd = RCC_APB2PeriphClockCmd ;
66+ break ;
67+ case PYB_USART_2 :
68+ USARTx = USART2 ;
69+
70+ GPIO_Port = GPIOD ;
71+ GPIO_AF_USARTx = GPIO_AF_USART2 ;
72+ GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 ;
73+ GPIO_PinSource_TX = GPIO_PinSource5 ;
74+ GPIO_PinSource_RX = GPIO_PinSource6 ;
75+
76+ RCC_APBxPeriph = RCC_APB1Periph_USART2 ;
77+ RCC_APBxPeriphClockCmd = RCC_APB1PeriphClockCmd ;
78+ break ;
79+ case PYB_USART_3 :
80+ USARTx = USART3 ;
81+
82+ GPIO_Port = GPIOD ;
83+ GPIO_AF_USARTx = GPIO_AF_USART3 ;
84+ GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 ;
85+ GPIO_PinSource_TX = GPIO_PinSource8 ;
86+ GPIO_PinSource_RX = GPIO_PinSource9 ;
87+
88+ RCC_APBxPeriph = RCC_APB1Periph_USART3 ;
89+ RCC_APBxPeriphClockCmd = RCC_APB1PeriphClockCmd ;
90+ break ;
91+ case PYB_USART_6 :
92+ USARTx = USART6 ;
93+
94+ GPIO_Port = GPIOC ;
95+ GPIO_AF_USARTx = GPIO_AF_USART6 ;
96+ GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 ;
97+ GPIO_PinSource_TX = GPIO_PinSource6 ;
98+ GPIO_PinSource_RX = GPIO_PinSource7 ;
99+
100+ RCC_APBxPeriph = RCC_APB2Periph_USART6 ;
101+ RCC_APBxPeriphClockCmd = RCC_APB2PeriphClockCmd ;
102+ break ;
103+ }
104+
105+ /* Initialize USARTx */
106+ RCC_APBxPeriphClockCmd (RCC_APBxPeriph , ENABLE );
107+
108+ GPIO_PinAFConfig (GPIO_Port , GPIO_PinSource_TX , GPIO_AF_USARTx );
109+ GPIO_PinAFConfig (GPIO_Port , GPIO_PinSource_RX , GPIO_AF_USARTx );
16110
17111 GPIO_InitTypeDef GPIO_InitStructure ;
18- GPIO_InitStructure .GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 ;
112+ GPIO_InitStructure .GPIO_Pin = GPIO_Pin ;
19113 GPIO_InitStructure .GPIO_Speed = GPIO_Speed_25MHz ;
20114 GPIO_InitStructure .GPIO_Mode = GPIO_Mode_AF ;
21115 GPIO_InitStructure .GPIO_OType = GPIO_OType_PP ;
22116 GPIO_InitStructure .GPIO_PuPd = GPIO_PuPd_UP ;
23- GPIO_Init (GPIOC , & GPIO_InitStructure );
117+ GPIO_Init (GPIO_Port , & GPIO_InitStructure );
24118
25119 USART_InitTypeDef USART_InitStructure ;
26- USART_InitStructure .USART_BaudRate = 115200 ;
120+ USART_InitStructure .USART_BaudRate = baudrate ;
27121 USART_InitStructure .USART_WordLength = USART_WordLength_8b ;
28122 USART_InitStructure .USART_StopBits = USART_StopBits_1 ;
29123 USART_InitStructure .USART_Parity = USART_Parity_No ;
30124 USART_InitStructure .USART_HardwareFlowControl = USART_HardwareFlowControl_None ;
31125 USART_InitStructure .USART_Mode = USART_Mode_Rx | USART_Mode_Tx ;
32- USART_Init (USART6 , & USART_InitStructure );
33-
34- USART_Cmd (USART6 , ENABLE );
126+ USART_Init (USARTx , & USART_InitStructure );
35127
36- is_enabled = true ;
128+ USART_Cmd ( USARTx , ENABLE ) ;
37129}
38130
39131bool usart_is_enabled (void ) {
@@ -44,31 +136,106 @@ bool usart_rx_any(void) {
44136 return USART_GetFlagStatus (USART6 , USART_FLAG_RXNE ) == SET ;
45137}
46138
47- int usart_rx_char (void ) {
48- return USART_ReceiveData (USART6 );
139+ int usart_rx_char (pyb_usart_t usart_id ) {
140+ USART_TypeDef * USARTx = usart_get_base (usart_id );
141+ return USART_ReceiveData (USARTx );
49142}
50143
51- void usart_tx_char (int c ) {
52- if (is_enabled ) {
53- // wait until the end of any previous transmission
54- uint32_t timeout = 100000 ;
55- while (USART_GetFlagStatus (USART6 , USART_FLAG_TC ) == RESET && -- timeout > 0 ) {
56- }
57- USART_SendData (USART6 , c );
144+ void usart_tx_char (pyb_usart_t usart_id , int c ) {
145+ USART_TypeDef * USARTx = usart_get_base (usart_id );
146+ // wait until the end of any previous transmission
147+ uint32_t timeout = 100000 ;
148+ while (USART_GetFlagStatus (USARTx , USART_FLAG_TC ) == RESET && -- timeout > 0 ) {
58149 }
150+ USART_SendData (USARTx , c );
59151}
60152
61- void usart_tx_str (const char * str ) {
153+ void usart_tx_str (pyb_usart_t usart_id , const char * str ) {
62154 for (; * str ; str ++ ) {
63- usart_tx_char (* str );
155+ usart_tx_char (usart_id , * str );
64156 }
65157}
66158
67- void usart_tx_strn_cooked (const char * str , int len ) {
159+ void usart_tx_strn_cooked (pyb_usart_t usart_id , const char * str , int len ) {
68160 for (const char * top = str + len ; str < top ; str ++ ) {
69161 if (* str == '\n' ) {
70- usart_tx_char ('\r' );
162+ usart_tx_char (usart_id , '\r' );
71163 }
72- usart_tx_char (* str );
164+ usart_tx_char (usart_id , * str );
165+ }
166+ }
167+
168+
169+ /******************************************************************************/
170+ /* Micro Python bindings */
171+
172+ typedef struct _pyb_usart_obj_t {
173+ mp_obj_base_t base ;
174+ pyb_usart_t usart_id ;
175+ bool is_enabled ;
176+ } pyb_usart_obj_t ;
177+
178+ static mp_obj_t usart_obj_rx_char (mp_obj_t self_in ) {
179+ mp_obj_t ret = mp_const_none ;
180+ pyb_usart_obj_t * self = self_in ;
181+
182+ if (self -> is_enabled ) {
183+ ret = mp_obj_new_int (usart_rx_char (self -> usart_id ));
184+ }
185+ return ret ;
186+ }
187+
188+ static mp_obj_t usart_obj_tx_char (mp_obj_t self_in , mp_obj_t c ) {
189+ pyb_usart_obj_t * self = self_in ;
190+ if (self -> is_enabled ) {
191+ usart_tx_char (self -> usart_id , mp_obj_get_int (c ));
192+ }
193+ return mp_const_none ;
194+ }
195+
196+ static mp_obj_t usart_obj_tx_str (mp_obj_t self_in , mp_obj_t s ) {
197+ pyb_usart_obj_t * self = self_in ;
198+ if (self -> is_enabled ) {
199+ //usart_tx_str(self->usart_id, mp_obj_get_str(s));
200+ usart_tx_str (self -> usart_id , "test" );
73201 }
202+ return mp_const_none ;
203+ }
204+
205+ static void usart_obj_print (void (* print )(void * env , const char * fmt , ...), void * env , mp_obj_t self_in ) {
206+ pyb_usart_obj_t * self = self_in ;
207+ print (env , "<Usart %lu>" , self -> usart_id );
208+ }
209+
210+ static MP_DEFINE_CONST_FUN_OBJ_1 (usart_obj_rx_char_obj , usart_obj_rx_char ) ;
211+ static MP_DEFINE_CONST_FUN_OBJ_2 (usart_obj_tx_char_obj , usart_obj_tx_char ) ;
212+ static MP_DEFINE_CONST_FUN_OBJ_2 (usart_obj_tx_str_obj , usart_obj_tx_str ) ;
213+
214+ static const mp_method_t usart_methods [] = {
215+ { "recv_chr" , & usart_obj_rx_char_obj },
216+ { "send_chr" , & usart_obj_tx_char_obj },
217+ { "send" , & usart_obj_tx_str_obj },
218+ { NULL , NULL },
219+ };
220+
221+ static const mp_obj_type_t usart_obj_type = {
222+ { & mp_const_type },
223+ "Usart" ,
224+ .print = usart_obj_print ,
225+ .methods = usart_methods ,
226+ };
227+
228+ mp_obj_t pyb_Usart (mp_obj_t usart_id , mp_obj_t baudrate ) {
229+ if (mp_obj_get_int (usart_id )> PYB_USART_MAX ) {
230+ return mp_const_none ;
231+ }
232+
233+ /* init USART */
234+ usart_init (mp_obj_get_int (usart_id ), mp_obj_get_int (baudrate ));
235+
236+ pyb_usart_obj_t * o = m_new_obj (pyb_usart_obj_t );
237+ o -> base .type = & usart_obj_type ;
238+ o -> usart_id = mp_obj_get_int (usart_id );
239+ o -> is_enabled = true;
240+ return o ;
74241}
0 commit comments