Example #1
0
bool aci_queue_is_empty(aci_queue_t *aci_q)
{
  bool state = false;

  ble_assert(NULL != aci_q);

  //Critical section
  noInterrupts();
  if (aci_q->head == aci_q->tail)
  {
    state = true;
  }
  interrupts();

  return state;
}
Example #2
0
//------------------------------------------------------------------------------
// Interrupt handler template method that takes a class that implements
// a standard set of methods for the timer abstraction
//------------------------------------------------------------------------------
template <class T> void Servo_Handler(T* timer)
{
    noInterrupts();
    
    uint8_t servoIndex;

    // clear interrupt
    timer->ResetInterrupt();

    if (timer->isEndOfCycle()) {
        timer->StartCycle();
    }
    else {
        servoIndex = SERVO_INDEX(timer->timerId(), timer->getCurrentChannel());
        if (servoIndex < s_servoCount && s_servos[servoIndex].info.isActive) {
            // pulse this channel low if activated
            digitalWrite(s_servos[servoIndex].info.pin, LOW);
        }
        timer->nextChannel();
    }
    
    servoIndex = SERVO_INDEX(timer->timerId(), timer->getCurrentChannel());

    if (servoIndex < s_servoCount && timer->getCurrentChannel() < SERVOS_PER_TIMER) {
        timer->SetPulseCompare(timer->usToTicks(s_servos[servoIndex].usPulse) - c_CycleCompensation);

        if (s_servos[servoIndex].info.isActive) {  // check if activated
            digitalWrite(s_servos[servoIndex].info.pin, HIGH); // its an active channel so pulse it high
        }
    }
    else {
        // finished all channels so wait for the refresh period to expire before starting over
        // allow a few ticks to ensure the next match is not missed
        uint32_t refreshCompare = timer->usToTicks(REFRESH_INTERVAL);
        if ((timer->GetCycleCount() + c_CycleCompensation * 2) < refreshCompare) {
            timer->SetCycleCompare(refreshCompare - c_CycleCompensation);
        }
        else {
            // at least REFRESH_INTERVAL has elapsed
            timer->SetCycleCompare(timer->GetCycleCount() + c_CycleCompensation * 2);
        }
        
        timer->setEndOfCycle();
    }
    
    interrupts();
}
Example #3
0
/**
 * @par Function
 *   read_bit
 * @par Description
 *   Read a bit. Port and bit is used to cut lookup time and provide
 *   more certain timing
 * @par Output
 *   None 
 * return
 *   return the bit value we read
 * @par Others
 *   None
 */
uint8_t LOOL_OneWire::read_bit(void)
{
  MeIO_REG_TYPE mask = bitmask;
  volatile MeIO_REG_TYPE *reg MeIO_REG_ASM = baseReg;
  uint8_t r;

  noInterrupts();
  MeDIRECT_MODE_OUTPUT(reg, mask);
  MeDIRECT_WRITE_LOW(reg, mask);
  delayMicroseconds(3);
  MeDIRECT_MODE_INPUT(reg, mask); /* let pin float, pull up will raise */
  delayMicroseconds(10);
  r = MeDIRECT_READ(reg, mask);
  interrupts();
  delayMicroseconds(53);
  return(r);
}
Example #4
0
void Timeout::configure(short delay_ms, void (*callback)(), bool every_arg){
    short ms = (delay_ms<8000 && delay_ms > 1)? delay_ms : 100;
    every_flag = every_arg;
    prescaler = 1024;
    timeoutCallback = callback;
    noInterrupts();
      // Clear registers to avoid bugs
      TCCR1A = 0;
      TCCR1B = 0;
      TCNT1  = 0;

      SET(TCCR1B, WGM12); // CTC mode
      SET(TIMSK1, OCIE1A); // allow interrupt on compare

      OCR1A = int(ms*F_CPU/prescaler/1000);
    interrupts();
}
void rc_read_values() {
  noInterrupts();
  memcpy(rc_values, (const void *)rc_shared, sizeof(rc_shared));
  interrupts();

  if (millis() - last_update_time > RC_TIMEOUT) {
    // If we don't get an input for RC_TIMEOUT, set all vals to 0
    fc_disarm();
    for (int i = 0; i < NUM_CHANNELS; i++) {
      rc_out_values[i] = 0;
    }
  } else {
    for (int i = 0; i < NUM_CHANNELS; i++) {
      process_channel_value(i);
    }
  }
}
void Adafruit_NeoPixel::show(void) {

//  if(!pixels) return; // corbin, constructor should always allocate, unless _numberOfBytes was 0..

  // Data latch = 50+ microsecond pause in the output stream.  Rather than
  // put a delay at the end of the function, the ending time is noted and
  // the function will simply hold off (if needed) on issuing the
  // subsequent round of data until the latch time has elapsed.  This
  // allows the mainline code to start generating the next frame of data
  // rather than stalling for the latch.
  while((micros() - endTime) < 50L);
  // endTime is a private member (rather than global var) so that mutliple
  // instances on different pins can be quickly issued in succession (each
  // instance doesn't delay the next).

  // In order to make this code runtime-configurable to work with any pin,
  // SBI/CBI instructions are eschewed in favor of full PORT writes via the
  // OUT or ST instructions.  It relies on two facts: that peripheral
  // functions (such as PWM) take precedence on output pins, so our PORT-
  // wide writes won't interfere, and that interrupts are globally disabled
  // while data is being issued to the LEDs, so no other code will be
  // accessing the PORT.  The code takes an initial 'snapshot' of the PORT
  // state, computes 'pin high' and 'pin low' values, and writes these back
  // to the PORT register as needed.

//    uint32_t start = micros();

    noInterrupts(); // Need 100% focus on instruction timing

    // from micros()
//	uint32_t count, current, istatus;
//    current = SYST_CVR;
//	count = systick_millis_count;
//	istatus = SCB_ICSR;	// bit 26 indicates if systick exception pending
//
//    if ((istatus & SCB_ICSR_PENDSTSET) && current > 50) count++;
//	current = ((F_CPU / 1000) - 1) - current;
//	uint32_t microsPassed = current / (F_CPU / 1000000);
//
//    static int microsLeftOver = 0;
//    
//    long microsTaken;
//    int32_t increase;

#ifdef __AVR__
..snipped
Example #7
0
void button_update(void)
{
  bool irq = false;
  irq |= esc.update();
  irq |= prev.update();
  irq |= ok.update();
  irq |= next.update();

  if (irq)
  {
    // Assert the interrupt signal. Requires critical section.
    noInterrupts();
    button_read_all();
    digitalWrite(IRQ, HIGH);
    interrupts();
  }
}
Example #8
0
// ***************************************************************
uint8_t osLoopClass::popLoop() {
   // move the head forward
   // if the head is at the end, mark the tail at the end, too
   // mark the task as not in the queue  
   uint8_t my_id=eOsNoAction;
   noInterrupts(); //atomic
   if( eOsNoAction != qHead_id) {
      my_id = qHead_id;
      qHead_id = loopQue[qHead_id].qNext_id;
      if( qHead_id == eOsNoAction ) {
        qTail_id = eOsNoAction;
      }
      loopQue[my_id].qNext_id = eOsNoAction;
   } 
   interrupts();
   return eOsNoAction;
}//popLoop
Example #9
0
bool scheduleSend(RNInfo &info,
                  comm_time_t when,
                  uint8_t size, char * buffer) {
    if (waitingToSend) {
        info.println("Can't send, another send is pending");
        return false;
    }
    noInterrupts();
    sendAt = when;
    sentAt = 0;
    waitingToSend = true;
    sendBufferSize = size;
    sendBuffer = buffer;
    interrupts();
    
    return true;
}
Example #10
0
/**
	\param pArg is a pointer to the timeElement that needs inserted into the list.
	\return the smallest index of timeElements having larger timeouts than pArg.
*/
uint8_t Timer::Search (const p_timeElement pArg)
{
	if (0 == _timeOutList.GetCount ())
		return 0;

	uint8_t i, __sreg = SREG;	// Prevent _presentTime changing.
	noInterrupts ();

	for (i=0; i<_timeOutList.GetCount (); i++)
		if (normalizeTimeOut (pArg->getTimeOut ()) < normalizeTimeOut (GET_TIMEOUT (i)))
			break;

	SREG = __sreg;			// Restore the processor's status register and interrupt mask.

	// Return the index of the first List element needing moved.
	return (i);
}
Example #11
0
void stopMozzi(){
#if IS_TEENSY3()
	timer1.end();
#elif IS_STM32()
        audio_update_timer.pause();
        control_timer.pause();
#else

    noInterrupts();
	
	// restore backed up register values
	TCCR0A = pre_mozzi_TCCR0A;
	TCCR0B = pre_mozzi_TCCR0B;
	OCR0A = pre_mozzi_OCR0A;


	TCCR1A = pre_mozzi_TCCR1A;
	TCCR1B = pre_mozzi_TCCR1B;
	OCR1A = pre_mozzi_OCR1A;

	TIMSK0 = pre_mozzi_TIMSK0;
	TIMSK1 = pre_mozzi_TIMSK1;

#if (AUDIO_MODE == HIFI)
#if defined(TCCR2A)
	TCCR2A = pre_mozzi_TCCR2A;
	TCCR2B = pre_mozzi_TCCR2B;
	OCR2A = pre_mozzi_OCR2A;
	TIMSK2 = pre_mozzi_TIMSK2;
#elif defined(TCCR2)
	TCCR2 = pre_mozzi_TCCR2;
	OCR2 = pre_mozzi_OCR2;
	TIMSK = pre_mozzi_TIMSK;
#elif defined(TCCR4A)
	TCCR4B = pre_mozzi_TCCR4A;
	TCCR4B = pre_mozzi_TCCR4B;
	TCCR4B = pre_mozzi_TCCR4C;
	TCCR4B = pre_mozzi_TCCR4D;
	TCCR4B = pre_mozzi_TCCR4E;
	OCR4C = pre_mozzi_OCR4C;
	TIMSK4 = pre_mozzi_TIMSK4;
#endif
#endif	
#endif	
	interrupts();
}
void timer4_init() {
	pinMode(LASER_INTENSITY_PIN, OUTPUT);
    analogWrite(LASER_INTENSITY_PIN, 1);  // let Arduino setup do it's thing to the PWM pin

    TCCR4B = 0x00;  // stop Timer4 clock for register updates
    TCCR4A = 0x82; // Clear OC4A on match, fast PWM mode, lower WGM4x=14
    ICR4 = labs(F_CPU / LASER_PWM); // clock cycles per PWM pulse
    OCR4A = labs(F_CPU / LASER_PWM) - 1; // ICR4 - 1 force immediate compare on next tick
    TCCR4B = 0x18 | 0x01; // upper WGM4x = 14, clock sel = prescaler, start running

    noInterrupts();
    TCCR4B &= 0xf8; // stop timer, OC4A may be active now
    TCNT4 = labs(F_CPU / LASER_PWM); // force immediate compare on next tick
    ICR4 = labs(F_CPU / LASER_PWM); // set new PWM period
    TCCR4B |= 0x01; // start the timer with proper prescaler value
    interrupts();
}
int MultiReadCircBuffer::peek(uint8_t* dest, int destLen, uint8_t reader)
{
  boolean intEn = interruptsEnabled();
  if (useInterrupts)
    noInterrupts();
  uint8_t* rptr = readPtrs[reader];
  int size = sizes[reader];
  int r = read(dest, destLen, reader);

  // Restore read values
  readPtrs[reader] = rptr;
  sizes[reader] = size;
  
  if (intEn)
    interrupts();
  return r;
}
Example #14
0
void EEPROMClass::begin(size_t size) {
  if (size <= 0)
    return;
  if (size > SPI_FLASH_SEC_SIZE)
    size = SPI_FLASH_SEC_SIZE;

  if (_data) {
    delete[] _data;
  }

  _data = new uint8_t[size];
  _size = size;

  noInterrupts();
  spi_flash_read(_sector * SPI_FLASH_SEC_SIZE, reinterpret_cast<uint32_t*>(_data), _size);
  interrupts();
}
/**
 * This method checks for RX messages that have come into the lower-level buffer
 * and populates the appropriate RX message ID's accordingly (via add message method).
 *   
 */
void cAcquireCAN::RXmsg()
{
	UINT8 i;
	bool validFrame = false;

	//temporary frame we'll use to figure out which CAN ID has been received and where to move data to
	RX_CAN_FRAME newFrame;

	//based upon the lower-level CAN library the get_rx_buff method appears to be critical 
	noInterrupts();

	//pull all data frames out of the buffer 
	while (C->read(newFrame))
	{
		//scan through message list and read the corresponding header ID
		for (i=0; i < msgCntRx; i++)
		{
			//look for a valid entry for the CAN ID we just received        
			if (rxMsgs[i]->ID == newFrame.id)
			{
                
				//fire callback to higher-level protocol (e.g. check PID parameter ID)
				validFrame = rxMsgs[i]->CallbackRx(&newFrame);                
                                
				//stuff the received  payload 
				if (validFrame)
				{
					///either NO PID OR PID's match so stuff it
					rxMsgs[i]->U.b[0] = newFrame.data.byte[0];
					rxMsgs[i]->U.b[1] = newFrame.data.byte[1];
					rxMsgs[i]->U.b[2] = newFrame.data.byte[2];
					rxMsgs[i]->U.b[3] = newFrame.data.byte[3];
					rxMsgs[i]->U.b[4] = newFrame.data.byte[4];
					rxMsgs[i]->U.b[5] = newFrame.data.byte[5];
					rxMsgs[i]->U.b[6] = newFrame.data.byte[6];
					rxMsgs[i]->U.b[7] = newFrame.data.byte[7];
					//NOTE: re-write in future versions for U32 transfers

					//increment receive counter
					RxCtr += 1;
				}
			}
		}
	}
	interrupts();
}
uint8_t atsha204Class::swi_send_bytes(uint8_t count, uint8_t *buffer)
{
    uint8_t i, bit_mask;

    // Disable interrupts while sending.
    noInterrupts();  //swi_disable_interrupts();

    // Set signal pin as output.


    *device_port_OUT |= pinBitmask;
    SET_DEVICE_PORT_TO_OUTPUT();
    //*device_port_DDR |= pinBitmask;

    // Wait turn around time.
    delayMicroseconds(RX_TX_DELAY);  //RX_TX_DELAY;

    for (i = 0; i < count; i++)
    {
        for (bit_mask = 1; bit_mask > 0; bit_mask <<= 1)
        {
            if (bit_mask & buffer[i])
            {
                *device_port_OUT &= ~pinBitmask;
                delayMicroseconds(BIT_DELAY);  //BIT_DELAY_1;
                *device_port_OUT |= pinBitmask;
                delayMicroseconds(7 * BIT_DELAY);  //BIT_DELAY_7;
            }
            else
            {
                // Send a zero bit.
                *device_port_OUT &= ~pinBitmask;
                delayMicroseconds(BIT_DELAY);  //BIT_DELAY_1;
                *device_port_OUT |= pinBitmask;
                delayMicroseconds(BIT_DELAY);  //BIT_DELAY_1;
                *device_port_OUT &= ~pinBitmask;
                delayMicroseconds(BIT_DELAY);  //BIT_DELAY_1;
                *device_port_OUT |= pinBitmask;
                delayMicroseconds(5 * BIT_DELAY);  //BIT_DELAY_5;
            }
        }
    }
    interrupts();  //swi_enable_interrupts();
    return SWI_FUNCTION_RETCODE_SUCCESS;
}
Example #17
0
void callbackIR() {
	if (status) return;

	// We do not want to be interrupted here
	noInterrupts();

	// We are working in, turn on the light!
	digitalWrite(working_led, HIGH);
	status = true;

	anOutput = aReceiver.recv();

	// Stop working, lights off..
	digitalWrite(working_led, LOW);

	// Now we want..
	interrupts();
}
Example #18
0
void Motores::lados(int intensidade, int lado, int sentido) {
  noInterrupts();
  analogWrite(m1_pwm,lado==0 ? intensidade*50 : 35*intensidade);
  if(independente==1) analogWrite(m2_pwm,lado==0 ? 35*intensidade : 50*intensidade);
  else analogWrite(m2_pwm,50*intensidade);
  digitalWrite(m1_a,sentido);
  digitalWrite(m1_b,!sentido);
  if(independente==1) {
    digitalWrite(m2_a,sentido);
    digitalWrite(m2_b,!sentido);
  }
  else {
    digitalWrite(m2_a,lado==0 ?  !sentido : sentido);
    digitalWrite(m2_b,lado==0 ?  sentido : !sentido);
  }
  interrupts();

}
Example #19
0
static void eint_callback(void* parameter, VM_DCL_EVENT event, VM_DCL_HANDLE device_handle)
{
    int i;

    for(i=0; i<EXTERNAL_NUM_INTERRUPTS; i++)
    {
        if(gExinterruptsPio[i].handle == device_handle)
        {
            if(noStopInterrupts())
            {
            	interrupts();
            	gExinterruptsPio[i].cb();
            	noInterrupts();
            }
            break;
        }
    }
}
int MultiReadCircBuffer::skip(int len, uint8_t reader)
{
  boolean intEn = interruptsEnabled();
  if (useInterrupts)
    noInterrupts();

  if (len > sizes[reader])
    len = sizes[reader];
      
  readPtrs[reader] += len;
  if (readPtrs[reader] >= getEndOfBuffer())
    readPtrs[reader] -= bufferLen;
  sizes[reader] -= len;
  
  if (intEn)
    interrupts();
  return len;
}
void Adafruit_VS1053_FilePlayer::feedBuffer(void) {
  noInterrupts();
  // dont run twice in case interrupts collided
  // This isn't a perfect lock as it may lose one feedBuffer request if
  // an interrupt occurs before feedBufferLock is reset to false. This
  // may cause a glitch in the audio but at least it will not corrupt
  // state.
  if (feedBufferLock) {
    interrupts();
    return;
  }
  feedBufferLock = true;
  interrupts();

  feedBuffer_noLock();

  feedBufferLock = false;
}
Example #22
0
bool RFM69::receiveDone() {
// ATOMIC_BLOCK(ATOMIC_FORCEON)
// {
  noInterrupts(); //re-enabled in unselect() via setMode() or via receiveBegin()
  if (_mode == RF69_MODE_RX && PAYLOADLEN>0)
  {
    setMode(RF69_MODE_STANDBY); //enables interrupts
    return true;
  }
  else if (_mode == RF69_MODE_RX)  //already in RX no payload yet
  {
    interrupts(); //explicitly re-enable interrupts
    return false;
  }
  receiveBegin();
  return false;
//}
}
Example #23
0
/*********************************************************************************************\
 * DHT sub to get an 8 bit value from the receiving bitstream
 \*********************************************************************************************/
byte read_dht_dat(void)
  {
  byte i = 0;
  byte result=0;

  noInterrupts();
  for(i=0; i< 8; i++)
    {
    while(!digitalRead(DHT_Pin));                                               // wait for 50us
    delayMicroseconds(30);
    if(digitalRead(DHT_Pin)) 
      result |=(1<<(7-i));
    while(digitalRead(DHT_Pin));                                                // wait '1' finish
    }
  interrupts();

  return result;
  }
Example #24
0
// select the transceiver
void RFM69::select() {
#ifdef SPI_HAS_TRANSACTION
  _SPCR = SPCR;
  _SPSR = SPSR;
  SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
#else
  _SREG = SREG;
  noInterrupts();
  // save current SPI settings
  _SPCR = SPCR;
  _SPSR = SPSR;
  // set RFM69 SPI settings
  SPI.setDataMode(SPI_MODE0);
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV4); // decided to slow down from DIV2 after SPI stalling in some instances, especially visible on mega1284p when RFM69 and FLASH chip both present
#endif
  digitalWrite(_slaveSelectPin, LOW);
}
Example #25
0
void ACZCPWM::setup(uint8_t _zeroCrossDetectPin, uint8_t _ssrControlPin, uint8_t _period, uint8_t _dither) {
  noInterrupts();
  zeroCrossDetectPin = _zeroCrossDetectPin;
  ssrControlPin = _ssrControlPin;
  period = _period;
  dither = _dither;
  crossCounter = 0;
  ditherCounter = 0;
  countdown = 0;
  duty=0;
  pinMode(ssrControlPin,OUTPUT);
  pinMode(zeroCrossDetectPin,INPUT);
  attachInterrupt(digitalPinToInterrupt(zeroCrossDetectPin), cross, CHANGE);
  interrupts();

  Timer1.initialize(1e6/300);
  Timer1.attachInterrupt(timeout);
}
Example #26
0
// Read one channel value
float AP_ADC_ADS7844::Ch(uint8_t ch_num)
{
	uint16_t count;
	uint32_t sum;

	// ensure we have at least one value
	while (_count[ch_num] == 0)  /* noop */ ;

	// grab the value with interrupts disabled, and clear the count
	noInterrupts();
	count = _count[ch_num];
	sum   = _sum[ch_num];
	_count[ch_num] = 0;
	_sum[ch_num]   = 0;
	interrupts();

	return ((float)sum)/count;
}
boolean Adafruit_VS1053_FilePlayer::startPlayingFile(const char *trackname) {
  // reset playback
  sciWrite(VS1053_REG_MODE, VS1053_MODE_SM_LINE1 | VS1053_MODE_SM_SDINEW);
  // resync
  sciWrite(VS1053_REG_WRAMADDR, 0x1e29);
  sciWrite(VS1053_REG_WRAM, 0);

  currentTrack = SD.open(trackname);
  if (!currentTrack) {
    return false;
  }
    
  // We know we have a valid file. Check if .mp3
  // If so, check for ID3 tag and jump it if present.
  if (isMP3File(trackname)) {
    currentTrack.seek(mp3_ID3Jumper(currentTrack));
  }

  // don't let the IRQ get triggered by accident here
  noInterrupts();

  // As explained in datasheet, set twice 0 in REG_DECODETIME to set time back to 0
  sciWrite(VS1053_REG_DECODETIME, 0x00);
  sciWrite(VS1053_REG_DECODETIME, 0x00);

  playingMusic = true;

  // wait till its ready for data
  while (! readyForData() ) {
#if defined(ESP8266)
	yield();
#endif
  }

  // fill it up!
  while (playingMusic && readyForData()) {
    feedBuffer();
  }
  
  // ok going forward, we can use the IRQ
  interrupts();

  return true;
}
Example #28
0
bool StationClass::config(String ssid, String password, bool autoConnectOnStartup /* = true*/)
{
	station_config config = {0};

	if (ssid.length() >= sizeof(config.ssid)) return false;
	if (password.length() >= sizeof(config.password)) return false;

	bool enabled = isEnabled();
	bool dhcp = isEnabledDHCP();
	enable(true); // Power on for configuration

	wifi_station_disconnect();
	if (dhcp) enableDHCP(false);
	bool cfgreaded = wifi_station_get_config(&config);
	if (!cfgreaded) debugf("Can't read station configuration!");

	memset(config.ssid, 0, sizeof(config.ssid));
	memset(config.password, 0, sizeof(config.password));
	config.bssid_set = false;
	strcpy((char*)config.ssid, ssid.c_str());
	strcpy((char*)config.password, password.c_str());

	noInterrupts();
	if(!wifi_station_set_config(&config))
	{
		interrupts();
		debugf("Can't set station configuration!");
		wifi_station_connect();
		enableDHCP(dhcp);
		enable(enabled);
		return false;
	}
	debugf("Station configuration was updated to: %s", ssid.c_str());

	interrupts();
	wifi_station_connect();
	enableDHCP(dhcp);
	enable(enabled);

	wifi_station_set_auto_connect(autoConnectOnStartup);

	return true;
}
Example #29
0
Event_t event_dequeue(void)
{
	Event_t e;
	
	// on masque les interruptions
	noInterrupts();
	
	// si la file possède au moins un élément et qu'il existe un évènement à l'emplacement du pointeur de lecture
	if (event_count-- && Queue[r_pointer] != EVENT_NULL)
	{
		// on le récupère
		e = Queue[r_pointer];

		// on suprime l'emplacement
		Queue[r_pointer++] = EVENT_NULL;

		// on met à jour le pointeur pour l'itération suivante
		r_pointer %= QUEUE_SIZE;

// analyse des évènements
#if KBS_ANALYSER

		events_processed++;

#endif
	}
	else
	{
		// si events_count == 0 ou si le pointeur est positionné sur un élément null
		e = EVENT_NULL;
		
		// on reset les pointeurs
		r_pointer = w_pointer = event_count = 0;
	}
	
	// s'il y a eu un overflow, on signal qu'une nouvelle place est disponible dans la file
	queue_overflow = false;

	// on démasque les interruptions
	interrupts();
		
	return e;
}
void setup()
{
  
  // initialize timer1 
  noInterrupts();           // disable all interrupts
  TCCR1A = 0;      // set entire TCCR1A register to 0
  TCCR1B = 0;     // same for TCCR1B
 
  // set compare match register to desired timer count:
  OCR1A = 780;
  // turn on CTC mode:
  TCCR1B |= (1 << WGM12);
  // Set CS10 and CS12 bits for 1024 prescaler:
  TCCR1B |= (1 << CS10);
  TCCR1B |= (1 << CS12);
  // enable timer compare interrupt:
  TIMSK1 |= (1 << OCIE1A);
  interrupts();             // enable all interrupts
}