init
This commit is contained in:
commit
2c2202e60d
2491 files changed
+1295990
No files matched your search
@@ -0,0 +1,155 @@
|
||||
#include "audio_analysis.h"
|
||||
#include "arm_math.h"
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#define FFT_SIZE AUDIO_ANALYSIS_FFT_SIZE
|
||||
#define NUM_BINS AUDIO_ANALYSIS_NUM_BINS
|
||||
|
||||
/* --- Capture en double buffer (ping-pong), ecrite depuis le chemin audio temps
|
||||
* reel, lue depuis la tache IHM. Un seul ecrivain, un seul lecteur : pas de verrou
|
||||
* necessaire, meme principe que la FIFO audio principale. --- */
|
||||
static float g_capture_buf[2][FFT_SIZE];
|
||||
static uint32_t g_capture_fill_idx = 0;
|
||||
static uint8_t g_capture_write_buf = 0;
|
||||
static volatile uint8_t g_capture_ready_buf = 0xFFU; /* 0xFF = aucun buffer complet en attente */
|
||||
|
||||
static bool g_analysis_enabled = false;
|
||||
|
||||
/* --- Fenetre precalculee (a l'init uniquement, jamais recalculee en boucle) --- */
|
||||
static float g_hann_window[FFT_SIZE];
|
||||
|
||||
/* --- FFT reelle CMSIS-DSP : instance initialisee une fois, buffers de travail --- */
|
||||
static arm_rfft_fast_instance_f32 g_rfft_instance;
|
||||
static float g_fft_work[FFT_SIZE]; /* echantillons fenetres ; ecrase (scratch) par arm_rfft_fast_f32 */
|
||||
static float g_fft_out[FFT_SIZE]; /* spectre complexe empaquete, format CMSIS (voir plus bas) */
|
||||
|
||||
static float g_magnitudes_db[NUM_BINS]; /* seule la moitie 0..Fe/2 est conservee */
|
||||
static float g_peak_freq_hz = 0.0f;
|
||||
|
||||
static void AudioAnalysis_BuildTables(void)
|
||||
{
|
||||
for (uint32_t i = 0; i < FFT_SIZE; i++)
|
||||
{
|
||||
/* Fenetre de Hann : reduit les fuites spectrales dues a la troncature du bloc. */
|
||||
g_hann_window[i] = 0.5f - 0.5f * cosf(2.0f * (float)M_PI * (float)i / (float)(FFT_SIZE - 1U));
|
||||
}
|
||||
}
|
||||
|
||||
void AudioAnalysis_Init(void)
|
||||
{
|
||||
memset(g_capture_buf, 0, sizeof(g_capture_buf));
|
||||
g_capture_fill_idx = 0;
|
||||
g_capture_write_buf = 0;
|
||||
g_capture_ready_buf = 0xFFU;
|
||||
g_analysis_enabled = false;
|
||||
|
||||
memset(g_magnitudes_db, 0, sizeof(g_magnitudes_db));
|
||||
|
||||
AudioAnalysis_BuildTables();
|
||||
arm_rfft_fast_init_f32(&g_rfft_instance, FFT_SIZE);
|
||||
}
|
||||
|
||||
void AudioAnalysis_PushSample(float sample)
|
||||
{
|
||||
if (!g_analysis_enabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_capture_buf[g_capture_write_buf][g_capture_fill_idx] = sample;
|
||||
g_capture_fill_idx++;
|
||||
|
||||
if (g_capture_fill_idx >= FFT_SIZE)
|
||||
{
|
||||
g_capture_fill_idx = 0;
|
||||
g_capture_ready_buf = g_capture_write_buf;
|
||||
g_capture_write_buf = 1U - g_capture_write_buf;
|
||||
}
|
||||
}
|
||||
|
||||
bool AudioAnalysis_Update(void)
|
||||
{
|
||||
if (!g_analysis_enabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t ready = g_capture_ready_buf;
|
||||
if (ready == 0xFFU)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
g_capture_ready_buf = 0xFFU;
|
||||
|
||||
for (uint32_t i = 0; i < FFT_SIZE; i++)
|
||||
{
|
||||
g_fft_work[i] = g_capture_buf[ready][i] * g_hann_window[i];
|
||||
}
|
||||
|
||||
/* arm_rfft_fast_f32 (forward, ifftFlag=0) empaquete le spectre d'un signal reel
|
||||
* en NUM_BINS paires {re,im}, sauf la premiere qui contient les deux seules
|
||||
* valeurs reelles (DC et Nyquist) : g_fft_out[0]=X[0] (DC), g_fft_out[1]=X[N/2]
|
||||
* (Nyquist, non utilise ici). Pour k=1..NUM_BINS-1 : re=g_fft_out[2k], im=g_fft_out[2k+1]. */
|
||||
arm_rfft_fast_f32(&g_rfft_instance, g_fft_work, g_fft_out, 0);
|
||||
|
||||
/* Magnitude normalisee (une sinusoide plein-echelle donne ~0dB) puis convertie
|
||||
* en dB, avec un plancher pour eviter log(0). Destine a un affichage visuel,
|
||||
* pas a une mesure calibree. Seule la moitie 0..Fe/2 du spectre est conservee :
|
||||
* le spectre d'un signal reel est symetrique, la seconde moitie n'apporte rien. */
|
||||
/* Recherche du pic en meme temps que le calcul des magnitudes. Le bin 0 (continu,
|
||||
* 0Hz) est ignore : une composante DC ne doit pas etre rapportee comme "frequence
|
||||
* dominante". */
|
||||
uint32_t peak_bin = 1U;
|
||||
float peak_mag = 0.0f;
|
||||
|
||||
for (uint32_t i = 0; i < NUM_BINS; i++)
|
||||
{
|
||||
float re = (i == 0U) ? g_fft_out[0] : g_fft_out[2U * i];
|
||||
float im = (i == 0U) ? 0.0f : g_fft_out[2U * i + 1U];
|
||||
float mag = sqrtf(re * re + im * im) / ((float)FFT_SIZE / 4.0f);
|
||||
|
||||
if (i >= 1U && mag > peak_mag)
|
||||
{
|
||||
peak_mag = mag;
|
||||
peak_bin = i;
|
||||
}
|
||||
|
||||
if (mag < 1.0e-6f)
|
||||
{
|
||||
mag = 1.0e-6f;
|
||||
}
|
||||
g_magnitudes_db[i] = 20.0f * log10f(mag);
|
||||
}
|
||||
|
||||
g_peak_freq_hz = (float)peak_bin * (float)AUDIO_ANALYSIS_SAMPLE_RATE_HZ / (float)FFT_SIZE;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const float *AudioAnalysis_GetMagnitudesDb(void)
|
||||
{
|
||||
return g_magnitudes_db;
|
||||
}
|
||||
|
||||
float AudioAnalysis_GetPeakFrequencyHz(void)
|
||||
{
|
||||
return g_peak_freq_hz;
|
||||
}
|
||||
|
||||
void AudioAnalysis_SetEnabled(bool enabled)
|
||||
{
|
||||
if (enabled && !g_analysis_enabled)
|
||||
{
|
||||
/* Redemarre une capture propre a chaque activation. */
|
||||
g_capture_fill_idx = 0;
|
||||
g_capture_write_buf = 0;
|
||||
g_capture_ready_buf = 0xFFU;
|
||||
}
|
||||
g_analysis_enabled = enabled;
|
||||
}
|
||||
|
||||
bool AudioAnalysis_IsEnabled(void)
|
||||
{
|
||||
return g_analysis_enabled;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
#include "audio_effects.h"
|
||||
|
||||
static AudioEffectsParams g_params;
|
||||
|
||||
static FxOctaverState g_octaverState;
|
||||
static FxEqualizerState g_eqState;
|
||||
static FxOverdriveState g_overdriveState;
|
||||
static FxSaturationState g_saturationState;
|
||||
static FxEchoState g_echoState;
|
||||
static FxReverbState g_reverbState;
|
||||
|
||||
void AudioEffects_Init(void)
|
||||
{
|
||||
g_params.audio_on_off = false;
|
||||
g_params.master_volume = 0.0f;
|
||||
FxOctaver_Init(&g_octaverState, &g_params.octaver);
|
||||
FxEqualizer_Init(&g_eqState, &g_params.equalizer);
|
||||
FxOverdrive_Init(&g_overdriveState, &g_params.overdrive);
|
||||
FxSaturation_Init(&g_saturationState, &g_params.saturation);
|
||||
FxEcho_Init(&g_echoState, &g_params.echo);
|
||||
FxReverb_Init(&g_reverbState, &g_params.reverb);
|
||||
}
|
||||
|
||||
float AudioEffects_Process(float input)
|
||||
{
|
||||
float sample = input;
|
||||
sample = FxOctaver_Process(&g_octaverState, &g_params.octaver, sample);
|
||||
sample = FxEqualizer_Process(&g_eqState, &g_params.equalizer, sample);
|
||||
sample = FxOverdrive_Process(&g_overdriveState, &g_params.overdrive, sample);
|
||||
sample = FxSaturation_Process(&g_saturationState, &g_params.saturation, sample);
|
||||
sample = FxEcho_Process(&g_echoState, &g_params.echo, sample);
|
||||
sample = FxReverb_Process(&g_reverbState, &g_params.reverb, sample);
|
||||
|
||||
/* Coupure de sortie : les effets continuent de tourner (pas de discontinuite
|
||||
* d'etat au reactivation), seule la sortie audible est reduite au silence. */
|
||||
if (!g_params.audio_on_off)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
return sample * g_params.master_volume;
|
||||
}
|
||||
|
||||
AudioEffectsParams *AudioEffects_GetParams(void)
|
||||
{
|
||||
return &g_params;
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
#include "audio_looper.h"
|
||||
|
||||
/* 5s a 48kHz en float = 937.5 Ko : ne rentre pas en RAM interne, place en EXTRAM (meme
|
||||
* section/region que le framebuffer TouchGFX, cf. AudioLooperBuffer dans le script de
|
||||
* link). Accede uniquement par ce coeur (pas de DMA dessus) : pas de probleme de
|
||||
* coherence de cache a gerer explicitement. */
|
||||
__attribute__((section("AudioLooperBuffer")))
|
||||
static float g_buffer[AUDIO_LOOPER_MAX_SAMPLES];
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LOOPER_IDLE = 0,
|
||||
LOOPER_RECORDING,
|
||||
LOOPER_PLAYBACK
|
||||
} LooperState;
|
||||
|
||||
/* g_state est ecrit depuis la tache IHM (Start/Stop) et lu/ecrit depuis le contexte
|
||||
* audio temps reel (Process) : meme principe "un seul ecrivain a la fois par variable,
|
||||
* volatile pour le flag d'etat partage" que le reste du projet (cf. audio_analysis.c). */
|
||||
static volatile LooperState g_state = LOOPER_IDLE;
|
||||
static uint32_t g_record_len = 0; /* nb d'echantillons valides captures, fige au relachement */
|
||||
static uint32_t g_write_idx = 0; /* ecrit uniquement depuis Process() en RECORDING */
|
||||
static float g_read_pos = 0.0f; /* lu/ecrit uniquement depuis Process() en PLAYBACK */
|
||||
|
||||
void AudioLooper_Init(void)
|
||||
{
|
||||
g_state = LOOPER_IDLE;
|
||||
g_record_len = 0;
|
||||
g_write_idx = 0;
|
||||
g_read_pos = 0.0f;
|
||||
}
|
||||
|
||||
void AudioLooper_StartRecording(void)
|
||||
{
|
||||
g_write_idx = 0;
|
||||
g_state = LOOPER_RECORDING;
|
||||
}
|
||||
|
||||
void AudioLooper_StopRecordingAndPlay(void)
|
||||
{
|
||||
if (g_state != LOOPER_RECORDING)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_record_len = g_write_idx;
|
||||
g_read_pos = 0.0f;
|
||||
g_state = (g_record_len > 0U) ? LOOPER_PLAYBACK : LOOPER_IDLE;
|
||||
}
|
||||
|
||||
float AudioLooper_Process(float sample_in)
|
||||
{
|
||||
switch (g_state)
|
||||
{
|
||||
case LOOPER_RECORDING:
|
||||
if (g_write_idx < AUDIO_LOOPER_MAX_SAMPLES)
|
||||
{
|
||||
g_buffer[g_write_idx++] = sample_in;
|
||||
}
|
||||
/* Buffer plein (5s atteintes) : on cesse de capturer mais on reste en
|
||||
* enregistrement, l'ecoute live continue jusqu'au relachement du bouton. */
|
||||
return sample_in;
|
||||
|
||||
case LOOPER_PLAYBACK:
|
||||
{
|
||||
uint32_t idx0 = (uint32_t)g_read_pos;
|
||||
if (idx0 >= g_record_len - 1U)
|
||||
{
|
||||
g_state = LOOPER_IDLE;
|
||||
return sample_in;
|
||||
}
|
||||
|
||||
/* Interpolation lineaire entre les deux echantillons encadrant la position de
|
||||
* lecture fractionnaire : necessaire car AUDIO_LOOPER_PLAYBACK_RATIO avance le
|
||||
* pointeur de lecture plus vite qu'un pas entier. */
|
||||
float frac = g_read_pos - (float)idx0;
|
||||
float s0 = g_buffer[idx0];
|
||||
float s1 = g_buffer[idx0 + 1U];
|
||||
float out = s0 + (s1 - s0) * frac;
|
||||
|
||||
g_read_pos += AUDIO_LOOPER_PLAYBACK_RATIO;
|
||||
return out;
|
||||
}
|
||||
|
||||
case LOOPER_IDLE:
|
||||
default:
|
||||
return sample_in;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* File Name : freertos.c
|
||||
* Description : Code for freertos applications
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2023 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "main.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PTD */
|
||||
|
||||
/* USER CODE END PTD */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PD */
|
||||
|
||||
/* USER CODE END PD */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PM */
|
||||
|
||||
/* USER CODE END PM */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Variables */
|
||||
|
||||
/* USER CODE END Variables */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* USER CODE BEGIN FunctionPrototypes */
|
||||
extern portBASE_TYPE IdleTaskHook(void* p);
|
||||
/* USER CODE END FunctionPrototypes */
|
||||
|
||||
/* Hook prototypes */
|
||||
void vApplicationIdleHook(void);
|
||||
|
||||
/* USER CODE BEGIN 2 */
|
||||
void vApplicationIdleHook( void )
|
||||
{
|
||||
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
|
||||
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
|
||||
task. It is essential that code added to this hook function never attempts
|
||||
to block in any way (for example, call xQueueReceive() with a block time
|
||||
specified, or call vTaskDelay()). If the application makes use of the
|
||||
vTaskDelete() API function (as this demo application does) then it is also
|
||||
important that vApplicationIdleHook() is permitted to return to its calling
|
||||
function, because it is the responsibility of the idle task to clean up
|
||||
memory allocated by the kernel to any task that has since been deleted. */
|
||||
|
||||
vTaskSetApplicationTaskTag(NULL, IdleTaskHook);
|
||||
}
|
||||
/* USER CODE END 2 */
|
||||
|
||||
/* Private application code --------------------------------------------------*/
|
||||
/* USER CODE BEGIN Application */
|
||||
|
||||
/* USER CODE END Application */
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
#include "fx_echo.h"
|
||||
#include <string.h>
|
||||
|
||||
void FxEcho_Init(FxEchoState *state, FxEchoParams *params)
|
||||
{
|
||||
memset(state->buffer, 0, sizeof(state->buffer));
|
||||
state->write_idx = 0;
|
||||
|
||||
params->enabled = false;
|
||||
params->delay_ms = 300.0f;
|
||||
params->feedback = 0.35f;
|
||||
params->mix = 0.3f;
|
||||
}
|
||||
|
||||
float FxEcho_Process(FxEchoState *state, const FxEchoParams *params, float input)
|
||||
{
|
||||
if (!params->enabled)
|
||||
{
|
||||
return input;
|
||||
}
|
||||
|
||||
uint32_t delay_samples = (uint32_t)(params->delay_ms * (FX_ECHO_SAMPLE_RATE / 1000.0f));
|
||||
if (delay_samples >= FX_ECHO_BUFFER_SIZE)
|
||||
{
|
||||
delay_samples = FX_ECHO_BUFFER_SIZE - 1U;
|
||||
}
|
||||
|
||||
uint32_t read_idx = (state->write_idx + FX_ECHO_BUFFER_SIZE - delay_samples) % FX_ECHO_BUFFER_SIZE;
|
||||
float delayed = (float)state->buffer[read_idx] / 32768.0f;
|
||||
|
||||
float to_store = input + delayed * params->feedback;
|
||||
if (to_store > 1.0f) to_store = 1.0f;
|
||||
if (to_store < -1.0f) to_store = -1.0f;
|
||||
state->buffer[state->write_idx] = (int16_t)(to_store * 32767.0f);
|
||||
state->write_idx = (state->write_idx + 1U) % FX_ECHO_BUFFER_SIZE;
|
||||
|
||||
return input * (1.0f - params->mix) + delayed * params->mix;
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
#include "fx_equalizer.h"
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define FX_EQ_SAMPLE_RATE 48000.0f
|
||||
|
||||
static const float fx_eq_default_freqs[FX_EQ_NUM_BANDS] =
|
||||
{
|
||||
31.0f, 62.0f, 125.0f, 250.0f, 500.0f, 1000.0f, 2000.0f, 4000.0f, 8000.0f, 16000.0f
|
||||
};
|
||||
|
||||
void FxEqualizer_Init(FxEqualizerState *state, FxEqualizerParams *params)
|
||||
{
|
||||
params->enabled = true;
|
||||
for (uint32_t i = 0; i < FX_EQ_NUM_BANDS; i++)
|
||||
{
|
||||
params->bands[i].freq_hz = fx_eq_default_freqs[i];
|
||||
params->bands[i].gain_db = 0.0f;
|
||||
params->bands[i].q = 1.0f;
|
||||
|
||||
state->band_state[i].last_freq_hz = -1.0f; /* force le calcul des coefficients au 1er sample */
|
||||
state->band_state[i].last_gain_db = 0.0f;
|
||||
state->band_state[i].last_q = 0.0f;
|
||||
state->x1[i] = state->x2[i] = state->y1[i] = state->y2[i] = 0.0f;
|
||||
}
|
||||
|
||||
// Pour couper les basses par defaukt et éviter les larsens :
|
||||
params->bands[0].gain_db = -15.0f;
|
||||
params->bands[1].gain_db = -10.0f;
|
||||
params->bands[2].gain_db = -2.5f;
|
||||
}
|
||||
|
||||
/* Filtre "peaking EQ" (cloche), formule de l'Audio EQ Cookbook (Robert Bristow-Johnson). */
|
||||
static void FxEq_ComputeBandCoeffs(FxEqBandState *bs, const FxEqBand *band)
|
||||
{
|
||||
float A = powf(10.0f, band->gain_db / 40.0f);
|
||||
float w0 = 2.0f * (float)M_PI * band->freq_hz / FX_EQ_SAMPLE_RATE;
|
||||
float alpha = sinf(w0) / (2.0f * band->q);
|
||||
float cosw0 = cosf(w0);
|
||||
|
||||
float a0 = 1.0f + alpha / A;
|
||||
bs->b0 = (1.0f + alpha * A) / a0;
|
||||
bs->b1 = (-2.0f * cosw0) / a0;
|
||||
bs->b2 = (1.0f - alpha * A) / a0;
|
||||
bs->a1 = (-2.0f * cosw0) / a0;
|
||||
bs->a2 = (1.0f - alpha / A) / a0;
|
||||
|
||||
bs->last_freq_hz = band->freq_hz;
|
||||
bs->last_gain_db = band->gain_db;
|
||||
bs->last_q = band->q;
|
||||
}
|
||||
|
||||
float FxEqualizer_Process(FxEqualizerState *state, const FxEqualizerParams *params, float input)
|
||||
{
|
||||
if (!params->enabled)
|
||||
{
|
||||
return input;
|
||||
}
|
||||
|
||||
float y = input;
|
||||
for (uint32_t i = 0; i < FX_EQ_NUM_BANDS; i++)
|
||||
{
|
||||
const FxEqBand *band = ¶ms->bands[i];
|
||||
FxEqBandState *bs = &state->band_state[i];
|
||||
|
||||
if (band->freq_hz != bs->last_freq_hz || band->gain_db != bs->last_gain_db || band->q != bs->last_q)
|
||||
{
|
||||
FxEq_ComputeBandCoeffs(bs, band);
|
||||
}
|
||||
|
||||
float x = y;
|
||||
y = bs->b0 * x + bs->b1 * state->x1[i] + bs->b2 * state->x2[i]
|
||||
- bs->a1 * state->y1[i] - bs->a2 * state->y2[i];
|
||||
|
||||
state->x2[i] = state->x1[i];
|
||||
state->x1[i] = x;
|
||||
state->y2[i] = state->y1[i];
|
||||
state->y1[i] = y;
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
#include "fx_octaver.h"
|
||||
#include <math.h>
|
||||
|
||||
#define FX_OCTAVER_BUFFER_MASK (FX_OCTAVER_BUFFER_SIZE - 1U)
|
||||
#define FX_OCTAVER_ENV_TABLE_SIZE 256U
|
||||
|
||||
/* Rapport de vitesse de lecture pour chaque voix : lire le buffer plus vite que
|
||||
* l'ecriture multiplie la frequence (octave au-dessus), plus lentement la divise
|
||||
* (octave en-dessous). */
|
||||
static const float fx_octaver_ratios[FX_OCTAVER_NUM_VOICES] =
|
||||
{
|
||||
0.25f, /* -2 octaves */
|
||||
0.5f, /* -1 octave */
|
||||
2.0f, /* +1 octave */
|
||||
4.0f /* +2 octaves */
|
||||
};
|
||||
|
||||
/* Fenetre de Hann tabulee (evite un cosf() par grain et par echantillon). */
|
||||
static float fx_octaver_env_table[FX_OCTAVER_ENV_TABLE_SIZE + 1U];
|
||||
static bool fx_octaver_env_table_ready = false;
|
||||
|
||||
static void FxOctaver_BuildEnvTable(void)
|
||||
{
|
||||
if (fx_octaver_env_table_ready)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (uint32_t i = 0; i <= FX_OCTAVER_ENV_TABLE_SIZE; i++)
|
||||
{
|
||||
float phase = (float)i / (float)FX_OCTAVER_ENV_TABLE_SIZE;
|
||||
fx_octaver_env_table[i] = 0.5f - 0.5f * cosf(2.0f * (float)M_PI * phase);
|
||||
}
|
||||
fx_octaver_env_table_ready = true;
|
||||
}
|
||||
|
||||
static inline float FxOctaver_EnvLookup(float phase)
|
||||
{
|
||||
float pos = phase * (float)FX_OCTAVER_ENV_TABLE_SIZE;
|
||||
uint32_t i0 = (uint32_t)pos;
|
||||
if (i0 >= FX_OCTAVER_ENV_TABLE_SIZE)
|
||||
{
|
||||
i0 = FX_OCTAVER_ENV_TABLE_SIZE - 1U;
|
||||
}
|
||||
float frac = pos - (float)i0;
|
||||
return fx_octaver_env_table[i0] * (1.0f - frac) + fx_octaver_env_table[i0 + 1U] * frac;
|
||||
}
|
||||
|
||||
static inline float FxOctaver_ReadInterpolated(const float *buffer, uint32_t write_idx, float delay)
|
||||
{
|
||||
/* write_idx grandit sans jamais etre replie (compteur perpetuel) ; le convertir
|
||||
* directement en float finirait par perdre en precision (un float ne represente
|
||||
* exactement les entiers que jusqu'a ~16.7 millions, soit quelques minutes a
|
||||
* 48kHz). On calcule donc la position de lecture uniquement a partir de l'index
|
||||
* DEJA REPLIE dans le buffer, qui reste toujours petit. */
|
||||
float write_pos = (float)(write_idx & FX_OCTAVER_BUFFER_MASK);
|
||||
float read_pos = write_pos - delay;
|
||||
while (read_pos < 0.0f)
|
||||
{
|
||||
read_pos += (float)FX_OCTAVER_BUFFER_SIZE;
|
||||
}
|
||||
uint32_t i0 = (uint32_t)read_pos & FX_OCTAVER_BUFFER_MASK;
|
||||
uint32_t i1 = (i0 + 1U) & FX_OCTAVER_BUFFER_MASK;
|
||||
float frac = read_pos - (float)(uint32_t)read_pos;
|
||||
return buffer[i0] * (1.0f - frac) + buffer[i1] * frac;
|
||||
}
|
||||
|
||||
/* Lecteur de grains a deux pointeurs en fondu croise : chaque pointeur avance
|
||||
* (ou recule) dans le buffer a une vitesse "ratio" differente de celle de
|
||||
* l'ecriture, ce qui change la hauteur percue. Les deux grains sont toujours
|
||||
* en opposition de phase exacte (decales d'un demi-grain a l'origine, et le
|
||||
* meme increment est applique aux deux avant chaque repli) : la fenetre de
|
||||
* Hann du second grain vaut donc toujours 1 moins celle du premier, ce qui
|
||||
* garantit un niveau de sortie constant pendant le fondu et evite un second
|
||||
* calcul de fenetre. */
|
||||
static float FxOctaver_ProcessVoice(FxOctaverVoiceState *vs, const float *buffer, uint32_t write_idx, float ratio)
|
||||
{
|
||||
float step = 1.0f - ratio;
|
||||
|
||||
for (uint32_t g = 0; g < 2U; g++)
|
||||
{
|
||||
vs->delay[g] += step;
|
||||
if (vs->delay[g] >= (float)FX_OCTAVER_GRAIN_SIZE)
|
||||
{
|
||||
vs->delay[g] -= (float)FX_OCTAVER_GRAIN_SIZE;
|
||||
}
|
||||
else if (vs->delay[g] < 0.0f)
|
||||
{
|
||||
vs->delay[g] += (float)FX_OCTAVER_GRAIN_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
float phase0 = vs->delay[0] / (float)FX_OCTAVER_GRAIN_SIZE;
|
||||
float env0 = FxOctaver_EnvLookup(phase0);
|
||||
float env1 = 1.0f - env0;
|
||||
|
||||
float sample0 = FxOctaver_ReadInterpolated(buffer, write_idx, vs->delay[0]);
|
||||
float sample1 = FxOctaver_ReadInterpolated(buffer, write_idx, vs->delay[1]);
|
||||
|
||||
return env0 * sample0 + env1 * sample1;
|
||||
}
|
||||
|
||||
void FxOctaver_Init(FxOctaverState *state, FxOctaverParams *params)
|
||||
{
|
||||
params->enabled = false;
|
||||
params->level_down2 = 0.0f;
|
||||
params->level_down1 = 0.0f;
|
||||
params->level_dry = 1.0f;
|
||||
params->level_up1 = 0.0f;
|
||||
params->level_up2 = 0.0f;
|
||||
|
||||
for (uint32_t i = 0; i < FX_OCTAVER_BUFFER_SIZE; i++)
|
||||
{
|
||||
state->buffer[i] = 0.0f;
|
||||
}
|
||||
state->write_idx = 0U;
|
||||
|
||||
for (uint32_t v = 0; v < FX_OCTAVER_NUM_VOICES; v++)
|
||||
{
|
||||
state->voices[v].delay[0] = 0.0f;
|
||||
state->voices[v].delay[1] = (float)FX_OCTAVER_GRAIN_SIZE * 0.5f;
|
||||
}
|
||||
|
||||
FxOctaver_BuildEnvTable();
|
||||
}
|
||||
|
||||
float FxOctaver_Process(FxOctaverState *state, const FxOctaverParams *params, float input)
|
||||
{
|
||||
if (!params->enabled)
|
||||
{
|
||||
return input;
|
||||
}
|
||||
|
||||
state->buffer[state->write_idx & FX_OCTAVER_BUFFER_MASK] = input;
|
||||
|
||||
float down2 = FxOctaver_ProcessVoice(&state->voices[0], state->buffer, state->write_idx, fx_octaver_ratios[0]);
|
||||
float down1 = FxOctaver_ProcessVoice(&state->voices[1], state->buffer, state->write_idx, fx_octaver_ratios[1]);
|
||||
float up1 = FxOctaver_ProcessVoice(&state->voices[2], state->buffer, state->write_idx, fx_octaver_ratios[2]);
|
||||
float up2 = FxOctaver_ProcessVoice(&state->voices[3], state->buffer, state->write_idx, fx_octaver_ratios[3]);
|
||||
|
||||
state->write_idx++;
|
||||
|
||||
return input * params->level_dry
|
||||
+ down2 * params->level_down2
|
||||
+ down1 * params->level_down1
|
||||
+ up1 * params->level_up1
|
||||
+ up2 * params->level_up2;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#include "fx_overdrive.h"
|
||||
#include <math.h>
|
||||
|
||||
void FxOverdrive_Init(FxOverdriveState *state, FxOverdriveParams *params)
|
||||
{
|
||||
state->tone_lp_state = 0.0f;
|
||||
|
||||
params->enabled = false;
|
||||
params->drive = 0.4f;
|
||||
params->tone = 0.6f;
|
||||
params->level = 0.7f;
|
||||
}
|
||||
|
||||
float FxOverdrive_Process(FxOverdriveState *state, const FxOverdriveParams *params, float input)
|
||||
{
|
||||
if (!params->enabled)
|
||||
{
|
||||
return input;
|
||||
}
|
||||
|
||||
float driven = input * (1.0f + params->drive * 20.0f);
|
||||
|
||||
/* Ecretage asymetrique (exponentiel) : plus caracteristique/agressif qu'un tanh symetrique. */
|
||||
float shaped;
|
||||
if (driven >= 0.0f)
|
||||
{
|
||||
shaped = 1.0f - expf(-driven);
|
||||
}
|
||||
else
|
||||
{
|
||||
shaped = -1.0f + expf(driven);
|
||||
}
|
||||
|
||||
/* Filtre passe-bas une pole pour la tonalite : coefficient = tone (0..1). */
|
||||
float coeff = 0.05f + params->tone * 0.9f;
|
||||
state->tone_lp_state += coeff * (shaped - state->tone_lp_state);
|
||||
|
||||
return state->tone_lp_state * params->level;
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
#include "fx_reverb.h"
|
||||
#include <string.h>
|
||||
|
||||
/* Lignes a retard inspirees de Freeverb (Jezar), redimensionnees de 44.1kHz vers 48kHz. */
|
||||
#define FX_REVERB_COMB0 1215U
|
||||
#define FX_REVERB_COMB1 1293U
|
||||
#define FX_REVERB_COMB2 1390U
|
||||
#define FX_REVERB_COMB3 1476U
|
||||
#define FX_REVERB_COMB4 1548U
|
||||
#define FX_REVERB_COMB5 1623U
|
||||
#define FX_REVERB_COMB6 1695U
|
||||
#define FX_REVERB_COMB7 1761U
|
||||
|
||||
#define FX_REVERB_ALLPASS0 605U
|
||||
#define FX_REVERB_ALLPASS1 480U
|
||||
#define FX_REVERB_ALLPASS2 371U
|
||||
#define FX_REVERB_ALLPASS3 245U
|
||||
|
||||
static float fx_reverb_comb_buf0[FX_REVERB_COMB0];
|
||||
static float fx_reverb_comb_buf1[FX_REVERB_COMB1];
|
||||
static float fx_reverb_comb_buf2[FX_REVERB_COMB2];
|
||||
static float fx_reverb_comb_buf3[FX_REVERB_COMB3];
|
||||
static float fx_reverb_comb_buf4[FX_REVERB_COMB4];
|
||||
static float fx_reverb_comb_buf5[FX_REVERB_COMB5];
|
||||
static float fx_reverb_comb_buf6[FX_REVERB_COMB6];
|
||||
static float fx_reverb_comb_buf7[FX_REVERB_COMB7];
|
||||
|
||||
static float fx_reverb_allpass_buf0[FX_REVERB_ALLPASS0];
|
||||
static float fx_reverb_allpass_buf1[FX_REVERB_ALLPASS1];
|
||||
static float fx_reverb_allpass_buf2[FX_REVERB_ALLPASS2];
|
||||
static float fx_reverb_allpass_buf3[FX_REVERB_ALLPASS3];
|
||||
|
||||
static float FxComb_Process(FxCombState *c, float input, float feedback, float damp1, float damp2)
|
||||
{
|
||||
float output = c->buffer[c->idx];
|
||||
c->filter_store = (output * damp2) + (c->filter_store * damp1);
|
||||
c->buffer[c->idx] = input + (c->filter_store * feedback);
|
||||
c->idx = (c->idx + 1U) % c->size;
|
||||
return output;
|
||||
}
|
||||
|
||||
static float FxAllpass_Process(FxAllpassState *a, float input, float feedback)
|
||||
{
|
||||
float buf_out = a->buffer[a->idx];
|
||||
float output = -input + buf_out;
|
||||
a->buffer[a->idx] = input + buf_out * feedback;
|
||||
a->idx = (a->idx + 1U) % a->size;
|
||||
return output;
|
||||
}
|
||||
|
||||
void FxReverb_Init(FxReverbState *state, FxReverbParams *params)
|
||||
{
|
||||
params->enabled = false;
|
||||
params->room_size = 0.5f;
|
||||
params->damping = 0.5f;
|
||||
params->mix = 0.3f;
|
||||
|
||||
float *comb_buffers[FX_REVERB_NUM_COMBS] = {
|
||||
fx_reverb_comb_buf0, fx_reverb_comb_buf1, fx_reverb_comb_buf2, fx_reverb_comb_buf3,
|
||||
fx_reverb_comb_buf4, fx_reverb_comb_buf5, fx_reverb_comb_buf6, fx_reverb_comb_buf7
|
||||
};
|
||||
uint32_t comb_sizes[FX_REVERB_NUM_COMBS] = {
|
||||
FX_REVERB_COMB0, FX_REVERB_COMB1, FX_REVERB_COMB2, FX_REVERB_COMB3,
|
||||
FX_REVERB_COMB4, FX_REVERB_COMB5, FX_REVERB_COMB6, FX_REVERB_COMB7
|
||||
};
|
||||
for (uint32_t i = 0; i < FX_REVERB_NUM_COMBS; i++)
|
||||
{
|
||||
state->combs[i].buffer = comb_buffers[i];
|
||||
state->combs[i].size = comb_sizes[i];
|
||||
state->combs[i].idx = 0;
|
||||
state->combs[i].filter_store = 0.0f;
|
||||
memset(comb_buffers[i], 0, comb_sizes[i] * sizeof(float));
|
||||
}
|
||||
|
||||
float *allpass_buffers[FX_REVERB_NUM_ALLPASS] = {
|
||||
fx_reverb_allpass_buf0, fx_reverb_allpass_buf1, fx_reverb_allpass_buf2, fx_reverb_allpass_buf3
|
||||
};
|
||||
uint32_t allpass_sizes[FX_REVERB_NUM_ALLPASS] = {
|
||||
FX_REVERB_ALLPASS0, FX_REVERB_ALLPASS1, FX_REVERB_ALLPASS2, FX_REVERB_ALLPASS3
|
||||
};
|
||||
for (uint32_t i = 0; i < FX_REVERB_NUM_ALLPASS; i++)
|
||||
{
|
||||
state->allpass[i].buffer = allpass_buffers[i];
|
||||
state->allpass[i].size = allpass_sizes[i];
|
||||
state->allpass[i].idx = 0;
|
||||
memset(allpass_buffers[i], 0, allpass_sizes[i] * sizeof(float));
|
||||
}
|
||||
}
|
||||
|
||||
float FxReverb_Process(FxReverbState *state, const FxReverbParams *params, float input)
|
||||
{
|
||||
if (!params->enabled)
|
||||
{
|
||||
return input;
|
||||
}
|
||||
|
||||
float feedback = 0.28f + params->room_size * 0.7f;
|
||||
float damp1 = params->damping * 0.4f;
|
||||
float damp2 = 1.0f - damp1;
|
||||
|
||||
float out = 0.0f;
|
||||
for (uint32_t i = 0; i < FX_REVERB_NUM_COMBS; i++)
|
||||
{
|
||||
out += FxComb_Process(&state->combs[i], input, feedback, damp1, damp2);
|
||||
}
|
||||
out /= (float)FX_REVERB_NUM_COMBS;
|
||||
|
||||
for (uint32_t i = 0; i < FX_REVERB_NUM_ALLPASS; i++)
|
||||
{
|
||||
out = FxAllpass_Process(&state->allpass[i], out, 0.5f);
|
||||
}
|
||||
|
||||
return input * (1.0f - params->mix) + out * params->mix;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#include "fx_saturation.h"
|
||||
#include <math.h>
|
||||
|
||||
#define FX_SATURATION_DC_BLOCK_R 0.995f
|
||||
|
||||
void FxSaturation_Init(FxSaturationState *state, FxSaturationParams *params)
|
||||
{
|
||||
state->dc_block_x1 = 0.0f;
|
||||
state->dc_block_y1 = 0.0f;
|
||||
|
||||
params->enabled = false;
|
||||
params->drive = 0.3f;
|
||||
params->level = 0.8f;
|
||||
}
|
||||
|
||||
float FxSaturation_Process(FxSaturationState *state, const FxSaturationParams *params, float input)
|
||||
{
|
||||
if (!params->enabled)
|
||||
{
|
||||
return input;
|
||||
}
|
||||
|
||||
float driven = input * (1.0f + params->drive * 12.0f);
|
||||
float shaped = tanhf(driven);
|
||||
|
||||
/* Le tanh sur un signal non symetrique introduit un leger DC : filtre bloqueur de DC. */
|
||||
float y = shaped - state->dc_block_x1 + FX_SATURATION_DC_BLOCK_R * state->dc_block_y1;
|
||||
state->dc_block_x1 = shaped;
|
||||
state->dc_block_y1 = y;
|
||||
|
||||
return y * params->level;
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,803 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32h7rsxx_hal_msp.c
|
||||
* @brief This file provides code for the MSP Initialization
|
||||
* and de-Initialization codes.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2023 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
extern DMA_NodeTypeDef Node_GPDMA1_Channel0;
|
||||
|
||||
extern DMA_QListTypeDef List_GPDMA1_Channel0;
|
||||
|
||||
extern DMA_HandleTypeDef handle_GPDMA1_Channel0;
|
||||
|
||||
extern DMA_HandleTypeDef handle_HPDMA1_Channel1;
|
||||
|
||||
extern DMA_HandleTypeDef handle_HPDMA1_Channel0;
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN TD */
|
||||
|
||||
/* USER CODE END TD */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Define */
|
||||
|
||||
/* USER CODE END Define */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Macro */
|
||||
|
||||
/* USER CODE END Macro */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PV */
|
||||
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* USER CODE BEGIN PFP */
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* External functions --------------------------------------------------------*/
|
||||
/* USER CODE BEGIN ExternalFunctions */
|
||||
|
||||
/* USER CODE END ExternalFunctions */
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
/**
|
||||
* Initializes the Global MSP.
|
||||
*/
|
||||
void HAL_MspInit(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN MspInit 0 */
|
||||
|
||||
/* USER CODE END MspInit 0 */
|
||||
|
||||
/* System interrupt init*/
|
||||
/* PendSV_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(PendSV_IRQn, 15, 0);
|
||||
|
||||
/* USER CODE BEGIN MspInit 1 */
|
||||
|
||||
/* USER CODE END MspInit 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MDF MSP Initialization
|
||||
* This function configures the hardware resources used in this example
|
||||
* @param hmdf: MDF handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_MDF_MspInit(MDF_HandleTypeDef* hmdf)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
DMA_NodeConfTypeDef NodeConfig;
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
|
||||
if(IS_MDF_ALL_INSTANCE(hmdf->Instance))
|
||||
{
|
||||
/* USER CODE BEGIN ADF1_MspInit 0 */
|
||||
|
||||
/* USER CODE END ADF1_MspInit 0 */
|
||||
|
||||
/** Initializes the peripherals clock
|
||||
*/
|
||||
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADF1;
|
||||
PeriphClkInit.Adf1ClockSelection = RCC_ADF1CLKSOURCE_PLL2P;
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_ADF1_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOE_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||
/**ADF1 GPIO Configuration
|
||||
PE2 ------> ADF1_CCK0
|
||||
PD6 ------> ADF1_SDI0
|
||||
*/
|
||||
GPIO_InitStruct.Pin = ADF1_CK_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; // était LOW : bien trop lent pour piloter proprement une horloge à 6-12MHz+ vers le micro PDM
|
||||
GPIO_InitStruct.Alternate = GPIO_AF1_ADF1;
|
||||
HAL_GPIO_Init(ADF1_CK_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = ADF1_D_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF3_ADF1;
|
||||
HAL_GPIO_Init(ADF1_D_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/* ADF1 DMA Init */
|
||||
/* GPDMA1_REQUEST_ADF1_FLT0 Init */
|
||||
NodeConfig.NodeType = DMA_GPDMA_LINEAR_NODE;
|
||||
NodeConfig.Init.Request = GPDMA1_REQUEST_ADF1_FLT0;
|
||||
NodeConfig.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
|
||||
NodeConfig.Init.Direction = DMA_PERIPH_TO_MEMORY;
|
||||
NodeConfig.Init.SrcInc = DMA_SINC_FIXED;
|
||||
NodeConfig.Init.DestInc = DMA_DINC_INCREMENTED;
|
||||
NodeConfig.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD;
|
||||
NodeConfig.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD;
|
||||
NodeConfig.Init.SrcBurstLength = 1;
|
||||
NodeConfig.Init.DestBurstLength = 1;
|
||||
NodeConfig.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT1;
|
||||
NodeConfig.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
|
||||
NodeConfig.Init.Mode = DMA_NORMAL;
|
||||
NodeConfig.TriggerConfig.TriggerPolarity = DMA_TRIG_POLARITY_MASKED;
|
||||
NodeConfig.DataHandlingConfig.DataExchange = DMA_EXCHANGE_NONE;
|
||||
NodeConfig.DataHandlingConfig.DataAlignment = DMA_DATA_RIGHTALIGN_ZEROPADDED;
|
||||
if (HAL_DMAEx_List_BuildNode(&NodeConfig, &Node_GPDMA1_Channel0) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
if (HAL_DMAEx_List_InsertNode(&List_GPDMA1_Channel0, NULL, &Node_GPDMA1_Channel0) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
if (HAL_DMAEx_List_SetCircularMode(&List_GPDMA1_Channel0) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
handle_GPDMA1_Channel0.Instance = GPDMA1_Channel0;
|
||||
handle_GPDMA1_Channel0.InitLinkedList.Priority = DMA_HIGH_PRIORITY;
|
||||
handle_GPDMA1_Channel0.InitLinkedList.LinkStepMode = DMA_LSM_FULL_EXECUTION;
|
||||
handle_GPDMA1_Channel0.InitLinkedList.LinkAllocatedPort = DMA_LINK_ALLOCATED_PORT1;
|
||||
handle_GPDMA1_Channel0.InitLinkedList.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
|
||||
handle_GPDMA1_Channel0.InitLinkedList.LinkedListMode = DMA_LINKEDLIST_CIRCULAR;
|
||||
if (HAL_DMAEx_List_Init(&handle_GPDMA1_Channel0) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
if (HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel0, &List_GPDMA1_Channel0) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
__HAL_LINKDMA(hmdf, hdma, handle_GPDMA1_Channel0);
|
||||
|
||||
if (HAL_DMA_ConfigChannelAttributes(&handle_GPDMA1_Channel0, DMA_CHANNEL_NPRIV) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/* ADF1 interrupt Init */
|
||||
HAL_NVIC_SetPriority(ADF1_FLT0_IRQn, 2, 0);
|
||||
HAL_NVIC_EnableIRQ(ADF1_FLT0_IRQn);
|
||||
/* USER CODE BEGIN ADF1_MspInit 1 */
|
||||
|
||||
/* USER CODE END ADF1_MspInit 1 */
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MDF MSP De-Initialization
|
||||
* This function freeze the hardware resources used in this example
|
||||
* @param hmdf: MDF handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_MDF_MspDeInit(MDF_HandleTypeDef* hmdf)
|
||||
{
|
||||
if(IS_MDF_ALL_INSTANCE(hmdf->Instance))
|
||||
{
|
||||
/* USER CODE BEGIN ADF1_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END ADF1_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_ADF1_CLK_DISABLE();
|
||||
|
||||
/**ADF1 GPIO Configuration
|
||||
PE2 ------> ADF1_CCK0
|
||||
PD6 ------> ADF1_SDI0
|
||||
*/
|
||||
HAL_GPIO_DeInit(ADF1_CK_GPIO_Port, ADF1_CK_Pin);
|
||||
|
||||
HAL_GPIO_DeInit(ADF1_D_GPIO_Port, ADF1_D_Pin);
|
||||
|
||||
/* ADF1 DMA DeInit */
|
||||
HAL_DMA_DeInit(hmdf->hdma);
|
||||
|
||||
/* ADF1 interrupt DeInit */
|
||||
HAL_NVIC_DisableIRQ(ADF1_FLT0_IRQn);
|
||||
/* USER CODE BEGIN ADF1_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END ADF1_MspDeInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CRC MSP Initialization
|
||||
* This function configures the hardware resources used in this example
|
||||
* @param hcrc: CRC handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_CRC_MspInit(CRC_HandleTypeDef* hcrc)
|
||||
{
|
||||
if(hcrc->Instance==CRC)
|
||||
{
|
||||
/* USER CODE BEGIN CRC_MspInit 0 */
|
||||
|
||||
/* USER CODE END CRC_MspInit 0 */
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_CRC_CLK_ENABLE();
|
||||
/* USER CODE BEGIN CRC_MspInit 1 */
|
||||
|
||||
/* USER CODE END CRC_MspInit 1 */
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CRC MSP De-Initialization
|
||||
* This function freeze the hardware resources used in this example
|
||||
* @param hcrc: CRC handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_CRC_MspDeInit(CRC_HandleTypeDef* hcrc)
|
||||
{
|
||||
if(hcrc->Instance==CRC)
|
||||
{
|
||||
/* USER CODE BEGIN CRC_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END CRC_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_CRC_CLK_DISABLE();
|
||||
/* USER CODE BEGIN CRC_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END CRC_MspDeInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA2D MSP Initialization
|
||||
* This function configures the hardware resources used in this example
|
||||
* @param hdma2d: DMA2D handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_DMA2D_MspInit(DMA2D_HandleTypeDef* hdma2d)
|
||||
{
|
||||
if(hdma2d->Instance==DMA2D)
|
||||
{
|
||||
/* USER CODE BEGIN DMA2D_MspInit 0 */
|
||||
|
||||
/* USER CODE END DMA2D_MspInit 0 */
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_DMA2D_CLK_ENABLE();
|
||||
/* DMA2D interrupt Init */
|
||||
HAL_NVIC_SetPriority(DMA2D_IRQn, 5, 0);
|
||||
/* USER CODE BEGIN DMA2D_MspInit 1 */
|
||||
|
||||
/* USER CODE END DMA2D_MspInit 1 */
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA2D MSP De-Initialization
|
||||
* This function freeze the hardware resources used in this example
|
||||
* @param hdma2d: DMA2D handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_DMA2D_MspDeInit(DMA2D_HandleTypeDef* hdma2d)
|
||||
{
|
||||
if(hdma2d->Instance==DMA2D)
|
||||
{
|
||||
/* USER CODE BEGIN DMA2D_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END DMA2D_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_DMA2D_CLK_DISABLE();
|
||||
|
||||
/* DMA2D interrupt DeInit */
|
||||
HAL_NVIC_DisableIRQ(DMA2D_IRQn);
|
||||
/* USER CODE BEGIN DMA2D_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END DMA2D_MspDeInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief GPU2D MSP Initialization
|
||||
* This function configures the hardware resources used in this example
|
||||
* @param hgpu2d: GPU2D handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_GPU2D_MspInit(GPU2D_HandleTypeDef* hgpu2d)
|
||||
{
|
||||
if(hgpu2d->Instance==GPU2D)
|
||||
{
|
||||
/* USER CODE BEGIN GPU2D_MspInit 0 */
|
||||
|
||||
/* USER CODE END GPU2D_MspInit 0 */
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_GPU2D_CLK_ENABLE();
|
||||
/* GPU2D interrupt Init */
|
||||
HAL_NVIC_SetPriority(GPU2D_IRQn, 5, 0);
|
||||
HAL_NVIC_EnableIRQ(GPU2D_IRQn);
|
||||
HAL_NVIC_SetPriority(GPU2D_ER_IRQn, 5, 0);
|
||||
HAL_NVIC_EnableIRQ(GPU2D_ER_IRQn);
|
||||
/* USER CODE BEGIN GPU2D_MspInit 1 */
|
||||
|
||||
/* USER CODE END GPU2D_MspInit 1 */
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief GPU2D MSP De-Initialization
|
||||
* This function freeze the hardware resources used in this example
|
||||
* @param hgpu2d: GPU2D handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_GPU2D_MspDeInit(GPU2D_HandleTypeDef* hgpu2d)
|
||||
{
|
||||
if(hgpu2d->Instance==GPU2D)
|
||||
{
|
||||
/* USER CODE BEGIN GPU2D_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END GPU2D_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_GPU2D_CLK_DISABLE();
|
||||
|
||||
/* GPU2D interrupt DeInit */
|
||||
HAL_NVIC_DisableIRQ(GPU2D_IRQn);
|
||||
HAL_NVIC_DisableIRQ(GPU2D_ER_IRQn);
|
||||
/* USER CODE BEGIN GPU2D_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END GPU2D_MspDeInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief I2C MSP Initialization
|
||||
* This function configures the hardware resources used in this example
|
||||
* @param hi2c: I2C handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
|
||||
if(hi2c->Instance==I2C1)
|
||||
{
|
||||
/* USER CODE BEGIN I2C1_MspInit 0 */
|
||||
|
||||
/* USER CODE END I2C1_MspInit 0 */
|
||||
|
||||
/** Initializes the peripherals clock
|
||||
*/
|
||||
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_I2C1_I3C1;
|
||||
PeriphClkInit.I2c1_I3c1ClockSelection = RCC_I2C1_I3C1CLKSOURCE_PCLK1;
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
/**I2C1 GPIO Configuration
|
||||
PB9 ------> I2C1_SDA
|
||||
PB6 ------> I2C1_SCL
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_6;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_I2C1_CLK_ENABLE();
|
||||
/* USER CODE BEGIN I2C1_MspInit 1 */
|
||||
|
||||
/* USER CODE END I2C1_MspInit 1 */
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief I2C MSP De-Initialization
|
||||
* This function freeze the hardware resources used in this example
|
||||
* @param hi2c: I2C handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
|
||||
{
|
||||
if(hi2c->Instance==I2C1)
|
||||
{
|
||||
/* USER CODE BEGIN I2C1_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END I2C1_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_I2C1_CLK_DISABLE();
|
||||
|
||||
/**I2C1 GPIO Configuration
|
||||
PB9 ------> I2C1_SDA
|
||||
PB6 ------> I2C1_SCL
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_9);
|
||||
|
||||
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6);
|
||||
|
||||
/* USER CODE BEGIN I2C1_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END I2C1_MspDeInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief JPEG MSP Initialization
|
||||
* This function configures the hardware resources used in this example
|
||||
* @param hjpeg: JPEG handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_JPEG_MspInit(JPEG_HandleTypeDef* hjpeg)
|
||||
{
|
||||
DMA_DataHandlingConfTypeDef DataHandlingConfig;
|
||||
if(hjpeg->Instance==JPEG)
|
||||
{
|
||||
/* USER CODE BEGIN JPEG_MspInit 0 */
|
||||
|
||||
/* USER CODE END JPEG_MspInit 0 */
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_JPEG_CLK_ENABLE();
|
||||
|
||||
/* JPEG DMA Init */
|
||||
/* HPDMA1_REQUEST_JPEG_TX Init */
|
||||
handle_HPDMA1_Channel1.Instance = HPDMA1_Channel1;
|
||||
handle_HPDMA1_Channel1.Init.Request = HPDMA1_REQUEST_JPEG_TX;
|
||||
handle_HPDMA1_Channel1.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
|
||||
handle_HPDMA1_Channel1.Init.Direction = DMA_PERIPH_TO_MEMORY;
|
||||
handle_HPDMA1_Channel1.Init.SrcInc = DMA_SINC_FIXED;
|
||||
handle_HPDMA1_Channel1.Init.DestInc = DMA_DINC_INCREMENTED;
|
||||
handle_HPDMA1_Channel1.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD;
|
||||
handle_HPDMA1_Channel1.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD;
|
||||
handle_HPDMA1_Channel1.Init.Priority = DMA_HIGH_PRIORITY;
|
||||
handle_HPDMA1_Channel1.Init.SrcBurstLength = 8;
|
||||
handle_HPDMA1_Channel1.Init.DestBurstLength = 8;
|
||||
handle_HPDMA1_Channel1.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT1|DMA_DEST_ALLOCATED_PORT0;
|
||||
handle_HPDMA1_Channel1.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
|
||||
handle_HPDMA1_Channel1.Init.Mode = DMA_NORMAL;
|
||||
if (HAL_DMA_Init(&handle_HPDMA1_Channel1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
__HAL_LINKDMA(hjpeg, hdmaout, handle_HPDMA1_Channel1);
|
||||
|
||||
if (HAL_DMA_ConfigChannelAttributes(&handle_HPDMA1_Channel1, DMA_CHANNEL_NPRIV) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/* HPDMA1_REQUEST_JPEG_RX Init */
|
||||
handle_HPDMA1_Channel0.Instance = HPDMA1_Channel0;
|
||||
handle_HPDMA1_Channel0.Init.Request = HPDMA1_REQUEST_JPEG_RX;
|
||||
handle_HPDMA1_Channel0.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
|
||||
handle_HPDMA1_Channel0.Init.Direction = DMA_MEMORY_TO_PERIPH;
|
||||
handle_HPDMA1_Channel0.Init.SrcInc = DMA_SINC_INCREMENTED;
|
||||
handle_HPDMA1_Channel0.Init.DestInc = DMA_DINC_FIXED;
|
||||
handle_HPDMA1_Channel0.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_BYTE;
|
||||
handle_HPDMA1_Channel0.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD;
|
||||
handle_HPDMA1_Channel0.Init.Priority = DMA_HIGH_PRIORITY;
|
||||
handle_HPDMA1_Channel0.Init.SrcBurstLength = 8;
|
||||
handle_HPDMA1_Channel0.Init.DestBurstLength = 8;
|
||||
handle_HPDMA1_Channel0.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT1;
|
||||
handle_HPDMA1_Channel0.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
|
||||
handle_HPDMA1_Channel0.Init.Mode = DMA_NORMAL;
|
||||
if (HAL_DMA_Init(&handle_HPDMA1_Channel0) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
DataHandlingConfig.DataExchange = DMA_EXCHANGE_NONE;
|
||||
DataHandlingConfig.DataAlignment = DMA_DATA_PACK;
|
||||
if (HAL_DMAEx_ConfigDataHandling(&handle_HPDMA1_Channel0, &DataHandlingConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
__HAL_LINKDMA(hjpeg, hdmain, handle_HPDMA1_Channel0);
|
||||
|
||||
if (HAL_DMA_ConfigChannelAttributes(&handle_HPDMA1_Channel0, DMA_CHANNEL_NPRIV) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/* JPEG interrupt Init */
|
||||
HAL_NVIC_SetPriority(JPEG_IRQn, 8, 0);
|
||||
HAL_NVIC_EnableIRQ(JPEG_IRQn);
|
||||
/* USER CODE BEGIN JPEG_MspInit 1 */
|
||||
|
||||
/* USER CODE END JPEG_MspInit 1 */
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief JPEG MSP De-Initialization
|
||||
* This function freeze the hardware resources used in this example
|
||||
* @param hjpeg: JPEG handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_JPEG_MspDeInit(JPEG_HandleTypeDef* hjpeg)
|
||||
{
|
||||
if(hjpeg->Instance==JPEG)
|
||||
{
|
||||
/* USER CODE BEGIN JPEG_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END JPEG_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_JPEG_CLK_DISABLE();
|
||||
|
||||
/* JPEG DMA DeInit */
|
||||
HAL_DMA_DeInit(hjpeg->hdmaout);
|
||||
HAL_DMA_DeInit(hjpeg->hdmain);
|
||||
|
||||
/* JPEG interrupt DeInit */
|
||||
HAL_NVIC_DisableIRQ(JPEG_IRQn);
|
||||
/* USER CODE BEGIN JPEG_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END JPEG_MspDeInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief LTDC MSP Initialization
|
||||
* This function configures the hardware resources used in this example
|
||||
* @param hltdc: LTDC handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_LTDC_MspInit(LTDC_HandleTypeDef* hltdc)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
|
||||
if(hltdc->Instance==LTDC)
|
||||
{
|
||||
/* USER CODE BEGIN LTDC_MspInit 0 */
|
||||
|
||||
/* USER CODE END LTDC_MspInit 0 */
|
||||
|
||||
/** Initializes the peripherals clock
|
||||
*/
|
||||
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
|
||||
PeriphClkInit.LtdcClockSelection = RCC_LTDCCLKSOURCE_PLL3R;
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_LTDC_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOF_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOG_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOE_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
/**LTDC GPIO Configuration
|
||||
PF0 ------> LTDC_R2
|
||||
PG0 ------> LTDC_R7
|
||||
PB3(JTDO/TRACESWO) ------> LTDC_R4
|
||||
PG2 ------> LTDC_HSYNC
|
||||
PE11 ------> LTDC_VSYNC
|
||||
PA12 ------> LTDC_B2
|
||||
PA11 ------> LTDC_B3
|
||||
PB4(NJTRST) ------> LTDC_R3
|
||||
PA9 ------> LTDC_B5
|
||||
PG1 ------> LTDC_R6
|
||||
PA10 ------> LTDC_B4
|
||||
PG14 ------> LTDC_B1
|
||||
PA8 ------> LTDC_B6
|
||||
PG13 ------> LTDC_CLK
|
||||
PA15(JTDI) ------> LTDC_R5
|
||||
PF7 ------> LTDC_G0
|
||||
PF9 ------> LTDC_R0
|
||||
PF10 ------> LTDC_R1
|
||||
PB12 ------> LTDC_G5
|
||||
PA0 ------> LTDC_G3
|
||||
PA1 ------> LTDC_G2
|
||||
PF11 ------> LTDC_B0
|
||||
PB14 ------> LTDC_DE
|
||||
PB15 ------> LTDC_G7
|
||||
PF15 ------> LTDC_G1
|
||||
PB11 ------> LTDC_G6
|
||||
PB13 ------> LTDC_G4
|
||||
PA6 ------> LTDC_B7
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_0;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF11_LTDC;
|
||||
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_2|GPIO_PIN_1|GPIO_PIN_14
|
||||
|GPIO_PIN_13;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF13_LTDC;
|
||||
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_12|GPIO_PIN_14
|
||||
|GPIO_PIN_11;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF13_LTDC;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_11;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF11_LTDC;
|
||||
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_11|GPIO_PIN_8|GPIO_PIN_15
|
||||
|GPIO_PIN_0|GPIO_PIN_1;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF13_LTDC;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF14_LTDC;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_9|GPIO_PIN_15;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF13_LTDC;
|
||||
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF14_LTDC;
|
||||
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_15|GPIO_PIN_13;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF10_LTDC;
|
||||
HAL_GPIO_Init(GPIOB, &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.Alternate = GPIO_AF12_LTDC;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/* LTDC interrupt Init */
|
||||
HAL_NVIC_SetPriority(LTDC_IRQn, 5, 0);
|
||||
/* USER CODE BEGIN LTDC_MspInit 1 */
|
||||
|
||||
/* USER CODE END LTDC_MspInit 1 */
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief LTDC MSP De-Initialization
|
||||
* This function freeze the hardware resources used in this example
|
||||
* @param hltdc: LTDC handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_LTDC_MspDeInit(LTDC_HandleTypeDef* hltdc)
|
||||
{
|
||||
if(hltdc->Instance==LTDC)
|
||||
{
|
||||
/* USER CODE BEGIN LTDC_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END LTDC_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_LTDC_CLK_DISABLE();
|
||||
|
||||
/**LTDC GPIO Configuration
|
||||
PF0 ------> LTDC_R2
|
||||
PG0 ------> LTDC_R7
|
||||
PB3(JTDO/TRACESWO) ------> LTDC_R4
|
||||
PG2 ------> LTDC_HSYNC
|
||||
PE11 ------> LTDC_VSYNC
|
||||
PA12 ------> LTDC_B2
|
||||
PA11 ------> LTDC_B3
|
||||
PB4(NJTRST) ------> LTDC_R3
|
||||
PA9 ------> LTDC_B5
|
||||
PG1 ------> LTDC_R6
|
||||
PA10 ------> LTDC_B4
|
||||
PG14 ------> LTDC_B1
|
||||
PA8 ------> LTDC_B6
|
||||
PG13 ------> LTDC_CLK
|
||||
PA15(JTDI) ------> LTDC_R5
|
||||
PF7 ------> LTDC_G0
|
||||
PF9 ------> LTDC_R0
|
||||
PF10 ------> LTDC_R1
|
||||
PB12 ------> LTDC_G5
|
||||
PA0 ------> LTDC_G3
|
||||
PA1 ------> LTDC_G2
|
||||
PF11 ------> LTDC_B0
|
||||
PB14 ------> LTDC_DE
|
||||
PB15 ------> LTDC_G7
|
||||
PF15 ------> LTDC_G1
|
||||
PB11 ------> LTDC_G6
|
||||
PB13 ------> LTDC_G4
|
||||
PA6 ------> LTDC_B7
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOF, GPIO_PIN_0|GPIO_PIN_7|GPIO_PIN_9|GPIO_PIN_10
|
||||
|GPIO_PIN_11|GPIO_PIN_15);
|
||||
|
||||
HAL_GPIO_DeInit(GPIOG, GPIO_PIN_0|GPIO_PIN_2|GPIO_PIN_1|GPIO_PIN_14
|
||||
|GPIO_PIN_13);
|
||||
|
||||
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_12|GPIO_PIN_14
|
||||
|GPIO_PIN_15|GPIO_PIN_11|GPIO_PIN_13);
|
||||
|
||||
HAL_GPIO_DeInit(GPIOE, GPIO_PIN_11);
|
||||
|
||||
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_12|GPIO_PIN_11|GPIO_PIN_9|GPIO_PIN_10
|
||||
|GPIO_PIN_8|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1
|
||||
|GPIO_PIN_6);
|
||||
|
||||
/* LTDC interrupt DeInit */
|
||||
HAL_NVIC_DisableIRQ(LTDC_IRQn);
|
||||
/* USER CODE BEGIN LTDC_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END LTDC_MspDeInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
@@ -0,0 +1,192 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32h7rsxx_hal_timebase_tim.c
|
||||
* @author MCD Application Team
|
||||
* @brief Template for HAL time base based on the peripheral hardware TIM6.
|
||||
*
|
||||
* This file override the native HAL time base functions (defined as weak)
|
||||
* the TIM time base:
|
||||
* + Initializes the TIM6 peripheral to generate a Period elapsed Event each 1ms
|
||||
* + HAL_IncTick is called inside HAL_TIM_PeriodElapsedCallback ie each 1ms
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32h7rsxx_hal.h"
|
||||
|
||||
/** @addtogroup STM32H7RSxx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup HAL_TimeBase
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
#define TIM_CNT_FREQ 1000000U /* Timer counter frequency : 1 MHz */
|
||||
#define TIM_FREQ 1000U /* Timer frequency : 1 kHz => to have 1 ms interrupt */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
TIM_HandleTypeDef htim6;
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1U)
|
||||
void TimeBase_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
|
||||
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief This function configures the TIM6 as a time base source.
|
||||
* The time source is configured to have 1ms time base with a dedicated
|
||||
* Tick interrupt priority.
|
||||
* @note This function is called automatically at the beginning of program after
|
||||
* reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig().
|
||||
* @param TickPriority Tick interrupt priority.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
|
||||
{
|
||||
RCC_ClkInitTypeDef clkconfig;
|
||||
uint32_t uwTimclock;
|
||||
uint32_t uwAPB1Prescaler;
|
||||
uint32_t uwPrescalerValue;
|
||||
uint32_t pFLatency;
|
||||
HAL_StatusTypeDef Status;
|
||||
|
||||
/* Enable TIM6 clock */
|
||||
__HAL_RCC_TIM6_CLK_ENABLE();
|
||||
|
||||
/* Get clock configuration */
|
||||
HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);
|
||||
|
||||
/* Get APB1 prescaler */
|
||||
uwAPB1Prescaler = clkconfig.APB1CLKDivider;
|
||||
|
||||
/* Compute TIM6 clock */
|
||||
if (uwAPB1Prescaler == RCC_APB1_DIV1)
|
||||
{
|
||||
uwTimclock = HAL_RCC_GetPCLK1Freq();
|
||||
}
|
||||
else if (uwAPB1Prescaler == RCC_APB1_DIV2)
|
||||
{
|
||||
uwTimclock = 2UL * HAL_RCC_GetPCLK1Freq();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (__HAL_RCC_GET_TIMCLKPRESCALER() == RCC_TIMPRES_DISABLE)
|
||||
{
|
||||
uwTimclock = 2UL * HAL_RCC_GetPCLK1Freq();
|
||||
}
|
||||
else
|
||||
{
|
||||
uwTimclock = 4UL * HAL_RCC_GetPCLK1Freq();
|
||||
}
|
||||
}
|
||||
|
||||
/* Compute the prescaler value to have TIM6 counter clock equal to TIM_CNT_FREQ */
|
||||
uwPrescalerValue = (uint32_t)((uwTimclock / TIM_CNT_FREQ) - 1U);
|
||||
|
||||
/* Initialize TIM6 */
|
||||
htim6.Instance = TIM6;
|
||||
|
||||
/* Initialize TIMx peripheral as follow:
|
||||
+ Period = [uwTickFreq * (TIM_CNT_FREQ/TIM_FREQ) - 1]. to have a (uwTickFreq/TIM_FREQ) s time base.
|
||||
+ Prescaler = (uwTimclock/TIM_CNT_FREQ - 1) to have a TIM_CNT_FREQ counter clock.
|
||||
+ ClockDivision = 0
|
||||
+ Counter direction = Up
|
||||
*/
|
||||
htim6.Init.Period = ((uint32_t)uwTickFreq * (TIM_CNT_FREQ / TIM_FREQ)) - 1U;
|
||||
htim6.Init.Prescaler = uwPrescalerValue;
|
||||
htim6.Init.ClockDivision = 0;
|
||||
htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||
Status = HAL_TIM_Base_Init(&htim6);
|
||||
if (Status == HAL_OK)
|
||||
{
|
||||
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1U)
|
||||
HAL_TIM_RegisterCallback(&htim6, HAL_TIM_PERIOD_ELAPSED_CB_ID, TimeBase_TIM_PeriodElapsedCallback);
|
||||
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
|
||||
/* Start the TIM time Base generation in interrupt mode */
|
||||
Status = HAL_TIM_Base_Start_IT(&htim6);
|
||||
if (Status == HAL_OK)
|
||||
{
|
||||
if (TickPriority < (1UL << __NVIC_PRIO_BITS))
|
||||
{
|
||||
/* Configure the TIM6 global Interrupt priority */
|
||||
HAL_NVIC_SetPriority(TIM6_IRQn, TickPriority, 0);
|
||||
|
||||
/* Enable the TIM6 global Interrupt */
|
||||
HAL_NVIC_EnableIRQ(TIM6_IRQn);
|
||||
|
||||
uwTickPrio = TickPriority;
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = HAL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Suspend Tick increment.
|
||||
* @note Disable the tick increment by disabling TIM6 update interrupt.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_SuspendTick(void)
|
||||
{
|
||||
/* Disable TIM6 update interrupt */
|
||||
__HAL_TIM_DISABLE_IT(&htim6, TIM_IT_UPDATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resume Tick increment.
|
||||
* @note Enable the tick increment by enabling TIM6 update interrupt.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_ResumeTick(void)
|
||||
{
|
||||
/* Enable TIM6 update interrupt */
|
||||
__HAL_TIM_ENABLE_IT(&htim6, TIM_IT_UPDATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Period elapsed callback in non blocking mode
|
||||
* @note This function is called when TIM6 interrupt took place, inside
|
||||
* HAL_TIM6_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
|
||||
* a global variable "uwTick" used as application time base.
|
||||
* @param htim TIM handle
|
||||
* @retval None
|
||||
*/
|
||||
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1U)
|
||||
void TimeBase_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(htim);
|
||||
|
||||
HAL_IncTick();
|
||||
|
||||
}
|
||||
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -0,0 +1,337 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32h7rsxx_it.c
|
||||
* @brief Interrupt Service Routines.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2023 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
#include "stm32h7rsxx_it.h"
|
||||
|
||||
#include "stm32h7s78_discovery_audio.h"
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN TD */
|
||||
|
||||
/* USER CODE END TD */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PD */
|
||||
|
||||
/* USER CODE END PD */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PM */
|
||||
|
||||
/* USER CODE END PM */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PV */
|
||||
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* USER CODE BEGIN PFP */
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* Private user code ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
extern DMA_NodeTypeDef Node_GPDMA1_Channel0;
|
||||
extern DMA_QListTypeDef List_GPDMA1_Channel0;
|
||||
extern DMA_HandleTypeDef handle_GPDMA1_Channel0;
|
||||
extern MDF_HandleTypeDef AdfHandle0;
|
||||
extern DMA2D_HandleTypeDef hdma2d;
|
||||
extern GPU2D_HandleTypeDef hgpu2d;
|
||||
extern DMA_HandleTypeDef handle_HPDMA1_Channel1;
|
||||
extern DMA_HandleTypeDef handle_HPDMA1_Channel0;
|
||||
extern JPEG_HandleTypeDef hjpeg;
|
||||
extern LTDC_HandleTypeDef hltdc;
|
||||
extern TIM_HandleTypeDef htim6;
|
||||
|
||||
extern DMA_HandleTypeDef hDmaI2sTx;
|
||||
|
||||
/* USER CODE BEGIN EV */
|
||||
|
||||
/* USER CODE END EV */
|
||||
|
||||
/******************************************************************************/
|
||||
/* Cortex Processor Interruption and Exception Handlers */
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* @brief This function handles Non maskable interrupt.
|
||||
*/
|
||||
void NMI_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
|
||||
|
||||
/* USER CODE END NonMaskableInt_IRQn 0 */
|
||||
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
/* USER CODE END NonMaskableInt_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Hard fault interrupt.
|
||||
*/
|
||||
void HardFault_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN HardFault_IRQn 0 */
|
||||
|
||||
/* USER CODE END HardFault_IRQn 0 */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
|
||||
/* USER CODE END W1_HardFault_IRQn 0 */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Memory management fault.
|
||||
*/
|
||||
void MemManage_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
|
||||
|
||||
/* USER CODE END MemoryManagement_IRQn 0 */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
|
||||
/* USER CODE END W1_MemoryManagement_IRQn 0 */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Pre-fetch fault, memory access fault.
|
||||
*/
|
||||
void BusFault_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN BusFault_IRQn 0 */
|
||||
|
||||
/* USER CODE END BusFault_IRQn 0 */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE BEGIN W1_BusFault_IRQn 0 */
|
||||
/* USER CODE END W1_BusFault_IRQn 0 */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Undefined instruction or illegal state.
|
||||
*/
|
||||
void UsageFault_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN UsageFault_IRQn 0 */
|
||||
|
||||
/* USER CODE END UsageFault_IRQn 0 */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE BEGIN W1_UsageFault_IRQn 0 */
|
||||
/* USER CODE END W1_UsageFault_IRQn 0 */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Debug monitor.
|
||||
*/
|
||||
void DebugMon_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
|
||||
|
||||
/* USER CODE END DebugMonitor_IRQn 0 */
|
||||
/* USER CODE BEGIN DebugMonitor_IRQn 1 */
|
||||
|
||||
/* USER CODE END DebugMonitor_IRQn 1 */
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* STM32H7RSxx Peripheral Interrupt Handlers */
|
||||
/* Add here the Interrupt Handlers for the used peripherals. */
|
||||
/* For the available peripheral interrupt handler names, */
|
||||
/* please refer to the startup file (startup_stm32h7rsxx.s). */
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief This function handles EXTI line3 interrupt.
|
||||
*/
|
||||
void EXTI3_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN EXTI3_IRQn 0 */
|
||||
|
||||
/* USER CODE END EXTI3_IRQn 0 */
|
||||
HAL_GPIO_EXTI_IRQHandler(TP_IRQ_Pin);
|
||||
/* USER CODE BEGIN EXTI3_IRQn 1 */
|
||||
|
||||
/* USER CODE END EXTI3_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles GPDMA1 Channel 0 global interrupt.
|
||||
*/
|
||||
void GPDMA1_Channel0_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN GPDMA1_Channel0_IRQn 0 */
|
||||
|
||||
/* USER CODE END GPDMA1_Channel0_IRQn 0 */
|
||||
HAL_DMA_IRQHandler(&handle_GPDMA1_Channel0);
|
||||
/* USER CODE BEGIN GPDMA1_Channel0_IRQn 1 */
|
||||
|
||||
/* USER CODE END GPDMA1_Channel0_IRQn 1 */
|
||||
}
|
||||
|
||||
void GPDMA1_Channel2_IRQHandler(void)
|
||||
{
|
||||
BSP_AUDIO_OUT_IRQHandler(0, AUDIO_OUT_HEADPHONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles TIM6 global interrupt.
|
||||
*/
|
||||
void TIM6_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN TIM6_IRQn 0 */
|
||||
|
||||
/* USER CODE END TIM6_IRQn 0 */
|
||||
HAL_TIM_IRQHandler(&htim6);
|
||||
/* USER CODE BEGIN TIM6_IRQn 1 */
|
||||
|
||||
/* USER CODE END TIM6_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles HPDMA1 Channel 0 global interrupt.
|
||||
*/
|
||||
void HPDMA1_Channel0_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN HPDMA1_Channel0_IRQn 0 */
|
||||
|
||||
/* USER CODE END HPDMA1_Channel0_IRQn 0 */
|
||||
HAL_DMA_IRQHandler(&handle_HPDMA1_Channel0);
|
||||
/* USER CODE BEGIN HPDMA1_Channel0_IRQn 1 */
|
||||
|
||||
/* USER CODE END HPDMA1_Channel0_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles HPDMA1 Channel 1 global interrupt.
|
||||
*/
|
||||
void HPDMA1_Channel1_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN HPDMA1_Channel1_IRQn 0 */
|
||||
|
||||
/* USER CODE END HPDMA1_Channel1_IRQn 0 */
|
||||
HAL_DMA_IRQHandler(&handle_HPDMA1_Channel1);
|
||||
/* USER CODE BEGIN HPDMA1_Channel1_IRQn 1 */
|
||||
|
||||
/* USER CODE END HPDMA1_Channel1_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles LTDC global interrupt.
|
||||
*/
|
||||
void LTDC_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN LTDC_IRQn 0 */
|
||||
|
||||
/* USER CODE END LTDC_IRQn 0 */
|
||||
HAL_LTDC_IRQHandler(&hltdc);
|
||||
/* USER CODE BEGIN LTDC_IRQn 1 */
|
||||
|
||||
/* USER CODE END LTDC_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles DMA2D global interrupt.
|
||||
*/
|
||||
void DMA2D_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN DMA2D_IRQn 0 */
|
||||
|
||||
/* USER CODE END DMA2D_IRQn 0 */
|
||||
HAL_DMA2D_IRQHandler(&hdma2d);
|
||||
/* USER CODE BEGIN DMA2D_IRQn 1 */
|
||||
|
||||
/* USER CODE END DMA2D_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles JPEG global interrupt.
|
||||
*/
|
||||
void JPEG_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN JPEG_IRQn 0 */
|
||||
|
||||
/* USER CODE END JPEG_IRQn 0 */
|
||||
HAL_JPEG_IRQHandler(&hjpeg);
|
||||
/* USER CODE BEGIN JPEG_IRQn 1 */
|
||||
|
||||
/* USER CODE END JPEG_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles ADF1 Filter 0 global Interrupt.
|
||||
*/
|
||||
void ADF1_FLT0_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN ADF1_FLT0_IRQn 0 */
|
||||
|
||||
/* USER CODE END ADF1_FLT0_IRQn 0 */
|
||||
HAL_MDF_IRQHandler(&AdfHandle0);
|
||||
/* USER CODE BEGIN ADF1_FLT0_IRQn 1 */
|
||||
|
||||
/* USER CODE END ADF1_FLT0_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles GPU2D global interrupt.
|
||||
*/
|
||||
void GPU2D_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN GPU2D_IRQn 0 */
|
||||
|
||||
/* USER CODE END GPU2D_IRQn 0 */
|
||||
HAL_GPU2D_IRQHandler(&hgpu2d);
|
||||
/* USER CODE BEGIN GPU2D_IRQn 1 */
|
||||
|
||||
/* USER CODE END GPU2D_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles GPU2D Error interrupt.
|
||||
*/
|
||||
void GPU2D_ER_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN GPU2D_ER_IRQn 0 */
|
||||
|
||||
/* USER CODE END GPU2D_ER_IRQn 0 */
|
||||
HAL_GPU2D_ER_IRQHandler(&hgpu2d);
|
||||
/* USER CODE BEGIN GPU2D_ER_IRQn 1 */
|
||||
|
||||
/* USER CODE END GPU2D_ER_IRQn 1 */
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
@@ -0,0 +1,304 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_stm32h7rsxx.c
|
||||
* @author MCD Application Team
|
||||
* @brief CMSIS Cortex-M7 Device Peripheral Access Layer System Source File
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2022 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*
|
||||
* This file provides two functions and one global variable to be called from
|
||||
* user application:
|
||||
* - SystemInit(): This function is called at startup just after reset and
|
||||
* before branch to main program. This call is made inside
|
||||
* the "startup_stm32h7rsxx.s" file.
|
||||
*
|
||||
* - SystemCoreClock variable: Contains the core clock (sys_cpu_ck), it can
|
||||
* be used by the user application to setup the
|
||||
* SysTick timer or configure other parameters.
|
||||
*
|
||||
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
|
||||
* be called whenever the core clock is changed
|
||||
* during program execution.
|
||||
*
|
||||
* After each device reset the HSI (64 MHz) is used as system clock source.
|
||||
* Then SystemInit() function is called, in "startup_stm32h7rsxx.s" file, to
|
||||
* optionally configure the system clock before to branch to main program.
|
||||
*
|
||||
*=============================================================================
|
||||
*/
|
||||
|
||||
/** @addtogroup CMSIS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H7RSxx_System
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H7RSxx_System_Private_Includes
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "stm32h7rsxx.h"
|
||||
#include <math.h>
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H7RSxx_System_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H7RSxx_System_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
#if !defined (HSE_VALUE)
|
||||
#define HSE_VALUE 24000000UL /*!< Value of the High-Speed External oscillator in Hz */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined (HSI_VALUE)
|
||||
#define HSI_VALUE 64000000UL /*!< Value of the High-Speed Internal oscillator in Hz */
|
||||
#endif /* HSI_VALUE */
|
||||
|
||||
#if !defined (CSI_VALUE)
|
||||
#define CSI_VALUE 4000000UL /*!< Value of the Low-power Internal oscillator in Hz */
|
||||
#endif /* CSI_VALUE */
|
||||
|
||||
/* Note: Following vector table addresses must be defined in line with linker
|
||||
configuration. */
|
||||
/*!< Uncomment the following line or define USER_VECT_TAB_ADDRESS at compiler level if you need
|
||||
to relocate the vector table anywhere in Flash or Sram, else the vector table is kept at
|
||||
the automatic remap of the selected boot address */
|
||||
/* #define USER_VECT_TAB_ADDRESS */
|
||||
|
||||
#if defined(USER_VECT_TAB_ADDRESS)
|
||||
/*!< Uncomment the following line or define VECT_TAB_SRAM at compiler level if you need
|
||||
to relocate your vector Table in Sram else user remap will be done in Flash. */
|
||||
/* #define VECT_TAB_SRAM */
|
||||
|
||||
#if defined(VECT_TAB_SRAM)
|
||||
#if !defined(VECT_TAB_BASE_ADDRESS)
|
||||
#define VECT_TAB_BASE_ADDRESS ITCM_BASE /*!< Vector Table base address field.
|
||||
This value must be a multiple of 0x400. */
|
||||
#endif
|
||||
#if !defined(VECT_TAB_OFFSET)
|
||||
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
|
||||
This value must be a multiple of 0x400. */
|
||||
#endif
|
||||
#else
|
||||
#if !defined(VECT_TAB_BASE_ADDRESS)
|
||||
#define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field.
|
||||
This value must be a multiple of 0x400. */
|
||||
#endif
|
||||
#if !defined(VECT_TAB_OFFSET)
|
||||
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
|
||||
This value must be a multiple of 0x400. */
|
||||
#endif
|
||||
#endif /* VECT_TAB_SRAM */
|
||||
#endif /* USER_VECT_TAB_ADDRESS */
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H7RSxx_System_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H7RSxx_System_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
/* The SystemCoreClock variable is updated in two ways:
|
||||
1) by calling CMSIS function SystemCoreClockUpdate()
|
||||
2) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
|
||||
Note: If you use this function to configure the system clock; then there
|
||||
is no need to call the first function listed above, since SystemCoreClock
|
||||
variable is updated automatically.
|
||||
*/
|
||||
uint32_t SystemCoreClock = HSI_VALUE;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H7RSxx_System_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H7RSxx_System_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Setup the microcontroller system.
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
void SystemInit(void)
|
||||
{
|
||||
/* Configure the Vector Table location -------------------------------------*/
|
||||
#if defined(USER_VECT_TAB_ADDRESS)
|
||||
SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET;
|
||||
#endif
|
||||
|
||||
/* FPU settings ------------------------------------------------------------*/
|
||||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||
SCB->CPACR |= ((3UL << 20U)|(3UL << 22U)); /* set CP10 and CP11 Full Access */
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update SystemCoreClock variable according to RCC registers values.
|
||||
* The SystemCoreClock variable contains the core clock (sys_cpu_ck), it can
|
||||
* be used by the user application to setup the SysTick timer or configure
|
||||
* other parameters.
|
||||
*
|
||||
* @note Each time the core clock changes, this function must be called
|
||||
* to update SystemCoreClock variable value. Otherwise, any configuration
|
||||
* based on this variable will be incorrect.
|
||||
*
|
||||
* @note - The system frequency computed by this function is not the real
|
||||
* frequency in the chip. It is calculated based on the predefined
|
||||
* constant and the selected clock source:
|
||||
*
|
||||
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
|
||||
*
|
||||
* - If SYSCLK source is CSI, SystemCoreClock will contain the CSI_VALUE(**)
|
||||
*
|
||||
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
|
||||
*
|
||||
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSI_VALUE(*)
|
||||
* or CSI_VALUE(**) or HSE_VALUE(***) multiplied/divided by the PLL factors.
|
||||
*
|
||||
* (*) HSI_VALUE is a constant defined in stm32h7rsxx_hal.h file (default value
|
||||
* 64 MHz) but the real value may vary depending on the variations
|
||||
* in voltage and temperature.
|
||||
*
|
||||
* (**) CSI_VALUE is a constant defined in stm32h7rsxx_hal.h file (default value
|
||||
* 4 MHz) but the real value may vary depending on the variations
|
||||
* in voltage and temperature.
|
||||
*
|
||||
* (***) HSE_VALUE is a constant defined in stm32h7rsxx_hal.h file (default value
|
||||
* 24 MHz), user has to ensure that HSE_VALUE is same as the real
|
||||
* frequency of the crystal used. Otherwise, this function may
|
||||
* have wrong result.
|
||||
*
|
||||
* - The result of this function could be not correct when using fractional
|
||||
* value for HSE crystal.
|
||||
*
|
||||
* @retval None
|
||||
*/
|
||||
void SystemCoreClockUpdate(void)
|
||||
{
|
||||
uint32_t sysclk, hsivalue, pllsource, pllm, pllp, core_presc;
|
||||
float_t pllfracn, pllvco;
|
||||
|
||||
/* Get SYSCLK source -------------------------------------------------------*/
|
||||
switch (RCC->CFGR & RCC_CFGR_SWS)
|
||||
{
|
||||
case 0x00: /* HSI used as system clock source (default after reset) */
|
||||
sysclk = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos));
|
||||
break;
|
||||
|
||||
case 0x08: /* CSI used as system clock source */
|
||||
sysclk = CSI_VALUE;
|
||||
break;
|
||||
|
||||
case 0x10: /* HSE used as system clock source */
|
||||
sysclk = HSE_VALUE;
|
||||
break;
|
||||
|
||||
case 0x18: /* PLL1 used as system clock source */
|
||||
/* PLL1_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLLM) * PLLN
|
||||
SYSCLK = PLL1_VCO / PLL1R
|
||||
*/
|
||||
pllsource = (RCC->PLLCKSELR & RCC_PLLCKSELR_PLLSRC);
|
||||
pllm = ((RCC->PLLCKSELR & RCC_PLLCKSELR_DIVM1) >> RCC_PLLCKSELR_DIVM1_Pos) ;
|
||||
if ((RCC->PLLCFGR & RCC_PLLCFGR_PLL1FRACEN) != 0U)
|
||||
{
|
||||
pllfracn = (float_t)(uint32_t)(((RCC->PLL1FRACR & RCC_PLL1FRACR_FRACN)>> RCC_PLL1FRACR_FRACN_Pos));
|
||||
}
|
||||
else
|
||||
{
|
||||
pllfracn = (float_t)0U;
|
||||
}
|
||||
|
||||
if (pllm != 0U)
|
||||
{
|
||||
switch (pllsource)
|
||||
{
|
||||
case 0x02: /* HSE used as PLL1 clock source */
|
||||
pllvco = ((float_t)HSE_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) + (pllfracn/(float_t)0x2000) +(float_t)1 );
|
||||
break;
|
||||
|
||||
case 0x01: /* CSI used as PLL1 clock source */
|
||||
pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) + (pllfracn/(float_t)0x2000) +(float_t)1 );
|
||||
break;
|
||||
|
||||
case 0x00: /* HSI used as PLL1 clock source */
|
||||
default:
|
||||
hsivalue = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos));
|
||||
pllvco = ( (float_t)hsivalue / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) + (pllfracn/(float_t)0x2000) +(float_t)1 );
|
||||
break;
|
||||
}
|
||||
pllp = (((RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVP) >> RCC_PLL1DIVR1_DIVP_Pos) + 1U ) ;
|
||||
sysclk = (uint32_t)(float_t)(pllvco/(float_t)pllp);
|
||||
}
|
||||
else
|
||||
{
|
||||
sysclk = 0U;
|
||||
}
|
||||
break;
|
||||
|
||||
default: /* Unexpected, default to HSI used as system clock source (default after reset) */
|
||||
sysclk = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos));
|
||||
break;
|
||||
}
|
||||
|
||||
/* system clock frequency : CM7 CPU frequency */
|
||||
core_presc = (RCC->CDCFGR & RCC_CDCFGR_CPRE);
|
||||
if (core_presc >= 8U)
|
||||
{
|
||||
SystemCoreClock = (sysclk >> (core_presc - RCC_CDCFGR_CPRE_3 + 1U));
|
||||
}
|
||||
else
|
||||
{
|
||||
SystemCoreClock = sysclk;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
Reference in new issue
Block a user