fifo.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. #include <stdio.h>
  2. #include "bma400.h"
  3. #define GRAVITY_EARTH (9.80665f) /* Earth's gravity in m/s^2 */
  4. /* Include 2 additional frames to account for
  5. * the next frame already being in the FIFO
  6. * and the sensor time frame
  7. */
  8. #define N_FRAMES 50
  9. /* 50 Frames result in 50*7, 350 bytes.
  10. * A few extra for the sensor time frame and
  11. * in case the next frame is available too.
  12. */
  13. #define FIFO_SIZE (357 + BMA400_FIFO_BYTES_OVERREAD)
  14. /* Delay to fill FIFO data At ODR of say 100 Hz,
  15. * 1 frame gets updated in 1/100 = 0.01s i.e. for
  16. * 50 frames we need 50 * 0.01 = 0.5 seconds delay
  17. */
  18. #define WAIT_PERIOD_MS 500
  19. void set_interface(enum bma400_intf intf, struct bma400_dev *dev);
  20. void delay_ms(uint32_t period);
  21. int8_t i2c_reg_write(void *intf_ptr, uint8_t i2c_addr, uint8_t reg_addr, uint8_t *reg_data, uint16_t length);
  22. int8_t i2c_reg_read(void *intf_ptr, uint8_t i2c_addr, uint8_t reg_addr, uint8_t *reg_data, uint16_t length);
  23. int8_t spi_reg_write(void *intf_ptr, uint8_t cs, uint8_t reg_addr, uint8_t *reg_data, uint16_t length);
  24. int8_t spi_reg_read(void *intf_ptr, uint8_t cs, uint8_t reg_addr, uint8_t *reg_data, uint16_t length);
  25. void print_rslt(int8_t rslt);
  26. float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width);
  27. float sensor_ticks_to_s(uint32_t sensor_time);
  28. int main(int argc, char const *argv[])
  29. {
  30. struct bma400_dev bma;
  31. struct bma400_sensor_data accel_data[N_FRAMES] = { 0 };
  32. struct bma400_fifo_data fifo_frame;
  33. struct bma400_device_conf fifo_conf;
  34. struct bma400_sensor_conf conf;
  35. int8_t rslt;
  36. uint16_t i;
  37. uint8_t fifo_buff[FIFO_SIZE] = { 0 };
  38. uint16_t accel_frames_req = N_FRAMES;
  39. float x, y, z, t;
  40. uint8_t n = 20; /* Read the FIFO 20 times */
  41. set_interface(BMA400_SPI_INTF, &bma);
  42. rslt = bma400_init(&bma);
  43. print_rslt(rslt);
  44. rslt = bma400_soft_reset(&bma);
  45. print_rslt(rslt);
  46. /* Select the type of configuration to be modified */
  47. conf.type = BMA400_ACCEL;
  48. /* Get the accelerometer configurations which are set in the sensor */
  49. rslt = bma400_get_sensor_conf(&conf, 1, &bma);
  50. print_rslt(rslt);
  51. /* Modify the desired configurations as per macros
  52. * available in bma400_defs.h file */
  53. conf.param.accel.odr = BMA400_ODR_100HZ;
  54. conf.param.accel.range = BMA400_2G_RANGE;
  55. conf.param.accel.data_src = BMA400_DATA_SRC_ACCEL_FILT_1;
  56. /* Set the desired configurations to the sensor */
  57. rslt = bma400_set_sensor_conf(&conf, 1, &bma);
  58. print_rslt(rslt);
  59. fifo_conf.type = BMA400_FIFO_CONF;
  60. rslt = bma400_get_device_conf(&fifo_conf, 1, &bma);
  61. print_rslt(rslt);
  62. fifo_conf.param.fifo_conf.conf_regs = BMA400_FIFO_X_EN | BMA400_FIFO_Y_EN | BMA400_FIFO_Z_EN
  63. | BMA400_FIFO_TIME_EN;
  64. fifo_conf.param.fifo_conf.conf_status = BMA400_ENABLE;
  65. rslt = bma400_set_device_conf(&fifo_conf, 1, &bma);
  66. print_rslt(rslt);
  67. rslt = bma400_set_power_mode(BMA400_NORMAL_MODE, &bma);
  68. print_rslt(rslt);
  69. while ((rslt == BMA400_OK) && n) {
  70. fifo_frame.data = fifo_buff;
  71. fifo_frame.length = FIFO_SIZE;
  72. bma.delay_ms(WAIT_PERIOD_MS);
  73. printf("Requested FIFO length : %d\r\n", fifo_frame.length);
  74. rslt = bma400_get_fifo_data(&fifo_frame, &bma);
  75. print_rslt(rslt);
  76. if (rslt != BMA400_OK) {
  77. printf("FIFO read failed\r\n");
  78. }
  79. printf("Available FIFO length : %d \r\n", fifo_frame.length);
  80. do {
  81. accel_frames_req = N_FRAMES;
  82. rslt = bma400_extract_accel(&fifo_frame, accel_data, &accel_frames_req, &bma);
  83. print_rslt(rslt);
  84. if (rslt != BMA400_OK) {
  85. printf("Accelerometer data extraction failed\r\n");
  86. }
  87. if (accel_frames_req) {
  88. printf("Extracted FIFO frames : %d \r\n", accel_frames_req);
  89. printf("Frame index, Ax[m/s2], Ay[m/s2], Az[m/s2]\r\n");
  90. for (i = 0; i < accel_frames_req; i++) {
  91. bma.delay_ms(10); /* Wait for 10ms as ODR is set to 100Hz */
  92. /* 12-bit accelerometer at range 2G */
  93. x = lsb_to_ms2(accel_data[i].x, 2, 12);
  94. y = lsb_to_ms2(accel_data[i].y, 2, 12);
  95. z = lsb_to_ms2(accel_data[i].z, 2, 12);
  96. printf("%d, %.2f, %.2f, %.2f\r\n", i, x, y, z);
  97. }
  98. }
  99. } while (accel_frames_req);
  100. if(fifo_frame.fifo_sensor_time) {
  101. t = sensor_ticks_to_s(fifo_frame.fifo_sensor_time);
  102. printf("FIFO sensor time : %.4fs\r\n", t);
  103. }
  104. if(fifo_frame.conf_change) {
  105. printf("FIFO configuration change: 0x%X\r\n", fifo_frame.conf_change);
  106. if (fifo_frame.conf_change & BMA400_FIFO_CONF0_CHANGE) {
  107. printf("FIFO data source configuration changed \r\n");
  108. }
  109. if (fifo_frame.conf_change & BMA400_ACCEL_CONF0_CHANGE) {
  110. printf("Accel filt1_bw configuration changed \r\n");
  111. }
  112. if (fifo_frame.conf_change & BMA400_ACCEL_CONF1_CHANGE) {
  113. printf("Accel odr/osr/range configuration changed \r\n");
  114. }
  115. }
  116. n--;
  117. }
  118. return 0;
  119. }
  120. void set_interface(enum bma400_intf intf, struct bma400_dev *dev)
  121. {
  122. switch (intf) {
  123. case BMA400_I2C_INTF:
  124. dev->intf_ptr = NULL; /* To attach your interface device reference */
  125. dev->delay_ms = delay_ms;
  126. dev->dev_id = BMA400_I2C_ADDRESS_SDO_LOW;
  127. dev->read = i2c_reg_read;
  128. dev->write = i2c_reg_write;
  129. dev->intf = BMA400_I2C_INTF;
  130. break;
  131. case BMA400_SPI_INTF:
  132. dev->intf_ptr = NULL; /* To attach your interface device reference */
  133. dev->dev_id = 0; /* Could be used to identify the chip select line. */
  134. dev->read = spi_reg_read;
  135. dev->write = spi_reg_write;
  136. dev->intf = BMA400_SPI_INTF;
  137. break;
  138. default:
  139. printf("Interface not supported.\r\n");
  140. }
  141. }
  142. void delay_ms(uint32_t period)
  143. {
  144. /* Wait for a period amount of ms*/
  145. }
  146. int8_t i2c_reg_write(void *intf_ptr, uint8_t i2c_addr, uint8_t reg_addr, uint8_t *reg_data, uint16_t length)
  147. {
  148. /* Write to registers using I2C. Return 0 for a successful execution. */
  149. return -1;
  150. }
  151. int8_t i2c_reg_read(void *intf_ptr, uint8_t i2c_addr, uint8_t reg_addr, uint8_t *reg_data, uint16_t length)
  152. {
  153. /* Read from registers using I2C. Return 0 for a successful execution. */
  154. return -1;
  155. }
  156. int8_t spi_reg_write(void *intf_ptr, uint8_t cs, uint8_t reg_addr, uint8_t *reg_data, uint16_t length)
  157. {
  158. /* Write to registers using SPI. Return 0 for a successful execution. */
  159. return -1;
  160. }
  161. int8_t spi_reg_read(void *intf_ptr, uint8_t cs, uint8_t reg_addr, uint8_t *reg_data, uint16_t length)
  162. {
  163. /* Read from registers using SPI. Return 0 for a successful execution. */
  164. return -1;
  165. }
  166. void print_rslt(int8_t rslt)
  167. {
  168. switch (rslt) {
  169. case BMA400_OK:
  170. /* Do nothing */
  171. break;
  172. case BMA400_E_NULL_PTR:
  173. printf("Error [%d] : Null pointer\r\n", rslt);
  174. break;
  175. case BMA400_E_COM_FAIL:
  176. printf("Error [%d] : Communication failure\r\n", rslt);
  177. break;
  178. case BMA400_E_DEV_NOT_FOUND:
  179. printf("Error [%d] : Device not found\r\n", rslt);
  180. break;
  181. case BMA400_E_INVALID_CONFIG:
  182. printf("Error [%d] : Invalid configuration\r\n", rslt);
  183. break;
  184. case BMA400_W_SELF_TEST_FAIL:
  185. printf("Warning [%d] : Self test failed\r\n", rslt);
  186. break;
  187. default:
  188. printf("Error [%d] : Unknown error code\r\n", rslt);
  189. break;
  190. }
  191. }
  192. float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width)
  193. {
  194. float half_scale = (float)(1 << bit_width) / 2.0f;
  195. return GRAVITY_EARTH * val * g_range / half_scale;
  196. }
  197. float sensor_ticks_to_s(uint32_t sensor_time)
  198. {
  199. return (float)sensor_time * 0.0000390625f;
  200. }