15#if DETWS_ENABLE_PCA9685
19const uint32_t PCA9685_OSC_HZ = 25000000u;
20const uint8_t PCA9685_PRESCALE_MIN = 3;
21const uint8_t PCA9685_PRESCALE_MAX = 255;
27 return PCA9685_PRESCALE_MAX;
28 uint32_t denom = 4096u * freq_hz;
29 uint32_t pre = (PCA9685_OSC_HZ + denom / 2) / denom;
30 pre = pre ? pre - 1 : 0;
31 if (pre < PCA9685_PRESCALE_MIN)
32 pre = PCA9685_PRESCALE_MIN;
33 if (pre > PCA9685_PRESCALE_MAX)
34 pre = PCA9685_PRESCALE_MAX;
48 uint64_t num = (uint64_t)microseconds * 4096u * freq_hz;
49 uint32_t count = (uint32_t)((num + 500000u) / 1000000u);
59 buf[1] = (uint8_t)(on & 0xFF);
60 buf[2] = (uint8_t)((on >> 8) & 0x1F);
61 buf[3] = (uint8_t)(off & 0xFF);
62 buf[4] = (uint8_t)((off >> 8) & 0x1F);
87bool wr(uint8_t reg, uint8_t val)
89 Wire.beginTransmission(s_pca.addr);
92 return Wire.endTransmission() == 0;
105 delayMicroseconds(500);
116 Wire.beginTransmission(s_pca.addr);
118 return Wire.endTransmission() == 0;
User-facing configuration for DeterministicESPAsyncWebServer.
#define DETWS_PCA9685_FREQ
Default PWM output frequency in Hz (50 Hz suits hobby servos).
#define DETWS_PCA9685_I2C_ADDR
I2C address of the PCA9685 (0x40 default; the six address pins select 0x40..0x7F).
The one owner of the shared I2C bus bring-up for the peripheral drivers.
void detws_i2c_begin()
Bring up the shared I2C bus on DETWS_I2C_SDA_PIN / DETWS_I2C_SCL_PIN (-1 = default).
NXP PCA9685 16-channel 12-bit PWM / servo driver codec (DETWS_ENABLE_PCA9685).
bool pca9685_begin(uint8_t addr, uint32_t freq_hz)
Reset the PCA9685 at addr and set the PWM frequency freq_hz.
#define PCA9685_CHANNELS
PWM output channels.
uint16_t pca9685_us_to_count(uint32_t microseconds, uint32_t freq_hz)
Convert a servo pulse width (microseconds) at freq_hz to a 12-bit OFF count (rounded),...
uint8_t pca9685_prescale(uint32_t freq_hz)
Compute the PRESCALE register value for a PWM output frequency (25 MHz oscillator): round(25e6 / (409...
#define PCA9685_REG_MODE2
bool pca9685_set_servo_us(uint8_t channel, uint32_t microseconds)
Drive a servo on channel to a microseconds pulse (uses the configured frequency).
#define PCA9685_REG_MODE1
bool pca9685_set_pwm(uint8_t channel, uint16_t on, uint16_t off)
Set channel's raw 12-bit ON / OFF counts.
uint8_t pca9685_channel_reg(uint8_t channel)
The register base (LED_ON_L) for channel (0..15); 0 for an out-of-range channel.
size_t pca9685_set_pwm_bytes(uint8_t *buf, size_t cap, uint8_t channel, uint16_t on, uint16_t off)
Emit the 5-byte channel PWM write: [LED_ON_L(channel), ON_L, ON_H, OFF_L, OFF_H] (each count 12-bit l...
#define PCA9685_COUNT_MAX
a PWM count is 12-bit (0..4095)
#define PCA9685_REG_LED0_ON_L
channel 0 base; channel n is this + 4*n
#define PCA9685_REG_PRESCALE