Odd timing with LedControl


the purpose of exercise experiment reducing flicker , trying buy more processing time between interrupts.

the program below running 2 8x8 bicolour matrices , using 4 cascaded max7219s. pair each matrix switched timer2 interrupt 2 colours not on described in http://www.arduino.cc/playground/main/multiplexmax72xx. program combination of program , ledcontrol library http://www.arduino.cc/playground/main/ledcontrol.

the latter has been de-libraried (such word?) modified , used direct in code has saved 772 bytes , gives same results intents, have closer access it.
the program works should except speed issue baffles me.
the 2 procedures of concern loop() , following setrow().

if activate startisr() & stopisr() in loop() , disable them in settrow() matrix update runs 3 times faster if reverse.

however, on surface, number of times interrupts interrupted same , time lag difference ought time taken call setrow() procedure , return it.

the eventual aim attempt turn interrupts on/off in latter half of spitransfer() [where commented] had bigger effect on speed , flicker.

could please explain going on?

code: [select]

//saves 772 bytes compiled
#include "binary.h"
//the opcodes max7221 , max7219
#define op_noop   0
#define op_digit0 1
#define op_digit1 2
#define op_digit2 3
#define op_digit3 4
#define op_digit4 5
#define op_digit5 6
#define op_digit6 7
#define op_digit7 8
#define op_decodemode  9
#define op_intensity   10
#define op_scanlimit   11
#define op_shutdown    12
#define op_displaytest 15

#define isr_freq 190                     //190=650hz 249=500hz
#define red 0
#define green 1
#define reda 0                           // address of max7221 red leds#define reda 0                           // address of max7221 red leds
#define greena 1                         // address of max7221 green leds
#define redb 2                           // address of max7221 red leds#define reda 0                           // address of max7221 red leds
#define greenb 3                         // address of max7221 green leds
#define spi_mosi 10
#define spi_clk 9
#define spi_cs 8
#define maxdevices 4

byte spidata[16];
byte status[64];
int maxinshutdown=green;                // tells max7221 off
unsigned long isrtime;                   // debug test how long in isr
byte count=0;
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void setup() {
   pinmode(spi_mosi,output);
   pinmode(spi_clk,output);
   pinmode(spi_cs,output);
   digitalwrite(spi_cs,high);
 
   for(int i=0;i<64;i++)
     status[i]=0x00;
   for(int i=0;i<maxdevices;i++) {
     spitransfer(i,op_displaytest,0);
     spitransfer(i, op_scanlimit,7);                  //scanlimit set max on startup
     spitransfer(i,op_decodemode,0);    //scanlimit set max on startup
     cleardisplay(i);
     spitransfer(i, op_shutdown,0);                  //shutdown-mode on startup
   }
   spitransfer(reda, op_intensity,12);
   spitransfer(redb, op_intensity,12);
   spitransfer(greena, op_intensity,15);
   spitransfer(greenb, op_intensity,15);  // 0 = dim, 15 = full brightness 15

   setisrtimer();                        // setup timer
   startisr();                           // start timer toggle shutdown
}

void loop() {
 count++;
  for(int row=0;row<8;row++) {
//stopisr();
   setrow(greenb,row,count);
//startisr();
//stopisr();
   setrow(redb,row,b01010101);
//startisr();
//stopisr();
   setrow(greena,row,b00001111);
//startisr();
//stopisr();
   setrow(reda,row,b11110000);    
//startisr();
  }
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
void setrow(int addr, int row, byte value) {
   int offset;
stopisr();
   offset=addr*8;
   status[offset+row]=value;
   spitransfer(addr, row+1,status[offset+row]);
startisr();
}

void spitransfer(int addr, volatile byte opcode, volatile byte data) {
   //create array data shift out
   int offset=addr*2;
   int maxbytes=maxdevices*2;
   for(int i=0;i<maxbytes;i++)
     spidata[i]=(byte)0;
   
   spidata[offset+1]=opcode;    //put our device data array
   spidata[offset]=data;
// stopisr();                      //added
   digitalwrite(spi_cs,low);        //enable line
   for(int i=maxbytes;i>0;i--)      //now shift out data
      shiftout(spi_mosi,spi_clk,msbfirst,spidata[i-1]);
   digitalwrite(spi_cs,high);      //latch data onto display
//  startisr();                    //added
}

////////////////////////////////////////////////////////////////////////////
/////////////////////////////isr timer functions ///////////////////////////
isr(timer2_compa_vect) {  //this isr toggles shutdown between 2max7221's
// digitalwrite(2, maxinshutdown == red ? high : low);
if(maxinshutdown==red){
  spitransfer(greena, op_shutdown,0);
  spitransfer(greenb, op_shutdown,0);
  spitransfer(reda, op_shutdown,1);
  spitransfer(redb, op_shutdown,1);
  maxinshutdown=green;
}
else {
  spitransfer(reda, op_shutdown,0);
  spitransfer(redb, op_shutdown,0);
  spitransfer(greena, op_shutdown,1);
  spitransfer(greenb, op_shutdown,1);
  maxinshutdown=red;
}
}  

void setisrtimer(){          // setup isr timer controlling toggling
 tccr2a = 0x02;                        // wgm22=0 + wgm21=1 + wgm20=0 = mode2 (ctc)
 tccr2b = 0x05;                // cs22=1 + cs21=0 + cs20=1 = /128 prescaler (125khz)
 tcnt2 = 0;                            // clear counter
 ocr2a = isr_freq;                     // set top (divisor) - see #define
}

void startisr(){  // starts isr
//  tcnt2 = 0;                            // clear counter (needed here also)
 timsk2|=(1<<ocie2a);                  // set interrupts=enabled (calls isr(timer2_compa_vect)
}

void stopisr(){    // stops isr
 timsk2&=~(1<<ocie2a);                  // disable interrupts
}
//****************************************************************************
//****************************************************************************
void cleardisplay(int addr) {
   int offset;
   offset=addr*8;
   for(int i=0;i<8;i++) {
     status[offset+i]=0;
     spitransfer(addr, i+1,status[offset+i]);
   }
}

void setled(int addr, int row, int column, boolean state) {
   int offset;
   byte val=0x00;
   offset=addr*8;
   val=b10000000 >> column;
   if(state)
     status[offset+row]=status[offset+row]|val;
   else {
     val=~val;
     status[offset+row]=status[offset+row]&val;
   }
   spitransfer(addr, row+1,status[offset+row]);
}
     
void setcolumn(int addr, int col, byte value) {
   byte val;
   for(int row=0;row<8;row++) {
     val=value >> (7-row);
     val=val & 0x01;
     setled(addr,row,col,val);
   }
}

void clearmatrix(){
//stopisr();            // disable interrupts - stop toggling shutdown when updating
 cleardisplay(reda);
 cleardisplay(greena);
 cleardisplay(redb);
 cleardisplay(greenb);
//startisr();           // enable interrupts again
}

i have no clue difference is, wonder whether making startisr , stopisr inline functions makes difference. there overhead involved in making call, , returning call. making functions inline removes overhead, since code replicated everywhere function called.

since functions single line functions, code shouldn't much, if any, larger.

have looked @ resulting assembly code in each case?


Arduino Forum > Forum 2005-2010 (read only) > Software > Syntax & Programs > Odd timing with LedControl


arduino

Comments

Popular posts from this blog

CAN'T INSTALL MAMBELFISH 1.5 FROM DIRECTORY - Joomla! Forum - community, help and support

error: expected initializer before 'void'

CPU load monitoring using GPIO and leds - Raspberry Pi Forums