added basic hard fault handler, moving shit around; debounce made to work

This commit is contained in:
2016-09-03 12:55:17 +02:00
parent 39296f1b8a
commit 3fd42eb41a
17 changed files with 892 additions and 34 deletions
+5 -4
View File
@@ -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
View File
@@ -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****/
-32
View 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
+1 -1
View File
@@ -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
View File
@@ -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