;
; Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
;
; SPDX-License-Identifier: BSD-3-Clause
;

; =====================================================
; this is the original pio program which ran at ~ 22058 Hz on the 48MHz FPGA.
; it had an effective resolution of 11 bit. (7+log2(16))

;	.program pwm_one_bit_dither
;	.side_set 1 opt
;	; Format:
;	; | high len | low len | (dither) * n |
;	; OSR level
;	; cycle length = 9 + 127
;	
;	; 136 clocks/cycle frequency 352941 / 16 = 22058
;	delay:
;	  nop [2]
;	.wrap_target
;	  out pins, 1
;	loops:
;	  mov x, isr        side 1
;	loop1:
;	  jmp x-- loop1
;	  mov x, y          side 0
;	loop0:
;	  jmp x-- loop0
;	  jmp !osre delay
;	public entry_point:
;	  pull
;	  out isr, 7
;	  out y, 7
;	.wrap


; =====================================================
; Modified program to run on the RP2040 which runs at a higher clock speed.
; It has an effective resolution of 12 bit. (8+log2(16))
;
; The sample is not emitted as one single pulse rather that 16 pulses.
; This results in a much higher, easier to filter frequency for the extremely load pwm noise.
;
; The basic resolution of each pulse is 8 bit. 
; 4 more bits are added by adding 1 clock cycle to 0 to 15 of these pulses.
;
; The sample rate depends on the system clock:
; To avoid audible artifacts, only an integer clock divider can be used, no fractional part.
; To avoid audible artifacts, all pwm pulse periods must be the same length.
; => we always use a pio clock divider of 1.00.
; => sample frequency = (255+9)*16 = 4224 clocks per sample 
;
; 100 MHz / 4224  = 23674 Hz
; 125 MHz / 4224  = 29593 Hz
; 44100 Hz * 4224 = 186.28 MHz
; 48000 Hz * 4224 = 202.75 MHz
; 290 MHz / 4224  = 68655 Hz   

; Data Format:
; | dither[16] | low_len[8] | high_len[8] |
; 
; requirement: high_len + low_len = 255 
; => cycle length = 9 + 255 = 264 clocks/cycle
; =>  264 * 16 = 4224 clocks per sample 

.program pwm_audio
.side_set 1 opt
delay:
	nop [2]
.wrap_target
	out  pins, 1			; dither bit
	mov  x, isr     side 1	; TODO: isn't this 1 cc early?!?
l1:	jmp  x-- l1
	mov  x, y		side 0
l0:	jmp  x-- l0
	jmp  !osre delay
public entry_point:
	pull
	out  isr, 8				; high length
	out  y, 8				; low length
.wrap




















