|
|
|
@ -27,19 +27,17 @@
|
|
|
|
|
|
|
|
|
|
/* Private typedef -----------------------------------------------------------*/
|
|
|
|
|
/* USER CODE BEGIN PTD */
|
|
|
|
|
typedef struct {
|
|
|
|
|
int32_t value : 18;
|
|
|
|
|
} sample_t;
|
|
|
|
|
typedef uint32_t sample_t;
|
|
|
|
|
/* USER CODE END PTD */
|
|
|
|
|
|
|
|
|
|
/* Private define ------------------------------------------------------------*/
|
|
|
|
|
/* USER CODE BEGIN PD */
|
|
|
|
|
#define SAMPLE_COUNT (256) // Sample count per half-transfer
|
|
|
|
|
#define SAMPLE_COUNT (256) // (Stereo!) Sample count per half-transfer
|
|
|
|
|
#define SAMPLES_PER_REPORT (48000) // Report every second given our 48 kHz rate
|
|
|
|
|
#define MIC_OFFSET_DB ( 0.f) // Linear offset
|
|
|
|
|
#define MIC_SENSITIVITY (-26.f) // dBFS value expected at MIC_REF_DB
|
|
|
|
|
#define MIC_REF_DB ( 94.f) // dB where sensitivity is specified
|
|
|
|
|
#define MIC_BITS (18)
|
|
|
|
|
#define MIC_BITS (18u)
|
|
|
|
|
/* USER CODE END PD */
|
|
|
|
|
|
|
|
|
|
/* Private macro -------------------------------------------------------------*/
|
|
|
|
@ -104,7 +102,7 @@ int main(void)
|
|
|
|
|
|
|
|
|
|
/* USER CODE BEGIN 1 */
|
|
|
|
|
ln10 = qfp_fln(10.f);
|
|
|
|
|
MIC_REF_AMPL = qfp_fmul(qfp_int2float((1 << (MIC_BITS - 1)) - 1),
|
|
|
|
|
MIC_REF_AMPL = qfp_fmul(qfp_int2float((1u << (MIC_BITS - 1)) - 1),
|
|
|
|
|
qfp_fpow(10.f, MIC_SENSITIVITY / 20.f));
|
|
|
|
|
/* USER CODE END 1 */
|
|
|
|
|
|
|
|
|
@ -443,53 +441,64 @@ error :
|
|
|
|
|
return errorcode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma)
|
|
|
|
|
{
|
|
|
|
|
SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)hdma->Parent;
|
|
|
|
|
(void)hspi;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static float process(float in_div4)
|
|
|
|
|
static inline float process(float in_div4)
|
|
|
|
|
{
|
|
|
|
|
static float z1 = 0, z2 = 0, z3 = 0, z5 = 0;
|
|
|
|
|
static float z[4] = {0.f, 0.f, 0.f, 0.f};
|
|
|
|
|
|
|
|
|
|
float out1 = qfp_fadd(in_div4, z1);
|
|
|
|
|
z1 = qfp_fadd(qfp_fmul(1.062f, out1), z2);
|
|
|
|
|
z2 = qfp_fsub(qfp_fmul(-0.14f, out1), in_div4);
|
|
|
|
|
float out1 = qfp_fadd(in_div4, z[0]);
|
|
|
|
|
z[0] = qfp_fadd(qfp_fmul(out1, 1.062f), z[1]);
|
|
|
|
|
z[1] = qfp_fsub(qfp_fmul(out1, -0.14f), in_div4);
|
|
|
|
|
|
|
|
|
|
float out2 = qfp_fadd(out1, z3);
|
|
|
|
|
z3 = out1;
|
|
|
|
|
float out2 = qfp_fadd(out1, z[2]);
|
|
|
|
|
z[2] = out1;
|
|
|
|
|
|
|
|
|
|
float out3 = qfp_fadd(out2, z5);
|
|
|
|
|
z5 = qfp_fsub(qfp_fmul(0.985f, out3), out2);
|
|
|
|
|
float out3 = qfp_fadd(out2, z[3]);
|
|
|
|
|
z[3] = qfp_fsub(qfp_fmul(out3, 0.985f), out2);
|
|
|
|
|
|
|
|
|
|
return out3;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma)
|
|
|
|
|
static void processSampleBlock(sample_t *sample)
|
|
|
|
|
{
|
|
|
|
|
HAL_GPIO_WritePin(IDLE_GPIO_Port, IDLE_Pin, GPIO_PIN_RESET);
|
|
|
|
|
|
|
|
|
|
SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)hdma->Parent;
|
|
|
|
|
(void)hspi;
|
|
|
|
|
// SAMPLE_COUNT is number of samples in this block
|
|
|
|
|
// Divide by 2 for left channel only
|
|
|
|
|
// Divide by 8 for stride to reduce compute time
|
|
|
|
|
#define STRIDE (2 * 8)
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < SAMPLE_COUNT; i += STRIDE) {
|
|
|
|
|
// 18-bit sample comes in as big-endian with right padding.
|
|
|
|
|
// 1. Convert to little-endian:
|
|
|
|
|
int samp;
|
|
|
|
|
asm("rev %0, %1" : "=r" (samp) : "r" (sample[i]));
|
|
|
|
|
// 2. Arithmetic shift right to remove padding, +2 to make "in_div4"
|
|
|
|
|
float f = process(qfp_int2float(samp >> (32 - MIC_BITS + 2)));
|
|
|
|
|
|
|
|
|
|
sample_t *sample = (sample_t *)I2S_Receive_Buffer;
|
|
|
|
|
for (int i = 0; i < SAMPLE_COUNT / 8; i++) {
|
|
|
|
|
float f = process(qfp_int2float(sample[i].value / 4));
|
|
|
|
|
DB_Sum_Squares = qfp_fadd(DB_Sum_Squares, qfp_fmul(f, f));
|
|
|
|
|
DB_Sum_Squares = qfp_fadd(qfp_fmul(f, f), DB_Sum_Squares);
|
|
|
|
|
}
|
|
|
|
|
DB_Count += SAMPLE_COUNT * 2; // Pretend we sampled the entire I2S buffer
|
|
|
|
|
DB_Count += SAMPLE_COUNT / STRIDE;
|
|
|
|
|
|
|
|
|
|
if (DB_Count > SAMPLES_PER_REPORT) {
|
|
|
|
|
if (DB_Count >= SAMPLES_PER_REPORT / STRIDE * 2) {
|
|
|
|
|
float rms = qfp_fsqrt(qfp_fdiv(DB_Sum_Squares, qfp_uint2float(DB_Count)));
|
|
|
|
|
float db = qfp_fadd(MIC_OFFSET_DB + MIC_REF_DB, qfp_fmul(20.f,
|
|
|
|
|
qfp_flog10(qfp_fdiv(rms, MIC_REF_AMPL))));
|
|
|
|
|
float db = qfp_fadd(qfp_fmul(qfp_flog10(qfp_fdiv(rms, MIC_REF_AMPL)), 20.f),
|
|
|
|
|
MIC_OFFSET_DB + MIC_REF_DB);
|
|
|
|
|
DB_Sum_Squares = 0.f;
|
|
|
|
|
DB_Count = 0;
|
|
|
|
|
|
|
|
|
|
printf("%d dB\r\n", qfp_float2int(db));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma)
|
|
|
|
|
{
|
|
|
|
|
processSampleBlock((sample_t *)I2S_Receive_Buffer + SAMPLE_COUNT);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma)
|
|
|
|
|
{
|
|
|
|
|
processSampleBlock((sample_t *)I2S_Receive_Buffer);
|
|
|
|
|
}
|
|
|
|
|
/* USER CODE END 4 */
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|