xref: /aosp_15_r20/external/openthread/examples/platforms/utils/uart_rtt.c (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1 /*
2  *  Copyright (c) 2023, The OpenThread Authors.
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /**
30  * @file
31  *   This file implements the RTT implementation of the uart API.
32  *
33  */
34 
35 #include <stdint.h>
36 
37 #include <openthread-core-config.h>
38 #include <openthread/config.h>
39 
40 #include <utils/code_utils.h>
41 #include <openthread/error.h>
42 
43 #if OPENTHREAD_UART_RTT_ENABLE
44 
45 #include "SEGGER_RTT.h"
46 #include "uart.h"
47 #include "uart_rtt.h"
48 
49 static bool sUartInitialized = false;
50 static bool sUartPendingUp   = false;
51 
52 #if UART_RTT_BUFFER_INDEX != 0
53 static uint8_t sUartUpBuffer[UART_RTT_UP_BUFFER_SIZE];
54 static uint8_t sUartDownBuffer[UART_RTT_DOWN_BUFFER_SIZE];
55 #endif
56 
otPlatUartEnable(void)57 otError otPlatUartEnable(void)
58 {
59     otError error = OT_ERROR_FAILED;
60 
61 #if UART_RTT_BUFFER_INDEX != 0
62     int resUp   = SEGGER_RTT_ConfigUpBuffer(UART_RTT_BUFFER_INDEX, UART_RTT_BUFFER_NAME, sUartUpBuffer,
63                                             UART_RTT_UP_BUFFER_SIZE, SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL);
64     int resDown = SEGGER_RTT_ConfigDownBuffer(UART_RTT_BUFFER_INDEX, UART_RTT_BUFFER_NAME, sUartDownBuffer,
65                                               UART_RTT_DOWN_BUFFER_SIZE, SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL);
66 #else
67     int resUp   = SEGGER_RTT_SetFlagsUpBuffer(UART_RTT_BUFFER_INDEX, SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL);
68     int resDown = SEGGER_RTT_SetFlagsDownBuffer(UART_RTT_BUFFER_INDEX, SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL);
69 #endif
70 
71     otEXPECT(resUp >= 0 && resDown >= 0);
72 
73     sUartInitialized = true;
74     sUartPendingUp   = false;
75     error            = OT_ERROR_NONE;
76 
77 exit:
78     return error;
79 }
80 
otPlatUartDisable(void)81 otError otPlatUartDisable(void)
82 {
83     sUartInitialized = false;
84 
85     return OT_ERROR_NONE;
86 }
87 
otPlatUartSend(const uint8_t * aBuf,uint16_t aBufLength)88 otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength)
89 {
90     otError error = OT_ERROR_NONE;
91 
92     otEXPECT_ACTION(SEGGER_RTT_Write(UART_RTT_BUFFER_INDEX, aBuf, aBufLength) != 0, error = OT_ERROR_FAILED);
93     sUartPendingUp = true;
94 
95 exit:
96     return error;
97 }
98 
otPlatUartFlush(void)99 otError otPlatUartFlush(void)
100 {
101     otError error = OT_ERROR_NONE;
102 
103     otEXPECT_ACTION(sUartPendingUp, error = OT_ERROR_INVALID_STATE);
104 
105     while (SEGGER_RTT_HasDataUp(UART_RTT_BUFFER_INDEX) != 0)
106     {
107     }
108 
109 exit:
110     return error;
111 }
112 
utilsUartRttProcess(void)113 void utilsUartRttProcess(void)
114 {
115     uint8_t  buf[UART_RTT_READ_BUFFER_SIZE];
116     unsigned count;
117 
118     otEXPECT(sUartInitialized);
119 
120     if (sUartPendingUp && SEGGER_RTT_HasDataUp(UART_RTT_BUFFER_INDEX) == 0)
121     {
122         sUartPendingUp = false;
123         otPlatUartSendDone();
124     }
125 
126     count = SEGGER_RTT_Read(UART_RTT_BUFFER_INDEX, &buf, sizeof(buf));
127     if (count > 0)
128     {
129         otPlatUartReceived((const uint8_t *)&buf, count);
130     }
131 
132 exit:
133     return;
134 }
135 
136 #endif // OPENTHREAD_UART_RTT_ENABLE
137