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 +++++++++++++++++++++++ 11 files changed, 240 insertions(+), 107 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 (limited to 'Core') 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(); + } + } +} -- cgit v1.2.3