main.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
#include <hardware/structs/io_bank0.h>
#include <pico/time.h>
#include <stdint.h>
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/spi.h"
#define SPI_PORT spi1
#define MOSI 11
#define MISO 8
#define CS 9
#define CLK 10
#define READ_BIT 0x80
#define WRITE_BIT 0x00
#define MB_BIT 0x40
#define DATAX0 0x32
#define POWERCTL 0x2D
#define MEASURE_BIT 0x08
#define DATA_FORMAT 0x30
#define ADXL345_RANGE_PM_2G 0x00
#define ADXL345_RANGE_PM_4G 0x01
#define ADXL345_RANGE_PM_8G 0x02
#define ADXL345_RANGE_PM_16G 0x03
#define ADXL345_LEFT_JUSTIFY 0x04
#define ADXL345_SCALE_FACTOR 0.0039
struct Config {
uint scale;
bool full_resolution;
};
static inline void cs_select() {
asm volatile("nop \n nop \n nop");
gpio_put(CS, 0); // Active low
asm volatile("nop \n nop \n nop");
}
static inline void cs_deselect() {
asm volatile("nop \n nop \n nop");
gpio_put(CS, 1);
asm volatile("nop \n nop \n nop");
}
void read_registers(uint8_t reg_address, uint8_t *buf, uint16_t len) {
reg_address = READ_BIT | reg_address;
cs_select();
spi_write_blocking(SPI_PORT, ®_address, 1);
spi_read_blocking(SPI_PORT, 0, buf, len);
cs_deselect();
}
void write_register(uint8_t reg_address, uint8_t byte) {
uint8_t buf[2] = {WRITE_BIT | reg_address,byte};
cs_select();
spi_write_blocking(SPI_PORT, buf, 2);
cs_deselect();
}
void read_acceleration(uint16_t accel[3]) {
uint8_t reg_address = MB_BIT | DATAX0;
uint8_t buffer[6];
read_registers(reg_address, buffer, 6);
for (int i = 0; i < 3; i++) {
accel[i] = (uint16_t)(buffer[(i * 2) + 1] << 8) + buffer[i * 2];
}
}
void acceleration_in_g(uint16_t accel[3], float accel_unit_g[3], struct Config conf) {
uint bit_mask = 0x3FF;
uint msb = 0x200;
if (conf.full_resolution == true) {
switch (conf.scale) {
case 16:
bit_mask += 0x1C00;
msb <<= 3;
case 8:
bit_mask += 0xC00;
msb <<= 2;
case 4:
bit_mask += 0x400;
msb <<= 1;
}
}
for (int i = 0; i < 3; i++) {
if ( (accel[i] & msb) != 0 ) {
accel_unit_g[i] = (float)( (accel[i] ^ 0xffff) + 1 ) * ADXL345_SCALE_FACTOR;
accel_unit_g[i] *= -1;
} else {
accel_unit_g[i] = (float)( accel[i] ) * ADXL345_SCALE_FACTOR;
}
}
}
int main() {
stdio_init_all();
spi_init(SPI_PORT, 2000*1000);
spi_set_format(SPI_PORT, 8, SPI_CPOL_1, SPI_CPHA_1, SPI_MSB_FIRST);
gpio_set_function(MOSI, GPIO_FUNC_SPI);
gpio_set_function(MISO, GPIO_FUNC_SPI);
gpio_set_function(CLK, GPIO_FUNC_SPI);
gpio_init(CS);
gpio_set_dir(CS, GPIO_OUT);
gpio_put(CS, 1);
uint16_t accel[3] = {0x67, 0x67, 0x67};
float float_accel[3];
uint8_t id;
read_registers(0x00, &id, 1);
write_register(POWERCTL, MEASURE_BIT);
struct Config config = {.scale = 16, .full_resolution = false};
write_register(DATA_FORMAT, ADXL345_RANGE_PM_16G);
while (true) {
read_acceleration(accel);
acceleration_in_g(accel, float_accel, config);
printf("%f %f %f\n", float_accel[0],float_accel[1],float_accel[2]);
//printf("%x %x %x\n\n", accel[0],accel[1],accel[2]);
sleep_ms(100);
}
}
|