Array of macro

hello all,

I try to make an array to hold some macros in order to be easy to call them in a loop
and so far i got this

typedef void (*func_ptr_t)(void);
//PC0-PC7 = CAM1-8
#define CAM00_1      PORTC |=  (1<<0)
#define CAM00_0      PORTC &= ~(1<<0)
#define CAM01_1      PORTC |=  (1<<1)
#define CAM01_0      PORTC &= ~(1<<1)
#define CAM02_1      PORTC |=  (1<<2)
#define CAM02_0      PORTC &= ~(1<<2)
#define CAM03_1      PORTC |=  (1<<3)
#define CAM03_0      PORTC &= ~(1<<3)
#define CAM04_1      PORTC |=  (1<<4)
#define CAM04_0      PORTC &= ~(1<<4)
#define CAM05_1      PORTC |=  (1<<5)
#define CAM05_0      PORTC &= ~(1<<5)
#define CAM06_1      PORTC |=  (1<<6)
#define CAM06_0      PORTC &= ~(1<<6)
#define CAM07_1      PORTC |=  (1<<7)
#define CAM07_0      PORTC &= ~(1<<7)
//PK0-PK7 = CAM9-16
#define CAM08_1      PORTK |=  (1<<0)
#define CAM08_0      PORTK &= ~(1<<0)
#define CAM09_1      PORTK |=  (1<<1)
#define CAM09_0      PORTK &= ~(1<<1)
#define CAM10_1      PORTK |=  (1<<2)
#define CAM10_0      PORTK &= ~(1<<2)
#define CAM11_1      PORTK |=  (1<<3)
#define CAM11_0      PORTK &= ~(1<<3)
#define CAM12_1      PORTK |=  (1<<4)
#define CAM12_0      PORTK &= ~(1<<4)
#define CAM13_1      PORTK |=  (1<<5)
#define CAM13_0      PORTK &= ~(1<<5)
#define CAM14_1      PORTK |=  (1<<6)
#define CAM14_0      PORTK &= ~(1<<6)
#define CAM15_1      PORTK |=  (1<<7)
#define CAM15_0      PORTK &= ~(1<<7)
//PA0-PA7 = CAM17-24
#define CAM16_1      PORTA |=  (1<<0)
#define CAM16_0      PORTA &= ~(1<<0)
#define CAM17_1      PORTA |=  (1<<1)
#define CAM17_0      PORTA &= ~(1<<1)
#define CAM18_1      PORTA |=  (1<<2)
#define CAM18_0      PORTA &= ~(1<<2)
#define CAM19_1      PORTA |=  (1<<3)
#define CAM19_0      PORTA &= ~(1<<3)
#define CAM20_1      PORTA |=  (1<<4)
#define CAM20_0      PORTA &= ~(1<<4)
#define CAM21_1      PORTA |=  (1<<5)
#define CAM21_0      PORTA &= ~(1<<5)
#define CAM22_1      PORTA |=  (1<<6)
#define CAM22_0      PORTA &= ~(1<<6)
#define CAM23_1      PORTA |=  (1<<7)
#define CAM23_0      PORTA &= ~(1<<7)
//PL0-PL5 = CAM25-30
#define CAM24_1      PORTL |=  (1<<0)
#define CAM24_0      PORTL &= ~(1<<0)
#define CAM25_1      PORTL |=  (1<<1)
#define CAM25_0      PORTL &= ~(1<<1)
#define CAM26_1      PORTL |=  (1<<2)
#define CAM26_0      PORTL &= ~(1<<2)
#define CAM27_1      PORTL |=  (1<<3)
#define CAM27_0      PORTL &= ~(1<<3)
#define CAM28_1      PORTL |=  (1<<4)
#define CAM28_0      PORTL &= ~(1<<4)
#define CAM29_1      PORTL |=  (1<<5)
#define CAM29_0      PORTL &= ~(1<<5)

const func_ptr_t CAM_1[30] = { 
CAM00_1, CAM01_1, CAM02_1, CAM03_1, CAM04_1, CAM05_1, CAM06_1, CAM07_1, CAM08_1, CAM09_1,
CAM10_1, CAM11_1, CAM12_1, CAM13_1, CAM14_1, CAM15_1, CAM16_1, CAM17_1, CAM18_1, CAM19_1,
CAM20_1, CAM21_1, CAM22_1, CAM23_1, CAM24_1, CAM25_1, CAM26_1, CAM27_1, CAM28_1, CAM29_1};

const  func_ptr_t CAM_0[30] = { 
CAM00_0, CAM01_0, CAM02_0, CAM03_0, CAM04_0, CAM05_0, CAM06_0, CAM07_0, CAM08_0, CAM09_0,
CAM10_0, CAM11_0, CAM12_0, CAM13_0, CAM14_0, CAM15_0, CAM16_0, CAM17_0, CAM18_0, CAM19_0,
CAM20_0, CAM21_0, CAM22_0, CAM23_0, CAM24_0, CAM25_0, CAM26_0, CAM27_0, CAM28_0, CAM29_0};

and the function where i need the arrays

void DoTheMatrix()
{
  unsigned long wait = ROM_VAL[ROM_DStart] * 1000 + millis();
  while (millis() < wait) {;} //We wait
  for(byte jj =0; jj < ROM_VAL[ROM_Cycles]; jj++)//repeat n times
  {
    for(ii = 0; ii < ROM_VAL[ROM_Cameras]; ii++)//activate each camera
    {
      ((func_ptr_t)pgm_read_word(&CAM_1[ii]))();//Shutter ON
      delay(ROM_VAL[ROM_BDelay]);
      ((func_ptr_t)pgm_read_word(&CAM_0[ii]))();//Shutter OFF
      delay(ROM_VAL[ROM_BDelay]);
    }
  }
}

But it doesn’t work. can any one help me to solve this issue or have another idea in how to call those macros in a loop?
Thank you

Is there a reason you don't want to use digitalWrite?

It will not work because all a #define does is a straight text replacement one for the other in the pre compiler before passing it onto the compiler. You can not get the macros into an array to call at run time because they will not have been compiled into machine code.

I am not sure why you want to do this. I could imagine you could compile each one as a function and have an array of function addresses, but that is beyond my pay grade in C.

For which board is this code being written?

Hello all, i don't use digitalWrite bcause is slow and i got use with direct port manipulation i got the idea of array from this post http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=138706 and i was thinking that might work also with macros

i will digg more, maybe i will come up with a nice solution

The boartd is arduino mega 2560

gvi70000:
i don’t use digitalWrite bcause is slow and i got use with direct port manipulation

  unsigned long wait = ROM_VAL[ROM_DStart] * 1000 + millis();
  while (millis() < wait) {;} //We wait

Uh huh. Slow. After waiting in a busy loop.

Have you performed any benchmarks to determine if digitalWrite really is too slow for your application?

After adding the necessary changes and code to get it working you will have essentially recreated digitalWrite. Why don’t you just clone digitalWrite and strip out the parts you believe are not necessary?

ok, in this case it doesn't matter the speed but as a general idea i would like to find a solution to my question

You need to create actual functions (macros are not functions)…

void CAM00_1( void ) { PORTC |=  (1<<0); }
void CAM00_0( void ) { PORTC &= ~(1<<0); }
void CAM01_1( void ) { PORTC |=  (1<<1); }
...

Thanks Coding Badly, I already started to change the macros to functions

That’s a lot of typing. If you see the pattern, you could make do with one very quick function call.

void doWhatThisGuyWants(int x, int y) {
  
  volatile uint8_t* thePort;
  
  switch (x>>3){   // x>>3 is the same as x/8 only faster
   case 0:
    thePort = &PORTC;
    break;
   case 1:
    thePort = &PORTK;
    break;
   case 2:
    thePort = &PORTA;
    break;
   case 3:
    thePort = &PORTL;
    break;
  }
  
  if (y){
    *thePort |= (1<< (x&7));  // x&7 is the same as x%8 but faster
  } else {
    *thePort &= ~(1<< (x&7));
  }
   
}

You would call that the same way you are calling the macros now, where the macro names are CAMxx_y.

wow, very nice code Delta_G thanks

Don't optimise it until you need to. Premature optimisation is a great way to waste time and obfuscate your code.

If you need to optimise it, you'll get the best gains from optimising the architecture rather than optimising code at the bottom level (I/O statements etc).

If you really really need to do faster I/O, use the fast digital I/O library rather than hitting the registers directly.

If you eventually do really need to hit registers directly and do it with lots of data as in your example, use a real array and don't try to fake it using numbered macros and hope they somehow end up forming an array - it doesn't work like that. If you need to do this (not that you do, until you have passed through all the other options above) then what you put in the arrays is the data, not the code.

const func_ptr_t CAM_1[30] = { 
CAM00_1, CAM01_1, CAM02_1, CAM03_1, CAM04_1, CAM05_1, CAM06_1, CAM07_1, CAM08_1, CAM09_1,
CAM10_1, CAM11_1, CAM12_1, CAM13_1, CAM14_1, CAM15_1, CAM16_1, CAM17_1, CAM18_1, CAM19_1,
CAM20_1, CAM21_1, CAM22_1, CAM23_1, CAM24_1, CAM25_1, CAM26_1, CAM27_1, CAM28_1, CAM29_1};

You are almost exactly duplicating the internal functionality of digitalWrite, which has arrays that translate pin numbers to ports and bitfields. Why don't you take a look at the source code for digitalWrite() to see how they do it?