Created
October 12, 2023 01:05
-
-
Save hraftery/902504b51316d6c4871ddcfbcf4825f3 to your computer and use it in GitHub Desktop.
Project wide includes, macros and types.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* \file | |
* | |
* \brief General utility functions | |
* | |
* \author Heath Raftery | |
* \date July, 2016 | |
*/ | |
#ifndef __COMMON_H__ | |
#define __COMMON_H__ | |
//===================== | |
// INCLUDES | |
//===================== | |
/** All modules should be using these utils. */ | |
#include "util/assert.h" | |
#include "util/fault.h" | |
//===================== | |
// TYPES | |
//===================== | |
/** Use the std bool and ints (uint32_t et al.) liberally */ | |
#include <stdbool.h> | |
#include <stdint.h> | |
/** | |
* A date/time value, as the number of seconds since 00:00 hours, Jan 1, 1970 UTC. | |
* Compatible with the Unix timestamp, and most time_t implementations. | |
*/ | |
typedef uint32_t tDatetime; | |
//===================== | |
// DEFINES | |
//===================== | |
/** Get the number of elements in a statically defined array */ | |
#define NUM_ELEMS(x) (sizeof(x) / sizeof((x)[0])) | |
/** | |
* Get n rounded up to a multiple of m. Eg ROUND_UP(12,5) = 15, ROUND_UP(4,4) = 4. | |
* Only intended for positive integers. | |
* \see http://stackoverflow.com/questions/3407012/ | |
*/ | |
#define ROUND_UP(n,m) ( (n)==0 ? (n) : ( ((n)+(m)-1) - (((n)-1)%(m)) ) ) | |
/** | |
* Get n rounded down to a multiple of m. Eg ROUND_DOWN(12,5) = 10, ROUND_DOWN(4,4) = 4, ROUND_DOWN(-1,4) = -4. | |
* Works with negative integers for the first argument. | |
* \see https://gist.github.com/aslakhellesoy/1134482 | |
*/ | |
#define ROUND_DOWN(n,m) ( (n) >= 0 ? ((n) / (m)) * (m) : (((n) - (m) + 1) / (m)) * (m) ) | |
/** | |
* Perform integer division n/d but round to nearest integer instead of truncating by adding d/2 first. | |
* Only intended for positive integers. See \ref DIV_ROUND_INT for signed integers support. | |
* \see http://stackoverflow.com/questions/2422712/c-rounding-integer-division-instead-of-truncating | |
*/ | |
#define DIV_ROUND(n,d) ((((n) + (d)/2)/(d))) | |
/** | |
* Perform integer division n/d but round to nearest integer instead of truncating. | |
* Works with positive or negative integers. | |
* \see http://stackoverflow.com/questions/2422712/c-rounding-integer-division-instead-of-truncating | |
*/ | |
#define DIV_ROUND_INT(n,d) ((((n) < 0) ^ ((d) < 0)) ? (((n) - (d)/2)/(d)) : (((n) + (d)/2)/(d))) | |
/** | |
* Return -1, 0 or 1 depending on whether x is negative, zero or positive. | |
* \see http://stackoverflow.com/questions/1903954/is-there-a-standard-sign-function-signum-sgn-in-c-c | |
*/ | |
#define SIGN(x) ((x > 0) - (x < 0)) | |
/** | |
* Get the number of wordSize words required to wholly contain numBytes. | |
* Eg. NUM_WORDS_FOR_BYTES(12,5) = 3, NUM_WORDS_FOR_BYTES(4,4) = 1. | |
* Only intended for positive integers. Could do with a better name. | |
*/ | |
#define NUM_WORDS_FOR_BYTES(numBytes, wordSize) (((numBytes)+(wordSize)-1)/(wordSize)) | |
/** Get the sizeof a member of a struct type. */ | |
#define SIZEOF_MEMBER(type, member) sizeof(((type *)0)->member) | |
/** Turn a define into a string by wrapping it in double quotes */ | |
#define STRINGIFY(s) STRINGIFY_HELPER(s) | |
#define STRINGIFY_HELPER(s) #s /* two macro levels required, as per https://gcc.gnu.org/onlinedocs/cpp/Stringification.html */ | |
/** Simple linear interpolation macro, without the overhead of std::lerp | |
* Returns the linear interpolation of x on the line (x0,y0) to (x1,y1) */ | |
#define LERP(x, x0, x1, y0, y1) (y0 + ((y1-y0)/(x1-x0)) * (x-x0)) | |
/** Stop the current task. Interrupts can still fire so context switches can still occur. */ | |
#define HALT() while(1) __asm volatile( "NOP" ); | |
#include "config/FreeRTOSConfig.h" | |
/** | |
* All interrupts that we enable should have priority >= configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY | |
* so we are free to call *FromISR FreeRTOS functions from the ISR. See the "Inverse Relationship Between | |
* Numeric Priority Value and the Logical Priority Setting" section of | |
* http://www.freertos.org/RTOS-Cortex-M3-M4.html for details. | |
*/ | |
#define INTERRUPT_PRIORITY configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY | |
/** | |
* This is a replacement for the retarded irq_register_handler in interrupt_sam_nvic.h. The documentation | |
* for irq_register_handler is so bad as to be considered dangerous. This version does what it says. | |
* In SAM4E, IRQ handlers are already assigned in the vector table (see startup_sam4e.c) so all one needs | |
* to do to enable an interrupt is call this define and provide a definition of the corresponding | |
* handler (see exceptions.c). irq_num must be of type IRQn_Type (see sam4e16e.h). | |
*/ | |
#define irq_enable(irq_num) \ | |
do { \ | |
NVIC_ClearPendingIRQ(irq_num); \ | |
NVIC_SetPriority(irq_num, INTERRUPT_PRIORITY); \ | |
NVIC_EnableIRQ(irq_num); \ | |
}while(0) /* user to supply ';' */ | |
//===================== | |
// DEBUG | |
//===================== | |
#ifdef _DEBUG | |
//In debug mode, try to print out the error message to stdout. Note printf is not thread safe, isn't guaranteed | |
//to be available and occasionally hard faults, but generally if you have a terminal session attached to the | |
//USB port the error message is useful debugging information. See serial_comms for the stdio setup. | |
#include <stdio_serial.h> | |
#define DEBUG_PRINT(...) printf(__VA_ARGS__) | |
#else | |
#define DEBUG_PRINT(...) | |
#endif | |
//===================== | |
// PROFILING | |
//===================== | |
/** #include this at top of the file of a function you wish to profile. */ | |
#define PROFILE_INCLUDE <stdio.h> | |
/** Place at the start of a function you wish to profile. */ | |
#define PROFILE_START \ | |
TickType_t endTick, startTick = xTaskGetTickCount(); | |
/** Place any number of times between \ref PROFILE_START and \ref PROFILE_END to get a profiling update. */ | |
#define PROFILE_PROGRESS \ | |
endTick = xTaskGetTickCount(); \ | |
DEBUG_PRINT("time = %lu, ", endTick-startTick); \ | |
startTick = xTaskGetTickCount(); | |
/** Place at the end of a function you wish to profile. */ | |
#define PROFILE_END \ | |
endTick = xTaskGetTickCount(); \ | |
DEBUG_PRINT("time = %lu.\n", endTick-startTick); | |
//===================== | |
// CALIBRATION | |
//===================== | |
/** | |
* Uncomment to enable calibration mode, where various calibration values are printed to the console, | |
* displayed on the home screen and configurable in the settings screen. See TT-PRO-0001 Assembly | |
* Instructions for details. | |
* | |
* Note that the preferred way to enable CALIBRATION_MODE is to build using the "Calibration" configuration. | |
* It is the same as "Debug", but defines CALIBRATION_MODE as well. It was created so we can have a normal | |
* Debug build without having to manually edit this file back and forth. | |
*/ | |
//#define CALIBRATION_MODE | |
#ifdef CALIBRATION_MODE | |
#ifdef NDEBUG | |
#error Cannot use calibration mode in Release build because Release build requires a Flash erase to overwrite, which deletes the calibration. | |
#endif | |
/** In cal mode, start with a fresh set of settings on boot so we don't launch with invalid values. */ | |
#define RESET_TO_FACTORY_DEFAULTS | |
#endif | |
#endif //__COMMON_H__ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment