Quantcast
Channel: MSP low-power microcontroller forum - Recent Threads
Viewing all articles
Browse latest Browse all 21948

MSP432 eUSCI I²C UCBCNTx stuck at UCBxTBCNT value in receiver mode

$
0
0

Hello world,

I've a problem with my MSP432P401R that I don't understand. I have configured the eUSCI register for I²C in master mode to send and receive data, all works well, except in receiver mode when i read the UCBCNTx field in UCBxSTATW register, this not return the number of bytes received on I²C bus since the last START or RESTART as it's indicate in the Technical Reference Manual p802, but always the value of UCTBCNRx field in UCBxTBCNT register that i have previously indicate. Whereas in transmitter mode all works perfectly. Can someone help me to understand this problem?

here is my code:

/******************************************************************************/
/*        @TITRE : i2c.h                                                      */
/*      @VERSION : 0                                                          */
/*     @CREATION : august 20, 2016                                            */
/* @MODIFICATION :                                                            */
/*      @AUTEURS : Enzo IGLESIS                                               */
/*    @COPYRIGHT : Copyright (c) 2016 Enzo IGLESIS                            */
/*      @LICENSE : MIT License (MIT)                                          */
/******************************************************************************/

#ifndef I2C_H_
#define I2C_H_

/******************************************************************************
 *
 *                                /|\  /|\
 *                MSP432P401       R    R
 *                  master         |    |
 *             -----------------   |    |
 *            |     P1.6/UCB0SDA|<-|----+->
 *            |                 |  |
 *            |                 |  |
 *            |     P1.7/UCB0SCL|<-+------>
 *            |                 |
 *
 *****************************************************************************/

/*******************************    LIBRARYS    *******************************/

/*******************************     MACROS     *******************************/
#define I2C_R   (!0)    /* Read */
#define I2C_W   (0)     /* Write */

#define I2C_ERR     (-1)

#define i2c_start()                 (UCB0CTLW0 |= UCTXSTT)
#define i2c_stop()                  (UCB0CTLW0 |= UCTXSTP)
#define i2c_start_stop();           (UCB0CTLW0 |= (UCTXSTT|UCTXSTP))
#define i2c_start_is_sent()         (UCB0CTLW0&UCTXSTT)
#define i2c_stop_is_sent()          (UCB0CTLW0&UCTXSTP)
#define i2c_bus_busy()              (UCB0STATW&UCBBUSY)


/*******************************     TYPES      *******************************/

/*******************************   CONSTANTES   *******************************/

/*******************************    VARIABLES   *******************************/

/*******************************   FUNCTIONS    *******************************/
void i2c_frequency(int_least32_t scl_frequency);
void i2c_setup_device(void);
void i2c_bytes_to_process(uint8_t counter);
void i2c_slave_address(uint8_t address, uint8_t r_w);
int i2c_status(void);
int i2c_read_write(uint8_t r_w, uint8_t address, uint8_t * data, uint8_t length);
int i2c_write(uint8_t address, uint8_t * data, uint8_t length);
int i2c_read(uint8_t address, uint8_t * data, uint8_t length);

#endif

/******************************************************************************/
/*        @TITRE : i2c.c                                                      */
/*      @VERSION : 0                                                          */
/*     @CREATION : august 20, 2016                                            */
/* @MODIFICATION :                                                            */
/*      @AUTEURS : Enzo IGLESIS                                               */
/*    @COPYRIGHT : Copyright (c) 2016 Enzo IGLESIS                            */
/*      @LICENSE : MIT License (MIT)                                          */
/******************************************************************************/

/*******************************    LIBRARYS    *******************************/
#include <msp432p401r.h>
#include "i2c.h"
/*******************************     MACROS     *******************************/

/*******************************     TYPES      *******************************/

/*******************************   CONSTANTES   *******************************/

/*******************************   VARIABLES    *******************************/
/* IRQHandler */
static volatile uint8_t * rtx_data;
static volatile int8_t status;
/*******************************   FUNCTIONS    *******************************/
void i2c_enable_interrupt(void)
{
	UCB0IE |= UCBCNTIE;         /* Byte counter interrupt enable */
	UCB0IE |= UCNACKIE;         /* Not-acknowledge interrupt enable */
	UCB0IE |= UCTXIE0;          /* Transmit interrupt enable 0 */
	UCB0IE |= UCRXIE0;          /* Receive interrupt enable 0 */
	NVIC_EnableIRQ(EUSCIB0_IRQn);
}

void i2c_frequency(int_least32_t scl_frequency)
{
    UCB0CTLW0 |= UCSWRST;        /* Software reset enable */
    UCB0BRW = SystemCoreClock/scl_frequency;  /* prescale */
    UCB0CTLW0 &= ~UCSWRST;      /* Software reset released for operation */
    i2c_enable_interrupt();
}

void i2c_setup_device(void)
{
	/* Set UCSWRST */
	UCB0CTLW0 = UCSWRST;        /* Software reset enable */
	/* initialize eUSCI_B register */
    UCB0CTLW0 &= ~UCA10;        /* Own address is a 7-bit address */
    UCB0CTLW0 &= ~UCSLA10;      /* Address slave with 7-bit address */
    UCB0CTLW0 &= ~UCMM;         /* Single master environment. There is no other master in the system. The address compare unit is disabled */
    UCB0CTLW0 |= UCMST;         /* Master mode */
    UCB0CTLW0 |= UCMODE_3;      /* I2C mode */
    UCB0CTLW0 |= UCSYNC;        /* Synchronous mode enable */
    UCB0CTLW0 |= UCSSEL_3;      /* clock source : SMCLK */
    UCB0CTLW0 &= ~UCTXACK;      /* (slave mode) Do not acknowledge the slave address */
    UCB0CTLW0 |= UCTR;          /* Transmitter */
    UCB0CTLW0 &= ~UCTXSTP;      /* No STOP generated */
    UCB0CTLW0 &= ~UCTXSTT;      /* Do not generate START condition */
    UCB0CTLW0 &= ~UCTXNACK;     /* Acknowledge normally */
    UCB0CTLW1 = 0x0000;			/* Reset UCB0CTLW1 */
    UCB0CTLW1 &= ~UCETXINT;     /* (slave mode) UCTXIFGx is set after an address match with UCxI2COAx and the direction bit indicating slave transmit */
    UCB0CTLW1 &= ~UCCLTO_3;     /* Disable clock low timeout counter */
    UCB0CTLW1 &= ~UCSTPNACK;    /* Send a not acknowledge before the STOP condition as a master receiver */
    UCB0CTLW1 &= ~UCSWACK;      /* The address acknowledge of the slave is controlled by the eUSCI_B module */
    UCB0CTLW1 |= UCASTP_2;      /* A STOP condition is generated automatically after the byte counter value reached UCBxTBCNT */
    UCB0CTLW1 |= UCGLIT_0;      /* Deglitch time = 50 ns */
    UCB0ADDMASK |= ADDMASK_M;   /* the address mask feature is desactivated */
    UCB0I2COA0 &= ~UCGCEN;      /* Do not respond to a general call */
    UCB0I2COA0 &= ~UCOAEN;      /* The slave address defined in I2COA0 is disabled */
    UCB0I2COA1 &= ~UCOAEN;      /* The slave address defined in I2COA1 is disabled */
    UCB0I2COA2 &= ~UCOAEN;      /* The slave address defined in I2COA2 is disabled */
    UCB0I2COA3 &= ~UCOAEN;      /* The slave address defined in I2COA3 is disabled */
    /* Configure ports */
    P1SEL0 |= BIT6;				/* Configure P1.6 as SDA */
    P1SEL1 &= ~BIT6;
    P1SEL0 |= BIT7;				/* Configure P1.7 as SCL */
    P1SEL1 &= ~BIT7;
    /* Reset UCSWRST */
    UCB0CTLW0 &= ~UCSWRST;      /* Software reset released for operation */
    /* Enable interrupts */
    i2c_enable_interrupt();
}

void i2c_bytes_to_process(uint8_t counter)
{
    UCB0CTLW0 |= UCSWRST;       /* Software reset enable */
    UCB0TBCNT &= ~UCTBCNT_M;    /* reset Counter Threshold Register */
    UCB0TBCNT |= counter;       /* set Counter Threshold Register */
    UCB0CTLW0 &= ~UCSWRST;      /* Software reset released for operation */
    i2c_enable_interrupt();
}

void i2c_slave_address(uint8_t address, uint8_t r_w)
{
    UCB0I2CSA &= ~I2CSA_M;  /* Reset Slave Address Register */
    UCB0I2CSA |= address;   /* I2C slave address */
    if(r_w) /* read */
    {
        UCB0CTLW0 &= ~UCTR; /* Receiver */
    }
    else    /* write */
    {
        UCB0CTLW0 |= UCTR;  /* Transmitter */
    }
}

int i2c_status(void)
{
    /* local declaration */
    int8_t old_status = status;
    /* program statement */
    status = 0;
    return old_status;
}

int i2c_read_write(uint8_t r_w, uint8_t address, uint8_t * data, uint8_t length)
{
    while(i2c_bus_busy());  /* Wait until i2c bus is available */
    rtx_data = data;
    status = 0;
    i2c_bytes_to_process(length);   /* set the number of bytes to send */
    i2c_slave_address(address, r_w);  /* set the slave address in write or read mode */
    i2c_start();    /* send an i2c start signal */
    /* IRQHandler */
    __sleep();
    return i2c_status();    /* return the number of bytes processed or -1 if an error occured */
}

int i2c_write(uint8_t address, uint8_t * data, uint8_t length)
{
    return i2c_read_write(I2C_W, address, data, length);
}

int i2c_read(uint8_t address, uint8_t * data, uint8_t length)
{
    return i2c_read_write(I2C_R, address, data, length);
}

/*******************************   INTERRUPT    *******************************/
void EUSCIB0_IRQHandler(void)
{
    if(UCB0IFG&UCTXIFG0)	/* transmit */
    {
        UCB0TXBUF = rtx_data[(UCB0STATW&UCBCNT_M)>>UCBCNT_OFS];    // Here it's incremented
	UCB0IFG &= ~UCTXIFG0;
    }
    if(UCB0IFG&UCRXIFG0)	/* receive */
    {
        UCB0IFG &= ~UCRXIFG0;
	rtx_data[(UCB0STATW&UCBCNT_M)>>UCBCNT_OFS] = UCB0RXBUF;    // Here it's stuck at the number of byte to process
    }
    if(UCB0IFG&UCNACKIFG)	/* Not-acknowledge received */
    {
    	UCB0IFG &= ~UCNACKIFG;
    	i2c_stop();             /* I2C Stop condition */
    	status = I2C_ERR;
    	__low_power_mode_off_on_exit()
    }
    if(UCB0IFG&UCBCNTIFG)	/* Byte counter */
    {
 	UCB0IFG &= ~UCBCNTIFG;
        status = UCB0TBCNT&UCTBCNT_M;
	__low_power_mode_off_on_exit();
    }
}


Viewing all articles
Browse latest Browse all 21948

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>