@krystian77, post #1
@krystian77, post #7
Opis sprzętu.
Prawy i lewy przycisk - standardowe działanie .
Przycisk na górze obudowy - przełącznik rozdzielczości (400,800,1200,1600 CPI)
Cztery niebieskie diody - wskaźnik aktualnej rozdzielczości.
Przycisk środkowy / kółko - aktualnie nie wykorzystywany (w trybie CDTV może emulować wciśnięcie prawego i lewego przycisku naraz).
Dwa Przyciski boczne - aktualnie nie wykorzystywane.
@sq7bti, post #9
@krystian77, post #10
In order to stay below the Class 1 power requirements, LASER_CTRL0 (register 0x1a), LASER_CTRL1 (register 0x1f ), LSRPWR_CFG0 (register 0x1c) and LSRPWR_CFG1 (register 0x1d) must be programmed to appropriate values. The ADNS-7550 integrated molded lead-frame DIP sensor which comprised of the sensor and VCSEL; is designed to maintain the output beam power within Class 1 requirements over components manufacturing tolerances [..]
[..] While a two port design will not win an award for first glance elegance compared to 1 port solutions like Cocolino (serial transfer of extra information) or Micromys (analog extra information) [..]
I think the Cocolino is an evolution of Eyetech's EZMouse, which was originally my design. What I did was have the microcontroller use PotX as a select signal, similar to how a Megadrive joypad works. a VBlank interrupt runs on the Amiga which briefly pulls PotX low. This signals the adapter to put alternative data on the mouse button lines and two of the direction lines (whichever two are mapped to the least significant bits of the mouse counters - I forget now), then an input handler generates NewMouse-style mousewheel events from these signals.
If memory serves, the Punchinello Mk II did some kind of simulation of analogue signals. The problem with this method is that the analogue counters on the Amiga count at different rates depending on the current screenmode.
@sq7bti, post #11
@sq7bti, post #12
//Ustawienie prądu lasera write2A7550(0x1a,0xc0); //11= Laser current range from approximately 4mA to 10mA _delay_us(30);/* min 30 us delay */ write2A7550(0x1f,0x00); _delay_us(30);/* min 30 us delay */ write2A7550(0x1c,0x92); //70% _delay_us(30);/* min 30 us delay */ write2A7550(0x1d,0x6d); _delay_us(30);/* min 30 us delay */
@krystian77, post #13
/* AVAGO ADNS-7550 The circuit: // Default SPI pinout for MSP430G2553 // MISO P1.7 // MOSI P1.6 // CLK P1.5 // set pin 8 as the slave select for the digital pot: // CS P2.0 */ //#define DEBUG 1 #define REG_PRODUCT_ID 0x00 #define REG_INV_PRODUCT_ID 0x3E #define REG_REVISION_ID 0x01 #define REG_INV_REVISION_ID 0x3F #define REG_MOTION 0x02 #define REG_DELTA_X 0x03 #define REG_DELTA_Y 0x04 #define REG_DELTA_XY_H 0x05 #define REG_SQUAL 0x06 #define REG_MAX_PIXEL 0x09 #define REG_PIXEL_SUM 0x0a #define REG_MIN_PIXEL 0x0b #define CONFIG2_400CPI 0x08 #define CONFIG2_800CPI 0x28 #define CONFIG2_1200CPI 0x48 #define CONFIG2_1600CPI 0x68 #define REG_CONFIGURATION2 0x12 #define LASER_3MA 0x00 #define LASER_5MA 0x30 #define LASER_10MA 0xC0 #define LASER_RANGE LASER_3MA /* 0x00 -> 33.6%, 0xff -> 100%*/ #define LASER_POWER 0x70 #define REG_LASER_CTRL0 0x1a #define REG_LASER_CTRL1 0x1f #define REG_LSRPWR_CFG0 0x1c #define REG_LSRPWR_CFG1 0x1d #define REG_OBSERVATION 0x2e #define REG_MBURST 0x42 #define REG_POWER_UP_RESET 0x3a // include the SPI library: #include <SPI.h> const int slaveSelectPin = SS; // MOTION pin set to trigger IRQ #define MOTION_PIN PUSH2 // quadrature outputs #define QXA P2_1 #define QXB P2_2 #define QYA P2_3 #define QYB P2_4 unsigned int motion = 0; unsigned int quad_x, quad_y; signed delta_x, delta_y; void setup() { // set the slaveSelectPin as an output: pinMode (slaveSelectPin, OUTPUT); // configure RED LED for output pinMode(RED_LED, OUTPUT); // initialize SPI: SPI.begin(); SPI.setClockDivider(16); // 1MHz SPI // Serial.begin(9600); // Serial.println("AVAGO SPI demo."); delayMicroseconds(250); digitalWrite(slaveSelectPin,LOW); delayMicroseconds(25); digitalWrite(slaveSelectPin,HIGH); delayMicroseconds(25); digitalWrite(slaveSelectPin,LOW); delayMicroseconds(25); digitalWrite(slaveSelectPin,HIGH); delayMicroseconds(25); #if DEBUG get_reg(REG_PRODUCT_ID); // 0x00 -> 0x32 get_reg(REG_INV_PRODUCT_ID); // 0x3e -> 0xfc get_reg(REG_REVISION_ID); // 0x01 -> 0x03 get_reg(REG_INV_REVISION_ID); // 0x3f -> 0xcd #endif // DEBUG // delayMicroseconds(250); set_reg(REG_POWER_UP_RESET, 0x5a); // (0x80 | 0x3a = 0xba) /* LASER_3MA LASER_5MA LASER_10MA */ set_reg(REG_LASER_CTRL0, LASER_RANGE); // 0x1a set_reg(REG_LASER_CTRL1, ~LASER_RANGE); // 0x1f set_reg(REG_LSRPWR_CFG0, LASER_POWER); // 0x1c set_reg(REG_LSRPWR_CFG1, ~LASER_POWER); // 0x1d /* CONFIG2_400CPI, CONFIG2_800CPI, CONFIG2_1200CPI, CONFIG2_1600CPI */ set_reg(REG_CONFIGURATION2, CONFIG2_1200CPI); // 0x12 // wait for at least one frame ? delayMicroseconds(250); // clear observation register set_reg(REG_OBSERVATION, 0x00); // wait for at least one frame delayMicroseconds(250); // and check observation register, all bits 0-3 must be set while((get_reg(REG_OBSERVATION) & 0x0F) != 0x0F) delayMicroseconds(500); get_reg(REG_MOTION); // read from registers one time regardless of the motion pin state 0x02 get_reg(REG_DELTA_X); // 0x03 get_reg(REG_DELTA_Y); // 0x04 get_reg(REG_DELTA_XY_H); // 0x05 set_reg(0x3c, 0x27); // 0xbc delayMicroseconds(10); set_reg(0x22, 0x0a); // 0xa2 delayMicroseconds(10); set_reg(0x21, 0x01); // 0xa1 delayMicroseconds(10); set_reg(0x3c, 0x32); // 0xbc delayMicroseconds(10); set_reg(0x23, 0x20); // 0xa3 delayMicroseconds(10); set_reg(0x3c, 0x05); // 0xbc delayMicroseconds(10); set_reg(0x37, 0xb9); // 0xb7 delayMicroseconds(250); // set motion pin as interrupt input FALLING pinMode(MOTION_PIN, INPUT_PULLUP); attachInterrupt(MOTION_PIN, set_motion, FALLING); // quadrature outputs pinMode(QXA, OUTPUT); pinMode(QXB, OUTPUT); pinMode(QYA, OUTPUT); pinMode(QYB, OUTPUT); digitalWrite(QXA, LOW); digitalWrite(QXB, LOW); digitalWrite(QYA, LOW); digitalWrite(QYB, LOW); quad_x = 0; quad_y = 0; delta_x = 0; delta_y = 0; } unsigned int reg_val, change_period; unsigned int delta_x_raw, delta_y_raw, delta_xy_raw; const unsigned int quad_state[] = { 0, 1, 3, 2 }; void loop() { if(motion) { digitalWrite(RED_LED, HIGH); #if 0 // get_reg(REG_OBSERVATION); // 0x2e // reg_val = get_reg(REG_MOTION); // 0x02 delta_x_raw = get_reg(REG_DELTA_X); // 0x03 delta_y_raw = get_reg(REG_DELTA_Y); // 0x04 delta_xy_raw = get_reg(REG_DELTA_XY_H); // 0x05 #else get_burst(); #if DEBUG get_reg(REG_SQUAL); // 0x06 get_reg(REG_MAX_PIXEL); // 0x09 get_reg(REG_PIXEL_SUM); // 0x0a get_reg(REG_MIN_PIXEL); // 0x0b #endif // DEBUG #endif delta_x_raw |= (delta_xy_raw >> 4) << 8; delta_y_raw |= (0x0F & delta_xy_raw) << 8; if(delta_x_raw < 0x800) { delta_x += delta_x_raw; } else { delta_x += ((signed int)delta_x_raw - 0x1000); } if(delta_y_raw < 0x800) { delta_y += delta_y_raw; } else { delta_y += ((signed int)delta_y_raw - 0x1000); } digitalWrite(RED_LED, LOW); --motion; change_period = min(750, max(5, 1650 / max(abs(delta_x),abs(delta_y)))); } else { if((delta_x != 0) || (delta_y != 0)) delayMicroseconds(change_period); } if(delta_x != 0) { if(delta_x > 0) { ++quad_x; --delta_x; } else { --quad_x; ++delta_x; } quad_x &= 0x03; digitalWrite(QXA, (quad_state[quad_x] & 0x01)?HIGH:LOW); digitalWrite(QXB, (quad_state[quad_x] & 0x02)?HIGH:LOW); } if(delta_y != 0) { if(delta_y > 0) { ++quad_y; --delta_y; } else { --quad_y; ++delta_y; } quad_y &= 0x03; digitalWrite(QYA, (quad_state[quad_y] & 0x01)?HIGH:LOW); digitalWrite(QYB, (quad_state[quad_y] & 0x02)?HIGH:LOW); } } void set_reg(int address, int value) { // take the SS pin low to select the chip: digitalWrite(slaveSelectPin,LOW); // send in the address and value via SPI: SPI.transfer(0x80 | address); SPI.transfer(value); // take the SS pin high to de-select the chip: digitalWrite(slaveSelectPin,HIGH); } int get_reg(int address) { unsigned int value = 0xFF; // take the SS pin low to select the chip: digitalWrite(slaveSelectPin,LOW); // send in the address and value via SPI: SPI.transfer(address); value = SPI.transfer(0xFF); // take the SS pin high to de-select the chip: digitalWrite(slaveSelectPin,HIGH); return value; } void get_burst() { unsigned int value = 0xFF; // take the SS pin low to select the chip: digitalWrite(slaveSelectPin,LOW); // send in the address and value via SPI: SPI.transfer(REG_MBURST); delayMicroseconds(4); value = SPI.transfer(0xFF); // MOTION 0x02 delta_x_raw = SPI.transfer(0xFF); // REG_DELTA_X 0x03 delta_y_raw = SPI.transfer(0xFF); // REG_DELTA_Y 0x04 delta_xy_raw = SPI.transfer(0xFF); // REG_DELTA_XY_H 0x05 // take the SS pin high to de-select the chip: digitalWrite(slaveSelectPin,HIGH); } void set_motion() { ++motion; }
@SimonGK, post #15
@sq7bti, post #16
@Rafał A-3000, post #18
@Rafael/ARMO, post #20
@sq7bti, post #21
@Rafał A-3000, post #28
@sq7bti, post #29