|
|
Netherlands
Offline
Tesla Member
Karma: 87
Posts: 9387
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #1 on: July 31, 2011, 01:09:33 pm » |
Your first link gives - page not found - error
|
|
|
|
|
Logged
|
|
|
|
|
SEA/PDX/CPH
Offline
Newbie
Karma: 0
Posts: 22
having fun!
|
 |
« Reply #2 on: July 31, 2011, 01:17:23 pm » |
|
|
|
|
|
Logged
|
|
|
|
|
Netherlands
Offline
Tesla Member
Karma: 87
Posts: 9387
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #3 on: July 31, 2011, 01:44:31 pm » |
From the link Description The ADNS-5050 is a mainstream, small form factor optical mouse sensor. It is a user-friendly product with many built-in features and optimized for LED-based corded products. The ADNS-5050 is capable of high-speed motion detection – up to 30ips and 8g. In addition, it has an on-chip oscil-lator and built-in LED driver to minimize external compo-nents. Frame rate is also adjusted internally.
The sensor is programmed via registers through a three-wire SPI interface. The PDF - http://www.avagotech.com/docs/AV02-1045EN - shows a schematic how to build a mouse (figure  and has a description of how a read operation should work. Can you post your code ?
|
|
|
|
|
Logged
|
|
|
|
|
SEA/PDX/CPH
Offline
Newbie
Karma: 0
Posts: 22
having fun!
|
 |
« Reply #4 on: July 31, 2011, 03:12:43 pm » |
Here's the code. The 3 wire SPI seems to be (unless I misunderstood) the CS pulled low, and then a clock and IO pin. I've set these on 2 and 3. The CS pin, I just set on 4. #define SCLK 3 #define SDIO 2
#define PRODUCT_ID 0x00 #define DELTA_Y_REG 0x03 #define DELTA_X_REG 0x04 #define SQUAL_REG 0x05 #define MAXIMUM_PIXEL_REG 0x08 #define MINIMUM_PIXEL_REG 0x0a #define PIXEL_SUM_REG 0x09 #define PIXEL_DATA_REG 0x0b #define SHUTTER_UPPER_REG 0x06 #define SHUTTER_LOWER_REG 0x07 #define RESET 0x3a #define CPI500v 0x00 #define CPI1000v 0x01
const int NCS = 4;
void setup() { Serial.begin(57600);
pinMode(NCS, OUTPUT); digitalWrite(NCS, LOW);
pinMode(SDIO, OUTPUT); pinMode(SCLK, OUTPUT);
delay(50); //from PD inactive (when NRESET pin is asserted high or write 0x5a to register 0x3a) to valid motion sync(); // //call reset writeReg(RESET, 0x5a); delay(50); // From NRESET pull high to valid mo tion, assuming VDD and motion is present.
}
void loop() { delay(100); Serial.print(readReg(PRODUCT_ID), DEC); // this should return 0x12 :/ }
//Essentially resets communication to the ADNS5050 void sync() { digitalWrite(SCLK, HIGH); delay(1); digitalWrite(SCLK, LOW); delay(1); digitalWrite(SCLK, HIGH); delay(100); }
//Reads a register from the ADNS5050 sensor. Returns the result to the calling function. char readReg(char address) { char value=0; pinMode(SDIO, OUTPUT); //Make sure the SDIO pin is set as an output. digitalWrite(SCLK, HIGH); //Make sure the clock is high. address &= 0x7F; //Make sure the highest bit of the address byte is '0' to indicate a read.
//Send the Address to the ADNS5050 for(int address_bit=7; address_bit >=0; address_bit--){ digitalWrite(SCLK, LOW); //Lower the clock pinMode(SDIO, OUTPUT); //Make sure the SDIO pin is set as an output. //If the current bit is a 1, set the SDIO pin. If not, clear the SDIO pin if(address & (1<<address_bit)){ digitalWrite(SDIO, HIGH); } else{ digitalWrite(SDIO, LOW);
} delayMicroseconds(10); digitalWrite(SCLK, HIGH); delayMicroseconds(10); } delayMicroseconds(120); //Allow extra time for ADNS5050 to transition the SDIO pin (per datasheet) //Make SDIO an input on the microcontroller pinMode(SDIO, INPUT); //Make sure the SDIO pin is set as an input. digitalWrite(SDIO, HIGH); //Enable the internal pull-up
//Send value byte for(int value_bit=7; value_bit >= 0; value_bit--){ digitalWrite(SCLK, LOW); //Lower the clock delayMicroseconds(10); //Allow the ADNS5050 to configure the SDIO pin digitalWrite(SCLK, HIGH); //Raise the clock delayMicroseconds(10); //If the SDIO pin is high, set the current bit in the 'value' variable. If low, leave the value bit default (0). //if((ADNS_PIN & (1<<ADNSSDIO)) == (1<<ADNSSDIO))value|=(1<<value_bit); if(digitalRead(SDIO))value |= (1<<value_bit); } return value; }
//Writes a value to a register on the ADNS5050. void writeReg(char address, char value) { pinMode(SDIO, OUTPUT); //Make sure the SDIO pin is set as an output. digitalWrite(SCLK, HIGH); //Make sure the clock is high. address |= 0x80; //the highest bit is '1' to indicate a write.
//Send Address for(int address_bit=7; address_bit >=0; address_bit--){ digitalWrite(SCLK, LOW); //Lower the clock delayMicroseconds(10); //small delay //If the current bit is a 1, set the SDIO pin. If not, clear the SDIO pin if(address & (1<<address_bit))digitalWrite(SDIO, HIGH); else digitalWrite(SDIO, LOW); delayMicroseconds(10); digitalWrite(SCLK, HIGH); delayMicroseconds(10);
}
//Send the Value byte to the ADNS5050
for(int value_bit=7; value_bit >= 0; value_bit--){ digitalWrite(SCLK, LOW); //Lower the clock //If the current bit is a 1, set the SDIO pin. If not, clear the SDIO pin if(value & (1<<value_bit))digitalWrite(SDIO, HIGH); else digitalWrite(SDIO, LOW); delayMicroseconds(10); digitalWrite(SCLK, HIGH); delayMicroseconds(10); }
}
|
|
|
|
|
Logged
|
|
|
|
|
|
|
Germany
Offline
Newbie
Karma: 0
Posts: 36
|
 |
« Reply #6 on: August 09, 2011, 06:22:42 am » |
I have worked on A5020 (with SCLK, NCS, SDIO). If your A5050 is similar than maybe I can help you out.
|
|
|
|
|
Logged
|
-- Nitin
|
|
|
|
SEA/PDX/CPH
Offline
Newbie
Karma: 0
Posts: 22
having fun!
|
 |
« Reply #7 on: August 10, 2011, 11:36:26 am » |
thanks nitin29. I'd love to hear any advice you have. I'm not sure if you meant that I should post all my code, but I'm going to go for it anyways. If anything in here looks wrong, I'd love to know about it. Thanks! #define SCLK 18 #define SDIO 19
#define PRODUCT_ID 0x00 // should be 0x12 #define PRODUCTID2 0x3e #define REVISION_ID 0x01 #define DELTA_Y_REG 0x03 #define DELTA_X_REG 0x04 #define SQUAL_REG 0x05 #define MAXIMUM_PIXEL_REG 0x08 #define MINIMUM_PIXEL_REG 0x0a #define PIXEL_SUM_REG 0x09 #define PIXEL_DATA_REG 0x0b #define SHUTTER_UPPER_REG 0x06 #define SHUTTER_LOWER_REG 0x07 #define RESET 0x3a #define CPI500v 0x00 #define CPI1000v 0x01
const int NCS = 4;
void setup() { Serial.begin(57600);
pinMode(SDIO, OUTPUT); pinMode(SCLK, OUTPUT);
pinMode(NCS, OUTPUT); digitalWrite(NCS, LOW); delayMicroseconds(2); digitalWrite(NCS, HIGH);
//call reset ADNS_write(RESET, 0x5a); delay(50); // From NRESET pull high to valid mo tion, assuming VDD and motion is present.
}
void loop() { delay(200); Serial.println(ADNS_read(PRODUCT_ID), BIN); }
void ADNS_write(unsigned char addr, unsigned char data) { char temp; int n;
digitalWrite(NCS, LOW);//nADNSCS = 0; // select the chip
temp = addr; digitalWrite(SCLK, LOW); // start clock low pinMode(SDIO, OUTPUT); // set data line for output for (n=0; n<8; n++) { digitalWrite(SCLK, LOW); pinMode(SDIO, OUTPUT); delayMicroseconds(1); if (temp & 0x80) digitalWrite(SDIO, HIGH); else digitalWrite(SDIO, LOW); temp = (temp << 1); digitalWrite(SCLK, HIGH); delayMicroseconds(1);//delayMicroseconds(1); // short clock pulse } temp = data; for (n=0; n<8; n++) { digitalWrite(SCLK, LOW); delayMicroseconds(1); if (temp & 0x80) digitalWrite(SDIO, HIGH); else digitalWrite(SDIO, LOW); temp = (temp << 1); digitalWrite(SCLK, HIGH); delayMicroseconds(1); // short clock pulse } delayMicroseconds(20); digitalWrite(NCS, HIGH); // de-select the chip }
byte ADNS_read(unsigned char addr) { byte temp; int n;
digitalWrite(NCS, LOW); // select the chip temp = addr; digitalWrite(SCLK, OUTPUT); // start clock low pinMode(SDIO, OUTPUT); // set data line for output for (n=0; n<8; n++) {
digitalWrite(SCLK, LOW); pinMode(SDIO, OUTPUT); if (temp & 0x80) { digitalWrite(SDIO, HIGH); } else { digitalWrite(SDIO, LOW); } temp = (temp << 1); delayMicroseconds(1); digitalWrite(SCLK, HIGH); delayMicroseconds(1); // short clock pulse } temp = 0; // This is a read, switch to input pinMode(SDIO, INPUT); delayMicroseconds(4); for (n=0; n<8; n++) { // read back the data digitalWrite(SCLK, LOW); delayMicroseconds(1); if(digitalRead(SDIO)) { // got a '1' temp |= 0x1; } temp = (temp << 1); // shift left digitalWrite(SCLK, HIGH); delayMicroseconds(1); } digitalWrite(NCS, HIGH); // de-select the chip return temp; }
I'm not able to get the chip to respond with anything at the moment, very frustrating as I've followed the data sheet very precisely.
|
|
|
|
|
Logged
|
|
|
|
|
SEA/PDX/CPH
Offline
Newbie
Karma: 0
Posts: 22
having fun!
|
 |
« Reply #8 on: August 20, 2011, 05:52:54 am » |
Came back to this and realized that I forgot to pull down the reset pin. Embarrassing, thanks for not embarrassing me futher by commenting on it  There were also some timing and read issues that I sorted out. Here's the code, and I'll put it wrapped nicely up on github. Big thanks to robtillaart for the copy/paste and internet tips. #define SCLK 18 #define SDIO 19 #define RESET 3 #define NCS 4
#define PRODUCT_ID 0x00 // should be 0x12 #define PRODUCTID2 0x3e #define REVISION_ID 0x01 #define DELTA_Y_REG 0x03 #define DELTA_X_REG 0x04 #define SQUAL_REG 0x05 #define MAXIMUM_PIXEL_REG 0x08 #define MINIMUM_PIXEL_REG 0x0a #define PIXEL_SUM_REG 0x09 #define PIXEL_DATA_REG 0x0b #define SHUTTER_UPPER_REG 0x06 #define SHUTTER_LOWER_REG 0x07 #define RESET 0x3a #define CPI500v 0x00 #define CPI1000v 0x01
#define NUM_PIXELS 361
byte pix[360];
void setup() { Serial.begin(57600);
pinMode(SDIO, OUTPUT); pinMode(SCLK, OUTPUT);
pinMode(RESET, OUTPUT); digitalWrite(RESET, LOW); sync(); ADNS_write(RESET, 0x5a); delay(50); // From NRESET pull high to valid mo tion, assuming VDD and motion is present.
}
void loop() { digitalWrite(RESET, LOW); delay(50); Serial.println(ADNS_read(MINIMUM_PIXEL_REG), BIN); //pixelGrab(); }
void sync() { pinMode(NCS, OUTPUT); digitalWrite(NCS, LOW); delayMicroseconds(2); digitalWrite(NCS, HIGH); }
void ADNS_write(unsigned char addr, unsigned char data) { char temp; int n;
digitalWrite(NCS, LOW);//nADNSCS = 0; // select the chip
temp = addr; digitalWrite(SCLK, LOW);//SCK = 0; // start clock low pinMode(SDIO, OUTPUT);//DATA_OUT; // set data line for output for (n=0; n<8; n++) { digitalWrite(SCLK, LOW);//SCK = 0; pinMode(SDIO, OUTPUT); delayMicroseconds(1); if (temp & 0x80) digitalWrite(SDIO, HIGH);//SDOUT = 1; else digitalWrite(SDIO, LOW);//SDOUT = 0; temp = (temp << 1); digitalWrite(SCLK, HIGH);//SCK = 1; delayMicroseconds(1);//delayMicroseconds(1); // short clock pulse } temp = data; for (n=0; n<8; n++) { digitalWrite(SCLK, LOW);//SCK = 0; delayMicroseconds(1); if (temp & 0x80) digitalWrite(SDIO, HIGH);//SDOUT = 1; else digitalWrite(SDIO, LOW);//SDOUT = 0; temp = (temp << 1); digitalWrite(SCLK, HIGH);//SCK = 1; delayMicroseconds(1); // short clock pulse } delayMicroseconds(20); digitalWrite(NCS, HIGH);//nADNSCS = 1; // de-select the chip }
byte ADNS_read(unsigned char addr) { byte temp; int n;
digitalWrite(NCS, LOW);//nADNSCS = 0; // select the chip temp = addr; digitalWrite(SCLK, OUTPUT); //SCK = 0; // start clock low pinMode(SDIO, OUTPUT); //DATA_OUT; // set data line for output for (n=0; n<8; n++) {
digitalWrite(SCLK, LOW);//SCK = 0; pinMode(SDIO, OUTPUT); //DATA_OUT; if (temp & 0x80) { digitalWrite(SDIO, HIGH);//SDOUT = 1; } else { digitalWrite(SDIO, LOW);//SDOUT = 0; } temp = (temp << 1); delayMicroseconds(1); digitalWrite(SCLK, HIGH); //SCK = 1; delayMicroseconds(1); // short clock pulse } temp = 0; // This is a read, switch to input pinMode(SDIO, INPUT); //DATA_IN; for (n=0; n<8; n++) { // read back the data digitalWrite(SCLK, LOW); if(digitalRead(SDIO)) {// got a '1' temp |= 0x1; } if( n != 7) temp = (temp << 1); // shift left digitalWrite(SCLK, HIGH); } digitalWrite(NCS, HIGH);// de-select the chip return temp; }
void pixelGrab() { int grabCount = 0; while( grabCount < NUM_PIXELS ) { pix[grabCount] = ADNS_read(PIXEL_DATA_REG); grabCount++; } }
|
|
|
|
« Last Edit: August 20, 2011, 05:58:13 am by joshuajnoble »
|
Logged
|
|
|
|
|
|