11#include " per/sai.h"
22#include " daisy_core.h"
3+ #include < cstring>
34
45namespace daisy
56{
@@ -39,8 +40,15 @@ class SaiHandle::Impl
3940 /* * Offset stored for weird inter-SAI stuff.*/
4041 size_t dma_offset;
4142
43+ // Optional buffer for audio callback output
44+ int32_t * buff_intermediate_ = nullptr ;
45+
46+ void SetIntermediateBuffer (int32_t * buffer) { buff_intermediate_ = buffer; }
47+
4248 /* * Callback that dispatches user callback from Cplt and HalfCplt DMA Callbacks */
43- void InternalCallback (size_t offset);
49+ void InternalCallbackRx (size_t offset);
50+
51+ void InternalCallbackTx (size_t offset);
4452
4553 /* * Pin Initiazlization */
4654 void InitPins ();
@@ -283,15 +291,25 @@ void SaiHandle::Impl::DeInitDma(PeripheralBlock block)
283291 }
284292}
285293
286- void SaiHandle::Impl::InternalCallback (size_t offset)
294+ void SaiHandle::Impl::InternalCallbackRx (size_t offset)
287295{
288296 int32_t *in, *out;
289297 in = buff_rx_ + offset;
290- out = buff_tx_ + offset;
298+ out = (buff_intermediate_ ? buff_intermediate_ : buff_tx_ + offset) ;
291299 if (callback_)
292300 callback_ (in, out, buff_size_ / 2 );
293301}
294302
303+ void SaiHandle::Impl::InternalCallbackTx (size_t offset)
304+ {
305+ if (!buff_intermediate_) {
306+ return ;
307+ }
308+ int32_t * in = buff_intermediate_;
309+ int32_t * out = buff_tx_ + offset;
310+ std::memcpy (out, in, buff_size_ / 2 * sizeof (*out));
311+ }
312+
295313SaiHandle::Result
296314SaiHandle::Impl::StartDmaTransfer (int32_t * buffer_rx,
297315 int32_t * buffer_tx,
@@ -503,12 +521,12 @@ extern "C" void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef* hsai)
503521 if (hsai->Instance == SAI1_Block_A || hsai->Instance == SAI1_Block_B)
504522 {
505523 sai_handles[0 ].dma_offset = 0 ;
506- sai_handles[0 ].InternalCallback (0 );
524+ sai_handles[0 ].InternalCallbackRx (0 );
507525 }
508526 else if (hsai->Instance == SAI2_Block_A || hsai->Instance == SAI2_Block_B)
509527 {
510528 sai_handles[1 ].dma_offset = 0 ;
511- sai_handles[1 ].InternalCallback (0 );
529+ sai_handles[1 ].InternalCallbackRx (0 );
512530 }
513531}
514532
@@ -517,12 +535,36 @@ extern "C" void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef* hsai)
517535 if (hsai->Instance == SAI1_Block_A || hsai->Instance == SAI1_Block_B)
518536 {
519537 sai_handles[0 ].dma_offset = sai_handles[0 ].buff_size_ / 2 ;
520- sai_handles[0 ].InternalCallback (sai_handles[0 ].dma_offset );
538+ sai_handles[0 ].InternalCallbackRx (sai_handles[0 ].dma_offset );
521539 }
522540 else if (hsai->Instance == SAI2_Block_A || hsai->Instance == SAI2_Block_B)
523541 {
524542 sai_handles[1 ].dma_offset = sai_handles[1 ].buff_size_ / 2 ;
525- sai_handles[1 ].InternalCallback (sai_handles[1 ].dma_offset );
543+ sai_handles[1 ].InternalCallbackRx (sai_handles[1 ].dma_offset );
544+ }
545+ }
546+
547+ extern " C" void HAL_SAI_TxHalfCpltCallback (SAI_HandleTypeDef* hsai)
548+ {
549+ if (hsai->Instance == SAI1_Block_A || hsai->Instance == SAI1_Block_B)
550+ {
551+ sai_handles[0 ].InternalCallbackTx (0 );
552+ }
553+ else if (hsai->Instance == SAI2_Block_A || hsai->Instance == SAI2_Block_B)
554+ {
555+ sai_handles[1 ].InternalCallbackTx (0 );
556+ }
557+ }
558+
559+ extern " C" void HAL_SAI_TxCpltCallback (SAI_HandleTypeDef* hsai)
560+ {
561+ if (hsai->Instance == SAI1_Block_A || hsai->Instance == SAI1_Block_B)
562+ {
563+ sai_handles[0 ].InternalCallbackTx (sai_handles[0 ].buff_size_ / 2 );
564+ }
565+ else if (hsai->Instance == SAI2_Block_A || hsai->Instance == SAI2_Block_B)
566+ {
567+ sai_handles[1 ].InternalCallbackTx (sai_handles[1 ].buff_size_ / 2 );
526568 }
527569}
528570
@@ -579,5 +621,9 @@ size_t SaiHandle::GetOffset() const
579621 return pimpl_->dma_offset ;
580622}
581623
624+ void SaiHandle::SetIntermediateBuffer (int32_t * buffer) {
625+ pimpl_->SetIntermediateBuffer (buffer);
626+ }
627+
582628
583629} // namespace daisy
0 commit comments