summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorozpv <39195175+ozpv@users.noreply.github.com>2026-08-19 21:34:09 -0500
committerozpv <39195175+ozpv@users.noreply.github.com>2026-08-19 21:34:09 -0500
commit0cb345ed5ccbe786d0a7e7e2de740c0a07b82770 (patch)
tree89682cd81419b138c5657cfa2dae797c81f8ea33
parent0c79f390c81f56fd087c2fffb07b373594119668 (diff)
sdram and ringmod effect
-rwxr-xr-xCore/Inc/Effects/ringmod.h16
-rwxr-xr-xCore/Inc/cs4272.h12
-rwxr-xr-xCore/Inc/w9825g6kh6.h17
-rwxr-xr-xCore/Src/Effects/ringmod.c37
-rwxr-xr-xCore/Src/cs4272.c122
-rwxr-xr-xCore/Src/fmc.c26
-rwxr-xr-xCore/Src/main.c21
-rwxr-xr-xCore/Src/quadspi.c27
-rwxr-xr-xCore/Src/sai.c4
-rwxr-xr-xCore/Src/system_stm32h7xx.c1
-rwxr-xr-xCore/Src/w9825g6kh6.c64
-rwxr-xr-xREADME.md1
-rwxr-xr-xSTM32H750ZBTX_FLASH.ld11
-rwxr-xr-xaudio.ioc43
14 files changed, 281 insertions, 121 deletions
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 <stdint.h>
+#include <stddef.h>
+
+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 <stdint.h>
+
+/* 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 <math.h>
+
+/* 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