aboutsummaryrefslogtreecommitdiff
path: root/02-usart/include/usart.h
blob: 257aab6ab393cfa5f8bf9067f0ad27490294ffd9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#ifndef H__USART_
#define H__USART_

#include "common.h"
#include "rcc.h"

#include <stdint.h>

/*
 * Possibel USART clock sources.
 */
typedef enum {
  USART_CLK_SRC_PLK = 0, /* Clock derived from the SysClk. */
  USART_CLK_SRC_SYSCLK = 1, /* System clock. */
  USART_CLK_SRC_HSI16 = 2, /* 16MHz oscillator. */
  USART_CLK_SRC_LSE = 3 /* Low power 32kHz clock. */
} usart_clk_src_t;

typedef struct {
  /* USART configuration registers 0x04 - 0x0c. */
  union {
    uint32_t c_r1;
    struct {
      bits_t ue:1;     /* UART enable */
      bits_t uesm:1;   /* UART enabled in stop mode. */
      bits_t re:1;     /* reciever enabled. */
      bits_t te:1;     /* transmitter enabled. */
      bits_t idleie:1; /* Idle interrupt enabled. */
      bits_t rxneie:1; /* RXNEIE RXNE interrupt enable. */
      bits_t tcie:1;
      bits_t txeie:1;
      bits_t peie:1;
      bits_t ps:1;
      bits_t pce:1;
      bits_t wake:1;
      bits_t m0:1;
      bits_t mme:1;
      bits_t cmie:1;
      bits_t over8:1;
      bits_t dedt:4;
      bits_t deat:4;
      bits_t rtoie:1;
      bits_t eobie:1;
      bits_t m1:1;
      bits_t reserved:3;
    } PACKED c1_bf;
  };
  uint32_t c_r2;
  uint32_t c_r3;

  /* USART baud rate register. */
  uint32_t br_r;
  uint32_t gtp_r;
  uint32_t rto_r;
  uint32_t rq_r;
  uint32_t is_r;
  uint32_t ic_r;
  uint32_t rd_r;
  uint32_t td_r;
} usart_t;

#define USART1 (* (__IO usart_t*) 0x40013800)
#define USART2 (* (__IO usart_t*) 0x40004400)
typedef enum {
  OVERSAMPLE_8,
  OVERSAMPLE_16
} oversampling_mode_t;

static inline void usart_set_divisor(
    __IO usart_t* usart,
    uint32_t usartdiv)
{
  if (usart->c_r1 & (1 << 15)) {
    /* OVER8 is set. */
    usart->br_r =
      (usartdiv & ~7) |
      ((usartdiv & 7) >> 1);
  } else {
    /* OVER8 is not set. */
    usart->br_r = usartdiv;
  }
}

static inline void usart_set_oversampling_mode(
    __IO usart_t* usart,
    oversampling_mode_t mode)
{
  if (mode == OVERSAMPLE_8) {
    usart->c_r1 |= 1 << 15;
  } else {
    usart->c_r1 &= ~(1 << 15);
  }
}

typedef enum {
  USART_PARITY_DISABLED = 0,
  USART_PARITY_EVEN     = 2 << 9,
  USART_PARITY_ODD      = 3 << 9,
} usart_parity_t;

typedef enum {
  USART_ENABLE_TX       = 0x02,
  USART_ENABLE_RX       = 0x01,
  USART_ENABLE_DISABLED = 0x00,
} usart_enable_t;

void usart_set_parity(__IO usart_t* usart, usart_parity_t parity);

void usart_set_enabled(__IO usart_t* usart, usart_enable_t enabled);

/*
 * Send a byte on the usart, This command blocks until the data
 * is fully sent.
 */
void usart_transmit_byte(__IO usart_t* usart, uint8_t byte);

void set_usart1_clock_src(__IO rcc_t* rcc, usart_clk_src_t usart_clk_src);

void set_usart1_clock_enabled(__IO rcc_t* rcc, bool enable);

void set_usart2_clock_src(__IO rcc_t* rcc, usart_clk_src_t usart_clk_src);

void set_usart2_clock_enabled(__IO rcc_t* rcc, bool enable);

void usart_transmit_bytes(
    __IO usart_t* usart, const uint8_t* bytes, uint32_t n);

void usart_transmit_str(__IO usart_t* usart, const char* str);


#endif /* H__USART_ */