Skip to content

Commit 4d7fa05

Browse files
author
Daniel Campora
committed
cc3200: Improve Pin and UART implementation.
Deassign pins af before assigning. Make uart.any() return the correct value everytime, this requires interrupts to be always enabled.
1 parent 4054c4e commit 4d7fa05

9 files changed

Lines changed: 157 additions & 43 deletions

File tree

cc3200/mods/pybpin.c

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ DECLARE PRIVATE FUNCTIONS
6060
******************************************************************************/
6161
STATIC pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name);
6262
STATIC pin_obj_t *pin_find_pin_by_port_bit (const mp_obj_dict_t *named_pins, uint port, uint bit);
63+
STATIC int8_t pin_obj_find_af (const pin_obj_t* pin, uint8_t fn, uint8_t unit, uint8_t type);
64+
STATIC void pin_deassign (pin_obj_t* pin);
6365
STATIC void pin_obj_configure (const pin_obj_t *self);
6466
STATIC void pin_get_hibernate_pin_and_idx (const pin_obj_t *self, uint *wake_pin, uint *idx);
6567
STATIC void pin_extint_enable (mp_obj_t self_in);
@@ -68,6 +70,7 @@ STATIC void pin_extint_register(pin_obj_t *self, uint32_t intmode, uint32_t prio
6870
STATIC void pin_validate_mode (uint mode);
6971
STATIC void pin_validate_pull (uint pull);
7072
STATIC void pin_validate_drive (uint strength);
73+
STATIC void pin_validate_af(const pin_obj_t* pin, int8_t idx, uint8_t *fn, uint8_t *unit, uint8_t *type);
7174
STATIC void GPIOA0IntHandler (void);
7275
STATIC void GPIOA1IntHandler (void);
7376
STATIC void GPIOA2IntHandler (void);
@@ -115,9 +118,7 @@ void pin_init0(void) {
115118
mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)&pin_board_pins_locals_dict);
116119
for (uint i = 0; i < named_map->used - 1; i++) {
117120
pin_obj_t * pin = (pin_obj_t *)named_map->table[i].value;
118-
pin_config (pin, PIN_MODE_0, GPIO_DIR_MODE_IN, PIN_TYPE_STD, -1, PIN_STRENGTH_2MA);
119-
// mark it as unused again
120-
pin->used = false;
121+
pin_deassign (pin);
121122
}
122123
#endif
123124
}
@@ -147,10 +148,12 @@ void pin_config (pin_obj_t *self, int af, uint mode, uint pull, int value, uint
147148
if (af != -1) {
148149
self->af = af;
149150
}
151+
150152
// if value is -1, then we want to keep it as it is
151153
if (value != -1) {
152154
self->value = value;
153155
}
156+
154157
// mark the pin as used
155158
self->used = true;
156159
pin_obj_configure ((const pin_obj_t *)self);
@@ -160,12 +163,27 @@ void pin_config (pin_obj_t *self, int af, uint mode, uint pull, int value, uint
160163
}
161164

162165
int8_t pin_find_af_index (const pin_obj_t* pin, uint8_t fn, uint8_t unit, uint8_t type) {
163-
for (int i = 0; i < pin->num_afs; i++) {
164-
if (pin->af_list[i].fn == fn && pin->af_list[i].unit == unit && pin->af_list[i].type == type) {
165-
return pin->af_list[i].idx;
166+
int8_t af = pin_obj_find_af(pin, fn, unit, type);
167+
if (af < 0) {
168+
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
169+
}
170+
return af;
171+
}
172+
173+
void pin_free_af_from_pins (uint8_t fn, uint8_t unit, uint8_t type) {
174+
mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)&pin_board_pins_locals_dict);
175+
for (uint i = 0; i < named_map->used - 1; i++) {
176+
pin_obj_t * pin = (pin_obj_t *)named_map->table[i].value;
177+
// af is different than GPIO
178+
if (pin->af > PIN_MODE_0) {
179+
// check if the pin supports the target af
180+
int af = pin_obj_find_af(pin, fn, unit, type);
181+
if (af > 0 && af == pin->af) {
182+
// the pin is assigned to the target af, de-assign it
183+
pin_deassign (pin);
184+
}
166185
}
167186
}
168-
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
169187
}
170188

171189
/******************************************************************************
@@ -191,6 +209,20 @@ STATIC pin_obj_t *pin_find_pin_by_port_bit (const mp_obj_dict_t *named_pins, uin
191209
return NULL;
192210
}
193211

212+
STATIC int8_t pin_obj_find_af (const pin_obj_t* pin, uint8_t fn, uint8_t unit, uint8_t type) {
213+
for (int i = 0; i < pin->num_afs; i++) {
214+
if (pin->af_list[i].fn == fn && pin->af_list[i].unit == unit && pin->af_list[i].type == type) {
215+
return pin->af_list[i].idx;
216+
}
217+
}
218+
return -1;
219+
}
220+
221+
STATIC void pin_deassign (pin_obj_t* pin) {
222+
pin_config (pin, PIN_MODE_0, GPIO_DIR_MODE_IN, PIN_TYPE_STD, -1, PIN_STRENGTH_4MA);
223+
pin->used = false;
224+
}
225+
194226
STATIC void pin_obj_configure (const pin_obj_t *self) {
195227
uint32_t type;
196228
if (self->mode == PIN_TYPE_ANALOG) {
@@ -370,6 +402,18 @@ STATIC void pin_validate_drive(uint strength) {
370402
}
371403
}
372404

405+
STATIC void pin_validate_af(const pin_obj_t* pin, int8_t idx, uint8_t *fn, uint8_t *unit, uint8_t *type) {
406+
for (int i = 0; i < pin->num_afs; i++) {
407+
if (pin->af_list[i].idx == idx) {
408+
*fn = pin->af_list[i].fn;
409+
*unit = pin->af_list[i].unit;
410+
*type = pin->af_list[i].type;
411+
return;
412+
}
413+
}
414+
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
415+
}
416+
373417
STATIC void GPIOA0IntHandler (void) {
374418
EXTI_Handler(GPIOA0_BASE);
375419
}
@@ -455,6 +499,12 @@ STATIC mp_obj_t pin_obj_init_helper(pin_obj_t *self, mp_uint_t n_args, const mp_
455499
goto invalid_args;
456500
}
457501

502+
// check for a valid af and then free it from any other pins
503+
if (af > PIN_MODE_0) {
504+
uint8_t fn, unit, type;
505+
pin_validate_af (self, af, &fn, &unit, &type);
506+
pin_free_af_from_pins(fn, unit, type);
507+
}
458508
pin_config (self, af, mode, pull, value, strength);
459509

460510
return mp_const_none;

cc3200/mods/pybpin.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,5 +140,6 @@ void pin_init0(void);
140140
void pin_config(pin_obj_t *self, int af, uint mode, uint type, int value, uint strength);
141141
pin_obj_t *pin_find(mp_obj_t user_obj);
142142
int8_t pin_find_af_index(const pin_obj_t* pin, uint8_t fn, uint8_t unit, uint8_t type);
143+
void pin_free_af_from_pins (uint8_t fn, uint8_t unit, uint8_t type);
143144

144145
#endif // PYBPIN_H_

cc3200/mods/pybuart.c

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,18 @@
7171

7272
#define PYBUART_RX_BUFFER_LEN (128)
7373

74+
// interrupt triggers
75+
#define E_UART_TRIGGER_RX_ANY (0x01)
76+
#define E_UART_TRIGGER_RX_HALF (0x02)
77+
#define E_UART_TRIGGER_RX_FULL (0x04)
78+
#define E_UART_TRIGGER_TX_DONE (0x08)
79+
7480
/******************************************************************************
7581
DECLARE PRIVATE FUNCTIONS
7682
******************************************************************************/
7783
STATIC void uart_init (pyb_uart_obj_t *self);
7884
STATIC bool uart_rx_wait (pyb_uart_obj_t *self);
85+
STATIC void uart_check_init(pyb_uart_obj_t *self);
7986
STATIC void UARTGenericIntHandler(uint32_t uart_id);
8087
STATIC void UART0IntHandler(void);
8188
STATIC void UART1IntHandler(void);
@@ -98,6 +105,7 @@ struct _pyb_uart_obj_t {
98105
uint16_t read_buf_tail; // indexes first full slot (not full if equals head)
99106
byte peripheral;
100107
byte irq_trigger;
108+
bool callback_enabled;
101109
};
102110

103111
/******************************************************************************
@@ -244,6 +252,7 @@ STATIC bool uart_rx_wait (pyb_uart_obj_t *self) {
244252
STATIC void UARTGenericIntHandler(uint32_t uart_id) {
245253
pyb_uart_obj_t *self;
246254
uint32_t status;
255+
bool exec_callback = false;
247256

248257
self = &pyb_uart_obj[uart_id];
249258
status = MAP_UARTIntStatus(self->reg, true);
@@ -266,9 +275,23 @@ STATIC void UARTGenericIntHandler(uint32_t uart_id) {
266275
}
267276
}
268277
}
269-
// call the user defined handler
270-
mp_obj_t _callback = mpcallback_find(self);
271-
mpcallback_handler(_callback);
278+
279+
if (self->irq_trigger & E_UART_TRIGGER_RX_ANY) {
280+
exec_callback = true;
281+
}
282+
283+
if (exec_callback && self->callback_enabled) {
284+
// call the user defined handler
285+
mp_obj_t _callback = mpcallback_find(self);
286+
mpcallback_handler(_callback);
287+
}
288+
}
289+
}
290+
291+
STATIC void uart_check_init(pyb_uart_obj_t *self) {
292+
// not initialized
293+
if (!self->baudrate) {
294+
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
272295
}
273296
}
274297

@@ -287,11 +310,12 @@ STATIC void uart_callback_enable (mp_obj_t self_in) {
287310
MAP_UARTIntClear(self->reg, UART_INT_RX | UART_INT_RT);
288311
MAP_UARTIntEnable(self->reg, UART_INT_RX | UART_INT_RT);
289312
}
313+
self->callback_enabled = true;
290314
}
291315

292316
STATIC void uart_callback_disable (mp_obj_t self_in) {
293317
pyb_uart_obj_t *self = self_in;
294-
MAP_UARTIntDisable(self->reg, UART_INT_RX | UART_INT_RT);
318+
self->callback_enabled = false;
295319
}
296320

297321
/******************************************************************************/
@@ -405,6 +429,7 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, mp_uint_t n_args, con
405429
}
406430
// the pins tuple passed looks good so far
407431
for (int i = 0; i < n_pins; i++) {
432+
pin_free_af_from_pins(PIN_FN_UART, self->uart_id, i);
408433
if (pins_t[i] != mp_const_none) {
409434
pin_obj_t *pin = pin_find(pins_t[i]);
410435
pin_config (pin, pin_find_af_index(pin, PIN_FN_UART, self->uart_id, i),
@@ -422,6 +447,8 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, mp_uint_t n_args, con
422447
uart_init (self);
423448
// register it with the sleep module
424449
pybsleep_add ((const mp_obj_t)self, (WakeUpCB_t)uart_init);
450+
// enable the callback
451+
uart_callback_new (self, mp_const_none, INT_PRIORITY_LVL_3, E_UART_TRIGGER_RX_ANY);
425452

426453
return mp_const_none;
427454

@@ -478,12 +505,14 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_deinit_obj, pyb_uart_deinit);
478505

479506
STATIC mp_obj_t pyb_uart_any(mp_obj_t self_in) {
480507
pyb_uart_obj_t *self = self_in;
508+
uart_check_init(self);
481509
return mp_obj_new_int(uart_rx_any(self));
482510
}
483511
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_any_obj, pyb_uart_any);
484512

485513
STATIC mp_obj_t pyb_uart_sendbreak(mp_obj_t self_in) {
486514
pyb_uart_obj_t *self = self_in;
515+
uart_check_init(self);
487516
// send a break signal for at least 2 complete frames
488517
MAP_UARTBreakCtl(self->reg, true);
489518
UtilsDelay(UTILS_DELAY_US_TO_COUNT(PYBUART_2_FRAMES_TIME_US(self->baudrate)));
@@ -498,6 +527,7 @@ STATIC mp_obj_t pyb_uart_callback (mp_uint_t n_args, const mp_obj_t *pos_args, m
498527

499528
// check if any parameters were passed
500529
pyb_uart_obj_t *self = pos_args[0];
530+
uart_check_init(self);
501531
mp_obj_t _callback = mpcallback_find((mp_obj_t)self);
502532
if (kw_args->used > 0) {
503533

@@ -547,6 +577,7 @@ STATIC MP_DEFINE_CONST_DICT(pyb_uart_locals_dict, pyb_uart_locals_dict_table);
547577
STATIC mp_uint_t pyb_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
548578
pyb_uart_obj_t *self = self_in;
549579
byte *buf = buf_in;
580+
uart_check_init(self);
550581

551582
// make sure we want at least 1 char
552583
if (size == 0) {
@@ -574,6 +605,7 @@ STATIC mp_uint_t pyb_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, i
574605
STATIC mp_uint_t pyb_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) {
575606
pyb_uart_obj_t *self = self_in;
576607
const char *buf = buf_in;
608+
uart_check_init(self);
577609

578610
// write the data
579611
if (!uart_tx_strn(self, buf, size)) {
@@ -585,6 +617,8 @@ STATIC mp_uint_t pyb_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t
585617
STATIC mp_uint_t pyb_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) {
586618
pyb_uart_obj_t *self = self_in;
587619
mp_uint_t ret;
620+
uart_check_init(self);
621+
588622
if (request == MP_IOCTL_POLL) {
589623
mp_uint_t flags = arg;
590624
ret = 0;

cc3200/mods/pybuart.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,6 @@
2828
#ifndef PYBUART_H_
2929
#define PYBUART_H_
3030

31-
// interrupt triggers
32-
#define E_UART_TRIGGER_RX_ANY (0x01)
33-
#define E_UART_TRIGGER_RX_HALF (0x02)
34-
#define E_UART_TRIGGER_RX_FULL (0x04)
35-
#define E_UART_TRIGGER_TX_DONE (0x08)
36-
3731
typedef enum {
3832
PYB_UART_0 = 0,
3933
PYB_UART_1 = 1,

cc3200/mptask.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,6 @@ void TASK_Micropython (void *pvParameters) {
145145
mp_obj_new_int(MICROPY_STDIO_UART_BAUD),
146146
};
147147
pyb_stdio_uart = pyb_uart_type.make_new((mp_obj_t)&pyb_uart_type, MP_ARRAY_SIZE(args), 0, args);
148-
uart_callback_new (pyb_stdio_uart, mp_const_none, INT_PRIORITY_LVL_3, E_UART_TRIGGER_RX_ANY);
149148
#else
150149
pyb_stdio_uart = MP_OBJ_NULL;
151150
#endif

tests/wipy/pin.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
machine = os.uname().machine
88
if 'LaunchPad' in machine:
99
pin_map = ['GP24', 'GP12', 'GP14', 'GP15', 'GP16', 'GP17', 'GP28', 'GP8', 'GP6', 'GP30', 'GP31', 'GP3', 'GP0', 'GP4', 'GP5']
10-
af_range = range(1, 16)
10+
max_af_idx = 15
1111
elif 'WiPy' in machine:
1212
pin_map = ['GP23', 'GP24', 'GP12', 'GP13', 'GP14', 'GP9', 'GP17', 'GP28', 'GP22', 'GP8', 'GP30', 'GP31', 'GP0', 'GP4', 'GP5']
13-
af_range = range(1, 16)
13+
max_af_idx = 15
1414
else:
1515
raise Exception('Board not supported!')
1616

@@ -28,9 +28,10 @@ def test_pin_read(pull):
2828

2929
def test_pin_af():
3030
for p in pin_map:
31-
for n in af_range:
32-
Pin(p, mode=Pin.ALT, alt=n)
33-
Pin(p, mode=Pin.ALT_OPEN_DRAIN, alt=n)
31+
for af in Pin(p).alt_list():
32+
if af[1] <= max_af_idx:
33+
Pin(p, mode=Pin.ALT, alt=af[1])
34+
Pin(p, mode=Pin.ALT_OPEN_DRAIN, alt=af[1])
3435

3536
# test un-initialized pins
3637
test_noinit()
@@ -67,10 +68,6 @@ def test_pin_af():
6768
print(pin)
6869
pin.init(mode=Pin.OUT, pull=Pin.PULL_UP, drive=pin.HIGH_POWER)
6970
print(pin)
70-
pin = Pin(pin_map[0], Pin.ALT, Pin.PULL_NONE, alt=1)
71-
print(pin)
72-
pin = Pin(pin_map[0], Pin.ALT_OPEN_DRAIN, Pin.PULL_NONE, alt=15)
73-
print(pin)
7471

7572
# test value in OUT mode
7673
pin = Pin(pin_map[0], mode=Pin.OUT)

tests/wipy/pin.py.exp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ Pin('GP23', mode=Pin.IN, pull=Pin.PULL_NONE, drive=Pin.MED_POWER, alt=-1)
3232
Pin('GP23', mode=Pin.IN, pull=Pin.PULL_DOWN, drive=Pin.MED_POWER, alt=-1)
3333
Pin('GP23', mode=Pin.OUT, pull=Pin.PULL_UP, drive=Pin.LOW_POWER, alt=-1)
3434
Pin('GP23', mode=Pin.OUT, pull=Pin.PULL_UP, drive=Pin.HIGH_POWER, alt=-1)
35-
Pin('GP23', mode=Pin.ALT, pull=Pin.PULL_NONE, drive=Pin.MED_POWER, alt=1)
36-
Pin('GP23', mode=Pin.ALT_OPEN_DRAIN, pull=Pin.PULL_NONE, drive=Pin.MED_POWER, alt=15)
3735
1
3836
0
3937
1

0 commit comments

Comments
 (0)