Appiko
mcp4012_x.c
1 
25 #include "mcp4012_x.h"
26 #include "boards.h"
27 #include "nrf.h"
28 #include "hal_nop_delay.h"
29 #include "hal_gpio.h"
30 #include "string.h"
31 #include "stdint.h"
32 #include "nrf_assert.h"
33 
34 #ifndef SPIM_ENABLE_ENABLE_Enabled
35 #error "The SoC does not have the SPIM peripheral needed for this module"
36 #endif
37 
38 #define SPIM_ID CONCAT_2(NRF_SPIM,SPIM_USED_MCP4012_DRIVER)
39 
42 static void simple_spi_init();
43 
50 static void simple_spi_transmit(uint8_t *data, uint32_t len);
51 
52 #define BUFFER_SIZE 16
53 
55 #define NO_OF_STEPS 64
56 
57 #define SIZE_OF_WORD (NO_OF_STEPS/BUFFER_SIZE)
58 
60 #define ALL_AA 0xAA
61 
62 #define ALL_00 0x00
63 
64 static uint8_t data_to_be_sent[BUFFER_SIZE];
65 static uint32_t UD_bar;
66 static uint32_t CS_bar;
67 static uint32_t SCK_pin;
68 
69 void mcp4012_init(uint32_t CS_bar_pin_no, uint32_t UD_bar_pin_no, uint32_t SCK_pin_no)
70 {
71  hal_gpio_cfg_output(CS_bar_pin_no, 1);
72  hal_gpio_cfg_output(UD_bar_pin_no, 1);
73  hal_gpio_cfg_output(SCK_pin_no, 1);
74  UD_bar = UD_bar_pin_no;
75  CS_bar = CS_bar_pin_no;
76  SCK_pin = SCK_pin_no;
77 }
78 
79 void mcp4012_set_value(uint32_t value_sent_by_user)
80 {
81  ASSERT(value_sent_by_user < NO_OF_STEPS);
82  uint32_t i =0;
83  uint32_t word_no = 0;
84  uint32_t last_seq = 0;
85  uint32_t last_word_no = 0;
86  uint32_t wiper_value = 0;
87  /*Set value of all the bytes in data_to_be_sent as 0b10101010*/
88  memset(data_to_be_sent, ALL_AA, BUFFER_SIZE);
89 
90  /* Part to set wiper value to maximum */
91  hal_gpio_pin_set(CS_bar);
92  hal_nop_delay_us(1);
93  hal_gpio_pin_set(UD_bar);
94  hal_nop_delay_us(1); //T(LCU)
95  hal_gpio_pin_clear(CS_bar);
96  hal_nop_delay_us(1); //T(LCUF)
97  hal_gpio_pin_clear(UD_bar);
98  hal_nop_delay_us(2); //T(LCUR)-T(LCUF)
99  simple_spi_transmit(data_to_be_sent, BUFFER_SIZE);
100  hal_gpio_pin_set(CS_bar);
101 
102  /* As we are setting wiper value to maximum, to set value to different value
103  we need to decrease it by (maximum_wiper_value - value_sent_by_user) */
104  wiper_value = NO_OF_STEPS - value_sent_by_user;
105  word_no = wiper_value/SIZE_OF_WORD;
106  last_seq = wiper_value % SIZE_OF_WORD;
107  last_word_no = word_no+1;
108 
109  /* To set data_to_be_sent[0 ... (byte-1)] as 0b10101010 */
110  memset(data_to_be_sent, ALL_AA, word_no);
111  /* To set data_to_be_sent[byte_no ... 15] as 0b0000000 */
112  memset(&data_to_be_sent[word_no], ALL_00, (BUFFER_SIZE-word_no));
113  /* Loop to set value for data_to_be_sent[byte_no] */
114  for(i = 0; i < last_seq; i++)
115  {
116  data_to_be_sent[word_no] = 0x80 | data_to_be_sent[word_no] >> 2;
117  }
118 
119  /* Part to decrease wiper value by (maximum - wiper_value_given_by_user) */
120  hal_gpio_pin_set(UD_bar);
121  hal_nop_delay_us(1);
122  hal_gpio_pin_set(CS_bar);
123  hal_gpio_pin_clear(UD_bar);
124  hal_nop_delay_us(1); //T(LCU)
125  hal_gpio_pin_clear(CS_bar);
126  hal_nop_delay_us(2); //T(LCUR)
127  simple_spi_transmit(data_to_be_sent, last_word_no);
128  hal_gpio_pin_set(CS_bar);
129 }
130 
131 
132 static void simple_spi_init()
133 {
134  SPIM_ID->TASKS_SUSPEND = 1;
135  SPIM_ID->TASKS_STOP = 1;
136  SPIM_ID->PSEL.MOSI = UD_bar | (0 << 31);//UD_bar selected as MOSI
137  SPIM_ID->PSEL.SCK = SCK_pin | (0 << 31);
138  SPIM_ID->CONFIG = (SPIM_CONFIG_ORDER_MsbFirst << SPIM_CONFIG_ORDER_Pos)
139  |(SPIM_CONFIG_CPHA_Trailing << SPIM_CONFIG_CPHA_Pos)
140  |(SPIM_CONFIG_CPOL_ActiveHigh << SPIM_CONFIG_CPOL_Pos);
141  //Data line frequency will be 500 kHz
142  SPIM_ID->FREQUENCY = SPIM_FREQUENCY_FREQUENCY_M1 << SPIM_FREQUENCY_FREQUENCY_Pos;
143  SPIM_ID->TXD.LIST = 1 << 0;
144 }
145 
146 static void simple_spi_transmit(uint8_t *data, uint32_t len)
147 {
148  simple_spi_init();
149  SPIM_ID->TXD.PTR = (uint32_t ) data;
150  SPIM_ID->TXD.MAXCNT = len;
151  SPIM_ID->ENABLE = SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos;
152  SPIM_ID->TASKS_START = 0x01;
153  while(!(SPIM_ID->EVENTS_ENDTX));
154  SPIM_ID->EVENTS_ENDTX = 0;
155  SPIM_ID->ENABLE = SPIM_ENABLE_ENABLE_Disabled << SPIM_ENABLE_ENABLE_Pos;
156  SPIM_ID->TASKS_STOP = 0x01;
157 }
#define ASSERT(expression)
Macro for runtime assertion of an expression. If the expression is false the assert_nrf_callback func...
Definition: nrf_assert.h:48
void mcp4012_init(uint32_t CS_bar_pin_no, uint32_t UD_bar_pin_no, uint32_t SCK_pin_no)
This function is used to initialize MCP4012 in our program. This will set wiper value of MCP4012 to z...
Definition: mcp4012_x.c:69
void mcp4012_set_value(uint32_t value_sent_by_user)
This function is used to set the value of MCP4012 wiper value.
Definition: mcp4012_x.c:79