It is currently Tue Jun 18, 2013 4:13 am



Post new topic Reply to topic  [ 21 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
 Post subject: Re: DigitalWriteFast library for Uno32?
PostPosted: Wed Feb 15, 2012 10:45 am 
Offline

Joined: Wed May 25, 2011 12:17 am
Posts: 148
So, remember this really ugly implementation of DigitalWriteFast? It relied on gcc being able to optimize away long and complex ternary statements containing constants. It was fast, but it relied on awful-looking C macros that were completely separate from the main pins_arduino.c structures, and thus subject to maintenance nightmares.

Well, it turns out that gcc will also optimize indexing into static arrays with a constant, so we can get ALMOST as fast an implementation, using the code that already exists. No maintenance nightmare, and a pretty closely parallel implementation, and no particularly ugly macros.

variants/xxx/Board_Data.c gets a slight set of modifications so that it can make either global arrays (for pins_arduino.c) or static arrays that disappear when only indexed by constants:
Code:
+#if defined(OPT_BOARD_DATA_STATIC)
+#define MAYBESTATIC static
+#else
+#define MAYBESTATIC
+#endif
 
 /* ------------------------------------------------------------ */
 /*                                     Data Tables                                                                     */
@@ -56,7 +61,7 @@
 ** the TRIS register for the port. This is used for setting the
 ** pin direction.
 */
-const uint32_t port_to_tris_PGM[] = {
+MAYBESTATIC const uint32_t port_to_tris_PGM[] = {
        NOT_A_PORT,                             //index value 0 is not used
 
 #if defined(_PORTA)
@@ -108,7 +113,7 @@
 /* This table is used to map the digital pin number to the port
 ** containing that pin.
 */
-const uint8_t digital_pin_to_port_PGM[] = {
+MAYBESTATIC const uint8_t digital_pin_to_port_PGM[] = {

And then fastio.h gets code to include the arrays, and uses inline functions that closely parallel wiring_digital.c. It even gets to include some of the sanity checking:
Code:
#define OPT_BOARD_DATA_STATIC 1
#define OPT_BOARD_DATA 1
#define OPT_BOARD_INTERNAL 1
#include <p32xxxx.h>
#include <WProgram.h>
#include <Board_Data.c>

/*
 * This looks a lot like digitalWrite, but uses the static arrays and is inline.
 * when called with constants, it should optimize down to the single instruct.
 */
static inline void _dwf(uint8_t pin, uint8_t val)
{
    p32_ioport *   iop;
    unsigned int      port;
    unsigned int      bit;

   //* Get the port number for this pin.
   if ((pin >= NUM_DIGITAL_PINS) ||
       ((port = digitalPinToPort(pin)) == NOT_A_PIN))
   {
      return;
   }

   //* Obtain pointer to the registers for this io port.
   iop = (p32_ioport *)portRegisters(port);

   //* Obtain bit mask for the specific bit for this pin.
   bit = digitalPinToBitMask(pin);

   //* Set the pin state
   if (val == LOW)
   {
      iop->lat.clr = bit;
   }
   else
   {
      iop->lat.set = bit;
   }
}


#define digitalWriteFast(P, V)  \
    if (__builtin_constant_p(P) && __builtin_constant_p(V)) {   \
   _dwf(P, V);                  \
    } else {                     \
   digitalWrite((P), (V));               \
    }

This makes me feel a lot warmer and fuzzier than the previous implementation. It ought to be MUCH easier to add to the different variants, and could have "partial" support added to the core with no impact...


Top
 Profile  
 
 Post subject: Re: DigitalWriteFast library for Uno32?
PostPosted: Tue Feb 21, 2012 10:40 pm 
Offline

Joined: Mon Aug 15, 2011 9:21 pm
Posts: 164
Location: Sweden
You're the man! :)


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 21 posts ]  Go to page Previous  1, 2, 3  Next

Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Theme designed by stylerbb.net © 2008
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
All times are UTC [ DST ]