added basic hard fault handler, moving shit around; debounce made to work
This commit is contained in:
+5
-4
@@ -64,13 +64,14 @@ void MX_GPIO_Init(void)
|
||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOE, SPI1_CS_Pin|LED4_Pin|LED3_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(GPIOE, SPI1_CS_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(GPIOE, LED4_Pin|LED3_Pin, 1); // MX: Changed
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(AUDIO_NSTBY_GPIO_Port, AUDIO_NSTBY_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(AUDIO_NSTBY_GPIO_Port, AUDIO_NSTBY_Pin, 1); // MX: Changed
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOD, LED2_Pin|LED1_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(GPIOD, LED2_Pin|LED1_Pin, 1); // MX: Changed
|
||||
|
||||
/*Configure GPIO pins : PEPin PEPin PEPin */
|
||||
GPIO_InitStruct.Pin = SPI1_CS_Pin|LED4_Pin|LED3_Pin;
|
||||
@@ -89,7 +90,7 @@ void MX_GPIO_Init(void)
|
||||
GPIO_InitStruct.Pin = BTN_UP_Pin|BTN_DN_Pin|BTN_L_Pin|BTN_R_Pin
|
||||
|BTN_CE_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP; // MX: Changed
|
||||
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : PDPin PDPin */
|
||||
|
||||
+50
-3
@@ -44,7 +44,7 @@
|
||||
extern DMA_HandleTypeDef hdma_adc1;
|
||||
|
||||
/******************************************************************************/
|
||||
/* Cortex-M3 Processor Interruption and Exception Handlers */
|
||||
/* Cortex-M3 Processor Interruption and Exception Handlers */
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
@@ -60,13 +60,61 @@ void NMI_Handler(void)
|
||||
/* USER CODE END NonMaskableInt_IRQn 1 */
|
||||
}
|
||||
|
||||
|
||||
/* USER CODE BEGIN prvGetRegistersFromStack */
|
||||
/**
|
||||
* Hard Fault diagnosis function (for use with debugger)
|
||||
*
|
||||
* Source:
|
||||
* http://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html
|
||||
*/
|
||||
static void __attribute__((noreturn)) __attribute__((used))
|
||||
prvGetRegistersFromStack(uint32_t *pulFaultStackAddress)
|
||||
{
|
||||
/* These are volatile to try and prevent the compiler/linker optimising them
|
||||
away as the variables never actually get used. If the debugger won't show the
|
||||
values of the variables, make them global my moving their declaration outside
|
||||
of this function. */
|
||||
volatile __attribute__((unused)) uint32_t r0;
|
||||
volatile __attribute__((unused)) uint32_t r1;
|
||||
volatile __attribute__((unused)) uint32_t r2;
|
||||
volatile __attribute__((unused)) uint32_t r3;
|
||||
volatile __attribute__((unused)) uint32_t r12;
|
||||
volatile __attribute__((unused)) uint32_t lr; /* Link register. */
|
||||
volatile __attribute__((unused)) uint32_t pc; /* Program counter. */
|
||||
volatile __attribute__((unused)) uint32_t psr;/* Program status register. */
|
||||
|
||||
r0 = pulFaultStackAddress[ 0 ];
|
||||
r1 = pulFaultStackAddress[ 1 ];
|
||||
r2 = pulFaultStackAddress[ 2 ];
|
||||
r3 = pulFaultStackAddress[ 3 ];
|
||||
|
||||
r12 = pulFaultStackAddress[ 4 ];
|
||||
lr = pulFaultStackAddress[ 5 ];
|
||||
pc = pulFaultStackAddress[ 6 ];
|
||||
psr = pulFaultStackAddress[ 7 ];
|
||||
|
||||
/* When the following line is hit, the variables contain the register values. */
|
||||
for (;;);
|
||||
}
|
||||
/* USER CODE END prvGetRegistersFromStack */
|
||||
|
||||
/**
|
||||
* @brief This function handles Hard fault interrupt.
|
||||
*/
|
||||
void HardFault_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN HardFault_IRQn 0 */
|
||||
uart_print("Hard fault.\n");
|
||||
__asm volatile
|
||||
(
|
||||
" tst lr, #4 \n"
|
||||
" ite eq \n"
|
||||
" mrseq r0, msp \n"
|
||||
" mrsne r0, psp \n"
|
||||
" ldr r1, [r0, #24] \n"
|
||||
" ldr r2, =prvGetRegistersFromStack \n"
|
||||
" bx r2 \n"
|
||||
);
|
||||
|
||||
/* USER CODE END HardFault_IRQn 0 */
|
||||
while (1)
|
||||
@@ -204,6 +252,5 @@ void DMA1_Channel1_IRQHandler(void)
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
||||
register char * stack_ptr asm("sp");
|
||||
|
||||
caddr_t _sbrk(int incr)
|
||||
{
|
||||
extern char end __asm("end");
|
||||
static char *heap_end;
|
||||
char *prev_heap_end;
|
||||
|
||||
if (heap_end == 0)
|
||||
heap_end = &end;
|
||||
|
||||
prev_heap_end = heap_end;
|
||||
if (heap_end + incr > stack_ptr)
|
||||
{
|
||||
// write(1, "Heap and stack collision\n", 25);
|
||||
// abort();
|
||||
errno = ENOMEM;
|
||||
return (caddr_t) -1;
|
||||
}
|
||||
|
||||
heap_end += incr;
|
||||
|
||||
return (caddr_t) prev_heap_end;
|
||||
}
|
||||
|
||||
|
||||
// Other systcalls are defined in
|
||||
// - com/com_fileio.c
|
||||
// - hw_utils/reset.h
|
||||
@@ -50,7 +50,7 @@ void MX_TIM3_Init(void)
|
||||
htim3.Instance = TIM3;
|
||||
htim3.Init.Prescaler = 0;
|
||||
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
htim3.Init.Period = 1800*2;
|
||||
htim3.Init.Period = 1800;
|
||||
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||
if (HAL_TIM_OC_Init(&htim3) != HAL_OK)
|
||||
{
|
||||
|
||||
-225
@@ -1,225 +0,0 @@
|
||||
//
|
||||
// Created by MightyPork on 2.9.16.
|
||||
//
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stm32f1xx_hal_gpio.h>
|
||||
#include <dotmatrix.h>
|
||||
#include <arm_math.h>
|
||||
#include <arm_const_structs.h>
|
||||
#include "mxconstants.h"
|
||||
#include "stm32f1xx_hal.h"
|
||||
#include "utils.h"
|
||||
#include "adc.h"
|
||||
#include "tim.h"
|
||||
#include "user_main.h"
|
||||
|
||||
#define SAMPLE_COUNT 256
|
||||
#define BIN_COUNT (SAMPLE_COUNT/2)
|
||||
|
||||
#define SCREEN_W 32
|
||||
#define SCREEN_H 16
|
||||
|
||||
static uint32_t audio_samples[SAMPLE_COUNT * 2]; // 2x size needed for complex FFT
|
||||
static float *audio_samples_f = (float *) audio_samples;
|
||||
|
||||
static DotMatrix_Cfg *disp;
|
||||
|
||||
static volatile bool capture_pending = false;
|
||||
|
||||
static void display_wave();
|
||||
static void display_fft();
|
||||
|
||||
void capture_start()
|
||||
{
|
||||
if (capture_pending) return;
|
||||
capture_pending = true;
|
||||
|
||||
//uart_print("- Starting ADC DMA\n");
|
||||
|
||||
HAL_ADC_Start_DMA(&hadc1, audio_samples, SAMPLE_COUNT);
|
||||
HAL_TIM_Base_Start(&htim3);
|
||||
}
|
||||
|
||||
/** This callback is called by HAL after the transfer is complete */
|
||||
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
|
||||
{
|
||||
display_wave();
|
||||
capture_pending = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert audio samples to float.
|
||||
* NOTE: This trashes the original array of ints, they share the same memory location.
|
||||
*/
|
||||
void samples_to_float()
|
||||
{
|
||||
// Convert to float
|
||||
for (int i = 0; i < SAMPLE_COUNT; i++) {
|
||||
audio_samples_f[i] = (float) audio_samples[i];
|
||||
}
|
||||
|
||||
// Obtain mean value
|
||||
float mean;
|
||||
arm_mean_f32(audio_samples_f, SAMPLE_COUNT, &mean);
|
||||
|
||||
// Subtract mean from all samples
|
||||
for (int i = 0; i < SAMPLE_COUNT; i++) {
|
||||
audio_samples_f[i] -= mean;
|
||||
}
|
||||
}
|
||||
|
||||
/** Spread numbers in the samples array so that they are interleaved by zeros (imaginary part) */
|
||||
void spread_samples_for_fft()
|
||||
{
|
||||
for (int i = SAMPLE_COUNT - 1; i >= 0; i--) {
|
||||
audio_samples_f[i * 2 + 1] = 0; // imaginary
|
||||
audio_samples_f[i * 2] = audio_samples_f[i]; // real
|
||||
}
|
||||
}
|
||||
|
||||
/** Display waveform preview */
|
||||
void display_wave()
|
||||
{
|
||||
float wave_y_mult = 0.0078125f;
|
||||
float relative = 1;
|
||||
|
||||
samples_to_float();
|
||||
|
||||
int x_offset = 0;
|
||||
|
||||
for (int i = 1; i < SAMPLE_COUNT; i++) {
|
||||
if (audio_samples_f[i] > 0 && audio_samples_f[i-1] < 0) {
|
||||
x_offset = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// make sure we're not gonna run out of range
|
||||
if (x_offset >= SAMPLE_COUNT - SCREEN_W) {
|
||||
x_offset = 0;
|
||||
}
|
||||
|
||||
dmtx_clear(disp);
|
||||
for (int i = 0; i < SCREEN_W; i++) {
|
||||
dmtx_set(disp, i, 7 + roundf(audio_samples_f[i + x_offset] * wave_y_mult * relative), 1);
|
||||
}
|
||||
dmtx_show(disp);
|
||||
}
|
||||
|
||||
/** Calculate and display FFT */
|
||||
static void display_fft()
|
||||
{
|
||||
float *bins = audio_samples_f;
|
||||
|
||||
samples_to_float();
|
||||
spread_samples_for_fft();
|
||||
|
||||
const arm_cfft_instance_f32 *S;
|
||||
S = &arm_cfft_sR_f32_len128;
|
||||
|
||||
arm_cfft_f32(S, bins, 0, true); // bit reversed FFT
|
||||
arm_cmplx_mag_f32(bins, bins, BIN_COUNT); // get magnitude (extract real values)
|
||||
|
||||
// Normalize & display
|
||||
|
||||
dmtx_clear(dmtx);
|
||||
|
||||
float factor = (1.0f / BIN_COUNT) * 0.25f;
|
||||
for (int i = 0; i < BIN_COUNT; i++) { // +1 because bin 0 is always 0
|
||||
bins[i] *= factor;
|
||||
}
|
||||
|
||||
// TODO implement offset using gamepad buttons
|
||||
for (int x = 0; x < SCREEN_W; x++) {
|
||||
for (int j = 0; j < 1 + floorf(bins[x]); j++) {
|
||||
dmtx_set(dmtx, x, j, 1);
|
||||
}
|
||||
}
|
||||
|
||||
dmtx_show(dmtx);
|
||||
}
|
||||
|
||||
|
||||
void user_main()
|
||||
{
|
||||
uart_print("== USER CODE STARTING ==\n");
|
||||
|
||||
// Leds OFF
|
||||
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, 1);
|
||||
HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, 1);
|
||||
HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, 1);
|
||||
HAL_GPIO_WritePin(LED4_GPIO_Port, LED4_Pin, 1);
|
||||
|
||||
// Enable audio input
|
||||
HAL_GPIO_WritePin(AUDIO_NSTBY_GPIO_Port, AUDIO_NSTBY_Pin, 1);
|
||||
|
||||
DotMatrix_Init disp_init;
|
||||
disp_init.cols = 4;
|
||||
disp_init.rows = 2;
|
||||
disp_init.CS_GPIOx = SPI1_CS_GPIO_Port;
|
||||
disp_init.CS_PINx = SPI1_CS_Pin;
|
||||
disp_init.SPIx = SPI1;
|
||||
disp = dmtx_init(&disp_init);
|
||||
|
||||
dmtx_intensity(disp, 7);
|
||||
|
||||
dmtx_clear(disp);
|
||||
dmtx_show(disp);
|
||||
|
||||
uint32_t counter1 = 0;
|
||||
uint32_t counter2 = 0;
|
||||
while (1) {
|
||||
if (counter1++ == 500) {
|
||||
counter2 = 0;
|
||||
// Blink
|
||||
HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
|
||||
}
|
||||
|
||||
if (counter2++ >= 5) {
|
||||
if (!capture_pending) {
|
||||
counter2 = 0;
|
||||
capture_start();
|
||||
}
|
||||
}
|
||||
|
||||
HAL_Delay(1);
|
||||
}
|
||||
}
|
||||
|
||||
//region Error handlers
|
||||
|
||||
void user_Error_Handler()
|
||||
{
|
||||
uart_print("HAL error occurred.\n");
|
||||
while (1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reports the name of the source file and the source line number
|
||||
* where the assert_param error has occurred.
|
||||
* @param file: pointer to the source file name
|
||||
* @param line: assert_param error line source number
|
||||
* @retval None
|
||||
*/
|
||||
void user_assert_failed(uint8_t *file, uint32_t line)
|
||||
{
|
||||
user_error_file_line("Assert failed", (const char *) file, line);
|
||||
}
|
||||
|
||||
void user_error_file_line(const char *message, const char *file, uint32_t line)
|
||||
{
|
||||
uart_print(message);
|
||||
uart_print(" in file ");
|
||||
uart_print((char *) file);
|
||||
uart_print(" on line ");
|
||||
|
||||
char x[10];
|
||||
sprintf(x, "%"PRIu32, line);
|
||||
uart_print(x);
|
||||
uart_print("\n");
|
||||
|
||||
while (1);
|
||||
}
|
||||
|
||||
// endregion
|
||||
Reference in New Issue
Block a user