Thank you to anyone who has already donated - your generous donations helped make three months of treatment possible.

My brother Nate continues to fight stage IV Hodgkin's lymphoma. He's just 31, with a wife and baby girl. They have no active income (since he's been unable to return to work), no insurance, and cannot afford the treatment he needs. Nate and his family need your help. Please consider a donation, every dollar helps. Thanks.


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));