1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
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];
}
}
|