diff --git a/NANOVNA_STM32_F072/i2s.c b/NANOVNA_STM32_F072/i2s.c index d1e3a86c..9cc3e248 100644 --- a/NANOVNA_STM32_F072/i2s.c +++ b/NANOVNA_STM32_F072/i2s.c @@ -22,10 +22,15 @@ // F072 SPI2 RX DMA1 interrupt #define STM32_SPI2_RX_DMA_IRQ_NUMBER DMA1_Channel4_5_6_7_IRQn +#define SPI_I2S_FHILLIPS_MODE ( 0) +#define SPI_I2S_MSB_MODE (SPI_I2SCFGR_I2SSTD_0) +#define SPI_I2S_LSB_MODE (SPI_I2SCFGR_I2SSTD_1) +#define SPI_I2S_PCM_MODE (SPI_I2SCFGR_I2SSTD_0 | SPI_I2SCFGR_I2SSTD_1) + /* * Run I2S bus in Circular mode, fill buffer, and handle read in I2S DMA RX interrupt */ -void initI2S(int16_t *buffer, uint16_t count) { +void initI2S(void *buffer, uint16_t count) { const uint16_t I2S_DMA_RX_ccr = 0 | STM32_DMA_CR_PL(3) // 3 - Very High | STM32_DMA_CR_PSIZE_HWORD // 16 bit @@ -39,9 +44,9 @@ void initI2S(int16_t *buffer, uint16_t count) { ; // I2S RX DMA setup. nvicEnableVector(STM32_SPI2_RX_DMA_IRQ_NUMBER, STM32_I2S_SPI2_IRQ_PRIORITY); - dmaChannelSetTransactionSize(I2S_DMA_RX, count);// number of data register + dmaChannelSetTransactionSize(I2S_DMA_RX, count); // number of data register dmaChannelSetPeripheral(I2S_DMA_RX, &SPI2->DR); // peripheral address register - dmaChannelSetMemory(I2S_DMA_RX, buffer); // memory address register + dmaChannelSetMemory(I2S_DMA_RX, buffer); // memory address register dmaChannelSetMode(I2S_DMA_RX, I2S_DMA_RX_ccr | STM32_DMA_CR_EN); // configuration register // Starting I2S @@ -53,6 +58,8 @@ void initI2S(int16_t *buffer, uint16_t count) { | SPI_I2SCFGR_I2SCFG_0 // 01: Slave - receive // | SPI_I2SCFGR_I2SCFG_1 // | SPI_I2SCFGR_I2SMOD // I2S mode is selected + | SPI_I2S_PCM_MODE // I2S PCM standard (aic3204 use DSP mode, short sync) + | SPI_I2SCFGR_PCMSYNC // Short sync | SPI_I2SCFGR_I2SE // I2S enable ; } diff --git a/NANOVNA_STM32_F303/i2s.c b/NANOVNA_STM32_F303/i2s.c index 554ee87e..5e1369e6 100644 --- a/NANOVNA_STM32_F303/i2s.c +++ b/NANOVNA_STM32_F303/i2s.c @@ -22,10 +22,15 @@ // F303 SPI2 RX DMA1 interrupt #define STM32_SPI2_RX_DMA_IRQ_NUMBER DMA1_Channel4_IRQn +#define SPI_I2S_FHILLIPS_MODE ( 0) +#define SPI_I2S_MSB_MODE (SPI_I2SCFGR_I2SSTD_0) +#define SPI_I2S_LSB_MODE (SPI_I2SCFGR_I2SSTD_1) +#define SPI_I2S_PCM_MODE (SPI_I2SCFGR_I2SSTD_0 | SPI_I2SCFGR_I2SSTD_1) + /* * Run I2S bus in Circular mode, fill buffer, and handle read in I2S DMA RX interrupt */ -void initI2S(int16_t *buffer, uint16_t count) { +void initI2S(void *buffer, uint16_t count) { const uint16_t I2S_DMA_RX_ccr = 0 | STM32_DMA_CR_PL(3) // 3 - Very High | STM32_DMA_CR_PSIZE_HWORD // 16 bit @@ -53,6 +58,8 @@ void initI2S(int16_t *buffer, uint16_t count) { | SPI_I2SCFGR_I2SCFG_0 // 01: Slave - receive // | SPI_I2SCFGR_I2SCFG_1 // | SPI_I2SCFGR_I2SMOD // I2S mode is selected + | SPI_I2S_PCM_MODE // I2S PCM standard (aic3204 use DSP mode, short sync) + | SPI_I2SCFGR_PCMSYNC // Short sync | SPI_I2SCFGR_I2SE // I2S enable ; } diff --git a/dsp.c b/dsp.c index 491311c5..1eabe6f3 100644 --- a/dsp.c +++ b/dsp.c @@ -141,7 +141,7 @@ acc_t acc_samp_c; acc_t acc_ref_s; acc_t acc_ref_c; void -dsp_process(int16_t *capture, size_t length) +dsp_process(audio_sample_t *capture, size_t length) { int32_t samp_s = 0; int32_t samp_c = 0; @@ -176,7 +176,7 @@ static acc_t acc_ref_c; // Cortex M4 DSP instruction use #include "dsp.h" void -dsp_process(int16_t *capture, size_t length) +dsp_process(audio_sample_t *capture, size_t length) { uint32_t i = 0; // int64_t samp_s = 0; diff --git a/hardware.h b/hardware.h index 3f93aea5..3fc7c45a 100644 --- a/hardware.h +++ b/hardware.h @@ -153,7 +153,7 @@ void dac_setvalue_ch2(uint16_t v); * i2s.c * Used for read samples from audio codec */ -void initI2S(int16_t *buffer, uint16_t count); +void initI2S(void *buffer, uint16_t count); /* * flash.c diff --git a/ili9341.c b/ili9341.c index 2440b720..b0de49e7 100644 --- a/ili9341.c +++ b/ili9341.c @@ -123,7 +123,7 @@ static const uint32_t rxdmamode = 0 | STM32_DMA_CR_PL(STM32_SPI_SPI1_DMA_PRIORITY) // Set priority | STM32_DMA_CR_DIR_P2M; // SPI to Memory -// SPI transmit byte buffer use DMA +// SPI transmit byte buffer use DMA (65535 bytes limit) static inline void spi_DMATxBuffer(const uint8_t *buffer, uint16_t len, bool wait) { dmaChannelSetMemory(LCD_DMA_TX, buffer); dmaChannelSetTransactionSize(LCD_DMA_TX, len); @@ -828,11 +828,23 @@ int lcd_printf(int16_t x, int16_t y, const char *fmt, ...) { return retval; } -void lcd_drawstringV(const char *str, int x, int y) -{ +int lcd_printfV(int16_t x, int16_t y, const char *fmt, ...) { + // Init small lcd print stream + struct lcd_printStreamVMT { + _base_sequential_stream_methods + } lcd_vmt = {NULL, NULL, lcd_put, NULL}; + lcdPrintStream ps = {&lcd_vmt, x, y, x, y, 0}; + lcd_set_foreground(LCD_FG_COLOR); + lcd_set_background(LCD_BG_COLOR); ili9341_set_rotation(DISPLAY_ROTATION_270); - lcd_drawstring(LCD_HEIGHT-y, x, str); + // Performing the print operation using the common code. + va_list ap; + va_start(ap, fmt); + int retval = chvprintf((BaseSequentialStream *)(void *)&ps, fmt, ap); + va_end(ap); ili9341_set_rotation(DISPLAY_ROTATION_0); + // Return number of bytes that would have been written. + return retval; } int lcd_drawchar_size(uint8_t ch, int x, int y, uint8_t size) diff --git a/main.c b/main.c index a53a3842..7fc74842 100644 --- a/main.c +++ b/main.c @@ -1057,11 +1057,11 @@ int load_properties(uint32_t id) { } #ifdef ENABLED_DUMP_COMMAND -int16_t *dump_buffer; +audio_sample_t *dump_buffer; volatile int16_t dump_len = 0; int16_t dump_selection = 0; static void -duplicate_buffer_to_dump(int16_t *p, size_t n) +duplicate_buffer_to_dump(audio_sample_t *p, size_t n) { p+=dump_selection; while (n) { @@ -1079,14 +1079,14 @@ static systime_t ready_time = 0; // sweep operation variables volatile uint16_t wait_count = 0; // i2s buffer must be 2x size (for process one while next buffer filled by DMA) -static int16_t rx_buffer[AUDIO_BUFFER_LEN * 2]; +static audio_sample_t rx_buffer[AUDIO_BUFFER_LEN * 2]; void i2s_lld_serve_rx_interrupt(uint32_t flags) { //if ((flags & (STM32_DMA_ISR_TCIF|STM32_DMA_ISR_HTIF)) == 0) return; uint16_t wait = wait_count; if (wait == 0 || chVTGetSystemTimeX() < ready_time) return; uint16_t count = AUDIO_BUFFER_LEN; - int16_t *p = (flags & STM32_DMA_ISR_TCIF) ? rx_buffer + AUDIO_BUFFER_LEN : rx_buffer; // Full or Half transfer complete + audio_sample_t *p = (flags & STM32_DMA_ISR_TCIF) ? rx_buffer + AUDIO_BUFFER_LEN : rx_buffer; // Full or Half transfer complete if (wait >= config._bandwidth+2) // At this moment in buffer exist noise data, reset and wait next clean buffer reset_dsp_accumerator(); else @@ -1268,9 +1268,9 @@ static bool sweep(bool break_on_operation, uint16_t mask) VNA_SHELL_FUNCTION(cmd_dump) { int i, j; - int16_t dump[96*2]; + audio_sample_t dump[96*2]; dump_buffer = dump; - dump_len = sizeof(dump) / sizeof(int16_t); + dump_len = ARRAY_COUNT(dump); int len = dump_len; if (argc == 1) dump_selection = my_atoi(argv[0]) == 1 ? 0 : 1; diff --git a/nanovna.h b/nanovna.h index 76482e90..48433dac 100644 --- a/nanovna.h +++ b/nanovna.h @@ -448,12 +448,8 @@ extern const char *info_about[]; #define BANDWIDTH_10 (100 - 1) #endif -#ifdef ENABLED_DUMP -extern int16_t ref_buf[]; -extern int16_t samp_buf[]; -#endif - -void dsp_process(int16_t *src, size_t len); +typedef int16_t audio_sample_t; +void dsp_process(audio_sample_t *src, size_t len); void reset_dsp_accumerator(void); void calculate_gamma(float *gamma); void fetch_amplitude(float *gamma); @@ -1205,7 +1201,7 @@ void lcd_drawstring(int16_t x, int16_t y, const char *str); #define lcd_drawstring lcd_printf #endif int lcd_printf(int16_t x, int16_t y, const char *fmt, ...); -void lcd_drawstringV(const char *str, int x, int y); +int lcd_printfV(int16_t x, int16_t y, const char *fmt, ...); int lcd_drawchar_size(uint8_t ch, int x, int y, uint8_t size); void lcd_drawstring_size(const char *str, int x, int y, uint8_t size); void lcd_drawfont(uint8_t ch, int x, int y); @@ -1346,7 +1342,7 @@ int plot_printf(char *str, int, const char *fmt, ...); #define ARRAY_COUNT(a) (sizeof(a)/sizeof(*(a))) // Speed profile definition #define START_PROFILE systime_t time = chVTGetSystemTimeX(); -#define STOP_PROFILE {char string_buf[12];plot_printf(string_buf, sizeof string_buf, "T:%08d", chVTGetSystemTimeX() - time); lcd_set_foreground(LCD_BG_COLOR); lcd_drawstringV(string_buf, 1, 90);} +#define STOP_PROFILE {lcd_printfV(1, 1, "T:%08d", chVTGetSystemTimeX() - time);} // Macros for convert define value to string #define STR1(x) #x #define define_to_STR(x) STR1(x) diff --git a/tlv320aic3204.c b/tlv320aic3204.c index 35ee040f..a0070a80 100644 --- a/tlv320aic3204.c +++ b/tlv320aic3204.c @@ -109,6 +109,22 @@ #define REG_39_CM2R_TO_RIGHT_N_20k (2<<0) #define REG_39_CM2R_TO_RIGHT_N_40k (3<<0) +#define REG_27_WCLK_IN (0<<2) +#define REG_27_WCLK_OUT (1<<2) +#define REG_27_BCLK_IN (0<<3) +#define REG_27_BCLK_OUT (1<<3) +#define REG_27_DATA_16 (0<<4) +#define REG_27_DATA_20 (1<<4) +#define REG_27_DATA_24 (2<<4) +#define REG_27_DATA_32 (3<<4) +#define REG_27_INTERFACE_I2S (0<<6) +#define REG_27_INTERFACE_DSP (1<<6) +#define REG_27_INTERFACE_RJF (2<<6) +#define REG_27_INTERFACE_LJF (3<<6) + +// Set the interface mode: 16 bit, BCLK, WCLK as output, DSP mode +#define REG_27 (REG_27_DATA_16 | REG_27_INTERFACE_DSP | REG_27_WCLK_OUT | REG_27_BCLK_OUT) + static const uint8_t conf_data[] = { // reg, data, // PLL clock config 0x00, 0x00, // Initialize to Page 0 @@ -162,9 +178,8 @@ static const uint8_t conf_data[] = { 0x3d, 0x01, // Select ADC PRB_R1 0x24, 0xee, // ADC power up - 0x1b, 0x0c, // Set the BCLK,WCLK as output + 0x1b, REG_27, // Set the interface mode 0x1e, 0x80 + 32,// Enable the BCLKN divider with value 32 (I2S clock = 98.304MHz/(NDAC*32) = 48kHz * (16+16) - #elif AUDIO_ADC_FREQ == 24000 // Clock config, default fs=24kHz // from PLL 98.304MHz/(4*8*128) = 24kHz @@ -181,9 +196,8 @@ static const uint8_t conf_data[] = { 0x3d, 0x01, // Select ADC PRB_R1 0x24, 0xee, // ADC power up - 0x1b, 0x0c, // Set the BCLK,WCLK as output + 0x1b, REG_27, // Set the interface mode 0x1e, 0x80 + 32,// Enable the BCLKN divider with value 32 (I2S clock = 98.304MHz/(NDAC*32) = 48kHz * (16+16) - #elif AUDIO_ADC_FREQ == 48000 // Clock config, default fs=48kHz // from PLL 98.304MHz/(2*8*128) = 48kHz @@ -200,7 +214,7 @@ static const uint8_t conf_data[] = { 0x3d, 0x01, // Select ADC PRB_R1 0x24, 0xee, // ADC power up - 0x1b, 0x0c, // Set the BCLK,WCLK as output + 0x1b, REG_27, // Set the interface mode 0x1e, 0x80 + 32,// Enable the BCLKN divider with value 32 (I2S clock = 98.304MHz/(NDAC*32) = 48kHz * (16+16) #elif AUDIO_ADC_FREQ == 96000 // Clock config, default fs=96kHz @@ -218,7 +232,7 @@ static const uint8_t conf_data[] = { 0x3d, 0x01, // Select ADC PRB_R1 (AOSR = 64 (Use with PRB_R1 to PRB_R12, ADC Filter Type A or B)) 0x24, 0xee, // ADC power up - 0x1b, 0x0c, // Set the BCLK,WCLK as output + 0x1b, REG_27, // Set the interface mode 0x1e, 0x80 + 16,// Enable the BCLKN divider with value 16 (I2S clock = 98.304MHz/(NDAC*16) = 96kHz * (16+16) #elif AUDIO_ADC_FREQ == 192000 // Clock config, default fs=192kHz @@ -237,8 +251,8 @@ static const uint8_t conf_data[] = { 0x3d, 7, // Select ADC PRB_R7 0x24, 0xee, // ADC power up - 0x1b, 0x0c, // Set the BCLK,WCLK as output - 0x1e, 0x80 + 8,// Enable the BCLKN divider with value 8 (I2S clock = 98.304MHz/(NDAC*8) = 192kHz * (16+16) + 0x1b, REG_27, // Set the interface mode + 0x1e, 0x80 + 8, // Enable the BCLKN divider with value 8 (I2S clock = 98.304MHz/(NDAC*8) = 192kHz * (16+16) #elif AUDIO_ADC_FREQ == 384000 // Clock config, default fs=384kHz // from PLL 98.304MHz/(2*4*32) = 384kHz @@ -256,8 +270,8 @@ static const uint8_t conf_data[] = { 0x3d, 7, // Select ADC PRB_R7 0x24, 0xee, // ADC power up - 0x1b, 0x0c, // Set the BCLK,WCLK as output - 0x1e, 0x80 + 4,// Enable the BCLKN divider with value 4 (I2S clock = 98.304MHz/(NDAC*4) = 384kHz * (16+16) + 0x1b, REG_27, // Set the interface mode + 0x1e, 0x80 + 4, // Enable the BCLKN divider with value 4 (I2S clock = 98.304MHz/(NDAC*4) = 384kHz * (16+16) #elif AUDIO_ADC_FREQ == 768000 // Clock config, default fs=768kHz // from PLL 98.304MHz/(2*4*16) = 768kHz @@ -275,8 +289,8 @@ static const uint8_t conf_data[] = { 0x3d, 7, // Select ADC PRB_R7 0x24, 0xee, // ADC power up - 0x1b, 0x0c, // Set the BCLK,WCLK as output - 0x1e, 0x80 + 2,// Enable the BCLKN divider with value 2 (I2S clock = 98.304MHz/(NDAC*2) = 768kHz * (16+16) + 0x1b, REG_27, // Set the interface mode + 0x1e, 0x80 + 2, // Enable the BCLKN divider with value 2 (I2S clock = 98.304MHz/(NDAC*2) = 768kHz * (16+16) #else #error "Need set correct ADC clock for aic3204" #endif