aboutsummaryrefslogtreecommitdiff
path: root/src/peripheral/tpiu.rs
blob: 5443fc0fd7d810cef884ac0db1f9da612b7a865a (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
//! Trace Port Interface Unit;
//!
//! *NOTE* Not available on Armv6-M.

use volatile_register::{RO, RW, WO};

use crate::peripheral::TPIU;
use bitfield::bitfield;

/// Register block
#[repr(C)]
pub struct RegisterBlock {
    /// Supported Parallel Port Sizes
    pub sspsr: RO<u32>,
    /// Current Parallel Port Size
    pub cspsr: RW<u32>,
    reserved0: [u32; 2],
    /// Asynchronous Clock Prescaler
    pub acpr: RW<u32>,
    reserved1: [u32; 55],
    /// Selected Pin Control
    pub sppr: RW<u32>,
    reserved2: [u32; 132],
    /// Formatter and Flush Control
    pub ffcr: RW<Ffcr>,
    reserved3: [u32; 810],
    /// Lock Access
    pub lar: WO<u32>,
    /// Lock Status
    pub lsr: RO<u32>,
    reserved4: [u32; 4],
    /// TPIU Type
    pub _type: RO<Type>,
}

bitfield! {
    /// Formatter and flush control register.
    #[repr(C)]
    #[derive(Clone, Copy)]
    pub struct Ffcr(u32);
    get_enfcont, set_enfcont: 1;
}

bitfield! {
    /// Type Register.
    #[repr(C)]
    #[derive(Clone, Copy)]
    pub struct Type(u32);
    u8, fifosz, _: 8, 6;
    ptinvalid, _: 9;
    mancvalid, _: 10;
    nrzvalid, _: 11;
}

/// The available protocols for the trace output.
pub enum TraceProtocol {
    /// Parallel trace port mode
    Parallel = 0b00,
    /// Asynchronous SWO, using Manchester encoding
    AsyncSWOManchester = 0b01,
    /// Asynchronous SWO, using NRZ encoding
    AsyncSWONRZ = 0b10,
}

/// The SWO options supported by the TPIU.
#[allow(dead_code)]
pub struct SWOSupports {
    /// Whether UART/NRZ encoding is supported for SWO.
    nrz_encoding: bool,
    /// Whether Manchester encoding is supported for SWO.
    manchester_encoding: bool,
    /// Whether parallel trace port operation is supported.
    parallel_operation: bool,
    /// The minimum implemented FIFO queue size of the TPIU for trace data.
    min_queue_size: u8,
}

impl TPIU {
    /// Sets the prescaler value for a wanted baud rate of the Serial
    /// Wire Output (SWO) in relation to a given asynchronous refernce
    /// clock rate.
    #[inline]
    pub fn set_swo_baud_rate(&mut self, ref_clk_rate: u32, baud_rate: u32) {
        unsafe {
            self.acpr.write((ref_clk_rate / baud_rate) - 1);
        }
    }

    /// Sets the used protocol for the trace output.
    #[inline]
    pub fn set_trace_output_protocol(&mut self, proto: TraceProtocol) {
        unsafe { self.sppr.write(proto as u32) }
    }

    /// Whether to enable the formatter. If disabled, only ITM and DWT
    /// trace sources are passed through. Data from the ETM is
    /// discarded.
    #[inline]
    pub fn enable_continuous_formatting(&mut self, bit: bool) {
        unsafe {
            self.ffcr.modify(|mut r| {
                r.set_enfcont(bit);
                r
            });
        }
    }

    /// Reads the supported trace output modes and the minimum size of
    /// the TPIU FIFO queue for trace data.
    #[inline]
    pub fn get_swo_supports() -> SWOSupports {
        let _type = unsafe { (*Self::ptr())._type.read() };
        SWOSupports {
            nrz_encoding: _type.nrzvalid(),
            manchester_encoding: _type.mancvalid(),
            parallel_operation: !_type.ptinvalid(),
            min_queue_size: _type.fifosz(),
        }
    }
}