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: reading data from PxIN, putting in variable and using that as pointer

Part Number: MSP430FR6989

Hi,

For a project I'm working with 2 MSP430FR6989, I need them to communicate to each other in a very specific way (No I cannot use I2C, SPI or other protocols like that). I need to use the GPIO ports to give through an address (ports 4, 8 and 9 for me), and Port 2 gives through data. The address is then "converted" to a pointer at which the data is stored. 
However, It seems I am not able to read the in the PxIN registers and concatenate the to the address. I cannot even read out the entire Port2 and put it in the variable. I checked that the databits are coming through via the registers (in CCS debugger), and they do. What seems to be the problem here?

Code: 

#include <msp430.h> 
#include "ram_module.h"

/**
 * main.c
 */
int main(void)
{
    PM5CTL0 &= ~LOCKLPM5;
	WDTCTL = WDTPW | WDTHOLD;	// stop watchdog timer
	
	//declare all the pins
	//Control Ports
	P3DIR |= 0b00000000; // third port is CSN port, this is READ ONLY
	P3IE |= 0b00000111;
	P3IES |= 0x03 ; // from high to low on the first two pins
	P3IFG &= ~0x03 ; // clear the flags
	__bis_SR_register(GIE);     // enable interrupts

	//Address Ports (Port 1: 5, Port 8: 4, Port 9: 7), READ ONLY
	P1DIR |= 0b00000000;
	P8DIR |= 0b00000000;
	P9DIR |= 0b00000000;
	//Data Port
	P2SEL0 &= 0x00;
	P2DIR |= 0x00;

	//For debugging
	while(1){
	    __no_operation();
	}

	return 0;
}

/*
 * Each port has only one vector and only one ISR can be written.
 * To distinguish between different interrupt sources for one interrupt vector,
 * in this case the different port pins, you'll have to check the IFG bits inside the ISR.
 */

#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
{
    uint16_t volatile * const address = (uint16_t *) getAddress();
    //uint16_t* data =  NULL;
    //data = address;
    if(P3IFG&BIT0){
       //P1OUT^=BIT0; data is written to this MPC
        *address = P2IN;
    }
    if(P3IFG&BIT1){ //could be an else
       //P1OUT^=BIT1;data is read from the MPC
        P2DIR &= 0xFF;  // put in write mode
        P2OUT = *address;
        //address = address + 8;
        //P2OUT = *address;
        __no_operation();
        P2DIR &= 0x00;  // put in read mode
    }

    P3IFG=0; // set all flags to 0

}

And the getAddress() method: 

inline uint16_t getAddress(){
    //uint16_t data_out = byte_MSB << 8 | byte_LSB;
    uint16_t byte_MSB = P9OUT & 0b01111111;
    byte_MSB = (P9OUT << 8) | (P8OUT & 0b11110000);
    short byte_LSB = (P1OUT & 0b11111000) >> 3;
    uint16_t total_address = byte_MSB << 1 | byte_LSB;
    __no_operation();
    __no_operation();
    return total_address;  
}

  • byte_MSB = (P9OUT << 8) | (P8OUT & 0b11110000);

    I think you need to cast P9OUT to 16 bits. You are just shifting an 8 bit number 8 bits which puts all the bits into the bit bucket.

  • Hi, 

    When I do the following then: 

    inline uint16_t getAddress(){
        uint16_t byte_MSB = (uint16_t) P9OUT & 0b0000000001111111;
        byte_MSB = (byte_MSB << 8) | ((uint16_t) P8OUT & 0b0000000011110000);
        short byte_LSB = (P1OUT & 0b11111000) >> 3;
        uint16_t total_address = byte_MSB << 1 | byte_LSB;
        __no_operation();
        __no_operation();
        return total_address;  
    }

    It does the exact same thing. 
    When looking at the variables in the debugger, it gives that byte_MSB is 256, same for byte_LSB. 

  • Your title refers to PxIN, but getAddress() is reading from PxOUT, which doesn't reflect the state of the pins. I think you want P9IN, P8IN etc there.

    ---------------------

    >        P2DIR &= 0xFF;  // put in write mode
    This doesn't set the P2 pins to output mode. Try:
    >        P2DIR |= 0xFF;  // put in write mode

    ---------------------

    You haven't described your protocol, but you're not giving the other side very long (maybe 3-5 usec) to accept the data. Should you maybe wait for P3.1 to go low again (or something) before releasing the bus?

     
  • It does indeed help to read out IN instead of OUT, how did I not catch that myself ...
    Thanks!

    The protocol is very timing critical, I am still working out what the timings themselves need to be. Releasing the bus later could be a good option though. 

  • You may want to dig up a data sheet from, say, a parallel SRAM or NAND-Flash chip, and steal, er "adapt" some of their ideas. Those bus protocols have been around forever (lots of time for "learning experiences") and they're pretty fast.

  • I'll look into it, thanks!!

    BTW (kinda off topic), is there any reason why I cannot put the data through in the pointer, it does not seem that the data is being stored on the address. Is that because of the MPU of the FRAM? Or is there a specific address range I need to write to, if so I can't seem to find it in the datasheet at first glance. 

  • Nevermind, I found it. 
    For the one stumbling onto this, there are information memory segments in the FRAM in which you can write this stuff. 

**Attention** This is a public forum