1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2019-07-22     Magicoe      The first version for LPC55S6x
9  */
10 
11 #include <rthw.h>
12 #include <rtdevice.h>
13 #include <rtthread.h>
14 
15 #include "rtconfig.h"
16 #include "drv_mma8562.h"
17 
18 enum _mma8562_i2c_constants
19 {
20     kMMA8562_ADDR = 0x1D,
21     kMMA8562_ADDR_With_SAO_Set = kMMA8562_ADDR | 1
22 };
23 
24 #define MMA8562_I2CBUS_NAME  "i2c4"
25 
26 static struct rt_i2c_bus_device *mma8562_i2c_bus;
27 
28 ////////////////////////////////////////////////////////////////////////////////
29 // Code
30 ////////////////////////////////////////////////////////////////////////////////
31 
32 
mma8562_read_reg(rt_uint8_t reg,rt_uint8_t len,rt_uint8_t * buf)33 rt_err_t mma8562_read_reg(rt_uint8_t reg, rt_uint8_t len, rt_uint8_t *buf)
34 {
35     struct rt_i2c_msg msgs[2];
36 
37     msgs[0].addr  = kMMA8562_ADDR;
38     msgs[0].flags = RT_I2C_WR;
39     msgs[0].buf   = &reg;
40     msgs[0].len   = 1;
41 
42     msgs[1].addr  = kMMA8562_ADDR;
43     msgs[1].flags = RT_I2C_RD;
44     msgs[1].buf   = buf;
45     msgs[1].len   = len;
46 
47     if (rt_i2c_transfer(mma8562_i2c_bus, msgs, 2) == 2)
48     {
49         return RT_EOK;
50     }
51     else
52     {
53         return -RT_ERROR;
54     }
55 }
56 
mma8562_write_reg(rt_uint8_t reg,rt_uint8_t data)57 rt_err_t mma8562_write_reg(rt_uint8_t reg, rt_uint8_t data)
58 {
59     rt_uint8_t buf[2];
60 
61     buf[0] = reg;
62     buf[1] = data;
63 
64     if (rt_i2c_master_send(mma8562_i2c_bus, kMMA8562_ADDR, 0, buf ,2) == 2)
65     {
66         return RT_EOK;
67     }
68     else
69     {
70         return -RT_ERROR;
71     }
72 }
73 
74 #ifdef RT_USING_FINSH
75 #include <finsh.h>
76 #include <rtdevice.h>
77 
get_mma8562(uint8_t data)78 void get_mma8562(uint8_t data)
79 {
80     volatile acceleration_t accel;
81 
82     uint8_t ucVal1 = 0;
83     uint8_t ucVal2 = 0;
84     uint8_t ucStatus = 0;
85 
86     do {
87        mma8562_read_reg(kMMA8562_STATUS, 1, &ucStatus);
88     } while (!(ucStatus & 0x08));
89 
90     mma8562_read_reg(kMMA8562_OUT_X_MSB, 1, &ucVal1);
91     mma8562_read_reg(kMMA8562_OUT_X_LSB, 1, &ucVal2);
92 
93     accel.x = ucVal1*256 +ucVal2;
94 
95     mma8562_read_reg(kMMA8562_OUT_Y_MSB, 1, &ucVal1);
96     mma8562_read_reg(kMMA8562_OUT_Y_LSB, 1, &ucVal2);
97     accel.y = ucVal1*256 +ucVal2;
98 
99     mma8562_read_reg(kMMA8562_OUT_Z_MSB, 1, &ucVal1);
100     mma8562_read_reg(kMMA8562_OUT_Z_LSB, 1, &ucVal2);
101     accel.z = ucVal1*256 +ucVal2;
102 
103     rt_kprintf("*** MMA8562 X %d, Y %d, Z %d\r\n", (accel.x), (accel.y), (accel.z) );
104 }
105 MSH_CMD_EXPORT(get_mma8562, get mma8562. e.g: get_mma8562(0))
106 #endif
107 
mma8562_hw_init(void)108 int mma8562_hw_init(void)
109 {
110     // Init the I2C port.
111     // Should be init in startup
112     uint8_t val = 0;
113 
114     mma8562_i2c_bus = rt_i2c_bus_device_find(MMA8562_I2CBUS_NAME);  /*  */
115 
116     // Read WHO_AM_I register.
117     mma8562_read_reg(kMMA8562_WHO_AM_I, 1, &val);
118     if (val != kMMA8562_WHO_AM_I_Device_ID)
119     {
120         rt_kprintf("MMA8562: Unexpected result from WHO_AM_I (0x%02x)\n", val);
121         return -RT_ERROR;
122     }
123 
124     /*  please refer to the "example FXOS8700CQ Driver Code" in FXOS8700 datasheet. */
125     /*  write 0000 0000 = 0x00 to accelerometer control register 1 */
126     /*  standby */
127     /*  [7-1] = 0000 000 */
128     /*  [0]: active=0 */
129     val = 0;
130     mma8562_write_reg( kMMA8562_CTRL_REG1, val);
131 
132     /*  write 0000 0001= 0x01 to XYZ_DATA_CFG register */
133     /*  [7]: reserved */
134     /*  [6]: reserved */
135     /*  [5]: reserved */
136     /*  [4]: hpf_out=0 */
137     /*  [3]: reserved */
138     /*  [2]: reserved */
139     /*  [1-0]: fs=01 for accelerometer range of +/-4g range with 0.488mg/LSB */
140     /*  databyte = 0x01; */
141     val = 0x01;
142     mma8562_write_reg(kMMA8562_XYZ_DATA_CFG, val);
143 
144     /*  write 0000 1101 = 0x0D to accelerometer control register 1 */
145     /*  [7-6]: aslp_rate=00 */
146     /*  [5-3]: dr=001 for 200Hz data rate (when in hybrid mode) */
147     /*  [2]: lnoise=1 for low noise mode */
148     /*  [1]: f_read=0 for normal 16 bit reads */
149     /*  [0]: active=1 to take the part out of standby and enable sampling */
150     /*   databyte = 0x0D; */
151     val = 0x0D;
152     mma8562_write_reg(kMMA8562_CTRL_REG1, val);
153 
154     return 0;
155 }
156 
157 INIT_DEVICE_EXPORT(mma8562_hw_init);
158 
159 
160 ////////////////////////////////////////////////////////////////////////////////
161 // EOF
162 ////////////////////////////////////////////////////////////////////////////////
163