]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/blob - rpp/src/drv/dac.c
Make configuration of SPI devices target dependent
[pes-rpp/rpp-lib.git] / rpp / src / drv / dac.c
1 /* Copyright (C) 2012-2015 Czech Technical University in Prague
2  *
3  * Authors:
4  *     - Michal Horn
5  *     - Carlos Jenkins <carlos@jenkins.co.cr>
6  *
7  * This document contains proprietary information belonging to Czech
8  * Technical University in Prague. Passing on and copying of this
9  * document, and communication of its contents is not permitted
10  * without prior written authorization.
11  *
12  * File : dac.c
13  * Abstract:
14  *     RPP driver implementation for DAC.
15  *
16  * References:
17  *     None
18  */
19
20
21 #include "drv/dac.h"
22 #include "drv/port.h"
23
24 #define DAC_PIN_NUM     4
25
26
27 /**
28  * Pin status for each DAC pin, the structure of each field is defined
29  * as spi command structure.
30  *
31  * See mcp4922.pdf p. 24
32  * Options:
33  *   Bit 13: Output Gain Selection bit set = 1x (VOUT = VREF * D/4096)
34  *   Bit 15: DACA (0) or DACB (1) Selection bit.
35  *
36  */
37 static uint16_t dac_pin_status[DAC_PIN_NUM] = {
38         (_BV(13)          ),
39         (_BV(13) | _BV(15)),
40         (_BV(13)          ),
41         (_BV(13) | _BV(15))
42 };
43
44 /**
45  * Port names for each DAC port, to be easily accessible by indexing
46  */
47 static const enum port_id dac_ports[DAC_PIN_NUM] = {
48         PORT_ID_DAC1_2,
49         PORT_ID_DAC1_2,
50         PORT_ID_DAC3_4,
51         PORT_ID_DAC3_4,
52 };
53
54 /**
55  * Command for SPI
56  */
57 static uint32_t dac_spi_cmd;
58 /**
59  * Shadow variable of SPI command
60  */
61 static uint32_t dac_spi_cmd_sh;
62
63 int drv_dac_spi_transfer(uint8_t pin, boolean_t enabled, uint16_t value)
64 {
65         // Check pin range
66         if (pin >= DAC_PIN_NUM)
67                 return -1;
68
69         // Check value range
70         if (value > 4095)
71                 return -2;
72
73         // Prepare command
74         if (enabled)
75                 bit_set(dac_pin_status[pin], 12);
76         else
77                 bit_clear(dac_pin_status[pin], 12);
78
79         dac_pin_status[pin] = dac_pin_status[pin] & 0xF000;
80         dac_pin_status[pin] |= (value & 0xFFF);
81
82         char commands[2];
83
84         // Warning!!! Can be "optimized" by compiler
85         dac_spi_cmd = dac_pin_status[pin];
86         dac_spi_cmd_sh = dac_spi_cmd;
87         //--
88         const struct port_desc *port = &port_desc[dac_ports[pin]];
89         commands[0] = (dac_spi_cmd_sh & 0xFF00) >> 8;
90         commands[1] = (dac_spi_cmd_sh & 0xFF);
91
92         return port->set(port, commands, sizeof(commands));
93 }