Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
Loading...
Searching...
No Matches
ak8963.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2014 Freek van Tienen <freek.v.tienen@gmail.com>
3 *
4 * This file is part of paparazzi.
5 *
6 * paparazzi is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * paparazzi is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with paparazzi; see the file COPYING. If not, write to
18 * the Free Software Foundation, 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 */
21
28#include "peripherals/ak8963.h"
29#include "std.h"
30
34void ak8963_init(struct Ak8963 *ak, struct i2c_periph *i2c_p, uint8_t addr)
35{
36 /* set i2c_peripheral */
37 ak->i2c_p = i2c_p;
38 /* set i2c address */
39 ak->i2c_trans.slave_addr = addr;
40 ak->data_available = false;
41 ak->initialized = false;
44}
45
46void ak8963_configure(struct Ak8963 *ak)
47{
48 // Only configure when not busy
50 && ak->i2c_trans.status != I2CTransDone) {
51 return;
52 }
53
54 // Only when succesfully continue with next
55 if (ak->i2c_trans.status == I2CTransSuccess) {
56 ak->init_status++;
57 }
58
60 switch (ak->init_status) {
61
62 // Soft Reset the device
63 case AK_CONF_UNINIT:
65 ak->i2c_trans.buf[1] = 1;
66 i2c_transmit(ak->i2c_p, &(ak->i2c_trans), ak->i2c_trans.slave_addr, 2);
67 break;
68
69 // Set it to continious measuring mode 2
70 case AK_CONF_MODE:
73 i2c_transmit(ak->i2c_p, &(ak->i2c_trans), ak->i2c_trans.slave_addr, 2);
74 break;
75
76 // Initialization done
77 default:
78 ak->initialized = true;
79 break;
80 }
81}
82
83void ak8963_read(struct Ak8963 *ak)
84{
85 if (ak->status != AK_STATUS_IDLE) {
86 return;
87 }
88
89 // Read the status register
91 i2c_transceive(ak->i2c_p, &(ak->i2c_trans), ak->i2c_trans.slave_addr, 1, 1);
92}
93
94#define Int16FromBuf(_buf,_idx) ((int16_t)(_buf[_idx] | (_buf[_idx+1] << 8)))
95void ak8963_event(struct Ak8963 *ak)
96{
97 if (!ak->initialized) {
98 return;
99 }
100
101 switch (ak->status) {
102 case AK_STATUS_IDLE:
103 // When DRDY start reading
104 if (ak->i2c_trans.status == I2CTransSuccess && ak->i2c_trans.buf[0] & 1) {
106 i2c_transceive(ak->i2c_p, &(ak->i2c_trans), ak->i2c_trans.slave_addr, 1, 6);
107 ak->status++;
108 }
109 break;
110
111 case AK_STATUS_READ:
112 if (ak->i2c_trans.status == I2CTransSuccess) {
113 // Copy the data
114 ak->data.vect.x = Int16FromBuf(ak->i2c_trans.buf, 0);
115 ak->data.vect.y = Int16FromBuf(ak->i2c_trans.buf, 2);
116 ak->data.vect.z = Int16FromBuf(ak->i2c_trans.buf, 4);
117
118 // Read second status register to be ready for reading again
119 ak->i2c_trans.buf[0] = AK8963_REG_ST2; // Data overflow bit 3 and data read error status bit 2
120 i2c_transceive(ak->i2c_p, &(ak->i2c_trans), ak->i2c_trans.slave_addr, 1, 1);
121 ak->status++;
122 break;
123 }
124
125 break;
126
127 default:
129 // Goto idle
132 // check overrun
133 if ((bit_is_set(ak->i2c_trans.buf[0], 3)) || (bit_is_set(ak->i2c_trans.buf[0], 2))) {
134 //if (bit_is_set(ak->i2c_trans.buf[0], 3)) {
135 ak->data_available = false;
136 } else {
137 ak->data_available = true;
139 }
140 }
141 break;
142 }
143}
144
void ak8963_event(struct Ak8963 *ak)
Definition ak8963.c:95
void ak8963_configure(struct Ak8963 *ak)
Definition ak8963.c:46
void ak8963_init(struct Ak8963 *ak, struct i2c_periph *i2c_p, uint8_t addr)
Initialize AK8963 struct.
Definition ak8963.c:34
void ak8963_read(struct Ak8963 *ak)
Definition ak8963.c:83
#define Int16FromBuf(_buf, _idx)
Definition ak8963.c:94
Register and address definitions for AK8963 magnetometer.
enum Ak8963Status status
main status
Definition ak8963.h:58
@ AK_STATUS_IDLE
Definition ak8963.h:47
@ AK_STATUS_READ
Definition ak8963.h:48
struct i2c_transaction i2c_trans
i2c transaction used for communication with the ak8936
Definition ak8963.h:55
enum Ak8963ConfStatus init_status
init status
Definition ak8963.h:59
bool initialized
config done flag
Definition ak8963.h:56
volatile bool data_available
data ready flag
Definition ak8963.h:61
union Ak8963::@310 data
struct i2c_periph * i2c_p
peripheral used for communcation
Definition ak8963.h:54
@ AK_CONF_MODE
Definition ak8963.h:41
@ AK_CONF_UNINIT
Definition ak8963.h:40
Default Ak8963 structure.
Definition ak8963.h:53
#define AK8963_REG_HXL
Definition ak8963_regs.h:46
#define AK8963_CNTL1_CM_2
Definition ak8963_regs.h:37
#define AK8963_REG_CNTL2
Definition ak8963_regs.h:54
#define AK8963_REG_CNTL1
Definition ak8963_regs.h:53
#define AK8963_REG_ST1
Definition ak8963_regs.h:45
#define AK8963_REG_ST2
Definition ak8963_regs.h:52
volatile uint8_t buf[I2C_BUF_LEN]
Transaction buffer With I2C_BUF_LEN number of bytes.
Definition i2c.h:122
enum I2CTransactionStatus status
Transaction status.
Definition i2c.h:126
uint8_t slave_addr
Slave address.
Definition i2c.h:104
bool i2c_transmit(struct i2c_periph *p, struct i2c_transaction *t, uint8_t s_addr, uint8_t len)
Submit a write only transaction.
Definition i2c.c:324
bool i2c_transceive(struct i2c_periph *p, struct i2c_transaction *t, uint8_t s_addr, uint8_t len_w, uint16_t len_r)
Submit a write/read transaction.
Definition i2c.c:344
@ I2CTransSuccess
transaction successfully finished by I2C driver
Definition i2c.h:57
@ I2CTransFailed
transaction failed
Definition i2c.h:58
@ I2CTransDone
transaction set to done by user level
Definition i2c.h:59
uint16_t foo
Definition main_demo5.c:58
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.