]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/blob - rpp/src/rpp/dac.c
57ef9e7646ab51cb23657246588dfc8d7e01e2dc
[pes-rpp/rpp-lib.git] / rpp / src / rpp / dac.c
1 /* Copyright (C) 2013, 2015 Czech Technical University in Prague
2  *
3  * Authors:
4  *     - Carlos Jenkins <carlos@jenkins.co.cr>
5  *
6  * This document contains proprietary information belonging to Czech
7  * Technical University in Prague. Passing on and copying of this
8  * document, and communication of its contents is not permitted
9  * without prior written authorization.
10  *
11  * File : dac.c
12  * Abstract:
13  *     Analog Output RPP API implementation file.
14  *
15  * References:
16  *     dac.h
17  *     RPP API documentation.
18  */
19
20
21 #include "rpp/rpp.h"
22 #include "rpp/mutex.h"
23
24 #ifndef FREERTOS_POSIX
25 #include "drv/dac.h"
26 #include "drv/spi.h"
27 #endif
28
29 RPP_MUTEX_DEFINE(mutex_dac);
30
31 static boolean_t initialized = FALSE;
32
33 int8_t rpp_dac_init()
34 {
35         if (initialized)
36                 return FAILURE;
37         if (!RPP_MUTEX_INIT(mutex_dac))
38                 return FAILURE;
39         initialized = TRUE;
40 #ifndef FREERTOS_POSIX
41         spi_init();
42 #endif
43         // Configure board
44         // FIXME find out why board has default output of ~3.8V
45         //rpp_dac_setup(1, FALSE);
46         //rpp_dac_setup(2, FALSE);
47         //rpp_dac_setup(3, FALSE);
48         //rpp_dac_setup(4, FALSE);
49
50         return SUCCESS;
51 }
52
53
54 static boolean_t changed_st[4] = {
55         FALSE, FALSE, FALSE, FALSE
56 };
57 static boolean_t enabled_cache[4] = {
58         FALSE, FALSE, FALSE, FALSE
59 };
60 static uint16_t out_cache[4] = {
61         0, 0, 0, 0
62 };
63
64 int8_t rpp_dac_setup(uint8_t pin, boolean_t enabled)
65 {
66         // Check range
67         if ((pin < 1) || (pin > 4))
68                 return -1;
69
70         uint8_t index = pin - 1;
71
72         RPP_MUTEX_LOCK(mutex_dac);
73         // Mark state
74         enabled_cache[index] = enabled;
75
76         // Mark as changed
77         changed_st[index] = TRUE;
78         RPP_MUTEX_UNLOCK(mutex_dac);
79         return SUCCESS;
80 }
81
82
83 // Value that tops the DAC output
84 const static uint16_t dac_top =
85         (uint16_t)(4095.0 * (12000.0 / 1000.0) / (RPP_DAC_OA * RPP_DAC_VREF));
86
87 // Simple mapping function
88 static int32_t map(int32_t x,
89                                    int32_t in_min,  int32_t in_max,
90                                    int32_t out_min, int32_t out_max)
91 {
92         return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
93 }
94
95 int8_t rpp_dac_set(uint8_t pin, uint16_t val)
96 {
97         // Check pin range
98         if ((pin < 1) || (pin > 4))
99                 return -1;
100
101         // Map value
102         val = map(val, 0, 4095, 0, dac_top);
103
104         // Check value range
105         if (val > 4095)
106                 return -2;
107
108         uint8_t index = pin - 1;
109
110         RPP_MUTEX_LOCK(mutex_dac);
111         // Set value to output cache
112         out_cache[index] = val;
113
114         // Mark as changed
115         changed_st[index] = TRUE;
116         RPP_MUTEX_UNLOCK(mutex_dac);
117
118         return SUCCESS;
119 }
120
121
122 int8_t rpp_dac_set_voltage(uint8_t pin, uint16_t mv)
123 {
124         // Check pin range
125         if ((pin < 1) || (pin > 4))
126                 return -1;
127
128         // Check millivolts range
129         if (mv > 12000)
130                 return -2;
131
132         // Calculate millivolts -> value
133         int val = (int)(4095.0 * ((float)mv / 1000.0) / (RPP_DAC_OA*RPP_DAC_VREF));
134         if (val > 4095)
135                 val = 4095;
136
137         uint8_t index = pin - 1;
138
139         RPP_MUTEX_LOCK(mutex_dac);
140         // Set value to output cache
141         out_cache[index] = val;
142
143         // Mark as changed
144         changed_st[index] = TRUE;
145         RPP_MUTEX_UNLOCK(mutex_dac);
146
147         return SUCCESS;
148 }
149
150
151 int8_t rpp_dac_update()
152 {
153         int i = 0;
154
155         for (i = 0; i < 4; i++) {
156                 RPP_MUTEX_LOCK(mutex_dac);
157                 // If changed commit changes to hardware
158                 if (changed_st[i]) {
159
160 #ifndef FREERTOS_POSIX
161                         // TODO: Confirm via returned SPI code that transfer was successful
162                         drv_dac_spi_transfer(i, enabled_cache[i], out_cache[i]);
163 #else
164                         UNUSED(enabled_cache);
165                         UNUSED(out_cache);
166 #endif
167
168                         changed_st[i] = FALSE;
169                 }
170                 RPP_MUTEX_UNLOCK(mutex_dac);
171         }
172
173         return SUCCESS;
174 }