CHERIoT RTOS
A compartmentalised RTOS for CHERIoT hardware
Toggle main menu visibility
Loading...
Searching...
No Matches
sdk
include
platform
synopsis
platform-uart.hh
1
#pragma once
2
#pragma push_macro("CHERIOT_PLATFORM_CUSTOM_UART")
3
#define CHERIOT_PLATFORM_CUSTOM_UART
4
#include_next <platform-uart.hh>
5
#pragma pop_macro("CHERIOT_PLATFORM_CUSTOM_UART")
6
7
/**
8
* The Synopsis extended 16550 UART has two additional registers that are not
9
* part of a standard 16550, one of which allows for fractional multipliers.
10
*
11
* This is always instantiated with 32-bit device registers. The default baud
12
* rate is set as a template parameter and can be overridden in `init`.
13
*/
14
template
<
unsigned
DefaultBaudRate = 115'200>
15
struct
SynopsisExtended16550
:
public
Uart16550
<uint32_t>
16
{
17
/**
18
* Loopback register. Unused.
19
*/
20
uint32_t
loopback
;
21
22
/**
23
* Divisor latch fraction. When the divisor latch is set (for writing the
24
* divisor), this is used for the fraction. RS-232 requires a 3% tolerance
25
* for the baud rate and an integer divisor over the clock frequency of the
26
* host may not get within this range. This register is used to provide a
27
* 4-bit correction that allows baud rates to stay within the required
28
* range.
29
*/
30
uint32_t
divisorLatchFraction
;
31
32
/**
33
* The divisor is calculated from 16 times the baud rate. The baud rate is
34
* in the range of KHz to hundreds of KHz, whereas the clock frequency is
35
* typically tens to hundreds of MHz. The divisor must fit in a 16-bit
36
* integer (written across two 8-bit device registers) and so is scaled to
37
* ensure that it fits (by a power of two, which makes it trivial to
38
* reverse the multiplication in the hardware).
39
*/
40
static
constexpr
uint32_t
BaudScaleFactorShift
= 4;
41
42
/**
43
* The value in `divisorLatchFraction` is truncated to this many bits.
44
*/
45
static
constexpr
uint32_t
BaudFractionBits
= 4;
46
47
/**
48
* Initialise the UART.
49
*/
50
void
init
(
unsigned
baudRate = DefaultBaudRate,
51
unsigned
timerFrequency = CPU_TIMER_HZ)
volatile
52
{
53
// The multiplier that we will scale the baud rate by.
54
constexpr
uint32_t Multiplier = (1 <<
BaudScaleFactorShift
);
55
// The scaled baud rate is used in all of the remaining calculations.
56
// See `BaudScaleFactorShift` for an explanation.
57
uint32_t scaledBaudRate = baudRate * Multiplier;
58
// The divisor to be programmed into the device.
59
uint32_t divisor = timerFrequency / scaledBaudRate;
60
// The remainder of the divisor.
61
uint32_t remainder = timerFrequency % scaledBaudRate;
62
// The remainder is scaled relative to the baud rate to give a
63
// correction factor.
64
remainder = (remainder << (
BaudScaleFactorShift
+ 1)) / scaledBaudRate;
65
// The remainder is rounded up to give the value that can be programmed
66
// into the device register.
67
remainder = (remainder >> 1) + (remainder & 0x1);
68
// Set up the base UART
69
Uart16550<uint32_t>::init
(divisor,
70
[&]() {
divisorLatchFraction
= remainder; });
71
// Write a character with the low bit set. Any value is fine here, but
72
// if we use 0x7 (ASCII bell character) then we should get a beep if it
73
// goes through to the receiver and so can tell whether this worked.
74
blocking_write
(0x7);
75
}
76
};
77
78
#ifndef CHERIOT_PLATFORM_CUSTOM_UART
79
using
Uart =
SynopsisExtended16550<>
;
80
#endif
Uart16550
Generic 16550A memory-mapped register layout.
Definition
platform-uart.hh:18
Uart16550::init
void init(int divisor=1, T &&otherSetup=no_custom_init) volatile
Initialise the UART.
Definition
platform-uart.hh:122
Uart16550< uint32_t >::blocking_write
void blocking_write(uint8_t byte) volatile
Definition
platform-uart.hh:110
SynopsisExtended16550
The Synopsis extended 16550 UART has two additional registers that are not part of a standard 16550,...
Definition
platform-uart.hh:16
SynopsisExtended16550::BaudFractionBits
static constexpr uint32_t BaudFractionBits
The value in divisorLatchFraction is truncated to this many bits.
Definition
platform-uart.hh:45
SynopsisExtended16550::loopback
uint32_t loopback
Loopback register.
Definition
platform-uart.hh:20
SynopsisExtended16550::divisorLatchFraction
uint32_t divisorLatchFraction
Divisor latch fraction.
Definition
platform-uart.hh:30
SynopsisExtended16550::init
void init(unsigned baudRate=DefaultBaudRate, unsigned timerFrequency=CPU_TIMER_HZ) volatile
Initialise the UART.
Definition
platform-uart.hh:50
SynopsisExtended16550::BaudScaleFactorShift
static constexpr uint32_t BaudScaleFactorShift
The divisor is calculated from 16 times the baud rate.
Definition
platform-uart.hh:40
Generated by
1.18.0