altos: Work on MAX6691 driver
[fw/altos] / src / drivers / ao_max6691.c
1 /*
2  * Copyright © 2019 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  */
14
15 #include "ao.h"
16 #include "ao_max6691.h"
17
18 #define cat(a,b)        a ## b
19
20 #define AO_MAX6691_CCR          (AO_MAX6691_TIMER->cat(ccr, AO_MAX6691_CH))
21
22 #if 0
23 static uint16_t ao_max6691_data[8];
24
25 void
26 ao_max6691_sample(void)
27 {
28         /* Get the DMA engine ready */
29         ao_dma_set_transfer(AO_MAX6691_DMA,
30                             &AO_MAX6691_CCR,
31                             &ao_max6691_data,
32                             8,
33                             (0 << STM_DMA_CCR_MEM2MEM) |
34                             (STM_DMA_CCR_PL_MEDIUM << STM_DMA_CCR_PL) |
35                             (STM_DMA_CCR_MSIZE_16 << STM_DMA_CCR_MSIZE) |
36                             (STM_DMA_CCR_PSIZE_16 << STM_DMA_CCR_PSIZE) |
37                             (1 << STM_DMA_CCR_MINC) |
38                             (0 << STM_DMA_CCR_PINC) |
39                             (0 << STM_DMA_CCR_CIRC) |
40                             (STM_DMA_CCR_DIR_PER_TO_MEM << STM_DMA_CCR_DIR));
41         ao_dma_start(AO_MAX6691_DMA);
42
43         /* Prod the max6691 */
44         ao_gpio_set(AO_MAX6691_PORT, AO_MAX6691_PIN, 0);
45         ao_arch_nop();
46         ao_gpio_set(AO_MAX6691_PORT, AO_MAX6691_PIN, 1);
47
48         /* Switch the pin to timer input mode */
49         stm_afr_set(AO_MAX6691_GPIO, AO_MAX6691_PIN, STM_AFR_AF1);
50
51         ao_arch_block_interrupts();
52         while (!ao_dma_done(AO_MAX6691_DMA))
53                 ao_sleep(&ao_dma_done(AO_MAX6691_DMA));
54         ao_arch_release_interrupts();
55
56         /* Switch pin back to output mode */
57         stm_moder_set(AO_MAX6691_GPIO, AO_MAX6691_PIN, STM_MODER_OUTPUT);
58
59         /* Mark DMA done */
60         ao_dma_done_transfer(AO_MAX6691_DMA);
61 }
62 #endif
63
64 static void
65 ao_max6691_test(void)
66 {
67         int i;
68
69         printf("Testing MAX6691\n");
70         /* Prod the max6691 */
71         ao_set_output(AO_MAX6691_GPIO, AO_MAX6691_PIN, 0);
72         for (i = 0; i < 1000; i++) {
73                 ao_led_on(AO_LED_ARMED);
74                 ao_gpio_set(AO_MAX6691_GPIO, AO_MAX6691_PIN, 0);
75                 ao_delay(AO_MS_TO_TICKS(250));
76                 ao_led_off(AO_LED_ARMED);
77                 ao_gpio_set(AO_MAX6691_GPIO, AO_MAX6691_PIN, 1);
78                 ao_delay(AO_MS_TO_TICKS(250));
79         }
80 #if 0
81         uint16_t        tick;
82         uint16_t        i, j;
83         uint8_t         p, v;
84
85         for (i = 0; i < 100; i++)
86                 ao_arch_nop();
87         ao_gpio_set(AO_MAX6691_GPIO, AO_MAX6691_PIN, 1);
88         ao_arch_nop();
89         ao_set_input(AO_MAX6691_GPIO, AO_MAX6691_PIN);
90         i = 0;
91         p = 1;
92         for (tick = 0; i < 8 && tick < 10000; tick++)
93         {
94                 v = ao_gpio_get(AO_MAX6691_GPIO, AO_MAX6691_PIN);
95                 if (v != p) {
96                         ao_max6691_data[i++] = tick;
97                         p = v;
98                 }
99         }
100         for (j = 0; j < i; i++)
101                 printf("%d: %5u\n", j, ao_max6691_data[j]);
102 #endif
103         printf("Done\n");
104 }
105
106 static const struct ao_cmds ao_max6691_cmds[] = {
107         { ao_max6691_test,      "q\0Thermistor test" },
108         { 0, NULL },
109 };
110
111
112 void
113 ao_max6691_init(void)
114 {
115         ao_cmd_register(&ao_max6691_cmds[0]);
116
117 #if 0
118         struct stm_tim234       *tim = &AO_MAX6691_TIMER;
119
120         stm_rcc.apb1enr |= (1 << AO_MAX6691_TIMER_ENABLE);
121
122         tim->cr1 = 0;
123         tim->psc = 0;
124         tim->cnt = 0;
125
126         tim->ccmr1 = ((0 << STM_TIM234_CCMR1_IC2F) |
127                       (
128
129
130         tim->ccmr2 = ((0 << STM_TIM234_CCMR2_OC4CE) |
131                       (STM_TIM234_CCMR2_OC4M_PWM_MODE_1 << STM_TIM234_CCMR2_OC4M) |
132                       (0 << STM_TIM234_CCMR2_OC4PE) |
133                       (0 << STM_TIM234_CCMR2_OC4FE) |
134                       (STM_TIM234_CCMR2_CC4S_OUTPUT << STM_TIM234_CCMR2_CC4S) |
135
136                       (0 << STM_TIM234_CCMR2_OC3CE) |
137                       (STM_TIM234_CCMR2_OC3M_PWM_MODE_1 << STM_TIM234_CCMR2_OC3M) |
138                       (0 << STM_TIM234_CCMR2_OC3PE) |
139                       (0 << STM_TIM234_CCMR2_OC3FE) |
140                       (STM_TIM234_CCMR2_CC3S_OUTPUT << STM_TIM234_CCMR2_CC3S));
141         tim->ccer = ((1 << STM_TIM234_CCER_CC1E) |
142                      (0 << STM_TIM234_CCER_CC1P) |
143                      (1 << STM_TIM234_CCER_CC2E) |
144                      (0 << STM_TIM234_CCER_CC2P) |
145                      (1 << STM_TIM234_CCER_CC3E) |
146                      (0 << STM_TIM234_CCER_CC3P) |
147                      (1 << STM_TIM234_CCER_CC4E) |
148                      (0 << STM_TIM234_CCER_CC4P));
149
150         tim->egr = 0;
151
152         tim->sr = 0;
153         tim->dier = 0;
154         tim->smcr = 0;
155         tim->cr2 = ((0 << STM_TIM234_CR2_TI1S) |
156                     (STM_TIM234_CR2_MMS_RESET<< STM_TIM234_CR2_MMS) |
157                     (0 << STM_TIM234_CR2_CCDS));
158
159         tim->cr1 = ((STM_TIM234_CR1_CKD_1 << STM_TIM234_CR1_CKD) |
160                     (0 << STM_TIM234_CR1_ARPE) |
161                     (STM_TIM234_CR1_CMS_EDGE << STM_TIM234_CR1_CMS) |
162                     (STM_TIM234_CR1_DIR_UP << STM_TIM234_CR1_DIR) |
163                     (0 << STM_TIM234_CR1_OPM) |
164                     (0 << STM_TIM234_CR1_URS) |
165                     (0 << STM_TIM234_CR1_UDIS) |
166                     (1 << STM_TIM234_CR1_CEN));
167
168         tim->cr2 = ((0 << STM_TIM234_CR2_TI1S) |
169                     (STM_TIM234_CR2_MMS_RESET << STM_TIM234_CR2_MMS) |
170                     (0 << STM_TIM234_CR2_CCDS));
171
172         tim->dier = ((0 << STM_TIM234_DIER_TDE) |
173                      (0 << STM_TIM234_DIER_CC4DE) |
174                      (0 << STM_TIM234_DIER_CC3DE) |
175                      (1 << STM_TIM234_DIER_CC2DE) |
176                      (0 << STM_TIM234_DIER_CC1DE) |
177                      (0 << STM_TIM234_DIER_TIE) |
178                      (0 << STM_TIM234_DIER_CC4IE) |
179                      (0 << STM_TIM234_DIER_CC3IE) |
180                      (0 << STM_TIM234_DIER_CC2IE) |
181                      (0 << STM_TIM234_DIER_CC1IE) |
182                      (0 << STM_TIM234_DIER_UIE));
183
184         tim->egr = ((0 << STM_TIM234_EGR_TG) |
185                     (0 << STM_TIM234_EGR_CC4G) |
186                     (0 << STM_TIM234_EGR_CC3G) |
187                     (1 << STM_TIM234_EGR_CC2G) |
188                     (0 << STM_TIM234_EGR_CC1G) |
189                     (0 << STM_TIM234_EGR_UG));
190
191         tim->ccmr1 = ((0 << STM_TIM234_CCMR_IC2F) |
192                       (0 << STM_TIM234_CCMR_IC2PSC) |
193                       (2 << STM_TIM234_CCMR_CC2S) |
194                       (
195
196         stm_ospeedr_set(AO_MAX6691_GPIO, AO_MAX6691_PIN, STM_OSPEEDR_40MHz);
197 #endif
198         ao_enable_output(AO_MAX6691_GPIO, AO_MAX6691_PIN, 1);
199 }