initial WIP
lots of code copied over, things filled in to hopefully get the LED matrix lighting up. untested.
This commit is contained in:
168
firmware/app/driver/accel.c
Normal file
168
firmware/app/driver/accel.c
Normal file
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* accel.c
|
||||
*
|
||||
* Created on: Oct 13, 2024
|
||||
* Author: true
|
||||
*/
|
||||
|
||||
#include "ch32x035_conf.h"
|
||||
|
||||
#include "accel.h"
|
||||
#include "lis2hh12_reg.h"
|
||||
|
||||
#include "comms/spi_master.h"
|
||||
|
||||
#include "misc/i8atan2.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
|
||||
// user data
|
||||
AccelData accel;
|
||||
|
||||
uint8_t accel_found = 0;
|
||||
|
||||
uint8_t movement_idx; // index into "read" register
|
||||
int16_t movement_read[4]; // last read movement value
|
||||
int16_t movement; // last calculated movement value
|
||||
uint16_t movement_worst; // worst seen movement value
|
||||
|
||||
|
||||
// hardware
|
||||
static stmdev_ctx_t dev_ctx;
|
||||
|
||||
|
||||
|
||||
static int32_t accel_write(void *handle, uint8_t reg, const uint8_t *bufp, uint16_t len)
|
||||
{
|
||||
(void)(handle);
|
||||
|
||||
// i2c_write_reg8(LIS2_I2C_ADDR_SDO_LOW, reg, bufp, len);
|
||||
LIS2_CS_PORT->BCR = LIS2_CS_PIN;
|
||||
spim_write_reg8(reg, bufp, len);
|
||||
LIS2_CS_PORT->BSHR = LIS2_CS_PIN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t accel_read(void *handle, uint8_t reg, uint8_t *bufp, uint16_t len)
|
||||
{
|
||||
(void)(handle);
|
||||
|
||||
// i2c_read_reg8(LIS2DW_I2C_ADDR_SDO_LOW, reg, bufp, len);
|
||||
LIS2_CS_PORT->BCR = LIS2_CS_PIN;
|
||||
spim_read_reg8(reg, bufp, len);
|
||||
LIS2_CS_PORT->BSHR = LIS2_CS_PIN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void accel_init()
|
||||
{
|
||||
uint8_t devid;
|
||||
uint8_t reset;
|
||||
uint16_t timeout = 1000;
|
||||
|
||||
dev_ctx.write_reg = accel_write;
|
||||
dev_ctx.read_reg = accel_read;
|
||||
|
||||
// make sure we've got the right device
|
||||
lis2hh12_dev_id_get(&dev_ctx, &devid);
|
||||
if (devid == LIS2HH12_ID) {
|
||||
accel_found = 1;
|
||||
}
|
||||
|
||||
// reset accelerometer
|
||||
if (accel_found) {
|
||||
lis2hh12_dev_reset_set(&dev_ctx, PROPERTY_ENABLE);
|
||||
do {
|
||||
lis2hh12_dev_reset_get(&dev_ctx, &reset);
|
||||
if (!reset) {
|
||||
timeout = 0;
|
||||
accel_found = 1;
|
||||
}
|
||||
} while (timeout--);
|
||||
}
|
||||
|
||||
if (accel_found) {
|
||||
// disable block update
|
||||
// data in output registers is updated immediately; FIFO is disabled
|
||||
lis2hh12_block_data_update_set(&dev_ctx, PROPERTY_DISABLE);
|
||||
|
||||
// configure scale, power mode
|
||||
lis2hh12_xl_full_scale_set(&dev_ctx, LIS2HH12_2g);
|
||||
// TODO: check this
|
||||
// lis2hh12_power_mode_set(&dev_ctx, LIS2DW12_CONT_LOW_PWR_LOW_NOISE_4);
|
||||
|
||||
// configure filter chain
|
||||
// low pass filter enabled for 6D (not currently used)
|
||||
lis2hh12_xl_filter_out_path_set(&dev_ctx, LIS2HH12_FILT_LP);
|
||||
// digital LPF2 filter of output data
|
||||
lis2hh12_xl_filter_low_bandwidth_set(&dev_ctx, LIS2HH12_LP_ODR_DIV_9);
|
||||
|
||||
// configure output data rate
|
||||
lis2hh12_xl_data_rate_set(&dev_ctx, LIS2HH12_XL_ODR_200Hz);
|
||||
}
|
||||
}
|
||||
|
||||
void accel_poll()
|
||||
{
|
||||
uint8_t reg = 1;
|
||||
int16_t xyz[3];
|
||||
|
||||
if (!accel_found) return;
|
||||
|
||||
while (reg) {
|
||||
// read output only if new value is available
|
||||
lis2hh12_xl_flag_data_ready_get(&dev_ctx, ®);
|
||||
|
||||
if (reg) {
|
||||
// read acceleration data
|
||||
memset(xyz, 0x00, 3 * sizeof(int16_t));
|
||||
lis2hh12_acceleration_raw_get(&dev_ctx, xyz);
|
||||
|
||||
accel.x = xyz[0] >>= 8;
|
||||
accel.y = xyz[1] >>= 8;
|
||||
accel.z = xyz[2] >>= 8;
|
||||
|
||||
// compute our shitty "movement" thing
|
||||
// awful way to detect being still
|
||||
reg = sizeof(movement_read) / sizeof(movement_read[0]);
|
||||
|
||||
movement_idx++;
|
||||
if (movement_idx == reg) {
|
||||
movement_idx = 0;
|
||||
movement = abs(movement_read[3] - movement_read[0]);
|
||||
if (movement > movement_worst) {
|
||||
movement_worst = movement;
|
||||
}
|
||||
}
|
||||
|
||||
movement_read[movement_idx] = abs(accel.x) + abs(accel.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int8_t accel_get_rotation(struct AccelData *a)
|
||||
{
|
||||
int8_t nx, ny, ret;
|
||||
|
||||
nx = -a->x;
|
||||
ny = a->y;
|
||||
|
||||
ret = i8atan2(nx, ny) >> 1;
|
||||
if (ret < 0) {
|
||||
ret += 128;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int16_t accel_get_movement()
|
||||
{
|
||||
return movement;
|
||||
}
|
||||
48
firmware/app/driver/accel.h
Normal file
48
firmware/app/driver/accel.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* accel.h
|
||||
*
|
||||
* Created on: Oct 13, 2024
|
||||
* Author: true
|
||||
*/
|
||||
|
||||
#ifndef USER_MISC_ACCEL_H_
|
||||
#define USER_MISC_ACCEL_H_
|
||||
|
||||
|
||||
#include "ch32x035_conf.h"
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
|
||||
#define LIS2_CS_PORT GPIOB // CH32X035-specific
|
||||
#define LIS2_CS_PIN GPIO_Pin_6
|
||||
|
||||
#define LIS2_I2C_ADDR 0x30
|
||||
#define LIS2_I2C_ADDR_SDO_LOW 0x32
|
||||
|
||||
|
||||
|
||||
typedef struct AccelData {
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
int16_t z;
|
||||
} AccelData;
|
||||
|
||||
|
||||
|
||||
extern AccelData accel;
|
||||
extern uint8_t accel_found;
|
||||
|
||||
extern uint16_t movement_worst;
|
||||
|
||||
|
||||
|
||||
void accel_init();
|
||||
void accel_poll();
|
||||
|
||||
int8_t accel_get_rotation(struct AccelData *a);
|
||||
int16_t accel_get_movement();
|
||||
|
||||
|
||||
|
||||
#endif /* USER_MISC_ACCEL_H_ */
|
||||
186
firmware/app/driver/adc.c
Normal file
186
firmware/app/driver/adc.c
Normal file
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* adc.c
|
||||
*
|
||||
* todo:
|
||||
* - use DMA
|
||||
*/
|
||||
|
||||
#include "ch32x035_conf.h"
|
||||
|
||||
|
||||
#define ADC_CHANNELS 8
|
||||
|
||||
#define CHAN_ENABLED 0x80
|
||||
|
||||
#define CHAN_MASK 0x7f
|
||||
#define CHAN_IS_NORMAL 0
|
||||
#define CHAN_IS_TOUCH 1
|
||||
#define CHAN_IS_LIGHTSENSE 2
|
||||
|
||||
#define TOUCH_DEFAULT_CHARGE 0x88
|
||||
#define TOUCH_DEFAULT_THRESH 0x800
|
||||
|
||||
|
||||
typedef struct AdcChan {
|
||||
uint8_t chan; // ADC channel number
|
||||
uint8_t type; // ADC channel type (use above defines)
|
||||
uint8_t timing; // sample rate for normal channels, charge values for touch-type channels
|
||||
uint8_t idx; // rawval index
|
||||
uint16_t avg; // averaged output
|
||||
uint16_t thresh; // touch threshold
|
||||
uint16_t rawval[8]; // raw counts
|
||||
} AdcChan;
|
||||
|
||||
|
||||
static uint8_t adc_idx = 0;
|
||||
static AdcChan adc_chan[ADC_CHANNELS] = {0};
|
||||
|
||||
|
||||
|
||||
void adc_init()
|
||||
{
|
||||
ADC_InitTypeDef adc = {0};
|
||||
|
||||
// configure pin struct
|
||||
for (uint8_t i = 0; i < ADC_CHANNELS; i++) {
|
||||
adc_chan[i].type = CHAN_ENABLED | CHAN_IS_TOUCH;
|
||||
adc_chan[i].timing = TOUCH_DEFAULT_CHARGE;
|
||||
adc_chan[i].thresh = TOUCH_DEFAULT_THRESH;
|
||||
}
|
||||
|
||||
adc_chan[0].chan = ADC_Channel_0;
|
||||
adc_chan[1].chan = ADC_Channel_1;
|
||||
adc_chan[2].chan = ADC_Channel_2;
|
||||
adc_chan[3].chan = ADC_Channel_3;
|
||||
adc_chan[4].chan = ADC_Channel_4;
|
||||
adc_chan[5].chan = ADC_Channel_8;
|
||||
adc_chan[6].chan = ADC_Channel_13;
|
||||
|
||||
adc_chan[7].chan = ADC_Channel_9;
|
||||
adc_chan[7].type = CHAN_IS_LIGHTSENSE;
|
||||
adc_chan[7].timing = ADC_SampleTime_7Cycles;
|
||||
|
||||
|
||||
// configure actual peripheral
|
||||
ADC_DeInit(ADC1);
|
||||
|
||||
ADC_CLKConfig(ADC1, ADC_CLK_Div6);
|
||||
|
||||
adc.ADC_Mode = ADC_Mode_Independent;
|
||||
adc.ADC_ScanConvMode = DISABLE;
|
||||
adc.ADC_ContinuousConvMode = DISABLE;
|
||||
adc.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
|
||||
adc.ADC_DataAlign = ADC_DataAlign_Right;
|
||||
adc.ADC_NbrOfChannel = 1;
|
||||
ADC_Init(ADC1, &adc);
|
||||
|
||||
ADC_Cmd(ADC1, ENABLE);
|
||||
}
|
||||
|
||||
int8_t adc_get_tkey(uint8_t key_idx)
|
||||
{
|
||||
if (key_idx > ADC_CHANNELS)
|
||||
return 0;
|
||||
|
||||
if (adc_chan[key_idx].avg < adc_chan[key_idx].thresh) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void adc_next()
|
||||
{
|
||||
AdcChan *chan;
|
||||
uint8_t timeout = 0;
|
||||
|
||||
// todo:
|
||||
// lightsense is timing-sensitive. will need to have this as an overridden channel?
|
||||
|
||||
// get next index
|
||||
adc_idx++;
|
||||
if (adc_idx > (sizeof(adc_chan) / sizeof(adc_chan[0]))) {
|
||||
adc_idx = 0;
|
||||
}
|
||||
|
||||
// so long as the channel is enabled
|
||||
while (!(adc_chan[adc_idx].type & CHAN_ENABLED) && (timeout++ < ADC_CHANNELS)) {
|
||||
adc_idx++;
|
||||
}
|
||||
|
||||
// if nothing is enabled, break out
|
||||
if (timeout == ADC_CHANNELS)
|
||||
return;
|
||||
|
||||
chan = &adc_chan[adc_idx];
|
||||
|
||||
// configure sampling
|
||||
switch (chan->type) {
|
||||
case CHAN_IS_NORMAL: {
|
||||
TKey1->CTLR1 &= ~ADC_TKENABLE; // disable TouchKey
|
||||
|
||||
// we don't have any
|
||||
break;
|
||||
}
|
||||
case CHAN_IS_TOUCH: {
|
||||
TKey1->CTLR1 |= ADC_TKENABLE; // enable TouchKey
|
||||
|
||||
ADC_RegularChannelConfig(ADC1, chan->chan, 1, ADC_SampleTime_11Cycles);
|
||||
TKey1->IDATAR1 = chan->timing & 0xf0; // R32_TKEY1_CHGOFFSET Charging Time
|
||||
TKey1->RDATAR = chan->timing & 0x0f; // R32_TKEY1_ACT_DCG Discharging Time
|
||||
// per the RM, setting RDATAR (ACT_DCG) starts the conversion
|
||||
|
||||
break;
|
||||
}
|
||||
case CHAN_IS_LIGHTSENSE: {
|
||||
TKey1->CTLR1 &= ~ADC_TKENABLE; // disable TouchKey
|
||||
|
||||
// todo: use thresh as a "timeout" value maybe?
|
||||
// this way the other channels can be sampled, and each time we pass by
|
||||
// the lightsensor, if it isn't time to sample it, it is skipped.
|
||||
ADC_RegularChannelConfig(ADC1, chan->chan, 1, chan->timing & 0xf);
|
||||
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void adc_isr()
|
||||
{
|
||||
AdcChan *chan;
|
||||
uint32_t v = 0;
|
||||
uint8_t amax, ashift;
|
||||
|
||||
chan = &adc_chan[adc_idx];
|
||||
|
||||
// conversion done
|
||||
if (ADC1->STATR & ADC_EOC) {
|
||||
chan->rawval[chan->idx] = ADC1->RDATAR;
|
||||
|
||||
// how many averages should we do?
|
||||
switch (chan->type & CHAN_MASK) {
|
||||
case CHAN_IS_TOUCH: {
|
||||
amax = 4;
|
||||
ashift = 2;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
amax = 8;
|
||||
ashift = 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
chan->idx++;
|
||||
if (chan->idx >= amax) {
|
||||
chan->idx = 0;
|
||||
for (int i = 0; i < amax; i++) {
|
||||
v += chan->rawval[i];
|
||||
}
|
||||
chan->avg = v >> ashift;
|
||||
}
|
||||
}
|
||||
|
||||
// flags cleared by software
|
||||
ADC1->STATR = 0;
|
||||
}
|
||||
22
firmware/app/driver/adc.h
Normal file
22
firmware/app/driver/adc.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __APP_DRIVER_ADC_H
|
||||
#define __APP_DRIVER_ADC_H
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
|
||||
void adc_init();
|
||||
void adc_next();
|
||||
|
||||
int8_t adc_get_tkey(uint8_t key_idx);
|
||||
|
||||
void adc_isr();
|
||||
|
||||
|
||||
|
||||
#endif /* __APP_DRIVER_ADC_H */
|
||||
247
firmware/app/driver/aw20xxx.c
Normal file
247
firmware/app/driver/aw20xxx.c
Normal file
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* awinic AW20108 / AW20072 / AW20054 / AW20036 LED Matrix Driver
|
||||
*
|
||||
* originally written by true in 2022
|
||||
* while sleep deprived for a super constrained mcu
|
||||
*
|
||||
* some bugs fixed for defcon 32 on aug 6-7, 2024
|
||||
* - don't remember what was fixed
|
||||
*
|
||||
* some bugs fixed for supercon on oct 15, 2024
|
||||
* - fixed support for AW20054, which only supports 9 rows
|
||||
* did this by respecting aw->rows
|
||||
*
|
||||
*
|
||||
* driver assumptions:
|
||||
* - rows and columns are as is ordered on the chip, lowest to highest
|
||||
* (if any are skipped, just skip this data in your buffer)
|
||||
* - buffer size does not need to encompass all possible LEDs, only those
|
||||
* which you have specified you are using.
|
||||
* ensure sizeof(aw->fade) == aw->rows + aw->cols
|
||||
* - duty cycle will be set automatically according to aw->cols
|
||||
* - all AW20xxx chips will operate on the same i2c bus
|
||||
* - a static data buffer is used
|
||||
*
|
||||
* driver notices:
|
||||
* - updates only happen one column at a time, and are blocking
|
||||
* (future version may implement a callback when each column is done)
|
||||
* - this driver has not yet implemented the pattern controller
|
||||
* - this driver has not yet implemented the GAIN register, except as
|
||||
* a global configuration, so dimming only operates 8-bit
|
||||
* (will be implemented later to allow for beyond-8-bit operation)
|
||||
* - this driver has not yet implemented FADEDIM mode
|
||||
*
|
||||
* if you need anything different, write it yourself
|
||||
*/
|
||||
|
||||
#include "aw20xxx.h"
|
||||
|
||||
|
||||
|
||||
#define AW20X_THIS_PAGE (aw->state & AW20X_STATE_PAGE_MASK)
|
||||
|
||||
#define AW20X_SET_PAGE(x) if (AW20X_THIS_PAGE != (x)) { \
|
||||
aw20x_page(aw, x); \
|
||||
aw->state &= ~AW20X_STATE_PAGE_MASK; \
|
||||
aw->state |= x; }
|
||||
|
||||
|
||||
|
||||
static uint8_t aw_buf[25]; // enough bytes for register and single column FADEDIM update (1 + (12*2))
|
||||
|
||||
|
||||
|
||||
void aw20x_page(struct AW20x *aw, uint8_t page)
|
||||
{
|
||||
// the datasheet isn't clear on this. the default is zero, and only the lower
|
||||
// three bits are specified. yet the DS says to send 0xCy where y is the page bits.
|
||||
// we'll just do what the DS says even though it contradicts itself.
|
||||
aw_buf[0] = 0xc0 | (page & AW20X_PAGE_MASK);
|
||||
AW20X_I2C_writereg(aw->addr, AW20X_REG_PAGE, aw_buf, 1);
|
||||
}
|
||||
|
||||
void aw20x_init(struct AW20x *aw, uint8_t addr, uint8_t cols, uint8_t rows, uint8_t imax)
|
||||
{
|
||||
// set config register as specified
|
||||
aw->addr = addr;
|
||||
aw->cols = cols;
|
||||
aw->rows = rows;
|
||||
aw->config = imax & AW20X_CONF_IMAX_MASK;
|
||||
|
||||
// wake up (and set page to config page)
|
||||
aw20x_set_sleep(aw, 0);
|
||||
|
||||
// enabled columns
|
||||
aw_buf[0] = cols - 1;
|
||||
while (AW20X_I2C_busy()) {};
|
||||
AW20X_I2C_writereg(aw->addr, AW20X_REG_SIZE, aw_buf, 1);
|
||||
|
||||
// general config
|
||||
aw_buf[0] = imax & AW20X_CONF_IMAX_MASK;
|
||||
while (AW20X_I2C_busy()) {};
|
||||
AW20X_I2C_writereg(aw->addr, AW20X_REG_GCCR, aw_buf, 1);
|
||||
}
|
||||
|
||||
void aw20x_set_sleep(struct AW20x *aw, uint8_t sleep)
|
||||
{
|
||||
// make sure we're on the config page
|
||||
AW20X_SET_PAGE(AW20X_PAGE0_CONFIG);
|
||||
|
||||
aw_buf[0] = sleep ? AW20X_SLPCR_SLEEP : 0;
|
||||
|
||||
// send sleep bit
|
||||
while (AW20X_I2C_busy()) {};
|
||||
AW20X_I2C_writereg(aw->addr, AW20X_REG_SLPCR, aw_buf, 1);
|
||||
|
||||
// set state
|
||||
if (sleep) aw->state |= AW20X_STATE_SLEEP_MASK;
|
||||
else aw->state &= ~AW20X_STATE_SLEEP_MASK;
|
||||
|
||||
// burn some cycles if we woke up
|
||||
if (!sleep) AW20X_INIT_DELAY();
|
||||
}
|
||||
|
||||
void aw20x_set_imax(struct AW20x *aw, uint8_t imax)
|
||||
{
|
||||
// make sure we're on the config page
|
||||
AW20X_SET_PAGE(AW20X_PAGE0_CONFIG);
|
||||
|
||||
aw_buf[0] = imax & AW20X_CONF_IMAX_MASK;
|
||||
|
||||
// send imax
|
||||
while (AW20X_I2C_busy()) {};
|
||||
AW20X_I2C_writereg(aw->addr, AW20X_REG_GCCR, aw_buf, 1);
|
||||
|
||||
aw->config = imax & AW20X_CONF_IMAX_MASK;
|
||||
}
|
||||
|
||||
/*
|
||||
* sends LED values to the chip
|
||||
*/
|
||||
void aw20x_set_fade(struct AW20x *aw)
|
||||
{
|
||||
uint8_t c;
|
||||
uint8_t row;
|
||||
uint8_t offset;
|
||||
|
||||
// make sure we're on the fade page
|
||||
AW20X_SET_PAGE(AW20X_PAGE2_FADE);
|
||||
// don't touch the buffer until we are allowed
|
||||
while (AW20X_I2C_busy()) {};
|
||||
|
||||
row = offset = 0;
|
||||
for (c = 0; c < aw->cols; c++) {
|
||||
// write to chip
|
||||
AW20X_I2C_writereg(aw->addr, offset, aw->fade + row, aw->rows);
|
||||
while (AW20X_I2C_busy());
|
||||
row += aw->rows;
|
||||
offset += AW20X_MAX_ROWS;
|
||||
}
|
||||
}
|
||||
|
||||
void aw20x_set_dim(struct AW20x *aw)
|
||||
{
|
||||
// todo: implement
|
||||
}
|
||||
|
||||
/*
|
||||
* sets all LEDs to the specified 6-bit DIM value.
|
||||
* used when just using FADE and 8-bit mode
|
||||
* to set initial and fine tune from IMAX the output current.
|
||||
*/
|
||||
void aw20x_set_dim_global(struct AW20x *aw, uint8_t dim)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t row;
|
||||
uint8_t offset;
|
||||
|
||||
// ceil
|
||||
if (dim > 0x3f) dim = 0x3f;
|
||||
|
||||
// make sure we're on the dim page
|
||||
AW20X_SET_PAGE(AW20X_PAGE1_DIM);
|
||||
// don't touch the buffer until we are allowed
|
||||
while (AW20X_I2C_busy()) {};
|
||||
|
||||
// clear buffer
|
||||
for (i = 0; i <= aw->rows; i++) aw_buf[i] = dim;
|
||||
|
||||
// send buffer for each column
|
||||
row = offset = 0;
|
||||
for (i = 0; i < aw->cols; i++) {
|
||||
AW20X_I2C_writereg(aw->addr, offset, aw_buf, aw->rows);
|
||||
while (AW20X_I2C_busy());
|
||||
row += aw->rows;
|
||||
offset += AW20X_MAX_ROWS;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void aw20x_commit_fadedim(struct AW20x *aw)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void aw20x_led_on(struct AW20x *aw, uint8_t first, uint8_t last, uint8_t on_bit)
|
||||
{
|
||||
|
||||
}
|
||||
/*
|
||||
* enables LEDs based on user LED count, zero-indexed
|
||||
* assumes AW20X_MAX_LEDON_BITS per row but will only turn on active defined rows
|
||||
* AW20036 would be 0-35, but AW20054 would be 0-71 and so on
|
||||
* for example, LEDs 8-12 on AW20054 with 9 roww enabled
|
||||
* would enable C0R8, C1R0, C1R1, C1R2. all other LEDs are disabled
|
||||
*
|
||||
* todo:
|
||||
* - read current state, and apply bitfields to the currently active state
|
||||
* - allow bypassing the readback for faster operation (such as setting all LEDs on at startup)
|
||||
* - make this more efficient (36 LEDs takes ~0.3ms on a 48MHz PIC!)
|
||||
*/
|
||||
void aw20x_led_enable_range(struct AW20x *aw, uint8_t first, uint8_t last)
|
||||
{
|
||||
uint8_t c, r;
|
||||
uint8_t idx;
|
||||
uint8_t boff;
|
||||
uint8_t *buf;
|
||||
|
||||
// make sure we're on the config page
|
||||
AW20X_SET_PAGE(AW20X_PAGE0_CONFIG);
|
||||
// don't touch the buffer until we are allowed
|
||||
while (AW20X_I2C_busy());
|
||||
|
||||
// bits are stored 6 bits per byte, 2 bytes per column, one bit for each row
|
||||
// for a maximum of the AW20X_MAX_ROWS of LED on bits
|
||||
// we only want to touch bits that exist on the chip and in the correct order
|
||||
idx = 0;
|
||||
for (c = 0; c < aw->cols; c++) {
|
||||
buf = &aw_buf[c*2];
|
||||
buf[0] = buf[1] = 0;
|
||||
boff = 0;
|
||||
for (r = 0; r < AW20X_MAX_LEDON_BITS*2; r++) {
|
||||
if (r + idx < first) continue; // only start at the first led
|
||||
if (r + idx > last) break; // and stop at the last
|
||||
|
||||
if (r >= aw->rows) continue; // max bits to process per row
|
||||
|
||||
if (r == AW20X_MAX_LEDON_BITS) { // only this many bits per byte
|
||||
boff += AW20X_MAX_LEDON_BITS;
|
||||
buf++;
|
||||
}
|
||||
|
||||
*buf |= (1 << (r - boff));
|
||||
}
|
||||
idx += AW20X_MAX_LEDON_BITS*2;
|
||||
}
|
||||
|
||||
AW20X_I2C_writereg(aw->addr, AW20X_REG_LEDON0, aw_buf, c*2);
|
||||
}
|
||||
|
||||
/*
|
||||
* disables LEDs based on user LED count, zero-indexed
|
||||
* (for example, LEDs 8-12 on AW20054 would enable C0R8, C0R9, C1R0, C1R1)
|
||||
*/
|
||||
void aw20x_led_disable(struct AW20x *aw, uint8_t first, uint8_t last)
|
||||
{
|
||||
|
||||
}
|
||||
194
firmware/app/driver/aw20xxx.h
Normal file
194
firmware/app/driver/aw20xxx.h
Normal file
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* awinic AW20108 / AW20072 / AW20054 / AW20036 LED Matrix Driver
|
||||
*/
|
||||
|
||||
#ifndef AW20X_LED_MATRIX_H
|
||||
#define AW20X_LED_MATRIX_H
|
||||
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../comms/i2c.h"
|
||||
|
||||
|
||||
|
||||
#define AW20X_INIT_DELAY() { uint16_t zz = 1000; while(zz--); }
|
||||
// burn cycles for ~200us
|
||||
|
||||
#define AW20X_MAX_COLS 9
|
||||
#define AW20X_MAX_ROWS 12
|
||||
|
||||
#define AW20X_MAX_LEDON_BITS 6
|
||||
|
||||
#define AW20X_ADDR_SCL 0x38 // AD pin tied to SCL
|
||||
#define AW20X_ADDR_SDA 0x39 // AD pin tied to SDA
|
||||
#define AW20X_ADDR_GND 0x3A // AD pin tied to GND
|
||||
#define AW20X_ADDR_VDD 0x3B // AD pin tied to VDD
|
||||
|
||||
#define AW20X_CONF_IMAX_MASK 0xf0 // 7:4
|
||||
#define AW20X_CONF_IMAX_OFFSET 4 // 7:4
|
||||
#define AW20X_CONF_ADDR_MASK 0x03 // 1:0
|
||||
#define AW20X_CONF_ADDR_OFFSET 0 // 1:0
|
||||
|
||||
#define AW20X_CONF_USE_FADEDIM 0x08 // aw20x.fade now becomes fadedim; updates are done with FADEDIM page
|
||||
// this mode uses 2 bytes per LED; dim as byte 0, fade as byte 1
|
||||
#define AW20X_CONF_USE_EXPEN 0x04 // sets GCCR.EXPEN=1; fade is now only 6 bits (not yet implemented)
|
||||
|
||||
#define AW20X_PAGE_MASK 0x07
|
||||
|
||||
#define AW20X_STATE_PAGE_MASK AW20X_PAGE_MASK
|
||||
#define AW20X_STATE_SLEEP_MASK 0x80
|
||||
|
||||
|
||||
#define AW20X_PAGE0_CONFIG 0x00 // function register
|
||||
#define AW20X_PAGE1_DIM 0x01 // 5:0 dim; 8 bits per LED
|
||||
#define AW20X_PAGE2_FADE 0x02 // 7:0 fade; 8 bits per LED
|
||||
#define AW20X_PAGE3_PATTERN 0x03 // 1:0 pattern; 8 bits per LED
|
||||
#define AW20X_PAGE4_DIMFADE 0x04 // 13:8 dim, 7:0 fade; 16 bits per LED
|
||||
#define AW20X_PAGE5_DFP 0x05 // 15:14 pat, 13:8 dim, 7:0 fade; 16 bits per LED
|
||||
|
||||
#define AW20X_REG_IDR 0x00 // R 7:0 chip ID {0x18}
|
||||
#define AW20X_REG_SLPCR 0x01 // RW 7 sleep {0x80}
|
||||
#define AW20X_REG_RSTR 0x02 // W 7:0 SW_RSTN (?)
|
||||
#define AW20X_REG_GCCR 0x03 // RW 7:3 IMAX(7:4), ALLON, -, -, EXPEN {0x10}
|
||||
#define AW20X_REG_FCD 0x04 // W 0 FCDE (fast clear display enable)
|
||||
#define AW20X_REG_CLKSYS 0x05 // RW 1:0 CLK_IO, CLK_SEL
|
||||
#define AW20X_REG_FLTCFG1 0x09 // RW 5:0 UVLOPE, OTPE, UVIE, OTIE, UVLOE, OTE
|
||||
#define AW20X_REG_FLTCFG2 0x0a // RW 3:2 UVTH
|
||||
#define AW20X_REG_ISRFLT 0x0b // RW 5:0 PAT2IS, PAT1IS, PAT0IS, -, -, UVLOIS, OTIS
|
||||
#define AW20X_REG_LEDON0 0x31 // W 5:0 ON0:ON5, same pattern through to LEDON17 (0x42)
|
||||
#define AW20X_REG_PATCR 0x43 // RW 6:0 PAT2IE, PAT1IE, PAT0IE, -, PAT2EN, PAT1EN, PAT0EN
|
||||
#define AW20X_REG_FADEH0 0x44 // RW 7:0 FADEH0
|
||||
#define AW20X_REG_FADEH1 0x45
|
||||
#define AW20X_REG_FADEH2 0x46
|
||||
#define AW20X_REG_FADEL0 0x47
|
||||
#define AW20X_REG_FADEL1 0x48
|
||||
#define AW20X_REG_FADEL2 0x49 // RW 7:0 FADEL2
|
||||
#define AW20X_REG_PAT0T0 0x4a // RW 7:0 T1[4], T2[4]
|
||||
#define AW20X_REG_PAT0T1 0x4b // RW 7:0 T3[4], T4[4]
|
||||
#define AW20X_REG_PAT0T2 0x4c // RW 7:0 LE[2], LB[2], LT(11:8)[4]
|
||||
#define AW20X_REG_PAT0T3 0x4d // RW 7:0 LT(7:0)
|
||||
#define AW20X_REG_PAT1T0 0x4e
|
||||
#define AW20X_REG_PAT1T1 0x4f
|
||||
#define AW20X_REG_PAT1T2 0x50
|
||||
#define AW20X_REG_PAT1T3 0x51
|
||||
#define AW20X_REG_PAT2T0 0x52
|
||||
#define AW20X_REG_PAT2T1 0x53
|
||||
#define AW20X_REG_PAT2T2 0x54
|
||||
#define AW20X_REG_PAT2T3 0x55
|
||||
#define AW20X_REG_PAT0CFG 0x56 // RW 2:0 SWITCH, RAMPE, PATMD
|
||||
#define AW20X_REG_PAT1CFG 0x57
|
||||
#define AW20X_REG_PAT2CFG 0x58
|
||||
#define AW20X_REG_PATGO 0x59 // RW 6:0 PAT2ST, PAT1ST, PAT0ST, -, RUN2, RUN1, RUN0
|
||||
#define AW20X_REG_SIZE 0x80 // RW 3:0 SWSEL
|
||||
#define AW20X_REG_PAGE 0xf0 // RW 2:0 page select, 0-5; available from all pages
|
||||
|
||||
#define AW20X_IDR_ID 0x18 // value for all chips in this series
|
||||
|
||||
#define AW20X_SLPCR_SLEEP 0x01 // sleep mode (default is HIGH / asleep)
|
||||
|
||||
#define AW20X_RSTR_SW_RSTN 0x01 // write value to soft reset the chip
|
||||
|
||||
#define AW20X_GCCR_IMAX 0xf0 // global current setting (default 20mA)
|
||||
#define AW20X_GCCR_ALLON 0x08 // 0=normal, 1=force all on
|
||||
#define AW20X_GCCR_EXPEN 0x01 // 0=fade is linear 8-bit, 1=fade is exponential 6-bit
|
||||
|
||||
#define AW20X_FCD_FCDE 0x01 // write value to clear display (DS doesn't specify; is this a blanker?)
|
||||
|
||||
#define AW20X_CLKSYS_CLK_IO 0x02 // 0=no clk output, 1=clk output on (output) CLKIO pin
|
||||
#define AW20X_CLKSYS_CLK_SEL 0x01 // 0=internal 4MHz, 1=use clk on (input) CLKIO pin
|
||||
|
||||
#define AW20X_FLTCFG1_UVLOPE 0x20 // 1=enable UVLO protection; chip sets SLPCR.SLEEP when ISRFLT.UVLOIS=1
|
||||
#define AW20X_FLTCFG1_OTPE 0x10 // 1=enable overtemp protection; chip sets SLPCR.SLEEP when ISRFLT.UVLOIS=1
|
||||
#define AW20X_FLTCFG1_UVIE 0x08 // 1=UVLO interrupt enable
|
||||
#define AW20X_FLTCFG1_OTIE 0x04 // 1=overtemp interrupt enable
|
||||
#define AW20X_FLTCFG1_UVLOE 0x02 // 1=enable UVLO detect
|
||||
#define AW20X_FLTCFG1_OTE 0x01 // 1=enable overtemp detect
|
||||
|
||||
#define AW20X_FLTCFG1_UVTH_2V0 (0x00 << 2) // UVLO threshold voltage
|
||||
#define AW20X_FLTCFG1_UVTH_2V1 (0x01 << 2) // UVLO threshold voltage
|
||||
#define AW20X_FLTCFG1_UVTH_2V2 (0x02 << 2) // UVLO threshold voltage
|
||||
#define AW20X_FLTCFG1_UVTH_2V3 (0x03 << 2) // UVLO threshold voltage
|
||||
|
||||
#define AW20X_ISRFLT_PAT2IS 0x40 // pattern controller 2 interrupt (finished breath loop)
|
||||
#define AW20X_ISRFLT_PAT1IS 0x20 // pattern controller 1 interrupt (finished breath loop)
|
||||
#define AW20X_ISRFLT_PAT0IS 0x10 // pattern controller 0 interrupt (finished breath loop)
|
||||
#define AW20X_ISRFLT_UVLOIS 0x02 // 0=normal, 1=UVLO detected
|
||||
#define AW20X_ISRFLT_OTIS 0x01 // 0=normal, 1=overtemp detected
|
||||
|
||||
// todo: fill in all values from PATCR onward
|
||||
|
||||
|
||||
|
||||
#define AW20X_SOFT_RESET AW20X_RSTR_SW_RSTN
|
||||
|
||||
enum aw20x_imax {
|
||||
AW20X_IMAX_10MA = 0x00,
|
||||
AW20X_IMAX_20MA = 0x10,
|
||||
AW20X_IMAX_30MA = 0x20,
|
||||
AW20X_IMAX_40MA = 0x30,
|
||||
AW20X_IMAX_60MA = 0x40,
|
||||
AW20X_IMAX_80MA = 0x50,
|
||||
AW20X_IMAX_120MA = 0x60,
|
||||
AW20X_IMAX_160MA = 0x70,
|
||||
AW20X_IMAX_3_3MA = 0x80,
|
||||
AW20X_IMAX_6_7MA = 0x90,
|
||||
AW20X_IMAX_10MA_2 = 0xa0,
|
||||
AW20X_IMAX_13_3MA = 0xb0,
|
||||
AW20X_IMAX_20MA_2 = 0xc0,
|
||||
AW20X_IMAX_26_7MA = 0xd0,
|
||||
AW20X_IMAX_40MA_2 = 0xe0,
|
||||
AW20X_IMAX_53_3MA = 0xf0
|
||||
};
|
||||
|
||||
enum aw20x_size {
|
||||
AW20X_SIZE_1COL = 0,
|
||||
AW20X_SIZE_2COL,
|
||||
AW20X_SIZE_3COL,
|
||||
AW20X_SIZE_4COL,
|
||||
AW20X_SIZE_5COL,
|
||||
AW20X_SIZE_6COL,
|
||||
AW20X_SIZE_7COL,
|
||||
AW20X_SIZE_8COL,
|
||||
AW20X_SIZE_9COL
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef SOFT_I2C_MASTER
|
||||
#define AW20X_I2C_busy() (0)
|
||||
#define AW20X_I2C_writereg(adr, reg, buf, siz) i2c_write_reg8(adr, reg, buf, siz)
|
||||
#else
|
||||
#define AW20X_I2C_busy() (0)
|
||||
#define AW20X_I2C_writereg(adr, reg, buf, siz) i2c_write_addr1b(adr, reg, buf, siz);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
typedef struct AW20x {
|
||||
uint8_t addr;
|
||||
uint8_t config; // settings for the chip
|
||||
uint8_t state; // keeps track of active page, and high bit is set if asleep
|
||||
uint8_t cols; // highest column used by application, 1-9
|
||||
uint8_t rows; // highest row used by application, 1-12
|
||||
uint8_t pad[3];
|
||||
uint8_t *fade; // led buffer location for FADE (required), of size cols+rows
|
||||
uint8_t *gain; // led buffer location for GAIN (optional), of size cols+rows
|
||||
} AW20x;
|
||||
|
||||
|
||||
|
||||
void aw20x_init(struct AW20x *aw, uint8_t addr, uint8_t cols, uint8_t rows, uint8_t imax);
|
||||
|
||||
void aw20x_set_sleep(struct AW20x *aw, uint8_t sleep);
|
||||
void aw20x_set_imax(struct AW20x *aw, uint8_t imax);
|
||||
|
||||
void aw20x_set_fade(struct AW20x *aw);
|
||||
void aw20x_set_dim_global(struct AW20x *aw, uint8_t dim);
|
||||
|
||||
void aw20x_led_enable_range(struct AW20x *aw, uint8_t first, uint8_t last);
|
||||
|
||||
|
||||
|
||||
#endif /* AW02X_LED_MATRIX_H */
|
||||
2549
firmware/app/driver/lis2hh12_reg.c
Normal file
2549
firmware/app/driver/lis2hh12_reg.c
Normal file
File diff suppressed because it is too large
Load Diff
992
firmware/app/driver/lis2hh12_reg.h
Normal file
992
firmware/app/driver/lis2hh12_reg.h
Normal file
@@ -0,0 +1,992 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lis2hh12_reg.h
|
||||
* @author Sensors Software Solution Team
|
||||
* @brief This file contains all the functions prototypes for the
|
||||
* lis2hh12_reg.c driver.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2021 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef LIS2HH12_REGS_H
|
||||
#define LIS2HH12_REGS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <math.h>
|
||||
|
||||
/** @addtogroup LIS2HH12
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
/** @defgroup Endianness definitions
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef DRV_BYTE_ORDER
|
||||
#ifndef __BYTE_ORDER__
|
||||
|
||||
#define DRV_LITTLE_ENDIAN 1234
|
||||
#define DRV_BIG_ENDIAN 4321
|
||||
|
||||
/** if _BYTE_ORDER is not defined, choose the endianness of your architecture
|
||||
* by uncommenting the define which fits your platform endianness
|
||||
*/
|
||||
//#define DRV_BYTE_ORDER DRV_BIG_ENDIAN
|
||||
#define DRV_BYTE_ORDER DRV_LITTLE_ENDIAN
|
||||
|
||||
#else /* defined __BYTE_ORDER__ */
|
||||
|
||||
#define DRV_LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__
|
||||
#define DRV_BIG_ENDIAN __ORDER_BIG_ENDIAN__
|
||||
#define DRV_BYTE_ORDER __BYTE_ORDER__
|
||||
|
||||
#endif /* __BYTE_ORDER__*/
|
||||
#endif /* DRV_BYTE_ORDER */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
/** @defgroup STMicroelectronics sensors common types
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MEMS_SHARED_TYPES
|
||||
#define MEMS_SHARED_TYPES
|
||||
|
||||
typedef struct
|
||||
{
|
||||
#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN
|
||||
uint8_t bit0 : 1;
|
||||
uint8_t bit1 : 1;
|
||||
uint8_t bit2 : 1;
|
||||
uint8_t bit3 : 1;
|
||||
uint8_t bit4 : 1;
|
||||
uint8_t bit5 : 1;
|
||||
uint8_t bit6 : 1;
|
||||
uint8_t bit7 : 1;
|
||||
#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN
|
||||
uint8_t bit7 : 1;
|
||||
uint8_t bit6 : 1;
|
||||
uint8_t bit5 : 1;
|
||||
uint8_t bit4 : 1;
|
||||
uint8_t bit3 : 1;
|
||||
uint8_t bit2 : 1;
|
||||
uint8_t bit1 : 1;
|
||||
uint8_t bit0 : 1;
|
||||
#endif /* DRV_BYTE_ORDER */
|
||||
} bitwise_t;
|
||||
|
||||
#define PROPERTY_DISABLE (0U)
|
||||
#define PROPERTY_ENABLE (1U)
|
||||
|
||||
/** @addtogroup Interfaces_Functions
|
||||
* @brief This section provide a set of functions used to read and
|
||||
* write a generic register of the device.
|
||||
* MANDATORY: return 0 -> no Error.
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
typedef int32_t (*stmdev_write_ptr)(
|
||||
void *handle,
|
||||
uint8_t reg,
|
||||
const uint8_t *buf,
|
||||
uint16_t len);
|
||||
|
||||
typedef int32_t (*stmdev_read_ptr)(
|
||||
void *handle,
|
||||
uint8_t reg,
|
||||
uint8_t *buf,
|
||||
uint16_t len);
|
||||
|
||||
typedef void (*stmdev_mdelay_ptr)(uint32_t millisec);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/** Component mandatory fields **/
|
||||
stmdev_write_ptr write_reg;
|
||||
stmdev_read_ptr read_reg;
|
||||
/** Component optional fields **/
|
||||
stmdev_mdelay_ptr mdelay;
|
||||
/** Customizable optional pointer **/
|
||||
void *handle;
|
||||
|
||||
/** private data **/
|
||||
void *priv_data;
|
||||
} stmdev_ctx_t;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
#endif /* MEMS_SHARED_TYPES */
|
||||
|
||||
#ifndef MEMS_UCF_SHARED_TYPES
|
||||
#define MEMS_UCF_SHARED_TYPES
|
||||
|
||||
/** @defgroup Generic address-data structure definition
|
||||
* @brief This structure is useful to load a predefined configuration
|
||||
* of a sensor.
|
||||
* You can create a sensor configuration by your own or using
|
||||
* Unico / Unicleo tools available on STMicroelectronics
|
||||
* web site.
|
||||
*
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t address;
|
||||
uint8_t data;
|
||||
} ucf_line_t;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
#endif /* MEMS_UCF_SHARED_TYPES */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
/** @defgroup LIS2HH12_Infos
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
/** I2C Device Address 8 bit format if SA0=0 -> 0x3D if SA0=1 -> 0x3B **/
|
||||
#define LIS2HH12_I2C_ADD_L 0x3DU
|
||||
#define LIS2HH12_I2C_ADD_H 0x3BU
|
||||
/** Device Identification (Who am I) **/
|
||||
#define LIS2HH12_ID 0x41U
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
#define LIS2HH12_TEMP_L 0x0BU
|
||||
#define LIS2HH12_TEMP_H 0x0CU
|
||||
#define LIS2HH12_WHO_AM_I 0x0FU
|
||||
#define LIS2HH12_ACT_THS 0x1EU
|
||||
typedef struct
|
||||
{
|
||||
#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN
|
||||
uint8_t ths : 7;
|
||||
uint8_t not_used_01 : 1;
|
||||
#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN
|
||||
uint8_t not_used_01 : 1;
|
||||
uint8_t ths : 7;
|
||||
#endif /* DRV_BYTE_ORDER */
|
||||
} lis2hh12_act_ths_t;
|
||||
|
||||
#define LIS2HH12_ACT_DUR 0x1FU
|
||||
typedef struct
|
||||
{
|
||||
uint8_t dur : 8;
|
||||
} lis2hh12_act_dur_t;
|
||||
|
||||
#define LIS2HH12_CTRL1 0x20U
|
||||
typedef struct
|
||||
{
|
||||
#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN
|
||||
uint8_t xen : 1;
|
||||
uint8_t yen : 1;
|
||||
uint8_t zen : 1;
|
||||
uint8_t bdu : 1;
|
||||
uint8_t odr : 3;
|
||||
uint8_t hr : 1;
|
||||
#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN
|
||||
uint8_t hr : 1;
|
||||
uint8_t odr : 3;
|
||||
uint8_t bdu : 1;
|
||||
uint8_t zen : 1;
|
||||
uint8_t yen : 1;
|
||||
uint8_t xen : 1;
|
||||
#endif /* DRV_BYTE_ORDER */
|
||||
} lis2hh12_ctrl1_t;
|
||||
|
||||
#define LIS2HH12_CTRL2 0x21U
|
||||
typedef struct
|
||||
{
|
||||
#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN
|
||||
uint8_t hpis : 2;
|
||||
uint8_t fds : 1;
|
||||
uint8_t hpm : 2;
|
||||
uint8_t dfc : 2;
|
||||
uint8_t not_used_01 : 1;
|
||||
#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN
|
||||
uint8_t not_used_01 : 1;
|
||||
uint8_t dfc : 2;
|
||||
uint8_t hpm : 2;
|
||||
uint8_t fds : 1;
|
||||
uint8_t hpis : 2;
|
||||
#endif /* DRV_BYTE_ORDER */
|
||||
} lis2hh12_ctrl2_t;
|
||||
|
||||
#define LIS2HH12_CTRL3 0x22U
|
||||
typedef struct
|
||||
{
|
||||
#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN
|
||||
uint8_t int1_drdy : 1;
|
||||
uint8_t int1_fth : 1;
|
||||
uint8_t int1_ovr : 1;
|
||||
uint8_t int1_ig1 : 1;
|
||||
uint8_t int1_ig2 : 1;
|
||||
uint8_t int1_inact : 1;
|
||||
uint8_t stop_fth : 1;
|
||||
uint8_t fifo_en : 1;
|
||||
#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN
|
||||
uint8_t fifo_en : 1;
|
||||
uint8_t stop_fth : 1;
|
||||
uint8_t int1_inact : 1;
|
||||
uint8_t int1_ig2 : 1;
|
||||
uint8_t int1_ig1 : 1;
|
||||
uint8_t int1_ovr : 1;
|
||||
uint8_t int1_fth : 1;
|
||||
uint8_t int1_drdy : 1;
|
||||
#endif /* DRV_BYTE_ORDER */
|
||||
} lis2hh12_ctrl3_t;
|
||||
|
||||
#define LIS2HH12_CTRL4 0x23U
|
||||
typedef struct
|
||||
{
|
||||
#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN
|
||||
uint8_t sim : 1;
|
||||
uint8_t i2c_disable : 1;
|
||||
uint8_t if_add_inc : 1;
|
||||
uint8_t bw_scale_odr : 1;
|
||||
uint8_t fs : 2;
|
||||
uint8_t bw : 2;
|
||||
#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN
|
||||
uint8_t bw : 2;
|
||||
uint8_t fs : 2;
|
||||
uint8_t bw_scale_odr : 1;
|
||||
uint8_t if_add_inc : 1;
|
||||
uint8_t i2c_disable : 1;
|
||||
uint8_t sim : 1;
|
||||
#endif /* DRV_BYTE_ORDER */
|
||||
} lis2hh12_ctrl4_t;
|
||||
|
||||
#define LIS2HH12_CTRL5 0x24U
|
||||
typedef struct
|
||||
{
|
||||
#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN
|
||||
uint8_t pp_od : 1;
|
||||
uint8_t h_lactive : 1;
|
||||
uint8_t st : 2;
|
||||
uint8_t dec : 2;
|
||||
uint8_t soft_reset : 1;
|
||||
uint8_t debug : 1;
|
||||
#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN
|
||||
uint8_t debug : 1;
|
||||
uint8_t soft_reset : 1;
|
||||
uint8_t dec : 2;
|
||||
uint8_t st : 2;
|
||||
uint8_t h_lactive : 1;
|
||||
uint8_t pp_od : 1;
|
||||
#endif /* DRV_BYTE_ORDER */
|
||||
} lis2hh12_ctrl5_t;
|
||||
|
||||
#define LIS2HH12_CTRL6 0x25U
|
||||
typedef struct
|
||||
{
|
||||
#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN
|
||||
uint8_t int2_drdy : 1;
|
||||
uint8_t int2_fth : 1;
|
||||
uint8_t int2_empty : 1;
|
||||
uint8_t int2_ig1 : 1;
|
||||
uint8_t int2_ig2 : 1;
|
||||
uint8_t int2_boot : 1;
|
||||
uint8_t not_used_01 : 1;
|
||||
uint8_t boot : 1;
|
||||
#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN
|
||||
uint8_t boot : 1;
|
||||
uint8_t not_used_01 : 1;
|
||||
uint8_t int2_boot : 1;
|
||||
uint8_t int2_ig2 : 1;
|
||||
uint8_t int2_ig1 : 1;
|
||||
uint8_t int2_empty : 1;
|
||||
uint8_t int2_fth : 1;
|
||||
uint8_t int2_drdy : 1;
|
||||
#endif /* DRV_BYTE_ORDER */
|
||||
} lis2hh12_ctrl6_t;
|
||||
|
||||
#define LIS2HH12_CTRL7 0x26U
|
||||
typedef struct
|
||||
{
|
||||
#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN
|
||||
uint8_t _4d_ig : 2;
|
||||
uint8_t lir : 2;
|
||||
uint8_t dcrm : 2;
|
||||
uint8_t not_used_01 : 2;
|
||||
#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN
|
||||
uint8_t not_used_01 : 2;
|
||||
uint8_t dcrm : 2;
|
||||
uint8_t lir : 2;
|
||||
uint8_t _4d_ig : 2;
|
||||
#endif /* DRV_BYTE_ORDER */
|
||||
} lis2hh12_ctrl7_t;
|
||||
|
||||
#define LIS2HH12_STATUS 0x27U
|
||||
typedef struct
|
||||
{
|
||||
#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN
|
||||
uint8_t xda : 1;
|
||||
uint8_t yda : 1;
|
||||
uint8_t zda : 1;
|
||||
uint8_t zyxda : 1;
|
||||
uint8_t _xor : 1;
|
||||
uint8_t yor : 1;
|
||||
uint8_t zor : 1;
|
||||
uint8_t zyxor : 1;
|
||||
#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN
|
||||
uint8_t zyxor : 1;
|
||||
uint8_t zor : 1;
|
||||
uint8_t yor : 1;
|
||||
uint8_t _xor : 1;
|
||||
uint8_t zyxda : 1;
|
||||
uint8_t zda : 1;
|
||||
uint8_t yda : 1;
|
||||
uint8_t xda : 1;
|
||||
#endif /* DRV_BYTE_ORDER */
|
||||
} lis2hh12_status_t;
|
||||
|
||||
#define LIS2HH12_OUT_X_L 0x28U
|
||||
#define LIS2HH12_OUT_X_H 0x29U
|
||||
#define LIS2HH12_OUT_Y_L 0x2AU
|
||||
#define LIS2HH12_OUT_Y_H 0x2BU
|
||||
#define LIS2HH12_OUT_Z_L 0x2CU
|
||||
#define LIS2HH12_OUT_Z_H 0x2DU
|
||||
#define LIS2HH12_FIFO_CTRL 0x2EU
|
||||
typedef struct
|
||||
{
|
||||
#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN
|
||||
uint8_t fth : 5;
|
||||
uint8_t fmode : 3;
|
||||
#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN
|
||||
uint8_t fmode : 3;
|
||||
uint8_t fth : 5;
|
||||
#endif /* DRV_BYTE_ORDER */
|
||||
} lis2hh12_fifo_ctrl_t;
|
||||
|
||||
#define LIS2HH12_FIFO_SRC 0x2FU
|
||||
typedef struct
|
||||
{
|
||||
#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN
|
||||
uint8_t fss : 5;
|
||||
uint8_t empty : 1;
|
||||
uint8_t ovr : 1;
|
||||
uint8_t fth : 1;
|
||||
#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN
|
||||
uint8_t fth : 1;
|
||||
uint8_t ovr : 1;
|
||||
uint8_t empty : 1;
|
||||
uint8_t fss : 5;
|
||||
#endif /* DRV_BYTE_ORDER */
|
||||
} lis2hh12_fifo_src_t;
|
||||
|
||||
#define LIS2HH12_IG_CFG1 0x30U
|
||||
typedef struct
|
||||
{
|
||||
#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN
|
||||
uint8_t xlie : 1;
|
||||
uint8_t xhie : 1;
|
||||
uint8_t ylie : 1;
|
||||
uint8_t yhie : 1;
|
||||
uint8_t zlie : 1;
|
||||
uint8_t zhie : 1;
|
||||
uint8_t _6d : 1;
|
||||
uint8_t aoi : 1;
|
||||
#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN
|
||||
uint8_t aoi : 1;
|
||||
uint8_t _6d : 1;
|
||||
uint8_t zhie : 1;
|
||||
uint8_t zlie : 1;
|
||||
uint8_t yhie : 1;
|
||||
uint8_t ylie : 1;
|
||||
uint8_t xhie : 1;
|
||||
uint8_t xlie : 1;
|
||||
#endif /* DRV_BYTE_ORDER */
|
||||
} lis2hh12_ig_cfg1_t;
|
||||
|
||||
#define LIS2HH12_IG_SRC1 0x31U
|
||||
typedef struct
|
||||
{
|
||||
#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN
|
||||
uint8_t xl : 1;
|
||||
uint8_t xh : 1;
|
||||
uint8_t yl : 1;
|
||||
uint8_t yh : 1;
|
||||
uint8_t zl : 1;
|
||||
uint8_t zh : 1;
|
||||
uint8_t ia : 1;
|
||||
uint8_t not_used_01 : 1;
|
||||
#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN
|
||||
uint8_t not_used_01 : 1;
|
||||
uint8_t ia : 1;
|
||||
uint8_t zh : 1;
|
||||
uint8_t zl : 1;
|
||||
uint8_t yh : 1;
|
||||
uint8_t yl : 1;
|
||||
uint8_t xh : 1;
|
||||
uint8_t xl : 1;
|
||||
#endif /* DRV_BYTE_ORDER */
|
||||
} lis2hh12_ig_src1_t;
|
||||
|
||||
#define LIS2HH12_IG_THS_X1 0x32U
|
||||
#define LIS2HH12_IG_THS_Y1 0x33U
|
||||
#define LIS2HH12_IG_THS_Z1 0x34U
|
||||
#define LIS2HH12_IG_DUR1 0x35U
|
||||
typedef struct
|
||||
{
|
||||
#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN
|
||||
uint8_t dur1 : 7;
|
||||
uint8_t wait1 : 1;
|
||||
#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN
|
||||
uint8_t wait1 : 1;
|
||||
uint8_t dur1 : 7;
|
||||
#endif /* DRV_BYTE_ORDER */
|
||||
} lis2hh12_ig_dur1_t;
|
||||
|
||||
#define LIS2HH12_IG_CFG2 0x36U
|
||||
typedef struct
|
||||
{
|
||||
#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN
|
||||
uint8_t xlie : 1;
|
||||
uint8_t xhie : 1;
|
||||
uint8_t ylie : 1;
|
||||
uint8_t yhie : 1;
|
||||
uint8_t zlie : 1;
|
||||
uint8_t zhie : 1;
|
||||
uint8_t _6d : 1;
|
||||
uint8_t aoi : 1;
|
||||
#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN
|
||||
uint8_t aoi : 1;
|
||||
uint8_t _6d : 1;
|
||||
uint8_t zhie : 1;
|
||||
uint8_t zlie : 1;
|
||||
uint8_t yhie : 1;
|
||||
uint8_t ylie : 1;
|
||||
uint8_t xhie : 1;
|
||||
uint8_t xlie : 1;
|
||||
#endif /* DRV_BYTE_ORDER */
|
||||
} lis2hh12_ig_cfg2_t;
|
||||
|
||||
#define LIS2HH12_IG_SRC2 0x37U
|
||||
typedef struct
|
||||
{
|
||||
#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN
|
||||
uint8_t xl : 1;
|
||||
uint8_t xh : 1;
|
||||
uint8_t yl : 1;
|
||||
uint8_t yh : 1;
|
||||
uint8_t zl : 1;
|
||||
uint8_t zh : 1;
|
||||
uint8_t ia : 1;
|
||||
uint8_t not_used_01 : 1;
|
||||
#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN
|
||||
uint8_t not_used_01 : 1;
|
||||
uint8_t ia : 1;
|
||||
uint8_t zh : 1;
|
||||
uint8_t zl : 1;
|
||||
uint8_t yh : 1;
|
||||
uint8_t yl : 1;
|
||||
uint8_t xh : 1;
|
||||
uint8_t xl : 1;
|
||||
#endif /* DRV_BYTE_ORDER */
|
||||
} lis2hh12_ig_src2_t;
|
||||
|
||||
#define LIS2HH12_IG_THS2 0x38U
|
||||
#define LIS2HH12_IG_DUR2 0x39U
|
||||
typedef struct
|
||||
{
|
||||
#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN
|
||||
uint8_t dur2 : 7;
|
||||
uint8_t wait2 : 1;
|
||||
#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN
|
||||
uint8_t wait2 : 1;
|
||||
uint8_t dur2 : 7;
|
||||
#endif /* DRV_BYTE_ORDER */
|
||||
} lis2hh12_ig_dur2_t;
|
||||
|
||||
#define LIS2HH12_XL_REFERENCE 0x3AU
|
||||
#define LIS2HH12_XH_REFERENCE 0x3BU
|
||||
#define LIS2HH12_YL_REFERENCE 0x3CU
|
||||
#define LIS2HH12_YH_REFERENCE 0x3DU
|
||||
#define LIS2HH12_ZL_REFERENCE 0x3EU
|
||||
#define LIS2HH12_ZH_REFERENCE 0x3FU
|
||||
|
||||
/**
|
||||
* @defgroup LIS2HH12_Register_Union
|
||||
* @brief This union group all the registers having a bit-field
|
||||
* description.
|
||||
* This union is useful but it's not needed by the driver.
|
||||
*
|
||||
* REMOVING this union you are compliant with:
|
||||
* MISRA-C 2012 [Rule 19.2] -> " Union are not allowed "
|
||||
*
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
lis2hh12_act_ths_t act_ths;
|
||||
lis2hh12_act_dur_t act_dur;
|
||||
lis2hh12_ctrl1_t ctrl1;
|
||||
lis2hh12_ctrl2_t ctrl2;
|
||||
lis2hh12_ctrl3_t ctrl3;
|
||||
lis2hh12_ctrl4_t ctrl4;
|
||||
lis2hh12_ctrl5_t ctrl5;
|
||||
lis2hh12_ctrl6_t ctrl6;
|
||||
lis2hh12_ctrl7_t ctrl7;
|
||||
lis2hh12_status_t status;
|
||||
lis2hh12_fifo_ctrl_t fifo_ctrl;
|
||||
lis2hh12_fifo_src_t fifo_src;
|
||||
lis2hh12_ig_cfg1_t ig_cfg1;
|
||||
lis2hh12_ig_src1_t ig_src1;
|
||||
lis2hh12_ig_dur1_t ig_dur1;
|
||||
lis2hh12_ig_cfg2_t ig_cfg2;
|
||||
lis2hh12_ig_src2_t ig_src2;
|
||||
lis2hh12_ig_dur2_t ig_dur2;
|
||||
bitwise_t bitwise;
|
||||
uint8_t byte;
|
||||
} lis2hh12_reg_t;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __weak
|
||||
#define __weak __attribute__((weak))
|
||||
#endif /* __weak */
|
||||
|
||||
/*
|
||||
* These are the basic platform dependent I/O routines to read
|
||||
* and write device registers connected on a standard bus.
|
||||
* The driver keeps offering a default implementation based on function
|
||||
* pointers to read/write routines for backward compatibility.
|
||||
* The __weak directive allows the final application to overwrite
|
||||
* them with a custom implementation.
|
||||
*/
|
||||
|
||||
int32_t lis2hh12_read_reg(const stmdev_ctx_t *ctx, uint8_t reg,
|
||||
uint8_t *data,
|
||||
uint16_t len);
|
||||
int32_t lis2hh12_write_reg(const stmdev_ctx_t *ctx, uint8_t reg,
|
||||
uint8_t *data,
|
||||
uint16_t len);
|
||||
|
||||
float_t lis2hh12_from_fs2g_to_mg(int16_t lsb);
|
||||
float_t lis2hh12_from_fs4g_to_mg(int16_t lsb);
|
||||
float_t lis2hh12_from_fs8g_to_mg(int16_t lsb);
|
||||
|
||||
float_t lis2hh12_from_lsb_to_celsius(int16_t lsb);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t xen : 1;
|
||||
uint8_t yen : 1;
|
||||
uint8_t zen : 1;
|
||||
} lis2hh12_xl_axis_t;
|
||||
int32_t lis2hh12_xl_axis_set(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_xl_axis_t val);
|
||||
int32_t lis2hh12_xl_axis_get(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_xl_axis_t *val);
|
||||
|
||||
int32_t lis2hh12_block_data_update_set(const stmdev_ctx_t *ctx,
|
||||
uint8_t val);
|
||||
int32_t lis2hh12_block_data_update_get(const stmdev_ctx_t *ctx,
|
||||
uint8_t *val);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LIS2HH12_XL_ODR_OFF = 0x00,
|
||||
LIS2HH12_XL_ODR_10Hz = 0x01,
|
||||
LIS2HH12_XL_ODR_50Hz = 0x02,
|
||||
LIS2HH12_XL_ODR_100Hz = 0x03,
|
||||
LIS2HH12_XL_ODR_200Hz = 0x04,
|
||||
LIS2HH12_XL_ODR_400Hz = 0x05,
|
||||
LIS2HH12_XL_ODR_800Hz = 0x06,
|
||||
} lis2hh12_xl_data_rate_t;
|
||||
int32_t lis2hh12_xl_data_rate_set(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_xl_data_rate_t val);
|
||||
int32_t lis2hh12_xl_data_rate_get(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_xl_data_rate_t *val);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LIS2HH12_2g = 0x00,
|
||||
LIS2HH12_4g = 0x02,
|
||||
LIS2HH12_8g = 0x03,
|
||||
} lis2hh12_xl_fs_t;
|
||||
int32_t lis2hh12_xl_full_scale_set(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_xl_fs_t val);
|
||||
int32_t lis2hh12_xl_full_scale_get(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_xl_fs_t *val);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LIS2HH12_NO_DECIMATION = 0x00,
|
||||
LIS2HH12_EVERY_2_SAMPLES = 0x01,
|
||||
LIS2HH12_EVERY_4_SAMPLES = 0x02,
|
||||
LIS2HH12_EVERY_8_SAMPLES = 0x03,
|
||||
} lis2hh12_dec_t;
|
||||
int32_t lis2hh12_xl_decimation_set(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_dec_t val);
|
||||
int32_t lis2hh12_xl_decimation_get(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_dec_t *val);
|
||||
|
||||
int32_t lis2hh12_xl_flag_data_ready_get(const stmdev_ctx_t *ctx,
|
||||
uint8_t *val);
|
||||
|
||||
int32_t lis2hh12_temperature_raw_get(const stmdev_ctx_t *ctx, int16_t *val);
|
||||
|
||||
int32_t lis2hh12_acceleration_raw_get(const stmdev_ctx_t *ctx,
|
||||
int16_t *val);
|
||||
|
||||
int32_t lis2hh12_dev_id_get(const stmdev_ctx_t *ctx, uint8_t *buff);
|
||||
|
||||
int32_t lis2hh12_dev_reset_set(const stmdev_ctx_t *ctx, uint8_t val);
|
||||
int32_t lis2hh12_dev_reset_get(const stmdev_ctx_t *ctx, uint8_t *val);
|
||||
|
||||
int32_t lis2hh12_dev_boot_set(const stmdev_ctx_t *ctx, uint8_t val);
|
||||
int32_t lis2hh12_dev_boot_get(const stmdev_ctx_t *ctx, uint8_t *val);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t xda : 1;
|
||||
uint8_t yda : 1;
|
||||
uint8_t zda : 1;
|
||||
uint8_t zyxda : 1;
|
||||
uint8_t _xor : 1;
|
||||
uint8_t yor : 1;
|
||||
uint8_t zor : 1;
|
||||
uint8_t zyxor : 1;
|
||||
} lis2hh12_status_reg_t;
|
||||
int32_t lis2hh12_dev_status_get(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_status_reg_t *val);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LIS2HH12_HP_DISABLE = 0x00,
|
||||
LIS2HH12_HP_ON_INT_GEN_1 = 0x02,
|
||||
LIS2HH12_HP_ON_INT_GEN_2 = 0x01,
|
||||
LIS2HH12_HP_ON_BOTH_GEN = 0x03,
|
||||
} lis2hh12_xl_hp_path_t;
|
||||
int32_t lis2hh12_xl_filter_int_path_set(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_xl_hp_path_t val);
|
||||
int32_t lis2hh12_xl_filter_int_path_get(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_xl_hp_path_t *val);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LIS2HH12_BYPASSED = 0x00,
|
||||
LIS2HH12_FILT_HP = 0x02,
|
||||
LIS2HH12_FILT_LP = 0x01,
|
||||
} lis2hh12_xl_out_path_t;
|
||||
int32_t lis2hh12_xl_filter_out_path_set(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_xl_out_path_t val);
|
||||
int32_t lis2hh12_xl_filter_out_path_get(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_xl_out_path_t *val);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LIS2HH12_HP_ODR_DIV_50 = 0x00,
|
||||
LIS2HH12_HP_ODR_DIV_100 = 0x10,
|
||||
LIS2HH12_HP_ODR_DIV_9 = 0x20,
|
||||
LIS2HH12_HP_ODR_DIV_400 = 0x30,
|
||||
LIS2HH12_HP_ODR_DIV_50_REF_MD = 0x01,
|
||||
LIS2HH12_HP_ODR_DIV_100_REF_MD = 0x11,
|
||||
LIS2HH12_HP_ODR_DIV_9_REF_MD = 0x21,
|
||||
LIS2HH12_HP_ODR_DIV_400_REF_MD = 0x31,
|
||||
} lis2hh12_xl_hp_bw_t;
|
||||
int32_t lis2hh12_xl_filter_hp_bandwidth_set(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_xl_hp_bw_t val);
|
||||
int32_t lis2hh12_xl_filter_hp_bandwidth_get(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_xl_hp_bw_t *val);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LIS2HH12_LP_ODR_DIV_50 = 0,
|
||||
LIS2HH12_LP_ODR_DIV_100 = 1,
|
||||
LIS2HH12_LP_ODR_DIV_9 = 2,
|
||||
LIS2HH12_LP_ODR_DIV_400 = 3,
|
||||
} lis2hh12_xl_lp_bw_t;
|
||||
int32_t lis2hh12_xl_filter_low_bandwidth_set(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_xl_lp_bw_t val);
|
||||
int32_t lis2hh12_xl_filter_low_bandwidth_get(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_xl_lp_bw_t *val);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LIS2HH12_AUTO = 0x00,
|
||||
LIS2HH12_408Hz = 0x10,
|
||||
LIS2HH12_211Hz = 0x11,
|
||||
LIS2HH12_105Hz = 0x12,
|
||||
LIS2HH12_50Hz = 0x13,
|
||||
} lis2hh12_xl_filt_aa_bw_t;
|
||||
int32_t lis2hh12_xl_filter_aalias_bandwidth_set(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_xl_filt_aa_bw_t val);
|
||||
int32_t lis2hh12_xl_filter_aalias_bandwidth_get(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_xl_filt_aa_bw_t *val);
|
||||
|
||||
int32_t lis2hh12_xl_filter_reference_set(const stmdev_ctx_t *ctx,
|
||||
int16_t *val);
|
||||
int32_t lis2hh12_xl_filter_reference_get(const stmdev_ctx_t *ctx,
|
||||
int16_t *val);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LIS2HH12_SPI_4_WIRE = 0x00,
|
||||
LIS2HH12_SPI_3_WIRE = 0x01,
|
||||
} lis2hh12_sim_t;
|
||||
int32_t lis2hh12_spi_mode_set(const stmdev_ctx_t *ctx, lis2hh12_sim_t val);
|
||||
int32_t lis2hh12_spi_mode_get(const stmdev_ctx_t *ctx, lis2hh12_sim_t *val);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LIS2HH12_I2C_ENABLE = 0x00,
|
||||
LIS2HH12_I2C_DISABLE = 0x01,
|
||||
} lis2hh12_i2c_dis_t;
|
||||
int32_t lis2hh12_i2c_interface_set(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_i2c_dis_t val);
|
||||
int32_t lis2hh12_i2c_interface_get(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_i2c_dis_t *val);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LIS2HH12_DISABLE = 0x00,
|
||||
LIS2HH12_ENABLE = 0x01,
|
||||
} lis2hh12_auto_inc_t;
|
||||
int32_t lis2hh12_auto_increment_set(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_auto_inc_t val);
|
||||
int32_t lis2hh12_auto_increment_get(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_auto_inc_t *val);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t int1_drdy : 1;
|
||||
uint8_t int1_fth : 1;
|
||||
uint8_t int1_ovr : 1;
|
||||
uint8_t int1_ig1 : 1;
|
||||
uint8_t int1_ig2 : 1;
|
||||
uint8_t int1_inact : 1;
|
||||
} lis2hh12_pin_int1_route_t;
|
||||
int32_t lis2hh12_pin_int1_route_set(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_pin_int1_route_t val);
|
||||
int32_t lis2hh12_pin_int1_route_get(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_pin_int1_route_t *val);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LIS2HH12_PUSH_PULL = 0x00,
|
||||
LIS2HH12_OPEN_DRAIN = 0x01,
|
||||
} lis2hh12_pp_od_t;
|
||||
int32_t lis2hh12_pin_mode_set(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_pp_od_t val);
|
||||
int32_t lis2hh12_pin_mode_get(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_pp_od_t *val);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LIS2HH12_ACTIVE_HIGH = 0x00,
|
||||
LIS2HH12_ACTIVE_LOW = 0x01,
|
||||
} lis2hh12_pin_pol_t;
|
||||
int32_t lis2hh12_pin_polarity_set(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_pin_pol_t val);
|
||||
int32_t lis2hh12_pin_polarity_get(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_pin_pol_t *val);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t int2_drdy : 1;
|
||||
uint8_t int2_fth : 1;
|
||||
uint8_t int2_empty : 1;
|
||||
uint8_t int2_ig1 : 1;
|
||||
uint8_t int2_ig2 : 1;
|
||||
uint8_t int2_boot : 1;
|
||||
} lis2hh12_pin_int2_route_t;
|
||||
int32_t lis2hh12_pin_int2_route_set(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_pin_int2_route_t val);
|
||||
int32_t lis2hh12_pin_int2_route_get(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_pin_int2_route_t *val);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LIS2HH12_INT_PULSED = 0x00,
|
||||
LIS2HH12_INT_LATCHED = 0x01,
|
||||
} lis2hh12_lir_t;
|
||||
int32_t lis2hh12_pin_notification_set(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_lir_t val);
|
||||
int32_t lis2hh12_pin_notification_get(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_lir_t *val);
|
||||
typedef enum
|
||||
{
|
||||
LIS2HH12_IG1_OR_IG2_OR = 0x00,
|
||||
LIS2HH12_IG1_AND_IG2_OR = 0x01,
|
||||
LIS2HH12_IG1_OR_IG2_AND = 0x10,
|
||||
LIS2HH12_IG1_AND_IG2_AND = 0x11,
|
||||
} lis2hh12_pin_logic_t;
|
||||
int32_t lis2hh12_pin_logic_set(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_pin_logic_t val);
|
||||
int32_t lis2hh12_pin_logic_get(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_pin_logic_t *val);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LIS2HH12_RESET_MODE = 0x00,
|
||||
LIS2HH12_DECREMENT_MODE = 0x01,
|
||||
} lis2hh12_dcrm_t;
|
||||
int32_t lis2hh12_xl_trshld_mode_set(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_dcrm_t val);
|
||||
int32_t lis2hh12_xl_trshld_mode_get(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_dcrm_t *val);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t ig1_xlie : 1;
|
||||
uint16_t ig1_xhie : 1;
|
||||
uint16_t ig1_ylie : 1;
|
||||
uint16_t ig1_yhie : 1;
|
||||
uint16_t ig1_zlie : 1;
|
||||
uint16_t ig1_zhie : 1;
|
||||
uint16_t ig2_xlie : 1;
|
||||
uint16_t ig2_xhie : 1;
|
||||
uint16_t ig2_ylie : 1;
|
||||
uint16_t ig2_yhie : 1;
|
||||
uint16_t ig2_zlie : 1;
|
||||
uint16_t ig2_zhie : 1;
|
||||
} lis2hh12_xl_trshld_en_t;
|
||||
int32_t lis2hh12_xl_trshld_axis_set(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_xl_trshld_en_t val);
|
||||
int32_t lis2hh12_xl_trshld_axis_get(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_xl_trshld_en_t *val);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t ig1_xl : 1;
|
||||
uint16_t ig1_xh : 1;
|
||||
uint16_t ig1_yl : 1;
|
||||
uint16_t ig1_yh : 1;
|
||||
uint16_t ig1_zl : 1;
|
||||
uint16_t ig1_zh : 1;
|
||||
uint16_t ig1_ia : 1;
|
||||
uint16_t ig2_xl : 1;
|
||||
uint16_t ig2_xh : 1;
|
||||
uint16_t ig2_yl : 1;
|
||||
uint16_t ig2_yh : 1;
|
||||
uint16_t ig2_zl : 1;
|
||||
uint16_t ig2_zh : 1;
|
||||
uint16_t ig2_ia : 1;
|
||||
} lis2hh12_xl_trshld_src_t;
|
||||
int32_t lis2hh12_xl_trshld_src_get(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_xl_trshld_src_t *val);
|
||||
|
||||
int32_t lis2hh12_xl_trshld_set(const stmdev_ctx_t *ctx, uint8_t ig1_x,
|
||||
uint8_t ig1_y, uint8_t ig1_z,
|
||||
uint8_t ig2_xyz);
|
||||
int32_t lis2hh12_xl_trshld_get(const stmdev_ctx_t *ctx, uint8_t *ig1_x,
|
||||
uint8_t *ig1_y, uint8_t *ig1_z,
|
||||
uint8_t *ig2_xyz);
|
||||
|
||||
int32_t lis2hh12_xl_trshld_min_sample_set(const stmdev_ctx_t *ctx,
|
||||
uint8_t ig1_sam, uint8_t ig2_sam);
|
||||
int32_t lis2hh12_xl_trshld_min_sample_get(const stmdev_ctx_t *ctx,
|
||||
uint8_t *ig1_sam, uint8_t *ig2_sam);
|
||||
|
||||
int32_t lis2hh12_act_threshold_set(const stmdev_ctx_t *ctx, uint8_t val);
|
||||
int32_t lis2hh12_act_threshold_get(const stmdev_ctx_t *ctx, uint8_t *val);
|
||||
|
||||
int32_t lis2hh12_act_duration_set(const stmdev_ctx_t *ctx, uint8_t val);
|
||||
int32_t lis2hh12_act_duration_get(const stmdev_ctx_t *ctx, uint8_t *val);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LIS2HH12_6D_4D_DISABLE = 0x00,
|
||||
LIS2HH12_ENABLE_ON_IG1_6D = 0x01,
|
||||
LIS2HH12_ENABLE_ON_IG2_6D = 0x02,
|
||||
LIS2HH12_ENABLE_ON_IG1_4D = 0x11,
|
||||
LIS2HH12_ENABLE_ON_IG2_4D = 0x12,
|
||||
} lis2hh12_6d_mode_t;
|
||||
int32_t lis2hh12_6d_mode_set(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_6d_mode_t val);
|
||||
int32_t lis2hh12_6d_mode_get(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_6d_mode_t *val);
|
||||
|
||||
int32_t lis2hh12_fifo_watermark_set(const stmdev_ctx_t *ctx, uint8_t val);
|
||||
int32_t lis2hh12_fifo_watermark_get(const stmdev_ctx_t *ctx, uint8_t *val);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LIS2HH12_FIFO_OFF = 0x00,
|
||||
LIS2HH12_BYPASS_MODE = 0x10,
|
||||
LIS2HH12_FIFO_MODE = 0x11,
|
||||
LIS2HH12_STREAM_MODE = 0x12,
|
||||
LIS2HH12_STREAM_TO_FIFO_MODE = 0x13,
|
||||
LIS2HH12_BYPASS_TO_STREAM_MODE = 0x14,
|
||||
LIS2HH12_BYPASS_TO_FIFO_MODE = 0x17,
|
||||
} lis2hh12_fifo_md_t;
|
||||
int32_t lis2hh12_fifo_mode_set(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_fifo_md_t val);
|
||||
int32_t lis2hh12_fifo_mode_get(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_fifo_md_t *val);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t fss : 5;
|
||||
uint8_t empty : 1;
|
||||
uint8_t ovr : 1;
|
||||
uint8_t fth : 1;
|
||||
} lis2hh12_fifo_stat_t;
|
||||
int32_t lis2hh12_fifo_status_get(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_fifo_stat_t *val);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LIS2HH12_ST_DISABLE = 0x00,
|
||||
LIS2HH12_ST_POSITIVE = 0x01,
|
||||
LIS2HH12_ST_NEGATIVE = 0x02,
|
||||
} lis2hh12_xl_st_t;
|
||||
int32_t lis2hh12_xl_self_test_set(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_xl_st_t val);
|
||||
int32_t lis2hh12_xl_self_test_get(const stmdev_ctx_t *ctx,
|
||||
lis2hh12_xl_st_t *val);
|
||||
|
||||
/**
|
||||
*@}
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LIS2HH12_REGS_H */
|
||||
Reference in New Issue
Block a user