Hi everyone.
Unfortunately, still no success with the MSP430G2231. Below one of the many versions the code segment I used. I tried all possible combinations for the SPI timing and for some I see that the console requests the status byte but nothing happens after that. Once in a few dozen tries I get an 'incompatible datalogger'. There are some extra variables in the code for debugging but else it should do about the same as Kashima's code. I checked the signals on the MCU with a scope and all looks clean. Does anyone see where I go wrong here?
Is it neccessary to switch to a MCU that allows true 4-whire (plus ground) instead of this 'emulated' 4-wire using the GPIO 'SS' pin below? (The smallest MCU I have here with true 4 wire SPI is a STM32F407, which seems a huge overkill for this simple task, and it might skew the temperature readings on the console due to its pretty hefty power consumption.)
Best,
Haku
//***************************************************************************************
// 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;
}
}
}
}