text: // coding: utf-8
  // ----------------------------------------------------------------------------
   /*
    * Copyright (c) 2015, Christian Menard
    * All rights reserved.
    *
    * Redistribution and use in source and binary forms, with or without
    * modification, are permitted provided that the following conditions are met:
    *
    *     * Redistributions of source code must retain the above copyright
    *       notice, this list of conditions and the following disclaimer.
    *     * Redistributions in binary form must reproduce the above copyright
    *       notice, this list of conditions and the following disclaimer in the
    *       documentation and/or other materials provided with the distribution.
    *     * Neither the name of the copyright holder nor the names of its
    *       contributors may be used to endorse or promote products derived from
    *       this software without specific prior written permission.
    *
    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
    * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
    * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
    * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
    * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
    * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
    * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    */
  // ----------------------------------------------------------------------------
  
  #ifndef XPCC__PCA9685_HPP
  #	error "Don't include this file directly, use 'pca9685.hpp' instead!"
  #endif
  
  // ----------------------------------------------------------------------------
  template<typename I2cMaster>
  xpcc::Pca9685<I2cMaster>::Pca9685(uint8_t address) :
  	I2cDevice<I2cMaster, 1, I2cWriteTransaction>(address)
  {}
  
  template<typename I2cMaster>
  xpcc::ResumableResult<bool>
  xpcc::Pca9685<I2cMaster>::initialize(uint8_t mode1, uint8_t mode2)
  {
  	RF_BEGIN();
  
  	// set the first mode register
  	buffer[0] = REG_MODE1;
  	buffer[1] = mode1 | MODE1_AI;  // ensure that auto increment is enabled
  	this->transaction.configureWrite(buffer, 2);
  
  	if (not RF_CALL( this->runTransaction() ))
  		RF_RETURN(false);
  
  	// set the second mode register
  
  	buffer[0] = REG_MODE2;
  	buffer[1] = mode2;
  	this->transaction.configureWrite(buffer, 2);
  
  	if (not RF_CALL( this->runTransaction() ))
  		RF_RETURN(false);
  
  	// Always turn on all LEDs at tick 0 and switch them of later according
  	// to the current value
  
  	buffer[0] = REG_ALL_LED_ON_L;
  	buffer[1] = 0x00;
  	buffer[2] = 0x00;
  	this->transaction.configureWrite(buffer, 3);
  
  	RF_END_RETURN_CALL( this->runTransaction() );
  }
  
  template<typename I2cMaster>
  xpcc::ResumableResult<bool>
  xpcc::Pca9685<I2cMaster>::setChannel(uint8_t channel, uint16_t value)
  {
  	RF_BEGIN();
  
  	// there are only 16 channels
  	if (channel >= 16)
  		RF_RETURN(false);
  
  	buffer[0] = REG_LED0_OFF_L + 4 * channel;
  	// The Controller turns all LEDs on at tick 0
  	// and turns this LED of at value
  	buffer[1] = uint8_t(value);
  	buffer[2] = uint8_t(value >> 8) & 0x0f;
  	this->transaction.configureWrite(buffer, 3);
  
  	RF_END_RETURN_CALL( this->runTransaction() );
  }
  
  template<typename I2cMaster>
  xpcc::ResumableResult<bool>
  xpcc::Pca9685<I2cMaster>::setAllChannels(uint16_t value)
  {
  	RF_BEGIN();
  
  	buffer[0] = REG_ALL_LED_OFF_L;
  	// The Controller turns all LEDs on at tick 0
  	// and turns this LED of at tick $value
  	buffer[1] = uint8_t(value);
  	buffer[2] = uint8_t(value >> 8) & 0x0f;
  	this->transaction.configureWrite(buffer, 3);
  
  	RF_END_RETURN_CALL( this->runTransaction() );
  }
  