
#ifndef __GLOBAL_H__
#define __GLOBAL_H__

#include <stdbool.h>
#include <stdint.h>
#include <sys/types.h>
#include <assert.h>
#include <string.h>

/* The IRQ header must be included before stm32_device.h since ST defines a bunch of messy macros there. */
#include <stm32_irqs.h> /* Header generated from stm32***_startup.s in Makefile */

#include <stm32g0xx.h>
#include <core_cm0plus.h>

#define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))

#define AFRL(pin, val) ((val) << ((pin)*4))
#define AFRH(pin, val) ((val) << (((pin)-8)*4))
#define AF(pin) (2<<(2*(pin)))
#define OUT(pin) (1<<(2*(pin)))
#define IN(pin) (0)
#define ANALOG(pin) (3<<(2*(pin)))
#define CLEAR(pin) (~(3<<(2*(pin))))
#define PULLUP(pin) (1<<(2*pin))
#define PULLDOWN(pin) (2<<(2*pin))
#define BSRR_CLEAR(pin) ((1<<pin)<<16)
#define BSRR_SET(pin) (1<<pin)
#define BSRR_VALUE(pin, value) ((((!(value))<<pin)<<16) | ((!!(value))<<pin))

#ifndef SYSTICK_INTERVAL_US
#define SYSTICK_INTERVAL_US 1000
#endif /* SYSTICK_INTERVAL_US */

#define FIRMWARE_VERSION 1
#define HARDWARE_VERSION 0

#define TS_CAL1 (*(uint16_t *)0x1FFFF7B8)
#define VREFINT_CAL (*(uint16_t *)0x1FFFF7BA)

#define VMEAS_R_HIGH 10000 /* kiloohms */
#define VMEAS_R_LOW 3300 /* kiloohms */


enum ErrorCode {
    ERR_SUCCESS = 0,
    ERR_TIMEOUT,
    ERR_PHYSICAL_LAYER,
    ERR_FRAMING,
    ERR_PROTOCOL,
    ERR_DMA,
    ERR_BUSY,
    ERR_BUFFER_OVERFLOW,
    ERR_RX_OVERRUN,
    ERR_TX_OVERRUN,
};

typedef enum ErrorCode ErrorCode;

void delay_us(int duration_us);

extern volatile uint64_t sys_time_us;
extern uint16_t jitter_meas_avg_ns;

#endif /* __GLOBAL_H__ */
