/** @file usart_regs.h
 * Module defining the USART registers.
 *
 * Mainly made to be used by the usart module. It is recommanded to go through
 * the functions provided by that module instead of directly using the registers
 * defined here.
 */

#ifndef _USART_REGS_H_
#define _USART_REGS_H_

//--includes--------------------------------------------------------------------

#include "reg.h"

#include "stdint.h"


//--type definitions------------------------------------------------------------

#define USART1_BASE_ADDRESS 0x40013800
#define USART2_BASE_ADDRESS 0x40004400
#define USART3_BASE_ADDRESS 0x40004800

union USART_SR {
	struct __attribute__((packed)) {
		uint32_t PE:1;
		uint32_t FE:1;
		uint32_t NE:1;
		uint32_t ORE:1;
		uint32_t IDLE:1;
		uint32_t RXNE:1;
		uint32_t TC:1;
		uint32_t TXE:1;
		uint32_t LBD:1;
		uint32_t CTS:1;
		uint32_t reserved1:22;
	};
	uint32_t word;
};

#define USART_SR_PE        reg_def( 0,  1)
#define USART_SR_FE        reg_def( 1,  1)
#define USART_SR_NE        reg_def( 2,  1)
#define USART_SR_ORE       reg_def( 3,  1)
#define USART_SR_IDLE      reg_def( 4,  1)
#define USART_SR_RXNE      reg_def( 5,  1)
#define USART_SR_TC        reg_def( 6,  1)
#define USART_SR_TXE       reg_def( 7,  1)
#define USART_SR_LBD       reg_def( 8,  1)
#define USART_SR_CTS       reg_def( 9,  1)
#define USART_SR_reserved1 reg_def(10, 22)

union USART_DR {
	struct __attribute__((packed)) {
		uint32_t DR:9;
		uint32_t reserved1:23;
	};
	uint32_t word;
};

#define USART_DR_DR        reg_def( 0,  9)
#define USART_DR_reserved1 reg_def( 9, 23)

union USART_BRR {
	struct __attribute__((packed)) {
		uint32_t DIV_Fraction:4;
		uint32_t DIV_Mantissa:12;
		uint32_t reserved1:16;
	};
	uint32_t word;
};

#define USART_BRR_DIV_Fraction reg_def( 0,  4)
#define USART_BRR_DIV_Mantissa reg_def( 4, 12)
#define USART_BRR_reserved1    reg_def(16, 16)

union USART_CR1 {
	struct __attribute__((packed)) {
		uint32_t SBK:1;
		uint32_t RWU:1;
		uint32_t RE:1;
		uint32_t TE:1;
		uint32_t IDLEIE:1;
		uint32_t RXNEIE:1;
		uint32_t TCIE:1;
		uint32_t TXEIE:1;
		uint32_t PEI:1;
		uint32_t PS:1;
		uint32_t PCE:1;
		uint32_t WAKE:1;
		uint32_t M:1;
		uint32_t UE:1;
		uint32_t reserved1:18;
	};
	uint32_t word;
};

#define USART_CR1_SBK       reg_def( 0,  1)
#define USART_CR1_RWU       reg_def( 1,  1)
#define USART_CR1_RE        reg_def( 2,  1)
#define USART_CR1_TE        reg_def( 3,  1)
#define USART_CR1_IDLEIE    reg_def( 4,  1)
#define USART_CR1_RXNEIE    reg_def( 5,  1)
#define USART_CR1_TCIE      reg_def( 6,  1)
#define USART_CR1_TXEIE     reg_def( 7,  1)
#define USART_CR1_PEI       reg_def( 8,  1)
#define USART_CR1_PS        reg_def( 9,  1)
#define USART_CR1_PCE       reg_def(10,  1)
#define USART_CR1_WAKE      reg_def(11,  1)
#define USART_CR1_M         reg_def(12,  1)
#define USART_CR1_UE        reg_def(13,  1)
#define USART_CR1_reserved1 reg_def(14, 18)

union USART_CR2 {
	struct __attribute__((packed)) {
		uint32_t ADD:4;
		uint32_t reserved1:1;
		uint32_t LBDL:1;
		uint32_t LBDIE:1;
		uint32_t reserved2:1;
		uint32_t LBCL:1;
		uint32_t CPHA:1;
		uint32_t CPOL:1;
		uint32_t CLKEN:1;
		uint32_t STOP:2;
		uint32_t LINEN:1;
		uint32_t reserved3:17;
	};
	uint32_t word;
};

#define USART_CR2_ADD       reg_def( 0,  4)
#define USART_CR2_reserved1 reg_def( 4,  1)
#define USART_CR2_LBDL      reg_def( 5,  1)
#define USART_CR2_LBDIE     reg_def( 6,  1)
#define USART_CR2_reserved2 reg_def( 7,  1)
#define USART_CR2_LBCL      reg_def( 8,  1)
#define USART_CR2_CPHA      reg_def( 9,  1)
#define USART_CR2_CPOL      reg_def(10,  1)
#define USART_CR2_CLKEN     reg_def(11,  1)
#define USART_CR2_STOP      reg_def(12,  2)
#define USART_CR2_LINEN     reg_def(14,  1)
#define USART_CR2_reserved3 reg_def(15, 17)

union USART_CR3 {
	struct __attribute__((packed)) {
		uint32_t EIE:1;
		uint32_t IREN:1;
		uint32_t IRLP:1;
		uint32_t HDSEL:1;
		uint32_t NACK:1;
		uint32_t SCEN:1;
		uint32_t DMAR:1;
		uint32_t DMAT:1;
		uint32_t RTSE:1;
		uint32_t CTSE:1;
		uint32_t CTSIE:1;
		uint32_t reserved3:21;
	};
	uint32_t word;
};

#define USART_CR3_EIE       reg_def( 0,  1)
#define USART_CR3_IREN      reg_def( 1,  1)
#define USART_CR3_IRLP      reg_def( 2,  1)
#define USART_CR3_HDSEL     reg_def( 3,  1)
#define USART_CR3_NACK      reg_def( 4,  1)
#define USART_CR3_SCEN      reg_def( 5,  1)
#define USART_CR3_DMAR      reg_def( 6,  1)
#define USART_CR3_DMAT      reg_def( 7,  1)
#define USART_CR3_RTSE      reg_def( 8,  1)
#define USART_CR3_CTSE      reg_def( 9,  1)
#define USART_CR3_CTSIE     reg_def(10,  1)
#define USART_CR3_reserved3 reg_def(11, 21)

union USART_GTPR {
	struct __attribute__((packed)) {
		uint32_t PSC:8;
		uint32_t GT:8;
		uint32_t reserved1:16;
	};
	uint32_t word;
};

#define USART_GTPR_PSC       reg_def( 0,  8)
#define USART_GTPR_GT        reg_def( 8,  8)
#define USART_GTPR_reserved1 reg_def(16, 16)

struct USART {
	union USART_SR SR;
	union USART_DR DR;
	union USART_BRR BRR;
	union USART_CR1 CR1;
	union USART_CR2 CR2;
	union USART_CR3 CR3;
	union USART_GTPR GTPR;
};


//--functions-------------------------------------------------------------------

#endif //_USART_REGS_H_

