diff options
Diffstat (limited to 'firmware/drivers/wm8523.h')
-rw-r--r-- | firmware/drivers/wm8523.h | 349 |
1 files changed, 345 insertions, 4 deletions
diff --git a/firmware/drivers/wm8523.h b/firmware/drivers/wm8523.h index e1bb8bc..aeffe7b 100644 --- a/firmware/drivers/wm8523.h +++ b/firmware/drivers/wm8523.h @@ -29,9 +29,350 @@ #include <stdint.h> -void WM8523_init(); -void WM8523_configure(); -uint16_t WM8523_read(uint8_t reg); -void WM8523_write(uint8_t reg, uint16_t data); + +typedef enum { + WM8523_FS_8K, + WM8523_FS_32K, + WM8523_FS_44K1, + WM8523_FS_48K, + WM8523_FS_88K2, + WM8523_FS_96K, + WM8523_FS_176K4, + WM8523_FS_192K, +} wm8523_samplerate_t; +/** + * Prepare I2S, SSP and GPIO. + */ +void wm8523_init(uint8_t portnum, wm8523_samplerate_t fs); + +/** + * Read chip ID. + * Is always 0x8523 + * Register: R0 [0:15] (read) + * Default: 1000 0101 0010 0011 + */ +#define WM8532_CHIP_ID 0b1000010100100011 +unsigned short wm8523_get_chip_id(uint8_t portnum); + +/** + * Reset all register values to their defaults. + * Register: R0 [0:15] (write) + */ +void wm8523_reset_registers(uint8_t portnum); + +/** + * Read hardware revision counter. + * Register: R1 [0:2] (read) + */ +uint8_t wm8523_get_hardware_revision(uint8_t portnum); + +typedef enum __attribute__ ((packed)) { + WM8523_PWR_OFF = 0b00, + WM8523_PWR_POWER_DOWN = 0b01, + WM8523_PWR_POWER_UP_TO_MUTE = 0b10, + WM8523_PWR_POWER_UP_TO_UNMUTE = 0b11, +} wm8523_power_mode_t; + +/** + * Get current power mode. + * Register: R2 [0:1] (read) + */ +wm8523_power_mode_t wm8523_get_power_mode(uint8_t portnum); + +/** + * Set power mode. + * Register: R2 [0:1] (write) + */ +void wm8523_set_power_mode(uint8_t portnum, wm8523_power_mode_t mode); + +/* +R3 [0:1] +Audio Data Interface Format +00 = Right justified +01 = Left justified +10 = I2S format +11 = DSP mode +*/ +typedef enum __attribute__ ((packed)) { + WM8523_FMT_RIGHT = 0b00, // Right justified + WM8523_FMT_LEFT = 0b01, // Left justified + WM8523_FMT_I2S = 0b10, // I2S format + WM8523_FMT_DSP = 0b11, // DSP mode +} wm8523_audio_data_interface_format_t; + +/* +R3 [3:4] +Audio Data Word Length +00 = 16 bits +01 = 20 bits +10 = 24 bits +11 = 32 bits +*/ +typedef enum __attribute__ ((packed)) { + WM8523_WLEN_16 = 0b00, // 16 bit word length + WM8523_WLEN_20 = 0b01, // 20 bit word length + WM8523_WLEN_24 = 0b10, // 24 bit word length + WM8523_WLEN_32 = 0b11, // 32 bit word length +} wm8523_audio_data_word_length_t; + +/* +R3 [5] +BCLK Inversion Control +Slave mode: +0 = Use rising edge +1 = Use falling edge +Master mode: +0 = BCLK normal +1 = BCLK inverted +*/ +typedef enum __attribute__ ((packed)) { + // Slave mode: + WM8523_INVCTL_SLAVE_RISING = 0b0, // Use rising edge + WM8523_INVCTL_SLAVE_FALLING = 0b1, // Use falling edge + + // Master mode: + WM8523_INVCTL_MASTER_NORMAL = 0b0, // BCLK normal + WM8523_INVCTL_MASTER_INVERTED = 0b1, // BCLK inverted +} wm8523_bclk_inversion_control_t; + +/* +R3 [6] +LRCLK Inversion Control +0 = Normal polarity +1 = Inverted polarity +When AIF_FMT[2:0]=011 (DSP Mode): +0 = Mode A (2nd clock) +1 = Mode B (1st clock) +*/ +typedef enum __attribute__ ((packed)) { + // Slave mode: + WM8523_LRCLKINVCTL_SLAVE_NORMAL = 0b0, // Normal polarity + WM8523_LRCLKINVCTL_SLAVE_INVERTED = 0b1, // Inverted polarity + + // Master mode: + WM8523_LRCLKINVCTL_MASTER_MODE_A = 0b0, // Mode A (2nd clock) + WM8523_LRCLKINVCTL_MASTER_MODE_B = 0b1, // Mode B (1st clock) +} wm8523_lrclk_inversion_control_t; + +/* +R3 [7] +Master/Slave Select +0 = Slave mode +1 = Master mode +*/ +typedef enum __attribute__ ((packed)) { + WM8523_MODESEL_SLAVE = 0b0, // Slave mode + WM8523_MODESEL_MASTER = 0b1, // Master mode +} wm8523_slave_master_mode_sel_t; + +/* +R3 [8] +DAC De-emphasis Control +0 = No de-emphasis +1 = De-emphasis enabled +*/ +typedef enum __attribute__ ((packed)) { + WM8523_DEEMPH_DISABLED = 0b0, // No de-emphasis + WM8523_DEEMPH_ENABLED = 0b1, // De-emphasis enabled +} wm8523_dac_deemphasis_control_t; + +typedef struct __attribute__ ((packed)) { + wm8523_audio_data_interface_format_t fmt:2; + int reserved:1; + wm8523_audio_data_word_length_t wlen:2; + wm8523_bclk_inversion_control_t invctl:1; + wm8523_lrclk_inversion_control_t lrclkinvctl:1; + wm8523_slave_master_mode_sel_t modesel:1; + wm8523_dac_deemphasis_control_t deemp:1; + uint16_t blank:7; +} wm8523_aif_ctrl1_t; + +void wm8523_set_aif_ctrl1(uint8_t portnum, wm8523_aif_ctrl1_t aif_ctrl1); +wm8523_aif_ctrl1_t wm8523_get_aif_ctrl1(uint8_t portnum); + +/* +R4 [0:2] +MCLK:LRCLK Ratio +000 = Auto detect +001 = 128fs +010 = 192fs +011 = 256fs +100 = 384fs +101 = 512fs +110 = 768fs +111 = 1152fs +*/ +typedef enum __attribute__ ((packed)) { + WM8523_CLKRATIO_AUTO = 0b000, // Auto detect + WM8523_CLKRATIO_128_FS = 0b001, // 128fs + WM8523_CLKRATIO_192_FS = 0b010, // 192fs + WM8523_CLKRATIO_256_FS = 0b011, // 256fs + WM8523_CLKRATIO_384_FS = 0b100, // 384fs + WM8523_CLKRATIO_512_FS = 0b101, // 512fs + WM8523_CLKRATIO_768_FS = 0b110, // 768fs + WM8523_CLKRATIO_1152_FS = 0b111, // 1152fs +} wm8523_mclk_lrclk_ratio_t; + +/* +R4 [3:5] +BCLK Divider Control (Master Mode) +000 = MCLK/4 +001 = MCLK/8 +010 = 32fs +011 = 64fs +100 = 128fs +101 - 111 reserved +*/ +typedef enum __attribute__ ((packed)) { + WM8523_CLKDIV_MCLK_4 = 0b000, // MCLK/4 + WM8523_CLKDIV_MCLK_8 = 0b001, // MCLK/8 + WM8523_CLKDIV_32_FS = 0b010, // 32fs + WM8523_CLKDIV_64_FS = 0b011, // 64fs + WM8523_CLKDIV_128_FS = 0b100, // 128fs +} wm8523_bclk_divider_control_t; + +/* +R4 [6:7] +Digital Monomix Control +00 = Stereo (normal operation) +01 = Mono (Left data to DACR) +10 = Mono (Right data to DACL) +11 = Digital monomix, (L+R)/2 +*/ +typedef enum __attribute__ ((packed)) { + WM8523_MIX_STEREO = 0b00, // Stereo (normal operation) + WM8523_MIX_MONO_LEFT = 0b01, // Mono (Left data to DACR) + WM8523_MIX_MONO_RIGHT = 0b10, // Mono (Right data to DACL) + WM8523_MIX_MONO_MIXED = 0b11, // Digital monomix, (L+R)/2 +} wm8523_digital_monomix_control_t; + +typedef struct __attribute__ ((packed)) { + wm8523_mclk_lrclk_ratio_t clkratio:3; + wm8523_bclk_divider_control_t clkdiv:3; + wm8523_digital_monomix_control_t mix:2; +} wm8523_aif_ctrl2_t; + +void wm8523_set_aif_ctrl2(uint8_t portnum, wm8523_aif_ctrl2_t aif_ctrl2); +wm8523_aif_ctrl2_t wm8523_get_aif_ctrl2(uint8_t portnum); + +/* +R5 [0] +DAC Digital Volume Decrease Control +0 = Apply volume decreases instantly (step) +1 = Ramp volume decreases +*/ +typedef enum __attribute__ ((packed)) { + WM8523_VOL_DOWN_RAMP = 0b00, // Apply volume decreases instantly (step) + WM8523_VOL_DOWN_INSTANT = 0b01, // Ramp volume decreases +} wm8523_dac_vol_down_ramp_t; + +/* +R5 [1] +DAC Digital Volume Increase Control +0 = Apply volume increases instantly (step) +1 = Ramp volume increases +*/ +typedef enum __attribute__ ((packed)) { + WM8523_VOL_UP_RAMP = 0b00, // Apply volume increases instantly (step) + WM8523_VOL_UP_INSTANT = 0b01, // Ramp volume increases +} wm8523_dac_vol_up_ramp_t; + +/* +R5 [2] +Left DAC Mute +0 = Normal operation +1 = Mute +*/ +typedef enum __attribute__ ((packed)) { + WM8523_DACL_UNMUTE = 0b00, // Normal operation + WM8523_DACL_MUTE = 0b01, // Mute +} wm8523_dacl_mute_t; + +/* +R5 [3] +Right DAC Mute +0 = Normal operation +1 = Mute +*/ +typedef enum __attribute__ ((packed)) { + WM8523_DACR_UNMUTE = 0b00, // Normal operation + WM8523_DACR_MUTE = 0b01, // Mute +} wm8523_dacr_mute_t; + +/* +R5 [4] +Zero Cross Enable +0 = Do not use zero cross +1 = Use zero cross +*/ +typedef enum __attribute__ ((packed)) { + WM8523_ZERO_CROSSING_DISABLED = 0b00, // Do not use zero cross + WM8523_ZERO_CROSSING_ENABLED = 0b01, // Use zero cross +} wm8523_dac_zc_t; + +typedef struct __attribute__ ((packed)) { + wm8523_dac_vol_down_ramp_t downramp:1; + wm8523_dac_vol_up_ramp_t upramp:1; + wm8523_dacl_mute_t lmute:1; + wm8523_dacr_mute_t rmute:1; + wm8523_dac_zc_t dac_zc:1; +} wm8523_dac_ctrl3_t; + +void wm8523_set_dac_ctrl3(uint8_t portnum, wm8523_dac_ctrl3_t dac_ctrl3); +wm8523_dac_ctrl3_t wm8523_get_dac_ctrl3(uint8_t portnum); + +/* +R6 [0:8] +Left DAC Digital Volume Control +0 0000 0000 = -100dB +0 0000 0001 = -99.75dB +0 0000 0010 = -99.5dB +...0.25dB steps +1 1001 0000 = 0dB +...0.25dB steps +1 1011 1110 = +11.75dB +1 11XX XXXX = +12dB +*/ + +/* +R6 [9] +Left DAC Digital Volume Update +0 = Latch Left DAC volume setting into register map but do not update volume +1 = Latch Left DAC volume setting into register map and update left and right channels simultaneously +*/ + +/* +R7 [0:8] +Right DAC Digital Volume Control +0 0000 0000 = -100dB +0 0000 0001 = -99.75dB +0 0000 0010 = -99.5dB +...0.25dB steps +1 1001 0000 = 0dB +...0.25dB steps +1 1011 1110 = +11.75dB +1 11XX XXXX = +12dB +*/ + +/* +R7 [9] +Right DAC Digital Volume Update +0 = Latch Right DAC volume setting into register map but do not update volume +1 = Latch Right DAC volume setting into register map and update left and right channels simultaneously +*/ + +/* +R8 [0] +Zero Detect Count Control +0 = 1024 +1 = 2048 +*/ + + +void wm8523_tone(); + +//void wm8523_configure(); +//uint16_t wm8523_read(uint8_t reg); +//void wm8523_write(uint8_t reg, uint16_t data); #endif/*__PEDAL2METAL_WM8523_H__*/ |