Davide Urbano
/
microSDreader
Working version. ADXL355 data saved to microSD.
Diff: adxl355.cpp
- Revision:
- 0:e2579e8d9b13
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/adxl355.cpp Fri Sep 29 12:53:50 2017 +0000 @@ -0,0 +1,659 @@ +/** + ****************************************************************************** + * @file adxl355.cpp + * @author DUR + * @version V1.0.0 + * @date 01-Aug-2017 + * @brief Library for adxl355 interface. + * + * @par Manual Reference Names: + * 1. "Low Noise, Low Drift, Low Power, 3-Axis MEMS Accelerometers + * ADXL354/ADXL355" + * 9/2016—Revision 0: Initial Version + * + * @par Document History: + * + * Version: 1.0.0 (01/08/2017) + * ---------------------------------------------------------------------------- + * Author: DUR + * First release. + * ---------------------------------------------------------------------------- + * +@verbatim +================================================================================ + ##### How to use this file ##### +================================================================================ +Questa libreria è stata redatta per poter gestire ad alto livello il sensore di +accelerazione ad uscita digitale a 20 bit della Analog Devices ADXL355, dotato +di un bus SPI/I2C per la comunicazione, insieme ad un pin per la segnalazione di +nuovi dati pronti e ben 2 pin di interrupt che sono configurabili per scattare a +seguito di ben precisi eventi interni. +Perché si possa utilizzare questa libreria su di una qualunque piattaforma +hardware, la seguente funzione dovrà poi essere associata a quella di basso +livello: + (+) uint16_t adxl355_spi_transfer(uint8_t * rbuffer, uint32_t rlen) + < trasferimento su bus SPI >; +Nella presente versione della libreria, sono state fatte le seguenti scelte +progettuali: + (+) è stato scelto di utilizzare il bus SPI piuttosto che il bus I2C per la + comunicazione da e verso l'host; + (+) è stato scelto l'utilizzo della sincronizzazione interna (EXT_SYNC = 0x00). +L'accelerometro viene configurato dall'utente, per mezzo di una struttura dati +adxl355_handler, con la quale è possibile definire un setting di parametri +applicativi in base alle differenti esigenze. Nel suo utilizzo è importante tenere +a mente le seguenti osservzioni: + (i) dopo avere lanciato il comando di reset software (adxl355_sw_reset) il + sensore deve essere nuovamente inizializzato (adxl355_init); + (i) per effettuare il self test, il sensore deve già essere in modalità di + acquisizione; il camando adxl355_self_test(true) dovrà essere lanciato + più volte perché ad ogni invocazione del metodo viene appicata una + specifica accelerazione all'interno, e quella che si andrà a rilevare + sarà proprio la differenza tra i valori in g rilevati tra due invocazioni + successive, e che dovrà rispettare i valori imposti dal datasheet. +@endverbatim + + ****************************************************************************** +@attention +<h2><center>© COPYRIGHT(c) 2014 TD Group</center></h2> + +The information contained herein is property of TD Group S.p.A. + +Licensees are granted free, non-transferable use of the information. NO +WARRANTY of ANY KIND is provided. This heading must NOT be removed from +the file. + ****************************************************************************** + */ + +#define ADXL355_VERSION 1 +#define ADXL355_REVISION 0 +#define ADXL355_PATCH 0 + + +/* Includes ------------------------------------------------------------------*/ + +/** @brief Add ONLY the header of THIS source file and not others. + */ + +#include "adxl355.h" + +/** @addtogroup FILE_FUNCTIONS + * @{ + */ + + + +/* Private function prototypes -----------------------------------------------*/ +/* Ricava da una maschera di bit, la posizione del primo bit della maschera stessa */ +static uint8_t adxl355_get_bit_position(uint8_t gbp_mask); +/* Setting dei parametri */ +static uint16_t adxl355_set_parameter(uint8_t sp_reg, uint8_t sp_mask_data, uint8_t sp_data); +/* Lettura valore accelerazione lungo asse X, Y e Z */ +static uint16_t adxl355_read_acc_value(adxl355_handler *adxl_acc); +/* Lettura valore di temperatura */ +static uint16_t adxl355_read_temp_value(adxl355_handler *adxl_temp); + + +/* Private variables ---------------------------------------------------------*/ +/* Definisce in ogni momento quali misure sono attive */ +static adxl355_measure_enabled adxl_measure_on; + + +/* Exported variables --------------------------------------------------------*/ + + +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup Group1 Private_Functions + * @brief Function used only in this file and NOT visible to the rest of the + * code. + * @{ + */ + + +/** + * @brief Ricava da una maschera di bit, la posizione del primo bit della maschera + * stessa. + * @note No one. + * @param gbp_mask maschera di bit + * @retval uint8_t posizione del primo bit nella maschera + * @todo Nothing. + * @warning No one. + */ +static uint8_t adxl355_get_bit_position(uint8_t gbp_mask) +{ + uint8_t gbp_index; + + for(gbp_index = 0; gbp_index < 8; gbp_index++) + { + if(((gbp_mask>>gbp_index) & 0x01) != 0) + { + break; + }else{} + } + + return gbp_index; +} + + +/** + * @brief Funzione per la scrittura di un parametro su di un registro dell'accelerometro. + * @note No one. + * @param sp_reg indirizzo del registro da settare + * @param sp_mask_data posizione del/i bit da settare sotto forma di maschera + * @param sp_data valore del/i bit da settare + * @retval uint16_t errore restituito dal metodo (se 0, tutto ok) + * @todo Nothing. + * @warning No one. + */ +static uint16_t adxl355_set_parameter(uint8_t sp_reg, uint8_t sp_mask_data, uint8_t sp_data) +{ + uint16_t adxl_sp_error = 0u; + uint8_t adxl_sp_data[2]; + + /* Lettura del registro */ + adxl_sp_data[0] = (uint8_t)((sp_reg << 1) | ADXL355_READ_BYTE_MASK); + adxl_sp_data[1] = 0x00; + if(adxl355_spi_transfer((uint8_t*)&adxl_sp_data, 2) == 0) + { + adxl_sp_data[0] = (uint8_t)((sp_reg << 1) & ADXL355_WRITE_BYTE_MASK); + adxl_sp_data[1] &= (uint8_t)~sp_mask_data; + adxl_sp_data[1] |= (uint8_t)(sp_data << (adxl355_get_bit_position(sp_mask_data))); + /* Scrittura del nuovo valore */ + if(adxl355_spi_transfer((uint8_t*)&adxl_sp_data, 2) == 0) + {} + else + { + adxl_sp_error = (uint16_t)__LINE__;//ERRORE SCRITTURA REGISTRO + } + } + else + { + adxl_sp_error = (uint16_t)__LINE__;//ERRORE LETTURA REGISTRO + } + + return adxl_sp_error; +} + + +/** + * @brief Funzione di lettura del dato grezzo di accelerazione lungo gli assi + * X, Y e Z dell'accelerometro. + * @note No one. + * @param adxl_acc puntatore all'handler dell'accelerometro + * @retval uint16_t errore restituito dal metodo (se 0, tutto ok) + * @todo No one. + * @warning No one. + */ +static uint16_t adxl355_read_acc_value(adxl355_handler *adxl_acc) +{ + uint16_t adxl_read_acc_error = 0u; + uint8_t adxl_read_acc_data[10]; + /* Azzeramento buffer dati SPI */ + memset(adxl_read_acc_data, 0x00, 10); + adxl_read_acc_data[0u] = (uint8_t)((ADXL355_XDATA3<<1) | ADXL355_READ_BYTE_MASK); + + if(adxl355_spi_transfer((uint8_t*)&adxl_read_acc_data, 10) == 0) + { + adxl_acc->raw_acc_x_value = 0u; + adxl_acc->raw_acc_x_value = (adxl_read_acc_data[1]<<16u) | (adxl_read_acc_data[2]<<8u) | (adxl_read_acc_data[3]); + adxl_acc->raw_acc_x_value = (adxl_acc->raw_acc_x_value>>4u) & ADXL355_20_BIT_MASK; + + adxl_acc->raw_acc_y_value = 0u; + adxl_acc->raw_acc_y_value = (adxl_read_acc_data[4]<<16u) | (adxl_read_acc_data[5]<<8u) | (adxl_read_acc_data[6]); + adxl_acc->raw_acc_y_value = (adxl_acc->raw_acc_y_value>>4u) & ADXL355_20_BIT_MASK; + + adxl_acc->raw_acc_z_value = 0u; + adxl_acc->raw_acc_z_value = (adxl_read_acc_data[7]<<16u) | (adxl_read_acc_data[8]<<8u) | (adxl_read_acc_data[9]); + adxl_acc->raw_acc_z_value = (adxl_acc->raw_acc_z_value>>4u) & ADXL355_20_BIT_MASK; + } + else + { + adxl_read_acc_error = (uint16_t)__LINE__;//ERRORE LETTURA DATI ACCELERAZIONE + } + + return adxl_read_acc_error; +} + + + +/** + * @brief Funzione di lettura del dato grezzo di temperatura fornito dall'accelerometro. + * @note No one. + * @param adxl_temp puntatore all'handler dell'accelerometro + * @retval uint16_t errore restituito dal metodo (se 0, tutto ok) + * @todo No one. + * @warning No one. + */ +static uint16_t adxl355_read_temp_value(adxl355_handler *adxl_temp) +{ + uint16_t adxl_read_temp_error = 0u; + uint8_t adxl_read_temp_data[3]; + /* Azzeramento buffer dati SPI */ + memset(adxl_read_temp_data, 0x00, 3); + adxl_read_temp_data[0u] = (uint8_t)((ADXL355_TEMP2<<1) | ADXL355_READ_BYTE_MASK); + + if(adxl355_spi_transfer((uint8_t*)&adxl_read_temp_data, 3) == 0) + { + adxl_temp->raw_temp_value = 0u; + adxl_temp->raw_temp_value = (adxl_read_temp_data[1]<<8u) | adxl_read_temp_data[2]; + adxl_temp->raw_temp_value &= ADXL355_12_BIT_MASK; + } + else + { + adxl_read_temp_error = (uint16_t)__LINE__;//ERRORE LETTURA DATI ACCELERAZIONE + } + + return adxl_read_temp_error; +} + + + + + + +/** + * @} + */ + + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup Group2 Exported_Functions + * @brief Functions used in this file and also visible to the rest of the + * code. + * @{ + */ + + + +/** +* @brief Funzione che restituisce i parametri identificativi del driver. +* @note No one. +* @param adxl355_driver_version puntatore all'identificatore di versione del driver +* @param adxl355_driver_revision puntatore all'identificatore di revisione del driver +* @param adxl355_driver_patch puntatore all'identificatore di patch del driver +* @retval No one. +* @todo No one. +* @warning No one. +*/ +void adxl355_driver_info(uint8_t * adxl355_driver_version, uint8_t * adxl355_driver_revision, uint8_t * adxl355_driver_patch) +{ + *adxl355_driver_version = ADXL355_VERSION; + *adxl355_driver_revision = ADXL355_REVISION; + *adxl355_driver_patch = ADXL355_PATCH; +} + + +/** +* @brief Funzione che restituisce l'ID dell'accelerometro. +* @note No one. +* @param adxl355_device_id puntatore all'identificatore del device +* @retval uint16_t errore restituito dal metodo (se 0, tutto ok) +* @todo No one. +* @warning No one. +*/ +uint16_t adxl355_who_am_i(uint8_t * adxl355_device_id) +{ + uint16_t adxl_whoami_error = 0u; + uint8_t adxl_whoami_data[2]; + + /* Lettura del registro */ + adxl_whoami_data[0] = (uint8_t)((ADXL355_PARTID << 1) | ADXL355_READ_BYTE_MASK); + adxl_whoami_data[1] = 0x00; + if(adxl355_spi_transfer((uint8_t*)&adxl_whoami_data, 2) == 0) + { + *adxl355_device_id = adxl_whoami_data[1]; + } + else + { + adxl_whoami_error = (uint16_t)__LINE__;//ERRORE LETTURA ID + } + + return adxl_whoami_error; +} + + +/** + * @brief Funzione di inizializzazione dell'accelerometro. + * @note No one. + * @param adxl_init_handler puntatore all'handler dell'accelerometro + * @retval uint16_t errore restituito dal metodo (se 0, tutto ok) + * @todo No one. + * @warning No one. + */ +uint16_t adxl355_init(adxl355_handler *adxl_init_handler) +{ + uint16_t adxl_init_error = 0u; + uint8_t adxl_init_state = 0u; + + switch(adxl_init_state) + { + case 0:/* Configurazione range di misura */ + if(0u == adxl355_set_parameter(ADXL355_RANGE, ADXL355_RANGE_MASK, (uint8_t)adxl_init_handler->measure_range)) + {} + else + { + adxl_init_error = (uint16_t)__LINE__;//ERRORE SETTING RANGE DI MISURA + break; + } + + + case 1:/* Configurazione output data rate */ + if(0u == adxl355_set_parameter(ADXL355_FILTER, ADXL355_ODR_MASK, (uint8_t)adxl_init_handler->out_data_rate)) + {} + else + { + adxl_init_error = (uint16_t)__LINE__;//ERRORE SETTING OUTPUT DATA RATE + break; + } + + + case 2:/* Configurazione polarità interrupt */ + if((adxl_init_handler->int1_pin == NULL) && + (adxl_init_handler->int2_pin == NULL)){}//Se i pin non sono configurati, è inutile configurare la polarità degli interrupt + else + { + if(0u == adxl355_set_parameter(ADXL355_RANGE, ADXL355_ODR_MASK, (adxl_init_handler->int_config.int_act_low==true) ? 0:1)) + {} + else + { + adxl_init_error = (uint16_t)__LINE__;//ERRORE SETTING POLARITA' INTERRUPT + break; + } + } + + + case 3:/* Configurazione interrupt 1 */ + if(adxl_init_handler->int1_pin == NULL){}//Se il pin non è configurato, è inutile configurare il relativo interrupt + else + { + if(0u == adxl355_set_parameter(ADXL355_INT_MAP, ADXL355_INT_1_MASK, (uint8_t)adxl_init_handler->int_config.int1_evt)) + {} + else + { + adxl_init_error = (uint16_t)__LINE__;//ERRORE SETTING EVENTO ASSOCIATO AD INTERRUPT 1 + break; + } + } + + + case 4:/* Configurazione interrupt 2 */ + if(adxl_init_handler->int2_pin == NULL){}//Se il pin non è configurato, è inutile configurare il relativo interrupt + else + { + if(0u == adxl355_set_parameter(ADXL355_INT_MAP, ADXL355_INT_2_MASK, (uint8_t)adxl_init_handler->int_config.int2_evt)) + {} + else + { + adxl_init_error = (uint16_t)__LINE__;//ERRORE SETTING EVENTO ASSOCIATO AD INTERRUPT 2 + break; + } + } + + + case 5:/* Stop di tutte le possibili misure */ + if(0u == adxl355_start_acquisition(adxl355_none)) + {} + else + { + adxl_init_error = (uint16_t)__LINE__;//ERRORE SETTING STOP MISURE + break; + } + + + case 6:/* Self-test disabilitato */ + if(0u == adxl355_self_test(false)) + {} + else + { + adxl_init_error = (uint16_t)__LINE__;//ERRORE DISABILITAZIONE SELF-TEST + break; + } + + + default: + break; + } + + return adxl_init_error; +} + + + +/** + * @brief Funzione di start/stop delle acquisizioni. + * @note No one. + * @param adxl_start misura/e da avviare + * @retval uint16_t errore restituito dal metodo (se 0, tutto ok) + * @todo No one. + * @warning No one. + */ +uint16_t adxl355_start_acquisition(adxl355_measure_enabled adxl_start) +{ + uint16_t adxl_start_error = 0u; + uint8_t adxl_start_data; + + switch(adxl_start) + { + case 0://Solo accelerazione + adxl_start_data = 0x02; + break; + + case 1://Entrambe le misure (accelerazione e temperatura) + adxl_start_data = 0x00; + break; + + case 2://Nessuna misura (mette in standby il sensore) + adxl_start_data = 0x03; + break; + + default: + break; + } + + if(0u == adxl355_set_parameter(ADXL355_POWER_CTL, ADXL355_MEAS_MASK, adxl_start_data)) + { + adxl_measure_on = adxl_start; + } + else + { + adxl_start_error = (uint16_t)__LINE__;//ERRORE SETTING RANGE DI MISURA + } + + return adxl_start_error; +} + + + +/** + * @brief Funzione per la lettura del/i dato/i acquisito/i. + * @note No one. + * @param adxl_data_handler puntatore all'handler dell'accelerometro + * @retval uint16_t errore restituito dal metodo (se 0, tutto ok) + * @todo No one. + * @warning No one. + */ +uint16_t adxl355_get_data(adxl355_handler *adxl_data_handler) +{ + uint16_t adxl_data_error = 0u; + + if((adxl_measure_on == adxl355_acc) || (adxl_measure_on == adxl355_both)) + { /* Lettura accelerazione */ + if(adxl355_read_acc_value(adxl_data_handler) == 0u) + { + if(adxl_measure_on == adxl355_both) + { /* Lettura temperatura */ + if(adxl355_read_temp_value(adxl_data_handler) == 0u) + {} + else + { + adxl_data_error = (uint16_t)__LINE__;//ERRORE LETTURA MISURA TEMPERATURA + } + } + else{} + + } + else + { + adxl_data_error = (uint16_t)__LINE__;//ERRORE LETTURA MISURA ACCELERAZIONE + } + }else{} + + return adxl_data_error; +} + + + +/** + * @brief Funzione che restituisce il valore grezzo di accelerazione lungo l'asse X. + * @note No one. + * @param adxl_xdata_handler puntatore all'handler dell'accelerometro + * @retval uint32_t valore grezzo accelerazione + * @todo No one. + * @warning No one. + */ +uint32_t adxl355_raw_x_acc(adxl355_handler *adxl_xdata_handler) +{ + return adxl_xdata_handler->raw_acc_x_value; +} + + + +/** + * @brief Funzione che restituisce il valore grezzo di accelerazione lungo l'asse Y. + * @note No one. + * @param adxl_ydata_handler puntatore all'handler dell'accelerometro + * @retval uint32_t valore grezzo accelerazione + * @todo No one. + * @warning No one. + */ +uint32_t adxl355_raw_y_acc(adxl355_handler *adxl_ydata_handler) +{ + return adxl_ydata_handler->raw_acc_y_value; +} + + + +/** + * @brief Funzione che restituisce il valore grezzo di accelerazione lungo l'asse Z. + * @note No one. + * @param adxl_zdata_handler puntatore all'handler dell'accelerometro + * @retval uint32_t valore grezzo accelerazione + * @todo No one. + * @warning No one. + */ +uint32_t adxl355_raw_z_acc(adxl355_handler *adxl_zdata_handler) +{ + return adxl_zdata_handler->raw_acc_z_value; +} + + + +/** + * @brief Funzione che restituisce il valore grezzo di temperatura. + * @note No one. + * @param adxl_tdata_handler puntatore all'handler dell'accelerometro + * @retval uint16_t valore grezzo temperatura + * @todo No one. + * @warning No one. + */ +uint16_t adxl355_raw_temp(adxl355_handler *adxl_tdata_handler) +{ + return adxl_tdata_handler->raw_temp_value; +} + + + +/** + * @brief Funzione per il reset sw. + * @note No one. + * @param No one. + * @retval uint16_t errore restituito dal metodo (se 0, tutto ok) + * @todo No one. + * @warning No one. + */ +uint16_t adxl355_sw_reset(void) +{ + uint16_t adxl_swres_error = 0u; + uint8_t adxl_swres_data[2]; + + /* Lettura del registro */ + adxl_swres_data[0] = (uint8_t)((ADXL355_RESET << 1) & ADXL355_WRITE_BYTE_MASK); + adxl_swres_data[1] = ADXL355_RESET_CODE; + if(adxl355_spi_transfer((uint8_t*)&adxl_swres_data, 2) == 0) + {} + else + { + adxl_swres_error = (uint16_t)__LINE__;//ERRORE RESET ACCELEROMETRO + } + + return adxl_swres_error; +} + + + +/** + * @brief Funzione per il self-test. + * @note Questo metodo va utilizzato lanciandolo ponendo a true adxl_start + * ad acquisizione in corso; in questa modalità il metodo va lanciato + * diverse volte in modo che si possa registrare la variazione di + * accelerazione sui 3 assi che deve essere, secondo datasheet: + * [X]: 0.3g + * [Y]: 0.3g + * [Z]: 1.5g + * In modalità self-test, il sensore non registra alcuna accelerazione + * esterna; ponendo a false adxl_start, il sensore termina il self-test + * e ritorna in modalità normale di funzionamento. + * @param adxl_start booleano per avviare/fermare il self test + * @retval uint16_t errore restituito dal metodo (se 0, tutto ok) + * @todo No one. + * @warning No one. + */ +uint16_t adxl355_self_test(bool adxl_start) +{ + uint16_t adxl_st_error = 0u; + static uint8_t adxl_st2_val = 0u; + + if(adxl_start == true) + { + adxl_measure_on = adxl355_acc; + if(0u == adxl355_set_parameter(ADXL355_SELF_TEST, ADXL355_SELF_TEST_MASK, (adxl_st2_val<<1)|ADXL355_SELF_TEST_ENABLE )) + { + if(adxl_st2_val == 0u) adxl_st2_val = 1u; + else adxl_st2_val = 0u; + } + else + { + adxl_st_error = (uint16_t)__LINE__;//ERRORE AVVIO SELF-TEST + } + } + else + { + if(0u == adxl355_set_parameter(ADXL355_SELF_TEST, ADXL355_SELF_TEST_MASK, ADXL355_SELF_TEST_DISABLE)) + { + adxl_st2_val = 0u; + } + else + { + adxl_st_error = (uint16_t)__LINE__;//ERRORE STOP SELF-TEST + } + } + + return adxl_st_error; +} + + + +/** + * @} + */ + + + + /** + * @} + */ + +/************************ (C) COPYRIGHT TD Group *****END OF FILE**************/ + +