Advertisement
7134956

Untitled

May 5th, 2024
662
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.08 KB | None | 0 0
  1.  
  2. #include <stdbool.h>
  3. #include <stdint.h>
  4. #include <stdlib.h>
  5. #include "spi.h"
  6. #include "task.h"
  7.  
  8. // 24 MHz max SPI frequency
  9. #define ICM426XX_MAX_SPI_CLK_HZ 24000000
  10.  
  11. #define ICM426XX_RA_REG_BANK_SEL                    0x76
  12. #define ICM426XX_BANK_SELECT0                       0x00
  13. #define ICM426XX_BANK_SELECT1                       0x01
  14. #define ICM426XX_BANK_SELECT2                       0x02
  15. #define ICM426XX_BANK_SELECT3                       0x03
  16. #define ICM426XX_BANK_SELECT4                       0x04
  17.  
  18. #define ICM426XX_RA_PWR_MGMT0                       0x4E  // User Bank 0
  19. #define ICM426XX_PWR_MGMT0_ACCEL_MODE_LN            (3 << 0)
  20. #define ICM426XX_PWR_MGMT0_GYRO_MODE_LN             (3 << 2)
  21. #define ICM426XX_PWR_MGMT0_GYRO_ACCEL_MODE_OFF      ((0 << 0) | (0 << 2))
  22. #define ICM426XX_PWR_MGMT0_TEMP_DISABLE_OFF         (0 << 5)
  23. #define ICM426XX_PWR_MGMT0_TEMP_DISABLE_ON          (1 << 5)
  24.  
  25. #define ICM426XX_RA_GYRO_CONFIG0                    0x4F
  26. #define ICM426XX_RA_ACCEL_CONFIG0                   0x50
  27.  
  28. // --- Registers for gyro and acc Anti-Alias Filter ---------
  29. #define ICM426XX_RA_GYRO_CONFIG_STATIC3             0x0C  // User Bank 1
  30. #define ICM426XX_RA_GYRO_CONFIG_STATIC4             0x0D  // User Bank 1
  31. #define ICM426XX_RA_GYRO_CONFIG_STATIC5             0x0E  // User Bank 1
  32. #define ICM426XX_RA_ACCEL_CONFIG_STATIC2            0x03  // User Bank 2
  33. #define ICM426XX_RA_ACCEL_CONFIG_STATIC3            0x04  // User Bank 2
  34. #define ICM426XX_RA_ACCEL_CONFIG_STATIC4            0x05  // User Bank 2
  35. // --- Register & setting for gyro and acc UI Filter --------
  36. #define ICM426XX_RA_GYRO_ACCEL_CONFIG0              0x52  // User Bank 0
  37. #define ICM426XX_ACCEL_UI_FILT_BW_LOW_LATENCY       (15 << 4)
  38. #define ICM426XX_GYRO_UI_FILT_BW_LOW_LATENCY        (15 << 0)
  39. // ----------------------------------------------------------
  40.  
  41. #define ICM426XX_RA_GYRO_DATA_X1                    0x25  // User Bank 0
  42. #define ICM426XX_RA_ACCEL_DATA_X1                   0x1F  // User Bank 0
  43.  
  44. #define ICM426XX_RA_INT_CONFIG                      0x14  // User Bank 0
  45. #define ICM426XX_INT1_MODE_PULSED                   (0 << 2)
  46. #define ICM426XX_INT1_MODE_LATCHED                  (1 << 2)
  47. #define ICM426XX_INT1_DRIVE_CIRCUIT_OD              (0 << 1)
  48. #define ICM426XX_INT1_DRIVE_CIRCUIT_PP              (1 << 1)
  49. #define ICM426XX_INT1_POLARITY_ACTIVE_LOW           (0 << 0)
  50. #define ICM426XX_INT1_POLARITY_ACTIVE_HIGH          (1 << 0)
  51.  
  52. #define ICM426XX_RA_INT_CONFIG0                     0x63  // User Bank 0
  53. #define ICM426XX_UI_DRDY_INT_CLEAR_ON_SBR           ((0 << 5) || (0 << 4))
  54. #define ICM426XX_UI_DRDY_INT_CLEAR_ON_SBR_DUPLICATE ((0 << 5) || (0 << 4)) // duplicate settings in datasheet, Rev 1.2.
  55. #define ICM426XX_UI_DRDY_INT_CLEAR_ON_F1BR          ((1 << 5) || (0 << 4))
  56. #define ICM426XX_UI_DRDY_INT_CLEAR_ON_SBR_AND_F1BR  ((1 << 5) || (1 << 4))
  57.  
  58. #define ICM426XX_RA_INT_CONFIG1                     0x64   // User Bank 0
  59. #define ICM426XX_INT_ASYNC_RESET_BIT                4
  60. #define ICM426XX_INT_TDEASSERT_DISABLE_BIT          5
  61. #define ICM426XX_INT_TDEASSERT_ENABLED              (0 << ICM426XX_INT_TDEASSERT_DISABLE_BIT)
  62. #define ICM426XX_INT_TDEASSERT_DISABLED             (1 << ICM426XX_INT_TDEASSERT_DISABLE_BIT)
  63. #define ICM426XX_INT_TPULSE_DURATION_BIT            6
  64. #define ICM426XX_INT_TPULSE_DURATION_100            (0 << ICM426XX_INT_TPULSE_DURATION_BIT)
  65. #define ICM426XX_INT_TPULSE_DURATION_8              (1 << ICM426XX_INT_TPULSE_DURATION_BIT)
  66.  
  67. #define ICM426XX_RA_INT_SOURCE0                     0x65  // User Bank 0
  68. #define ICM426XX_UI_DRDY_INT1_EN_DISABLED           (0 << 3)
  69. #define ICM426XX_UI_DRDY_INT1_EN_ENABLED            (1 << 3)
  70.  
  71. enum gyro_fsr_e {
  72.     INV_FSR_250DPS = 0,
  73.     INV_FSR_500DPS,
  74.     INV_FSR_1000DPS,
  75.     INV_FSR_2000DPS,
  76.     NUM_GYRO_FSR
  77. };
  78.  
  79. enum accel_fsr_e {
  80.     INV_FSR_2G = 0,
  81.     INV_FSR_4G,
  82.     INV_FSR_8G,
  83.     INV_FSR_16G,
  84.     NUM_ACCEL_FSR
  85. };
  86.  
  87. typedef enum {
  88.     ODR_CONFIG_8K = 0,
  89.     ODR_CONFIG_4K,
  90.     ODR_CONFIG_2K,
  91.     ODR_CONFIG_1K,
  92.     ODR_CONFIG_COUNT
  93. } odrConfig_e;
  94.  
  95. typedef enum {
  96.     AAF_CONFIG_258HZ = 0,
  97.     AAF_CONFIG_536HZ,
  98.     AAF_CONFIG_997HZ,
  99.     AAF_CONFIG_1962HZ,
  100.     AAF_CONFIG_COUNT
  101. } aafConfig_e;
  102.  
  103. typedef struct aafConfig_s {
  104.     uint8_t delt;
  105.     uint16_t deltSqr;
  106.     uint8_t bitshift;
  107. } aafConfig_t;
  108.  
  109. // Possible output data rates (ODRs)
  110. static uint8_t odrLUT[ODR_CONFIG_COUNT] = {  // see GYRO_ODR in section 5.6
  111.     [ODR_CONFIG_8K] = 3,
  112.     [ODR_CONFIG_4K] = 4,
  113.     [ODR_CONFIG_2K] = 5,
  114.     [ODR_CONFIG_1K] = 6,
  115. };
  116.  
  117. // Possible gyro Anti-Alias Filter (AAF) cutoffs for ICM-42688P
  118. static aafConfig_t aafLUT42688[AAF_CONFIG_COUNT] = {  // see table in section 5.3
  119.     [AAF_CONFIG_258HZ]  = {  6,   36, 10 },
  120.     [AAF_CONFIG_536HZ]  = { 12,  144,  8 },
  121.     [AAF_CONFIG_997HZ]  = { 21,  440,  6 },
  122.     [AAF_CONFIG_1962HZ] = { 37, 1376,  4 },
  123. };
  124.  
  125. void spiWriteReg(uint8_t addr, uint8_t data)
  126. {
  127.     spi_select_chip();
  128.  
  129.     spi_send_byte(addr);
  130.     spi_send_byte(data);
  131.  
  132.     spi_deselect_chip();
  133. }
  134.  
  135. uint8_t spiReadReg(uint8_t addr)
  136. {
  137.     uint8_t t;
  138.  
  139.     spi_select_chip();
  140.  
  141.     spi_send_byte(addr);
  142.     t = spi_send_byte(0);
  143.  
  144.     spi_deselect_chip();
  145.  
  146.     return t;
  147. }
  148.  
  149. static void turnAGOff(void)
  150. {
  151.     spiWriteReg(ICM426XX_RA_PWR_MGMT0, ICM426XX_PWR_MGMT0_GYRO_ACCEL_MODE_OFF);
  152. }
  153.  
  154. // Turn on gyro and acc on in Low Noise mode
  155. static void turnAGOn(void)
  156. {
  157.     spiWriteReg(ICM426XX_RA_PWR_MGMT0, ICM426XX_PWR_MGMT0_TEMP_DISABLE_OFF | ICM426XX_PWR_MGMT0_ACCEL_MODE_LN | ICM426XX_PWR_MGMT0_GYRO_MODE_LN);
  158.     task_wait(1);
  159. }
  160.  
  161. static void setUserBank(const uint8_t user_bank)
  162. {
  163.     spiWriteReg(ICM426XX_RA_REG_BANK_SEL, user_bank & 7);
  164. }
  165.  
  166. void icm426xxAGInit(void)
  167. {
  168.     SPI_Configuration();
  169.  
  170.     //accDataReg = ICM426XX_RA_ACCEL_DATA_X1;
  171.     //gyro->gyroDataReg = ICM426XX_RA_GYRO_DATA_X1;
  172.  
  173.     // Turn off ACC and GYRO so they can be configured
  174.     // See section 12.9 in ICM-42688-P datasheet v1.7
  175.     setUserBank(ICM426XX_BANK_SELECT0);
  176.     turnAGOff();
  177.  
  178.     // Configure gyro Anti-Alias Filter (see section 5.3 "ANTI-ALIAS FILTER")
  179.     aafConfig_t aafConfig = aafLUT42688[AAF_CONFIG_258HZ];
  180.     setUserBank(ICM426XX_BANK_SELECT1);
  181.     spiWriteReg(ICM426XX_RA_GYRO_CONFIG_STATIC3, aafConfig.delt);
  182.     spiWriteReg(ICM426XX_RA_GYRO_CONFIG_STATIC4, aafConfig.deltSqr & 0xFF);
  183.     spiWriteReg(ICM426XX_RA_GYRO_CONFIG_STATIC5, (aafConfig.deltSqr >> 8) | (aafConfig.bitshift << 4));
  184.  
  185.     // Configure acc Anti-Alias Filter for 1kHz sample rate (see tasks.c)
  186.     aafConfig = aafLUT42688[AAF_CONFIG_258HZ];
  187.     setUserBank(ICM426XX_BANK_SELECT2);
  188.     spiWriteReg(ICM426XX_RA_ACCEL_CONFIG_STATIC2, aafConfig.delt << 1);
  189.     spiWriteReg(ICM426XX_RA_ACCEL_CONFIG_STATIC3, aafConfig.deltSqr & 0xFF);
  190.     spiWriteReg(ICM426XX_RA_ACCEL_CONFIG_STATIC4, (aafConfig.deltSqr >> 8) | (aafConfig.bitshift << 4));
  191.  
  192.     // Configure gyro and acc UI Filters
  193.     setUserBank(ICM426XX_BANK_SELECT0);
  194.     spiWriteReg(ICM426XX_RA_GYRO_ACCEL_CONFIG0, ICM426XX_ACCEL_UI_FILT_BW_LOW_LATENCY | ICM426XX_GYRO_UI_FILT_BW_LOW_LATENCY);
  195.  
  196.     // Configure interrupt pin
  197.     spiWriteReg(ICM426XX_RA_INT_CONFIG, ICM426XX_INT1_MODE_PULSED | ICM426XX_INT1_DRIVE_CIRCUIT_PP | ICM426XX_INT1_POLARITY_ACTIVE_HIGH);
  198.     spiWriteReg(ICM426XX_RA_INT_CONFIG0, ICM426XX_UI_DRDY_INT_CLEAR_ON_SBR);
  199.  
  200.     spiWriteReg(ICM426XX_RA_INT_SOURCE0, ICM426XX_UI_DRDY_INT1_EN_ENABLED);
  201.  
  202.     uint8_t intConfig1Value = spiReadReg(ICM426XX_RA_INT_CONFIG1 | 0x80);
  203.     // Datasheet says: "User should change setting to 0 from default setting of 1, for proper INT1 and INT2 pin operation"
  204.     intConfig1Value &= ~(1 << ICM426XX_INT_ASYNC_RESET_BIT);
  205.     intConfig1Value |= (ICM426XX_INT_TPULSE_DURATION_8 | ICM426XX_INT_TDEASSERT_DISABLED);
  206.  
  207.     spiWriteReg(ICM426XX_RA_INT_CONFIG1, intConfig1Value);
  208.  
  209.     // Turn on gyro and acc on again so ODR and FSR can be configured
  210.     turnAGOn();
  211.  
  212.     uint8_t odrConfig = odrLUT[ODR_CONFIG_1K];
  213.  
  214.     spiWriteReg(ICM426XX_RA_GYRO_CONFIG0, (3 - INV_FSR_2000DPS) << 5 | (odrConfig & 0x0F));
  215.     task_wait(15);
  216.  
  217.     spiWriteReg(ICM426XX_RA_ACCEL_CONFIG0, (3 - INV_FSR_16G) << 5 | (odrConfig & 0x0F));
  218.     task_wait(15);
  219. }
  220.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement