From 2f60747dd3b51321903de9c51789765d41ed83e4 Mon Sep 17 00:00:00 2001 From: ozpv <39195175+ozpv@users.noreply.github.com> Date: Mon, 17 Aug 2026 00:01:22 -0500 Subject: audio driver --- Core/Src/cs4272.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100755 Core/Src/cs4272.c (limited to 'Core/Src/cs4272.c') diff --git a/Core/Src/cs4272.c b/Core/Src/cs4272.c new file mode 100755 index 0000000..e7b639e --- /dev/null +++ b/Core/Src/cs4272.c @@ -0,0 +1,126 @@ +/* + * cs4272.c + * + * Created on: Aug 16, 2026 + * Author: ozpv + */ + +#include "i2c.h" +#include "cs4272.h" + +volatile int32_t rx_buffer[BUFFER_SIZE] __attribute__((section(".audio_buffers"))); +volatile int32_t tx_buffer[BUFFER_SIZE] __attribute__((section(".audio_buffers"))); + +const uint8_t CS4272_CONFIG[7] = { + // MODE CONTROL 1 + // single speed i2s slave + 0b00000001, + // DAC CONTROL + // no auto mute steep roll off interpolation 48 kHz de-emphasis + // Soft Ramp Up and Down and no polarity flipping + 0b00001100, + // DAC Volume & Mixing Control + // Channel B Volume = Channel A Volume Soft Ramp and Zero Cross + // a = L b = R + 0b01111001, + // Channel A volume + // 0 dB + // Binary Code Decimal Value Volume Setting + // 0000000 0 0 dB + // 0010100 20 -20 dB + // 0101000 40 -40 dB + // 0111100 60 -60 dB + // 1011010 90 -90 dB + 0b00000000, + // Channel B volume + 0b00000000, + // ADC control + // I2S up to 24-bit data High Pass filter on + // bits 3:2 adc channel mute + 0b00010000, + // MODE CONTROL 2 + // power down OFF + 0b00000010, +}; + +HAL_StatusTypeDef CS4272_ReadRegister(uint8_t addr, uint8_t *data) { + return HAL_I2C_Mem_Read(&hi2c4, CS4272_I2C_ADDR, addr, I2C_MEMADD_SIZE_8BIT, + data, 1, HAL_MAX_DELAY); +} + +HAL_StatusTypeDef CS4272_WriteRegister(uint8_t addr, uint8_t data) { + return HAL_I2C_Mem_Write(&hi2c4, CS4272_I2C_ADDR, addr, + I2C_MEMADD_SIZE_8BIT, &data, 1, HAL_MAX_DELAY); +} + +void CS4272_Reset() { + HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET); + + HAL_Delay(10); + + HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET); + + HAL_Delay(10); +} + +uint8_t CS4272_Init() { + CS4272_Reset(); + + if (HAL_I2C_IsDeviceReady(&hi2c4, CS4272_I2C_ADDR, 3, 1000) != HAL_OK) { + return HAL_ERROR; + } + + // 5.2.1 Recommended Power-Up Sequence + // power down mode and control port enable + if (CS4272_WriteRegister(MODE_CONTROL_2, 0x03) != HAL_OK) { + return HAL_ERROR; + } + + // check if device ID is correct + uint8_t id = 0; + if (CS4272_ReadRegister(CHIP_ID, &id) != HAL_OK) { + return HAL_ERROR; + } + + if ((id >> 4) != CS4272_CHIP_ID) { + return 2; + } + + // Configure + uint8_t cfg = 0; + for (uint8_t i = MODE_CONTROL_1; i < MODE_CONTROL_2; ++i) { + if (CS4272_WriteRegister(i, CS4272_CONFIG[i - 1]) != HAL_OK) { + return HAL_ERROR; + } + + if (CS4272_ReadRegister(i, &cfg) != HAL_OK) { + return HAL_ERROR; + } + + if (cfg != CS4272_CONFIG[i - 1]) { + return 2; + } + } + + if (CS4272_WriteRegister(MODE_CONTROL_2, 0x02) != HAL_OK) { + return HAL_ERROR; + } + + if (CS4272_ReadRegister(MODE_CONTROL_2, &cfg) != HAL_OK || cfg != 0x02) { + return 2; + } + + return HAL_OK; +} + +void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai) { + for(int i = 0; i < BUFFER_SIZE / 2; i++) { + tx_buffer[i] = rx_buffer[i]; + } +} + +void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai) { + for(int i = BUFFER_SIZE / 2; i < BUFFER_SIZE; i++) { + tx_buffer[i] = rx_buffer[i]; + } +} -- cgit v1.2.3