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