Question regarding timer1/counter

csnsc14320:
…am having a little trouble figuring out what is missing. also, what are ringBuff(TOTALRING), tick2, and flag doing exactly?

I’m not sure you need the explanation anymore, but I left out the digital reading and writing because I though you’d need something more low-level to do the job. As for the bugger, ringBuff was the 56 bytes (I used 60) that stored the back information. The TOTALRING was a macro - it is replaced in this case with a constant number, and is a handy way to speed up code, rather than using variables that have to be read/written at run time. The problem was I was trying to write fast code for the interrupt instead of easy to read code for you - sorry.

As far as code goes, Graynomad’s solves the problem very nicely, using very few cycles by using pointers instead of arrays. He also removes the start pointer, by assuming ALL data is valid, and the buffer is always 56 bytes long. The first 56 microseconds you might send out bad data (as he mentioned), but that’s easily solved by prefilling the buffer with zeros in the setup() function.

Reworking the code to handle boundary conditions as the buffer rolls over, and to clamp it 56 bytes, here’s an option:

#define BUFFSIZE    56
#define INPORT PINB
#define OUTPORT PORTC
#define MYPORT_IN_BIT 2  
#define MYPORT_OUT_BIT 6  
volatile unsigned char buffer[BUFFSIZE], *ptr=buffer, *end=ptr+BUFFSIZE;
// rather than shifting in code, just use masks of position
#define MYPORT_IN_MASK (1<<MYPORT_IN_BIT)
#define MYPORT_OUT_MASK (1<<MYPORT_OUT_BIT)
void setup(void)
{
  // ... lots of things, plus:
  memset(buffer,0,sizeof(buffer));
}
void  one_mhz_interrupt_func () 
{
  OUTPORT |= (*ptr) ? MYPORT_OUT_MASK : 0; // alternative: if (*ptr) OUTPORT |= MYPORT_OUT_MASK;
  *ptr++ = INPORT & MYPORT_IN_MASK; // store true/false flag - bit is immaterial
  if (ptr == end)
    ptr = buffer;
}

Another optimization: since the actual bits are immaterial, we don’t need to shift them, so we just store the values in our array after masking off the other bits - the result should be faster, possibly fast enough to run 1 million times a second.

But if this doesn’t all work in 1mhz, I have another solution…

If the signal of interest is 1Hz and you are delaying its edges by microseconds the simplest solution is do timing loops in the ISR. Will have to find a loop body that takes 16 cycles to execute and that's a 1us resolution counter....

If synching to the external 1MHz clock is needed, use DQ latches on the outputs.

Good points (and improved code) by both Rob and David, the actual input bit doesn't matter, we just need to know the "logical" level of the input, there's no need to move the actual bit around.

delayed output signal on pins 6, 7, and 8 on PORTC?

If the signal on these pins is exactly the same why use three pins? Current-driving capacity?


Rob

MarkT:
If the signal of interest is 1Hz and you are delaying its edges by microseconds the simplest solution is do timing loops in the ISR. Will have to find a loop body that takes 16 cycles to execute and that’s a 1us resolution counter…

Variations of that have been discussed, but he wants to use a very precise 1mhz external signal for the timing. Otherwise, as you say, an interrupt routine on rise and fall with a careful loop, or checking micros()would do the job.

But the delay is a few cycles, so the difference between the external and internal clocks isn't going to be significant - if the delays were a whole second, say, then ppm accuracy would matter!