using Timer1 alternately SPI and 38kHz PWM

Hi, I was hoping to combine into one sketch, working code for both SPI Dataflash and serial UART IR output.
I was thinking of combining them as a separate function for each process.
So what is currently in setup() will end up in a function within the main loop().
Will I need to reset all the Timer1 registers to wiring IDE defaults before attempting SPI access again?

The CS pin on the Dataflash will still be switching high/low at 38kHz when data transmitted.
Not sure if that is a good idea. The output on pin 10 is not needed.

[code]
//test IR transmission using Arduino pro mini UART
//generates 38kHz carrier wave on pin 9 and 10
//sends data via TX every 500ms
void setup()
{
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);

  // Clear Timer on Compare Match (CTC) Mode
  bitWrite(TCCR1A, WGM10, 0);
  bitWrite(TCCR1A, WGM11, 0);
  bitWrite(TCCR1B, WGM12, 1);
  bitWrite(TCCR1B, WGM13, 0);

  // Toggle OC1A and OC1B on Compare Match.
  bitWrite(TCCR1A, COM1A0, 1);
  bitWrite(TCCR1A, COM1A1, 0);
  bitWrite(TCCR1A, COM1B0, 1);
  bitWrite(TCCR1A, COM1B1, 0);

  // No prescaling
  bitWrite(TCCR1B, CS10, 1);
  bitWrite(TCCR1B, CS11, 0);
  bitWrite(TCCR1B, CS12, 0);

  OCR1A = 210;
  OCR1B = 210;

  Serial.begin(1200);
}

void loop()
{
  Serial.write(0);
  Serial.write(128);//my data from an array[] will go here
  Serial.write(255);
  delay(500);
}

[/code]

rxstopend.ino (1.15 KB)

program1test.ino (2.32 KB)

Please put both sketches being combined into post in code tags.

Please put your best attempt at combining them into post (also in code tags), along with any compiler errors you get.

Please attach a schematic (hand drawn is fine. No fritzing, the helpful people hate it) of what is connected to what.

You. Should be able to turn off the pin 10 38khz signal. There’s no reason that it should have to toggle both 9 and 10.
You might be able to stop it just by doing a digitalWrite(10, 0) immediately after the 38k in it code - that way you shouldn’t have to figure out the timer internals.

If you clear bit COM1B0 in TCCR1A then pin 10 will stop toggling and revert to normal function.

But you could also simply use a different pin for your chip select. As long as pin 10 (aka SS) is set as an output the SPI will function as a master. You don’t have to use that pin as a chip select your flash part.

simplystupid:
Hi, I was hoping to combine into one sketch, working code for both SPI Dataflash and serial UART IR output.
I was thinking of combining them as a separate function for each process.
So what is currently in setup() will end up in a function within the main loop().
Will I need to reset all the Timer1 registers to wiring IDE defaults before attempting SPI access again?

The CS pin on the Dataflash will still be switching high/low at 38kHz when data transmitted.
Not sure if that is a good idea. The output on pin 10 is not needed.

You can perfectly configure the timer outside the setup function. Depending on how you plan to use it it might be wise to stop the timer, set the registers and start it again. Not doing so, most registers will be updated when the timer overflows, not exactly when you update them.

I suggest, when configuring the timer, to first clear all the registers. The Arduino compiler sets defaults. Sometimes this may not be obvious and causes the timer to work differently from what you expected.

You should then end up with a function as this:

    TCCR1B = 0;                                            // Clear Register

     // Set timer 1 Clock source = FOsc/8 <=> 2MHz, Enable Noise Canceller
    TCCR1B |= ((1<<ICNC1)|(1<<CS11));                
    TCCR1A = 0;                                            // Normal counting mode 
    TIMSK1 |= _BV(ICIE1);                              // Enable input capture interrupt for timer 1
    TIMSK1 |= _BV(OCIE1A);                           // Timer1 compare output interrupt enable (A)
    TIMSK1 |= _BV(OCIE1B);                           // Timer1 compare output interrupt enable (B)
    
    ...

Note: Bitwise operations work this way:
Lets assume you want to set (write 1) OCIE1B bit on the TIMSK1 register.

Using

TIMSK1 |= _BV(OCIE1B);

writes a logical one on this bit. It does not affect others

Using

TIMSK1 &= ~_BV(OCIE1B);

writes a logical zero on this bit. It does not affect others.

Assuming you follow my advise to clear the timer before setting it up all registers are set to zero, therefore you’ll only have to write ones.

As to Pin 10 you should be able to disable output on it. There is a register to configure if pin 10, 11 or 12 are used as general purpose I/O or toggled trough the hardware OC1x flag (for PWM or waveform generation).

I dont have code handy for the ATMEGA328, but have a sketch from an attiny 13

  // PWM Configuration
  // Pag 78 Datasheet, Table 11.3 - Fast PWM (32KHz)
  // OCOA/PB0 - Non Inverting Mode, Clear on Compare match, Set on Bottom
  // OC0B/PB1 - Disconnected, Normal I/O operation
  TCCR0A = 2<<COM0A0 | 0<<COM0B0 | 3<<WGM00;
  TCCR0B = 1<<CS00;

This sets PB0 to generate a PWM waveform trough hardware. Normally PB1 should be the complementary (inverted) output for PB0, however I’ve set it up as an I/O.

Ok, thanks for all the suggestions in reply here.
It seems I will not have a problem as long as I set the timers up each function call to transmit the data using the UART.
That is, as far as I understand it, no matter what the SPI does to do it's part with the same registers and how it leaves the timer registers after the call to save (program) the data.

In my testprogram1 sketch, I just have the comment//echo to UART, this is where the function call to transmit IR will be.

When I have had a chance to do a trial sketch, I'll post compile errors or issues on this post.
to be continued.

I'm a bit confused at what you're trying to achieve, please read post #1 and post accordingly

Are you just having problems because while configuring the timer, you're chosen CS line gets linked to the OCRx outputs from timer 1?

These two should work fine independently, so you have to elaborate a bit on what is actually causing the issue.