70 {
71 uint32_t need_write =
max(write_data.size_, read_data.size_);
72
73 if (dma_buff_rx_.
size_ > 0)
74 {
75 ASSERT(need_write <= dma_buff_rx_.
size_);
76 }
77
78 if (dma_buff_tx_.
size_ > 0)
79 {
80 ASSERT(need_write <= dma_buff_tx_.
size_);
81 }
82
83 if (spi_handle_->State != HAL_SPI_STATE_READY)
84 {
85 return ErrorCode::BUSY;
86 }
87
88 mem_read_ = false;
89
90 if (need_write > dma_enable_min_size_)
91 {
92 rw_op_ = op;
93
94 if (write_data.size_ > 0)
95 {
96 memcpy(dma_buff_tx_.
addr_, write_data.addr_, need_write);
97
98#if __DCACHE_PRESENT
99 SCB_CleanDCache_by_Addr(
static_cast<uint32_t *
>(dma_buff_tx_.
addr_),
100 static_cast<int32_t>(write_data.size_));
101#endif
102 }
103 if (read_data.size_ > 0)
104 {
105 read_buff_ = read_data;
106 }
107
108 if (write_data.size_ > 0 && read_data.size_ > 0)
109 {
110 HAL_SPI_TransmitReceive_DMA(
111 spi_handle_,
static_cast<uint8_t *
>(dma_buff_tx_.
addr_),
112 static_cast<uint8_t *
>(dma_buff_rx_.
addr_), need_write);
113 }
114 else if (write_data.size_ > 0)
115 {
116 HAL_SPI_Transmit_DMA(spi_handle_,
static_cast<uint8_t *
>(dma_buff_tx_.
addr_),
117 need_write);
118 }
119 else if (read_data.size_ > 0)
120 {
121 HAL_SPI_Receive_DMA(spi_handle_,
static_cast<uint8_t *
>(dma_buff_rx_.
addr_),
122 need_write);
123 }
124 else
125 {
126 if (op.type != OperationRW::OperationType::BLOCK)
127 {
128 op.UpdateStatus(false, ErrorCode::OK);
129 }
130 return ErrorCode::OK;
131 }
132
134 if (op.type == OperationRW::OperationType::BLOCK)
135 {
136 return op.data.sem_info.sem->Wait(op.data.sem_info.timeout);
137 }
138 return ErrorCode::OK;
139 }
140 else
141 {
142 if (write_data.size_ > 0)
143 {
144 memcpy(dma_buff_tx_.
addr_, write_data.addr_, write_data.size_);
145 }
146
147 ErrorCode ans = ErrorCode::OK;
148 if (read_data.size_ > 0 && write_data.size_ > 0)
149 {
150 ans = HAL_SPI_TransmitReceive(
151 spi_handle_,
static_cast<uint8_t *
>(dma_buff_tx_.
addr_),
152 static_cast<uint8_t *
>(dma_buff_rx_.
addr_), need_write, 20) == HAL_OK
153 ? ErrorCode::OK
154 : ErrorCode::BUSY;
155 }
156 else if (read_data.size_ > 0)
157 {
158 ans = HAL_SPI_Receive(spi_handle_,
static_cast<uint8_t *
>(dma_buff_rx_.
addr_),
159 need_write, 20) == HAL_OK
160 ? ErrorCode::OK
161 : ErrorCode::BUSY;
162 }
163 else if (write_data.size_ > 0)
164 {
165 ans = HAL_SPI_Transmit(spi_handle_,
static_cast<uint8_t *
>(dma_buff_tx_.
addr_),
166 need_write, 20) == HAL_OK
167 ? ErrorCode::OK
168 : ErrorCode::BUSY;
169 }
170 else
171 {
172 if (op.type != OperationRW::OperationType::BLOCK)
173 {
174 op.UpdateStatus(false, ErrorCode::OK);
175 }
176 return ErrorCode::OK;
177 }
178
179 memcpy(read_data.addr_, dma_buff_rx_.
addr_, read_data.size_);
180
181 op.UpdateStatus(false, std::forward<ErrorCode>(ans));
182
183 if (op.type == OperationRW::OperationType::BLOCK)
184 {
185 return op.data.sem_info.sem->Wait(op.data.sem_info.timeout);
186 }
187
188 return ans;
189 }
190 }
void MarkAsRunning()
标记操作为运行状态。 Marks the operation as running.
constexpr auto max(T1 a, T2 b) -> typename std::common_type< T1, T2 >::type
计算两个数的最大值