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.

ccsv5 with msp430f5659 i2c help with arrays, .h file, and pointers.

Other Parts Discussed in Thread: MSP430F5659

ok so my project consists of using an msp430f5659 and a PN532 communicating over I2C.  its working for the most part but i need some advice.  i started off a example program which has now been wildly altered to fit my project.  my first question is now that i have over seven data packs is there a way to have less pointers say not a pointer for each array.  as it stands i have a function for transmitting and reciving and it would be extremely convenient if i say could put the data pack in the function like "transmit(0x02, 0xAA);" and the function takes care of the preamble as well as the data length byte the check sum frame identifier and data check sum and post-amble automatically. so fare i have just been making an array of each with all the information. like this...

unsigned char *PTxData; // Pointer to TX data
volatile unsigned char TXByteCtr;

const unsigned char TxData[] = // get firmwear version
{
0x00,
0x00,
0xFF,
0x02,
0xFE,
0xD4,
0x02,
0x2A,
0x00
};

then when i want to transmit i do something like this.

x=0;

Transmit();                                    // Get Firmewar version

which calls my function

void Transmit(void){

unsigned int i;
for(i=0;i<10;i++); // Delay required between transaction


if(x == 1)
{
PTx2Data = (unsigned char *)Tx2Data; // TX array start address
// Place breakpoint here to see each // transmit operation.
TXByteCtr = sizeof Tx2Data; // Load TX byte counter

}
else if(x == 2)
{
PTx3Data = (unsigned char *)Tx3Data; // TX array start address
// Place breakpoint here to see each // transmit operation.
TXByteCtr = sizeof Tx3Data; // Load TX byte counter
}
else if(x == 3)
{
PTx4Data = (unsigned char *)Tx4Data; // TX array start address
// Place breakpoint here to see each // transmit operation.
TXByteCtr = sizeof Tx4Data; // Load TX byte counter

}
else if(x == 4)
{
PTx5Data = (unsigned char *)Tx5Data; // TX array start address
// Place breakpoint here to see each // transmit operation.
TXByteCtr = sizeof Tx5Data; // Load TX byte counter
}
else
{
PTxData = (unsigned char *)TxData; // TX array start address
// Place breakpoint here to see each // transmit operation.
TXByteCtr = sizeof TxData; // Load TX byte counter
}


UCB0CTL1 |= UCTXSTT | UCTR; // I2C TX, start condition

__bis_SR_register(LPM0_bits | GIE); // Enter LPM0, enable interrupts
__no_operation(); // Remain in LPM0 until all data
// is TX'd
while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent

}

and the isr

case 12: // Vector 12: TXIFG
if (TXByteCtr) // Check TX byte counter
{
if(x == 1)
{
UCB0TXBUF = *PTx2Data++; // Load TX buffer
TXByteCtr--; // Decrement TX byte counter
}
else if(x == 2)
{
UCB0TXBUF = *PTx3Data++; // Load TX buffer with int passive mode
TXByteCtr--; // Decrement TX byte counter
}
else if(x == 3)
{
UCB0TXBUF = *PTx4Data++; // Load TX buffer
TXByteCtr--; // Decrement TX byte counter
}
else if(x == 4)
{
UCB0TXBUF = *PTx5Data++; // Load TX buffer
TXByteCtr--;
}
else
{
UCB0TXBUF = *PTxData++; // Load TX buffer
TXByteCtr--; // Decrement TX byte counter
}

}
else
{
UCB0CTL1 |= UCTXSTP; // I2C stop condition
UCB0IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag
__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
}
default: break;
}

this is just the case in the isr that deals with transmitting......

now u can see as i make entire data packs each with its own pointer and changing a value of x before each transmit function is called now that can be overly complicated as well as take up more memory.  i also use the same rx buffer and i haven't found out yet if each time i receive information if it starts back at 0.  this will be impotent now because i will need to check incoming data in order to know what to send the pn532 as well as when it sends information about a card its reading it will say have 4 bytes in a pre determined spot of the incoming data pack that are to be repeated back in my next data pack to verify i wanted that card or as say an authorization thing.  any advice about all of this would be much appreciated.  maybe a suggestion about how to change my transmit function to just put that value of to tell it to send the data pack i want or better yet the data for the data pack bearing in mind it would have to fill in the check sum and all that  as well as possibly filling in 4 bytes that was from a data pack just received.  also what is the best way to check the rxbuffer in terms of setting the hex value of a variable to say rxbuffer[5] whatever it may be.  i used....

volatile unsigned char c;


c = RxBuffer[9];

 and im not sure it has always worked nor am i sure if my rx buffer resets to zero everytime it recives data or if it tacks it onto the end of the last data fed to the array my rx buffer is being used like this...

unsigned char *PRxData; // Pointer to RX data
volatile unsigned char RXByteCtr;
volatile unsigned char RxBuffer[100]; // Allocate 100 byte of RAM

-- this is to set the byte ctr to what im expecting to recive

RXByteCtr = 32; // Bytes to get

Receive(); 

--this is my receive function

void Receive(void){

unsigned int i;
for(i=0;i<10;i++); // Delay required between transaction
PRxData = (unsigned char *)RxBuffer; // Start of RX buffer
// RXByteCtr = 7; // Load RX byte counter (moved to outside function due to change as needed)

UCB0CTL1 |= UCTXSTT; // I2C start condition

__bis_SR_register(LPM0_bits | GIE); // Enter LPM0, enable interrupts
__no_operation(); // Remain in LPM0 until all data
// is RX'd
while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent


}

---and the part of the isr that deals with receving. 

case 10: // Vector 10: RXIFG
// RXByteCtr--; // Decrement RX byte counter (changed due to being skipped)
if (RXByteCtr)
{
RXByteCtr--; // Decrement RX byte counter ****change
*PRxData++ = UCB0RXBUF; // Move RX data to address PRxData

if(RXByteCtr == 1) // Only one byte left?
{
UCB0CTL1 |= UCTXSTP; // Generate I2C stop condition
__bic_SR_register_on_exit(LPM0_bits); // Exit active CPU
}
}
else
{

// *PRxData = UCB0RXBUF; // Move final RX data to PRxData
// __bic_SR_register_on_exit(LPM0_bits); // Exit active CPU
}
break;

please let me know if theres anything i can do or say the syntax (if you will) of having the receive function load the bite counter to where all i have to do is put Receive(32);  and it will receive 32 bytes.  also with all my data packets iv had to create assuming theres not way to have to data set ups made for me by code can i use a .h file for alot of this so my main is a little less busy?  any help would be greatly appreciated keep in mined my code works up tell i want to check my received data array for some reason or i need to automatically change a data pack of mine to match 4 bites of what was received. thats where im stuck.  thank you for any help and sorry this is so long.

  • Your question is a rather generic programming question: how to handle data in general, and data packets of a specific format.

    Sure you can dynamically create your packets. Just have a generic buffer of sufficient size, and fill-in preamble and passed data, and checksum and whatever, then send it.
    However, it is questionable whether the needed code is smaller than the size of your predefined packets.

    You may put the pointers to your packets into an array, and reference them with an index number instead of using different pointers. Or, in case of same size or an acceptable maximum size of the packets, you can just define a two-dimensional array, so your 'packet ID' is one dimension of the array while the data in the packet is the second dimension. The length of the data can be stored as the first byte of each data array:

    Const unsigned char
    
    TXData[][]=  {{9,0x00,0x00,0xFF,0x02,0xFe,0xD4,0x02,0x2A,0x00},{...},{...}...}
    [...]
    void Transmit(int x){
      TXByteCtr = TXData[x][0]; // first byte of array x = length of data
      PTxData = TXDATA[x]+1; // pointer to the 2nd byte of array x
      [...]
    }
    
    

    If your data packets require dynamic content, the creation of the packets based on passed information is the best way to go. But then you of course need to add code to calculate checksum etc.

    Some hints regarding your code:

    empty for loops are no reliable delays. They might be optimized away by the compiler. Don't assume that certain code will result in a certain timing. The C standard only ensures that the system state changes in the given way (that means, the loop variable has a certain value at the end of the loop - the compiler might just set it to this value and skip the loop if nothing else is done inside).
    For delays, use a timer or the _delay_cycles intrinsic.

  • thank you thats good advice what i think im gonna do is make command arrays like 

    const unsigned char Getfirm[ ]=

    {

    1,

    0x02

    };

    that way i have an array with the command that needs to be sent with the size.  then make an array that is preloaded ready to send but use a function (that i make) to set byte 3 to 0x01, calculate what i need for byte 4 and place it there then byte 5 will be predetermined then place using a for loop each byte i need after that in the rest of the array to transmit in this case just 0x02.  then have it sum up byte 5 through the last byte and add the check sum to equal zero then have a postamble.  

    i think thats how id like to do it then in that same function i can place my transmit function after that and it will transmit whatever that transmit array was loaded as.

    that being said how would i initialize a function to except an array 

    for example

    void transmitprocess(volatile unsigned char data[ ])  //  would i do something like that

    {

                      // would data[ ]; inside this function be the same as getfirm[ ] if called like i have below ?

                      //place my code here to load my tx array to be sent

    transmit();

    }

    //then be able to call on the function like this

    transmitprocess(getfirm[ ]);

    i apologize if i am a bit frustrating with all of this. 

  • Robert Breitenstein said:
    how would i initialize a function to except an array 

    The C language does not support passing arrays by value ( a copy of hte array content). You pass them by reference - with a pointer.

    void transmitprocess(unsigned char * data){..}

    Data then would be the same as getfirm. You pass the reference:

    transmitprocess(getfirm);

    Unless your array data contains length information (e.g. as the first byte as I suggested) or a unique termination byte (such as strings which end with 0x00), the called function doesn't know how long the array is whose pointer was passed. (well, the calling code doesn't know this either - even if getfirm was defined getfirm[10], you can always do x=getfirm[100] and get something back. But getfirm[100]=x; would be disastrous then.

**Attention** This is a public forum