74 void init(
const char * name, uint8_t i2c_address,
75 uint16_t pwm_freq = 200, int32_t external_clock_freq = -1)
77 uint32_t clock_freq = external_clock_freq >= 0 ? external_clock_freq :
81 i2c_ = ::open(name, O_RDWR);
85 HASSERT(clock_freq <= 50000000);
86 HASSERT(pwm_freq < (clock_freq / (4096 * 4)));
94 uint8_t prescaler = (clock_freq / (4096 * (uint32_t)pwm_freq)) - 1;
97 if (external_clock_freq < 0)
109 start(name, configMAX_PRIORITIES - 1, 1024);
211 void *
entry()
override;
220 uint8_t addr = address;
222 struct i2c_msg msgs[] =
238 struct i2c_rdwr_ioctl_data ioctl_data =
239 {.msgs = msgs, .nmsgs =
ARRAYSIZE(msgs)};
244 rd_data |= (data & mask);
255 duty_[channel] = counts;
257 portENTER_CRITICAL();
270 return duty_[channel];
284 else if (counts == 0)
294 ctl.
off.
counts = (counts + (channel * 256)) % 0x1000;
309 uint8_t payload[] = {address, data};
310 ::write(
i2c_, payload,
sizeof(payload));
319 uint8_t payload[count + 1];
320 payload[0] = address;
321 memcpy(payload + 1, data, count);
322 ::write(
i2c_, payload,
sizeof(payload));
335 std::array<uint16_t, NUM_CHANNELS>
duty_;
int ioctl(int fd, unsigned long int key,...)
Request and ioctl transaction.
This class provides a counting semaphore API.
void post()
Post (increment) a semaphore.
This class provides a threading API.
void start(const char *name, int priority, size_t stack_size)
Starts the thread.
Specialization of the PWM abstract interface for the PCA9685.
void set_period(uint32_t counts) override
Set PWM period.
PCA9685PWMBit(PCA9685PWM *instance, unsigned index)
Constructor.
PCA9685PWM * instance_
instance pointer to the whole chip complement
~PCA9685PWMBit()
Destructor.
unsigned index_
bit index within PCA9685
uint32_t get_period_max() override
Get max period supported.
uint32_t get_duty() override
Gets the duty cycle.
uint32_t get_period_min() override
Get min period supported.
uint32_t get_period() override
Get PWM period.
void set_duty(uint32_t counts) override
Sets the duty cycle.
Agragate of 16 PWM channels for a PCA9685PWM.
void register_write(Registers address, uint8_t data)
Write to an I2C register.
void set_pwm_duty(unsigned channel, uint16_t counts)
Set the pwm duty cycle.
static constexpr size_t MAX_PWM_COUNTS
maximum number of PWM counts supported by the PCA9685
friend PCA9685PWMBit
Allow access to private members.
static constexpr size_t NUM_CHANNELS
maximum number of PWM channels supported by the PCA9685
void bit_modify(Registers address, uint8_t data, uint8_t mask)
Bit modify to an I2C register.
OSSem sem_
Wakeup for the thread processing.
void write_pwm_duty(unsigned channel, uint16_t counts)
Set the pwm duty cycle.
Registers
Important device register offsets.
@ PRE_SCALE
clock prescale divider
@ LED0_ON_L
first LED control register
std::array< uint16_t, NUM_CHANNELS > duty_
local cache of the duty cycles
uint16_t get_pwm_duty(unsigned channel)
Get the pwm duty cycle.
int i2c_
I2C file descriptor.
uint8_t i2cAddress_
I2C address of the device.
uint16_t dirty_
set if the duty_ value is updated (bit mask)
void * entry() override
User entry point for the created thread.
void init(const char *name, uint8_t i2c_address, uint16_t pwm_freq=200, int32_t external_clock_freq=-1)
Initialize device.
void register_write_multiple(Registers address, void *data, size_t count)
Write to multiple sequential I2C registers.
Abstract interface for a PWM driver.
#define ARRAYSIZE(a)
Returns the number of elements in a statically defined array (of static size)
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Removes default copy-constructor and assignment added by C++.
Representation of the replicative 4 LED control register.
On on
on registers instance
Off off
off registers instance
uint16_t word
full word data
uint16_t counts
turn off counts
uint16_t fullOff
set if full off
uint16_t counts
turn on counts
uint16_t fullOn
set if full on
uint16_t word
full word data
Represent the mode 1 register.
uint8_t extClk
external clock
uint8_t byte
full byte value
uint8_t sleep
sleep enabled
uint8_t allCall
respond to "all call" address
uint8_t sub1
sub-address 1
uint8_t sub3
sub-address 3
uint8_t sub2
sub-address 2
Represent the mode 2 register.
uint8_t och
1 = updata on ack, 0 = update on stop
uint8_t invert
invert output
uint8_t byte
full byte data
uint8_t outDrv
1 = push/pull, 0 = open drain
uint8_t outNE
output not enable