1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
diff --git a/firmware/target/arm/as3525/pcm-as3525.c b/firmware/target/arm/as3525/pcm-as3525.c
index 720f615..b539fb6 100644
--- a/firmware/target/arm/as3525/pcm-as3525.c
+++ b/firmware/target/arm/as3525/pcm-as3525.c
@@ -73,7 +73,7 @@ static void play_start_pcm(void)
     dma_size -= size;
     dma_start_addr += size;

-    clean_dcache_range((void*)addr, size);  /* force write back */
+    commit_dcache_range((void*)addr, size);  /* force write back */
     dma_enable_channel(1, (void*)addr, (void*)I2SOUT_DATA, DMA_PERI_I2SOUT,
                 DMAC_FLOWCTRL_DMAC_MEM_TO_PERI, true, false, size >> 2, DMA_S1,
                 dma_callback);
@@ -243,14 +243,12 @@ void pcm_rec_unlock(void)


 static void rec_dma_start(void)
-{
-    rec_dma_transfer_size = rec_dma_size;
-
+{                                                
     /* We are limited to 8188 DMA transfers, and the recording core asks for
      * 8192 bytes. Avoid splitting 8192 bytes transfers in 8188 + 4 */
-    if(rec_dma_transfer_size > 4096)
-        rec_dma_transfer_size = 4096;
+    rec_dma_transfer_size = MIN(rec_dma_size, 4096);

+    discard_dcache_range(rec_dma_start_addr, rec_dma_transfer_size);
     dma_enable_channel(1, (void*)I2SIN_DATA, rec_dma_start_addr, DMA_PERI_I2SIN,
                 DMAC_FLOWCTRL_DMAC_PERI_TO_MEM, false, true,
                 rec_dma_transfer_size >> 2, DMA_S4, rec_dma_callback);
@@ -275,7 +273,7 @@ static inline void mono2stereo(int16_t *end)
     mono_samples = samples; /* update pointer */
 #else
     /* gcc doesn't use pre indexing : let's save 1 cycle */
-    int16_t left;
+    register int left;
     asm (
         "1: ldrh %0, [%1], #2   \n" // load 1 sample of the left-channel
         "   strh %0, [%1], #2   \n" // copy it in the right-channel
@@ -291,25 +289,18 @@ static inline void mono2stereo(int16_t *end)

 static void rec_dma_callback(void)
 {
-    if(rec_dma_transfer_size)
-    {
-        rec_dma_size -= rec_dma_transfer_size;
-        rec_dma_start_addr += rec_dma_transfer_size;
-
-        /* don't act like we just transferred data when we are called from
-         * pcm_rec_unlock() */
-        rec_dma_transfer_size = 0;
+    rec_dma_size -= rec_dma_transfer_size;
+    rec_dma_start_addr += rec_dma_transfer_size;

 #if CONFIG_CPU == AS3525
-        /* the 2nd channel is silent when recording microphone on as3525v1 */
-        mono2stereo(AS3525_UNCACHED_ADDR((int16_t*)rec_dma_start_addr));
+    /* the 2nd channel is silent when recording microphone on as3525v1 */
+    mono2stereo((int16_t*)rec_dma_start_addr);
 #endif

-        if(locked)
-        {
-            rec_callback_pending = is_recording;
-            return;
-        }
+    if(locked)
+    {
+        rec_callback_pending = is_recording;
+        return;
     }

     if(!rec_dma_size)
@@ -319,10 +310,8 @@ static void rec_dma_callback(void)

         if(rec_dma_size == 0)
             return;
-
-        dump_dcache_range(rec_dma_start_addr, rec_dma_size);
 #if CONFIG_CPU == AS3525
-        mono_samples = AS3525_UNCACHED_ADDR((int16_t*)rec_dma_start_addr);
+        mono_samples = (int16_t*)rec_dma_start_addr;
 #endif
     }

@@ -346,10 +335,10 @@ void pcm_rec_dma_stop(void)

 void pcm_rec_dma_start(void *addr, size_t size)
 {
-    dump_dcache_range(addr, size);
+    discard_dcache_range(addr, size);
     rec_dma_start_addr = addr;
 #if CONFIG_CPU == AS3525
-    mono_samples = AS3525_UNCACHED_ADDR(addr);
+    mono_samples = addr;
 #endif
     rec_dma_size = size;

@@ -397,12 +386,16 @@ const void * pcm_rec_dma_get_peak_buffer(void)
      */

     int old = disable_irq_save();
+    /* make mono2stereo operate on uncached memory for look-ahead */
+    mono_samples = AS3525_UNCACHED_ADDR(mono_samples);
+
     int16_t *addr = AS3525_UNCACHED_ADDR((int16_t *)DMAC_CH_DST_ADDR(1));
     mono2stereo(addr);
+
+    mono_samples = AS3525_CACHED_ADDR(mono_samples);
     restore_irq(old);

     return addr;
-
 #else
     /* Microphone recording is stereo on as3525v2 */
     return AS3525_UNCACHED_ADDR((int16_t *)DMAC_CH_DST_ADDR(1));