]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/blob - rpp/src/drv/dac.c
Merge port and gpio definitions into one file in the DRV layer
[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
23 #define DAC_PIN_NUM     4
24
25
26 /**
27  * Pin status for each DAC pin, the structure of each field is defined
28  * as spi command structure.
29  *
30  * See mcp4922.pdf p. 24
31  * Options:
32  *   Bit 13: Output Gain Selection bit set = 1x (VOUT = VREF * D/4096)
33  *   Bit 15: DACA (0) or DACB (1) Selection bit.
34  *
35  */
36 static uint16_t dac_pin_status[DAC_PIN_NUM] = {
37         (_BV(13)          ),
38         (_BV(13) | _BV(15)),
39         (_BV(13)          ),
40         (_BV(13) | _BV(15))
41 };
42
43 /**
44  * Port names for each DAC port, to be easily accessible by indexing
45  */
46 const char *dac_port_names[DAC_PIN_NUM] = {
47         DIO_PORT_NAME_DAC1_2,
48         DIO_PORT_NAME_DAC1_2,
49         DIO_PORT_NAME_DAC3_4,
50         DIO_PORT_NAME_DAC3_4
51 };
52
53 /**
54  * Command for SPI
55  */
56 static uint32_t dac_spi_cmd;
57 /**
58  * Shadow variable of SPI command
59  */
60 static uint32_t dac_spi_cmd_sh;
61
62 int drv_dac_spi_transfer(uint8_t pin, boolean_t enabled, uint16_t value)
63 {
64         // Check pin range
65         if (pin >= DAC_PIN_NUM)
66                 return -1;
67
68         // Check value range
69         if (value > 4095)
70                 return -2;
71
72         // Prepare command
73         if (enabled)
74                 bit_set(dac_pin_status[pin], 12);
75         else
76                 bit_clear(dac_pin_status[pin], 12);
77
78         dac_pin_status[pin] = dac_pin_status[pin] & 0xF000;
79         dac_pin_status[pin] |= (value & 0xFFF);
80
81         uint32_t commands[2];
82
83         // Warning!!! Can be "optimized" by compiler
84         dac_spi_cmd = dac_pin_status[pin];
85         dac_spi_cmd_sh = dac_spi_cmd;
86         //--
87         dio_port_desc_t *desc;
88         desc = dio_port_get_dsc(dac_port_names[pin], -1);
89         commands[0] = (dac_spi_cmd_sh & 0xFF00) >> 8;
90         commands[1] = (dac_spi_cmd_sh & 0xFF);
91
92         return desc->port_setfnc_ptr(desc->config, desc->numValues, commands);
93 }