Skip to content

Commit 0d4cab1

Browse files
committed
Merge pull request adafruit#127 from iabdalkader/master
Add USART Micro Python Bindings
2 parents be84297 + e78e2dd commit 0d4cab1

5 files changed

Lines changed: 208 additions & 35 deletions

File tree

stm/Makefile

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,16 @@ OBJCOPY = arm-none-eabi-objcopy
2222
SIZE = arm-none-eabi-size
2323

2424
CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -mabi=aapcs-linux -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant -Wdouble-promotion -DSTM32F40XX -DHSE_VALUE=8000000
25-
CFLAGS = -I. -I$(PY_SRC) -I$(FATFSSRC) -I$(STMSRC) -Wall -ansi -std=gnu99 -Os -DNDEBUG $(CFLAGS_CORTEX_M4) -D$(TARGET)
25+
CFLAGS = -I. -I$(PY_SRC) -I$(FATFSSRC) -I$(STMSRC) -Wall -ansi -std=gnu99 $(CFLAGS_CORTEX_M4) -D$(TARGET)
2626
#CFLAGS += -I$(STMOTGSRC) -DUSE_HOST_MODE -DUSE_OTG_MODE
27+
28+
#Debugging/Optimization
29+
ifeq ($(DEBUG), 1)
30+
CFLAGS += -O0 -ggdb
31+
else
32+
CFLAGS += -Os -DNDEBUG
33+
endif
34+
2735
LDFLAGS = --nostdlib -T stm32f405.ld
2836

2937
SRC_C = \

stm/main.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -852,8 +852,9 @@ int main(void) {
852852
rt_store_attr(m, qstr_from_str_static("rand"), rt_make_function_0(pyb_rng_get));
853853
rt_store_attr(m, qstr_from_str_static("Led"), rt_make_function_1(pyb_Led));
854854
rt_store_attr(m, qstr_from_str_static("Servo"), rt_make_function_1(pyb_Servo));
855-
rt_store_attr(m, qstr_from_str_static("I2C"), rt_make_function_2(pyb_I2C));
855+
rt_store_attr(m, qstr_from_str_static("I2C"), rt_make_function_2(pyb_I2C));
856856
rt_store_attr(m, qstr_from_str_static("gpio"), (mp_obj_t)&pyb_gpio_obj);
857+
rt_store_attr(m, qstr_from_str_static("Usart"), rt_make_function_2(pyb_Usart));
857858
rt_store_name(qstr_from_str_static("pyb"), m);
858859

859860
rt_store_name(qstr_from_str_static("open"), rt_make_function_2(pyb_io_open));

stm/printf.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
#include <stdarg.h>
33
#include "std.h"
44
#include "misc.h"
5+
#include "systick.h"
6+
#include "mpconfig.h"
7+
#include "obj.h"
58
#include "lcd.h"
69
#include "usart.h"
710
#include "usb.h"

stm/usart.c

Lines changed: 193 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,131 @@
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

811
static 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

39131
bool 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
}

stm/usart.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1 @@
1-
void usart_init(void);
2-
bool usart_is_enabled(void);
3-
bool usart_rx_any(void);
4-
int usart_rx_char(void);
5-
void usart_tx_char(int c);
6-
void usart_tx_str(const char *str);
7-
void usart_tx_strn_cooked(const char *str, int len);
1+
mp_obj_t pyb_Usart(mp_obj_t usart_id, mp_obj_t baudrate);

0 commit comments

Comments
 (0)