diff --git a/icm20948_8h_source.html b/icm20948_8h_source.html index 99b6c54ca..8b32a41d5 100644 --- a/icm20948_8h_source.html +++ b/icm20948_8h_source.html @@ -566,581 +566,579 @@
438 Result SetupMag()
439 {
-
440 uint8_t buffer[2];
+
440 SetI2CBypass(false);
441
-
442 SetI2CBypass(false);
+
442 ConfigureI2CMaster();
443
-
444 ConfigureI2CMaster();
+
444 EnableI2CMaster(true);
445
-
446 EnableI2CMaster(true);
-
447
-
448 if(AuxI2CBusSetupFailed() == ERR)
-
449 {
-
450 return ERR;
-
451 }
-
452
-
453 // set mag data rate
-
454 if(!SetMagDataRate(AK09916_MAG_DATARATE_100_HZ))
-
455 {
-
456 // Serial.println("Error setting magnetometer data rate on external bus");
-
457 return ERR;
-
458 }
-
459
-
460 // TODO: extract method
-
461 // Set up Slave0 to proxy Mag readings
-
462 SetBank(3);
-
463
-
464 // set up slave0 to proxy reads to mag
-
465 Write8(ICM20X_B3_I2C_SLV0_ADDR, 0x8C);
-
466 if(GetTransportError() != OK)
-
467 {
-
468 return ERR;
-
469 }
-
470
-
471 Write8(ICM20X_B3_I2C_SLV0_REG, 0x10);
-
472 if(GetTransportError() != OK)
-
473 {
-
474 return ERR;
-
475 }
-
476
-
477 // enable, read 9 bytes
-
478 Write8(ICM20X_B3_I2C_SLV0_CTRL, 0x89);
-
479 if(GetTransportError() != OK)
-
480 {
-
481 return ERR;
-
482 }
-
483
-
484 return OK;
-
485 }
-
-
486
-
-
493 uint8_t ReadMagRegister(uint8_t mag_reg_addr)
-
494 {
-
495 return ReadExternalRegister(0x8C, mag_reg_addr);
-
496 }
-
-
497
-
-
498 bool WriteMagRegister(uint8_t mag_reg_addr, uint8_t value)
-
499 {
-
500 return WriteExternalRegister(0x0C, mag_reg_addr, value);
-
501 }
-
-
502
-
-
503 void ScaleValues()
-
504 {
-
505 icm20948_gyro_range_t gyro_range
-
506 = (icm20948_gyro_range_t)current_gyro_range_;
-
507 icm20948_accel_range_t accel_range
-
508 = (icm20948_accel_range_t)current_accel_range_;
-
509
-
510 float accel_scale = 1.0;
-
511 float gyro_scale = 1.0;
-
512
-
513 if(gyro_range == ICM20948_GYRO_RANGE_250_DPS)
-
514 gyro_scale = 131.0;
-
515 if(gyro_range == ICM20948_GYRO_RANGE_500_DPS)
-
516 gyro_scale = 65.5;
-
517 if(gyro_range == ICM20948_GYRO_RANGE_1000_DPS)
-
518 gyro_scale = 32.8;
-
519 if(gyro_range == ICM20948_GYRO_RANGE_2000_DPS)
-
520 gyro_scale = 16.4;
-
521
-
522 if(accel_range == ICM20948_ACCEL_RANGE_2_G)
-
523 accel_scale = 16384.0;
-
524 if(accel_range == ICM20948_ACCEL_RANGE_4_G)
-
525 accel_scale = 8192.0;
-
526 if(accel_range == ICM20948_ACCEL_RANGE_8_G)
-
527 accel_scale = 4096.0;
-
528 if(accel_range == ICM20948_ACCEL_RANGE_16_G)
-
529 accel_scale = 2048.0;
-
530
-
531 gyroX = rawGyroX / gyro_scale;
-
532 gyroY = rawGyroY / gyro_scale;
-
533 gyroZ = rawGyroZ / gyro_scale;
-
534
-
535 accX = rawAccX / accel_scale;
-
536 accY = rawAccY / accel_scale;
-
537 accZ = rawAccZ / accel_scale;
-
538
-
539 magX = rawMagX * ICM20948_UT_PER_LSB;
-
540 magY = rawMagY * ICM20948_UT_PER_LSB;
-
541 magZ = rawMagZ * ICM20948_UT_PER_LSB;
-
542 }
-
-
543
-
-
547 void SetAccelRateDivisor(uint16_t new_accel_divisor)
-
548 {
-
549 SetBank(2);
-
550 Write16(ICM20X_B2_ACCEL_SMPLRT_DIV_1, new_accel_divisor);
-
551 SetBank(0);
-
552 }
-
-
553
-
-
557 icm20948_accel_range_t GetAccelRange()
-
558 {
-
559 return (icm20948_accel_range_t)ReadAccelRange();
-
560 }
-
-
561
-
-
565 uint8_t ReadAccelRange()
-
566 {
-
567 SetBank(2);
-
568 uint8_t range = ReadBits(ICM20X_B2_ACCEL_CONFIG_1, 2, 1);
-
569 SetBank(0);
-
570 return range;
-
571 }
-
-
572
-
-
576 void WriteAccelRange(uint8_t new_accel_range)
-
577 {
-
578 SetBank(2);
-
579 WriteBits(ICM20X_B2_ACCEL_CONFIG_1, new_accel_range, 2, 1);
-
580 current_accel_range_ = new_accel_range;
-
581 SetBank(0);
-
582 }
-
-
583
-
-
587 void SetAccelRange(icm20948_accel_range_t new_accel_range)
-
588 {
-
589 WriteAccelRange((uint8_t)new_accel_range);
-
590 }
-
-
591
-
592
-
-
596 void SetGyroRateDivisor(uint8_t new_gyro_divisor)
-
597 {
-
598 SetBank(2);
-
599 Write8(ICM20X_B2_GYRO_SMPLRT_DIV, new_gyro_divisor);
-
600 SetBank(0);
-
601 }
-
-
602
-
-
606 icm20948_gyro_range_t GetGyroRange()
-
607 {
-
608 return (icm20948_gyro_range_t)ReadGyroRange();
-
609 }
-
-
610
-
-
614 void SetGyroRange(icm20948_gyro_range_t new_gyro_range)
-
615 {
-
616 WriteGyroRange((uint8_t)new_gyro_range);
-
617 }
-
-
618
-
-
622 void WriteGyroRange(uint8_t new_gyro_range)
-
623 {
-
624 SetBank(2);
-
625 WriteBits(ICM20X_B2_GYRO_CONFIG_1, new_gyro_range, 2, 1);
-
626 current_gyro_range_ = new_gyro_range;
-
627 SetBank(0);
-
628 }
-
-
629
-
630
-
-
634 uint8_t ReadGyroRange()
-
635 {
-
636 SetBank(2);
-
637 uint8_t range = ReadBits(ICM20X_B2_GYRO_CONFIG_1, 2, 1);
-
638 SetBank(0);
-
639 return range;
-
640 }
-
-
641
-
642
-
-
646 ak09916_data_rate_t GetMagDataRate()
-
647 {
-
648 uint8_t raw_mag_rate = ReadMagRegister(AK09916_CNTL2);
-
649 return (ak09916_data_rate_t)(raw_mag_rate);
-
650 }
-
-
651
-
-
656 bool SetMagDataRate(ak09916_data_rate_t rate)
-
657 {
-
658 /* Following the datasheet, the sensor will be set to
-
659 * AK09916_MAG_DATARATE_SHUTDOWN followed by a 100ms delay, followed by
-
660 * setting the new data rate.
-
661 *
-
662 * See page 9 of https://www.y-ic.es/datasheet/78/SMDSW.020-2OZ.pdf */
-
663
-
664 // don't need to read/mask because there's nothing else in the register and
-
665 // it's right justified
-
666 bool success
-
667 = WriteMagRegister(AK09916_CNTL2, AK09916_MAG_DATARATE_SHUTDOWN);
-
668 System::Delay(1);
-
669 return WriteMagRegister(AK09916_CNTL2, rate) && success;
-
670 }
-
-
671
-
-
675 void SetBank(uint8_t bank_number)
-
676 {
-
677 Write8(ICM20X_B0_REG_BANK_SEL, (bank_number & 0b11) << 4);
-
678 }
-
-
679
-
680
-
-
686 uint8_t ReadExternalRegister(uint8_t slv_addr, uint8_t reg_addr)
-
687 {
-
688 return AuxillaryRegisterTransaction(true, slv_addr, reg_addr);
-
689 }
-
-
690
-
698 bool
-
-
699 WriteExternalRegister(uint8_t slv_addr, uint8_t reg_addr, uint8_t value)
-
700 {
-
701 return (bool)AuxillaryRegisterTransaction(
-
702 false, slv_addr, reg_addr, value);
-
703 }
-
-
704
-
-
711 uint8_t AuxillaryRegisterTransaction(bool read,
-
712 uint8_t slv_addr,
-
713 uint8_t reg_addr,
-
714 uint8_t value)
-
715 {
-
716 SetBank(3);
-
717
-
718 if(read)
-
719 {
-
720 // set high bit for read, presumably for multi-byte reads
-
721 slv_addr |= 0x80;
-
722 }
-
723 else
-
724 {
-
725 Write8(ICM20X_B3_I2C_SLV4_DO, value);
-
726 if(GetTransportError() == ERR)
-
727 {
-
728 return (uint8_t) false;
-
729 }
-
730 }
-
731
-
732 Write8(ICM20X_B3_I2C_SLV4_ADDR, slv_addr);
-
733 if(GetTransportError() == ERR)
-
734 {
-
735 return (uint8_t) false;
-
736 }
-
737
-
738 Write8(ICM20X_B3_I2C_SLV4_REG, reg_addr);
-
739 if(GetTransportError() == ERR)
-
740 {
-
741 return (uint8_t) false;
-
742 }
-
743
-
744 Write8(ICM20X_B3_I2C_SLV4_CTRL, 0x80);
-
745 if(GetTransportError() == ERR)
-
746 {
-
747 return (uint8_t) false;
-
748 }
-
749
-
750 SetBank(0);
-
751 uint8_t tries = 0;
-
752 // wait until the operation is finished
-
753 while(ReadBits(ICM20X_B0_I2C_MST_STATUS, 1, 6) != true)
-
754 {
-
755 tries++;
-
756 if(tries >= NUM_FINISHED_CHECKS)
-
757 {
-
758 return (uint8_t) false;
-
759 }
-
760 }
-
761
-
762 if(read)
-
763 {
-
764 SetBank(3);
-
765 return Read8(ICM20X_B3_I2C_SLV4_DI);
-
766 }
-
767
-
768 return (uint8_t) true;
-
769 }
-
-
770
-
-
772 void Process()
-
773 {
-
774 SetBank(0);
-
775
-
776 // reading 9 bytes of mag data to fetch the register that tells the mag we've
-
777 // read all the data
-
778 const uint8_t numbytes
-
779 = 14 + 9; // Read Accel, gyro, temp, and 9 bytes of mag
-
780
-
781 uint8_t buffer[numbytes];
-
782 transport_.ReadReg(ICM20X_B0_ACCEL_XOUT_H, buffer, numbytes);
-
783
-
784 rawAccX = buffer[0] << 8 | buffer[1];
-
785 rawAccY = buffer[2] << 8 | buffer[3];
-
786 rawAccZ = buffer[4] << 8 | buffer[5];
-
787
-
788 rawGyroX = buffer[6] << 8 | buffer[7];
-
789 rawGyroY = buffer[8] << 8 | buffer[9];
-
790 rawGyroZ = buffer[10] << 8 | buffer[11];
+
446 if(AuxI2CBusSetupFailed() == ERR)
+
447 {
+
448 return ERR;
+
449 }
+
450
+
451 // set mag data rate
+
452 if(!SetMagDataRate(AK09916_MAG_DATARATE_100_HZ))
+
453 {
+
454 // Serial.println("Error setting magnetometer data rate on external bus");
+
455 return ERR;
+
456 }
+
457
+
458 // TODO: extract method
+
459 // Set up Slave0 to proxy Mag readings
+
460 SetBank(3);
+
461
+
462 // set up slave0 to proxy reads to mag
+
463 Write8(ICM20X_B3_I2C_SLV0_ADDR, 0x8C);
+
464 if(GetTransportError() != OK)
+
465 {
+
466 return ERR;
+
467 }
+
468
+
469 Write8(ICM20X_B3_I2C_SLV0_REG, 0x10);
+
470 if(GetTransportError() != OK)
+
471 {
+
472 return ERR;
+
473 }
+
474
+
475 // enable, read 9 bytes
+
476 Write8(ICM20X_B3_I2C_SLV0_CTRL, 0x89);
+
477 if(GetTransportError() != OK)
+
478 {
+
479 return ERR;
+
480 }
+
481
+
482 return OK;
+
483 }
+
+
484
+
+
491 uint8_t ReadMagRegister(uint8_t mag_reg_addr)
+
492 {
+
493 return ReadExternalRegister(0x8C, mag_reg_addr);
+
494 }
+
+
495
+
+
496 bool WriteMagRegister(uint8_t mag_reg_addr, uint8_t value)
+
497 {
+
498 return WriteExternalRegister(0x0C, mag_reg_addr, value);
+
499 }
+
+
500
+
+
501 void ScaleValues()
+
502 {
+
503 icm20948_gyro_range_t gyro_range
+
504 = (icm20948_gyro_range_t)current_gyro_range_;
+
505 icm20948_accel_range_t accel_range
+
506 = (icm20948_accel_range_t)current_accel_range_;
+
507
+
508 float accel_scale = 1.0;
+
509 float gyro_scale = 1.0;
+
510
+
511 if(gyro_range == ICM20948_GYRO_RANGE_250_DPS)
+
512 gyro_scale = 131.0;
+
513 if(gyro_range == ICM20948_GYRO_RANGE_500_DPS)
+
514 gyro_scale = 65.5;
+
515 if(gyro_range == ICM20948_GYRO_RANGE_1000_DPS)
+
516 gyro_scale = 32.8;
+
517 if(gyro_range == ICM20948_GYRO_RANGE_2000_DPS)
+
518 gyro_scale = 16.4;
+
519
+
520 if(accel_range == ICM20948_ACCEL_RANGE_2_G)
+
521 accel_scale = 16384.0;
+
522 if(accel_range == ICM20948_ACCEL_RANGE_4_G)
+
523 accel_scale = 8192.0;
+
524 if(accel_range == ICM20948_ACCEL_RANGE_8_G)
+
525 accel_scale = 4096.0;
+
526 if(accel_range == ICM20948_ACCEL_RANGE_16_G)
+
527 accel_scale = 2048.0;
+
528
+
529 gyroX = rawGyroX / gyro_scale;
+
530 gyroY = rawGyroY / gyro_scale;
+
531 gyroZ = rawGyroZ / gyro_scale;
+
532
+
533 accX = rawAccX / accel_scale;
+
534 accY = rawAccY / accel_scale;
+
535 accZ = rawAccZ / accel_scale;
+
536
+
537 magX = rawMagX * ICM20948_UT_PER_LSB;
+
538 magY = rawMagY * ICM20948_UT_PER_LSB;
+
539 magZ = rawMagZ * ICM20948_UT_PER_LSB;
+
540 }
+
+
541
+
+
545 void SetAccelRateDivisor(uint16_t new_accel_divisor)
+
546 {
+
547 SetBank(2);
+
548 Write16(ICM20X_B2_ACCEL_SMPLRT_DIV_1, new_accel_divisor);
+
549 SetBank(0);
+
550 }
+
+
551
+
+
555 icm20948_accel_range_t GetAccelRange()
+
556 {
+
557 return (icm20948_accel_range_t)ReadAccelRange();
+
558 }
+
+
559
+
+
563 uint8_t ReadAccelRange()
+
564 {
+
565 SetBank(2);
+
566 uint8_t range = ReadBits(ICM20X_B2_ACCEL_CONFIG_1, 2, 1);
+
567 SetBank(0);
+
568 return range;
+
569 }
+
+
570
+
+
574 void WriteAccelRange(uint8_t new_accel_range)
+
575 {
+
576 SetBank(2);
+
577 WriteBits(ICM20X_B2_ACCEL_CONFIG_1, new_accel_range, 2, 1);
+
578 current_accel_range_ = new_accel_range;
+
579 SetBank(0);
+
580 }
+
+
581
+
+
585 void SetAccelRange(icm20948_accel_range_t new_accel_range)
+
586 {
+
587 WriteAccelRange((uint8_t)new_accel_range);
+
588 }
+
+
589
+
590
+
+
594 void SetGyroRateDivisor(uint8_t new_gyro_divisor)
+
595 {
+
596 SetBank(2);
+
597 Write8(ICM20X_B2_GYRO_SMPLRT_DIV, new_gyro_divisor);
+
598 SetBank(0);
+
599 }
+
+
600
+
+
604 icm20948_gyro_range_t GetGyroRange()
+
605 {
+
606 return (icm20948_gyro_range_t)ReadGyroRange();
+
607 }
+
+
608
+
+
612 void SetGyroRange(icm20948_gyro_range_t new_gyro_range)
+
613 {
+
614 WriteGyroRange((uint8_t)new_gyro_range);
+
615 }
+
+
616
+
+
620 void WriteGyroRange(uint8_t new_gyro_range)
+
621 {
+
622 SetBank(2);
+
623 WriteBits(ICM20X_B2_GYRO_CONFIG_1, new_gyro_range, 2, 1);
+
624 current_gyro_range_ = new_gyro_range;
+
625 SetBank(0);
+
626 }
+
+
627
+
628
+
+
632 uint8_t ReadGyroRange()
+
633 {
+
634 SetBank(2);
+
635 uint8_t range = ReadBits(ICM20X_B2_GYRO_CONFIG_1, 2, 1);
+
636 SetBank(0);
+
637 return range;
+
638 }
+
+
639
+
640
+
+
644 ak09916_data_rate_t GetMagDataRate()
+
645 {
+
646 uint8_t raw_mag_rate = ReadMagRegister(AK09916_CNTL2);
+
647 return (ak09916_data_rate_t)(raw_mag_rate);
+
648 }
+
+
649
+
+
654 bool SetMagDataRate(ak09916_data_rate_t rate)
+
655 {
+
656 /* Following the datasheet, the sensor will be set to
+
657 * AK09916_MAG_DATARATE_SHUTDOWN followed by a 100ms delay, followed by
+
658 * setting the new data rate.
+
659 *
+
660 * See page 9 of https://www.y-ic.es/datasheet/78/SMDSW.020-2OZ.pdf */
+
661
+
662 // don't need to read/mask because there's nothing else in the register and
+
663 // it's right justified
+
664 bool success
+
665 = WriteMagRegister(AK09916_CNTL2, AK09916_MAG_DATARATE_SHUTDOWN);
+
666 System::Delay(1);
+
667 return WriteMagRegister(AK09916_CNTL2, rate) && success;
+
668 }
+
+
669
+
+
673 void SetBank(uint8_t bank_number)
+
674 {
+
675 Write8(ICM20X_B0_REG_BANK_SEL, (bank_number & 0b11) << 4);
+
676 }
+
+
677
+
678
+
+
684 uint8_t ReadExternalRegister(uint8_t slv_addr, uint8_t reg_addr)
+
685 {
+
686 return AuxillaryRegisterTransaction(true, slv_addr, reg_addr);
+
687 }
+
+
688
+
696 bool
+
+
697 WriteExternalRegister(uint8_t slv_addr, uint8_t reg_addr, uint8_t value)
+
698 {
+
699 return (bool)AuxillaryRegisterTransaction(
+
700 false, slv_addr, reg_addr, value);
+
701 }
+
+
702
+
+
709 uint8_t AuxillaryRegisterTransaction(bool read,
+
710 uint8_t slv_addr,
+
711 uint8_t reg_addr,
+
712 uint8_t value)
+
713 {
+
714 SetBank(3);
+
715
+
716 if(read)
+
717 {
+
718 // set high bit for read, presumably for multi-byte reads
+
719 slv_addr |= 0x80;
+
720 }
+
721 else
+
722 {
+
723 Write8(ICM20X_B3_I2C_SLV4_DO, value);
+
724 if(GetTransportError() == ERR)
+
725 {
+
726 return (uint8_t) false;
+
727 }
+
728 }
+
729
+
730 Write8(ICM20X_B3_I2C_SLV4_ADDR, slv_addr);
+
731 if(GetTransportError() == ERR)
+
732 {
+
733 return (uint8_t) false;
+
734 }
+
735
+
736 Write8(ICM20X_B3_I2C_SLV4_REG, reg_addr);
+
737 if(GetTransportError() == ERR)
+
738 {
+
739 return (uint8_t) false;
+
740 }
+
741
+
742 Write8(ICM20X_B3_I2C_SLV4_CTRL, 0x80);
+
743 if(GetTransportError() == ERR)
+
744 {
+
745 return (uint8_t) false;
+
746 }
+
747
+
748 SetBank(0);
+
749 uint8_t tries = 0;
+
750 // wait until the operation is finished
+
751 while(ReadBits(ICM20X_B0_I2C_MST_STATUS, 1, 6) != true)
+
752 {
+
753 tries++;
+
754 if(tries >= NUM_FINISHED_CHECKS)
+
755 {
+
756 return (uint8_t) false;
+
757 }
+
758 }
+
759
+
760 if(read)
+
761 {
+
762 SetBank(3);
+
763 return Read8(ICM20X_B3_I2C_SLV4_DI);
+
764 }
+
765
+
766 return (uint8_t) true;
+
767 }
+
+
768
+
+
770 void Process()
+
771 {
+
772 SetBank(0);
+
773
+
774 // reading 9 bytes of mag data to fetch the register that tells the mag we've
+
775 // read all the data
+
776 const uint8_t numbytes
+
777 = 14 + 9; // Read Accel, gyro, temp, and 9 bytes of mag
+
778
+
779 uint8_t buffer[numbytes];
+
780 transport_.ReadReg(ICM20X_B0_ACCEL_XOUT_H, buffer, numbytes);
+
781
+
782 rawAccX = buffer[0] << 8 | buffer[1];
+
783 rawAccY = buffer[2] << 8 | buffer[3];
+
784 rawAccZ = buffer[4] << 8 | buffer[5];
+
785
+
786 rawGyroX = buffer[6] << 8 | buffer[7];
+
787 rawGyroY = buffer[8] << 8 | buffer[9];
+
788 rawGyroZ = buffer[10] << 8 | buffer[11];
+
789
+
790 temperature = buffer[12] << 8 | buffer[13];
791
-
792 temperature = buffer[12] << 8 | buffer[13];
-
793
-
794 rawMagX = ((buffer[16] << 8)
-
795 | (buffer[15] & 0xFF)); // Mag data is read little endian
-
796 rawMagY = ((buffer[18] << 8) | (buffer[17] & 0xFF));
-
797 rawMagZ = ((buffer[20] << 8) | (buffer[19] & 0xFF));
-
798
-
799 ScaleValues();
-
800 SetBank(0);
-
801 }
-
-
802
-
-
803 Icm20948Vect GetAccelVect()
-
804 {
-
805 Icm20948Vect vect;
-
806 vect.x = accX * SENSORS_GRAVITY_EARTH;
-
807 vect.y = accY * SENSORS_GRAVITY_EARTH;
-
808 vect.z = accZ * SENSORS_GRAVITY_EARTH;
-
809
-
810 return vect;
-
811 }
-
-
812
-
-
813 Icm20948Vect GetGyroVect()
-
814 {
-
815 Icm20948Vect vect;
-
816 vect.x = gyroX * SENSORS_DPS_TO_RADS;
-
817 vect.y = gyroY * SENSORS_DPS_TO_RADS;
-
818 vect.z = gyroZ * SENSORS_DPS_TO_RADS;
-
819
-
820 return vect;
-
821 }
-
-
822
-
-
823 Icm20948Vect GetMagVect()
-
824 {
-
825 Icm20948Vect vect;
-
826 vect.x = magX;
-
827 vect.y = magY;
-
828 vect.z = magZ;
-
829
-
830 return vect;
-
831 }
-
+
792 rawMagX = ((buffer[16] << 8)
+
793 | (buffer[15] & 0xFF)); // Mag data is read little endian
+
794 rawMagY = ((buffer[18] << 8) | (buffer[17] & 0xFF));
+
795 rawMagZ = ((buffer[20] << 8) | (buffer[19] & 0xFF));
+
796
+
797 ScaleValues();
+
798 SetBank(0);
+
799 }
+ +
800
+
+
801 Icm20948Vect GetAccelVect()
+
802 {
+
803 Icm20948Vect vect;
+
804 vect.x = accX * SENSORS_GRAVITY_EARTH;
+
805 vect.y = accY * SENSORS_GRAVITY_EARTH;
+
806 vect.z = accZ * SENSORS_GRAVITY_EARTH;
+
807
+
808 return vect;
+
809 }
+
+
810
+
+
811 Icm20948Vect GetGyroVect()
+
812 {
+
813 Icm20948Vect vect;
+
814 vect.x = gyroX * SENSORS_DPS_TO_RADS;
+
815 vect.y = gyroY * SENSORS_DPS_TO_RADS;
+
816 vect.z = gyroZ * SENSORS_DPS_TO_RADS;
+
817
+
818 return vect;
+
819 }
+
+
820
+
+
821 Icm20948Vect GetMagVect()
+
822 {
+
823 Icm20948Vect vect;
+
824 vect.x = magX;
+
825 vect.y = magY;
+
826 vect.z = magZ;
+
827
+
828 return vect;
+
829 }
+
+
830
+
831 float GetTemp() { return (temperature / 333.87) + 21.0; }
832
-
833 float GetTemp() { return (temperature / 333.87) + 21.0; }
-
834
-
839 uint8_t Read8(uint8_t reg) { return transport_.Read8(reg); }
-
840
-
-
845 void Write8(uint8_t reg, uint8_t value)
-
846 {
-
847 return transport_.Write8(reg, value);
-
848 }
-
-
849
-
-
854 void Write16(uint8_t reg, uint16_t value)
-
855 {
-
856 return transport_.Write16(reg, value);
-
857 }
-
-
858
-
-
860 void ReadReg(uint8_t reg, uint8_t *buff, uint8_t size)
-
861 {
-
862 return transport_.ReadReg(reg, buff, size);
-
863 }
-
-
864
-
-
865 uint8_t ReadBits(uint8_t reg, uint8_t bits, uint8_t shift)
-
866 {
-
867 uint8_t val = Read8(reg);
-
868 val >>= shift;
-
869 return val & ((1 << (bits)) - 1);
-
870 }
-
-
871
-
-
872 void WriteBits(uint8_t reg, uint8_t data, uint8_t bits, uint8_t shift)
-
873 {
-
874 uint8_t val = Read8(reg);
-
875
-
876 // mask off the data before writing
-
877 uint8_t mask = (1 << (bits)) - 1;
-
878 data &= mask;
-
879
-
880 mask <<= shift;
-
881 val &= ~mask; // remove the current data at that spot
-
882 val |= data << shift; // and add in the new data
-
883
-
884 Write8(reg, val);
-
885 }
-
-
886
-
-
892 void SetI2CBypass(bool bypass_i2c)
-
893 {
-
894 SetBank(0);
-
895 WriteBits(ICM20X_B0_REG_INT_PIN_CFG, bypass_i2c, 1, 1);
-
896 }
-
-
897
-
-
902 Result EnableI2CMaster(bool enable_i2c_master)
-
903 {
-
904 SetBank(0);
-
905 WriteBits(ICM20X_B0_USER_CTRL, enable_i2c_master, 1, 5);
-
906 return GetTransportError();
-
907 }
-
-
908
-
-
912 Result ConfigureI2CMaster(void)
-
913 {
-
914 SetBank(3);
-
915 Write8(ICM20X_B3_I2C_MST_CTRL, 0x17);
-
916 return GetTransportError();
-
917 }
-
-
918
-
-
920 void ResetI2CMaster(void)
-
921 {
-
922 SetBank(0);
-
923
-
924 WriteBits(ICM20X_B0_USER_CTRL, true, 1, 1);
-
925 while(ReadBits(ICM20X_B0_USER_CTRL, 1, 1))
-
926 {
-
927 System::Delay(10);
-
928 }
-
929 System::Delay(100);
-
930 }
-
-
931
-
932 // A million thanks to the SparkFun folks for their library that I pillaged to
-
933 // write this method! See their Arduino library here:
-
934 // https://github.com/sparkfun/SparkFun_ICM-20948_ArduinoLibrary
-
-
935 Result AuxI2CBusSetupFailed(void)
-
936 {
-
937 // check aux I2C bus connection by reading the magnetometer chip ID
-
938 for(int i = 0; i < I2C_MASTER_RESETS_BEFORE_FAIL; i++)
-
939 {
-
940 if(GetMagId() != ICM20948_MAG_ID)
-
941 {
-
942 ResetI2CMaster();
-
943 }
-
944 else
-
945 {
-
946 return ERR;
-
947 }
-
948 }
-
949 return OK;
-
950 }
-
-
951
-
955 Result GetTransportError() { return transport_.GetError() ? ERR : OK; }
-
956
-
957 private:
-
958 Config config_;
-
959 Transport transport_;
-
960
-
961 uint16_t _sensorid_accel,
-
962 _sensorid_gyro,
-
963 _sensorid_mag,
-
964 _sensorid_temp;
-
965
-
966 uint8_t current_accel_range_;
-
967 uint8_t current_gyro_range_;
-
968
-
969 int16_t rawAccX,
-
970 rawAccY,
-
971 rawAccZ,
-
972 rawTemp,
-
973 rawGyroX,
-
974 rawGyroY,
-
975 rawGyroZ,
-
976 rawMagX,
-
977 rawMagY,
-
978 rawMagZ;
-
979
-
980 float temperature,
-
981 accX,
-
982 accY,
-
983 accZ,
-
984 gyroX,
-
985 gyroY,
-
986 gyroZ,
-
987 magX,
-
988 magY,
-
989 magZ;
-
990};
- -
991
-
994using Icm20948I2C = Icm20948<Icm20948I2CTransport>;
-
995using Icm20948Spi = Icm20948<Icm20948SpiTransport>;
-
996} // namespace daisy
-
997#endif
+
837 uint8_t Read8(uint8_t reg) { return transport_.Read8(reg); }
+
838
+
+
843 void Write8(uint8_t reg, uint8_t value)
+
844 {
+
845 return transport_.Write8(reg, value);
+
846 }
+
+
847
+
+
852 void Write16(uint8_t reg, uint16_t value)
+
853 {
+
854 return transport_.Write16(reg, value);
+
855 }
+
+
856
+
+
858 void ReadReg(uint8_t reg, uint8_t *buff, uint8_t size)
+
859 {
+
860 return transport_.ReadReg(reg, buff, size);
+
861 }
+
+
862
+
+
863 uint8_t ReadBits(uint8_t reg, uint8_t bits, uint8_t shift)
+
864 {
+
865 uint8_t val = Read8(reg);
+
866 val >>= shift;
+
867 return val & ((1 << (bits)) - 1);
+
868 }
+
+
869
+
+
870 void WriteBits(uint8_t reg, uint8_t data, uint8_t bits, uint8_t shift)
+
871 {
+
872 uint8_t val = Read8(reg);
+
873
+
874 // mask off the data before writing
+
875 uint8_t mask = (1 << (bits)) - 1;
+
876 data &= mask;
+
877
+
878 mask <<= shift;
+
879 val &= ~mask; // remove the current data at that spot
+
880 val |= data << shift; // and add in the new data
+
881
+
882 Write8(reg, val);
+
883 }
+
+
884
+
+
890 void SetI2CBypass(bool bypass_i2c)
+
891 {
+
892 SetBank(0);
+
893 WriteBits(ICM20X_B0_REG_INT_PIN_CFG, bypass_i2c, 1, 1);
+
894 }
+
+
895
+
+
900 Result EnableI2CMaster(bool enable_i2c_master)
+
901 {
+
902 SetBank(0);
+
903 WriteBits(ICM20X_B0_USER_CTRL, enable_i2c_master, 1, 5);
+
904 return GetTransportError();
+
905 }
+
+
906
+
+
910 Result ConfigureI2CMaster(void)
+
911 {
+
912 SetBank(3);
+
913 Write8(ICM20X_B3_I2C_MST_CTRL, 0x17);
+
914 return GetTransportError();
+
915 }
+
+
916
+
+
918 void ResetI2CMaster(void)
+
919 {
+
920 SetBank(0);
+
921
+
922 WriteBits(ICM20X_B0_USER_CTRL, true, 1, 1);
+
923 while(ReadBits(ICM20X_B0_USER_CTRL, 1, 1))
+
924 {
+
925 System::Delay(10);
+
926 }
+
927 System::Delay(100);
+
928 }
+
+
929
+
930 // A million thanks to the SparkFun folks for their library that I pillaged to
+
931 // write this method! See their Arduino library here:
+
932 // https://github.com/sparkfun/SparkFun_ICM-20948_ArduinoLibrary
+
+
933 Result AuxI2CBusSetupFailed(void)
+
934 {
+
935 // check aux I2C bus connection by reading the magnetometer chip ID
+
936 for(int i = 0; i < I2C_MASTER_RESETS_BEFORE_FAIL; i++)
+
937 {
+
938 if(GetMagId() != ICM20948_MAG_ID)
+
939 {
+
940 ResetI2CMaster();
+
941 }
+
942 else
+
943 {
+
944 return ERR;
+
945 }
+
946 }
+
947 return OK;
+
948 }
+
+
949
+
953 Result GetTransportError() { return transport_.GetError() ? ERR : OK; }
+
954
+
955 private:
+
956 Config config_;
+
957 Transport transport_;
+
958
+
959 uint16_t _sensorid_accel,
+
960 _sensorid_gyro,
+
961 _sensorid_mag,
+
962 _sensorid_temp;
+
963
+
964 uint8_t current_accel_range_;
+
965 uint8_t current_gyro_range_;
+
966
+
967 int16_t rawAccX,
+
968 rawAccY,
+
969 rawAccZ,
+
970 rawTemp,
+
971 rawGyroX,
+
972 rawGyroY,
+
973 rawGyroZ,
+
974 rawMagX,
+
975 rawMagY,
+
976 rawMagZ;
+
977
+
978 float temperature,
+
979 accX,
+
980 accY,
+
981 accZ,
+
982 gyroX,
+
983 gyroY,
+
984 gyroZ,
+
985 magX,
+
986 magY,
+
987 magZ;
+
988};
+ +
989
+
992using Icm20948I2C = Icm20948<Icm20948I2CTransport>;
+
993using Icm20948Spi = Icm20948<Icm20948SpiTransport>;
+
994} // namespace daisy
+
995#endif
daisy::I2CHandle
Definition i2c.h:26
daisy::I2CHandle::Init
Result Init(const Config &config)
daisy::I2CHandle::Result::OK
@ OK
daisy::I2CHandle::ReceiveBlocking
Result ReceiveBlocking(uint16_t address, uint8_t *data, uint16_t size, uint32_t timeout)
daisy::I2CHandle::TransmitBlocking
Result TransmitBlocking(uint16_t address, uint8_t *data, uint16_t size, uint32_t timeout)
daisy::Icm20948
Device support for ICM20948 IMU sensor.
Definition icm20948.h:317
-
daisy::Icm20948::GetAccelRange
icm20948_accel_range_t GetAccelRange()
Definition icm20948.h:557
-
daisy::Icm20948::SetAccelRange
void SetAccelRange(icm20948_accel_range_t new_accel_range)
Definition icm20948.h:587
-
daisy::Icm20948::GetTransportError
Result GetTransportError()
Definition icm20948.h:955
+
daisy::Icm20948::GetAccelRange
icm20948_accel_range_t GetAccelRange()
Definition icm20948.h:555
+
daisy::Icm20948::SetAccelRange
void SetAccelRange(icm20948_accel_range_t new_accel_range)
Definition icm20948.h:585
+
daisy::Icm20948::GetTransportError
Result GetTransportError()
Definition icm20948.h:953
daisy::Icm20948::Init
Result Init(Config config)
Definition icm20948.h:376
-
daisy::Icm20948::ResetI2CMaster
void ResetI2CMaster(void)
Definition icm20948.h:920
+
daisy::Icm20948::ResetI2CMaster
void ResetI2CMaster(void)
Definition icm20948.h:918
daisy::Icm20948::icm20948_accel_range_t
icm20948_accel_range_t
Definition icm20948.h:338
daisy::Icm20948::ICM20948_ACCEL_RANGE_8_G
@ ICM20948_ACCEL_RANGE_8_G
Definition icm20948.h:341
daisy::Icm20948::ICM20948_ACCEL_RANGE_16_G
@ ICM20948_ACCEL_RANGE_16_G
Definition icm20948.h:342
daisy::Icm20948::ICM20948_ACCEL_RANGE_2_G
@ ICM20948_ACCEL_RANGE_2_G
Definition icm20948.h:339
daisy::Icm20948::ICM20948_ACCEL_RANGE_4_G
@ ICM20948_ACCEL_RANGE_4_G
Definition icm20948.h:340
-
daisy::Icm20948::AuxI2CBusSetupFailed
Result AuxI2CBusSetupFailed(void)
Definition icm20948.h:935
-
daisy::Icm20948::WriteMagRegister
bool WriteMagRegister(uint8_t mag_reg_addr, uint8_t value)
Definition icm20948.h:498
-
daisy::Icm20948::SetBank
void SetBank(uint8_t bank_number)
Definition icm20948.h:675
+
daisy::Icm20948::AuxI2CBusSetupFailed
Result AuxI2CBusSetupFailed(void)
Definition icm20948.h:933
+
daisy::Icm20948::WriteMagRegister
bool WriteMagRegister(uint8_t mag_reg_addr, uint8_t value)
Definition icm20948.h:496
+
daisy::Icm20948::SetBank
void SetBank(uint8_t bank_number)
Definition icm20948.h:673
daisy::Icm20948::Icm20948
Icm20948()
Definition icm20948.h:319
-
daisy::Icm20948::ReadAccelRange
uint8_t ReadAccelRange()
Definition icm20948.h:565
-
daisy::Icm20948::Write16
void Write16(uint8_t reg, uint16_t value)
Definition icm20948.h:854
-
daisy::Icm20948::GetMagDataRate
ak09916_data_rate_t GetMagDataRate()
Definition icm20948.h:646
+
daisy::Icm20948::ReadAccelRange
uint8_t ReadAccelRange()
Definition icm20948.h:563
+
daisy::Icm20948::Write16
void Write16(uint8_t reg, uint16_t value)
Definition icm20948.h:852
+
daisy::Icm20948::GetMagDataRate
ak09916_data_rate_t GetMagDataRate()
Definition icm20948.h:644
daisy::Icm20948::~Icm20948
~Icm20948()
Definition icm20948.h:320
daisy::Icm20948::GetMagId
uint8_t GetMagId()
Definition icm20948.h:432
-
daisy::Icm20948::GetGyroVect
Icm20948Vect GetGyroVect()
Definition icm20948.h:813
-
daisy::Icm20948::SetMagDataRate
bool SetMagDataRate(ak09916_data_rate_t rate)
Definition icm20948.h:656
-
daisy::Icm20948::WriteBits
void WriteBits(uint8_t reg, uint8_t data, uint8_t bits, uint8_t shift)
Definition icm20948.h:872
-
daisy::Icm20948::SetGyroRange
void SetGyroRange(icm20948_gyro_range_t new_gyro_range)
Definition icm20948.h:614
-
daisy::Icm20948::ReadExternalRegister
uint8_t ReadExternalRegister(uint8_t slv_addr, uint8_t reg_addr)
Definition icm20948.h:686
+
daisy::Icm20948::GetGyroVect
Icm20948Vect GetGyroVect()
Definition icm20948.h:811
+
daisy::Icm20948::SetMagDataRate
bool SetMagDataRate(ak09916_data_rate_t rate)
Definition icm20948.h:654
+
daisy::Icm20948::WriteBits
void WriteBits(uint8_t reg, uint8_t data, uint8_t bits, uint8_t shift)
Definition icm20948.h:870
+
daisy::Icm20948::SetGyroRange
void SetGyroRange(icm20948_gyro_range_t new_gyro_range)
Definition icm20948.h:612
+
daisy::Icm20948::ReadExternalRegister
uint8_t ReadExternalRegister(uint8_t slv_addr, uint8_t reg_addr)
Definition icm20948.h:684
daisy::Icm20948::Reset
void Reset()
Definition icm20948.h:417
-
daisy::Icm20948::GetMagVect
Icm20948Vect GetMagVect()
Definition icm20948.h:823
-
daisy::Icm20948::Write8
void Write8(uint8_t reg, uint8_t value)
Definition icm20948.h:845
-
daisy::Icm20948::WriteExternalRegister
bool WriteExternalRegister(uint8_t slv_addr, uint8_t reg_addr, uint8_t value)
Definition icm20948.h:699
-
daisy::Icm20948::ConfigureI2CMaster
Result ConfigureI2CMaster(void)
Definition icm20948.h:912
+
daisy::Icm20948::GetMagVect
Icm20948Vect GetMagVect()
Definition icm20948.h:821
+
daisy::Icm20948::Write8
void Write8(uint8_t reg, uint8_t value)
Definition icm20948.h:843
+
daisy::Icm20948::WriteExternalRegister
bool WriteExternalRegister(uint8_t slv_addr, uint8_t reg_addr, uint8_t value)
Definition icm20948.h:697
+
daisy::Icm20948::ConfigureI2CMaster
Result ConfigureI2CMaster(void)
Definition icm20948.h:910
daisy::Icm20948::SetupMag
Result SetupMag()
Definition icm20948.h:438
daisy::Icm20948::icm20948_gyro_range_t
icm20948_gyro_range_t
Definition icm20948.h:347
daisy::Icm20948::ICM20948_GYRO_RANGE_500_DPS
@ ICM20948_GYRO_RANGE_500_DPS
Definition icm20948.h:349
daisy::Icm20948::ICM20948_GYRO_RANGE_250_DPS
@ ICM20948_GYRO_RANGE_250_DPS
Definition icm20948.h:348
daisy::Icm20948::ICM20948_GYRO_RANGE_1000_DPS
@ ICM20948_GYRO_RANGE_1000_DPS
Definition icm20948.h:350
daisy::Icm20948::ICM20948_GYRO_RANGE_2000_DPS
@ ICM20948_GYRO_RANGE_2000_DPS
Definition icm20948.h:351
-
daisy::Icm20948::WriteGyroRange
void WriteGyroRange(uint8_t new_gyro_range)
Definition icm20948.h:622
-
daisy::Icm20948::EnableI2CMaster
Result EnableI2CMaster(bool enable_i2c_master)
Definition icm20948.h:902
-
daisy::Icm20948::SetAccelRateDivisor
void SetAccelRateDivisor(uint16_t new_accel_divisor)
Definition icm20948.h:547
-
daisy::Icm20948::GetGyroRange
icm20948_gyro_range_t GetGyroRange()
Definition icm20948.h:606
+
daisy::Icm20948::WriteGyroRange
void WriteGyroRange(uint8_t new_gyro_range)
Definition icm20948.h:620
+
daisy::Icm20948::EnableI2CMaster
Result EnableI2CMaster(bool enable_i2c_master)
Definition icm20948.h:900
+
daisy::Icm20948::SetAccelRateDivisor
void SetAccelRateDivisor(uint16_t new_accel_divisor)
Definition icm20948.h:545
+
daisy::Icm20948::GetGyroRange
icm20948_gyro_range_t GetGyroRange()
Definition icm20948.h:604
daisy::Icm20948::ak09916_data_rate_t
ak09916_data_rate_t
Definition icm20948.h:356
daisy::Icm20948::AK09916_MAG_DATARATE_50_HZ
@ AK09916_MAG_DATARATE_50_HZ
updates at 50Hz
Definition icm20948.h:363
daisy::Icm20948::AK09916_MAG_DATARATE_10_HZ
@ AK09916_MAG_DATARATE_10_HZ
updates at 10Hz
Definition icm20948.h:361
@@ -1148,22 +1146,22 @@
daisy::Icm20948::AK09916_MAG_DATARATE_SHUTDOWN
@ AK09916_MAG_DATARATE_SHUTDOWN
Stops measurement updates.
Definition icm20948.h:357
daisy::Icm20948::AK09916_MAG_DATARATE_SINGLE
@ AK09916_MAG_DATARATE_SINGLE
Definition icm20948.h:358
daisy::Icm20948::AK09916_MAG_DATARATE_20_HZ
@ AK09916_MAG_DATARATE_20_HZ
updates at 20Hz
Definition icm20948.h:362
-
daisy::Icm20948::GetTemp
float GetTemp()
Definition icm20948.h:833
-
daisy::Icm20948::ReadBits
uint8_t ReadBits(uint8_t reg, uint8_t bits, uint8_t shift)
Definition icm20948.h:865
-
daisy::Icm20948::GetAccelVect
Icm20948Vect GetAccelVect()
Definition icm20948.h:803
-
daisy::Icm20948::AuxillaryRegisterTransaction
uint8_t AuxillaryRegisterTransaction(bool read, uint8_t slv_addr, uint8_t reg_addr, uint8_t value)
Definition icm20948.h:711
-
daisy::Icm20948::WriteAccelRange
void WriteAccelRange(uint8_t new_accel_range)
Definition icm20948.h:576
-
daisy::Icm20948::SetGyroRateDivisor
void SetGyroRateDivisor(uint8_t new_gyro_divisor)
Definition icm20948.h:596
-
daisy::Icm20948::ScaleValues
void ScaleValues()
Definition icm20948.h:503
+
daisy::Icm20948::GetTemp
float GetTemp()
Definition icm20948.h:831
+
daisy::Icm20948::ReadBits
uint8_t ReadBits(uint8_t reg, uint8_t bits, uint8_t shift)
Definition icm20948.h:863
+
daisy::Icm20948::GetAccelVect
Icm20948Vect GetAccelVect()
Definition icm20948.h:801
+
daisy::Icm20948::AuxillaryRegisterTransaction
uint8_t AuxillaryRegisterTransaction(bool read, uint8_t slv_addr, uint8_t reg_addr, uint8_t value)
Definition icm20948.h:709
+
daisy::Icm20948::WriteAccelRange
void WriteAccelRange(uint8_t new_accel_range)
Definition icm20948.h:574
+
daisy::Icm20948::SetGyroRateDivisor
void SetGyroRateDivisor(uint8_t new_gyro_divisor)
Definition icm20948.h:594
+
daisy::Icm20948::ScaleValues
void ScaleValues()
Definition icm20948.h:501
daisy::Icm20948::Result
Result
Definition icm20948.h:368
daisy::Icm20948::OK
@ OK
Definition icm20948.h:369
daisy::Icm20948::ERR
@ ERR
Definition icm20948.h:370
-
daisy::Icm20948::Read8
uint8_t Read8(uint8_t reg)
Definition icm20948.h:839
-
daisy::Icm20948::ReadMagRegister
uint8_t ReadMagRegister(uint8_t mag_reg_addr)
Definition icm20948.h:493
-
daisy::Icm20948::SetI2CBypass
void SetI2CBypass(bool bypass_i2c)
Definition icm20948.h:892
-
daisy::Icm20948::ReadReg
void ReadReg(uint8_t reg, uint8_t *buff, uint8_t size)
Definition icm20948.h:860
-
daisy::Icm20948::ReadGyroRange
uint8_t ReadGyroRange()
Definition icm20948.h:634
-
daisy::Icm20948::Process
void Process()
Definition icm20948.h:772
+
daisy::Icm20948::Read8
uint8_t Read8(uint8_t reg)
Definition icm20948.h:837
+
daisy::Icm20948::ReadMagRegister
uint8_t ReadMagRegister(uint8_t mag_reg_addr)
Definition icm20948.h:491
+
daisy::Icm20948::SetI2CBypass
void SetI2CBypass(bool bypass_i2c)
Definition icm20948.h:890
+
daisy::Icm20948::ReadReg
void ReadReg(uint8_t reg, uint8_t *buff, uint8_t size)
Definition icm20948.h:858
+
daisy::Icm20948::ReadGyroRange
uint8_t ReadGyroRange()
Definition icm20948.h:632
+
daisy::Icm20948::Process
void Process()
Definition icm20948.h:770
daisy::Icm20948I2CTransport
Definition icm20948.h:81
daisy::Icm20948I2CTransport::Read
void Read(uint8_t *data, uint16_t size)
Definition icm20948.h:128
daisy::Icm20948I2CTransport::Write8
void Write8(uint8_t reg, uint8_t value)
Definition icm20948.h:138