Skip to content

Commit

Permalink
v0.3: addded exceptions.c and reworked stdream module
Browse files Browse the repository at this point in the history
  • Loading branch information
SMFSW committed Apr 24, 2017
1 parent ad54b37 commit 2665c7d
Show file tree
Hide file tree
Showing 6 changed files with 240 additions and 38 deletions.
41 changes: 31 additions & 10 deletions GPIO_ex.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
/*!\file GPIO_ex.c
** \author SMFSW
** \version v0.2
** \version v0.3
** \date 2017
** \copyright MIT (c) 2017, SMFSW
** \brief Simple extension for GPIOs
**/
#include <string.h>
#include <assert.h>

#include "GPIO_ex.h"

Expand All @@ -14,21 +15,41 @@

int str_GPIO_name(char * name, GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
const char *port, prt[][7] = { "GPIOA", "GPIOB", "GPIOC", "GPIOD", "GPIOF", "GPIO?" };
char pin;
const char *port, prt[][7] = { "GPIOA", "GPIOB", "GPIOC", "GPIOD", "GPIOE", "GPIOF", "GPIOG", "GPIOH", "GPIO?" };

/* Check the parameters */
assert_param(name);
assert_param(IS_GPIO_PIN(GPIO_Pin));

if (!name) { return -1; } // pointer for storage is not defined

// Find port comparing address
if (GPIOx == GPIOA) { port = prt[0]; }
else if (GPIOx == GPIOB) { port = prt[1]; }
else if (GPIOx == GPIOC) { port = prt[2]; }
else if (GPIOx == GPIOD) { port = prt[3]; }
else if (GPIOx == GPIOF) { port = prt[4]; }
else { port = prt[5]; }
if (GPIOx == GPIOA) port = prt[0];
#if defined(GPIOB)
else if (GPIOx == GPIOB) port = prt[1];
#endif
#if defined(GPIOC)
else if (GPIOx == GPIOC) port = prt[2];
#endif
#if defined(GPIOD)
else if (GPIOx == GPIOD) port = prt[3];
#endif
#if defined(GPIOE)
else if (GPIOx == GPIOE) port = prt[4];
#endif
#if defined(GPIOF)
else if (GPIOx == GPIOF) port = prt[5];
#endif
#if defined(GPIOG)
else if (GPIOx == GPIOG) port = prt[6];
#endif
#if defined(GPIOH)
else if (GPIOx == GPIOH) port = prt[7];
#endif
else port = prt[8];

// Find pin shifting values to get pin index
for (pin = 0 ; pin < MAX_PINS_PORT ; pin++)
for (int pin = 0 ; pin < MAX_PINS_PORT ; pin++)
{
if (1U << pin == GPIO_Pin)
{
Expand Down
4 changes: 2 additions & 2 deletions PWM.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ HAL_StatusTypeDef set_PWM_Freq(TIM_HandleTypeDef * pTim, uint32_t Freq)
if (Freq > coreCLK / 100) { return HAL_ERROR; }

// TODO: find prescaler & period with i++ instead of shifts
for (i = 1 ; i < (uint16_t) -1 ; i<<=1)
for (i = 1 ; i < (uint16_t) -1 ; i <<= 1)
{
per = (coreCLK / (Freq * (i + 1))) - 1;
if (per <= (uint16_t) -1) { break; } // If in 16b range
if (i == 1<<15) { return HAL_ERROR; } // If nothing has been found (last iteration)
if (i == 1 << 15) { return HAL_ERROR; } // If nothing has been found (last iteration)
}

pTim->Init.Period = per;
Expand Down
77 changes: 77 additions & 0 deletions exceptions.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*!\file exceptions.c
** \author SMFSW
** \version v0.3
** \date 2017
** \copyright MIT (c) 2017, SMFSW
** \brief Debug tool helpers functions
**/

#include <string.h>

#include "exceptions.h"

#include "stdream_rdir.h"


void stackDump(uint32_t stack[])
{
enum { r0, r1, r2, r3, r12, lr, pc, psr};

printf("r0 = 0x%08lx\n", stack[r0]);
printf("r1 = 0x%08lx\n", stack[r1]);
printf("r2 = 0x%08lx\n", stack[r2]);
printf("r3 = 0x%08lx\n", stack[r3]);
printf("r12 = 0x%08lx\n", stack[r12]);
printf("lr = 0x%08lx\n", stack[lr]);
printf("pc = 0x%08lx\n", stack[pc]);
printf("psr = 0x%08lx\n", stack[psr]);
}


void HardFault_Handler_callback(uint32_t stack[])
{
printf("Hard Fault handler\t");
printf("SCB->HFSR = 0x%08lx\n", SCB->HFSR);

if ((SCB->HFSR & (1 << 30)) != 0)
{
uint32_t CFSRValue = SCB->CFSR;

printf("Hard Fault\t");
printf("SCB->CFSR = 0x%08lx\n", CFSRValue);
if ((SCB->CFSR & 0xFFFF0000) != 0)
{
printf("Usage fault: ");
CFSRValue >>= 16; // right shift to lsb
if((CFSRValue & (1 << 9)) != 0) { printf("Zero div\n"); }
}

if ((SCB->CFSR & 0xFF00) != 0)
{
CFSRValue = ((CFSRValue & 0x0000FF00) >> 8); // mask and shift
printf("Bus fault: 0x%02lx\n", CFSRValue);
}

if ((SCB->CFSR & 0xFF) != 0) {
CFSRValue &= 0x000000FF; // mask other faults
printf("Memory Management fault: 0x%02lx\n", CFSRValue);
}
}

stackDump(stack);

__BKPT(01);
while(1);
}


void Error_Handler_callback(uint32_t stack[])
{
// TODO: maybe pass by another asm code to retrieve HAL error code if not in stack
printf("Error handler\t");
stackDump(stack);

// __BKPT(01);
// while(1);
}

43 changes: 43 additions & 0 deletions exceptions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*!\file exceptions.h
** \author SMFSW
** \version v0.3
** \date 2017
** \copyright MIT (c) 2017, SMFSW
** \brief Debug tool and helpers declaration
**/
/****************************************************************/
#ifndef __EXCEPTIONS_H
#define __EXCEPTIONS_H
/****************************************************************/

#include "sarmfsw.h"
#include CMSIS_INC
#include CMSIS_CFG


#define exception_Handler(e) \
__asm( "tst lr, #4 \n" \
"ite EQ \n" \
"mrseq r0, MSP \n" \
"mrsne r0, PSP \n" \
"b " #e "_Handler_callback \n") //!< The exception_Handler should be called with corresponding exception name \b e as parameter


#define dump_stack() \
__asm( "tst lr, #4 \n" \
"ite EQ \n" \
"mrseq r0, MSP \n" \
"mrsne r0, PSP \n" \
"b stackDump \n")


/* Handled callbacks for reference
** (not really needed as called by assembly from macro)
** use macros to pass stack pointer properly */
void HardFault_Handler_callback(uint32_t stack[]); // HardFault handler
void Error_Handler_callback(uint32_t stack[]); // HAL Error handler


/****************************************************************/
#endif
/****************************************************************/
92 changes: 74 additions & 18 deletions stdream_rdir.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*!\file stream_redirect.c
** \author SMFSW
** \version v0.2
** \version v0.3
** \date 2017
** \copyright MIT (c) 2017, SMFSW
** \brief Stream redirection
Expand All @@ -12,55 +12,111 @@

#include "stdream_rdir.h"

#include "arm_stdclib.h"


static char buf_stream[128] = "";


#if defined(HAL_UART_MODULE_ENABLED)
#include "usart.h"

#if !defined(DBG_SERIAL)
#error "You have to define DBG_SERIAL in usart.h with an UART instance for this to work!"
#warning "You have to define DBG_SERIAL in usart.h with an UART instance for this to work!"
#endif

__STATIC_INLINE void __attribute__((always_inline)) print_uart(char* ptr, int len)
{
HAL_UART_Transmit(DBG_SERIAL, (uint8_t *) ptr, len, 30);
}

static char buf_stream[128] = "";
#endif


// Used to redirect stuff printed with printf and puts
/*int _write(int file, char *ptr, int len)
static void print_itm(const char * msg, int len)
{
int i=0;
for(i=0 ; i<len ; i++)
ITM_SendChar((*ptr++));
return len;
}*/
//while (*msg != '\0')
for (int i = 0 ; i < len ; i++)
ITM_SendChar(*msg++);
}


__STATIC_INLINE void __attribute__((always_inline)) uart_prt(char* ptr, int len)
void print_itm_port(int port, const char * msg, int len)
{
HAL_UART_Transmit(DBG_SERIAL, (uint8_t *) ptr, len, 30);
for (int i = 0 ; i < len ; i++)
{
while (ITM->PORT[port].u32 == 0);
ITM->PORT[port].u8 = *msg++;
}
}


int uart_printf(char *string, ...)
/********************/
/*** PRINTF LIKES ***/
/********************/

/*** ITM ***/
int printf_ITM(char * string, ...)
{
va_list args;

va_start(args, string);
vsprintf(buf_stream, string, args);
va_end(args);
uart_prt(buf_stream, strlen(buf_stream));
buf_stream[0] = '\0'; // Erase string
print_itm(buf_stream, strlen(buf_stream));
str_clr(buf_stream); // Erase string
return 0;
}

int vprintf_ITM(char * string, va_list args)
{
vsprintf(buf_stream, string, args);
print_itm(buf_stream, strlen(buf_stream));
str_clr(buf_stream); // Erase string
return 0;
}


int uart_vprintf(char *string, va_list args)
/*** GENERAL REDIRECTION ***/
int printf_rdir(char * string, ...)
{
uint16_t len;
va_list args;

va_start(args, string);
vsprintf(buf_stream, string, args);
uart_prt(buf_stream, strlen(buf_stream));
buf_stream[0] = '\0'; // Erase string
va_end(args);
len = strlen(buf_stream);

#if defined(ITM_ENABLED)
print_itm(buf_stream, len);
#endif

#if defined(DBG_SERIAL)
print_uart(buf_stream, len);
#endif

str_clr(buf_stream); // Erase string
return 0;
}


int vprintf_rdir(char * string, va_list args)
{
uint16_t len;

vsprintf(buf_stream, string, args);
len = strlen(buf_stream);

#if defined(ITM_ENABLED)
print_itm(buf_stream, len);
#endif

#if defined(DBG_SERIAL)
print_uart(buf_stream, len);
#endif

str_clr(buf_stream); // Erase string
return 0;
}

21 changes: 13 additions & 8 deletions stdream_rdir.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*!\file stream_redirect.h
** \author SMFSW
** \version v0.1
** \version v0.3
** \date 2017
** \copyright MIT (c) 2017, SMFSW
** \brief Stream redirection header
Expand All @@ -18,17 +18,22 @@
#include CMSIS_CFG


#if defined(HAL_UART_MODULE_ENABLED)
#include "usart.h"
#define ITM_ENABLED // Enable ITM send if defined

#define printf uart_printf // Shadowing printf use
#define vprintf uart_vprintf // Shadowing vprintf use

#define printf printf_rdir // Shadowing printf use
#define vprintf vprintf_rdir // Shadowing vprintf use

int uart_printf(char *string, ...);
int uart_vprintf(char *string, va_list args);

#endif
void print_itm_port(int port, const char * msg, int len);

// printf_ITM & vprintf_ITM will be redirected to ITM port 0 (ITM_SendChar used)
int printf_ITM(char * string, ...);
int vprintf_ITM(char * string, va_list args);

// General printf & vprintf redirection, will flood all enabled ports (at the cost of speed)
int printf_rdir(char * string, ...);
int vprintf_rdir(char * string, va_list args);


/****************************************************************/
Expand Down

0 comments on commit 2665c7d

Please sign in to comment.