Using two interupts together

I am using two interupts. One which fills a buffer, the other sends the buffer to OCR1A. However I need the second interupt to wait until the first has read into the buffer before “interupting” it. To disable an interupt do I just disable the timer. i.e

TCCR0|=(0<<CS00); //disable pwm timer
    	TIMSK|=(0<<TOIE0);
		res =	f_read(&fsrc, &bufor0, 512, &bw2);//first timer reads into buffer
		printf("res0 = %d", res);
		TCCR0|=(1<<CS00); //enable pwm timer
		TCNT0=0;
    	TIMSK|=(1<<TOIE0);
		buf_1 = 0;

It isnt quite working, but I think Im on the right track?

Hello.

You could disable the timer, or you could just disable the timer interrupt (often, disabling a timer is not acceptable because it will interfere with timing). It looks like you are trying to do both, though it doesn’t sound like you realize it:

TCCR0|=(0<<CS00); //trying to disable pwm timer
TIMSK|=(0<<TOIE0); // trying to disable timer0 overflow interrupt

The problem is that the two lines above have no effect on the registers, because ORing a value with zero has no effect on it, and bit-shifted zero is still zero. If you want to set a bit, in a byte, you use the following construct:

byte |= (1 << bitnumber)

but if you want to clear a bit in a byte, you can’t just change the 1 to a zero, you need to do the following:

byte &= ~(1 << bitnumber)

I urge you to actually work it out on paper with a few examples, first by doing it your (wrong) way and then by doing what I posted. It should very quickly become clear why what you’re doing doesn’t work.

Also, if the code you posted is from within an interrupt, disabling the timer0 interrupt might be unnecessary since interrupts are already globally disabled while inside an interrupt.

Aside from all this, using interrupts is really tricky, and I suspect you don’t appreciate all of the subtle and potentially major problems that can arise from using them unsafely (and using two interrupts together in a coordinated way can be significantly more difficult to pull off correctly). If it’s possible to do something without using interrupts, or using only one, I urge you to go that route, and, as a general rule, you should be trying to keep your interrupts as short as possible.

- Ben

Thanks Ben,
So you have to delete the value as oppsed to changing it to 0. Right.
That code isnt inside an interupt. Thats inside while(1){ } in main. I am trying to learn to use double buffers to access data on an sd card. I found a file system for sd cards and I need to use the data in the buffers and pass that to a pin, when the buffer’s empty I need to switch to the other buffer.
I learnt about using interupt timers from tutorials on dimming leds! Its quite a leap to using two interupts at the same time - I cant avoid it though - pwm and filling buffers…
Something more like this then:

TCCR0 &= ~(1<<CS00); //trying to disable pwm timer

?

Yup.

Ok, Spent all night reading about timers and pwm. I still havent solved my buffer filling issue, however I have made some modifications to my pwm initialization - wondered if you could check it. Ive added comments to explain what I think is going on.

void pwm_init(void)
{
    /* use OC1A pin as output */
    DDRB = _BV(PB5);

    /* 
    * clear OC1A on compare match 
    * set OC1A at BOTTOM, non-inverting mode
    * Fast PWM, 8bit
    */
    TCCR1A = _BV(COM1A1) | _BV(WGM10);//COM1A1 = clear at TOP, WGM10 = fast pwm
    /* fast PWM, 8bit
    * Prescaler: clk/1 = 16MHz, running 16MHz clock.
    */
    TCCR1B = _BV(WGM12) | _BV(CS10) ;//no prescaling. WGM12 = fast pwm
    //TCCR1B =(1<<WGM13)|(1<<WGM12); 
    /* set initial duty cycle to zero */
    OCR1A = 0;
	//DO I NEED TO WORRY ABOUT THE OTHER REGISTER? i.e OCR1AH and OCR1AL??
    
    // Setup Timer0  This compares to timer1 above I think?
  
    TCCR0|=(1<<CS01);//prescaler of 8
    TCNT0=0;//start count at 0
    TIMSK|=(1<<TOIE0);
	//sample_count = 8;
	sample = 0;

}


ISR(TIMER0_OVF_vect) 

{ 
			if(buf_1)								//play from first buffor
		{	
			OCR1A=bufor1[sample++];		//set PWM VAlue
						
			if(sample>511)
			{
				read=1;
				sample=0;
				buf_1=0;
				
			}
		}else//buf_1 = 0									//play from second buffor
		{	
			OCR1A=bufor0[sample++];		//set PWM VAlue
						
			if(sample>511)
			{
				read=1;
				sample=0;
				buf_1=1;				

			}
		}
}

I have tried to setup the timers in pwm_init() to handle the pwm side of things. Then in ISR I am doing a check on which buffer to pass to OCR1A. Im a bit of a beginner when it comes to pwm, but from reading the registers from the datasheet I think Im there - a little worried as OCR1A is 16bit, but checked an example and I think its OK. I dont know whether I should be passing 1 bit to OCR1AH and the next bit to OCR1AL rather than just a single it to OCR1A??

Im thinking

OCR1AH=bufor1[sample++];		//set PWM VAlue
OCR1AL=bufor1[sample++];	//I understand the line above will shift sample on 1, so this will shift it on another 1 bit?