@@ -44,23 +44,35 @@ PDMClass::~PDMClass()
4444{
4545}
4646
47+ void PDMClass::setPins (int dataPin, int clkPin, int pwrPin)
48+ {
49+ _dinPin = dataPin;
50+ _clkPin = clkPin;
51+ _pwrPin = pwrPin;
52+ }
53+
4754int PDMClass::begin (int channels, long sampleRate)
4855{
4956 _channels = channels;
5057
51- /*
58+ // Enable high frequency oscillator if not already enabled
59+ if (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0 ) {
60+ NRF_CLOCK->TASKS_HFCLKSTART = 1 ;
61+ while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0 ) { }
62+ }
63+
5264 // configure the sample rate and channels
5365 switch (sampleRate) {
5466 case 16000 :
55- nrf_pdm_clock_set(NRF_PDM_FREQ_1032K);
67+ NRF_PDM->RATIO = ((PDM_RATIO_RATIO_Ratio80 << PDM_RATIO_RATIO_Pos) & PDM_RATIO_RATIO_Msk);
68+ nrf_pdm_clock_set (NRF_PDM_FREQ_1280K);
5669 break ;
5770 case 41667 :
5871 nrf_pdm_clock_set (NRF_PDM_FREQ_2667K);
5972 break ;
6073 default :
6174 return 0 ; // unsupported
6275 }
63- */
6476
6577 switch (channels) {
6678 case 2 :
@@ -74,6 +86,7 @@ int PDMClass::begin(int channels, long sampleRate)
7486 default :
7587 return 0 ; // unsupported
7688 }
89+
7790 setGain (DEFAULT_PDM_GAIN);
7891
7992 // configure the I/O and mux
@@ -82,8 +95,6 @@ int PDMClass::begin(int channels, long sampleRate)
8295
8396 pinMode (_dinPin, INPUT);
8497
85- Serial.printf (" Clock P %d Data P %d\n " , digitalPinToPinName (_clkPin), digitalPinToPinName (_dinPin));
86-
8798 nrf_pdm_psel_connect (digitalPinToPinName (_clkPin), digitalPinToPinName (_dinPin));
8899
89100 // clear events and enable PDM interrupts
@@ -98,14 +109,13 @@ int PDMClass::begin(int channels, long sampleRate)
98109 digitalWrite (_pwrPin, HIGH);
99110 }
100111
101-
102112 // clear the buffer
103113 _doubleBuffer.reset ();
114+
104115 // set the PDM IRQ priority and enable
105116 NVIC_SetPriority (PDM_IRQn, PDM_IRQ_PRIORITY);
106117 NVIC_ClearPendingIRQ (PDM_IRQn);
107118 NVIC_EnableIRQ (PDM_IRQn);
108-
109119
110120 // set the buffer for transfer
111121 // nrf_pdm_buffer_set((uint32_t*)_doubleBuffer.data(), _doubleBuffer.availableForWrite() / (sizeof(int16_t) * _channels));
@@ -116,7 +126,6 @@ int PDMClass::begin(int channels, long sampleRate)
116126 nrf_pdm_event_clear (NRF_PDM_EVENT_STARTED);
117127 nrf_pdm_task_trigger (NRF_PDM_TASK_START);
118128
119-
120129 return 1 ;
121130}
122131
@@ -133,6 +142,8 @@ void PDMClass::end()
133142 pinMode (_pwrPin, INPUT);
134143 }
135144
145+ // Don't disable high frequency oscillator since it could be in use by RADIO
146+
136147 // unconfigure the I/O and un-mux
137148 nrf_pdm_psel_disconnect ();
138149
@@ -145,7 +156,7 @@ int PDMClass::available()
145156
146157 size_t avail = _doubleBuffer.available ();
147158
148- // NVIC_EnableIRQ(PDM_IRQn);
159+ NVIC_EnableIRQ (PDM_IRQn);
149160
150161 return avail;
151162}
@@ -156,7 +167,7 @@ int PDMClass::read(void* buffer, size_t size)
156167
157168 int read = _doubleBuffer.read (buffer, size);
158169
159- // NVIC_EnableIRQ(PDM_IRQn);
170+ NVIC_EnableIRQ (PDM_IRQn);
160171
161172 return read;
162173}
@@ -203,13 +214,24 @@ void PDMClass::IrqHandler()
203214 }
204215}
205216
206- extern " C" {
207- void PDM_IRQHandler (void );
208- }
209-
210- void PDM_IRQHandler (void )
217+ extern " C"
211218{
212- PDM.IrqHandler ();
219+ void PDM_IRQHandler (void )
220+ {
221+ PDM.IrqHandler ();
222+ }
213223}
214224
215- extern PDMClass PDM;
225+ #ifndef PIN_PDM_DIN
226+ #define PIN_PDM_DIN -1
227+ #endif
228+
229+ #ifndef PIN_PDM_CLK
230+ #define PIN_PDM_CLK -1
231+ #endif
232+
233+ #ifndef PIN_PDM_PWR
234+ #define PIN_PDM_PWR -1
235+ #endif
236+
237+ PDMClass PDM (PIN_PDM_DIN, PIN_PDM_CLK, PIN_PDM_PWR);
0 commit comments