ジャパンオープン用のメインプログラム
Dependencies: mbed AQM1602 HMC6352 PID
adns_9800.cpp
00001 /** 00002 * @author Alexander Entinger, MSc / LXRobotics 00003 * @brief this class acts as interface for accessing the adns-9800 sensor - based on https://github.com/mrjohnk/ADNS-9800 00004 * @file adns_9800.cpp 00005 */ 00006 00007 #include "adns_9800.h" 00008 #include "adns_9800_regs.h" 00009 #include "adns_9800_srom_a4.h" 00010 00011 /** 00012 * @brief Constructor 00013 */ 00014 adns_9800::adns_9800(PinName mosi, PinName miso, PinName sclk, PinName ncs) : m_spi(mosi, miso, sclk), m_ncs_pin(ncs) 00015 { 00016 m_spi.format(8, 3); // 8 bits with mode 3 =>Polarity = 1, Phase = 1 00017 m_spi.frequency(1000000); // 1 MHz 00018 00019 startup(); 00020 } 00021 00022 /** 00023 * @brief Destructor 00024 */ 00025 adns_9800::~adns_9800() 00026 { 00027 00028 } 00029 00030 /** 00031 * @brief returns true if a motion has occured since the last readout 00032 */ 00033 bool adns_9800::new_motion_data_available() 00034 { 00035 uint8_t const motion_reg = read_reg(REG_Motion); 00036 bool const new_data_available = (motion_reg & 0x80) > 0; 00037 return new_data_available; 00038 } 00039 00040 /** 00041 * @brief retrieves the latest delta values 00042 */ 00043 void adns_9800::get_delta_x_y(int16_t &delta_x, int16_t &delta_y) 00044 { 00045 uint16_t delta_x_l = (uint16_t)(read_reg(REG_Delta_X_L)); 00046 uint16_t delta_x_h = (uint16_t)(read_reg(REG_Delta_X_H)) << 8; 00047 delta_x = (int16_t)(delta_x_h | delta_x_l); 00048 00049 uint16_t delta_y_l = (uint16_t)(read_reg(REG_Delta_Y_L)); 00050 uint16_t delta_y_h = (uint16_t)(read_reg(REG_Delta_Y_H)) << 8; 00051 delta_y = (int16_t)(delta_y_h | delta_y_l); 00052 } 00053 00054 /** 00055 * @brief start and stop communication with the sensor by clearing/setting the ncs pin 00056 */ 00057 void adns_9800::com_begin() 00058 { 00059 m_ncs_pin = 0; 00060 } 00061 void adns_9800::com_end() 00062 { 00063 m_ncs_pin = 1; 00064 } 00065 00066 /** 00067 * @brief provide read/write access to a adns register 00068 */ 00069 uint8_t adns_9800::read_reg(uint8_t const address) 00070 { 00071 com_begin(); 00072 00073 // send adress of the register, with MSBit = 0 to indicate it's a read 00074 m_spi.write(address & 0x7f ); 00075 wait_us(100); // tSRAD 00076 // read data 00077 uint8_t data = m_spi.write(0); 00078 00079 wait_us(1); // tSCLK-NCS for read operation is 120ns 00080 com_end(); 00081 wait_us(19); // tSRW/tSRR (=20us) minus tSCLK-NCS 00082 00083 return data; 00084 } 00085 void adns_9800::write_reg(uint8_t const address, uint8_t const data) 00086 { 00087 com_begin(); 00088 00089 //send adress of the register, with MSBit = 1 to indicate it's a write 00090 m_spi.write(address | 0x80 ); 00091 //sent data 00092 m_spi.write(data); 00093 00094 wait_us(20); // tSCLK-NCS for write operation 00095 com_end(); 00096 wait_us(100); // tSWW/tSWR (=120us) minus tSCLK-NCS. Could be shortened, but is looks like a safe lower bound 00097 } 00098 00099 /** 00100 * @brief upload the firmware 00101 */ 00102 void adns_9800::upload_firmware() 00103 { 00104 // set the configuration_IV register in 3k firmware mode 00105 write_reg(REG_Configuration_IV, 0x02); // bit 1 = 1 for 3k mode, other bits are reserved 00106 00107 // write 0x1d in SROM_enable reg for initializing 00108 write_reg(REG_SROM_Enable, 0x1d); 00109 00110 // wait for more than one frame period 00111 wait_ms(10); // assume that the frame rate is as low as 100fps... even if it should never be that low 00112 00113 // write 0x18 to SROM_enable to start SROM download 00114 write_reg(REG_SROM_Enable, 0x18); 00115 00116 // write the SROM file (=firmware data) 00117 com_begin(); 00118 m_spi.write(REG_SROM_Load_Burst | 0x80); // write burst destination adress 00119 wait_us(15); 00120 00121 // send all bytes of the firmware 00122 for(int i = 0; i < firmware_length; i++) 00123 { 00124 m_spi.write(firmware_data[i]); 00125 wait_us(15); 00126 } 00127 00128 com_end(); 00129 } 00130 00131 /** 00132 * @brief starts the sensor up 00133 */ 00134 void adns_9800::startup() 00135 { 00136 com_end(); // ensure that the serial port is reset 00137 com_begin(); // ensure that the serial port is reset 00138 com_end(); // ensure that the serial port is reset 00139 write_reg(REG_Power_Up_Reset, 0x5a); // force reset 00140 wait_ms(50); // wait for it to reboot 00141 // read registers 0x02 to 0x06 (and discard the data) 00142 read_reg(REG_Motion); 00143 read_reg(REG_Delta_X_L); 00144 read_reg(REG_Delta_X_H); 00145 read_reg(REG_Delta_Y_L); 00146 read_reg(REG_Delta_Y_H); 00147 // upload the firmware 00148 upload_firmware(); 00149 wait_ms(10); 00150 //enable laser(bit 0 = 0b), in normal mode (bits 3,2,1 = 000b) 00151 // reading the actual value of the register is important because the real 00152 // default value is different from what is said in the datasheet, and if you 00153 // change the reserved bytes (like by writing 0x00...) it would not work. 00154 uint8_t laser_ctrl0 = read_reg(REG_LASER_CTRL0); 00155 write_reg(REG_LASER_CTRL0, laser_ctrl0 & 0xf0 ); 00156 00157 wait_ms(1); 00158 }
Generated on Wed Jul 13 2022 02:59:03 by 1.7.2