ATtiny1604 Single Slope PWM Frequency using TCA0

I have a a single slope PWM signal suitable for driving a servo.
I can get output on WO2 (PB2) but the frequency is a bit off.
The data sheet defines the frequency as:

Fpwm = Fclk_per/(Scalar * (PER +1))

With a tuned (I had to tune the device using MegaTinyTuner [MegaTinyTuner](megaTinyCore/megaavr/extras/Ref_Tuning.md at master · SpenceKonde/megaTinyCore · GitHub to get serial debug to work at the correct baud - I was using my scope’s 1KHz reference output for the timing source) 20MHz device, a per-scaler of 8 and 50Hz as my PWM frequency.

Rearrange this and you get:

((20000000 / (50 * 8)) -1 = 49999

However using my scope this generated a frequency of 49Hz

I had to use a PER value of 48900 to get a measured frequency of 50Hz

Are you able to explain what I got wrong?

Please see the code snippet that sets the PWM signal going…

void PWM_0_TCA0_init(){
  takeOverTCA0();         			                                                // millis() is using TCB0
  PORTMUX_CTRLC |= PORTMUX_TCA02_DEFAULT_gc; 	                                  // Use default pin (the alt pin is physically unavailable)
  // from the data sheet the single slope PWM signal frequency is defined as below:
  // Fpwm = Fclk_per/(Scalar 8 (PER +1))
  // PER = (Fclk_per/(Fpwm * Scalar)) - 1
  // ((20000000 / (50 * 8)) -1 = 49999
  // TCA0_SINGLE_PER = 49999;                                                      // sets 49Hz signal
  TCA0_SINGLE_PER = 48900;                                                      // sets 50Hz signal
  TCA0_SINGLE_CTRLA = TCA_SINGLE_CLKSEL_DIV8_gc;                                //Select division factor (1,2,4,8,16,64,256,1024) but not enabled
  
  TCA0_SINGLE_CTRLA |= TCA_SINGLE_ENABLE_bm;  		                            // Enable when servo is started
  
  TCA0_SINGLE_INTCTRL = TCA_SINGLE_OVF_bm;                                      // Overflow Interrupt Enable: enabled - I want to count PWM pulses
  TCA0_SINGLE_CTRLB = TCA_SINGLE_WGMODE_SINGLESLOPE_gc;                         // select waveform generation mode - fast PWM for servo control on WO2
  
  TCA0_SINGLE_CTRLB |=  TCA_SINGLE_CMP2EN_bm;                                // enable output on WO2 when servo is started
  TCA0_SINGLE_CMP2BUF = TCA0_CMP_Lock;                                        // signal to drive the servo into lock position
}

And for good measure, my platformio.ini

        ; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:ATtiny1604]
platform = atmelmegaavr
board = ATtiny1604
framework = arduino

build_unflags = -DMILLIS_USE_TIMERA0    ; stop megaTinyCore using TCA0
build_flags = -DMILLIS_USE_TIMERB0      ; have it use TIMERB0 

board_build.f_cpu = 20000000L


; upload_speed = 115200
upload_speed = 230400               ; seems to work for me
upload_port = /dev/ttyUSB0

monitor_port = /dev/ttyUSB1
monitor_speed = 115200
monitor_filters = send_on_enter     ; to mimic Arduino serial monitor
monitor_echo = true                 ; so I may see commands typed in
    
upload_flags =
    --tool
    uart
    --device
    ATtiny1604
    --uart
    $UPLOAD_PORT
    --clk
    $UPLOAD_SPEED
upload_command = pymcuprog write --erase $UPLOAD_FLAGS --filename $SOURCE