SPI>[0x9f r:4] <<< Check If I have a good SPI communication
/CS ENABLED
WRITE: 0x9F
READ: 0x1F 0x22 0x00 0x00
/CS DISABLED
SPI>[0x77 0 0 0 r:128] <<< Read in the security register
/CS ENABLED
WRITE: 0x77
WRITE: 0x00
WRITE: 0x00
WRITE: 0x00
READ: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0x0B 0x02 0x0E 0x05 0x3A 0x30 0x1F 0x22 0x00 0x00 0x5E 0x00 0xFF 0xFF 0xBC
0xFF 0x30 0x30 0x4D 0x32 0x36 0x36 0x39 0x38 0x07 0x5E 0x2D 0xFF 0xFF 0xFF 0xFF
0xFF 0x43 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF
/CS DISABLED
SPI>[0x9b 0x00 0x00 0x00 0x80 0x2D 0x22 0x6F 0x52 0x6F 0x98 0xA9 0x21 0x25 0x5E
0x2D 0x2D 0x31 0xD2 0x39 <<< Security register write start here
/CS ENABLED
WRITE: 0x9B
WRITE: 0x00
WRITE: 0x00
WRITE: 0x00
WRITE: 0x80
WRITE: 0x2D
WRITE: 0x22
WRITE: 0x6F
WRITE: 0x52
WRITE: 0x6F
WRITE: 0x98
WRITE: 0xA9
WRITE: 0x21
WRITE: 0x25
WRITE: 0x5E
WRITE: 0x2D
WRITE: 0x2D
WRITE: 0x31
WRITE: 0xD2
WRITE: 0x39
SPI>0x18 0x1C 0x63 0x0C 0x31 0x21 0x2D 0x39 0x90 0xDE 0x94 0x6F 0x6B 0x77 0x73 0
x7F 0x63 0x8C 0x88 0x84 <<< I have to break it in to many line because I can't copy/paste the whole data in
WRITE: 0x18
WRITE: 0x1C
WRITE: 0x63
WRITE: 0x0C
WRITE: 0x31
WRITE: 0x21
WRITE: 0x2D
WRITE: 0x39
WRITE: 0x90
WRITE: 0xDE
WRITE: 0x94
WRITE: 0x6F
WRITE: 0x6B
WRITE: 0x77
WRITE: 0x73
WRITE: 0x7F
WRITE: 0x63
WRITE: 0x8C
WRITE: 0x88
WRITE: 0x84
SPI>0x80 0x9C 0x98 0x94 0x90 0xAD 0xA9 0xA5 0xA1 0xBD 0xB9 0xB5 0xB1 0xCA 0xCE 0
xC2 0xC6 0xDA 0xDE 0xD2
WRITE: 0x80
WRITE: 0x9C
WRITE: 0x98
WRITE: 0x94
WRITE: 0x90
WRITE: 0xAD
WRITE: 0xA9
WRITE: 0xA5
WRITE: 0xA1
WRITE: 0xBD
WRITE: 0xB9
WRITE: 0xB5
WRITE: 0xB1
WRITE: 0xCA
WRITE: 0xCE
WRITE: 0xC2
WRITE: 0xC6
WRITE: 0xDA
WRITE: 0xDE
WRITE: 0xD2
SPI>0xD6 0xEB 0xEF 0xE3 0xE7 0xFB 0xFF 0xF3] <<< finish write the security register
WRITE: 0xD6
WRITE: 0xEB
WRITE: 0xEF
WRITE: 0xE3
WRITE: 0xE7
WRITE: 0xFB
WRITE: 0xFF
WRITE: 0xF3
/CS DISABLED
SPI>[0xd7 r]
/CS ENABLED
WRITE: 0xD7
READ: 0x8C
/CS DISABLED
SPI>[0x77 0 0 0 r:128] <<< read it back in.... nothing change!!!
/CS ENABLED
WRITE: 0x77
WRITE: 0x00
WRITE: 0x00
WRITE: 0x00
READ: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0x0B 0x02 0x0E 0x05 0x3A 0x30 0x1F 0x22 0x00 0x00 0x5E 0x00 0xFF 0xFF 0xBC
0xFF 0x30 0x30 0x4D 0x32 0x36 0x36 0x39 0x38 0x07 0x5E 0x2D 0xFF 0xFF 0xFF 0xFF
0xFF 0x43 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF
/CS DISABLED
SPI>
Am I doing something wrong?
Am I doing something wrong?
If it isn't working, then you are certainly doing something wrong. Don't know what though.
Have you tried more than once to program the security register? You only get one chance to get it right. If you screw up by not getting it just right the first time, you've got to throw the chip away and try again on a new one.
I would suggest trying something simpler like a page write (http://dangerousprototypes.com/docs/AT45DB041D_4Mbit_flash_memory#Page_write) and get that working first before trying again on a new chip.
So you built your own logger with Xbee communication? Sweet.
SPI>(1)
Sniffer
Any key to exit
[0x6B(0xFF)0x80(0xC6)][0x3B(0x7F)0x80(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0x
FF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0x
FF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0x
FF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0x
FF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0x
FF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0x
FF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0x
FF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0x
FF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0x85)0x00(0x
81)0x00(0x07)0x00(0x02)0x00(0x9D)0x00(0x18)0x00(0x0F)0x00(0x91)0x00(0x00)0x00(0x
00)0x00(0x2F)0x00(0x00)0x00(0x7F)0x00(0xFF)0x00(0xDE)0x00(0x7F)0x00(0x98)0x00(0x
18)0x00(0x26)0x00(0x99)0x00(0x1B)0x00(0x1B)0x00(0x1C)0x00(0x9C)0x00(0x03)0x00(0x
AF)0x00(0x16)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xA1)0x00(0x
FF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0x
FF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0x
FF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0x
FF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)0x00(0xFF)]
I am not familiar with your test equipment, but it looks to me like the trigger point is too slow or the sampling rate is off (or both).
I had odd results when I used my Bus Pirate as well. I might play around with this on the weekend and will post here if I figure out the problem.
I am not familiar with your test equipment, but it looks to me like the trigger point is too slow or the sampling rate is off (or both).
I had odd results when I used my Bus Pirate as well. I might play around with this on the weekend and will post here if I figure out the problem.
[dekay@laptop dataflash]$ python2 spi_test.py
Entering binmode: OK.
Entering raw SPI mode: OK.
Configuring SPI.
Chip Status: 0x8c
Chip ID: 0x1f 0x22 0x00 0x00
Reading Security Register:
[ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ]
[ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ]
[ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ]
[ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ]
[ 0x0b 0x01 0x1e 0x0e 0x13 0x15 0x1f 0x22 0x00 0x00 0x56 0x00 0xff 0xff 0xd8 0xff ]
[ 0x30 0x30 0x4d 0x32 0x35 0x36 0x32 0x36 0x08 0x31 0x34 0xff 0xff 0xff 0xff 0xff ]
[ 0x43 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ]
[ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ]
I've sorted out my Bus Pirate problem.
I think that Davis uses both sections of security register (0..63 and 64..127) for decryption, because it makes no sense to use only a static key in the 1st block of security register to be save. My opinion is that Davis uses the unique ID in the second part for encryption of a view bytes in the first part of security register.
If I empathize me with the part of Davis, I would write some coded product info (serial, revision, production date,...) + encrypted info from 2nd part of security register (unique ID) into this 1st part of security register.
But to prove this theory we need at least a second owner of a green dot datalogger which is able to read out security register to compare the data of the 0..63 byte of security register with data of rdsman. I fear that this 0..63 bytes differ for every green dot datalogger.
BR
franzz
The key rdsman discovered doesn't show up in the new firmware, so there is likely a computation involved rather than a static key.
Anybody know when the console reports the incompatible logger error? After the first beep? Second beep?
I think that Davis uses both sections of security register (0..63 and 64..127) for decryption, because it makes no sense to use only a static key in the 1st block of security register to be save. My opinion is that Davis uses the unique ID in the second part for encryption of a view bytes in the first part of security register.
If I empathize me with the part of Davis, I would write some coded product info (serial, revision, production date,...) + encrypted info from 2nd part of security register (unique ID) into this 1st part of security register.
But to prove this theory we need at least a second owner of a green dot datalogger which is able to read out security register to compare the data of the 0..63 byte of security register with data of rdsman. I fear that this 0..63 bytes differ for every green dot datalogger.
BR
franzz
One more concern rdsman, While I'm waiting for my bus pirate I have some feeling that Davis might be using the Security Register from bit 65 to 127, which is unique for every single 45DB to calculate what is to be programmed in the first 64 bit of the Security Register. If my concern becoming true it would be nightmare.
Maybe I just think too much.
Status Register (0xD7): 0x8C
Manufacturer and Device ID Information (0x9F): 0x1F 0x22 0x00 0x00
Sector Lockdown Register (0x35): 0x00 0x00 0x00 0x00
Security Register (0x77):
0x80 0x2D 0x22 0x6F 0x52 0x6F 0x98 0xA9 0x21 0x25 0x5E 0x2D 0x2D 0x31 0xD2 0x39
0x18 0x1C 0x63 0x0C 0x31 0x21 0x2D 0x39 0x90 0xDE 0x94 0x6F 0x6B 0x77 0x73 0x7F
0x63 0x8C 0x88 0x84 0x80 0x9C 0x98 0x94 0x90 0xAD 0xA9 0xA5 0xA1 0xBD 0xB9 0xB5
0xB1 0xCA 0xCE 0xC2 0xC6 0xDA 0xDE 0xD2 0xD6 0xEB 0xEF 0xE3 0xE7 0xFB 0xFF 0xF3
0x0B 0x02 0x16 0x17 0x11 0x15 0x1F 0x22 0x00 0x00 0x46 0x00 0xFF 0xFF 0xAC 0xFF
0x30 0x30 0x4D 0x32 0x36 0x39 0x37 0x31 0x0F 0x1C 0x0C 0xFF 0xFF 0xFF 0xFF 0xFF
0x3F 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
It might be possible to just "spoof" the console into enabling the serial port. This would only interest people that don't need the full logging capability. You could for example use a setup that provides a USB interface or the XBee footprint. Write some code and off you go! Here is just one example:Good point, and thinking about it using the chip select line you could enable logging after the link is opened.
rdsman, Is it possible to plug in the buspirate and spoof the console (in the power on phase), then take off the buspirate and plug in the NON GreenDot logger (never stop the power to the console). Just some thing like tether jailbreak.
/*
Arduino program to spoof the Green Dot Logger
SPI interface. (Causes the serial interface
to be enabled?)
by rdsman
20 FEB 2013
YOU MUST USE AN ARDUINO RUNNING ON 3.3 VOLTS
OR PROVIDE LOGIC LEVEL CONVERSION!
YOU HAVE BEEN WARNED!
*/
#include "Arduino.h"
//
// Arduino Definitions.
//
#define RX 0 // The interface pins are defined here.
#define TX 1
#define SS 10
#define MOSI 11
#define MISO 12
#define SCK 13
//
// 45DB011D Definitions.
//
#define STATUS_REGISTER 0xD7
#define STATUS_WORD 0x8C
#define SECURITY_REGISTER 0x77
//
const byte SECURITY_RESPONSE[128] =
{
0x80, 0x2D, 0x22, 0x6F, 0x52, 0x6F, 0x98, 0xA9, 0x21, 0x25, 0x5E, 0x2D, 0x2D, 0x31, 0xD2, 0x39,
0x18, 0x1C, 0x63, 0x0C, 0x31, 0x21, 0x2D, 0x39, 0x90, 0xDE, 0x94, 0x6F, 0x6B, 0x77, 0x73, 0x7F,
0x63, 0x8C, 0x88, 0x84, 0x80, 0x9C, 0x98, 0x94, 0x90, 0xAD, 0xA9, 0xA5, 0xA1, 0xBD, 0xB9, 0xB5,
0xB1, 0xCA, 0xCE, 0xC2, 0xC6, 0xDA, 0xDE, 0xD2, 0xD6, 0xEB, 0xEF, 0xE3, 0xE7, 0xFB, 0xFF, 0xF3,
0x0B, 0x02, 0x16, 0x17, 0x11, 0x15, 0x1F, 0x22, 0x00, 0x00, 0x46, 0x00, 0xFF, 0xFF, 0xAC, 0xFF,
0x30, 0x30, 0x4D, 0x32, 0x36, 0x39, 0x37, 0x31, 0x0F, 0x1C, 0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
//
// Setup Loop.
//
void setup()
{
delay(100);
initialize();
delay(100);
}
//
// Main Loop.
//
void loop() // run over and over
{
}
//
// Setup the microprocessor.
//
void initialize()
{
byte temp;
byte sreg = SREG;
cli(); // Disable global interrupts while we make our changes.
pinMode(RX, INPUT); // Set up the Serial data pins. (Not used by the processor,
pinMode(TX, INPUT); // simply passed through to the USB interface.)
pinMode(SS, INPUT); // Set up the SPI pins.
pinMode(MOSI, INPUT);
pinMode(MISO, OUTPUT);
pinMode(SCK, INPUT);
// Turn off everything that might interfere!
ADCSRA = 0x00; // Disable the analog comparator.
TCCR1B = 0x00; // Disable Timer 1.
TCCR2B = 0x00; // Disable Timer 2.
SPCR = (1 << SPIE | 1 << SPE); // Initialize the SPI in Slave Mode.
temp = SPSR; // Clear SPSR.
temp = SPDR; // Flush SPDR.
SREG = sreg; // Enable global interrupts.
}
//
// SPI Interrupt Service Routine.
//
ISR(SPI_STC_vect)
{
volatile byte temp = SPDR;
if (temp == STATUS_REGISTER) // Is it reading the Status Register?
{
SPDR = STATUS_WORD; // If so, send the Status Word.
while(!(SPSR & (1 << SPIF)));
temp = SPSR; // Clear SPIF.
temp = SPDR; // Flush SPDR.
return;
}
if (temp == SECURITY_REGISTER) // Is it reading the Security Register?
{
for (int i = 0; i < 3; i++) // If so, rx/tx three dummy bytes.
{
SPDR = 0x00;
while(!(SPSR & (1 << SPIF)));
temp = SPSR;
temp = SPDR;
if (temp != 0x00) // Check for all 0x00's.
return;
}
for (int i = 0; i < 128; i++) // Dump the Security Register.
{
SPDR = SECURITY_RESPONSE[i];
while(!(SPSR & (1 << SPIF)));
temp = SPSR;
temp = SPDR;
}
SPCR == 0x00; // Disable the SPI.
}
}
//
// The End.
//
Due to the fact that most of unique ID bytes have the value 0xFF I have determined that the corresponding byte in area 1-64 is encrypted with this byte value and the position of the byte, but there is no cross encryption to other bytes.
If you take all the 0xFF and put it into the table below, you can see that there is a pattern. Other values than 0xFF will also take place in this pattern. (see attached table).
Only 64 bytes of 256 possibilities will be used and each value will be used 1 time for a specific unique ID byte depending on the position. All used bytes are highlighted in picture. For all 0xFF and the known position it is very easy to get the right value with this table. For all other byte values the Arduino software from rdsman could be extended to change one byte of know unique ID and make a try which encrypted byte will be used for decryption (it could be only one of 64 bytes)
This sounds great.
If it is possible to emulate eeprom access to enable serial line, it could be possible to downgrade FW to 1.9.
It gives us also the possibility to play with different values in security table.
I've analyzed the hex codes from security region bytes 1-64 and the connection to unique ID in bytes 65-128:
Due to the fact that most of unique ID bytes have the value 0xFF I have determined that the corresponding byte in area 1-64 is encrypted with this byte value and the position of the byte, but there is no cross encryption to other bytes.
If you take all the 0xFF and put it into the table below, you can see that there is a pattern. Other values than 0xFF will also take place in this pattern. (see attached table).
Only 64 bytes of 256 possibilities will be used and each value will be used 1 time for a specific unique ID byte depending on the position. All used bytes are highlighted in picture. For all 0xFF and the known position it is very easy to get the right value with this table. For all other byte values the Arduino software from rdsman could be extended to change one byte of know unique ID and make a try which encrypted byte will be used for decryption (it could be only one of 64 bytes)
E.g. change byte 65 from 0x0B to 0x00 and try to change byte 1 to one of the 64 possible bytes. I assume that this procedure could be done automatically by arduino because the RESET of Davis console is also available on the datalogger plug. If encrypted byte was found for 0x00 on the first position let's change the 66th byte to 0x00. Now there are only 63 possibilities left for this position. After finding out 2nd position let's go to byte 67 and do the same try with 3rd byte and 62 left bytes.
If you have any questions please let me know to explain it more detailed.
BR
franzz
For all 0xFF and the known position it is very easy to get the right value with this table. For all other byte values the Arduino software from rdsman could be extended to change one byte of know unique ID and make a try which encrypted byte will be used for decryption (it could be only one of 64 bytes)
=D> Thanks franzz,
As I understand If I have a 45DB that have the unique ID of all 0x00 the 128 byte security register should be look like this
00 04 08 0C 10 14 18 1C 21 25 29 2D 31 35 39 3D 42 45 4A 4E 52 56 5A 5E 63 67 6B 6F 73 77 7B 7F
80 84 88 8C 90 94 98 9C A1 A5 A9 AD B1 B5 B9 BD C2 C6 CA CE D2 D6 DA DE E3 E7 EB EF F3 F7 FB FF
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Am I correct?
Franz
I put together a table in Excel from 0x0 to 0xff and highlighted in yellow the actual values mapping to 0xff. These hex values are left justified in the attached image. Like your picture, there is clearly a pattern. Then I show numbers right justified representing the index in the 64 byte factory written key where the 0xff values appear. The indexes don't increment regularly from one row to the other. Instead, there are differences between rows. Do you understand how to predict the next index?
e.g. Row 21: the index into the factory key is 44, 43, 42, 41.
Row 29: the index into the factory key is 59, 60, 57, 58.
/*
* compiler: Microchip XC8
*
* PIC12F1822
* +--+ +--+
* VCC |1 ~ 8| GND
* |2 7| SDO
* |3 6| SCK
* SS |4 5| SDI
* +-------+
*/
#include <pic.h>
#pragma config FOSC=INTOSC,PLLEN=ON,BOREN=ON,BORV=HI,WDTE=OFF,MCLRE=OFF,LVP=OFF
//
// 45DB011D Definitions.
//
#define STATUS_REGISTER 0xD7
#define STATUS_WORD 0x8C
#define SECURITY_REGISTER 0x77
//
const unsigned char SECURITY_RESPONSE[128] =
{
0x80, 0x2D, 0x22, 0x6F, 0x52, 0x6F, 0x98, 0xA9, 0x21, 0x25, 0x5E, 0x2D, 0x2D, 0x31, 0xD2, 0x39,
0x18, 0x1C, 0x63, 0x0C, 0x31, 0x21, 0x2D, 0x39, 0x90, 0xDE, 0x94, 0x6F, 0x6B, 0x77, 0x73, 0x7F,
0x63, 0x8C, 0x88, 0x84, 0x80, 0x9C, 0x98, 0x94, 0x90, 0xAD, 0xA9, 0xA5, 0xA1, 0xBD, 0xB9, 0xB5,
0xB1, 0xCA, 0xCE, 0xC2, 0xC6, 0xDA, 0xDE, 0xD2, 0xD6, 0xEB, 0xEF, 0xE3, 0xE7, 0xFB, 0xFF, 0xF3,
0x0B, 0x02, 0x16, 0x17, 0x11, 0x15, 0x1F, 0x22, 0x00, 0x00, 0x46, 0x00, 0xFF, 0xFF, 0xAC, 0xFF,
0x30, 0x30, 0x4D, 0x32, 0x36, 0x39, 0x37, 0x31, 0x0F, 0x1C, 0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
void main()
{
unsigned char i;
unsigned char cmd, tmp;
OSCCON = 0b11110000; // set a system clock 8MHz x4PLL = 32MHz
ANSELA = 0; // all digital I/O
TRISA = 0b11111110; // SDO pin set to output
SSP1STAT = 0b00000000; // initialize MSSP module
SSP1CON1 = 0b00110100;
SSP1BUF = 0;
while(1){
reset:
while(!BF); // wait a command
if(RA3) goto reset;
cmd = SSP1BUF;
switch( cmd ){
case STATUS_REGISTER:
SSP1BUF = STATUS_WORD; // response word
SSP1IF = 0;
while(!BF); // wait a sending
if(RA3) goto reset;
tmp = SSP1BUF;
SSP1IF = 0;
break;
case SECURITY_REGISTER:
for(i = 0; i < 3; i++){ // put a dummy word
SSP1BUF = 0;
SSP1IF = 0;
while(!BF);
if(RA3) goto reset;
tmp = SSP1BUF;
}
for(i = 0; i < 128; i++){ // put a security response
SSP1BUF = SECURITY_RESPONSE[i];
SSP1IF = 0;
while(!BF);
if(RA3) goto reset;
tmp = SSP1BUF;
}
SSP1IF = 0;
break;
default:
break;
}
}
}
kashima & torkelmj:
The fact that you have it working is good news. It would also be nice to know if it reads the entire Security Register or perhaps just the first 10 bytes. Just a guess!
Since it now appears to confirm that Davis is only using the Security Register, it gets those who desire back to building their own logger. Just take a blank 45DB011D and program the Security Register with an Arduino, Bus Pirate, etc.
Folks,I am working on this as I type....
Does this mean we are close to getting the RS-232 comms. port working on the newer green dot Vantage products? That
indeed would be great news. I have my ISS working via 3DR as per Andrew Tridge solution but their are a few readings from the Console
are not available...have the rs-232 port working would be magic.
It would be easier for us if we could break the code for the EEPROM, but not much easier. It doesn't seem worth the effort anymore :-)
It would also be nice to know if it reads the entire Security Register or perhaps just the first 10 bytes. Just a guess!
It would also be nice to know if it reads the entire Security Register or perhaps just the first 10 bytes.
I may misunderstand your question here;
Building on the work already presented by others here, my own pre-Christmas tinkering, handwritten notes and experiences from running 15+ VP2 stations at different locations utilizing non-Davis equipment to gather, forward and store data (including the troubles we started running into when we found ourselves in need of a replacement console which happened to have FW v. 3.00 installed) - I've gathered what I believe is the essential stuff into a single document. For anyone with an interest in gaining access to the console's serial line using simple equipment and techniques, http://meteo.annoyingdesigns.com/DavisSPI.pdf may be just what you need to get started. Having run the "ATtiny-variant" for half a year now, concurrently at 15+ different sites, I'm confident that it works as it should.
- the absurdly excessive yet well-placed vitriol dripping from every page \:D/
Hi,
First big thanks to all who have contributed to this! I see that many of you have invested a large amount of time to figure this out. I received a Davis Vantage Vue with the dreaded firmware V3.0, which (given the incredibly ugly looking console) has no other function than to stream the data to some place where it can be processed. I currently use a Kindle PW and an old Oregon Scientific 200A to display the readings in my living room and I upload it to a web-page. I’m happy to share this project if someone is interested.
Other things I have observed is that the slave select (SS, pin 1 on the console) goes to high when I power up the console, but then it stays high even during the SPI transmission. That’s unexpected! The SPI clock line initially idles high, but after the first byte it seems to idle low (again, please see the pictures: top trace is SPI clock (pin 2 on the console) and the bottom is either MISO or MOSI (as defined on the console side). All signals are measured directly at the pins of the MCU to make sure that the signals arrive undistorted, which seems to be the case. I use 2-3 inch wires between the console and the MCU.
Please do!I will as soon as I figure this one out ](*,)
The console also uses SPI to talk to the radio chip, but it uses a different pin off the MCU for SS that is not brought out to the rear connector. The unexpected is actually very expected :-)Does that mean that the Vue would need another datalogger than the VP? I would think that the flash chip would not respond without the /CS pulled low. Or maybe there are redundant lines on the data logger board. Would you happen to know which pin on the ATMega would be used for the SS in the Vue? I could solder a line directly on the chip inside the console. I am planning to put the MCU inside anyway so I get an unlocked console without the extra board hanging off the back.
[/quote]The console also uses SPI to talk to the radio chip, but it uses a different pin off the MCU for SS that is not brought out to the rear connector. The unexpected is actually very expected :-)Does that mean that the Vue would need another datalogger than the VP? I would think that the flash chip would not respond without the /CS pulled low. Or maybe there are redundant lines on the data logger board. Would you happen to know which pin on the ATMega would be used for the SS in the Vue? I could solder a line directly on the chip inside the console. I am planning to put the MCU inside anyway so I get an unlocked console without the extra board hanging off the back.
Maybe I should use another MCU as a logic analyzer.
//***************************************************************************************
// MSP430 Unlock Davis
//
// Description: Unlock the Davis Vantage Vue/Pro(TM) Serial Port
// This code was based on the PIC version from kashima
//
// Slave Master
// MSP430G2231 Davis Weather Station Console
// ----------------- -----------------
// | | | |
// | | | |
// | | | |
// | | /|\ | |
// | RST/NMI|--- | |
// LED <-|P1.0 | | |
// | | | |
// | SDI/P1.7|<-------|3/MOSI |
// | SDO/P1.6|------->|4/MISO |
// | SCLK/P1.5|<-------|2/SCLK |
// | SS/P1.1|<-------|1/SS |
// | | | |
// ----------------- -----------------
//
//
// Special thanks to (in no particular order): DeKay, rdsman, kashima, iBangkok24, franzz, belfryboy, and all the other nice folks over at WXForum.net
//
// Built with Code Composer Studio v5
//***************************************************************************************
#include <msp430.h>
#define STATUS_REGISTER 0xD7 //215
#define STATUS_WORD 0x8C //140
#define SECURITY_REGISTER 0x77 //119
#define SS (P1IN&0x02) //Slave Select pin: Slave is addressed if SS reads zero
const unsigned char SECURITY_RESPONSE[128] =
{
0x80, 0x2D, 0x22, 0x6F, 0x52, 0x6F, 0x98, 0xA9, 0x21, 0x25, 0x5E, 0x2D, 0x2D, 0x31, 0xD2, 0x39,
0x18, 0x1C, 0x63, 0x0C, 0x31, 0x21, 0x2D, 0x39, 0x90, 0xDE, 0x94, 0x6F, 0x6B, 0x77, 0x73, 0x7F,
0x63, 0x8C, 0x88, 0x84, 0x80, 0x9C, 0x98, 0x94, 0x90, 0xAD, 0xA9, 0xA5, 0xA1, 0xBD, 0xB9, 0xB5,
0xB1, 0xCA, 0xCE, 0xC2, 0xC6, 0xDA, 0xDE, 0xD2, 0xD6, 0xEB, 0xEF, 0xE3, 0xE7, 0xFB, 0xFF, 0xF3,
0x0B, 0x02, 0x16, 0x17, 0x11, 0x15, 0x1F, 0x22, 0x00, 0x00, 0x46, 0x00, 0xFF, 0xFF, 0xAC, 0xFF,
0x30, 0x30, 0x4D, 0x32, 0x36, 0x39, 0x37, 0x31, 0x0F, 0x1C, 0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
volatile unsigned char i;
volatile unsigned char dbg_cnt,statcnt,seccnt; //for debugging
volatile unsigned char cmd;
int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
BCSCTL1 = 0x8f; //16 MHz
DCOCTL = 0x60;
P1OUT = 0x10; //0x10 // P1.4 set
P1REN |= 0x10; //0x30; // pull-up. P1.4 must be pulled up
P1DIR = 0x01; //0x01; // P1.0 output, else input. MISO will be controlled below
//just to save power:
P2OUT = 0x00; //all low
P2REN |= 0xff; //pull-downs
P2DIR = 0x00; //all in
dbg_cnt=statcnt=seccnt=0; //just for debugging
P1OUT &= ~0x01;
USICTL0 |= USIPE7 + USIPE6 + USIPE5 + USIOE + USIGE; // Port, SPI slave
// USICTL1 |= USICKPH; //clockphase
// USICKCTL |= USICKPL; //clock inactive state is high
// (I tried all the combinations of USICKPH, USICKPL, and USIGE a few dozen times.)
USICTL0 &= ~USISWRST; // USI released for operation
P1OUT |= 0x01;
while(SS==0); //wait until ss goes high (idle). This ensures that we wait until the console is powered up
USISRL = 0x00; // init-load data
USICNT = 8; // ready SPI for 8 bit reception
P1OUT &= ~0x01;
while(1){
reset:
USICTL0 &= ~USIOE; //release MISO line
USICNT = 8;
USISRL = 0;
while(USICNT){if(SS)USICNT = 8;} // wait for a command
cmd = USISRL;
dbg_cnt++;
if(cmd==215) //status byte
{
USICTL0 |= USIOE; //turn on MISO (output)
USISRL = STATUS_WORD; // response word
USICNT = 8;
statcnt++; //for debugging
while(USICNT); // wait a sending
if(SS) goto reset;
statcnt++;
}
else
if(cmd==119) //status register
{
USICTL0 |= USIOE;
for(i = 0; i < 3; i++) // put a dummy word
{
USISRL = 0;
USICNT = 8;
seccnt++; //for debugging
while(USICNT);
if(SS) goto reset;
}
for(i = 0; i < 128; i++) // put a security response
{
USISRL = SECURITY_RESPONSE[i];
USICNT = 8;
seccnt++; //for debugging
while(USICNT);
if(SS) goto reset;
}
}
}
}
Well done, travisc!
I received the proto board today. The VP2 arrived the other day so I should be all set to test this tonight. I've already made the changes to the source code and tested it on a little console simulator I made. Everything looks great on the logic analyzer. I'll post again tonight with some more pics and results.(http://www.frightideas.com/hobbies/logger/proto_board.jpg)
@DeKay:
You don't happen to have a Logic capture session saved from a valid green dot logger do you? I'd love to see the timing on a valid logger so I could make sure this setup emulates it as closely as possible.
Travisc...great work. Are u a son of Torkel ???
Awesome work here, travisc. I'm happy to try and help out. However, I don't have a green dot logger. My console predates all this stuff, and I've never owned a real Davis logger. So what I'm about to provide here probably isn't useful.Thanks DeKay! I think I confused myself there. I remembered seeing a green dot logger in a screen shot, but that must have been in torkelmj's PDF. Sorry, still getting familiar with the users here. :) In any case, the data you sent is useful to compare timing. Thank you.
I'd rather say like-minded. FWIW, apart from the PIC used here - I used the same approach when I assembled a data logger. Didn't turn out as appealing as this one, though - just wanted a proof-of-concept. Travisc has done a great job with this project! Now, what will be the next move from Hayward?Thanks torkelmj! Your excellent research on this topic made this possible. :grin:
Mission Accomplished. :grin:
<snip>
I'll make the final changes to the gerbers, clean up the code, then share it here tomorrow.
Awesome. I feel a bit more comfortable looking at actually buying a Vantage Pro now I know that I have a chance at not having to fork out for an expensive logger too.I agree. I wouldn't have just bought one if I had to shell out $150 for a logger either.
Code: [Select]/*
Arduino program to spoof the Green Dot Logger
SPI interface. (Causes the serial interface
to be enabled?)
by rdsman
20 FEB 2013
[...]
It needs to be tried out by someone!
I tried the code with an Envoy without success.
I'd try sniffing the Envoy by itself using the Bus Pirate to confirm the settings on the Bus Pirate are setup correctly.
QuoteI'd try sniffing the Envoy by itself using the Bus Pirate to confirm the settings on the Bus Pirate are setup correctly.
I second that opinion! Let us know when you have this working. DeKay can most likely help you with this...........
Bad advice! I've had issues with my Bus Pirate and SPI that I've never been able to sort out.
Two questions...
- Is it possible that you also publish the Gerbers of the first version of the board that was working?
- Is it possible that you can provide me with a programmed PIC for that version 1 board?
@travisc: Great Work!
I've one suggestion for implementation in PIC controler: If you want to use security registers for emulation which are not a dump of an existing Green Dot Logger but which are working with Console FW versions >= 3.0, you can use this security register content:
0xF7 , 0x00 , 0x04 , 0x08 , 0x0C , 0x10 , 0x14 , 0x18 , 0x1C , 0x21 , 0x25 , 0x29 , 0x2D , 0x31 , 0x35 , 0x39 ,
0x3D , 0x46 , 0x42 , 0x4E , 0x4A , 0x56 , 0x52 , 0x5E , 0x5A , 0x67 , 0x63 , 0x6F , 0x6B , 0x77 , 0x73 , 0x7F ,
0x7B , 0x8C , 0x88 , 0x84 , 0x80 , 0x9C , 0x98 , 0x94 , 0x90 , 0xAD , 0xA9 , 0xA5 , 0xA1 , 0xBD , 0xB9 , 0xB5 ,
0xB1 , 0xCA , 0xCE , 0xC2 , 0xC6 , 0xDA , 0xDE , 0xD2 , 0xD6 , 0xEB , 0xEF , 0xE3 , 0xE7 , 0xFB , 0xFF , 0xF3 ,
0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF
As you can see the unique ID range (byte 64-123) is 0xFF which is for sure not implemented in any davis flash memory. The first range of the security registers (byte 0-63) is tuned to work with security checks of Davis Console. I've tested this configuration with Console FW 3.0 and Attiny85 (emulation software from torkelmj)
BR
franzz
@Franzz: could you share how you figured this out? Have you determined the algorithm Davis uses to determine the security register?
Franzz,
I'm using the Torkel solution on a Vantage Vue in combination with a RaspberryPi, it is working perfectly.
There was a minor issue in the programming, the Vantage Vue didn't work with the code Torkel supplied, but I solved that and Torkel confirmed that this solution worked also on his Pro2.
I asked myself...If the serial solution that Torkel supplied is working fine (without memory) and also the solution that Travs supplied is working, why do I need the extra sucurity registers?
John
To show you that I'm not kidding, if you give me any combination of 64 bytes I can post the corresponding 64 bytes obtained by the algorithm.
Awesome. Awaiting a description of the algorithm. And just as interesting: how you found it.
Cheers,
T.
is there also a universal pattern that we can always use
May I ask how you figured out the algorithm?
...and when the world will actually get to see it?
No. The "Davis programmed" 64 bytes (first 64 bytes of Adesto Chip "Security Register") are always obtained from the Adesto chip "Factory Programmed" 64 bytes
Am I wrong? What do you think about this?
QuoteNo. The "Davis programmed" 64 bytes (first 64 bytes of Adesto Chip "Security Register") are always obtained from the Adesto chip "Factory Programmed" 64 bytes
But I could read it all wrong :roll:
So with the solution you and also Travis supplied every console can be used
u8 const GreenDot_Table[256] =
{
0x00, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x18, 0x1C, 0x21, 0x25, 0x29, 0x2D, 0x31, 0x35, 0x39, 0x3D,
0x46, 0x42, 0x4E, 0x4A, 0x56, 0x52, 0x5E, 0x5A, 0x67, 0x63, 0x6F, 0x6B, 0x77, 0x73, 0x7F, 0x7B,
0x8C, 0x88, 0x84, 0x80, 0x9C, 0x98, 0x94, 0x90, 0xAD, 0xA9, 0xA5, 0xA1, 0xBD, 0xB9, 0xB5, 0xB1,
0xCA, 0xCE, 0xC2, 0xC6, 0xDA, 0xDE, 0xD2, 0xD6, 0xEB, 0xEF, 0xE3, 0xE7, 0xFB, 0xFF, 0xF3, 0xF7,
0x18, 0x1C, 0x10, 0x14, 0x08, 0x0C, 0x00, 0x04, 0x39, 0x3D, 0x31, 0x35, 0x29, 0x2D, 0x21, 0x25,
0x5E, 0x5A, 0x56, 0x52, 0x4E, 0x4A, 0x46, 0x42, 0x7F, 0x7B, 0x77, 0x73, 0x6F, 0x6B, 0x67, 0x63,
0x94, 0x90, 0x9C, 0x98, 0x84, 0x80, 0x8C, 0x88, 0xB5, 0xB1, 0xBD, 0xB9, 0xA5, 0xA1, 0xAD, 0xA9,
0xD2, 0xD6, 0xDA, 0xDE, 0xC2, 0xC6, 0xCA, 0xCE, 0xF3, 0xF7, 0xFB, 0xFF, 0xE3, 0xE7, 0xEB, 0xEF,
0x31, 0x35, 0x39, 0x3D, 0x21, 0x25, 0x29, 0x2D, 0x10, 0x14, 0x18, 0x1C, 0x00, 0x04, 0x08, 0x0C,
0x77, 0x73, 0x7F, 0x7B, 0x67, 0x63, 0x6F, 0x6B, 0x56, 0x52, 0x5E, 0x5A, 0x46, 0x42, 0x4E, 0x4A,
0xBD, 0xB9, 0xB5, 0xB1, 0xAD, 0xA9, 0xA5, 0xA1, 0x9C, 0x98, 0x94, 0x90, 0x8C, 0x88, 0x84, 0x80,
0xFB, 0xFF, 0xF3, 0xF7, 0xEB, 0xEF, 0xE3, 0xE7, 0xDA, 0xDE, 0xD2, 0xD6, 0xCA, 0xCE, 0xC2, 0xC6,
0x29, 0x2D, 0x21, 0x25, 0x39, 0x3D, 0x31, 0x35, 0x08, 0x0C, 0x00, 0x04, 0x18, 0x1C, 0x10, 0x14,
0x6F, 0x6B, 0x67, 0x63, 0x7F, 0x7B, 0x77, 0x73, 0x4E, 0x4A, 0x46, 0x42, 0x5E, 0x5A, 0x56, 0x52,
0xA5, 0xA1, 0xAD, 0xA9, 0xB5, 0xB1, 0xBD, 0xB9, 0x84, 0x80, 0x8C, 0x88, 0x94, 0x90, 0x9C, 0x98,
0xE3, 0xE7, 0xEB, 0xEF, 0xF3, 0xF7, 0xFB, 0xFF, 0xC2, 0xC6, 0xCA, 0xCE, 0xD2, 0xD6, 0xDA, 0xDE
};
u8 const Adesto_Factory_Programmed[64] =
{
// put here AT45DB011D Security Register from byte 64 to 127
};
u8 OneTime_User_Programmable[64];
OneTime_User_Programmable[0] = 0x00; // or whatever you want
OneTime_User_Programmable[1] = 0x00; // or whatever you want
OneTime_User_Programmable[2] = 0x00; // or whatever you want
u8 n, value;
for(n=3;n<64;n++)
{
value = (u8)(Adesto_Factory_Programmed[n] + n);
OneTime_User_Programmable[n] = GreenDot_Table[value];
}
@Torkel:
I basically agree with your beliefs.
So, let's bare it all.
Have fun guys.Code: [Select]
u8 const GreenDot_Table[256] =
{
0x00, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x18, 0x1C, 0x21, 0x25, 0x29, 0x2D, 0x31, 0x35, 0x39, 0x3D,
0x46, 0x42, 0x4E, 0x4A, 0x56, 0x52, 0x5E, 0x5A, 0x67, 0x63, 0x6F, 0x6B, 0x77, 0x73, 0x7F, 0x7B,
0x8C, 0x88, 0x84, 0x80, 0x9C, 0x98, 0x94, 0x90, 0xAD, 0xA9, 0xA5, 0xA1, 0xBD, 0xB9, 0xB5, 0xB1,
0xCA, 0xCE, 0xC2, 0xC6, 0xDA, 0xDE, 0xD2, 0xD6, 0xEB, 0xEF, 0xE3, 0xE7, 0xFB, 0xFF, 0xF3, 0xF7,
0x18, 0x1C, 0x10, 0x14, 0x08, 0x0C, 0x00, 0x04, 0x39, 0x3D, 0x31, 0x35, 0x29, 0x2D, 0x21, 0x25,
0x5E, 0x5A, 0x56, 0x52, 0x4E, 0x4A, 0x46, 0x42, 0x7F, 0x7B, 0x77, 0x73, 0x6F, 0x6B, 0x67, 0x63,
0x94, 0x90, 0x9C, 0x98, 0x84, 0x80, 0x8C, 0x88, 0xB5, 0xB1, 0xBD, 0xB9, 0xA5, 0xA1, 0xAD, 0xA9,
0xD2, 0xD6, 0xDA, 0xDE, 0xC2, 0xC6, 0xCA, 0xCE, 0xF3, 0xF7, 0xFB, 0xFF, 0xE3, 0xE7, 0xEB, 0xEF,
0x31, 0x35, 0x39, 0x3D, 0x21, 0x25, 0x29, 0x2D, 0x10, 0x14, 0x18, 0x1C, 0x00, 0x04, 0x08, 0x0C,
0x77, 0x73, 0x7F, 0x7B, 0x67, 0x63, 0x6F, 0x6B, 0x56, 0x52, 0x5E, 0x5A, 0x46, 0x42, 0x4E, 0x4A,
0xBD, 0xB9, 0xB5, 0xB1, 0xAD, 0xA9, 0xA5, 0xA1, 0x9C, 0x98, 0x94, 0x90, 0x8C, 0x88, 0x84, 0x80,
0xFB, 0xFF, 0xF3, 0xF7, 0xEB, 0xEF, 0xE3, 0xE7, 0xDA, 0xDE, 0xD2, 0xD6, 0xCA, 0xCE, 0xC2, 0xC6,
0x29, 0x2D, 0x21, 0x25, 0x39, 0x3D, 0x31, 0x35, 0x08, 0x0C, 0x00, 0x04, 0x18, 0x1C, 0x10, 0x14,
0x6F, 0x6B, 0x67, 0x63, 0x7F, 0x7B, 0x77, 0x73, 0x4E, 0x4A, 0x46, 0x42, 0x5E, 0x5A, 0x56, 0x52,
0xA5, 0xA1, 0xAD, 0xA9, 0xB5, 0xB1, 0xBD, 0xB9, 0x84, 0x80, 0x8C, 0x88, 0x94, 0x90, 0x9C, 0x98,
0xE3, 0xE7, 0xEB, 0xEF, 0xF3, 0xF7, 0xFB, 0xFF, 0xC2, 0xC6, 0xCA, 0xCE, 0xD2, 0xD6, 0xDA, 0xDE
};
u8 const Adesto_Factory_Programmed[64] =
{
// put here AT45DB011D Security Register from byte 64 to 127
};
u8 OneTime_User_Programmable[64];
OneTime_User_Programmable[0] = 0x00; // or whatever you want
OneTime_User_Programmable[1] = 0x00; // or whatever you want
OneTime_User_Programmable[2] = 0x00; // or whatever you want
u8 n, value;
for(n=3;n<64;n++)
{
value = (u8)(Adesto_Factory_Programmed[n] + n);
OneTime_User_Programmable[n] = GreenDot_Table[value];
}
Is it possible that this code can be used in the already made programming?
I bet you've got a number of data loggers available, to fill the entire matrix with the missing values
Do we have to change the programming with the new information ?
You know, I don't know why Davis just does not build in the interface (USB/serial) to the console and just up the price. In these everything connected days I suspect most eventually hook the wx stn to the net.
I have been playing with this for a few days and have just successfully programed the security register on one of my clone loggers \:D/ . I need a guinea pig to try out the interface, any volunteers?
Nope, if you trawl the forum you'll find that I was one of the first to supply 3rd party loggers, based on Dekays design. I have programmed the register on one of my clone loggers that uses the same chip as a davis logger, but i do not have a console to test it with.
That is what I get from my spread sheet too :grin: Though I am not 100% sure what you should do with the first three bytes, translate them, or leave them 'as-is'?
Well it looks like I may be back in the game! new set of boards coming from oshpark.com (http://oshpark.com) thanks to all those that have worked hard on this. I beleive the Dataflash option to be the least hassle and most cost effective, and now I have found a way to program the security register I should be able to produce clone loggers and wireless interfaces again!
I was hoping it wouldn't take that long after watson's awesome discovery. Somebody buy that guy a drink!
no worries, send me a pm with your address and I'll get one in the mail, gratis.QuoteI was hoping it wouldn't take that long after watson's awesome discovery. Somebody buy that guy a drink!
Well, if someone really wants to thank me.. he could send me some of his compatible loggers for free :)
I would gladly accept that gift, testing them on my network stations.
I should be able to produce clone loggers and wireless interfaces
Hi
Just got a UK Vantage Vue :grin: with firmware 3.0 and serial number starting MF.
Is this module available prebuilt in the UK? If so, how much is it and how do I order one?
I'm assuming it functions the same as the genuine version (i.e. USB output to PC and will log data ok)
Cheers!
belfryboy wireless pc data link (http://belfryboy wireless pc data link)
And I got the new version of the logger in the post this morning.
Works great with my Vue with v3.0 firmware
Thanks Rob :grin:
The belfryboy logger is USB but using the FTDI chipset so appears as a virtual serial port. 2 recent sales were to RaspberryPi users running Weewx.
I do also make a serial version as well for the same price.
Next batch of boards have been ordered, I expect they'll arrive in a fortnight or so.
Then they would cost about 1/3 or less. Take a look at radio control aircraft receivers to see what I mean.Next batch of boards have been ordered, I expect they'll arrive in a fortnight or so.
You'll have a factory in China cranking them out before you know it! :roll:
. Boris at Meteobridge and myself think the data logger is kaput ( fantastic quality). Does anyone else have any ideas?
The dodgy logger has been posted to belfry boy for testing and I have purchased a belfry boy logger which will connect with the meteobridge to WU.
By the way the original supplier went bust.
I imported my second VP2 from the US at a massive saving even with the freight and duties.
In preparation for the last step in my setup, I have been doing some further reading, which led me to another question. Do I have to go into the logger via a terminal editor like Realterm to set up the logging capability for your logger?
I have been lurking for a while and ordered the parts to build the logger here ( http://oshpark.com/shared_projects/XrOiaET6 ). I assembled it last night and I have a V3.x firmware console that reports "lcd ok.INCOMPATIBLE LOGGER" via the serial utility ( from here (WeatherStation.exe) https://drive.google.com/folderview?id=0BxWPDCRn6BMXRGtxcXBDUGdNdnc&usp=sharing ).
I suspect it might be that I need to program the security register? The PC recognizes the USB serial port, and I am able to see data come across as the console starts. If it is not the security register, I suspect I may of installed the 1MB memory chip incorrectly.
Any guidance/advice would be very helpful. Thank you all so much for the work you have done on this!
The belfryboy loggers are still being made, they work with the latest Davis firmware (AFAIK) and I know of forum members that are using them with WeatherDisplay, Cumulus, Meteohub, and Weatherlink.
#include <SPI.h>
/* This code by default reads the 64 byte unique Device Identifier on
the attached AT45DB001D, outputs it to the console, and then calculates
the 64 bytes to be programmed in the Security Register to match a
genuine Davis Weatherlink interface, and outputs those 64 bytes
to the console. By uncommenting the last section in the setup() loop
you can choose to program the Security Register. But first make sure that
the read was successful and the calculated bytes are correct before enabling
writing.
*******
NOTE: YOU ONLY GET ONE CHANCE TO WRITE THE SECURITY REGISTER!
So make sure communication with the AT45 is OK or you'll have a dead
dataflash on your hands!
*******
*/
//DataFlash Commands
#define DATAFLASH_READ_MANUFACTURER_AND_DEVICE_ID 0x9F
#define DATAFLASH_READ_SECURITY_REGISTER 0x77
#define DATAFLASH_STATUS_REGISTER_READ 0xD7
#define DATAFLASH_CHIP_ERASE_0 0xC7
#define DATAFLASH_CHIP_ERASE_1 0x94
#define DATAFLASH_CHIP_ERASE_2 0x80
#define DATAFLASH_CHIP_ERASE_3 0x9A
#define DATAFLASH_READ_SECURITY_REGISTER 0x77
#define DATAFLASH_PROGRAM_SECURITY_REGISTER_0 0x9B
#define DATAFLASH_PROGRAM_SECURITY_REGISTER_1 0x00
#define DATAFLASH_PROGRAM_SECURITY_REGISTER_2 0x00
#define DATAFLASH_PROGRAM_SECURITY_REGISTER_3 0x00
//As per Watson's work described at http://www.wxforum.net/index.php?topic=18110.msg200376
int const GreenDot_Table[256] =
{
0x00, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x18, 0x1C, 0x21, 0x25, 0x29, 0x2D, 0x31, 0x35, 0x39, 0x3D,
0x46, 0x42, 0x4E, 0x4A, 0x56, 0x52, 0x5E, 0x5A, 0x67, 0x63, 0x6F, 0x6B, 0x77, 0x73, 0x7F, 0x7B,
0x8C, 0x88, 0x84, 0x80, 0x9C, 0x98, 0x94, 0x90, 0xAD, 0xA9, 0xA5, 0xA1, 0xBD, 0xB9, 0xB5, 0xB1,
0xCA, 0xCE, 0xC2, 0xC6, 0xDA, 0xDE, 0xD2, 0xD6, 0xEB, 0xEF, 0xE3, 0xE7, 0xFB, 0xFF, 0xF3, 0xF7,
0x18, 0x1C, 0x10, 0x14, 0x08, 0x0C, 0x00, 0x04, 0x39, 0x3D, 0x31, 0x35, 0x29, 0x2D, 0x21, 0x25,
0x5E, 0x5A, 0x56, 0x52, 0x4E, 0x4A, 0x46, 0x42, 0x7F, 0x7B, 0x77, 0x73, 0x6F, 0x6B, 0x67, 0x63,
0x94, 0x90, 0x9C, 0x98, 0x84, 0x80, 0x8C, 0x88, 0xB5, 0xB1, 0xBD, 0xB9, 0xA5, 0xA1, 0xAD, 0xA9,
0xD2, 0xD6, 0xDA, 0xDE, 0xC2, 0xC6, 0xCA, 0xCE, 0xF3, 0xF7, 0xFB, 0xFF, 0xE3, 0xE7, 0xEB, 0xEF,
0x31, 0x35, 0x39, 0x3D, 0x21, 0x25, 0x29, 0x2D, 0x10, 0x14, 0x18, 0x1C, 0x00, 0x04, 0x08, 0x0C,
0x77, 0x73, 0x7F, 0x7B, 0x67, 0x63, 0x6F, 0x6B, 0x56, 0x52, 0x5E, 0x5A, 0x46, 0x42, 0x4E, 0x4A,
0xBD, 0xB9, 0xB5, 0xB1, 0xAD, 0xA9, 0xA5, 0xA1, 0x9C, 0x98, 0x94, 0x90, 0x8C, 0x88, 0x84, 0x80,
0xFB, 0xFF, 0xF3, 0xF7, 0xEB, 0xEF, 0xE3, 0xE7, 0xDA, 0xDE, 0xD2, 0xD6, 0xCA, 0xCE, 0xC2, 0xC6,
0x29, 0x2D, 0x21, 0x25, 0x39, 0x3D, 0x31, 0x35, 0x08, 0x0C, 0x00, 0x04, 0x18, 0x1C, 0x10, 0x14,
0x6F, 0x6B, 0x67, 0x63, 0x7F, 0x7B, 0x77, 0x73, 0x4E, 0x4A, 0x46, 0x42, 0x5E, 0x5A, 0x56, 0x52,
0xA5, 0xA1, 0xAD, 0xA9, 0xB5, 0xB1, 0xBD, 0xB9, 0x84, 0x80, 0x8C, 0x88, 0x94, 0x90, 0x9C, 0x98,
0xE3, 0xE7, 0xEB, 0xEF, 0xF3, 0xF7, 0xFB, 0xFF, 0xC2, 0xC6, 0xCA, 0xCE, 0xD2, 0xD6, 0xDA, 0xDE
};
/* Pin connection definitions. Pin connections between Arduino and Dataflash
should be as follows:
AT45DB011D ------------ ARDUINO
1 (SI/MOSI) ------------ Pin 11
2 (SCK) ------------ Pin 13
3 (RESET) ------------ Pin 8
4 (CS) ------------ Pin 10
5 (WP) ------------ Pin 7
6 (VCC) ------------ 3.3V
7 (GND) ------------ Ground
8 (SO) ------------ Pin 12
Note that pin #s on AT45DB are as follows:
1 8
2 7
3 6
4 5
A breakout board for the SOIC package makes connections easier but isn't
strictly necessary
*/
int csPin = 10;
int resetPin = 8;
int writeProtectPin = 7;
int delayTime = 500; //half-second typical delay
void setup(){
//Initial setup & SPI Initialization
pinMode(csPin,OUTPUT);
SPI.begin();
SPI.setDataMode(SPI_MODE3);
SPI.setBitOrder(MSBFIRST);
SPI.setClockDivider(SPI_CLOCK_DIV2);
Serial.begin(19200);
delay(delayTime*4); //wait 2 seconds before continuing
//Begin communication tests
Serial.println("Attempting communication with DataFlash...");
//First we get the current status register
uint8_t STATUS;
digitalWrite(csPin,LOW);
SPI.transfer(DATAFLASH_STATUS_REGISTER_READ);
STATUS=SPI.transfer(0);
digitalWrite(csPin,HIGH);
Serial.print("Status Register: 0b");
Serial.println(STATUS,BIN);
Serial.println("Format: RDY MEMCOMP 0 0 1 1 SECPROT PAGESZ");
delay(delayTime);
//Next Manufacturer ID and Device ID
byte MANUFACTURER_DEVICE_ID[4];
digitalWrite(csPin,LOW);
SPI.transfer(DATAFLASH_READ_MANUFACTURER_AND_DEVICE_ID);
for (int i=0;i<4;i++){
MANUFACTURER_DEVICE_ID[i]=SPI.transfer(0);
}
digitalWrite(csPin,HIGH);
//Output result
Serial.print("Manufacturer ID (Should be 0x1F): ");
Serial.println(MANUFACTURER_DEVICE_ID[0],HEX);
Serial.print("Device ID byte1 (should be 0x22): ");
Serial.println(MANUFACTURER_DEVICE_ID[1],HEX);
Serial.print("Device ID byte2 (should be 0x00): ");
Serial.println(MANUFACTURER_DEVICE_ID[2],HEX);
Serial.print("Length of Extended Device Info: ");
Serial.println(MANUFACTURER_DEVICE_ID[3],HEX);
delay(delayTime);
/*Security Register
The Security Register consists of two 64-byte parts, composing a total
of 128 bytes. Bytes 0-63 are one-time user programmable. Bytes 64-127
are programmed at factory and can't be changed. As outlined at
http://www.wxforum.net/index.php?topic=18110.0 Davis calculates the first
64 bytes based on an algorithm that uses the second 64 bytes and the values
in the GreenDot_Table above. Here we will read the 64 factory-programmed bytes
and calculate what should be programmed for the other 64 bytes.
*/
byte FACTORY_SECURITY_REGISTER[64]; //Factory-programmed
byte USER_SECURITY_REGISTER[64]; //Calculated by us
//We need to read the entire 128 bytes in one shot.
//Start with verifying the first 64 bytes are unwritten
Serial.println("Reading Security Register...");
digitalWrite(csPin,LOW);
SPI.transfer(DATAFLASH_READ_SECURITY_REGISTER);
SPI.transfer(0x00);//dummy 1
SPI.transfer(0x00);//dummy 2
SPI.transfer(0x00);//dummy 3
Serial.println("Checking that Programmable Register is empty (0xFF)...");
for (int i=0;i<64;i++){
uint8_t CURRENT_BYTE;
CURRENT_BYTE=SPI.transfer(0x00);
if (CURRENT_BYTE != 0xFF){
Serial.print("Error! Byte #");
Serial.print(i);
Serial.println(" is not 0xFF!!");
}
}
// Read Factory programmed 64 Byte security Register
Serial.println("Reading Factory-programmed Security Register..,.");
for(int i=0;i<64;i++){
int byteNumber = i+64;
Serial.print(byteNumber);
Serial.print(" - 0x");
FACTORY_SECURITY_REGISTER[i]=SPI.transfer(0x00);
Serial.println(FACTORY_SECURITY_REGISTER[i],HEX);
}
digitalWrite(csPin,HIGH);
delay(delayTime);
// Calculate User-programmable security bytes
Serial.println("Calculating User-Programmable Security Register...");
// The first 3 bytes can be anything. Davis uses it as a serial number
USER_SECURITY_REGISTER[0]=0x01; //I just used 1, 2, 3... Change as you like
USER_SECURITY_REGISTER[1]=0x02;
USER_SECURITY_REGISTER[2]=0x03;
/* Calculate the remaining 61 bytes
This is taken verbatim from Watson's post, above. location is the location
in the green dot table that the value we need at position i is located.
Because we're using an 8-bit unsigned integer when the calculation below for
location is greater than 255 it loops around and starts at 0 again.
*/
uint8_t location,i;
for ( i=3; i<64; i++){
Serial.print("Byte #");
Serial.print(i);
location = (uint8_t)FACTORY_SECURITY_REGISTER[i]+i;
Serial.print(" Location in Table: ");
Serial.print(location,DEC);
USER_SECURITY_REGISTER[i] = GreenDot_Table[location];
Serial.print(" Value: 0x");
Serial.println(USER_SECURITY_REGISTER[i],HEX);
}
delay(delayTime);
//Uncomment (remove the /* at the start and */ at the end) the lines
//below to program the Security Register
/*
boolean wait = true; //Make sure chip isn't busy
while (wait == true){
uint8_t STATUSREG;
uint8_t NOTBUSY;
digitalWrite(csPin,LOW);
SPI.transfer(DATAFLASH_STATUS_REGISTER_READ);
STATUSREG=SPI.transfer(0);
digitalWrite(csPin,HIGH);
NOTBUSY= getBit(STATUSREG, 7);
if (NOTBUSY == 1){
wait=false;
}
}
digitalWrite(csPin,LOW);
Serial.println("Programming security register...");
SPI.transfer(DATAFLASH_PROGRAM_SECURITY_REGISTER_0);
SPI.transfer(DATAFLASH_PROGRAM_SECURITY_REGISTER_1);
SPI.transfer(DATAFLASH_PROGRAM_SECURITY_REGISTER_2);
SPI.transfer(DATAFLASH_PROGRAM_SECURITY_REGISTER_3);
for(int i=0;i<64;i++){
Serial.print("Programming Byte ");
Serial.println(i);
SPI.transfer(USER_SECURITY_REGISTER[i]);
}
digitalWrite(csPin,HIGH);
//Verify everything wrote out OK
wait=true; //Make sure chip isn't busy
while (wait == true){
uint8_t STATUSREG;
uint8_t NOTBUSY;
digitalWrite(csPin,LOW);
SPI.transfer(DATAFLASH_STATUS_REGISTER_READ);
STATUSREG=SPI.transfer(0);
digitalWrite(csPin,HIGH);
NOTBUSY= getBit(STATUSREG, 7);
if (NOTBUSY == 1){
wait=false;
}
}
delay(delayTime);
Serial.println("Verifying everything went OK...");
byte VERIFY_SECURITY_REGISTER[128];
digitalWrite(csPin,LOW);
SPI.transfer(DATAFLASH_READ_SECURITY_REGISTER);
SPI.transfer(0x00);//dummy 1
SPI.transfer(0x00);//dummy 2
SPI.transfer(0x00);//dummy 3
for(int i=0;i<128;i++){
VERIFY_SECURITY_REGISTER[i]=SPI.transfer(0x00);
}
digitalWrite(csPin,HIGH);
boolean writeOk = true;
for (int i=0;i<64;i++){
if (USER_SECURITY_REGISTER[i]!=VERIFY_SECURITY_REGISTER[i]){
Serial.print("Error at security register ");
Serial.print(i);
Serial.print(": Should be 0x");
Serial.print(USER_SECURITY_REGISTER[i],HEX);
Serial.print(". Is 0x");
Serial.print(VERIFY_SECURITY_REGISTER[i],HEX);
Serial.println(".");
writeOk = false;
}
}
if (writeOk == true){
Serial.println("Looks like everything went great!");
}
else{
Serial.println("Oh no! There was a problem programming the security register!!");
}
*/
}
void loop(){
}
uint8_t getBit(uint8_t bits, uint8_t pos){
return (bits >> pos) & 0x01;
}
Hi all,
I've benefitted enormously from all the hard work done by everyone in this thread and have built several clone dataloggers successfully following the information here. To give back in some small way I thought I'd do a quick how-to writeup for those who may read this but are too intimidated by the technical aspects to give it a try. It's really not too hard!
JoeBean, very nice project. I'm wondering if it would be possible to simply use the Arduino for all the interfacing and emulate the logger's memory with it, too. Maybe a Moteino (http://lowpowerlab.com/moteino/) with the flash installed would be a possible candidate? One would still need the board from eg. OSHPark to be able to connect to the console, though.
Yes you need an arduino that is running on 3.3v.
Kobuki, thanks for your reply and usefull information.
I do intent to write my own interpreter and this program will only run on one PC or Mac at the same time,
and that's the one I'm using at that time, so it's not a problem if it can't transmit to multiple computers.
The ESP8266 module I use is loaded with this firmware (https://github.com/beckdac/ESP8266-transparent-bridge).
I've used it succesfull with several other projects and it should be able to work for this project too.
I've attached the schematic and a picture of the PCB (without the AT45DB011 unfortunately).
Today I made another programming shield for this chip and used a CD4050 as a buffer between the 3V3 AT chip and the 5V Arduino ports, but still no succes in reading or writing the chip, so I'm not sure about what to try next. Any help on this is more than welcome.
Picture of the shield is also attached.
pinMode(resetPin,OUTPUT);
digitalWrite(resetPin,HIGH);
pinMode(writeProtectPin,OUTPUT);
digitalWrite(writeProtectPin,HIGH);
Thanks. First one under "here" appears to be the correct one. Found and ordered the other one but it does not match up with the parts list on page 8 or 9. Serial to USB chip has too many leads for the first board.
Here. (https://oshpark.com/shared_projects/Q4pne4fy)
EDIT: Hmm, it's not his original.Maybe he took off his works from OSHPark after someone made and sold them en masse at online places. Too bad. Best to ask him, I guess.
It's still all up, see here (https://oshpark.com/profiles/belfryboy).
andre58:
Try inserting this just above SPI.begin();Code: [Select]pinMode(resetPin,OUTPUT);
digitalWrite(resetPin,HIGH);
pinMode(writeProtectPin,OUTPUT);
digitalWrite(writeProtectPin,HIGH);
Thanks. First one under "here" appears to be the correct one. Found and ordered the other one but it does not match up with the parts list on page 8 or 9. Serial to USB chip has too many leads for the first board.Here. (https://oshpark.com/shared_projects/Q4pne4fy)
EDIT: Hmm, it's not his original.Maybe he took off his works from OSHPark after someone made and sold them en masse at online places. Too bad. Best to ask him, I guess.
It's still all up, see here (https://oshpark.com/profiles/belfryboy).
You refer to this post, right? The first link is a modified design for standard RS232 line voltages (description is somewhere in this thread, can't remember the poster, sorry). The second link points to the original Belfryboy designs. Going to add comments so it's clear for later readers.
SPI.setClockDivider(SPI_CLOCK_DIV2);
SPI.setClockDivider(SPI_CLOCK_DIV32);
Ι will be needed Usb Hub 2.0 between Logger and Meteobridge ?
Respectfully: no.Well, alrighty then.
The Davis serial protocol specification is available for download from http://www.davisnet.com.LOL. Humble to a fault, yeah? :lol:
The SPI authentication process is well covered in this excellent forum and in a humble PDF document: http://lmgtfy.com/?q=Unlock+Davis+serial+line ;)
Also, sniffing the logger via USB won't reveal much. That's simply not where the magic happens.I figured, but it didn't seem like a lot of other people had delved into it, at least with the "new" logger.
You can have plenty of fun with an Arduino and the logger, though. Not very expensive, and it will get you started in no time.
The only way Davis will prevent such "piracy" (ha!) of the logger is to modernize the console with built-in connectivity. Imagine - it is 2017 and we have no built-in connection. Hell, my toaster is connected to the Internet!
Maybe the minority should think twice next time before creating a headache for the majority, definitely not appreciated.
hi,
My Vue is #6250 and Mfg code of ME18041xxxx. 'VER' returns May 1 2012. 'NVER' returns 3.0.
this is C source code for a funny experiments.Code: [Select]/*
* compiler: Microchip XC8
*
* PIC12F1822
* +--+ +--+
* VCC |1 ~ 8| GND
* |2 7| SDO
* |3 6| SCK
* SS |4 5| SDI
* +-------+
*/
// ... ... ...
I'm attempting to move from the AVR world to the PIC universe ...Well, I'm aware this is not really on topic, but still...
Did anyone successfully implement & run this program?
Like I said, I'm not a programmer. But if you'd combine a copy of weewx or Cumulus MX on the same machine, you'd have a potent little device. And you'd run it a lot cheaper than a second console and logger. But you'd still need a barometer connected to it as well as probably an inside temp if you truly are replacing the console.
Some of the SDR heavy lifting has already been done.....
https://github.com/bemasher/rtldavis (https://github.com/bemasher/rtldavis)
So this solution doesn't look reliable with the existing software. Too bad...
AT45DB011D ------------ ARDUINO
1 (SI/MOSI) ------------ Pin 11
2 (SCK) ------------ Pin 13layout
3 (RESET) ------------ Pin 8
4 (CS) ------------ Pin 10
5 (WP) ------------ Pin 7
6 (VCC) ------------ 3.3V
7 (GND) ------------ Ground
8 (SO) ------------ Pin 12
ATTINY85-20SU-ND ------- ARDUINO
1 (RESET) ------------ Pin 8
2 (WP) ------------ Pin 7 (??)
3 (CS) ------------ Pin 10 (?)
4 (GND) ------------ Ground
5 (SI/MOSI) ------------ Pin 11
6 (SO) ------------ Pin 12 (??)
7 (SCK) ------------ Pin 13
8 (VCC) ------------ 5V
Hi, first post here. :)
We're trying to follow the different guides in this forum to create a DIY data logger. We use the pcb from night303 (http://www.wxforum.net/index.php?topic=18110.msg348033#msg348033) with an ATTINY85-20SU-ND as described in the PDF by Torkelmj (http://wx.annoyingdesigns.com/DavisSPI.pdf). To program the ATTINY85 we use an Arduino UNO and the program described by JoeBean (http://www.wxforum.net/index.php?topic=18110.msg235399#msg235399). Unfortunately JoeBean used an AT45DB011 chip that seems to have a different pin assignment than the ATTINY85. We're thus a little unsure how to connect the ATTINY85 to the Ardunio. We came up with following set-up, but it seems not to work (no connection and out of sync-errors appear in the Ardunio sketch output, after changing pin 7 and 12 there's no output at all anymore, we might just have bricked the chip):
Can anybody confirm the pin assignment? Or give a hint how to proceed?
Thanks in advance!
Simon
/*
Unlock the Davis VP2/Vue console serial line using the ATtiny85 and a
random device ID. Using algorithm as described by WXForum.net user
"watson" on November 28, 2013: http://www.wxforum.net/index.php?topic=18110.msg200376.
Code based on a programm by Torkel M. Jodalen <tmj@bitwrap.no> in revision from 2013-11-30
available at http://wx.annoyingdesigns.com/DavisSPI.pdf
Ported to Arduino Sketch by Simon Harhues (2018-07-06 to 2018-07-16 )
See example for SPI slave support:
https://gist.github.com/Weathergadget/b96255e5ec700a15e42c4c1497ec506b#file-attiny_spi_slave-ino
https://weathergadget.wordpress.com/2016/05/19/usi-spi-slave-communication/
https://avrhelp.mcselec.com/index.html?using_usi_universal_serial_int.htm
Pin assignment of ATtiny85 for ISP communciation (https://github.com/SpenceKonde/ATTinyCore):
Note: Davis Console acts as master, data logger as slave
1: Reset 8: VCC
2: xy 7: SCK
3: xy 6: MISO/DO [as slave]
4: GND 5: MOSI/DI [as slave]
*/
// Static look-up table for security register
u8 const GreenDot_Table[256] =
{
0x00, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x18, 0x1C, 0x21, 0x25, 0x29, 0x2D, 0x31, 0x35, 0x39, 0x3D,
0x46, 0x42, 0x4E, 0x4A, 0x56, 0x52, 0x5E, 0x5A, 0x67, 0x63, 0x6F, 0x6B, 0x77, 0x73, 0x7F, 0x7B,
0x8C, 0x88, 0x84, 0x80, 0x9C, 0x98, 0x94, 0x90, 0xAD, 0xA9, 0xA5, 0xA1, 0xBD, 0xB9, 0xB5, 0xB1,
0xCA, 0xCE, 0xC2, 0xC6, 0xDA, 0xDE, 0xD2, 0xD6, 0xEB, 0xEF, 0xE3, 0xE7, 0xFB, 0xFF, 0xF3, 0xF7,
0x18, 0x1C, 0x10, 0x14, 0x08, 0x0C, 0x00, 0x04, 0x39, 0x3D, 0x31, 0x35, 0x29, 0x2D, 0x21, 0x25,
0x5E, 0x5A, 0x56, 0x52, 0x4E, 0x4A, 0x46, 0x42, 0x7F, 0x7B, 0x77, 0x73, 0x6F, 0x6B, 0x67, 0x63,
0x94, 0x90, 0x9C, 0x98, 0x84, 0x80, 0x8C, 0x88, 0xB5, 0xB1, 0xBD, 0xB9, 0xA5, 0xA1, 0xAD, 0xA9,
0xD2, 0xD6, 0xDA, 0xDE, 0xC2, 0xC6, 0xCA, 0xCE, 0xF3, 0xF7, 0xFB, 0xFF, 0xE3, 0xE7, 0xEB, 0xEF,
0x31, 0x35, 0x39, 0x3D, 0x21, 0x25, 0x29, 0x2D, 0x10, 0x14, 0x18, 0x1C, 0x00, 0x04, 0x08, 0x0C,
0x77, 0x73, 0x7F, 0x7B, 0x67, 0x63, 0x6F, 0x6B, 0x56, 0x52, 0x5E, 0x5A, 0x46, 0x42, 0x4E, 0x4A,
0xBD, 0xB9, 0xB5, 0xB1, 0xAD, 0xA9, 0xA5, 0xA1, 0x9C, 0x98, 0x94, 0x90, 0x8C, 0x88, 0x84, 0x80,
0xFB, 0xFF, 0xF3, 0xF7, 0xEB, 0xEF, 0xE3, 0xE7, 0xDA, 0xDE, 0xD2, 0xD6, 0xCA, 0xCE, 0xC2, 0xC6,
0x29, 0x2D, 0x21, 0x25, 0x39, 0x3D, 0x31, 0x35, 0x08, 0x0C, 0x00, 0x04, 0x18, 0x1C, 0x10, 0x14,
0x6F, 0x6B, 0x67, 0x63, 0x7F, 0x7B, 0x77, 0x73, 0x4E, 0x4A, 0x46, 0x42, 0x5E, 0x5A, 0x56, 0x52,
0xA5, 0xA1, 0xAD, 0xA9, 0xB5, 0xB1, 0xBD, 0xB9, 0x84, 0x80, 0x8C, 0x88, 0x94, 0x90, 0x9C, 0x98,
0xE3, 0xE7, 0xEB, 0xEF, 0xF3, 0xF7, 0xFB, 0xFF, 0xC2, 0xC6, 0xCA, 0xCE, 0xD2, 0xD6, 0xDA, 0xDE
};
// the setup function runs once when you press reset or power the board
void setup() {
u8 const OptCode_ChipStatus = 0xD7; // optcode to request chip status
u8 const Reply_ChipStatus = 0x8C; // response to chip status request
u8 const OptCode_SecurityRegister = 0x77; // optcode to request security register value
//the following is probably not needed (according to Torkels PDF)
// u8 const OptCode_ManufacturerID_DataDensity = 0x9F; // optcode to request manufacturer id (0x1F) and data density (0x22)
// The 128 byte one time programmable security register
// Bytes 0 - 2: fixed (value seems to not matter)
// Bytes 3 - 64: calculated value (derived from devide id)
// Bytes 64 - 127: device id (we'll use a random one here)
u8 Security_Register[128];
// Fill fixed values, bytes 0-2
Security_Register[0] = 0x00; // or whatever you want
Security_Register[1] = 0x00; // or whatever you want
Security_Register[2] = 0x07; // or whatever you want
// Fill in a random device ID, bytes 64-127
for (int i=64;i<128;i++){
Security_Register[i] = (u8)random(256);
}
// Fill in appropiate calculated security register values, bytes 3-63
u8 value;
for (int i=3;i<64;i++){
value = (u8)(Security_Register[64 + n] + n); //device ID starts at byte 64 of security register
Security_Register[i] = GreenDot_Table[value];
}
// Wait for console to communicate with us, the data logger
//ToDo: to request optcode 0xD7 reply with chip status (0x8C)
//ToDo: to request optcode 0x77 reply with security register
for (int i=0;i<128;i++){
//write Security_Register[i];
}
// see examples
// see: https://create.arduino.cc/projecthub/arjun/programming-attiny85-with-arduino-uno-afb829
}
// the loop function runs over and over again forever
void loop() {
}
The other 192 bytes of the GreenDot_Table is a stupid "copy and paste" of the first 64 bytes, with very poor permutations.