This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430FR6989: timing problems between two MSP's

Part Number: MSP430FR6989

Dear, 

For a project I am connecting two MSP's with each other, one as a master and one as a slave. The slave one will just act as a memory extansion to the master (who will write an address and data to the slave). There are many ways of "solving" this, however my hand was forced in how to do it. 

The master will write an address to the slave, and he will also pull one pin high (doesn't do anything on the slave) and another low (will cause an interrupt on the slave). These pins are respectively 3.0 and 3.1.  Depending on which pin is pulled low, the slave will either read the data from the master and store it in the address the master has given, or it will look at the address and write the data stored at this address to the master. 

As you can imagine, a lot of timing problems occur when you just do this (data doesn't stay on the pins long enough, etc.). I tried to solve this by using the pin 3.2. The master will only read if that pin is pulled High(it will basically poll the entire time since the master need not do anything else in this time). The same thing happens (about ish) when writing. The master will push this pin Low again

The pieces for the code of the master are: 

 

void write(uint16_t address, uint8_t data){
    splitAndWriteAddress(address);  // splits up the address over the available pins in ports and writes it.
    P2DIR |= 0xFF;      // set dataIO in write mode
    P3OUT |= BIT1;      // deactivate read mode
    P3OUT &= ~BIT0;     // activate write mode
    P2OUT = data;       // write data
    while(!(P3IN & BIT2)){
        __no_operation();
    }
    P3OUT |= BIT0;      // deactivate write mode
    P3DIR |= BIT2;
    P3OUT &= ~BIT2;
    P3DIR &= ~BIT2;
    //P2DIR |= 0x00;      // set dataIO in read mode

}
uint8_t read(uint16_t address){
    uint8_t data = 0x00;
    splitAndWriteAddress(address);
    P2DIR &= 0x00;      // set dataIO in read mode
    P3OUT |= BIT0;      // deactivate write mode
    P3OUT &= ~BIT1;     // activate read mode
    while(!(P3IN & BIT2)){
        __no_operation();
    }
    data = P2IN;
    P3OUT |= BIT1;      // deactivate read mode
    P3DIR |= BIT2;
    P3OUT &= ~BIT2;
    P3DIR &= ~BIT2;
    return data;
}

And for the slave the interrupt is: 

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=PORT3_VECTOR
__interrupt void Port_3(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(PORT3_VECTOR))) Port_3 (void)
#else
#error Compiler not supported!
#endif
{
    /*
     * 4 usable RAM sections:
     * 1. D --> 1800h 'till 187Fh
     * 2. C --> 1880h 'till 18FFh
     * 3. B --> 1900h 'till 187Fh
     * 4. A --> 1980h 'till 19FFh
     */
    uint16_t volatile * address = (uint16_t *) getAddress(); // gets the address from the ports
    P3DIR |= BIT2;


        if(P3IFG & BIT0){
            P2DIR &= 0x00;  // put in read mode
            *address = P2IN;
            P3OUT |= BIT2;
        }
        //WRITE
        if(P3IFG & BIT1){ //could be an else
            P2DIR |= 0xFF;  // put in write mode
            P2OUT = *address;
            P3OUT |= BIT2;
        }

    P3DIR &= ~BIT2;

    P3IFG=0; // set all flags to 0

}

When debugging, everything works fine (I test using an UART connection) , but when running as normal (in release mode), it does not anymore (the data and address are all given through correctly). This makes me think that it is still a timing error, however I don't know how and why. 

I was also thinking that I should be able to do it without using that port 3.2, but I have not tried it yet, because I think there will also be some major timing issues there which I don't know how to solve right now. 

If more code is needed please ask, but those are just about the only ones that matter I think.

With kind regards. 

  • Hi Yannick,

    Can you give me more details on how you were testing when the code works? Was this through a UART interface to CCS? (were you also debugging the code through CCS?)  Did you check to see if there were any similar example in MSP-ware?

    BR,
    Leo

  • Are both MCU's using the same clock frequency?

    Use a strobe/ack system when data is ready, the sender sets the strobe high, and waits for the receiver to send an ack before releasing the strobe and pins.

    The other option is to use the USCI in SPI mode.

  • Both are indeed on the same CLK freq. (8MHz). 

    The problem with all those options is that I have been "given" the master code and I can only change small things (for example the polling I now do on pin 3.2), I can not use any other ports, or do major changes to the code. 

  • Hi Leonardo, 

    For the UART connection I simply use Putty to connect with it. That all works fine, since I send more than just this through it and everything seems to be perfect. What I do is very simple, I write 4 times to a different address in the MCU (a valid overwriteable address) with some different data, and then read those out again (although in a different order). The code for this is very simply and is started whenever I write '1' in the Putty terminal: 

    int testing(){
        int tests_succeeded = 0;
        uint16_t address1 = 0x1820;
        uint8_t data1 = 0b10101010;
        uint16_t address2 = 0x1860;
        uint8_t data2 = 0b01010101;
        uint16_t address3 = 0x1920;
        uint8_t data3 = 0b11110000;-
        uint16_t address4 = 0x1960;
        uint8_t data4 = 0b00001111;
    
        write(address1, data1);
        __no_operation();
        write(address2, data2);
        __no_operation();
        write(address3, data3);
        __no_operation();
        write(address4, data4);
        __no_operation();
    
        uint8_t new_data = read(address1);
        if(new_data == data1){
            send_data(0x4B4F); // send 'OK' through UART
            tests_succeeded ++;
        } else{
            send_data(0x4F4E); // send 'NO'through UART
        }
    
    
        new_data = read(address4);
        if(new_data == data4){
            send_data(0x4B4F); // send 'OK'through UART
            tests_succeeded ++;
        } else{
            send_data(0x4F4E); // send 'NO'through UART
        }
    
        new_data = read(address3);
        if(new_data == data3){
            send_data(0x4B4F); // send 'OK'through UART
            tests_succeeded ++;
        } else{
            send_data(0x4F4E); // send 'NO'through UART
        }
    
        new_data = read(address2);
        if(new_data == data2){
            send_data(0x4B4F); // send 'OK'through UART
            tests_succeeded ++;
        } else{
                send_data(0x4F4E); // send 'NO'through UART
        }
    
        return tests_succeeded;
    }

    Which will give a "OK" or a "NO" through the UART. In the putty terminal I only read NO's back, but sometimes, just sometimes there is an "OK", but I don't know how much I trust this "OK" since maybe it could just be data still stuck on the lines that was read by accident. $

    The debugging was done in the CCS environment where I went step by step on both MCU's and they worked flawlessly then, that is why I suspect a timing error now. 

    I did not check for any similar examples, thanks for suggesting that. I will take a look. However since I was given this "master" code and am not allowed to change much (cannot use any extra pins besides the one I use right now, no major code changes (so no interrupts, the polling I am doing however is okay)). 

    With kind regards. 

  •  >   P3OUT |= BIT1;      // deactivate read mode
     >   P3OUT &= ~BIT0;     // activate write mode
     >   P2OUT = data;       // write data

     

    From your description, one of the first two lines causes an interrupt on the slave, but the data lines haven't been set up yet. This sets up a race. The master will usually win, but if e.g. a stray interrupt happens it will lose.

    From your description, only one of P3.0/1 triggers a slave interrupt, but I'm not sure I understand how this works since P2IES can only be set in one direction. How are these pins configured?

  • I could already set up the data lines, but I don't think this will works. There is a race, yes, but the slaves needs to do a lot of things before actually reading in the data (getting in the interrupt, getting the address, checking flags, ...). For this reason I do not think the slave will ever win. However it is a good idea to not even let the race happen, so I will fix this. 

    P3.0/1 can either trigger a slave interrupt when either one of those goes down. This is what is being done (by the slave) just before writing the data. There is no interrupt on the data pins. The data pins are set like this in the slave: 

    __bis_SR_register(GIE);     // enable interrupts
    
        //declare all the pins
        //Control Ports
        P3IFG &= ~0x03 ; // clear the flags
        P3DIR |= 0b00000100; // third port is CSN port use this port to say when ready, make WRITE
        P3OUT &= ~BIT2;
        P3IE |= 0b00000011;
        P3IES |= 0x03 ; // from high to low on the first two pins
        P3IFG &= ~0x03 ; // clear the flags
    
        //Address Ports (Port 1: 5, Port 8: 4, Port 9: 7), READ ONLY
        P1DIR |= 0b00000000;
        P8DIR |= 0b00000000;
        P9DIR |= 0b00000000;
        __no_operation();
    
        //Data Port
        P2DIR |= 0x00;

  • I cited a case where the slave would win. More generally, I suggest you not think in those terms. If there's a race, either side could win.

    In what way do you think setting the data bus first won't work?

    How long are your wires? How fast is your CPU clock (MCLK)?

    You'll probably find it useful to display the failing data on a "NO" result. Even better would be visibility into the slave. It's usually useful to know whether the write or the read failed.

  • The "problem" I have with setting the databus first is that if the slave goes from writing( reading for the master) to reading (writing for the master), it still has its own data on the line and is still writing, whilst the master also starts writing. Which would mean two MCU's are writing on the same lines at the same time, which is just asking for problems. 

    I though of fixing it by just letting the slave write and then directly change its DIR to reading (0x00), which means that it is possible something will "write" something over on these lines (chances of this happening is rather slim, but still). 

    The MCU's are both on 8MHz, but there is no CLK wire connecting them. The wires used are regular jumper wires (female to female) with a length of I guess 10cm, however since there are so much, they are in a bit of a mess, maybe there is some inductance problem with it, I did not think about that, but I don't really know how to go about solving this now (too many wires to just twist them). 

    Printing in the slave, however, is a really good idea. Like I said, it is possible to do this in the debugging mode so I expect a timing error, but there is no fault in adding some code to check the slave and maybe this gives a better clue. 

    In the meantime I also connected a logic analyzer, but this gave some data of which I am not sure (e.g. the data lines go up and down a lot when they should not be doing so, or when I read 6 times, the logic analyzer only gives through 4 "dips" in the line whilst the Putty clearly shows all 6 ones have been done). I think it is because the connection, I had to connect them with some longer jumper wires (25cm) into the female connectors of the analyzer and into the female connectors of the board. 

  • Ordinarily I would expect the data bus wires to be floating (input on both sides) between transactions, which means that either side can grab it. 

    10cm wires at 8MHz should be OK. I've seen propagation skew at 8MHz, but that was over maybe 30cm wire. [Notwithstanding Adm Hopper's "nanosecond wire"]

    I can imagine the wiring is a challenge. And (for better or worse) the Launchpads don't order the header pins by port number.

  • I have found some solution that just changes the usage of the CTRL lines (of port 3) where I will use 1 wire as a R/W wire, 1 as a trigger wire (both only written on by the master), and 1 as an ACK from the slave. I am going to test this tomorrow and do a write-down about it if it works. It does however make for some larger changes to the master code than I would have liked, but at the moment this doesn't seem to work either, so why not try it. 

    The wires indeed should be fine, but they still have me worried because of the not entirely ideal connectors. The ports on the launchpad have really been a nightmare to get around (to get in an address of 16 bit, I have to concatenate 3 different ports with their different pins). But I managed!

  • Maybe you already thought of this, but: Now that you've separated R/W and Request, I think you could adopt the Request as the second part of a two-way ack:

    0) Initially: Request=1 (output from master), Slave-Ack=1 (output from slave), Data is floating

    1) Master sets R/W and (maybe) Data, then sets Request=0 and waits for Slave-Ack to go low

    2) Slave processes request (maybe sets Data) then sets Slave-Ack low and waits for Request to go high

    3) Master sets Request=1 (end of transaction) and (maybe) releases Data to float

    4) Slave (maybe) releases Data to float, and sets Slave-Ack high (end of transaction)

    5) Finally: Request=1 (output from master), Slave-Ack=1 (output from slave), Data is floating [Same as Initially]

    This way, all the (non-Data) pins are unidirectional, and there is a clear moment when the transaction ends. The two-way Ack assures lock-step through the entire process.

    I've probably made it sound complicated, but I don't think it's more code than you have now.

  • That was the exact thing I had in mind, but with Ack and Request going Low instead of high.

  • You've got my vote.

  • what you described seemed to be quite confusing to me.

    what I would suggest, as a starter:

    1. address line: master -> slave.

    2. data line: bi-directional. so it should idles as input on both ends.

    3. R/W line: level indicating read or write. master -> slave.

    4. strobe: transition indicating transaction. master -> slave. You can add slave signalling later on. and I think a low->high transition makes more sense as that allows the slave to pull down the line to signal.

    so a write routine would be something like this:

    1. present address;

    2. present data;

    3. clear the R/W line;

    4. strobe;

    5. wait a little while (or slave ack).

    6. float data line.

    and a read routine would be like this

    1. present address;

    2. set the R/W line;

    3. strobe;

    4. wait a little while (or slave ack);

    5. read the data line.

    the slave would be activated by the strobe line:

    1. read the address line

    2. if R/W line set -> this is for master to read and slave to write

      2.1 present the data on the data line;

      2.2 wait some time

      2.3 float the data line

      2.4.exit / send the ack

      else -> this is for master to write and slave to read

      2.5 read data

      2.6 exit / send the ack

    initially you can start with fixed length of delay and add ack later on.

    with that many lines involved, some kind of serial protocol is actually helpful.and much easier to code.

      

    2. 

  • So, I've solved it, but I've hit another problem. 

    First let me show the new code. 

    In the master, the write and read are changed to this: 

    void write(uint16_t address, uint8_t data){
        splitAndWriteAddress(address);  // splits up the address over the available pins in ports and writes it.
        P2DIR |= 0xFF;      // set dataIO in write mode
        P2OUT = data;       // write data
    
        P3OUT &= ~BIT0;     // deactivate READ mode set WRITE mode  --> R/~W = 0
        P3OUT &= ~BIT1;     // activate trigger --> T = 0 (High to Low)
    
        while(!(P3IN & BIT2)){  // if P3.2 (ACK) goes to 1, go further
            __no_operation();
        }
        P3OUT |= BIT1;      // deactivate trigger  --> T = 1
        P2DIR |= 0x00;      // set dataIO in read mode
    
        while((P3IN & BIT2)){  // if P3.2 (ACK) goes to 1, go further  --> COULD GET STUCK HERE
            __no_operation();
        }
    
    }
    
    
    uint8_t read(uint16_t address){
        uint8_t data = 0x00;
        splitAndWriteAddress(address);
        P2DIR &= 0x00;      // set dataIO in read mode
        P3OUT |= BIT0;      // deactivate WRITE mode set READ mode  --> R/~W = 1
        P3OUT &= ~BIT1;     // activate trigger --> T = 0 (High to Low)
        while(!(P3IN & BIT2)){ // if P3.2 (ACK) goes to 1, go further
            __no_operation();
        }
        data = P2IN;
        P3OUT |= BIT1;      // deactivate trigger --> T = 1
    
        while(P3IN & BIT2){ // if P3.2 goes to 0, go further
            __no_operation();
        }
        return data;
    }

    Which basically follows the above given logic. 

    And the slave interrupt is changed to this: 

    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=PORT3_VECTOR
    __interrupt void Port_3(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(PORT3_VECTOR))) Port_3 (void)
    #else
    #error Compiler not supported!
    #endif
    {
        /*
         * 4 usable RAM sections:
         * 1. D --> 1800h 'till 187Fh
         * 2. C --> 1880h 'till 18FFh
         * 3. B --> 1900h 'till 187Fh
         * 4. A --> 1980h 'till 19FFh
         */
        uint16_t volatile * address = (uint16_t *) getAddress();
    
            if(!(P3IN & BIT0)){  // READ
                P2DIR &= 0x00;  // put in read mode
                *address = P2IN;
                P3OUT |= BIT2;
            }
            //WRITE
            else{
                P2DIR |= 0xFF;  // put in write mode
                P2OUT &= 0x00;
                P2OUT |= *address;
                P3OUT |= BIT2;  // set ACK to 1
                P4DIR |= BIT0;
                P4OUT |= BIT0;
            }
        //}
        while(!(P3IN & BIT1)){ // do nothing while Trigger (3.1) is still high
            __no_operation();
        }
    
        P2DIR &= 0x00;
        P3OUT = ~BIT2;
    
        P3IFG=0; // set all flags to 0
    
    }

    Which again follows the above mentioned logic. 

    However, there is some error now. 

    Mainly I cannot write to memory in the slave. I get inside the if-statement for READ (as a slave, thus in the interrupt, tested it with an LED on a different port that lights up when in this statement), but nothing is put into memory. I know this because I only get "NO" if I try to write something new to the memory address. However the master does READ very good, because I already put some data in the slave previously (with other debugs etc.), and now when I read those some adresses back as a master, the "correct" data (thus the old data) came out. 

    I tried testing this by writing new data to the same address, and low and behold, the master could read the first data (which was still the same as the old one), but after that he kept giving back the same data. 

  •         if(!(P3IN & BIT0)){  // READ

    This test looks backwards. The master seems to think READ is P3.0=1 (R/~W), but this says it's P3.0=0 (~R/W).

  • Nono. The semantics here are weird. 

    the READ for a slave is the WRITE for a master, since when a master writes to a slave (R/W = 0), the slave must read. 

  • How about the initial settings? I expect P3.0=1 (output from master), P3.2=0 (output from slave), P2.all floating.

    Is there any chance you've lost your MPU settings, and Information FRAM suddenly isn't writable?

    I just noticed: "address" is a (uint16_t *), but you're really only reading/writing 8 bits. At minimum, the write puts an extra 0x00 byte. There may also be some alignment thing. (Even so, I expect reasonable results if you use exactly the same address.)

  • The initial setting for the Master are: 

    PM5CTL0 &= ~LOCKLPM5;
        WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
    
        //declare all the pins
        //Control Ports
        P3DIR |= 0b00000011; // third port is ACK port, this is READ only
        P3OUT |= 0b00000011;
    
        //Address Ports (Port 1: 5, Port 8: 4, Port 9: 7)
        P1DIR |= 0b11111000;
        P8DIR |= 0b11110000;
        P9DIR |= 0b01111111;
    
        //Data Port
        P2SEL0 &= 0x00;
        P2DIR |= 0x00;
    
        //initialise GPIO and clocks for timers and UART
        init_GPIO();
        init_clocks();
        init_communication();
        init_timer();

    With the above methods being: 

    void init_GPIO(void){
        //WDTCTL = WDTPW | WDTHOLD;                 // Stop Watchdog
    
        // Configure GPIO
        P3SEL0 |= BIT4 + BIT5;                    // eUSCI_A1 UART
        P3SEL1 &= ~(BIT4 + BIT5);                 // eUSCI_A1 UART
        PJSEL0 |= BIT4 | BIT5;                    // Configure XT1 pins for ACLK
    
        // Disable the GPIO power-on default high-impedance mode to activate
        // previously configured port settings
        PM5CTL0 &= ~LOCKLPM5;
    }
    
    void init_clocks (void){
        // Clock System Setup
        CSCTL0_H = CSKEY >> 8;                    // Unlock CS registers
        CSCTL1 = DCOFSEL_6;                       // Set DCO to 8MHz
        CSCTL2 = SELA__LFXTCLK | SELS__DCOCLK | SELM__DCOCLK;  // Set SMCLK = MCLK = DCO
                                                    // ACLK = VLOCLK
        CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;     // Set all dividers to 1
    
        CSCTL4 &= ~LFXTOFF;
        do
        {
        CSCTL5 &= ~LFXTOFFG;                      // Clear XT1 fault flag
        SFRIFG1 &= ~OFIFG;
        }while (SFRIFG1&OFIFG);                   // Test oscillator fault flag
    
        CSCTL0_H = 0;                             // Lock CS registerss
    }
    
    void init_communication(void)
    {
       // Configure USCI_A1 for UART mode
       UCA1CTLW0 = UCSWRST;                      // Put eUSCI in reset
       UCA1CTLW0 |= UCSSEL__ACLK;                // CLK = ACLK
       UCA1BR0 = 3;                              // 9600 baud
       UCA1MCTLW |= 0x5300;                      // 32768/9600 - INT(32768/9600)=0.41
       // UCBRSx value = 0x53 (See UG)
       UCA1BR1 = 0;
       UCA1CTL1 &= ~UCSWRST;                     // Initialize eUSCI
       UCA1IE |= UCRXIE;                         // Enable USCI_A1 RX interrupt
    
       __bis_SR_register(GIE);       // Enter LPM3, interrupts enabled --> writing to status register
       __no_operation();
    }
    
    void init_timer(void){
        TA0CTL = TASSEL__SMCLK | MC__CONTINOUS;   // SMCLK, continuous mode
    }

    And for the slave we have: 

    void main(void)
    {
        PM5CTL0 &= ~LOCKLPM5;
    	WDTCTL = WDTPW | WDTHOLD;	// stop watchdog timer
    	init_GPIO();
    	init_clocks();
    	while(1){
    	    __no_operation();
    	}
    }

    With the methods refferd to: 

    void init_GPIO(void){
        __bis_SR_register(GIE);     // enable interrupts
    
        P4DIR |= BIT0;
        P4OUT &= ~BIT0;
    
        //declare all the pins
        //Control Ports
        P3IFG &= ~0x02; // clear the flags
        P3DIR |= 0b00000100; // third port is CSN port, this is READ ONLY --> use this port to say when ready, make WRITE
        P3OUT &= ~BIT2;
        P3IE |= BIT1;
        P3IES |= BIT1;  // from L to H on the second
        P3IFG &= ~0x02 ; // clear the flags
    
        //Address Ports (Port 1: 5, Port 8: 4, Port 9: 7), READ ONLY
        P1DIR |= 0b00000000;
        P8DIR |= 0b00000000;
        P9DIR |= 0b00000000;
        __no_operation();
    
        //Data Port
        P2DIR &= 0x00;
    }
    
    void init_clocks (void){
        // Clock System Setup
        CSCTL0_H = CSKEY >> 8;                    // Unlock CS registers
        CSCTL1 = DCOFSEL_6;                       // Set DCO to 8MHz
        CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK;  // Set SMCLK = MCLK = DCO
                                                  // ACLK = VLOCLK
        CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;     // Set all dividers to 1
        CSCTL0_H = 0;
    }

    I don't think anything weird happens here? 

    Since the MSP430 that I use as a slave is a brand new one, I wouldn't know how I would've changed MPU settings in it. I looked at one of the coding examples, and I can implement it if needed, but I do not see how and why this would work though, as I am writing to an "open" RAM section (my addresses used are always between 0x1800 and 0x19FF). In the debug mode, I was able to write to it though.

    I also changed the pointer to a uint8_t*, but this hasn't solved it. 

  • According to data sheet (SLAS789D) Table 6-46, those addresses are in Information FRAM, which is acccess-controlled by the MPU. Whenever I've wanted to write to them (I don't recall whether I've tried on an FR6989) I've needed to make them writable using the "Build Settings->CCS General->MPU" tab, 

    The odd thing is that apparently you've succeeded before. On the other hand, the symptom you describe is one that you would see if those areas were write-protected. 

  • After doing this (in the tab do the "manually specify memory ...", and have lower border of segment 1 be 0x4400 and top 0x4800) and make that segment Read and Write, whenever I write to address e.g. 0x4410, I still get nothing. However I think it is because the borders are <<4 moved right. As in 0x4400 is actually 0x440000 (see MSP430FR58xx, MSP430FR59xx, and MSP430FR6xx Family User's Guide (Rev. P) on page 315 - 316). Is this correct? 

    For the fact that I have been able to write. I think I have been able to do this in the Debug mode, where probably the MPU isn't as strict and more forgiving. And afterwards it just stayed there.

  • It seems to work when I do that. The addresses really are 0x4400/0x4800, which are the beginning of FRAM [Ref data sheet Table 6-45]

    Experiments aside, I suggest you focus on Information FRAM (down at the bottom of the MPU tab), since working there you won't conflict with whatever the linker does.

  • Hi Bruce, 

    I was already doing that as well (writing to 0x1810 and so forth). It still does not seem to work with me. I never had any experience with an MPU, so this is kinda new to me (I normally don't work with specific memory). 

    However, since we are really off topic for this thread, I created a new one about this exact problem (writing to memory, although I can assure you that I am also looking in the datasheets and trying to find a solution) here: https://e2e.ti.com/support/microcontrollers/msp430/f/166/t/932016 

    In this (timing errors) thread I will make sure one of your above comments is a "this resolved my issue" comment (the one with the suggestion for the protocol). 

    I thank you for your help, and help on the next thread would be much appreciated.

  • Have you been able to watch (e.g. in the debugger) as the slave fails to write? That would serve as primary evidence. One good thing about this lock-step protocol is that you should be able to halt it (breakpoint) at any time and it will still do the right thing.

  • That's the thing, in the debugger is does not fail to write. I can clearly see that the data on that address is overwritten. And even better, if I then read again (either in the debugger or just normally), the master gives me the OK (the sign that it got back the data that he expected), however if I change the data of the address, then it goes back to 'NO'. 

  • Is getAddress() the same as it was in the other thread over here?

    https://e2e.ti.com/support/microcontrollers/msp430/f/166/p/903258/3338850

  • Yes. 

    The address itself is correct normally( cheked it with debugger multiple times)

  • You reported over in the other thread that something was "solved". Does that mean these programs work as expected now?

  • I am still testing it thoroughly, but everything seems to be working perfect .

  •     P2DIR &= 0x00;
        P3OUT = ~BIT2;

    I would be quite worried about having that in the code. After a while you don't know what you are trying to do there.

    I would put a macro that describe the activity there instead and map the macro based on the target / pin assignment. Essentially make the code as 'hardware independent' as possible. so next time you can take the same code to a different platform and remap the macro and you are done.

**Attention** This is a public forum