EFR32 Mighty Gecko 13 Software Documentation  efr32mg13-doc-5.1.2
cpt112s_i2c.c
Go to the documentation of this file.
1 /**************************************************************************/
16 #include "cpt112s_i2c.h"
17 #include "cpt112s_config.h"
18 #include "em_chip.h"
19 #include "em_cmu.h"
20 #include "em_i2c.h"
21 #include "em_gpio.h"
22 #include "em_device.h"
23 #include <stdbool.h>
24 #include <stdint.h>
25 #include <stdio.h>
26 
27 /******************************************************************************
28  * @brief
29  * I2C data structure
30  * For CPT112S there are 12 capsense outputs, each pin
31  * corresponds to a capsenseCurrent bit showing whether a
32  * cap-sense button pressed or not, and capsensePrevious
33  * bit showing the status of previous cycle.
34  *
35  * If capsenseCurrent==1 && capsensePrevious==0, detects a "press"
36  * If capsenseCurrent==0 && capsensePrevious==1, detects a "release"
37  *
38  * capsenseCurrent bit-map byte:
39  * | N/A | N/A | N/A | N/A| cC11 | cC10| cC9 | cC8 |
40  * | cC7 | cC6 | cC5 | cC4 | cC3 | cC2 | cC1 | cC0 |
41  *
42  * capsensePrevious bit-map byte:
43  * | N/A | N/A | N/A | N/A| cP11 | cP10| cP9 | cP8 |
44  * | cP7 | cP6 | cP5 | cP4 | cP3 | cP2 | cP1 | cP0 |
45  *
46  * *cC,cP are abbreviation for capsenseCurrent and capsensePrevious
47  *
48  *****************************************************************************/
49 
50 /*******************************************************************************
51  ***************************** LOCAL VARIABLES *********************************
52  ******************************************************************************/
53 
54 // GPIO data structure declaration
55 static uint16_t capsenseCurrent, sliderCurrent;
56 static uint16_t capsensePrevious, sliderPrevious;
57 
58 // Buffers
59 static uint8_t i2c_rxBuffer[CPT112S_I2C_RXBUFFER_SIZE];
60 
61 // Transmission flags
62 static volatile bool i2c_rxInProgress;
63 static volatile bool i2c_startTx;
64 
65 /*******************************************************************************
66  ******************************* PROTOTYPES ***********************************
67  ******************************************************************************/
68 
69 static void setupOscillators(void);
70 static void setupI2C(void);
71 static void performI2CTransfer(void);
72 static void parseI2C(void);
73 
74 /*******************************************************************************
75  ****************************** FUNCTIONS ***********************************
76  ******************************************************************************/
77 
78 /******************************************************************************
79  * @brief Return a bitmask containing the current state for all capsense
80  * buttons
81  *****************************************************************************/
82 uint16_t CPT112S_getCapsenseCurrent(void)
83 {
84  return capsenseCurrent;
85 }
86 
87 /******************************************************************************
88  * @brief Return a bitmask containing the previous state for all capsense
89  * buttons
90  *****************************************************************************/
91 uint16_t CPT112S_getCapsensePrevious(void)
92 {
93  return capsensePrevious;
94 }
95 
96 /******************************************************************************
97  * @brief Return the current slider value
98  *****************************************************************************/
99 uint16_t CPT112S_getSliderCurrent(void)
100 {
101  return sliderCurrent;
102 }
103 
104 /******************************************************************************
105  * @brief Return the previous slider value
106  *****************************************************************************/
107 uint16_t CPT112S_getSliderPrevious(void)
108 {
109  return sliderPrevious;
110 }
111 
112 /******************************************************************************
113  * @brief GPIO data structure initialization
114  *****************************************************************************/
115 void CPT112S_init(void)
116 {
118  setupI2C();
119 
120  capsenseCurrent = 0;
121  capsensePrevious = 0;
122  sliderCurrent = 0xFFFF;
123  sliderPrevious = 0xFFFF;
124 }
125 
126 /******************************************************************************
127  * @brief parse i2c packet received from slave, update i2c data structure
128  *****************************************************************************/
129 void CPT112S_update(void)
130 {
131  // get previous states of Cap-sense button array
132  capsensePrevious = capsenseCurrent;
133  sliderPrevious = sliderCurrent;
134 
135  while (!GPIO_PinInGet(CS0_I2C_INT_PORT, CS0_I2C_INT_PIN))
136  {
137  // update current button states
138  parseI2C();
139  }
140 }
141 
142 /*******************************************************************************
143  ***************************** LOCAL FUNCTIONS *********************************
144  ******************************************************************************/
145 
146 void parseI2C()
147 {
149 
150  if((i2c_rxBuffer[0] & 0x0F) == CPT112S_I2C_TOUCH_EVENT)
151  {
152  sliderCurrent = 0xFFFF;
153  capsenseCurrent |= 1 << i2c_rxBuffer[1];
154  }
155  else if((i2c_rxBuffer[0] & 0x0F) == CPT112S_I2C_RELEASE_EVENT)
156  {
157  sliderCurrent = 0xFFFF;
158  capsenseCurrent &= ~(1 << i2c_rxBuffer[1]);
159  }
160  else if((i2c_rxBuffer[0] & 0x0F) == CPT112S_I2C_SLIDER_ACTIVITY)
161  {
162  sliderCurrent = (i2c_rxBuffer[1] << 8) | (i2c_rxBuffer[2]);
163  }
164 }
165 
166 /**************************************************************************/
170 {
171  /* Enabling clock to the I2C, GPIO, LE */
174 
175  /* Starting LFXO and waiting until it is stable */
176  CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);
177 
178  /* Routing the LFXO clock to the RTC */
180 }
181 
182 /**************************************************************************/
185 void setupI2C(void)
186 {
187 #ifdef I2C_INIT_FAST_MODE
188  // Using default settings
189  I2C_Init_TypeDef i2cInit = I2C_INIT_FAST_MODE;
190  #else
191  // Using default settings
193 #endif
194 
195 #ifdef CS0_SENSOR_EN_PORT
196  /* Enable sensor isolation switch for external pull-up resistors */
197  GPIO_PinModeSet(CS0_SENSOR_EN_PORT, CS0_SENSOR_EN_PIN, gpioModePushPull, 1);
198 #endif
199 
200  /* Configure SDA/SCL */
201  GPIO_PinModeSet(CS0_I2C_SDA_PORT, CS0_I2C_SDA_PIN, gpioModeWiredAndPullUpFilter, 1);
202  GPIO_PinModeSet(CS0_I2C_SCL_PORT, CS0_I2C_SCL_PIN, gpioModeWiredAndPullUpFilter, 1);
203 
204  // Configure interrupt pin
205  GPIO_PinModeSet(CS0_I2C_INT_PORT, CS0_I2C_INT_PIN, gpioModeInput, 0);
206 
207 #ifdef CS0_I2C_SDA_LOC
208  /* Enable pins */
210  I2C0->ROUTELOC0 = (CS0_I2C_SDA_LOC << _I2C_ROUTELOC0_SDALOC_SHIFT) |
211  (CS0_I2C_SCL_LOC << _I2C_ROUTELOC0_SCLLOC_SHIFT);
212 #else
213  /* Enable pins at location */
214  I2C0->ROUTE = I2C_ROUTE_SDAPEN |
215  I2C_ROUTE_SCLPEN |
216  (CS0_I2C_LOC << _I2C_ROUTE_LOCATION_SHIFT);
217 #endif
218 
219  /* Initializing the I2C */
220  I2C_Init(I2C0, &i2cInit);
221 
222  /* Setting the status flags and index */
223  i2c_rxInProgress = false;
224  i2c_startTx = false;
225 
227 }
228 
229 /**************************************************************************/
233 {
234  /* Transfer structure */
235  I2C_TransferSeq_TypeDef i2cTransfer;
236 
237  /* Initializing I2C transfer */
238  i2cTransfer.addr = CPT112S_I2C_ADDRESS;
239  i2cTransfer.flags = I2C_FLAG_READ;
240  i2cTransfer.buf[0].data = i2c_rxBuffer;
241  i2cTransfer.buf[0].len = CPT112S_I2C_RXBUFFER_SIZE;
242  I2C_TransferInit(I2C0, &i2cTransfer);
243 
244  /* Sending data */
246 }
#define I2C_CTRL_AUTOSN
Clock management unit (CMU) API.
void CMU_ClockSelectSet(CMU_Clock_TypeDef clock, CMU_Select_TypeDef ref)
Select reference clock/oscillator used for a clock branch.
Definition: em_cmu.c:2521
#define I2C_FLAG_READ
Indicate plain read sequence: S+ADDR(R)+DATA0+P.
Definition: em_i2c.h:135
Chip Initialization API.
I2C_TransferReturn_TypeDef I2C_TransferInit(I2C_TypeDef *i2c, I2C_TransferSeq_TypeDef *seq)
Prepare and start an I2C transfer (single master mode only).
Definition: em_i2c.c:807
#define I2C_CTRL_AUTOACK
CMSIS Cortex-M Peripheral Access Layer for Silicon Laboratories microcontroller devices.
#define I2C_ROUTEPEN_SDAPEN
#define I2C_ROUTEPEN_SCLPEN
#define I2C0
void GPIO_PinModeSet(GPIO_Port_TypeDef port, unsigned int pin, GPIO_Mode_TypeDef mode, unsigned int out)
Set the mode for a GPIO pin.
Definition: em_gpio.c:269
Driver for retrieving capsense button and slider inputs from CPT112S.
void I2C_Init(I2C_TypeDef *i2c, const I2C_Init_TypeDef *init)
Initialize I2C.
Definition: em_i2c.c:353
#define I2C_INIT_DEFAULT
Definition: em_i2c.h:227
General Purpose IO (GPIO) peripheral API.
struct I2C_TransferSeq_TypeDef::@0 buf[2]
void CMU_ClockEnable(CMU_Clock_TypeDef clock, bool enable)
Enable/disable a clock.
Definition: em_cmu.c:1453
#define _I2C_ROUTELOC0_SDALOC_SHIFT
Master mode transfer message structure used to define a complete I2C transfer sequence (from start to...
Definition: em_i2c.h:252
void CMU_OscillatorEnable(CMU_Osc_TypeDef osc, bool enable, bool wait)
Enable/disable oscillator.
Definition: em_cmu.c:3594
#define _I2C_ROUTELOC0_SCLLOC_SHIFT
static void setupOscillators(void)
Starting oscillators and enabling clocks.
Definition: cpt112s_i2c.c:169
Inter-intergrated circuit (I2C) peripheral API.
static void performI2CTransfer(void)
Transmitting I2C data. Will busy-wait until the transfer is complete.
Definition: cpt112s_i2c.c:232
__STATIC_INLINE unsigned int GPIO_PinInGet(GPIO_Port_TypeDef port, unsigned int pin)
Read the pad value for a single pin in a GPIO port.
Definition: em_gpio.h:781
uint16_t addr
Address to use after (repeated) start.
Definition: em_i2c.h:262
static void setupI2C(void)
Setup I2C.
Definition: cpt112s_i2c.c:185
I2C_TransferReturn_TypeDef I2C_Transfer(I2C_TypeDef *i2c)
Continue an initiated I2C transfer (single master mode only).
Definition: em_i2c.c:428