Skip to content

Commit dbdcb58

Browse files
author
Daniel Campora
committed
cc3200: New irq API, affects all classes that provide the irq method.
1 parent 81d64ab commit dbdcb58

31 files changed

+1404
-757
lines changed

cc3200/application.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ APP_MISC_SRC_C = $(addprefix misc/,\
7878
antenna.c \
7979
FreeRTOSHooks.c \
8080
help.c \
81-
mpcallback.c \
81+
mpirq.c \
8282
mperror.c \
8383
mpexception.c \
8484
mpsystick.c \

cc3200/boards/cc3200_prefix.c

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,18 @@
5252
#define PIN(p_pin_name, p_port, p_bit, p_pin_num, p_af_list, p_num_afs) \
5353
{ \
5454
{ &pin_type }, \
55-
.name = MP_QSTR_ ## p_pin_name, \
56-
.port = PORT_A ## p_port, \
57-
.af_list = (p_af_list), \
58-
.pull = PIN_TYPE_STD, \
59-
.bit = (p_bit), \
60-
.pin_num = (p_pin_num), \
61-
.af = PIN_MODE_0, \
62-
.strength = PIN_STRENGTH_4MA, \
63-
.mode = GPIO_DIR_MODE_IN, \
64-
.num_afs = (p_num_afs), \
65-
.value = 0, \
66-
.used = false, \
55+
.name = MP_QSTR_ ## p_pin_name, \
56+
.port = PORT_A ## p_port, \
57+
.af_list = (p_af_list), \
58+
.pull = PIN_TYPE_STD, \
59+
.bit = (p_bit), \
60+
.pin_num = (p_pin_num), \
61+
.af = PIN_MODE_0, \
62+
.strength = PIN_STRENGTH_4MA, \
63+
.mode = GPIO_DIR_MODE_IN, \
64+
.num_afs = (p_num_afs), \
65+
.value = 0, \
66+
.used = false, \
67+
.irq_trigger = 0, \
68+
.irq_flags = 0, \
6769
}

cc3200/hal/prcm.c

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,17 +112,17 @@
112112
// following wrapper can be used to convert the value from cycles to
113113
// millisecond:
114114
//
115-
// CYCLES_U16MS(cycles) ((cycles *1000)/ 1024),
115+
// CYCLES_U16MS(cycles) ((cycles * 1000) / 1024),
116116
//
117117
// Similarly, before setting the value, it must be first converted (from ms to
118118
// cycles).
119119
//
120-
// U16MS_CYCLES(msec) ((msec *1024)/1000)
120+
// U16MS_CYCLES(msec) ((msec * 1024) / 1000)
121121
//
122122
// Note: There is a precision loss of 1 ms with the above scheme.
123123
//
124124
//
125-
#define SCC_U64MSEC_GET() (MAP_PRCMSlowClkCtrGet() >> 5)
125+
#define SCC_U64MSEC_GET() (RTCFastDomainCounterGet() >> 5)
126126
#define SCC_U64MSEC_MATCH_SET(u64Msec) (MAP_PRCMSlowClkCtrMatchSet(u64Msec << 5))
127127
#define SCC_U64MSEC_MATCH_GET() (MAP_PRCMSlowClkCtrMatchGet() >> 5)
128128

@@ -208,6 +208,39 @@ static void RTCU32SecRegWrite(unsigned long u32Msec)
208208
MAP_PRCMHIBRegWrite(RTC_SECS_U32_REG_ADDR, u32Msec);
209209
}
210210

211+
//*****************************************************************************
212+
// Fast function to get the most accurate RTC counter value
213+
//*****************************************************************************
214+
static unsigned long long RTCFastDomainCounterGet (void) {
215+
216+
#define BRK_IF_RTC_CTRS_ALIGN(c2, c1) if (c2 - c1 <= 1) { \
217+
itr++; \
218+
break; \
219+
}
220+
221+
unsigned long long rtc_count1, rtc_count2, rtc_count3;
222+
unsigned int itr;
223+
224+
do {
225+
rtc_count1 = PRCMSlowClkCtrFastGet();
226+
rtc_count2 = PRCMSlowClkCtrFastGet();
227+
rtc_count3 = PRCMSlowClkCtrFastGet();
228+
itr = 0;
229+
230+
BRK_IF_RTC_CTRS_ALIGN(rtc_count2, rtc_count1);
231+
BRK_IF_RTC_CTRS_ALIGN(rtc_count3, rtc_count2);
232+
BRK_IF_RTC_CTRS_ALIGN(rtc_count3, rtc_count1);
233+
234+
// Consistent values in two consecutive reads implies a correct
235+
// value of the counter. Do note, the counter does not give the
236+
// calendar time but a hardware that ticks upwards continuously.
237+
// The 48-bit counter operates at 32,768 HZ.
238+
239+
} while (true);
240+
241+
return (1 == itr) ? rtc_count2 : rtc_count3;
242+
}
243+
211244
//*****************************************************************************
212245
// Macros
213246
//*****************************************************************************
@@ -1245,6 +1278,35 @@ unsigned long long PRCMSlowClkCtrGet(void)
12451278
return ullRTCVal;
12461279
}
12471280

1281+
//*****************************************************************************
1282+
//
1283+
//! Gets the current value of the internal slow clock counter
1284+
//!
1285+
//! This function is similar to \sa PRCMSlowClkCtrGet() but reads the counter
1286+
//! value from a relatively faster interface using an auto-latch mechainsm.
1287+
//!
1288+
//! \note Due to the nature of implemetation of auto latching, when using this
1289+
//! API, the recommendation is to read the value thrice and identify the right
1290+
//! value (as 2 out the 3 read values will always be correct and with a max. of
1291+
//! 1 LSB change)
1292+
//!
1293+
//! \return 64-bit current counter vlaue.
1294+
//
1295+
//*****************************************************************************
1296+
unsigned long long PRCMSlowClkCtrFastGet(void)
1297+
{
1298+
unsigned long long ullRTCVal;
1299+
1300+
//
1301+
// Read as 2 32-bit values
1302+
//
1303+
ullRTCVal = HWREG(HIB1P2_BASE + HIB1P2_O_HIB_RTC_TIMER_MSW_1P2);
1304+
ullRTCVal = ullRTCVal << 32;
1305+
ullRTCVal |= HWREG(HIB1P2_BASE + HIB1P2_O_HIB_RTC_TIMER_LSW_1P2);
1306+
1307+
return ullRTCVal;
1308+
1309+
}
12481310

12491311
//*****************************************************************************
12501312
//

cc3200/hal/prcm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ extern void PRCMHibernateWakeupSourceDisable(unsigned long ulHIBWakupSrc);
247247
extern void PRCMHibernateIntervalSet(unsigned long long ullTicks);
248248

249249
extern unsigned long long PRCMSlowClkCtrGet(void);
250+
extern unsigned long long PRCMSlowClkCtrFastGet(void);
250251
extern void PRCMSlowClkCtrMatchSet(unsigned long long ullTicks);
251252
extern unsigned long long PRCMSlowClkCtrMatchGet(void);
252253

Lines changed: 66 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -34,105 +34,92 @@
3434
#include "inc/hw_types.h"
3535
#include "interrupt.h"
3636
#include "pybsleep.h"
37-
#include "mpcallback.h"
3837
#include "mpexception.h"
3938
#include "mperror.h"
39+
#include "mpirq.h"
4040

4141

4242
/******************************************************************************
43-
DEFINE PUBLIC DATA
43+
DECLARE PUBLIC DATA
4444
******************************************************************************/
45-
const mp_arg_t mpcallback_init_args[] = {
46-
{ MP_QSTR_mode, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
45+
const mp_arg_t mp_irq_init_args[] = {
46+
{ MP_QSTR_trigger, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
47+
{ MP_QSTR_priority, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} }, // the lowest priority
4748
{ MP_QSTR_handler, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
48-
{ MP_QSTR_priority, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
49-
{ MP_QSTR_value, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
50-
{ MP_QSTR_wake_from, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = PYB_PWR_MODE_ACTIVE} },
49+
{ MP_QSTR_wake, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
5150
};
5251

52+
/******************************************************************************
53+
DECLARE PRIVATE DATA
54+
******************************************************************************/
55+
STATIC uint8_t mp_irq_priorities[] = { INT_PRIORITY_LVL_7, INT_PRIORITY_LVL_6, INT_PRIORITY_LVL_5, INT_PRIORITY_LVL_4,
56+
INT_PRIORITY_LVL_3, INT_PRIORITY_LVL_2, INT_PRIORITY_LVL_1 };
57+
5358
/******************************************************************************
5459
DEFINE PUBLIC FUNCTIONS
5560
******************************************************************************/
56-
void mpcallback_init0 (void) {
61+
void mp_irq_init0 (void) {
5762
// initialize the callback objects list
58-
mp_obj_list_init(&MP_STATE_PORT(mpcallback_obj_list), 0);
63+
mp_obj_list_init(&MP_STATE_PORT(mp_irq_obj_list), 0);
5964
}
6065

61-
mp_obj_t mpcallback_new (mp_obj_t parent, mp_obj_t handler, const mp_cb_methods_t *methods, bool enable) {
62-
mpcallback_obj_t *self = m_new_obj(mpcallback_obj_t);
63-
self->base.type = &pyb_callback_type;
66+
mp_obj_t mp_irq_new (mp_obj_t parent, mp_obj_t handler, const mp_irq_methods_t *methods) {
67+
mp_irq_obj_t *self = m_new_obj(mp_irq_obj_t);
68+
self->base.type = &mp_irq_type;
6469
self->handler = handler;
6570
self->parent = parent;
66-
self->methods = (mp_cb_methods_t *)methods;
67-
self->isenabled = enable;
71+
self->methods = (mp_irq_methods_t *)methods;
72+
self->isenabled = true;
6873
// remove it in case it was already registered
69-
mpcallback_remove(parent);
70-
mp_obj_list_append(&MP_STATE_PORT(mpcallback_obj_list), self);
74+
mp_irq_remove(parent);
75+
mp_obj_list_append(&MP_STATE_PORT(mp_irq_obj_list), self);
7176
return self;
7277
}
7378

74-
mpcallback_obj_t *mpcallback_find (mp_obj_t parent) {
75-
for (mp_uint_t i = 0; i < MP_STATE_PORT(mpcallback_obj_list).len; i++) {
76-
mpcallback_obj_t *callback_obj = ((mpcallback_obj_t *)(MP_STATE_PORT(mpcallback_obj_list).items[i]));
79+
mp_irq_obj_t *mp_irq_find (mp_obj_t parent) {
80+
for (mp_uint_t i = 0; i < MP_STATE_PORT(mp_irq_obj_list).len; i++) {
81+
mp_irq_obj_t *callback_obj = ((mp_irq_obj_t *)(MP_STATE_PORT(mp_irq_obj_list).items[i]));
7782
if (callback_obj->parent == parent) {
7883
return callback_obj;
7984
}
8085
}
8186
return NULL;
8287
}
8388

84-
void mpcallback_wake_all (void) {
89+
void mp_irq_wake_all (void) {
8590
// re-enable all active callback objects one by one
86-
for (mp_uint_t i = 0; i < MP_STATE_PORT(mpcallback_obj_list).len; i++) {
87-
mpcallback_obj_t *callback_obj = ((mpcallback_obj_t *)(MP_STATE_PORT(mpcallback_obj_list).items[i]));
91+
for (mp_uint_t i = 0; i < MP_STATE_PORT(mp_irq_obj_list).len; i++) {
92+
mp_irq_obj_t *callback_obj = ((mp_irq_obj_t *)(MP_STATE_PORT(mp_irq_obj_list).items[i]));
8893
if (callback_obj->isenabled) {
8994
callback_obj->methods->enable(callback_obj->parent);
9095
}
9196
}
9297
}
9398

94-
void mpcallback_disable_all (void) {
99+
void mp_irq_disable_all (void) {
95100
// re-enable all active callback objects one by one
96-
for (mp_uint_t i = 0; i < MP_STATE_PORT(mpcallback_obj_list).len; i++) {
97-
mpcallback_obj_t *callback_obj = ((mpcallback_obj_t *)(MP_STATE_PORT(mpcallback_obj_list).items[i]));
101+
for (mp_uint_t i = 0; i < MP_STATE_PORT(mp_irq_obj_list).len; i++) {
102+
mp_irq_obj_t *callback_obj = ((mp_irq_obj_t *)(MP_STATE_PORT(mp_irq_obj_list).items[i]));
98103
callback_obj->methods->disable(callback_obj->parent);
99104
}
100105
}
101106

102-
void mpcallback_remove (const mp_obj_t parent) {
103-
mpcallback_obj_t *callback_obj;
104-
if ((callback_obj = mpcallback_find(parent))) {
105-
mp_obj_list_remove(&MP_STATE_PORT(mpcallback_obj_list), callback_obj);
107+
void mp_irq_remove (const mp_obj_t parent) {
108+
mp_irq_obj_t *callback_obj;
109+
if ((callback_obj = mp_irq_find(parent))) {
110+
mp_obj_list_remove(&MP_STATE_PORT(mp_irq_obj_list), callback_obj);
106111
}
107112
}
108113

109-
uint mpcallback_translate_priority (uint priority) {
110-
if (priority < 1 || priority > 7) {
114+
uint mp_irq_translate_priority (uint priority) {
115+
if (priority < 1 || priority > MP_ARRAY_SIZE(mp_irq_priorities)) {
111116
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
112117
}
113-
114-
switch (priority) {
115-
case 1:
116-
return INT_PRIORITY_LVL_7;
117-
case 2:
118-
return INT_PRIORITY_LVL_6;
119-
case 3:
120-
return INT_PRIORITY_LVL_5;
121-
case 4:
122-
return INT_PRIORITY_LVL_4;
123-
case 5:
124-
return INT_PRIORITY_LVL_3;
125-
case 6:
126-
return INT_PRIORITY_LVL_2;
127-
case 7:
128-
return INT_PRIORITY_LVL_1;
129-
default:
130-
return INT_PRIORITY_LVL_7;
131-
}
118+
return mp_irq_priorities[priority - 1];
132119
}
133120

134-
void mpcallback_handler (mp_obj_t self_in) {
135-
mpcallback_obj_t *self = self_in;
121+
void mp_irq_handler (mp_obj_t self_in) {
122+
mp_irq_obj_t *self = self_in;
136123
if (self && self->handler != mp_const_none) {
137124
// when executing code within a handler we must lock the GC to prevent
138125
// any memory allocations.
@@ -159,59 +146,57 @@ void mpcallback_handler (mp_obj_t self_in) {
159146
/******************************************************************************/
160147
// Micro Python bindings
161148

162-
/// \method init()
163-
/// Initializes the interrupt callback. With no parameters passed, everything will default
164-
/// to the values assigned to mpcallback_init_args[].
165-
STATIC mp_obj_t callback_init(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
166-
mpcallback_obj_t *self = pos_args[0];
149+
STATIC mp_obj_t mp_irq_init (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
150+
mp_irq_obj_t *self = pos_args[0];
167151
// this is a bit of a hack, but it let us reuse the callback_create method from our parent
168152
((mp_obj_t *)pos_args)[0] = self->parent;
169153
self->methods->init (n_args, pos_args, kw_args);
170154
return mp_const_none;
171155
}
172-
MP_DEFINE_CONST_FUN_OBJ_KW(callback_init_obj, 1, callback_init);
156+
MP_DEFINE_CONST_FUN_OBJ_KW(mp_irq_init_obj, 1, mp_irq_init);
173157

174-
/// \method enable()
175-
/// Enables the interrupt callback
176-
STATIC mp_obj_t callback_enable (mp_obj_t self_in) {
177-
mpcallback_obj_t *self = self_in;
158+
STATIC mp_obj_t mp_irq_enable (mp_obj_t self_in) {
159+
mp_irq_obj_t *self = self_in;
178160
self->methods->enable(self->parent);
179161
self->isenabled = true;
180162
return mp_const_none;
181163
}
182-
STATIC MP_DEFINE_CONST_FUN_OBJ_1(callback_enable_obj, callback_enable);
164+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_irq_enable_obj, mp_irq_enable);
183165

184-
/// \method disable()
185-
/// Disables the interrupt callback
186-
STATIC mp_obj_t callback_disable (mp_obj_t self_in) {
187-
mpcallback_obj_t *self = self_in;
166+
STATIC mp_obj_t mp_irq_disable (mp_obj_t self_in) {
167+
mp_irq_obj_t *self = self_in;
188168
self->methods->disable(self->parent);
189169
self->isenabled = false;
190170
return mp_const_none;
191171
}
192-
STATIC MP_DEFINE_CONST_FUN_OBJ_1(callback_disable_obj, callback_disable);
172+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_irq_disable_obj, mp_irq_disable);
173+
174+
STATIC mp_obj_t mp_irq_flags (mp_obj_t self_in) {
175+
mp_irq_obj_t *self = self_in;
176+
return mp_obj_new_int(self->methods->flags(self->parent));
177+
}
178+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_irq_flags_obj, mp_irq_flags);
193179

194-
/// \method \call()
195-
/// Triggers the interrupt callback
196-
STATIC mp_obj_t callback_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
180+
STATIC mp_obj_t mp_irq_call (mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
197181
mp_arg_check_num(n_args, n_kw, 0, 0, false);
198-
mpcallback_handler (self_in);
182+
mp_irq_handler (self_in);
199183
return mp_const_none;
200184
}
201185

202-
STATIC const mp_map_elem_t callback_locals_dict_table[] = {
186+
STATIC const mp_map_elem_t mp_irq_locals_dict_table[] = {
203187
// instance methods
204-
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&callback_init_obj },
205-
{ MP_OBJ_NEW_QSTR(MP_QSTR_enable), (mp_obj_t)&callback_enable_obj },
206-
{ MP_OBJ_NEW_QSTR(MP_QSTR_disable), (mp_obj_t)&callback_disable_obj },
188+
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&mp_irq_init_obj },
189+
{ MP_OBJ_NEW_QSTR(MP_QSTR_enable), (mp_obj_t)&mp_irq_enable_obj },
190+
{ MP_OBJ_NEW_QSTR(MP_QSTR_disable), (mp_obj_t)&mp_irq_disable_obj },
191+
{ MP_OBJ_NEW_QSTR(MP_QSTR_flags), (mp_obj_t)&mp_irq_flags_obj },
207192
};
208193

209-
STATIC MP_DEFINE_CONST_DICT(callback_locals_dict, callback_locals_dict_table);
194+
STATIC MP_DEFINE_CONST_DICT(mp_irq_locals_dict, mp_irq_locals_dict_table);
210195

211-
const mp_obj_type_t pyb_callback_type = {
196+
const mp_obj_type_t mp_irq_type = {
212197
{ &mp_type_type },
213-
.name = MP_QSTR_callback,
214-
.call = callback_call,
215-
.locals_dict = (mp_obj_t)&callback_locals_dict,
198+
.name = MP_QSTR_irq,
199+
.call = mp_irq_call,
200+
.locals_dict = (mp_obj_t)&mp_irq_locals_dict,
216201
};
217202

0 commit comments

Comments
 (0)