1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - SPI - libraries
3   File:     mic.c
4 
5   Copyright 2003-2008 Nintendo. All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law. They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Date:: 2008-09-17#$
14   $Rev: 8556 $
15   $Author: okubata_ryoma $
16  *---------------------------------------------------------------------------*/
17 
18 #include    <nitro/spi.h>
19 #include    <nitro/os/common/systemWork.h>
20 
21 #ifdef  SDK_TWL
22 #include    <twl/os/common/codecmode.h>
23 #include    "micex.h"
24 #endif
25 
26 /*---------------------------------------------------------------------------*
27     Structure Definitions
28  *---------------------------------------------------------------------------*/
29 #ifndef SDK_TWL
30 // Lock definition for exclusive processing of asynchronous functions
31 typedef enum MICLock
32 {
33     MIC_LOCK_OFF = 0,                  // Unlock status
34     MIC_LOCK_ON,                       // Lock status
35     MIC_LOCK_MAX
36 }
37 MICLock;
38 
39 // Work structure
40 typedef struct MICWork
41 {
42     MICLock lock;                      // Exclusive lock
43     MICCallback callback;              // For saving an asynchronous callback function
44     void   *callbackArg;               // For saving arguments to the callback function
45     MICResult commonResult;            // For saving asynchronous function processing results
46     MICCallback full;                  // For saving the sampling completion callback
47     void   *fullArg;                   // For saving arguments to the completion callback function
48     void   *dst_buf;                   // For saving a storage area for individual sampling results
49 
50 }
51 MICWork;
52 #endif
53 
54 /*---------------------------------------------------------------------------*
55     Internal Variable Definitions
56  *---------------------------------------------------------------------------*/
57 static u16 micInitialized;             // Initialized verify flag
58 static MICWork micWork;                // Structure that combines work variables
59 
60 
61 /*---------------------------------------------------------------------------*
62     Internal Function Definitions
63  *---------------------------------------------------------------------------*/
64 static void MicCommonCallback(PXIFifoTag tag, u32 data, BOOL err);
65 static BOOL MicDoSampling(u16 type);
66 static BOOL MicStartAutoSampling(void *buf, u32 size, u32 span, u8 flags);
67 static BOOL MicStopAutoSampling(void);
68 static BOOL MicAdjustAutoSampling(u32 span);
69 static void MicGetResultCallback(MICResult result, void *arg);
70 static void MicWaitBusy(void);
71 
72 
73 /*---------------------------------------------------------------------------*
74   Name:         MIC_Init
75 
76   Description:  Initializes microphone library
77 
78   Arguments:    None.
79 
80   Returns:      None.
81  *---------------------------------------------------------------------------*/
MIC_Init(void)82 void MIC_Init(void)
83 {
84     // Verification of non-initialization
85     if (micInitialized)
86     {
87         return;
88     }
89     micInitialized = 1;
90 
91     // Work variable initialization
92     micWork.lock = MIC_LOCK_OFF;
93     micWork.callback = NULL;
94 
95     // Wait until ARM7 MIC library starts
96     PXI_Init();
97     while (!PXI_IsCallbackReady(PXI_FIFO_TAG_MIC, PXI_PROC_ARM7))
98     {
99     }
100 
101     // Clear the shared area storage address for the latest sampling result
102     OS_GetSystemWork()->mic_last_address = 0;
103 
104     // Set the PXI callback function.
105     PXI_SetFifoRecvCallback(PXI_FIFO_TAG_MIC, MicCommonCallback);
106 }
107 
108 /*---------------------------------------------------------------------------*
109   Name:         MIC_DoSamplingAsync
110 
111   Description:  Performs a single asynchronous sample of the microphone.
112 
113   Arguments:    type:      - Specifies the sampling type.
114                 buf:       - Specifies the buffer that stores the sampling data.
115                 callback     - Specifies the function to be called when the asynchronous process is completed.
116                 arg       - Specifies the argument used when calling the callback function.
117 
118   Returns:      MICResult:    - Returns the result of starting the asynchronous device operation
119  *---------------------------------------------------------------------------*/
MIC_DoSamplingAsync(MICSamplingType type,void * buf,MICCallback callback,void * arg)120 MICResult MIC_DoSamplingAsync(MICSamplingType type, void *buf, MICCallback callback, void *arg)
121 {
122     OSIntrMode enabled;
123     u16     wtype;
124 
125     SDK_NULL_ASSERT(buf);
126     SDK_NULL_ASSERT(callback);
127 
128     // Confirms parameters
129     if (type >= MIC_SAMPLING_TYPE_MAX)
130     {
131         return MIC_RESULT_ILLEGAL_PARAMETER;
132     }
133     switch (type)
134     {
135     case MIC_SAMPLING_TYPE_8BIT:
136         wtype = SPI_MIC_SAMPLING_TYPE_8BIT;
137         break;
138     case MIC_SAMPLING_TYPE_12BIT:
139         wtype = SPI_MIC_SAMPLING_TYPE_12BIT;
140         break;
141     case MIC_SAMPLING_TYPE_SIGNED_8BIT:
142         wtype = SPI_MIC_SAMPLING_TYPE_S8BIT;
143         break;
144     case MIC_SAMPLING_TYPE_SIGNED_12BIT:
145         wtype = SPI_MIC_SAMPLING_TYPE_S12BIT;
146         break;
147     default:
148         return MIC_RESULT_ILLEGAL_PARAMETER;
149     }
150 
151     // Check lock
152     enabled = OS_DisableInterrupts();
153     if (micWork.lock != MIC_LOCK_OFF)
154     {
155         (void)OS_RestoreInterrupts(enabled);
156         return MIC_RESULT_BUSY;
157     }
158     micWork.lock = MIC_LOCK_ON;
159     (void)OS_RestoreInterrupts(enabled);
160 
161     // Sends the sampling run command
162     micWork.callback = callback;
163     micWork.callbackArg = arg;
164     micWork.dst_buf = buf;
165     if (MicDoSampling(wtype))
166     {
167         return MIC_RESULT_SUCCESS;
168     }
169     micWork.lock = MIC_LOCK_OFF;
170     return MIC_RESULT_SEND_ERROR;
171 }
172 
173 /*---------------------------------------------------------------------------*
174   Name:         MIC_DoSampling
175 
176   Description:  Samples the microphone once.
177 
178   Arguments:    type:      - Specifies the sampling type.
179                 buf:       - Specifies the buffer that stores the sampling data.
180 
181   Returns:      MICResult:    - Returns the result of the device operation process
182  *---------------------------------------------------------------------------*/
MIC_DoSampling(MICSamplingType type,void * buf)183 MICResult MIC_DoSampling(MICSamplingType type, void *buf)
184 {
185     micWork.commonResult = MIC_DoSamplingAsync(type, buf, MicGetResultCallback, NULL);
186     if (micWork.commonResult == MIC_RESULT_SUCCESS)
187     {
188         MicWaitBusy();
189     }
190     return micWork.commonResult;
191 }
192 
193 /*---------------------------------------------------------------------------*
194   Name:         MIC_StartAutoSamplingAsync
195 
196   Description:  Asynchronously starts microphone auto sampling
197 
198   Arguments:    param:     Pointer to a structure that specifies auto-sampling settings.
199                 callback     - Specifies the function to be called when the asynchronous process is completed.
200                 arg       - Specifies the argument used when calling the callback function.
201 
202   Returns:      MICResult:    - Returns the result of starting the asynchronous device operation
203  *---------------------------------------------------------------------------*/
MIC_StartAutoSamplingAsync(const MICAutoParam * param,MICCallback callback,void * arg)204 MICResult MIC_StartAutoSamplingAsync(const MICAutoParam *param, MICCallback callback, void *arg)
205 {
206     OSIntrMode enabled;
207     u8      flags;
208 
209     SDK_NULL_ASSERT(callback);
210     SDK_NULL_ASSERT(param->buffer);
211 
212     // Confirms parameters
213     {
214         // 32-byte buffer alignment
215         if ((u32)(param->buffer) & 0x01f)
216         {
217 #ifdef  SDK_DEBUG
218             OS_TWarning("Parameter param->buffer must be 32-byte aligned.\n");
219 #endif
220             return MIC_RESULT_ILLEGAL_PARAMETER;
221         }
222         // Buffer size alignment
223         if (param->size & 0x01f)
224         {
225 #ifdef  SDK_DEBUG
226             OS_TWarning("Parameter param->size must be a multiple of 32-byte.\n");
227 #endif
228             return MIC_RESULT_ILLEGAL_PARAMETER;
229         }
230         // Buffer size
231         if (param->size <= 0)
232         {
233             return MIC_RESULT_ILLEGAL_PARAMETER;
234         }
235         // sampling period
236         if (param->rate < MIC_SAMPLING_RATE_LIMIT)
237         {
238             return MIC_RESULT_ILLEGAL_PARAMETER;
239         }
240         // AD conversion bit width
241         switch (param->type)
242         {
243         case MIC_SAMPLING_TYPE_8BIT:
244             flags = SPI_MIC_SAMPLING_TYPE_8BIT;
245             break;
246         case MIC_SAMPLING_TYPE_12BIT:
247             flags = SPI_MIC_SAMPLING_TYPE_12BIT;
248             break;
249         case MIC_SAMPLING_TYPE_SIGNED_8BIT:
250             flags = SPI_MIC_SAMPLING_TYPE_S8BIT;
251             break;
252         case MIC_SAMPLING_TYPE_SIGNED_12BIT:
253             flags = SPI_MIC_SAMPLING_TYPE_S12BIT;
254             break;
255         case MIC_SAMPLING_TYPE_12BIT_FILTER_OFF:
256             flags = (SPI_MIC_SAMPLING_TYPE_12BIT | SPI_MIC_SAMPLING_TYPE_FILTER_OFF);
257             break;
258         case MIC_SAMPLING_TYPE_SIGNED_12BIT_FILTER_OFF:
259             flags = (SPI_MIC_SAMPLING_TYPE_S12BIT | SPI_MIC_SAMPLING_TYPE_FILTER_OFF);
260             break;
261         default:
262             return MIC_RESULT_ILLEGAL_PARAMETER;
263         }
264         // Enable/disable loop
265         if (param->loop_enable)
266         {
267             flags = (u8)(flags | SPI_MIC_SAMPLING_TYPE_LOOP_ON);
268         }
269         else
270         {
271             flags = (u8)(flags | SPI_MIC_SAMPLING_TYPE_LOOP_OFF);
272         }
273         // Correction flag for expansion is currently fixed to be OFF
274         flags = (u8)(flags | SPI_MIC_SAMPLING_TYPE_CORRECT_OFF);
275     }
276 
277     // Check lock
278     enabled = OS_DisableInterrupts();
279     if (micWork.lock != MIC_LOCK_OFF)
280     {
281         (void)OS_RestoreInterrupts(enabled);
282         return MIC_RESULT_BUSY;
283     }
284     micWork.lock = MIC_LOCK_ON;
285     (void)OS_RestoreInterrupts(enabled);
286 
287     // Send auto-sampling start command
288     micWork.callback = callback;
289     micWork.callbackArg = arg;
290     micWork.full = param->full_callback;
291     micWork.fullArg = param->full_arg;
292     if (MicStartAutoSampling(param->buffer, param->size, param->rate, flags))
293     {
294         return MIC_RESULT_SUCCESS;
295     }
296     micWork.lock = MIC_LOCK_OFF;
297     return MIC_RESULT_SEND_ERROR;
298 }
299 
300 /*---------------------------------------------------------------------------*
301   Name:         MIC_StartAutoSampling
302 
303   Description:  Starts auto-sampling with the microphone.
304 
305   Arguments:    param:     Pointer to a structure that specifies auto-sampling settings.
306 
307   Returns:      MICResult:    - Returns the result of the device operation process
308  *---------------------------------------------------------------------------*/
MIC_StartAutoSampling(const MICAutoParam * param)309 MICResult MIC_StartAutoSampling(const MICAutoParam *param)
310 {
311     micWork.commonResult = MIC_StartAutoSamplingAsync(param, MicGetResultCallback, NULL);
312     if (micWork.commonResult == MIC_RESULT_SUCCESS)
313     {
314         MicWaitBusy();
315     }
316     return micWork.commonResult;
317 }
318 
319 /*---------------------------------------------------------------------------*
320   Name:         MIC_StopAutoSamplingAsync
321 
322   Description:  Asynchronously stops microphone auto-sampling
323 
324   Arguments:    callback     - Specifies the function to be called when the asynchronous process is completed.
325                 arg       - Specifies the argument used when calling the callback function.
326 
327   Returns:      MICResult:    - Returns the result of starting the asynchronous device operation
328  *---------------------------------------------------------------------------*/
MIC_StopAutoSamplingAsync(MICCallback callback,void * arg)329 MICResult MIC_StopAutoSamplingAsync(MICCallback callback, void *arg)
330 {
331     OSIntrMode enabled;
332 
333     SDK_NULL_ASSERT(callback);
334 
335     // Check lock
336     enabled = OS_DisableInterrupts();
337     if (micWork.lock != MIC_LOCK_OFF)
338     {
339         (void)OS_RestoreInterrupts(enabled);
340         return MIC_RESULT_BUSY;
341     }
342     micWork.lock = MIC_LOCK_ON;
343     (void)OS_RestoreInterrupts(enabled);
344 
345     // Send auto-sampling stop command
346     micWork.callback = callback;
347     micWork.callbackArg = arg;
348     if (MicStopAutoSampling())
349     {
350         return MIC_RESULT_SUCCESS;
351     }
352     micWork.lock = MIC_LOCK_OFF;
353     return MIC_RESULT_SEND_ERROR;
354 }
355 
356 /*---------------------------------------------------------------------------*
357   Name:         MIC_StopAutoSampling
358 
359   Description:  Stops auto-sampling with the microphone.
360                 If a loop was not specified at the start of auto-sampling, sampling will stop automatically when the buffer is full.
361 
362 
363   Arguments:    None.
364 
365   Returns:      MICResult:    - Returns the result of the device operation process
366  *---------------------------------------------------------------------------*/
MIC_StopAutoSampling(void)367 MICResult MIC_StopAutoSampling(void)
368 {
369     micWork.commonResult = MIC_StopAutoSamplingAsync(MicGetResultCallback, NULL);
370     if (micWork.commonResult == MIC_RESULT_SUCCESS)
371     {
372         MicWaitBusy();
373     }
374     return micWork.commonResult;
375 }
376 
377 /*---------------------------------------------------------------------------*
378   Name:         MIC_AdjustAutoSamplingAsync
379 
380   Description:  Asynchronously adjusts the sampling rate used in microphone auto sampling
381 
382 
383   Arguments:    rate:       - Specifies the sampling rate.
384                 callback     - Specifies the function to be called when the asynchronous process is completed.
385                 arg       - Specifies the argument used when calling the callback function.
386 
387   Returns:      MICResult:    - Returns the result of starting the asynchronous device operation
388  *---------------------------------------------------------------------------*/
MIC_AdjustAutoSamplingAsync(u32 rate,MICCallback callback,void * arg)389 MICResult MIC_AdjustAutoSamplingAsync(u32 rate, MICCallback callback, void *arg)
390 {
391     OSIntrMode enabled;
392 
393     SDK_NULL_ASSERT(callback);
394 
395     // Confirms parameters
396     if (rate < MIC_SAMPLING_RATE_LIMIT)
397     {
398         return MIC_RESULT_ILLEGAL_PARAMETER;
399     }
400 
401     // Check lock
402     enabled = OS_DisableInterrupts();
403     if (micWork.lock != MIC_LOCK_OFF)
404     {
405         (void)OS_RestoreInterrupts(enabled);
406         return MIC_RESULT_BUSY;
407     }
408     micWork.lock = MIC_LOCK_ON;
409     (void)OS_RestoreInterrupts(enabled);
410 
411     // Send the auto sampling adjustment command
412     micWork.callback = callback;
413     micWork.callbackArg = arg;
414     if (MicAdjustAutoSampling(rate))
415     {
416         return MIC_RESULT_SUCCESS;
417     }
418     micWork.lock = MIC_LOCK_OFF;
419     return MIC_RESULT_SEND_ERROR;
420 }
421 
422 /*---------------------------------------------------------------------------*
423   Name:         MIC_AdjustAutoSampling
424 
425   Description:  Adjusts the sampling rate of the microphone auto-sampling
426 
427   Arguments:    rate:       - Specifies the sampling rate.
428 
429   Returns:      MICResult:    - Returns the result of the device operation process
430  *---------------------------------------------------------------------------*/
MIC_AdjustAutoSampling(u32 rate)431 MICResult MIC_AdjustAutoSampling(u32 rate)
432 {
433     micWork.commonResult = MIC_AdjustAutoSamplingAsync(rate, MicGetResultCallback, NULL);
434     if (micWork.commonResult == MIC_RESULT_SUCCESS)
435     {
436         MicWaitBusy();
437     }
438     return micWork.commonResult;
439 }
440 
441 /*---------------------------------------------------------------------------*
442   Name:         MIC_GetLastSamplingAddress
443 
444   Description:  Gets the address where the most recent mic sampling result is stored
445 
446   Arguments:    None.
447 
448   Returns:      void*:   Returns the storage address of the sampling result.
449                         Returns NULL if nothing has been sampled yet.
450  *---------------------------------------------------------------------------*/
MIC_GetLastSamplingAddress(void)451 void   *MIC_GetLastSamplingAddress(void)
452 {
453     return (void *)(OS_GetSystemWork()->mic_last_address);
454 }
455 
456 #ifdef  SDK_TWL
457 /*---------------------------------------------------------------------------*
458   Name:         MIC_StartLimitedSamplingAsync
459 
460   Description:  Asynchronously starts sampling rate limited microphone auto-sampling.
461                 Sampling on precise frequencies is possible with a low burden on the CPU because sampling is performed by the hardware, but the sampling rate is limited to the rates supported by the hardware.
462 
463 
464                 This is an asynchronous function, so the actual processing results are passed when the callback is called.
465                 If this function is called on NITRO, it is replaced by the preexisting CPU-based auto-sampling start function.
466 
467 
468   Arguments:    param:     Pointer to a structure that specifies auto-sampling settings.
469                 callback     - Specifies the function to be called when the asynchronous process is completed.
470                 arg       - Specifies the argument used when calling the callback function.
471 
472   Returns:      MICResult:    - Returns the result of starting the asynchronous device operation
473  *---------------------------------------------------------------------------*/
474 MICResult
MIC_StartLimitedSamplingAsync(const MICAutoParam * param,MICCallback callback,void * arg)475 MIC_StartLimitedSamplingAsync(const MICAutoParam* param, MICCallback callback, void* arg)
476 {
477     return ((OSi_IsCodecTwlMode() == TRUE) ?
478             MICEXi_StartLimitedSamplingAsync(param, callback, arg) :
479             MIC_StartAutoSamplingAsync(param, callback, arg));
480 }
481 
482 /*---------------------------------------------------------------------------*
483   Name:         MIC_StopLimitedSamplingAsync
484 
485   Description:  Asynchronously stops sampling rate limited microphone auto-sampling.
486 
487                 This is an asynchronous function, so the actual processing results are passed when the callback is called.
488                 f this function is called on NITRO, it is replaced by the preexisting CPU-based auto-sampling stop function.
489 
490 
491   Arguments:    callback     - Specifies the function to be called when the asynchronous process is completed.
492                 arg       - Specifies the argument used when calling the callback function.
493 
494   Returns:      MICResult:    - Returns the result of starting the asynchronous device operation
495  *---------------------------------------------------------------------------*/
496 MICResult
MIC_StopLimitedSamplingAsync(MICCallback callback,void * arg)497 MIC_StopLimitedSamplingAsync(MICCallback callback, void* arg)
498 {
499     return ((OSi_IsCodecTwlMode() == TRUE) ?
500             MICEXi_StopLimitedSamplingAsync(callback, arg) :
501             MIC_StopAutoSamplingAsync(callback, arg));
502 }
503 
504 /*---------------------------------------------------------------------------*
505   Name:         MIC_AdjustLimitedSamplingAsync
506 
507   Description:  Asynchronously adjusts the sampling rate used in sampling rate limited microphone auto-sampling.
508 
509                 This is an asynchronous function, so the actual processing results are passed when the callback is called.
510                 If this function is called on NITRO, it is replaced by the preexisting CPU-based auto-sampling adjustment function.
511 
512 
513   Arguments:    rate: Specifies the sampling interval in ARM7 CPU clock units.
514                 callback     - Specifies the function to be called when the asynchronous process is completed.
515                 arg       - Specifies the argument used when calling the callback function.
516 
517   Returns:      MICResult:    - Returns the result of starting the asynchronous device operation
518  *---------------------------------------------------------------------------*/
519 MICResult
MIC_AdjustLimitedSamplingAsync(u32 rate,MICCallback callback,void * arg)520 MIC_AdjustLimitedSamplingAsync(u32 rate, MICCallback callback, void* arg)
521 {
522     return ((OSi_IsCodecTwlMode() == TRUE) ?
523             MICEXi_AdjustLimitedSamplingAsync(rate, callback, arg) :
524             MIC_AdjustAutoSamplingAsync(rate, callback, arg));
525 }
526 
527 /*---------------------------------------------------------------------------*
528   Name:         MIC_StartLimitedSampling
529 
530   Description:  Starts sampling rate limited microphone auto-sampling.
531                 Sampling on precise frequencies is possible with a low burden on the CPU because sampling is performed by the hardware, but the sampling rate is limited to the rates supported by the hardware.
532 
533 
534                 This is a synchronous function, so calling from within an interrupt handler is prohibited.
535                 If this function is called on NITRO, it is replaced by the preexisting CPU-based auto-sampling start function.
536 
537 
538   Arguments:    param:     Pointer to a structure that specifies auto-sampling settings.
539 
540   Returns:      MICResult:    - Returns the result of the device operation process
541  *---------------------------------------------------------------------------*/
542 MICResult
MIC_StartLimitedSampling(const MICAutoParam * param)543 MIC_StartLimitedSampling(const MICAutoParam* param)
544 {
545     return ((OSi_IsCodecTwlMode() == TRUE) ?
546             MICEXi_StartLimitedSampling(param) :
547             MIC_StartAutoSampling(param));
548 }
549 
550 /*---------------------------------------------------------------------------*
551   Name:         MIC_StopLimitedSampling
552 
553   Description:  Stops sampling rate limited microphone auto-sampling.
554                 This is a synchronous function, so calling from within an interrupt handler is prohibited.
555                 f this function is called on NITRO, it is replaced by the preexisting CPU-based auto-sampling stop function.
556 
557 
558   Arguments:    None.
559 
560   Returns:      MICResult:    - Returns the result of the device operation process
561  *---------------------------------------------------------------------------*/
562 MICResult
MIC_StopLimitedSampling(void)563 MIC_StopLimitedSampling(void)
564 {
565     return ((OSi_IsCodecTwlMode() == TRUE) ?
566             MICEXi_StopLimitedSampling() :
567             MIC_StopAutoSampling());
568 }
569 
570 /*---------------------------------------------------------------------------*
571   Name:         MIC_AdjustLimitedSampling
572 
573   Description:  Adjusts the sampling rate used in sampling rate limited microphone auto-sampling.
574 
575                 This is a synchronous function, so calling from within an interrupt handler is prohibited.
576                 If this function is called on NITRO, it is replaced by the preexisting CPU-based auto-sampling adjustment function.
577 
578 
579   Arguments:    rate: Specifies the sampling interval in ARM7 CPU clock units.
580 
581   Returns:      MICResult:    - Returns the result of the device operation process
582  *---------------------------------------------------------------------------*/
583 MICResult
MIC_AdjustLimitedSampling(u32 rate)584 MIC_AdjustLimitedSampling(u32 rate)
585 {
586     return ((OSi_IsCodecTwlMode() == TRUE) ?
587             MICEXi_AdjustLimitedSampling(rate) :
588             MIC_AdjustAutoSampling(rate));
589 }
590 #endif
591 
592 /*---------------------------------------------------------------------------*
593   Name:         MicCommonCallback
594 
595   Description:  Common callback function for asynchronous MIC functions
596 
597   Arguments:    tag:   PXI tag that shows the message type.
598                 data:  Message from ARM7.
599                 err:   PXI transfer error flag.
600 
601   Returns:      None.
602  *---------------------------------------------------------------------------*/
MicCommonCallback(PXIFifoTag tag,u32 data,BOOL err)603 static void MicCommonCallback(PXIFifoTag tag, u32 data, BOOL err)
604 {
605 #pragma unused( tag )
606 
607     u16     command;
608     u16     pxiresult;
609     MICResult result;
610     MICCallback cb;
611 
612     // Verify PXI communication error
613     if (err)
614     {
615         if (micWork.lock != MIC_LOCK_OFF)
616         {
617             micWork.lock = MIC_LOCK_OFF;
618         }
619         if (micWork.callback)
620         {
621             cb = micWork.callback;
622             micWork.callback = NULL;
623             cb(MIC_RESULT_FATAL_ERROR, micWork.callbackArg);
624         }
625     }
626 
627     // Analyze received data
628     command = (u16)((data & SPI_PXI_RESULT_COMMAND_MASK) >> SPI_PXI_RESULT_COMMAND_SHIFT);
629     pxiresult = (u16)((data & SPI_PXI_RESULT_DATA_MASK) >> SPI_PXI_RESULT_DATA_SHIFT);
630 
631     // Check the result of processing
632     switch (pxiresult)
633     {
634     case SPI_PXI_RESULT_SUCCESS:
635         result = MIC_RESULT_SUCCESS;
636         break;
637     case SPI_PXI_RESULT_INVALID_COMMAND:
638         result = MIC_RESULT_INVALID_COMMAND;
639         break;
640     case SPI_PXI_RESULT_INVALID_PARAMETER:
641         result = MIC_RESULT_ILLEGAL_PARAMETER;
642         break;
643     case SPI_PXI_RESULT_ILLEGAL_STATUS:
644         result = MIC_RESULT_ILLEGAL_STATUS;
645         break;
646     case SPI_PXI_RESULT_EXCLUSIVE:
647         result = MIC_RESULT_BUSY;
648         break;
649     default:
650         result = MIC_RESULT_FATAL_ERROR;
651     }
652 
653     // Verify processing target command
654     if (command == SPI_PXI_COMMAND_MIC_BUFFER_FULL)
655     {
656         // Callback buffer full notification
657         if (micWork.full)
658         {
659             micWork.full(result, micWork.fullArg);
660         }
661     }
662     else
663     {
664         if (command == SPI_PXI_COMMAND_MIC_SAMPLING)
665         {
666             // Store sampling result in buffer
667             if (micWork.dst_buf)
668             {
669                 *(u16 *)(micWork.dst_buf) = OS_GetSystemWork()->mic_sampling_data;
670             }
671         }
672         // Open exclusive lock
673         if (micWork.lock != MIC_LOCK_OFF)
674         {
675             micWork.lock = MIC_LOCK_OFF;
676         }
677         // Callback processing result
678         if (micWork.callback)
679         {
680             cb = micWork.callback;
681             micWork.callback = NULL;
682             cb(result, micWork.callbackArg);
683         }
684     }
685 }
686 
687 /*---------------------------------------------------------------------------*
688   Name:         MicDoSampling
689 
690   Description:  Send command to ARM7 for sampling microphone once
691 
692   Arguments:    type - Sampling type
693                 ( 0: 8-bit , 1: 12-bit , 2: signed 8-bit, 3: signed 12-bit )
694 
695   Returns:      BOOL - Returns TRUE when the command was successfully sent via PXI and FALSE on failure.
696 
697  *---------------------------------------------------------------------------*/
MicDoSampling(u16 type)698 static BOOL MicDoSampling(u16 type)
699 {
700     // PXI Packet [0]
701     if (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_MIC,
702                                SPI_PXI_START_BIT |
703                                SPI_PXI_END_BIT |
704                                (0 << SPI_PXI_INDEX_SHIFT) |
705                                (SPI_PXI_COMMAND_MIC_SAMPLING << 8) | (u32)type, 0))
706     {
707         return FALSE;
708     }
709 
710     return TRUE;
711 }
712 
713 /*---------------------------------------------------------------------------*
714   Name:         MicStartAutoSampling
715 
716   Description:  Send start command for microphone auto-sampling to ARM7
717 
718   Arguments:    buf: Address of buffer storing sampled data.
719                 size     - Buffer size. Specified in byte units.
720                 span     - sampling interval (specify with ARM7 CPU clock)
721                         Because of the characteristics of the timer, only numbers of 16 bits x 1, 64, 256, or 1024 can be accurately set.
722                         Bits at the end are truncated.
723                 flags - Specifies the AD conversion bit width, enabling/disabling of loops, and enabling/disabling of correction
724 
725   Returns:      BOOL - Returns TRUE when the command was successfully sent via PXI and FALSE on failure.
726 
727  *---------------------------------------------------------------------------*/
MicStartAutoSampling(void * buf,u32 size,u32 span,u8 flags)728 static BOOL MicStartAutoSampling(void *buf, u32 size, u32 span, u8 flags)
729 {
730     // PXI Packet [0]
731     if (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_MIC,
732                                SPI_PXI_START_BIT |
733                                (0 << SPI_PXI_INDEX_SHIFT) |
734                                (SPI_PXI_COMMAND_MIC_AUTO_ON << 8) | (u32)flags, 0))
735     {
736         return FALSE;
737     }
738 
739     // PXI Packet [1]
740     if (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_MIC, (1 << SPI_PXI_INDEX_SHIFT) | ((u32)buf >> 16), 0))
741     {
742         return FALSE;
743     }
744 
745     // PXI Packet [2]
746     if (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_MIC,
747                                (2 << SPI_PXI_INDEX_SHIFT) | ((u32)buf & 0x0000ffff), 0))
748     {
749         return FALSE;
750     }
751 
752     // PXI Packet [3]
753     if (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_MIC, (3 << SPI_PXI_INDEX_SHIFT) | (size >> 16), 0))
754     {
755         return FALSE;
756     }
757 
758     // PXI Packet [4]
759     if (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_MIC,
760                                (4 << SPI_PXI_INDEX_SHIFT) | (size & 0x0000ffff), 0))
761     {
762         return FALSE;
763     }
764 
765     // PXI Packet [5]
766     if (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_MIC, (5 << SPI_PXI_INDEX_SHIFT) | (span >> 16), 0))
767     {
768         return FALSE;
769     }
770 
771     // PXI Packet [6]
772     if (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_MIC,
773                                SPI_PXI_END_BIT |
774                                (6 << SPI_PXI_INDEX_SHIFT) | (span & 0x0000ffff), 0))
775     {
776         return FALSE;
777     }
778     return TRUE;
779 }
780 
781 /*---------------------------------------------------------------------------*
782   Name:         MicStopAutoSampling
783 
784   Description:  Send stop command for microphone auto-sampling to ARM7
785 
786   Arguments:    None.
787 
788   Returns:      BOOL - Returns TRUE when the command was successfully sent via PXI and FALSE on failure.
789 
790  *---------------------------------------------------------------------------*/
MicStopAutoSampling(void)791 static BOOL MicStopAutoSampling(void)
792 {
793     // PXI Packet [0]
794     if (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_MIC,
795                                SPI_PXI_START_BIT |
796                                SPI_PXI_END_BIT |
797                                (0 << SPI_PXI_INDEX_SHIFT) | (SPI_PXI_COMMAND_MIC_AUTO_OFF << 8), 0))
798     {
799         return FALSE;
800     }
801     return TRUE;
802 }
803 
804 /*---------------------------------------------------------------------------*
805   Name:         MicAdjustAutoSampling
806 
807   Description:  Sends microphone auto-sampling change command to ARM7.
808 
809   Arguments:    span: Specifies the sampling interval in ARM7 CPU clock units.
810 
811   Returns:      BOOL - Returns TRUE when the command was successfully sent via PXI and FALSE on failure.
812 
813  *---------------------------------------------------------------------------*/
MicAdjustAutoSampling(u32 span)814 static BOOL MicAdjustAutoSampling(u32 span)
815 {
816     // PXI Packet [0]
817     if (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_MIC,
818                                SPI_PXI_START_BIT |
819                                (0 << SPI_PXI_INDEX_SHIFT) |
820                                (SPI_PXI_COMMAND_MIC_AUTO_ADJUST << 8), 0))
821     {
822         return FALSE;
823     }
824 
825     // PXI Packet [1]
826     if (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_MIC, (1 << SPI_PXI_INDEX_SHIFT) | (span >> 16), 0))
827     {
828         return FALSE;
829     }
830 
831     // PXI Packet [2]
832     if (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_MIC,
833                                SPI_PXI_END_BIT |
834                                (2 << SPI_PXI_INDEX_SHIFT) | (span & 0x0000ffff), 0))
835     {
836         return FALSE;
837     }
838     return TRUE;
839 }
840 
841 /*---------------------------------------------------------------------------*
842   Name:         MicGetResultCallback
843 
844   Description:  Called when asynchronous processing completes. Updates the processing results of internal variables.
845 
846   Arguments:    result  -   The processing results from async function.
847                 arg    - Not used
848 
849   Returns:      None.
850  *---------------------------------------------------------------------------*/
MicGetResultCallback(MICResult result,void * arg)851 static void MicGetResultCallback(MICResult result, void *arg)
852 {
853 #pragma unused( arg )
854 
855     micWork.commonResult = result;
856 }
857 
858 #include    <nitro/code32.h>
859 /*---------------------------------------------------------------------------*
860   Name:         MicWaitBusy
861 
862   Description:  Wait while asynchronous processing for MIC is locked
863 
864   Arguments:    None.
865 
866   Returns:      None.
867  *---------------------------------------------------------------------------*/
868 static asm void
MicWaitBusy(void)869 MicWaitBusy( void )
870 {
871     ldr     r12,    =micWork.lock
872 loop:
873     ldr     r0,     [ r12,  #0 ]
874     cmp     r0,     #MIC_LOCK_ON
875     beq     loop
876     bx      lr
877 }
878 #include    <nitro/codereset.h>
879 
880 #ifdef  SDK_TWL
881 /*---------------------------------------------------------------------------*
882   Name:         MICi_GetSysWork
883 
884   Description:  Gets the MIC library control structure.
885 
886   Arguments:    None.
887 
888   Returns:      MICWork*: Returns a pointer to the structure.
889  *---------------------------------------------------------------------------*/
890 MICWork*
MICi_GetSysWork(void)891 MICi_GetSysWork(void)
892 {
893     return &micWork;
894 }
895 #endif
896 
897 /*---------------------------------------------------------------------------*
898   End of file
899  *---------------------------------------------------------------------------*/
900