10 #include <xcore/interrupt.h>
11 #include <xcore/channel_streaming.h>
12 #include <xcore/port.h>
14 #include "mic_array.h"
18 #if defined(BLOCK_SIZE) || defined(CHANNELS_IN) || defined(CHANNELS_OUT) || defined(SUBBLOCKS)
19 # error Application must not define the following as precompiler macros: MIC_COUNT, CHANNELS_IN, CHANNELS_OUT, SUBBLOCKS.
35 uint32_t* pdm_buffer[2];
52 void enable_pdm_rx_isr(
53 const port_t p_pdm_mics)
57 "ldap r11, pdm_rx_isr \n"
58 "setv res[%0], r11 \n"
61 :
"r"(p_pdm_mics),
"r"(XS1_SETC_IE_MODE_INTERRUPT)
100 template <
unsigned BLOCK_SIZE,
class SubType>
111 static constexpr
unsigned BlockSize = BLOCK_SIZE;
122 unsigned phase = BLOCK_SIZE;
127 uint32_t block_data[2][BLOCK_SIZE];
136 uint32_t* blocks[2] = {&block_data[0][0], &block_data[1][0]};
248 template <
unsigned CHANNELS_IN,
unsigned CHANNELS_OUT,
unsigned SUBBLOCKS>
250 StandardPdmRxService<CHANNELS_IN, CHANNELS_OUT, SUBBLOCKS>>
262 streaming_channel_t c_pdm_blocks;
273 unsigned channel_map[CHANNELS_OUT];
283 uint32_t out_block[CHANNELS_OUT][SUBBLOCKS];
300 void SendBlock(uint32_t block[CHANNELS_IN * SUBBLOCKS]);
307 void Init(port_t p_pdm_mics);
323 void MapChannels(
unsigned map[CHANNELS_OUT]);
340 void MapChannel(
unsigned out_channel,
unsigned in_channel);
365 uint32_t* GetPdmBlock();
379 template <
unsigned BLOCK_SIZE,
class SubType>
382 this->p_pdm_mics = p_pdm_mics;
386 template <
unsigned BLOCK_SIZE,
class SubType>
389 this->blocks[0][--phase] =
static_cast<SubType*
>(
this)->ReadPort();
392 this->phase = BLOCK_SIZE;
393 uint32_t* ready_block = this->blocks[0];
394 this->blocks[0] = this->blocks[1];
395 this->blocks[1] = ready_block;
397 static_cast<SubType*
>(
this)->SendBlock(ready_block);
402 template <
unsigned BLOCK_SIZE,
class SubType>
417 template <
unsigned CHANNELS_IN,
unsigned CHANNELS_OUT,
unsigned SUBBLOCKS>
421 return port_in(this->p_pdm_mics);
425 template <
unsigned CHANNELS_IN,
unsigned CHANNELS_OUT,
unsigned SUBBLOCKS>
429 s_chan_out_word(this->c_pdm_blocks.end_a,
430 reinterpret_cast<uint32_t
>( &block[0] ));
434 template <
unsigned CHANNELS_IN,
unsigned CHANNELS_OUT,
unsigned SUBBLOCKS>
438 for(
int k = 0; k < CHANNELS_OUT; k++)
439 this->channel_map[k] = k;
441 this->c_pdm_blocks = s_chan_alloc();
443 this->SetPort(p_pdm_mics);
447 template <
unsigned CHANNELS_IN,
unsigned CHANNELS_OUT,
unsigned SUBBLOCKS>
451 for(
int k = 0; k < CHANNELS_OUT; k++)
452 this->channel_map[k] = map[k];
456 template <
unsigned CHANNELS_IN,
unsigned CHANNELS_OUT,
unsigned SUBBLOCKS>
460 this->channel_map[out_channel] = in_channel;
464 template <
unsigned CHANNELS_IN,
unsigned CHANNELS_OUT,
unsigned SUBBLOCKS>
468 pdm_rx_isr_context.p_pdm_mics = this->p_pdm_mics;
469 pdm_rx_isr_context.c_pdm_data = this->c_pdm_blocks.end_a;
470 pdm_rx_isr_context.pdm_buffer[0] = &this->block_data[0][0];
471 pdm_rx_isr_context.pdm_buffer[1] = &this->block_data[1][0];
472 pdm_rx_isr_context.phase_reset = CHANNELS_IN*SUBBLOCKS-1;
473 pdm_rx_isr_context.phase = CHANNELS_IN*SUBBLOCKS-1;
475 enable_pdm_rx_isr(this->p_pdm_mics);
479 template <
unsigned CHANNELS_IN,
unsigned CHANNELS_OUT,
unsigned SUBBLOCKS>
483 interrupt_unmask_all();
487 template <
unsigned CHANNELS_IN,
unsigned CHANNELS_OUT,
unsigned SUBBLOCKS>
491 uint32_t* full_block = (uint32_t*) s_chan_in_word(this->c_pdm_blocks.end_b);
492 mic_array::deinterleave_pdm_samples<CHANNELS_IN>(full_block, SUBBLOCKS);
494 uint32_t (*block)[CHANNELS_IN] = (uint32_t (*)[CHANNELS_IN]) full_block;
496 for(
int ch = 0; ch < CHANNELS_OUT; ch++) {
497 for(
int sb = 0; sb < SUBBLOCKS; sb++) {
498 unsigned d = this->channel_map[ch];
499 this->out_block[ch][sb] = block[SUBBLOCKS-1-sb][d];
502 return &this->out_block[0][0];
Used to collect PDM sample data from a port.
Definition: PdmRx.hpp:102
void ThreadEntry()
Entry point for PDM processing thread.
Definition: PdmRx.hpp:403
port_t p_pdm_mics
Port from which to collect PDM data.
Definition: PdmRx.hpp:117
void SetPort(port_t p_pdm_mics)
Set the port from which to collect PDM samples.
Definition: PdmRx.hpp:380
void ProcessNext()
Perform a port read and if a new block has completed, signal.
Definition: PdmRx.hpp:387
PDM rx service which uses a streaming channel to send a block of data by pointer.
Definition: PdmRx.hpp:251
uint32_t * GetPdmBlock()
Get a block of PDM data.
Definition: PdmRx.hpp:489
void SendBlock(uint32_t block[CHANNELS_IN *SUBBLOCKS])
Send a block of PDM data to a listener.
Definition: PdmRx.hpp:427
uint32_t ReadPort()
Read a word of PDM data from the port.
Definition: PdmRx.hpp:419
void InstallISR()
Install ISR for PDM reception on the current core.
Definition: PdmRx.hpp:466
void Init(port_t p_pdm_mics)
Initialize this object with a channel and port.
Definition: PdmRx.hpp:436
void MapChannels(unsigned map[CHANNELS_OUT])
Set the input-output mapping for all output channels.
Definition: PdmRx.hpp:449
void MapChannel(unsigned out_channel, unsigned in_channel)
Set the input-output mapping for a single output channel.
Definition: PdmRx.hpp:458
void UnmaskISR()
Unmask interrupts on the current core.
Definition: PdmRx.hpp:481