]> Pileus Git - ~andy/csm213a-hw/blob - hw2/test.cpp
Improve time sync accuracy
[~andy/csm213a-hw] / hw2 / test.cpp
1 #include "mbed.h"\r
2 #include "serial_dma.h"\r
3 #include "timer_dma.h"\r
4 \r
5 /**\r
6  *\r
7  * Only port A, C, and D can do aysnc DMA (p. 67)\r
8  *\r
9  * DMA Channel Allocation:\r
10  *     Ch  Trigger    Description\r
11  *     0   gpio       timestamp (async event)\r
12  *     1   uart1      transmit\r
13  *     2   uart2 tx   timestamp (time sync xmt)\r
14  *     3   uart2 rx   timestamp (time sync rcv)\r
15  *\r
16  * Uart Sources:\r
17  *      UART 0     UART 1     UART 2\r
18  *     xmt  rcv   xmt  rcv   xmt  rcv\r
19  *     ---  ---   ---  ---   ---  ---\r
20  *     A2   A1  --A19  A18-- -    -\r
21  *     A14  A15   -    -     -    -\r
22  *     B17  B16   -    -     -    -\r
23  *     -    -   **C4   C3--  -    -\r
24  *     D7   D6    -    -   **D3/3 D2/3** <<<\r
25  *     -    -     -    -   **D5/3 D4/3**\r
26  *     E20  E21   E0   E1    E16  E17\r
27  *     -    -     -    -     E22  E23\r
28  *\r
29  * Pinout\r
30  *     A1    B18        E30  C1\r
31  *     A2    B19        B20  C2\r
32  *     D3    C0         E23  B3\r
33  *     A12   C4         E22  B2\r
34  *     A4    C6         E21  B1\r
35  *     A5    C7         E20  B0\r
36  *     C8    C10\r
37  *     C9    C11        E2   P5-9V\r
38  *                      E3   GND\r
39  *     A13   C13        E6   GND\r
40  *     D2    C16        E16  P5V-USB\r
41  *     D4    A7         E17  P3V3\r
42  *     D6    A6         E18  RST\r
43  *     D7    A14        E19  P3V3\r
44  *     D5    A15        E31  SDA/D5\r
45  *     GND   A15\r
46  *     VREFH A17\r
47  *     E0    B9\r
48  *     E1    --\r
49  */\r
50 \r
51 /* Trigger select options */\r
52 \r
53 #define TMP_CONF_TRGSEL_EXTRG 0x0 // 0b0000 External trigger pin input (EXTRG_IN)\r
54 #define TMP_CONF_TRGSEL_CMP0  0x1 // 0b0001 CMP0 output\r
55 #define TMP_CONF_TRGSEL_PIT0  0x4 // 0b0100 PIT trigger 0\r
56 #define TMP_CONF_TRGSEL_PIT1  0x5 // 0b0101 PIT trigger 1\r
57 #define TMP_CONF_TRGSEL_TPM0  0x8 // 0b1000 TPM0 overflow\r
58 #define TMP_CONF_TRGSEL_TPM1  0x9 // 0b1001 TPM1 overflow\r
59 #define TMP_CONF_TRGSEL_TPM2  0xA // 0b1010 TPM2 overflow\r
60 #define TMP_CONF_TRGSEL_RTCA  0xC // 0b1100 RTC alarm\r
61 #define TMP_CONF_TRGSEL_RTCS  0xD // 0b1101 RTC seconds\r
62 #define TMP_CONF_TRGSEL_LPTMR 0xE // 0b1110 LPTMR trigger\r
63 \r
64 /********************\r
65  * Data definitions *\r
66  ********************/\r
67 \r
68 // LEDs\r
69 extern DigitalOut led1;\r
70 extern DigitalOut led2;\r
71 \r
72 // UARTs\r
73 extern Serial     uart0;\r
74 extern Serial     uart1;\r
75 extern Serial     uart2;\r
76 \r
77 // Serial DMA\r
78 extern sdma_t    *sdma0;\r
79 extern sdma_t    *sdma1;\r
80 extern sdma_t    *sdma2;\r
81 \r
82 // Timer DMA\r
83 extern tdma_t    *tdma0;\r
84 extern tdma_t    *tdma1;\r
85 extern tdma_t    *tdma2;\r
86 extern tdma_t    *tdma3;\r
87 \r
88 /********\r
89  * Main *\r
90  ********/\r
91 \r
92 void test_tpm_init(void)\r
93 {\r
94         // EXTRG_IN - PTB8 - alt 3\r
95         //            PTC0 - alt 3\r
96         //            PTC6 - alt 3\r
97 \r
98         // Setup System Integration Module\r
99         SIM_Type *sim = SIM;\r
100 \r
101         sim->SCGC5 |= SIM_SCGC5_PORTA_MASK\r
102                    |  SIM_SCGC5_PORTB_MASK\r
103                    |  SIM_SCGC5_PORTC_MASK\r
104                    |  SIM_SCGC5_PORTD_MASK\r
105                    |  SIM_SCGC5_PORTE_MASK\r
106                    |  SIM_SCGC5_LPTMR_MASK;\r
107 \r
108         sim->SCGC6 |= SIM_SCGC6_TPM0_MASK\r
109                    |  SIM_SCGC6_TPM1_MASK\r
110                    |  SIM_SCGC6_TPM2_MASK\r
111                    |  SIM_SCGC6_DAC0_MASK\r
112                    |  SIM_SCGC6_ADC0_MASK\r
113                    |  SIM_SCGC6_PIT_MASK\r
114                    |  SIM_SCGC6_DMAMUX_MASK\r
115                    |  SIM_SCGC6_RTC_MASK;\r
116 \r
117         sim->SOPT2 |= SIM_SOPT2_TPMSRC(1);\r
118 \r
119         sim->SOPT4  = SIM_SOPT4_TPM1CLKSEL_MASK\r
120                    |  SIM_SOPT4_TPM1CH0SRC(3);\r
121 \r
122         printf("SOPT2:%08lx SCGC5:%08lx SCGC6:%08lx\r\n",\r
123                         sim->SOPT2, sim->SCGC5, sim->SCGC6);\r
124         //SOPT2:05010000 SCGC5:00003f83 SCGC6:07800001\r
125 \r
126         //sim->SOPT7 |= SIM_SOPT7_ADC0TRGSEL(TMP_CONF_TRGSEL_EXTRG);\r
127 \r
128         // Setup Port Control\r
129         PORT_Type *port = PORTC;\r
130 \r
131         PORTE->PCR[25] = PORT_PCR_ISF_MASK\r
132                        | PORT_PCR_IRQC(0x1)\r
133                        | PORT_PCR_MUX(3) ;\r
134 \r
135         port->PCR[0]   = PORT_PCR_ISF_MASK\r
136                        | PORT_PCR_IRQC(0x1)\r
137                        | PORT_PCR_MUX(3)\r
138                        | PORT_PCR_PE_MASK;\r
139 \r
140         // Setup Timer/PWM Module\r
141         volatile TPM_Type *tpm = TPM1;\r
142 \r
143         tpm->SC               = TPM_SC_PS(0x7)\r
144                               | TPM_SC_TOF_MASK;\r
145 \r
146         tpm->CNT              = TPM_CNT_COUNT(0);\r
147 \r
148         tpm->MOD              = TPM_CNT_COUNT(0xFFFF);\r
149 \r
150         tpm->CONTROLS[1].CnV  = 0x1234;\r
151         tpm->CONTROLS[1].CnSC = TPM_CnSC_CHF_MASK\r
152                               | TPM_CnSC_CHIE_MASK\r
153                               | TPM_CnSC_ELSA_MASK;\r
154 \r
155         //tpm->CONTROLS[0].CnSC = TPM_CnSC_CHF_MASK\r
156         //                    | TPM_CnSC_CHIE_MASK\r
157         //                    | TPM_CnSC_MSB_MASK\r
158         //                    | TPM_CnSC_MSA_MASK\r
159         //                    | TPM_CnSC_ELSB_MASK\r
160         //                    | TPM_CnSC_ELSA_MASK;\r
161 \r
162         tpm->STATUS           = TPM_STATUS_CH0F_MASK\r
163                               | TPM_STATUS_CH1F_MASK\r
164                               | TPM_STATUS_CH2F_MASK\r
165                               | TPM_STATUS_CH3F_MASK\r
166                               | TPM_STATUS_CH4F_MASK\r
167                               | TPM_STATUS_CH5F_MASK\r
168                               | TPM_STATUS_TOF_MASK;\r
169 \r
170         tpm->CONF             = TPM_CONF_TRGSEL(TMP_CONF_TRGSEL_EXTRG)\r
171                               | TPM_CONF_CSOO_MASK\r
172                               | TPM_CONF_CSOT_MASK\r
173                               | TPM_CONF_GTBEEN_MASK\r
174                               | TPM_CONF_DBGMODE_MASK;\r
175 \r
176         tpm->SC               = TPM_SC_CMOD(1)\r
177                               | TPM_SC_PS(0x7)\r
178                               | TPM_SC_TOF_MASK;\r
179 \r
180         printf("test - %02lx %08lx\r\n", tpm->CONTROLS[1].CnSC, tpm->CONTROLS[1].CnV); wait(0.1);\r
181 }\r
182 \r
183 void test_tpm_run(void)\r
184 {\r
185         //static DigitalIn pin(PTC0);\r
186         //static DigitalIn pin(PTC2);\r
187         //static int pin = 0;\r
188 \r
189         printf("PTC0:%08lx GPCR:%08lx:%08lx - SC:%04lx CNT:%04lx MOD:%04lx STATUS:%04lx CONF:%08lx - CnSC:%02lx CnV:%04lx\r\n",\r
190                         PORTC->PCR[0], PORTC->GPCHR, PORTC->GPCLR,\r
191                         TPM1->SC, TPM1->CNT, TPM1->MOD, TPM1->STATUS, TPM1->CONF,\r
192                         TPM1->CONTROLS[1].CnSC, TPM1->CONTROLS[1].CnV);\r
193         TPM1->SC     |= TPM_STATUS_TOF_MASK;\r
194         TPM1->STATUS |= TPM_STATUS_TOF_MASK;\r
195 }\r
196 \r
197 void test_pit_init(void)\r
198 {\r
199         //printf("test_pit_init\r\n");\r
200 \r
201         // Enable\r
202         SIM->SCGC6 |= SIM_SCGC6_PIT_MASK;\r
203         PIT->MCR    = 0;\r
204 \r
205         // Channel 0\r
206         PIT->CHANNEL[0].LDVAL = 0xFFFFFFFF;\r
207         PIT->CHANNEL[0].TCTRL = 0;\r
208 \r
209         // Channel 1\r
210         PIT->CHANNEL[1].LDVAL = 0xFFFFFFFF;\r
211         PIT->CHANNEL[1].TCTRL = PIT_TCTRL_CHN_MASK;\r
212 \r
213         // Start timers\r
214         PIT->CHANNEL[0].TCTRL |= PIT_TCTRL_TEN_MASK;\r
215         PIT->CHANNEL[1].TCTRL |= PIT_TCTRL_TEN_MASK;\r
216 \r
217 }\r
218 \r
219 void test_pit_run(void)\r
220 {\r
221         register volatile uint32_t *tmh asm("r4") = &PIT->LTMR64H;\r
222         register volatile uint32_t *tml asm("r5") = &PIT->LTMR64L;\r
223 \r
224         register uint32_t hi0 asm("r0"), lo0 asm("r1");\r
225         register uint32_t hi1 asm("r2"), lo1 asm("r3");\r
226 \r
227         asm("ldr %0, [%4]\n\t" // Two clocks per load\r
228             "ldr %1, [%5]\n\t"\r
229             "ldr %2, [%4]\n\t"\r
230             "ldr %3, [%5]\n\t"\r
231             : "=r"(hi0), "=r"(lo0), "=r"(hi1), "=r"(lo1)\r
232             :  "r"(tmh),  "r"(tml));\r
233 \r
234         uint64_t tm0 = ~((uint64_t)hi0 << 32 | lo0);\r
235         uint64_t tm1 = ~((uint64_t)hi1 << 32 | lo1);\r
236         double   bus = 24E6;   // 24 MHz bus clock\r
237 \r
238         printf(" - pit");\r
239         printf("  %08lx:%08lx", (uint32_t)(tm0>>32), (uint32_t)tm0);\r
240         printf("  %08lx:%08lx", (uint32_t)(tm1>>32), (uint32_t)tm1);\r
241         printf("  %08lx",       (uint32_t)(tm1-tm0));\r
242         printf("  %f",          (double)tm0 / bus);\r
243 }\r
244 \r
245 void test_sdma_init(void)\r
246 {\r
247         sdma0 = sdma_open(SDMA_UART0, SDMA_CHANNEL0, SDMA_CHANNEL1);\r
248         sdma1 = sdma_open(SDMA_UART1, SDMA_CHANNEL0, SDMA_CHANNEL1);\r
249         sdma2 = sdma_open(SDMA_UART2, SDMA_CHANNEL2, SDMA_CHANNEL3);\r
250 \r
251         sdma_pinmap(sdma1, PTE0, PTE1);\r
252         sdma_pinmap(sdma2, PTD3, PTD2);\r
253 }\r
254 \r
255 void test_sdma_run(void)\r
256 {\r
257         char xmt[32] = "hello, world";\r
258         char rcv[32] = {};\r
259 \r
260         uint64_t tm1, tm2;\r
261 \r
262         sdma_write(sdma1, xmt, strlen(xmt));\r
263         sdma_flush(sdma1, &tm1);\r
264 \r
265         sdma_read(sdma2, rcv, strlen(xmt));\r
266         sdma_wait(sdma2, &tm2);\r
267 \r
268         printf("send: [%s] -> [%s] ", xmt, rcv);\r
269         printf("time: %08lx / %08lx ", (uint32_t)tm1, (uint32_t)tm2);\r
270         printf("tag: dir:%08lx in:%08lx\r\n",\r
271                         FPTD->PDDR, FPTD->PDIR);\r
272 \r
273         (void)xmt; (void)rcv;\r
274         (void)tm1; (void)tm2;\r
275 }\r
276 \r
277 void test_tdma_init(void)\r
278 {\r
279         tdma_init();\r
280 \r
281         tdma0 = tdma_open(TDMA_CHAN0, 3, PTA1, PullNone);\r
282         tdma1 = tdma_open(TDMA_CHAN1, 3, PTC1, PullNone);\r
283         tdma2 = tdma_open(TDMA_CHAN2, 3, PTD3, PullUp);\r
284         tdma3 = tdma_open(TDMA_CHAN3, 3, PTD2, PullUp);\r
285 }\r
286 \r
287 void test_tdma_run(void)\r
288 {\r
289         static uint32_t time0[2];\r
290         static uint32_t time1[2];\r
291         static uint32_t time2[2];\r
292         static uint32_t time3[2];\r
293 \r
294         tdma_stamp(tdma0, (uint64_t*)&time0);\r
295         tdma_stamp(tdma1, (uint64_t*)&time1);\r
296         tdma_stamp(tdma2, (uint64_t*)&time2);\r
297         tdma_stamp(tdma3, (uint64_t*)&time3);\r
298 \r
299         tdma_start(tdma0);\r
300         tdma_start(tdma1);\r
301         tdma_start(tdma2);\r
302         tdma_start(tdma3);\r
303 \r
304         printf(" - timer:");\r
305         printf(" %08lx:%08lx", time0[1], time0[0]);\r
306         printf(" %08lx:%08lx", time1[1], time1[0]);\r
307         printf(" %08lx:%08lx", time2[1], time2[0]);\r
308         printf(" %08lx:%08lx", time3[1], time3[0]);\r
309         //printf(" do:%08lx", FPTD->PDOR);\r
310         //printf(" di:%08lx", FPTD->PDIR);\r
311         //printf(" dd:%08lx", FPTD->PDDR);\r
312 }\r
313 \r
314 void test_leds(void)\r
315 {\r
316         led1 = 1; led2 = 0; wait(0.1);\r
317         led1 = 0; led2 = 1; wait(0.1);\r
318 }\r
319 \r
320 void test_main(void)\r
321 {\r
322         printf("init\r\n");\r
323         //test_tpm_init();\r
324         //test_pit_init();\r
325         //test_sdma_init();\r
326         //test_tdma_init();\r
327 \r
328         printf("run\r\n");\r
329         for (int i = 0; true; i++) {\r
330                 printf("%8d", i);\r
331                 test_leds();\r
332                 //test_tpm_run();\r
333                 //test_pit_run();\r
334                 //test_sdma_run();\r
335                 //test_tdma_run();\r
336                 printf("\r\n");\r
337         }\r
338 }\r