Hi,
while porting the Arduino based AeroQuad software to the Maple libraries I found some bugs and other problems:
micros() is not counter underrun safe:
static inline uint32 micros(void) {
uint32 ms;
uint32 cycle_cnt;
uint32 res;
nvic_globalirq_disable();
cycle_cnt = systick_get_count();
ms = millis();
nvic_globalirq_enable();
/* SYSTICK_RELOAD_VAL is 1 less than the number of cycles it
actually takes to complete a SysTick reload */
res = (ms * US_PER_MS) +
(SYSTICK_RELOAD_VAL + 1 - cycle_cnt)/CYCLES_PER_MICROSECOND;
return res;
}
Nice try, but you can not prevent a hardware counter to count by blocking interrupts. When the counter reaches 0 while the interrupts are blocked, the value returned by millis() is not yet incremented, so the returned value is wrong by a millisecond. This code works:
static inline uint32 micros(void) {
uint32 ms;
uint32 cycle_cnt;
uint32 res;
do {
ms = millis();
cycle_cnt = systick_get_count();
} while(ms != millis());
/* SYSTICK_RELOAD_VAL is 1 less than the number of cycles it
actually takes to complete a SysTick reload */
res = (ms * US_PER_MS) +
(SYSTICK_RELOAD_VAL + 1 - cycle_cnt)/CYCLES_PER_MICROSECOND;
return res;
}
The Print class has a bug in the function printing binary values, which uses fillBinary:
static void fillBinary(char *buf, int64 n, int start_bit) {
int b = 0; // position in buf
int i = start_bit; // position in n's bits
while(!(n & (1 << i))) {
i--;
}
for(; i >= 0; i--) {
buf[b++] = '0' + ((n >> i) & 0x1);
}
buf[b] = '';
}
With n=0 the expression !(n & (1 << i))
is always true, so the while loop loops forever. Use this instead:
while(i>0 && !(n & (1 << i))) {
The Wire I2C code has some problems. It does not support clock stretching. It has a major problem when receiving multiple bytes, so it does not work with a ITG-3200 gyro. I will post the fixed code when tuning is done.
The compiler options in libmaple\Makefile are bad. GLOBAL_CFLAGS misses -Wall, so you do not see the potential compiling problems of the library.