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.

CCS/MSP430FR5994: Create universal function for MPU hardware

Part Number: MSP430FR5994
Other Parts Discussed in Thread: MSP430WARE

Tool/software: Code Composer Studio

Possible create universal function for hardware?

For examle function for I2C on different eUSCI

for B1

void I2C_init(unsigned int addr,unsigned int count,unsigned int dv){
    UCB1CTLW0 = UCSWRST; // Software reset enabled
    UCB1CTLW0 |= UCMODE_3 | UCMST | UCSYNC | UCSSEL__SMCLK; // I2C mode, Master mode, sync
    UCB1CTLW1 |= UCASTP_2; // Automatic stop generated
    UCB1BRW = dv; // baudrate divider
    UCB1TBCNT = count; // number of bytes to be received
    UCB1I2CSA = addr; // Slave address
    UCB1CTLW0 &= ~UCSWRST; // clear reset register
    UCB1IE |= UCRXIE0 | UCNACKIE; //receive interrupt enable
}

for B0 or A0, or A1 - change only name register

Why create one function for differnet  eUSCI ? if use pointer to map port directly - create variable, up use memory and other overheads 

  • if minimum edit in manual mode i create for example

    header i2c.h :

    #ifndef INCLUDE_I2C_LIB__
    #define INCLUDE_I2C_LIB__
    
    #define I2C_RX_SIZE 64
    
    #define I2C_MAIN_CONTROL        UCB1CTLW0
    #define I2C_SLAVE_CONTROL       UCB1CTLW1
    #define I2C_WORK_CONTROL        UCB1CTL1
    #define I2C_ADDR_CONTROL        UCB1I2CSA
    #define I2C_DIV_CONTROL         UCB1BRW
    #define I2C_SEND_LEN_CONTROL    UCB1TBCNT
    #define I2C_STATUS              UCB1STATW
    #define I2C_SEND_BUFF           UCB1TXBUF
    #define I2C_TAKE_BUFF           UCB1RXBUF
    #define I2C_RESET_INIT          I2C_MAIN_CONTROL=UCSWRST // Software reset enabled
    #define I2C_RESET_ON            I2C_MAIN_CONTROL|=UCSWRST // Software reset enabled
    #define I2C_RESET_OFF           I2C_MAIN_CONTROL&=~UCSWRST // clear reset register
    #define I2C_SET_AUTO_STOP       I2C_SLAVE_CONTROL|=UCASTP_2
    #define I2C_SEND_MODE           I2C_WORK_CONTROL|=UCTR
    #define I2C_TAKE_MODE           I2C_WORK_CONTROL&=~UCTR
    #define I2C_START               I2C_WORK_CONTROL|=UCTXSTT
    
    #define I2C_SET_ADDR(a)         I2C_ADDR_CONTROL=a
    #define I2C_SET_DIVIDER(d)      I2C_DIV_CONTROL=d
    #define I2C_SET_SEND_LEN(l)     I2C_SEND_LEN_CONTROL=l
    #define I2C_SEND_BYTE(b)        I2C_SEND_BUFF=b
    #define I2C_WAIT_START()        I2C_WORK_CONTROL & UCTXSTT
    #define I2C_WAIT_STOP()         I2C_WORK_CONTROL & UCTXSTP
    #define I2C_WAIT_BUSY()         I2C_STATUS & UCBBUSY
    
    unsigned char I2C_RX_BUFF[I2C_RX_SIZE];
    volatile unsigned char I2C_Count;
    
    void I2C_init(unsigned int addr, unsigned int count, unsigned int dv);
    void I2C_setSlaveAddr(unsigned int addr);
    void I2C_readChar();
    unsigned char I2C_sendChar(unsigned char c, unsigned char reset);
    
    #endif /* INCLUDE_I2C_LIB__ */

    and i2c.c

    #include <msp430.h>
    #include "i2c.h"
    
    /*** Init I2C bus ***/
    void I2C_init(unsigned int addr, unsigned int count, unsigned int dv){
        I2C_RESET_INIT;
        I2C_MAIN_CONTROL|=UCMODE_3 | UCMST | UCSYNC | UCSSEL__SMCLK;         // I2C mode, Master mode, sync
        I2C_SET_AUTO_STOP;
        I2C_SET_DIVIDER(dv);
        I2C_SET_SEND_LEN(count);
        I2C_SET_ADDR(addr);
        I2C_RESET_OFF;
        I2C_Count=0;
    }
    /*** set slave address on I2C bus ***/
    void I2C_setSlaveAddr(unsigned int addr){
        I2C_RESET_ON;
        I2C_SET_ADDR(addr);
        I2C_RESET_OFF;
    }
    /*** read byte from I2C bus ***/
    void I2C_readChar(){
        if(I2C_Count>=I2C_RX_SIZE) I2C_Count=0;
        I2C_RX_BUFF[I2C_Count++] = I2C_TAKE_BUFF;             // Get RX data
    }
    /*** Send byte to I2C bus and wait anwver ***/
    unsigned char I2C_sendChar(unsigned char c, unsigned char reset){
        if(reset) I2C_Count=0;
        unsigned char cnt=I2C_Count;
        I2C_SEND_MODE;
        I2C_START;
        while (I2C_WAIT_START());
        I2C_SEND_BYTE(c);
        while (I2C_WAIT_BUSY());
        I2C_TAKE_MODE;
        I2C_START;
        while (I2C_WAIT_STOP());
        while (I2C_WAIT_BUSY());
        __delay_cycles(20000); // 8000 - 1 ms, when received byte write to TX register?
        return I2C_RX_BUFF[cnt];
    }

    and if change port i change only

    #define I2C_MAIN_CONTROL            UCB1CTLW0
    #define I2C_SLAVE_CONTROL          UCB1CTLW1
    #define I2C_WORK_CONTROL          UCB1CTL1
    #define I2C_ADDR_CONTROL           UCB1I2CSA
    #define I2C_DIV_CONTROL               UCB1BRW
    #define I2C_SEND_LEN_CONTROL  UCB1TBCNT
    #define I2C_STATUS                           UCB1STATW
    #define I2C_SEND_BUFF                   UCB1TXBUF
    #define I2C_TAKE_BUFF                    UCB1RXBUF

    why one way change all?

  • Hello Alexander,

    Yes. You can have one eusci sw for each protocol.
    And we have the MSP Driver Library that is already doing this.
    We do encourage user to use the driver library because it the abstracted API keeps you above the bits and bytes of the MSP430 hardware by providing easy-to-use function calls.

    MSP430Ware is a collection of resources that help users to effectively create and build MSP430 code. It included the MSP Driver Library.

    MSP Driver Library: www.ti.com/.../MSPDRIVERLIB
    MSPWare: http://www.ti.com/tool/mspware

    Thanks,
    Yiding
  • Thanks, I'll take a look at this library. 

    as I expected - the base address is taken and all other registers are considered from it

    in all function send first base address to specify the selected port

**Attention** This is a public forum