Advertisement
Guest User

Untitled

a guest
Oct 19th, 2017
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.01 KB | None | 0 0
  1. /* Includes ------------------------------------------------------------------*/
  2. #include <string.h>
  3.  
  4. #include "stm32f0xx_hal.h"
  5. #include "globals.h"
  6. #include "sensors.h"
  7.  
  8. static void Handle_LSM6DSL_Read(void);
  9. static void Handle_LIS3MDL_Read(void);
  10. /*These are the functions for interfacing with the SPI sensors*/
  11. //LIS3MDL
  12. static const uint8_t LIS3MDL_Config_[]={0x60,0x02,0x00,0x00,0x00,0x40};/*Write registers 0x20 (0x40-Address incr+0x20=0x60) to 0x24*/
  13. static const uint8_t LIS3MDL_Bytes=6;/*^ sets 1khz update with BDU and little endianess, +-4Guass sensor range*/
  14. static const uint8_t LIS3MDL_Read_Bytes[]={0xE8,0x00,0x00,0x00,0x00,0x00,0x00};
  15. static const uint8_t LIS3MDL_Read_Transaction=7;
  16.  
  17. #define LIS3_CS_LOW HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2,GPIO_PIN_RESET)
  18. #define LIS3_CS_HIGH HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2,GPIO_PIN_SET)
  19. //LSM6DSL
  20. static const uint8_t LSM6DSL_Config_One[]={0x0D,0x03};/*Single byte to set up DRDY on INT1 pin*/
  21. static const uint8_t LSM6DSL_Config_One_Bytes=2;
  22. static const uint8_t LSM6DSL_Config_Two[]={0x10,0xAE,0xAC,0x44,0x06,0x00,0x03};
  23. /*6.66khz output with 1.5khz analogue front end +-8G, 6.66khz +-2kdbps, BDU addr inc, LPF on gyro, no ST, 937hz gyro front end*/
  24. static const uint8_t LSM6DSL_Config_Two_Bytes=7;
  25. static const uint8_t LSM6DSL_Read_Bytes[]={0xA0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
  26. static const uint8_t LSM6DSL_Read_Transaction=15;/*One byte to config, then fourteen bytes to read*/
  27.  
  28. #define LSM6_CS_LOW HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3,GPIO_PIN_RESET);
  29. #define LSM6_CS_HIGH HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3,GPIO_PIN_SET);
  30. //Buffers which are used to store the raw data
  31. volatile uint8_t rawbuff[15]={};/*This is used for all the sensors for the dma, memcpy is then used to copy to main data buffer in callback function*/
  32. volatile uint8_t* LSM6DSL_datacallback=NULL;
  33. volatile uint8_t* LIS3MDL_datacallback=NULL;
  34. volatile uint8_t LIS3MDL_Flag=0,LSM6DSL_Flag=0;
  35.  
  36. uint8_t Sensors=0;          /*Used to hold flags for the sensors*/
  37. void (* volatile handlercallback)(void);/*Callback function pointer*/
  38.  
  39. //These four functions are used to interface
  40.  
  41. /*This function configures the LIS3MDL magnetometer*/
  42. uint8_t LIS3MDL_Config() {
  43.     LIS3_CS_LOW;
  44.     uint8_t status=0;
  45.     status=HAL_SPI_Transmit_DMA(&hspi1, LIS3MDL_Config_, LIS3MDL_Bytes);
  46.     if(status) {
  47.         LIS3_CS_HIGH;
  48.         return status;      /*An error*/
  49.     }
  50.     while(hspi1.State != HAL_SPI_STATE_READY);/*Wait for transmit to be completed*/
  51.     LIS3_CS_HIGH;
  52.     uint8_t device_id=0xCF;
  53.     asm volatile("dmb");
  54.     LIS3_CS_LOW;
  55.     status=HAL_SPI_Transmit_DMA(&hspi1, &device_id, 1);
  56.     if(status) {
  57.         LIS3_CS_HIGH;
  58.         return status;      /*An error*/
  59.     }
  60.     while(hspi1.State != HAL_SPI_STATE_READY);/*Wait for transmit to be completed*/
  61.     status=HAL_SPI_Receive_DMA(&hspi1, &device_id, 1);
  62.     if(status) {
  63.         LIS3_CS_HIGH;
  64.         return status;      /*An error*/
  65.     }
  66.     while(hspi1.State != HAL_SPI_STATE_READY);/*Wait for receive to be completed*/
  67.     LIS3_CS_HIGH;
  68.     if(device_id==0x3D)     /*Sensor repies with the correct ID byte*/
  69.         return 0;
  70.     else
  71.         return 1;
  72. }
  73.  
  74. /*This function configures the LIS3MDL magnetometer*/
  75. uint8_t LSM6DSL_Config() {
  76.     LSM6_CS_LOW;
  77.     uint8_t status=0;
  78.     status=HAL_SPI_Transmit_DMA(&hspi1, LSM6DSL_Config_One, LSM6DSL_Config_One_Bytes);
  79.     if(status) {
  80.         LSM6_CS_HIGH;
  81.         return status;      /*An error*/
  82.     }
  83.     while(hspi1.State != HAL_SPI_STATE_READY);/*Wait for transmit to be completed*/
  84.     LSM6_CS_HIGH;
  85.     asm volatile("dmb");
  86.     LSM6_CS_LOW;
  87.     status=HAL_SPI_Transmit_DMA(&hspi1, LSM6DSL_Config_Two, LSM6DSL_Config_Two_Bytes);
  88.     if(status) {
  89.         LSM6_CS_HIGH;
  90.         return status;      /*An error*/
  91.     }
  92.     while(hspi1.State != HAL_SPI_STATE_READY);/*Wait for transmit to be completed*/
  93.     LSM6_CS_HIGH;
  94.     uint8_t device_id=0x8F;
  95.     asm volatile("dmb");
  96.     LSM6_CS_LOW;
  97.     asm volatile("dmb");
  98.     status=HAL_SPI_Transmit_DMA(&hspi1, &device_id, 1);
  99.     if(status) {
  100.         LSM6_CS_HIGH;
  101.         return status;      /*An error*/
  102.     }
  103.     while(hspi1.State != HAL_SPI_STATE_READY);/*Wait for transmit to be completed*/
  104.     status=HAL_SPI_Receive_DMA(&hspi1, &device_id, 1);
  105.     if(status) {
  106.         LSM6_CS_HIGH;
  107.         return status;      /*An error*/
  108.     }
  109.     while(hspi1.State != HAL_SPI_STATE_READY);/*Wait for receive to be completed*/
  110.     LSM6_CS_HIGH;
  111.     if(device_id==0x6A)     /*Sensor repies with the correct ID byte*/
  112.         return 0;
  113.     else
  114.         return 1;
  115. }
  116.  
  117. uint8_t LSM6DSL_Read(lsm6sensortype* receivedata, uint32_t timestamp) {
  118.     receivedata->updateflag=1;  /*This can be used to check for an ongoing update, but it isnt thread safe, be careful where it is checked from*/
  119.     receivedata->timestamp=timestamp;
  120.     LSM6_CS_LOW;
  121.     LSM6DSL_datacallback=(uint8_t*)receivedata;
  122.     void (* volatile handlercallback_)(void);
  123.     handlercallback_=handlercallback;
  124.     handlercallback=Handle_LSM6DSL_Read;//tx/rx uses rx complete callback handling
  125.     HAL_StatusTypeDef her=HAL_SPI_TransmitReceive_DMA(&hspi1, LSM6DSL_Read_Bytes, rawbuff, LSM6DSL_Read_Transaction);
  126.     if(her==HAL_BUSY) {//The tx/rx
  127.         handlercallback=handlercallback_;//Restore previous value
  128.         LSM6DSL_Flag=1;//Flag this so next transaction can begin immediatly afterwards
  129.         her=HAL_OK;
  130.     }
  131.     else if(her==HAL_OK)
  132.         LSM6DSL_Flag=0;
  133.     return her;
  134. }
  135.  
  136. uint8_t LIS3MDL_Read(lis3sensortype* receivedata, uint32_t timestamp) {
  137.     receivedata->updateflag=1;  /*This can be used to check for an ongoing update, but it isnt thread safe, be careful where it is checked from*/
  138.     receivedata->timestamp=timestamp;
  139.     LIS3MDL_datacallback=(uint8_t*)receivedata;
  140.     if(!LIS3MDL_Flag) {
  141.         LIS3MDL_Flag=1;//This is flagged and will be handled by the next LSM6DSL callback (as the two sensors share the bus and LSM6DSM is much faster)
  142.         return 0;
  143.     }
  144.     else
  145.         return 1;           /*This is an error*/
  146. }
  147.  
  148. uint8_t Sensors_CheckChanged(samplestype* data) {
  149.     static samplestype internalsample;
  150.     static uint8_t unchanged;
  151.     uint8_t Fault=0;
  152.     if(!memcmp(data,&internalsample,sizeof(sensortype)*2))
  153.         Fault|=(1<<LSM6);
  154.     if(!memcmp(&(data->mag),&(internalsample.mag),sizeof(sensortype)))
  155.         Fault|=(1<<LIS3);
  156.     memcpy(&internalsample,data,sizeof(samplestype));
  157.     if(Fault)
  158.         unchanged++;
  159.     else
  160.         unchanged=0;
  161.     if(unchanged>30)            /*30 consecutive calls with unchanged data leads to Fault condition*/
  162.         unchanged=30;
  163.     else
  164.         Fault=0;
  165.     return Fault;
  166. }
  167.  
  168. //Used to check what the status is without using globals
  169. uint8_t LIS3MDL_Being_Read(void) {
  170.     return LIS3MDL_Flag;
  171. }
  172.  
  173. //user function for HAL
  174. void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) {
  175.     if(handlercallback)
  176.         handlercallback();
  177. }
  178.  
  179. //Internal functions
  180.  
  181. /* This is used as a callback function to handle read of LSM6DSL */
  182. static void Handle_LSM6DSL_Read(void) {
  183.     if(LSM6DSL_datacallback) {
  184.         memcpy(LSM6DSL_datacallback,&(rawbuff[1]),14);//Copy 14 bytes of raw data, ignoring the first byte which was address
  185.         ((lsm6sensortype*)LSM6DSL_datacallback)->updateflag=0;/*Clear ongoing update - isnt thread safe, be careful where it is checked from*/
  186.     }
  187.     LSM6_CS_HIGH;           /*Deselect the sensor*/
  188.     if(LIS3MDL_Flag && !LSM6DSL_Flag) { /*There is some LIS3MDL data ready*/
  189.         LIS3_CS_LOW;
  190.         handlercallback=Handle_LIS3MDL_Read;
  191.         if(HAL_SPI_TransmitReceive_DMA(&hspi1, LIS3MDL_Read_Bytes, rawbuff, LIS3MDL_Read_Transaction)) {
  192.             handlercallback=NULL;
  193.             LIS3_CS_HIGH;
  194.         }
  195.     }
  196.     else if(LSM6DSL_Flag) {
  197.         asm volatile("dmb");
  198.         LSM6_CS_LOW;
  199.         HAL_SPI_TransmitReceive_DMA(&hspi1, LSM6DSL_Read_Bytes, rawbuff, LSM6DSL_Read_Transaction);
  200.         LSM6DSL_Flag=0;     //No queued request
  201.     }
  202.     else
  203.         handlercallback=NULL;
  204. }
  205.  
  206. static void Handle_LIS3MDL_Read(void) {
  207.     if(LIS3MDL_datacallback) {
  208.         memcpy(LIS3MDL_datacallback,&(rawbuff[1]),6);//Copy 6 bytes of raw data, ignoring the first byte which was address
  209.         ((lis3sensortype*)LIS3MDL_datacallback)->updateflag=0;/*Clear ongoing update - isnt thread safe, be careful where it is checked from*/
  210.     }
  211.     LIS3_CS_HIGH;
  212.     LIS3MDL_Flag=0;
  213.     if(LSM6DSL_Flag) {
  214.         LSM6_CS_LOW;
  215.         handlercallback=Handle_LSM6DSL_Read;
  216.         HAL_SPI_TransmitReceive_DMA(&hspi1, LSM6DSL_Read_Bytes, rawbuff, LSM6DSL_Read_Transaction);
  217.         LSM6DSL_Flag=0;     //No queued request
  218.     }
  219.     else
  220.         handlercallback=NULL;
  221. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement