From 0cb345ed5ccbe786d0a7e7e2de740c0a07b82770 Mon Sep 17 00:00:00 2001 From: ozpv <39195175+ozpv@users.noreply.github.com> Date: Wed, 19 Aug 2026 21:34:09 -0500 Subject: sdram and ringmod effect --- Core/Inc/Effects/ringmod.h | 16 ++++++ Core/Inc/cs4272.h | 12 +++-- Core/Inc/w9825g6kh6.h | 17 ++++++ Core/Src/Effects/ringmod.c | 37 ++++++++++++++ Core/Src/cs4272.c | 122 +++++++++++++++++++++++++------------------- Core/Src/fmc.c | 26 +++------- Core/Src/main.c | 21 +++++--- Core/Src/quadspi.c | 27 ++-------- Core/Src/sai.c | 4 +- Core/Src/system_stm32h7xx.c | 1 - Core/Src/w9825g6kh6.c | 64 +++++++++++++++++++++++ README.md | 1 + STM32H750ZBTX_FLASH.ld | 11 +++- audio.ioc | 43 +++++++++++----- 14 files changed, 281 insertions(+), 121 deletions(-) create mode 100755 Core/Inc/Effects/ringmod.h create mode 100755 Core/Inc/w9825g6kh6.h create mode 100755 Core/Src/Effects/ringmod.c create mode 100755 Core/Src/w9825g6kh6.c diff --git a/Core/Inc/Effects/ringmod.h b/Core/Inc/Effects/ringmod.h new file mode 100755 index 0000000..42cb229 --- /dev/null +++ b/Core/Inc/Effects/ringmod.h @@ -0,0 +1,16 @@ +/* + * ringmod.h + * + * Created on: Aug 19, 2026 + * Author: ozpv + */ + +#ifndef INC_EFFECTS_RINGMOD_H_ +#define INC_EFFECTS_RINGMOD_H_ + +#include +#include + +void ringmod(float *samples, size_t range_min, size_t range_max); + +#endif /* INC_EFFECTS_RINGMOD_H_ */ diff --git a/Core/Inc/cs4272.h b/Core/Inc/cs4272.h index 30e493a..423b7c0 100755 --- a/Core/Inc/cs4272.h +++ b/Core/Inc/cs4272.h @@ -8,7 +8,9 @@ #ifndef INC_CS4272_H_ #define INC_CS4272_H_ -// cs4272k-czzr 7. REGISTER QUICK REFERENCE +#include + +/* cs4272k-czzr 7. REGISTER QUICK REFERENCE */ #define MODE_CONTROL_1 0x01 #define DAC_CONTROL 0x02 #define DAC_VOLUME_AND_MIXING_CONTROL 0x03 @@ -20,16 +22,20 @@ #define CS4272_CHIP_ID 0x0 -// set by ncs/ad0 pin +/* set by ad0 ncs pin */ #define CS4272_I2C_ADDR (0b0010000 << 1) +#define SAMPLE_RATE 48000 #define BUFFER_SIZE 512 extern volatile int32_t rx_buffer[BUFFER_SIZE]; extern volatile int32_t tx_buffer[BUFFER_SIZE]; +extern volatile float samples[BUFFER_SIZE]; extern const uint8_t CS4272_CONFIG[7]; -uint8_t CS4272_Init(); +uint8_t CS4272_Init(void); + +#define INT24_MAX 0x7FFFFF #endif /* INC_CS4272_H_ */ diff --git a/Core/Inc/w9825g6kh6.h b/Core/Inc/w9825g6kh6.h new file mode 100755 index 0000000..3e4f043 --- /dev/null +++ b/Core/Inc/w9825g6kh6.h @@ -0,0 +1,17 @@ +/* + * w9825g6kh6.h + * + * Created on: Aug 18, 2026 + * Author: ozpv + */ + +#ifndef INC_W9825G6KH6_H_ +#define INC_W9825G6KH6_H_ + +#define SDRAM_BASE 0xC0000000 +#define SDRAM_SIZE 0x02000000 + +void FMC_Init(void); +void SDRAM_Test(void); + +#endif /* INC_W9825G6KH6_H_ */ diff --git a/Core/Src/Effects/ringmod.c b/Core/Src/Effects/ringmod.c new file mode 100755 index 0000000..732f68e --- /dev/null +++ b/Core/Src/Effects/ringmod.c @@ -0,0 +1,37 @@ +/* + * ringmod.c + * + * Created on: Aug 19, 2026 + * Author: ozpv + */ + +#include "cs4272.h" +#include "ringmod.h" +#include + +/* ring modulator */ +void ringmod(float *samples, size_t range_min, size_t range_max) { + static float lfo_phase = 0.0f; + static float carrier_phase = 0.0f; + + const float frequency = 156.0f; + const float amount = 0.67f; + const float sample_rate = (float)SAMPLE_RATE; + + float lfo_increment = M_TWOPI * (0.18f / sample_rate); + + /* plus two because of */ + for (size_t i = range_min; i < range_max; i += 2) { + lfo_phase = fmodf(lfo_phase + lfo_increment, M_TWOPI); + + float lfo = sinf(lfo_phase); + + float carrier_increment = M_TWOPI * ((frequency + lfo * (frequency * 3.0f * amount)) / sample_rate); + + carrier_phase = fmodf(carrier_phase + carrier_increment, M_TWOPI); + + float carrier = sinf(carrier_phase); + + samples[i] = (samples[i] * 0.50f) + (samples[i] * carrier * 0.50f); + } +} diff --git a/Core/Src/cs4272.c b/Core/Src/cs4272.c index e7b639e..81179c7 100755 --- a/Core/Src/cs4272.c +++ b/Core/Src/cs4272.c @@ -7,42 +7,78 @@ #include "i2c.h" #include "cs4272.h" +#include "ringmod.h" volatile int32_t rx_buffer[BUFFER_SIZE] __attribute__((section(".audio_buffers"))); volatile int32_t tx_buffer[BUFFER_SIZE] __attribute__((section(".audio_buffers"))); +volatile float samples[BUFFER_SIZE] __attribute__((section(".sdram"))); const uint8_t CS4272_CONFIG[7] = { - // MODE CONTROL 1 - // single speed i2s slave + /* 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 + /* DAC CONTROL + Steep Interpolation Filter + 48 kHz de-emphasis + Soft Ramp Up and Down and no polarity flip */ + 0b01101100, + /* DAC Volume & Mixing Control + Channel B Volume = Channel A Volume + Soft Ramp and Zero Cross + a = L b = R + stereo 0b01111001 */ + 0b01111000, + /* 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 + /* Channel B volume + Muted for mono */ + 0b10000000, + /* ADC control + I2S up to 24-bit data High Pass filter on + bits 3:2 active high adc channel mute + Channel B muted */ + 0b00010100, + /* MODE CONTROL 2 + power down OFF */ 0b00000010, }; +void int32_t_to_float(int32_t *in, float *out, size_t range_min, size_t range_max) { + for (size_t i = range_min; i < range_max; ++i) { + out[i] = ((float)(in[i] << 8)) / ((float)INT32_MAX); + } +} + +void float_to_int32_t(float *in, int32_t *out, size_t range_min, size_t range_max) { + for (size_t i = range_min; i < range_max; ++i) { + out[i] = ((int32_t)(in[i] * ((float)INT32_MAX))) >> 8; + } +} + +void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai) { + int32_t_to_float((int32_t *)rx_buffer, (float *)samples, 0, BUFFER_SIZE / 2); + + ringmod((float *)samples, 0, BUFFER_SIZE / 2); + + float_to_int32_t((float *)samples, (int32_t *)tx_buffer, 0, BUFFER_SIZE / 2); +} + +void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai) { + int32_t_to_float((int32_t *)rx_buffer, (float *)samples, BUFFER_SIZE / 2, BUFFER_SIZE); + + ringmod((float *)samples, BUFFER_SIZE / 2, BUFFER_SIZE); + + float_to_int32_t((float *)samples, (int32_t *)tx_buffer, BUFFER_SIZE / 2, BUFFER_SIZE); +} + + 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); @@ -53,7 +89,7 @@ HAL_StatusTypeDef CS4272_WriteRegister(uint8_t addr, uint8_t data) { I2C_MEMADD_SIZE_8BIT, &data, 1, HAL_MAX_DELAY); } -void CS4272_Reset() { +void CS4272_Reset(void) { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET); HAL_Delay(10); @@ -63,20 +99,20 @@ void CS4272_Reset() { HAL_Delay(10); } -uint8_t CS4272_Init() { +uint8_t CS4272_Init(void) { 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 + /* 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 + /* check if device ID is correct */ uint8_t id = 0; if (CS4272_ReadRegister(CHIP_ID, &id) != HAL_OK) { return HAL_ERROR; @@ -86,9 +122,9 @@ uint8_t CS4272_Init() { return 2; } - // Configure + /* Configure */ uint8_t cfg = 0; - for (uint8_t i = MODE_CONTROL_1; i < MODE_CONTROL_2; ++i) { + for (size_t i = MODE_CONTROL_1; i < CHIP_ID; ++i) { if (CS4272_WriteRegister(i, CS4272_CONFIG[i - 1]) != HAL_OK) { return HAL_ERROR; } @@ -102,25 +138,5 @@ uint8_t CS4272_Init() { } } - 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]; - } -} diff --git a/Core/Src/fmc.c b/Core/Src/fmc.c index ae14948..b1eac4d 100755 --- a/Core/Src/fmc.c +++ b/Core/Src/fmc.c @@ -53,15 +53,15 @@ void MX_FMC_Init(void) hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE; hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2; hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE; - hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0; + hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_2; /* SdramTiming */ - SdramTiming.LoadToActiveDelay = 16; - SdramTiming.ExitSelfRefreshDelay = 12; - SdramTiming.SelfRefreshTime = 16; - SdramTiming.RowCycleDelay = 10; - SdramTiming.WriteRecoveryTime = 16; - SdramTiming.RPDelay = 3; - SdramTiming.RCDDelay = 3; + SdramTiming.LoadToActiveDelay = 2; + SdramTiming.ExitSelfRefreshDelay = 8; + SdramTiming.SelfRefreshTime = 5; + SdramTiming.RowCycleDelay = 6; + SdramTiming.WriteRecoveryTime = 3; + SdramTiming.RPDelay = 2; + SdramTiming.RCDDelay = 2; if (HAL_SDRAM_Init(&hsdram1, &SdramTiming) != HAL_OK) { @@ -84,16 +84,6 @@ static void HAL_FMC_MspInit(void){ return; } FMC_Initialized = 1; - RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; - - /** Initializes the peripherals clock - */ - PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_FMC; - PeriphClkInitStruct.FmcClockSelection = RCC_FMCCLKSOURCE_PLL; - if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) - { - Error_Handler(); - } /* Peripheral clock enable */ __HAL_RCC_FMC_CLK_ENABLE(); diff --git a/Core/Src/main.c b/Core/Src/main.c index 574bba8..9c58861 100755 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -29,6 +29,7 @@ /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "cs4272.h" +#include "w9825g6kh6.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ @@ -74,7 +75,7 @@ int main(void) /* USER CODE BEGIN 1 */ - // disabled by the boot loader + /* disabled by the boot loader */ __enable_irq(); /* USER CODE END 1 */ @@ -119,6 +120,9 @@ int main(void) //MX_QUADSPI_Init(); /* USER CODE BEGIN 2 */ + FMC_Init(); + SDRAM_Test(); + __HAL_RCC_SAI1_CLK_ENABLE(); __HAL_SAI_ENABLE(&hsai_BlockA1); @@ -207,10 +211,8 @@ void SystemClock_Config(void) } } -/** - * @brief Peripherals Common Clock Configuration - * @retval None - */ +/* USER CODE BEGIN 4 */ + void PeriphCommonClock_Config(void) { RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; @@ -233,8 +235,6 @@ void PeriphCommonClock_Config(void) } } -/* USER CODE BEGIN 4 */ - /* USER CODE END 4 */ /* MPU Configuration */ @@ -287,6 +287,13 @@ void Error_Handler(void) /* User can add his own implementation to report the HAL error return state */ while (1) { + HAL_GPIO_WritePin(GPIOC, GPIO_PIN_12, GPIO_PIN_SET); + + HAL_Delay(500); + + HAL_GPIO_WritePin(GPIOC, GPIO_PIN_12, GPIO_PIN_RESET); + + HAL_Delay(500); } /* USER CODE END Error_Handler_Debug */ } diff --git a/Core/Src/quadspi.c b/Core/Src/quadspi.c index 8572981..e5346af 100755 --- a/Core/Src/quadspi.c +++ b/Core/Src/quadspi.c @@ -42,7 +42,7 @@ void MX_QUADSPI_Init(void) hqspi.Init.FifoThreshold = 4; hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE; hqspi.Init.FlashSize = 23; - hqspi.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_1_CYCLE; + hqspi.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_2_CYCLE; hqspi.Init.ClockMode = QSPI_CLOCK_MODE_0; hqspi.Init.FlashID = QSPI_FLASH_ID_1; hqspi.Init.DualFlash = QSPI_DUALFLASH_DISABLE; @@ -60,30 +60,11 @@ void HAL_QSPI_MspInit(QSPI_HandleTypeDef* qspiHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; - RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; if(qspiHandle->Instance==QUADSPI) { /* USER CODE BEGIN QUADSPI_MspInit 0 */ /* USER CODE END QUADSPI_MspInit 0 */ - - /** Initializes the peripherals clock - */ - PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_QSPI; - PeriphClkInitStruct.PLL2.PLL2M = 2; - PeriphClkInitStruct.PLL2.PLL2N = 16; - PeriphClkInitStruct.PLL2.PLL2P = 2; - PeriphClkInitStruct.PLL2.PLL2Q = 2; - PeriphClkInitStruct.PLL2.PLL2R = 1; - PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_3; - PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE; - PeriphClkInitStruct.PLL2.PLL2FRACN = 0; - PeriphClkInitStruct.QspiClockSelection = RCC_QSPICLKSOURCE_PLL2; - if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) - { - Error_Handler(); - } - /* QUADSPI clock enable */ __HAL_RCC_QSPI_CLK_ENABLE(); @@ -100,21 +81,21 @@ void HAL_QSPI_MspInit(QSPI_HandleTypeDef* qspiHandle) GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI; HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI; HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_6; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI; HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); diff --git a/Core/Src/sai.c b/Core/Src/sai.c index 9601fc8..b91cd1f 100755 --- a/Core/Src/sai.c +++ b/Core/Src/sai.c @@ -120,7 +120,7 @@ void HAL_SAI_MspInit(SAI_HandleTypeDef* saiHandle) hdma_sai1_a.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; hdma_sai1_a.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; hdma_sai1_a.Init.Mode = DMA_CIRCULAR; - hdma_sai1_a.Init.Priority = DMA_PRIORITY_HIGH; + hdma_sai1_a.Init.Priority = DMA_PRIORITY_VERY_HIGH; hdma_sai1_a.Init.FIFOMode = DMA_FIFOMODE_DISABLE; if (HAL_DMA_Init(&hdma_sai1_a) != HAL_OK) { @@ -161,7 +161,7 @@ void HAL_SAI_MspInit(SAI_HandleTypeDef* saiHandle) hdma_sai1_b.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; hdma_sai1_b.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; hdma_sai1_b.Init.Mode = DMA_CIRCULAR; - hdma_sai1_b.Init.Priority = DMA_PRIORITY_HIGH; + hdma_sai1_b.Init.Priority = DMA_PRIORITY_VERY_HIGH; hdma_sai1_b.Init.FIFOMode = DMA_FIFOMODE_DISABLE; if (HAL_DMA_Init(&hdma_sai1_b) != HAL_OK) { diff --git a/Core/Src/system_stm32h7xx.c b/Core/Src/system_stm32h7xx.c index 9c59735..fcd79ca 100755 --- a/Core/Src/system_stm32h7xx.c +++ b/Core/Src/system_stm32h7xx.c @@ -311,7 +311,6 @@ void SystemInit (void) // //#endif /*DUAL_CORE && CORE_CM4*/ - RCC->CFGR = 0x00000000; SCB->VTOR = 0x90000000; } diff --git a/Core/Src/w9825g6kh6.c b/Core/Src/w9825g6kh6.c new file mode 100755 index 0000000..56c5fde --- /dev/null +++ b/Core/Src/w9825g6kh6.c @@ -0,0 +1,64 @@ +/* + * w9825g6kh6.c + * + * Created on: Aug 18, 2026 + * Author: ozpv + */ + +#include "fmc.h" +#include "w9825g6kh6.h" + +void FMC_Init(void) { + /* USER CODE BEGIN FMC_Init 2 */ + + FMC_SDRAM_CommandTypeDef Command; + + /* Step 1 and Step 2 already done in HAL_SDRAM_Init() */ + + /* Step 3: Configure a clock configuration enable command */ + Command.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE; /* Set MODE bits to "001" */ + Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; /* configure the Target Bank bits */ + Command.AutoRefreshNumber = 1; + Command.ModeRegisterDefinition = 0; + HAL_SDRAM_SendCommand(&hsdram1, &Command, 0xfff); + + /* Step 4: Insert 100 us minimum delay - Min HAL Delay is 1ms */ + HAL_Delay(1); + + /* Step 5: Configure a PALL (precharge all) command */ + Command.CommandMode = FMC_SDRAM_CMD_PALL; /* Set MODE bits to "010" */ + HAL_SDRAM_SendCommand(&hsdram1, &Command, 0xfff); + + /* Step 6: Configure an Auto Refresh command */ + Command.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE; /* Set MODE bits to "011" */ + Command.AutoRefreshNumber = 2; + HAL_SDRAM_SendCommand(&hsdram1, &Command, 0xfff); + + /* Step 7: Program the external memory mode register */ + Command.CommandMode = FMC_SDRAM_CMD_LOAD_MODE;/*set the MODE bits to "100" */ + Command.ModeRegisterDefinition = (uint32_t)0 | 0<<3 | 2<<4 | 0<<7 | 1<<9; + HAL_SDRAM_SendCommand(&hsdram1, &Command, 0xfff); + + /* Step 8: Set the refresh rate counter - refer to section SDRAM refresh timer register in RM0455 */ + /* Set the device refresh rate + * COUNT = [(SDRAM self refresh time / number of row) x SDRAM CLK] – 20 + = [(64ms/8192) * 100MHz] - 20 = floor(1562.5 - 20) = 761 */ + HAL_SDRAM_ProgramRefreshRate(&hsdram1, 761); + + /* USER CODE END FMC_Init 2 */ +} + +/* a test using address dependent values */ +void SDRAM_Test(void) { + volatile uint32_t *sdram = (volatile uint32_t *)SDRAM_BASE; + + for (uint32_t i = 0; i < SDRAM_SIZE / sizeof(uint32_t); ++i) { + sdram[i] = i ^ 0xDEADDEAD; + } + + for (uint32_t i = 0; i < SDRAM_SIZE / sizeof(uint32_t); ++i) { + if (sdram[i] != (i ^ 0xDEADDEAD)) { + Error_Handler(); + } + } +} diff --git a/README.md b/README.md index 86ddc8a..7f3df55 100755 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ Note: Application will not work and get stuck in Reset_Handler with XIP when compiled with no optimization. Ensure you use -Os or -O2. QUADSPI should not be reinitalized. Only configure it in STM32CubeMX so the clocks are the same and comment out MX_QUADSPI_Init. +Comment out PeriphCommonClock_Config when regenerating. \ No newline at end of file diff --git a/STM32H750ZBTX_FLASH.ld b/STM32H750ZBTX_FLASH.ld index 972ca74..a9622d8 100755 --- a/STM32H750ZBTX_FLASH.ld +++ b/STM32H750ZBTX_FLASH.ld @@ -44,6 +44,7 @@ _Min_Stack_Size = 0x400; /* required amount of stack */ MEMORY { FLASH (rx) : ORIGIN = 0x90000000, LENGTH = 16M + SDRAM (xrw) : ORIGIN = 0xC0000000, LENGTH = 32M DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K @@ -176,7 +177,7 @@ SECTIONS .ARM.attributes 0 : { *(.ARM.attributes) } - .audio_buffers (NOLOAD): + .audio_buffers (NOLOAD) : { . = ALIGN(32); _saudio_buffers = .; @@ -185,6 +186,14 @@ SECTIONS . = ALIGN(32); _eaudio_buffers = .; } >RAM_D1 + + .sdram (NOLOAD) : + { + . = ALIGN(4); + *(.sdram) + *(.sdram*) + . = ALIGN(4); + } >SDRAM } diff --git a/audio.ioc b/audio.ioc index 68685db..d69b35c 100755 --- a/audio.ioc +++ b/audio.ioc @@ -35,7 +35,7 @@ Dma.SAI1_A.1.Mode=DMA_CIRCULAR Dma.SAI1_A.1.PeriphDataAlignment=DMA_PDATAALIGN_WORD Dma.SAI1_A.1.PeriphInc=DMA_PINC_DISABLE Dma.SAI1_A.1.Polarity=HAL_DMAMUX_REQ_GEN_RISING -Dma.SAI1_A.1.Priority=DMA_PRIORITY_HIGH +Dma.SAI1_A.1.Priority=DMA_PRIORITY_VERY_HIGH Dma.SAI1_A.1.RequestNumber=1 Dma.SAI1_A.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber Dma.SAI1_A.1.SignalID=NONE @@ -53,7 +53,7 @@ Dma.SAI1_B.0.Mode=DMA_CIRCULAR Dma.SAI1_B.0.PeriphDataAlignment=DMA_PDATAALIGN_WORD Dma.SAI1_B.0.PeriphInc=DMA_PINC_DISABLE Dma.SAI1_B.0.Polarity=HAL_DMAMUX_REQ_GEN_RISING -Dma.SAI1_B.0.Priority=DMA_PRIORITY_HIGH +Dma.SAI1_B.0.Priority=DMA_PRIORITY_VERY_HIGH Dma.SAI1_B.0.RequestNumber=1 Dma.SAI1_B.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber Dma.SAI1_B.0.SignalID=NONE @@ -63,18 +63,22 @@ Dma.SAI1_B.0.SyncRequestNumber=1 Dma.SAI1_B.0.SyncSignalID=NONE FMC.CASLatency1=FMC_SDRAM_CAS_LATENCY_2 FMC.ColumnBitsNumber1=FMC_SDRAM_COLUMN_BITS_NUM_9 -FMC.ExitSelfRefreshDelay1=12 -FMC.IPParameters=ColumnBitsNumber1,CASLatency1,SDClockPeriod1,SDClockPeriod2,ReadBurst1,ReadBurst2,ReadPipeDelay1,ExitSelfRefreshDelay1,RCDDelay1,RPDelay1,RPDelay2,RowCycleDelay1,RowCycleDelay2 -FMC.RCDDelay1=3 -FMC.RPDelay1=3 -FMC.RPDelay2=3 +FMC.ExitSelfRefreshDelay1=8 +FMC.IPParameters=ColumnBitsNumber1,CASLatency1,SDClockPeriod1,SDClockPeriod2,ReadBurst1,ReadBurst2,ReadPipeDelay1,ExitSelfRefreshDelay1,RCDDelay1,RPDelay1,RPDelay2,RowCycleDelay1,RowCycleDelay2,LoadToActiveDelay1,SelfRefreshTime1,WriteRecoveryTime1,ReadPipeDelay2 +FMC.LoadToActiveDelay1=2 +FMC.RCDDelay1=2 +FMC.RPDelay1=2 +FMC.RPDelay2=2 FMC.ReadBurst1=FMC_SDRAM_RBURST_ENABLE FMC.ReadBurst2=FMC_SDRAM_RBURST_ENABLE -FMC.ReadPipeDelay1=FMC_SDRAM_RPIPE_DELAY_0 -FMC.RowCycleDelay1=10 -FMC.RowCycleDelay2=10 +FMC.ReadPipeDelay1=FMC_SDRAM_RPIPE_DELAY_2 +FMC.ReadPipeDelay2=FMC_SDRAM_RPIPE_DELAY_2 +FMC.RowCycleDelay1=6 +FMC.RowCycleDelay2=6 FMC.SDClockPeriod1=FMC_SDRAM_CLOCK_PERIOD_2 FMC.SDClockPeriod2=FMC_SDRAM_CLOCK_PERIOD_2 +FMC.SelfRefreshTime1=5 +FMC.WriteRecoveryTime1=3 File.Version=6 GPIO.groupedBy=Group By Peripherals I2C4.I2C_Speed_Mode=I2C_Standard @@ -365,6 +369,8 @@ PE8.Signal=FMC_D5_DA5 PE9.Signal=FMC_D6_DA6 PF0.Signal=FMC_A0 PF1.Signal=FMC_A1 +PF10.GPIOParameters=GPIO_Speed +PF10.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH PF10.Mode=Single Bank 1 PF10.Signal=QUADSPI_CLK PF11.Signal=FMC_SDNRAS @@ -376,12 +382,20 @@ PF2.Signal=FMC_A2 PF3.Signal=FMC_A3 PF4.Signal=FMC_A4 PF5.Signal=FMC_A5 +PF6.GPIOParameters=GPIO_Speed +PF6.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH PF6.Mode=Single Bank 1 PF6.Signal=QUADSPI_BK1_IO3 +PF7.GPIOParameters=GPIO_Speed +PF7.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH PF7.Mode=Single Bank 1 PF7.Signal=QUADSPI_BK1_IO2 +PF8.GPIOParameters=GPIO_Speed +PF8.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH PF8.Mode=Single Bank 1 PF8.Signal=QUADSPI_BK1_IO0 +PF9.GPIOParameters=GPIO_Speed +PF9.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH PF9.Mode=Single Bank 1 PF9.Signal=QUADSPI_BK1_IO1 PG0.Signal=FMC_A10 @@ -390,6 +404,8 @@ PG15.Signal=FMC_SDNCAS PG2.Signal=FMC_A12 PG4.Signal=FMC_A14_BA0 PG5.Signal=FMC_A15_BA1 +PG6.GPIOParameters=GPIO_Speed +PG6.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH PG6.Mode=Single Bank 1 PG6.Signal=QUADSPI_BK1_NCS PG7.GPIOParameters=GPIO_Label @@ -433,10 +449,11 @@ ProjectManager.UAScriptAfterPath= ProjectManager.UAScriptBeforePath= ProjectManager.UnderRoot=true ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_FMC_Init-FMC-false-HAL-true,5-MX_I2C4_Init-I2C4-false-HAL-true,6-MX_SAI1_Init-SAI1-false-HAL-true,7-MX_USB_DEVICE_Init-USB_DEVICE-false-HAL-false,8-MX_QUADSPI_Init-QUADSPI-false-HAL-true,0-MX_CORTEX_M7_Init-CORTEX_M7-false-HAL-true +QUADSPI.ChipSelectHighTime=QSPI_CS_HIGH_TIME_2_CYCLE QUADSPI.ClockPrescaler=2 QUADSPI.FifoThreshold=4 QUADSPI.FlashSize=23 -QUADSPI.IPParameters=ClockPrescaler,FifoThreshold,SampleShifting,FlashSize +QUADSPI.IPParameters=ClockPrescaler,FifoThreshold,SampleShifting,FlashSize,ChipSelectHighTime QUADSPI.SampleShifting=QSPI_SAMPLE_SHIFTING_HALFCYCLE RCC.ADCFreq_Value=100000000 RCC.AHB12Freq_Value=240000000 @@ -478,8 +495,8 @@ RCC.DIVR2Freq_Value=200000000 RCC.DIVR3=30 RCC.DIVR3Freq_Value=8192016.6015625 RCC.FDCANFreq_Value=64000000 -RCC.FMCCLockSelection=RCC_FMCCLKSOURCE_PLL -RCC.FMCFreq_Value=64000000 +RCC.FMCCLockSelection=RCC_FMCCLKSOURCE_PLL2 +RCC.FMCFreq_Value=200000000 RCC.FamilyName=M RCC.HCLK3ClockFreq_Value=240000000 RCC.HCLKFreq_Value=240000000 -- cgit v1.2.3