gke
Its a shame we have to tunnel in ourselves to make the pin I/O respectably quick when it should have just been coded that way in the first place. ...
LeafLabs have aimed for API compatibility with the Arduino/Wiring digitalRead/digitalWrite mechanism.
One of the things that attracted me to Maple is Arduino/Wiring compatibility.
That API uses an integer to refer to each pin, which needs to be mapped, and some pin-number validation on every access. On the Arduino, this mechanism supports a pin change rate of about 100KHz, vs a raw rate of several MHz.
Many Arduino examples assign the pin number to an ordinary int
variable. Worse, the variables are usually global, and not const
. For example, the Arduino reference page for digitalWrite:
http://arduino.cc/en/Reference/DigitalWrite
This makes optimisation hard for the compiler.
IIRC the mbed software team decided to go a slightly different path, which gives them more room to maneuver as they use pin labels.
Software designers make a choice. The Maple approach is to aim for compatibility with Arduino and Wiring. Mbed went a different route.
IMHO, the Arduino/Wiring approach, followed by Maple, is to make using a microcontroller as simple as practical for a new user. There is now quite a lot of legacy code based on those APIs. When mbed started they had the benefit of hindsight :-)
It is pretty easy to get a high GPIO toggle rate. Each bit of each port can be written or read individually using a hardware mechanism called 'bit banding' at full instruction speed (2 cycle store instruction). All that is needed is the bit band address for the corresponding port bit. All Cortex-M3 processors support bit banding. Sadly, bit band addressing is not supported by DMA, which could have enabled some very sneaky serial peripherals.
I'd like to see LeafLabs support an API which converts a pin number to a bit-band address, and have that API supported and consistent across versions of the library.
For example, a function that returns the bit band address for any valid digital pin, and one that uses it for a fast digital write might be:
typedef int* FastDigitalPin;
FastDigitalPin digitalPinToFastAccess(int pin); // map pin to bit band address
static void inline fastDigitalWrite(FastDigitalPin fastAddress, int value)
{ *fastAddress = value; )
then use it as this (silly) example:
const FastDigitalPin fastPin = digitalPinToFastAccess(13);
// ...
void loop() {
fastDigitalWrite(fastPin, 0);
fastDigitalWrite(fastPin, 1);
}
I taught undergraduate CS, and post graduate SE, though I have been in commercial software products and services for over 20 years.
IMHO, there are many software 'quality' 'dimensions', and the Arduino/Wiring/Maple libraries are not optimised for speed, or completeness of functionality. Their saving feature is they allow things beyond base library support, and usually provide some of the hardware access infrastructure (like struct
definitions and symbolic addresses).
There is a view that Open Source software development has intrinsically higher 'quality', on the basis of 'more eyes'. IMHO this is extremly misleading. I believe Open Source development does allow more eyes to examine code than proprietary code development approaches. IMHO it is misleading because the majority of Open Source projects won't get enough 'eyes', or those 'eyes' don't understand enough to solve hard problems, or they don't have enough time ..., etc. Further, if the problem requires access to specialised hardware, like a good logic analyser, and enough expertise to use it well, then the number of potential 'eyes' become small.
You may be in the privileged position of having rare 'eyes'!
So if you have time to help, please do.
Unfortunately, the I2C on STM32F1xx is a bit weird. If you glance at the Revision History at the back of the RM0008 manual for the STM32F1xx, pretty much every one of the 14 document revisions contain changes and clarification on the I2C peripheral. I think Crenn is very likely the most knowledgeable I2C contributor, ahead of the official library.