forked from EmbeddedRPC/erpc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
erpc_uart_cmsis_transport.cpp
139 lines (115 loc) · 3.08 KB
/
erpc_uart_cmsis_transport.cpp
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
132
133
134
135
136
137
138
139
/*
* Copyright (c) 2014-2016, Freescale Semiconductor, Inc.
* Copyright 2016-2023 NXP
* Copyright 2021 ACRIOS Systems s.r.o.
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "erpc_uart_cmsis_transport.hpp"
#include <cstdio>
using namespace erpc;
////////////////////////////////////////////////////////////////////////////////
// Variables
////////////////////////////////////////////////////////////////////////////////
static volatile bool s_isTransferReceiveCompleted = false;
static volatile bool s_isTransferSendCompleted = false;
static UartTransport *s_uart_instance = NULL;
////////////////////////////////////////////////////////////////////////////////
// Code
////////////////////////////////////////////////////////////////////////////////
UartTransport::UartTransport(ARM_DRIVER_USART *uartDrv) :
m_uartDrv(uartDrv)
#if !ERPC_THREADS_IS(NONE)
,
m_rxSemaphore(), m_txSemaphore()
#endif
{
s_uart_instance = this;
}
UartTransport::~UartTransport(void)
{
(void)(*m_uartDrv).Uninitialize();
}
void UartTransport::tx_cb(void)
{
#if !ERPC_THREADS_IS(NONE)
m_txSemaphore.putFromISR();
#else
s_isTransferSendCompleted = true;
#endif
}
void UartTransport::rx_cb(void)
{
#if !ERPC_THREADS_IS(NONE)
m_rxSemaphore.putFromISR();
#else
s_isTransferReceiveCompleted = true;
#endif
}
/* Transfer callback */
static void TransferCallback(uint32_t event)
{
UartTransport *transport = s_uart_instance;
if (event == ARM_USART_EVENT_SEND_COMPLETE)
{
transport->tx_cb();
}
if (event == ARM_USART_EVENT_RECEIVE_COMPLETE)
{
transport->rx_cb();
}
}
erpc_status_t UartTransport::init(void)
{
erpc_status_t erpcStatus = kErpcStatus_InitFailed;
int32_t status = (*m_uartDrv).Initialize(TransferCallback);
if (status == ARM_DRIVER_OK)
{
status = (*m_uartDrv).PowerControl(ARM_POWER_FULL); /* Enable Receiver and Transmitter lines */
if (status == ARM_DRIVER_OK)
{
erpcStatus = kErpcStatus_Success;
}
}
return erpcStatus;
}
erpc_status_t UartTransport::underlyingReceive(uint8_t *data, uint32_t size)
{
erpc_status_t erpcStatus = kErpcStatus_ReceiveFailed;
s_isTransferReceiveCompleted = false;
int32_t status = (*m_uartDrv).Receive(data, size);
if (status == ARM_DRIVER_OK)
{
/* wait until the receiving is finished */
#if !ERPC_THREADS_IS(NONE)
(void)m_rxSemaphore.get();
#else
while (!s_isTransferReceiveCompleted)
{
}
#endif
erpcStatus = kErpcStatus_Success;
}
return erpcStatus;
}
erpc_status_t UartTransport::underlyingSend(const uint8_t *data, uint32_t size)
{
erpc_status_t erpcStatus = kErpcStatus_SendFailed;
s_isTransferSendCompleted = false;
int32_t status = (*m_uartDrv).Send(data, size);
if (status == ARM_DRIVER_OK)
{
/* wait until the sending is finished */
#if !ERPC_THREADS_IS(NONE)
(void)m_txSemaphore.get();
#else
while (!s_isTransferSendCompleted)
{
}
#endif
erpcStatus = kErpcStatus_Success;
}
return erpcStatus;
}