From 4f1eebf4d11ea530da0533dc37aca48fa522481a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alf=20H=C3=B8gemark?= Date: Tue, 24 Mar 2015 09:52:29 +0100 Subject: [PATCH 01/13] msp430: twi: remove whitespace at end of lines --- hardware/msp430/cores/msp430/twi.c | 16 ++++++++-------- hardware/msp430/cores/msp430/usci_isr_handler.c | 2 +- hardware/msp430/cores/msp430/usci_isr_handler.h | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/hardware/msp430/cores/msp430/twi.c b/hardware/msp430/cores/msp430/twi.c index 0a361c42451..06e89a29eae 100644 --- a/hardware/msp430/cores/msp430/twi.c +++ b/hardware/msp430/cores/msp430/twi.c @@ -74,7 +74,7 @@ static uint8_t twi_my_addr; #if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) \ || defined(__MSP430_HAS_USCI_B1__) #ifndef USE_USCI_B1 -#define UCBxCTLW0 UCB0CTLW0 +#define UCBxCTLW0 UCB0CTLW0 #define UCBxCTL0 UCB0CTL0 #define UCBxCTL1 UCB0CTL1 #define UCBxCTL0 UCB0CTL0 @@ -685,7 +685,7 @@ void i2c_txrx_isr(void) // RX/TX Service #endif /* Master transmit mode */ if (twi_state == TWI_MTX) { - // if there is data to send, send it, otherwise stop + // if there is data to send, send it, otherwise stop if(twi_masterBufferIndex < twi_masterBufferLength){ // Copy data to output register and ack. UCB0TXBUF = twi_masterBuffer[twi_masterBufferIndex++]; @@ -697,7 +697,7 @@ void i2c_txrx_isr(void) // RX/TX Service __bic_SR_register(LPM0_bits); } else { twi_inRepStart = true; // we're gonna send the START - // don't enable the interrupt. We'll generate the start, but we + // don't enable the interrupt. We'll generate the start, but we // avoid handling the interrupt until we're in the next transaction, // at the point where we would normally issue the start. UCB0CTL1 |= UCTXSTT; @@ -766,7 +766,7 @@ void i2c_state_isr(void) // I2C Service /* Request for txBuffer to be filled and length to be set. */ /* note: user must call twi_transmit(bytes, length) to do this */ twi_onSlaveTransmit(); - /* If they didn't change buffer & length, initialize it + /* If they didn't change buffer & length, initialize it * TODO: Is this right? Shouldn't we reply with a NACK if there is no data to send? */ if (0 == twi_txBufferLength) { twi_txBufferLength = 1; @@ -837,7 +837,7 @@ void USCI_B0_ISR(void) // leave slave receiver state twi_state = TWI_IDLE; twi_error = TWI_ERROR_DATA_NACK; - __bic_SR_register_on_exit(CPUOFF); // Exit LPM0 + __bic_SR_register_on_exit(CPUOFF); // Exit LPM0 break; case USCI_I2C_UCSTTIFG: // USCI I2C Mode: UCSTTIFG UCB0IFG &= ~UCSTTIFG; @@ -877,7 +877,7 @@ void USCI_B0_ISR(void) */ UCB0CTLW0 &= ~0x18; - __bic_SR_register_on_exit(CPUOFF); // Exit LPM0 + __bic_SR_register_on_exit(CPUOFF); // Exit LPM0 break; case USCI_I2C_UCRXIFG3: // USCI I2C Mode: UCRXIFG3 break; @@ -915,7 +915,7 @@ void USCI_B0_ISR(void) case USCI_I2C_UCTXIFG0: // USCI I2C Mode: UCTXIFG0 UCB0IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag if (twi_state == TWI_MTX) { // Master receive mode - // if there is data to send, send it, otherwise stop + // if there is data to send, send it, otherwise stop if(twi_masterBufferIndex < twi_masterBufferLength){ // copy data to output register and ack UCB0TXBUF = twi_masterBuffer[twi_masterBufferIndex++]; // Transmit data at address PTxData @@ -924,7 +924,7 @@ void USCI_B0_ISR(void) UCB0CTLW0 |= UCTXSTP; // Generate I2C stop condition else { twi_inRepStart = true; // we're gonna send the START - // don't enable the interrupt. We'll generate the start, but we + // don't enable the interrupt. We'll generate the start, but we // avoid handling the interrupt until we're in the next transaction, // at the point where we would normally issue the start. UCB0CTLW0 |= UCTXSTT; diff --git a/hardware/msp430/cores/msp430/usci_isr_handler.c b/hardware/msp430/cores/msp430/usci_isr_handler.c index 4aa00598177..f081ea8a4ed 100644 --- a/hardware/msp430/cores/msp430/usci_isr_handler.c +++ b/hardware/msp430/cores/msp430/usci_isr_handler.c @@ -1,6 +1,6 @@ #include "Energia.h" #if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_A0__) || defined(__MSP430_HAS_USCI_A1__) \ - || defined(__MSP430_HAS_EUSCI_A0__)|| defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) + || defined(__MSP430_HAS_EUSCI_A0__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) #include "usci_isr_handler.h" /* This dummy function ensures that, when called from any module that * is interested in having the USCIAB0TX_VECTOR and USCIAB0TX_VECTOR diff --git a/hardware/msp430/cores/msp430/usci_isr_handler.h b/hardware/msp430/cores/msp430/usci_isr_handler.h index 5ff362330b2..59605f26a97 100644 --- a/hardware/msp430/cores/msp430/usci_isr_handler.h +++ b/hardware/msp430/cores/msp430/usci_isr_handler.h @@ -2,7 +2,7 @@ #define usci_isr_handler_h #if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_A0__) || defined(__MSP430_HAS_USCI_A1__) \ - || defined(__MSP430_HAS_EUSCI_A0__)|| defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) + || defined(__MSP430_HAS_EUSCI_A0__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) typedef void CHardwareSerial; #ifdef __cplusplus From 7795facdfc47a50ae864f396c29190348b8bdc23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alf=20H=C3=B8gemark?= Date: Tue, 24 Mar 2015 10:04:41 +0100 Subject: [PATCH 02/13] Msp430: twi: replace ifdef with if defined Replace #ifdef with #if defined, to consistently use if defined in the twi.c file. Likewise, replace ifndef with if !defined. --- hardware/msp430/cores/msp430/twi.c | 58 +++++++++++++++--------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/hardware/msp430/cores/msp430/twi.c b/hardware/msp430/cores/msp430/twi.c index 06e89a29eae..0611d517e8a 100644 --- a/hardware/msp430/cores/msp430/twi.c +++ b/hardware/msp430/cores/msp430/twi.c @@ -30,11 +30,11 @@ #include #include "Energia.h" // for digitalWrite -#ifndef cbi +#if !defined(cbi) #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #endif -#ifndef sbi +#if !defined(sbi) #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) #endif @@ -65,7 +65,7 @@ static volatile uint8_t twi_rxBufferIndex; static volatile uint8_t twi_error; -#ifdef __MSP430_HAS_USI__ +#if defined(__MSP430_HAS_USI__) static uint8_t twi_slarw; static uint8_t twi_my_addr; @@ -73,7 +73,7 @@ static uint8_t twi_my_addr; #if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) \ || defined(__MSP430_HAS_USCI_B1__) -#ifndef USE_USCI_B1 +#if !defined(USE_USCI_B1) #define UCBxCTLW0 UCB0CTLW0 #define UCBxCTL0 UCB0CTL0 #define UCBxCTL1 UCB0CTL1 @@ -118,10 +118,10 @@ static uint8_t twi_my_addr; #endif #endif -#ifdef __MSP430_HAS_USCI__ +#if defined(__MSP430_HAS_USCI__) #endif -#ifdef __MSP430_HAS_EUSCI_B0__ +#if defined(__MSP430_HAS_EUSCI_B0__) #endif /* @@ -137,7 +137,7 @@ void twi_init(void) twi_sendStop = true; // default value twi_inRepStart = false; -#ifdef __MSP430_HAS_USI__ +#if defined(__MSP430_HAS_USI__) /* 100 KHz for all */ #if (F_CPU >= 16000000L) || (F_CPU >= 12000000L) @@ -202,7 +202,7 @@ void twi_init(void) #endif #endif -#ifdef __MSP430_HAS_EUSCI_B0__ +#if defined(__MSP430_HAS_EUSCI_B0__) P1SEL1 |= BIT6 + BIT7; // Pin init @@ -244,14 +244,14 @@ void twi_init(void) */ void twi_setAddress(uint8_t address) { -#ifdef __MSP430_HAS_USI__ +#if defined(__MSP430_HAS_USI__) twi_my_addr = address << 1; #endif #if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) /* UCGCEN = respond to general Call */ UCB0I2COA = (address | UCGCEN); #endif -#ifdef __MSP430_HAS_EUSCI_B0__ +#if defined(__MSP430_HAS_EUSCI_B0__) /* UCGCEN = respond to general Call */ UCB0I2COA0 = (address | UCOAEN | UCGCEN); #endif @@ -270,7 +270,7 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen { uint8_t i; -#ifdef __MSP430_HAS_USI__ +#if defined(__MSP430_HAS_USI__) /* Disable START condition interrupt */ USICTL1 &= ~USISTTIE; /* I2C master mode */ @@ -283,14 +283,14 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen UCB0CTL1 &= ~(UCTR); // Configure in receive mode UCB0I2CSA = address; // Set Slave Address UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation -#ifdef __MSP430_HAS_USCI__ +#if defined(__MSP430_HAS_USCI__) UCB0I2CIE |= (UCALIE|UCNACKIE|UCSTPIE); // Enable I2C interrupts UC0IE |= (UCB0RXIE | UCB0TXIE); // Enable I2C interrupts #else UCB0IE |= (UCALIE|UCNACKIE|UCSTPIE|UCRXIE|UCTXIE); // Enable I2C interrupts #endif #endif -#ifdef __MSP430_HAS_EUSCI_B0__ +#if defined(__MSP430_HAS_EUSCI_B0__) UCB0CTLW0 = UCSWRST; // Enable SW reset UCB0CTLW0 |= (UCMST | UCMODE_3 | UCSYNC | UCSSEL__SMCLK); // I2C Master, synchronous mode UCB0CTLW0 &= ~(UCTR); // Configure in receive mode @@ -312,7 +312,7 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen // received, causing that NACK to be sent in response to receiving the last // expected byte of data. -#ifdef __MSP430_HAS_USI__ +#if defined(__MSP430_HAS_USI__) /* build sla+w, slave device address + w bit */ twi_slarw = 1; twi_slarw |= address << 1; @@ -331,7 +331,7 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen UCB0CTL1 |= UCTXSTP; // Send I2C stop condition after recv } #endif -#ifdef __MSP430_HAS_EUSCI_B0__ +#if defined(__MSP430_HAS_EUSCI_B0__) twi_state = TWI_MRX; // Master receive mode while (UCB0CTLW0 & UCTXSTP); // Ensure stop condition got sent UCB0CTLW0 |= UCTXSTT; // I2C start condition @@ -376,7 +376,7 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait twi_error = TWI_ERRROR_NO_ERROR; twi_sendStop = sendStop; -#ifdef __MSP430_HAS_USI__ +#if defined(__MSP430_HAS_USI__) /* Disable START condition interrupt */ USICTL1 &= ~USISTTIE; /* I2C master mode */ @@ -389,14 +389,14 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait UCB0CTL1 |= UCTR; // Configure in transmit mode UCB0I2CSA = address; // Set Slave Address UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation -#ifdef __MSP430_HAS_USCI__ +#if defined(__MSP430_HAS_USCI__) UCB0I2CIE |= (UCALIE|UCNACKIE|UCSTPIE); // Enable I2C interrupts UC0IE |= UCB0TXIE; // Enable I2C interrupts #else UCB0IE |= (UCALIE|UCNACKIE|UCSTPIE|UCTXIE); // Enable I2C interrupts #endif #endif -#ifdef __MSP430_HAS_EUSCI_B0__ +#if defined(__MSP430_HAS_EUSCI_B0__) UCB0CTLW0 = UCSWRST; // Enable SW reset UCB0CTLW0 |= (UCMST | UCMODE_3 | UCSSEL__SMCLK | UCSYNC); // I2C Master, synchronous mode UCB0CTLW0 |= UCTR; // Configure in transmit mode @@ -422,7 +422,7 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait twi_masterBuffer[i] = data[i]; } -#ifdef __MSP430_HAS_USI__ +#if defined(__MSP430_HAS_USI__) /* build sla+w, slave device address + w bit */ twi_slarw = 0; twi_slarw |= address << 1; @@ -435,7 +435,7 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait twi_state = TWI_MTX; // Master Transmit mode UCB0CTL1 |= UCTXSTT; // I2C start condition #endif -#ifdef __MSP430_HAS_EUSCI_B0__ +#if defined(__MSP430_HAS_EUSCI_B0__) twi_state = TWI_MTX; // Master Transmit mode while (UCB0CTLW0 & UCTXSTP); // Ensure stop condition got sent UCB0CTLW0 |= UCTXSTT; // I2C start condition @@ -514,7 +514,7 @@ void twi_attachSlaveTxEvent( void (*function)(void) ) void send_start() { -#ifdef __MSP430_HAS_USI__ +#if defined(__MSP430_HAS_USI__) USISRL = 0x00; USICTL0 |= USIGE+USIOE; USICTL0 &= ~USIGE; @@ -523,7 +523,7 @@ void send_start() #endif } -#ifdef __MSP430_HAS_USI__ +#if defined(__MSP430_HAS_USI__) __attribute__((interrupt(USI_VECTOR))) void USI_ISR(void) { @@ -647,7 +647,7 @@ void i2c_txrx_isr(void) // RX/TX Service { /* USCI I2C mode. USCI_B0 receive interrupt flag. * UCB0RXIFG is set when UCB0RXBUF has received a complete character. */ -#ifdef __MSP430_HAS_USCI__ +#if defined(__MSP430_HAS_USCI__) if (UC0IFG & UCB0RXIFG){ #else if (UCB0IFG & UCRXIFG){ @@ -678,7 +678,7 @@ void i2c_txrx_isr(void) // RX/TX Service } /* USCI I2C mode. USCI_B0 transmit interrupt flag. * UCB0TXIFG is set when UCB0TXBUF is empty.*/ -#ifdef __MSP430_HAS_USCI__ +#if defined(__MSP430_HAS_USCI__) if (UC0IFG & UCB0TXIFG){ #else if (UCB0IFG & UCTXIFG){ @@ -721,7 +721,7 @@ void i2c_txrx_isr(void) // RX/TX Service void i2c_state_isr(void) // I2C Service { /* Arbitration lost interrupt flag */ -#ifdef __MSP430_HAS_USCI__ +#if defined(__MSP430_HAS_USCI__) if (UCB0STAT & UCALIFG) { UCB0STAT &= ~UCALIFG; #else @@ -732,7 +732,7 @@ void i2c_state_isr(void) // I2C Service } /* Not-acknowledge received interrupt flag. * UCNACKIFG is automatically cleared when a START condition is received.*/ -#ifdef __MSP430_HAS_USCI__ +#if defined(__MSP430_HAS_USCI__) if (UCB0STAT & UCNACKIFG) { UCB0STAT &= ~UCNACKIFG; #else @@ -748,7 +748,7 @@ void i2c_state_isr(void) // I2C Service } /* Start condition interrupt flag. * UCSTTIFG is automatically cleared if a STOP condition is received. */ -#ifdef __MSP430_HAS_USCI__ +#if defined(__MSP430_HAS_USCI__) if (UCB0STAT & UCSTTIFG) { UCB0STAT &= ~UCSTTIFG; #else @@ -781,7 +781,7 @@ void i2c_state_isr(void) // I2C Service } /* Stop condition interrupt flag. * UCSTPIFG is automatically cleared when a START condition is received. */ -#ifdef __MSP430_HAS_USCI__ +#if defined(__MSP430_HAS_USCI__) if (UCB0STAT & UCSTPIFG) { UCB0STAT &= ~UCSTPIFG; #else @@ -797,7 +797,7 @@ void i2c_state_isr(void) // I2C Service } #endif -#ifdef __MSP430_HAS_EUSCI_B0__ +#if defined(__MSP430_HAS_EUSCI_B0__) __attribute__((interrupt(USCI_B0_VECTOR))) void USCI_B0_ISR(void) { From 1a59ea172aa3ef1a0a78170d6a32e1846e9ae437 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alf=20H=C3=B8gemark?= Date: Tue, 24 Mar 2015 10:09:31 +0100 Subject: [PATCH 03/13] msp430: twi: remove duplicate defines --- hardware/msp430/cores/msp430/twi.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/hardware/msp430/cores/msp430/twi.c b/hardware/msp430/cores/msp430/twi.c index 0611d517e8a..ef447d57652 100644 --- a/hardware/msp430/cores/msp430/twi.c +++ b/hardware/msp430/cores/msp430/twi.c @@ -77,7 +77,6 @@ static uint8_t twi_my_addr; #define UCBxCTLW0 UCB0CTLW0 #define UCBxCTL0 UCB0CTL0 #define UCBxCTL1 UCB0CTL1 -#define UCBxCTL0 UCB0CTL0 #define UCBxBRW UCB0BRW #define UCBxBR0 UCB0BR0 #define UCBxBR1 UCB0BR1 @@ -98,7 +97,6 @@ static uint8_t twi_my_addr; #define UCBxCTLW0 UCB1CTLW0 #define UCBxCTL0 UCB1CTL0 #define UCBxCTL1 UCB1CTL1 -#define UCBxCTL0 UCB1CTL0 #define UCBxBRW UCB1BRW #define UCBxBR0 UCB1BR0 #define UCBxBR1 UCB1BR1 From 294dc2caa0ae2fa186229d9e18eb938b00917de3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alf=20H=C3=B8gemark?= Date: Tue, 24 Mar 2015 10:39:42 +0100 Subject: [PATCH 04/13] msp430: twi: replace UCB0 with UCBx, allow choice of using USCB0 or USCB1 Replace hardcoded USCB0... registers with use of UCBx defines, so we can choose if we want to use USCB0 or USCB1. --- hardware/msp430/cores/msp430/twi.c | 125 ++++++++++++++--------------- 1 file changed, 62 insertions(+), 63 deletions(-) diff --git a/hardware/msp430/cores/msp430/twi.c b/hardware/msp430/cores/msp430/twi.c index ef447d57652..d125ee81a3a 100644 --- a/hardware/msp430/cores/msp430/twi.c +++ b/hardware/msp430/cores/msp430/twi.c @@ -169,7 +169,7 @@ void twi_init(void) pinMode_int(TWISCL, TWISCL_SET_MODE); //Disable the USCI module and clears the other bits of control register - UCB0CTL1 = UCSWRST; + UCBxCTL1 = UCSWRST; /* * Configure as I2C Slave. @@ -177,17 +177,17 @@ void twi_init(void) * UCSYNC = Synchronous mode * UCCLK = SMCLK */ - UCB0CTL0 = UCMODE_3 | UCSYNC; + UCBxCTL0 = UCMODE_3 | UCSYNC; /* * Compute the clock divider that achieves less than or * equal to 100kHz. The numerator is biased to favor a larger * clock divider so that the resulting clock is always less than or equal * to the desired clock, never greater. */ - UCB0BR0 = (unsigned char)((F_CPU / TWI_FREQ) & 0xFF); - UCB0BR1 = (unsigned char)((F_CPU / TWI_FREQ) >> 8); + UCBxBR0 = (unsigned char)((F_CPU / TWI_FREQ) & 0xFF); + UCBxBR1 = (unsigned char)((F_CPU / TWI_FREQ) >> 8); - UCB0CTL1 &= ~(UCSWRST); + UCBxCTL1 &= ~(UCSWRST); #if defined(__MSP430_HAS_USCI__) /* Set I2C state change interrupt mask */ @@ -196,12 +196,11 @@ void twi_init(void) UC0IE |= UCB0RXIE | UCB0TXIE; #else /* Set I2C state change interrupt mask and TX/RX interrupts */ - UCB0IE |= (UCALIE|UCNACKIE|UCSTTIE|UCSTPIE|UCRXIE|UCTXIE); + UCBxIE |= (UCALIE|UCNACKIE|UCSTTIE|UCSTPIE|UCRXIE|UCTXIE); #endif #endif #if defined(__MSP430_HAS_EUSCI_B0__) - P1SEL1 |= BIT6 + BIT7; // Pin init //Disable the USCI module and clears the other bits of control register @@ -275,17 +274,17 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen USICTL0 |= USIMST; #endif #if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) - UCB0CTL1 = UCSWRST; // Enable SW reset - UCB0CTL1 |= (UCSSEL_2); // I2C Master, synchronous mode - UCB0CTL0 |= (UCMST | UCMODE_3 | UCSYNC); // I2C Master, synchronous mode - UCB0CTL1 &= ~(UCTR); // Configure in receive mode + UCBxCTL1 = UCSWRST; // Enable SW reset + UCBxCTL1 |= (UCSSEL_2); // I2C Master, synchronous mode + UCBxCTL0 |= (UCMST | UCMODE_3 | UCSYNC); // I2C Master, synchronous mode + UCBxCTL1 &= ~(UCTR); // Configure in receive mode UCB0I2CSA = address; // Set Slave Address - UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation + UCBxCTL1 &= ~UCSWRST; // Clear SW reset, resume operation #if defined(__MSP430_HAS_USCI__) UCB0I2CIE |= (UCALIE|UCNACKIE|UCSTPIE); // Enable I2C interrupts UC0IE |= (UCB0RXIE | UCB0TXIE); // Enable I2C interrupts #else - UCB0IE |= (UCALIE|UCNACKIE|UCSTPIE|UCRXIE|UCTXIE); // Enable I2C interrupts + UCBxIE |= (UCALIE|UCNACKIE|UCSTPIE|UCRXIE|UCTXIE); // Enable I2C interrupts #endif #endif #if defined(__MSP430_HAS_EUSCI_B0__) @@ -322,11 +321,11 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen #endif #if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) twi_state = TWI_MRX; // Master receive mode - UCB0CTL1 |= UCTXSTT; // I2C start condition + UCBxCTL1 |= UCTXSTT; // I2C start condition if(length == 1) { // When only receiving 1 byte.. - while(UCB0CTL1 & UCTXSTT); // Wait for start bit to be sent - UCB0CTL1 |= UCTXSTP; // Send I2C stop condition after recv + while(UCBxCTL1 & UCTXSTT); // Wait for start bit to be sent + UCBxCTL1 |= UCTXSTP; // Send I2C stop condition after recv } #endif #if defined(__MSP430_HAS_EUSCI_B0__) @@ -349,7 +348,7 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen #if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) /* Ensure stop condition got sent before we exit. */ - while (UCB0CTL1 & UCTXSTP); + while (UCBxCTL1 & UCTXSTP); #endif return length; } @@ -381,17 +380,17 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait USICTL0 |= USIMST; #endif #if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) - UCB0CTL1 = UCSWRST; // Enable SW reset - UCB0CTL1 |= UCSSEL_2; // SMCLK - UCB0CTL0 |= (UCMST | UCMODE_3 | UCSYNC); // I2C Master, synchronous mode - UCB0CTL1 |= UCTR; // Configure in transmit mode + UCBxCTL1 = UCSWRST; // Enable SW reset + UCBxCTL1 |= UCSSEL_2; // SMCLK + UCBxCTL0 |= (UCMST | UCMODE_3 | UCSYNC); // I2C Master, synchronous mode + UCBxCTL1 |= UCTR; // Configure in transmit mode UCB0I2CSA = address; // Set Slave Address - UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation + UCBxCTL1 &= ~UCSWRST; // Clear SW reset, resume operation #if defined(__MSP430_HAS_USCI__) UCB0I2CIE |= (UCALIE|UCNACKIE|UCSTPIE); // Enable I2C interrupts UC0IE |= UCB0TXIE; // Enable I2C interrupts #else - UCB0IE |= (UCALIE|UCNACKIE|UCSTPIE|UCTXIE); // Enable I2C interrupts + UCBxIE |= (UCALIE|UCNACKIE|UCSTPIE|UCTXIE); // Enable I2C interrupts #endif #endif #if defined(__MSP430_HAS_EUSCI_B0__) @@ -431,7 +430,7 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait #endif #if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) twi_state = TWI_MTX; // Master Transmit mode - UCB0CTL1 |= UCTXSTT; // I2C start condition + UCBxCTL1 |= UCTXSTT; // I2C start condition #endif #if defined(__MSP430_HAS_EUSCI_B0__) twi_state = TWI_MTX; // Master Transmit mode @@ -448,11 +447,11 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait /* Ensure stop/start condition got sent before we exit. */ if(sendStop) { - while (UCB0CTL1 & UCTXSTP); // end with stop condition + while (UCBxCTL1 & UCTXSTP); // end with stop condition } else { - while (UCB0CTL1 & UCTXSTT); // end with (re)start condition + while (UCBxCTL1 & UCTXSTT); // end with (re)start condition } #endif @@ -643,20 +642,20 @@ void USI_ISR(void) #if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) void i2c_txrx_isr(void) // RX/TX Service { - /* USCI I2C mode. USCI_B0 receive interrupt flag. - * UCB0RXIFG is set when UCB0RXBUF has received a complete character. */ + /* USCI I2C mode. USCI_Bx receive interrupt flag. + * UCBxRXIFG is set when UCBxRXBUF has received a complete character. */ #if defined(__MSP430_HAS_USCI__) if (UC0IFG & UCB0RXIFG){ #else - if (UCB0IFG & UCRXIFG){ + if (UCBxIFG & UCRXIFG){ #endif /* Master receive mode. */ if (twi_state == TWI_MRX) { - twi_masterBuffer[twi_masterBufferIndex++] = UCB0RXBUF; + twi_masterBuffer[twi_masterBufferIndex++] = UCBxRXBUF; if(twi_masterBufferIndex == twi_masterBufferLength ) /* Only one byte left. Generate STOP condition. * In master mode a STOP is preceded by a NACK */ - UCB0CTL1 |= UCTXSTP; + UCBxCTL1 |= UCTXSTP; if(twi_masterBufferIndex > twi_masterBufferLength ) { /* All bytes received. We are idle*/ __bic_SR_register(LPM0_bits); @@ -667,30 +666,30 @@ void i2c_txrx_isr(void) // RX/TX Service // if there is still room in the rx buffer if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){ // put byte in buffer and ack - twi_rxBuffer[twi_rxBufferIndex++] = UCB0RXBUF; + twi_rxBuffer[twi_rxBufferIndex++] = UCBxRXBUF; }else{ // otherwise nack - UCB0CTL1 |= UCTXNACK; // Generate NACK condition + UCBxCTL1 |= UCTXNACK; // Generate NACK condition } } } - /* USCI I2C mode. USCI_B0 transmit interrupt flag. - * UCB0TXIFG is set when UCB0TXBUF is empty.*/ + /* USCI I2C mode. USCI_Bx transmit interrupt flag. + * UCB0TXIFG is set when UCBxTXBUF is empty.*/ #if defined(__MSP430_HAS_USCI__) if (UC0IFG & UCB0TXIFG){ #else - if (UCB0IFG & UCTXIFG){ + if (UCBxIFG & UCTXIFG){ #endif /* Master transmit mode */ if (twi_state == TWI_MTX) { // if there is data to send, send it, otherwise stop if(twi_masterBufferIndex < twi_masterBufferLength){ // Copy data to output register and ack. - UCB0TXBUF = twi_masterBuffer[twi_masterBufferIndex++]; + UCBxTXBUF = twi_masterBuffer[twi_masterBufferIndex++]; }else{ if (twi_sendStop) { /* All done. Generate STOP condition and IDLE */ - UCB0CTL1 |= UCTXSTP; + UCBxCTL1 |= UCTXSTP; twi_state = TWI_IDLE; __bic_SR_register(LPM0_bits); } else { @@ -698,7 +697,7 @@ void i2c_txrx_isr(void) // RX/TX Service // don't enable the interrupt. We'll generate the start, but we // avoid handling the interrupt until we're in the next transaction, // at the point where we would normally issue the start. - UCB0CTL1 |= UCTXSTT; + UCBxCTL1 |= UCTXSTT; twi_state = TWI_IDLE; __bic_SR_register(LPM0_bits); } @@ -706,11 +705,11 @@ void i2c_txrx_isr(void) // RX/TX Service /* Slave transmit mode (twi_state = TWI_STX) */ } else { // copy data to output register - UCB0TXBUF = twi_txBuffer[twi_txBufferIndex++]; + UCBxTXBUF = twi_txBuffer[twi_txBufferIndex++]; // if there is more to send, ack, otherwise nack if(twi_txBufferIndex < twi_txBufferLength){ }else{ - UCB0CTL1 |= UCTXNACK; // Generate NACK condition + UCBxCTL1 |= UCTXNACK; // Generate NACK condition } } } @@ -720,24 +719,24 @@ void i2c_state_isr(void) // I2C Service { /* Arbitration lost interrupt flag */ #if defined(__MSP430_HAS_USCI__) - if (UCB0STAT & UCALIFG) { - UCB0STAT &= ~UCALIFG; + if (UCBxSTAT & UCALIFG) { + UCBxSTAT &= ~UCALIFG; #else - if (UCB0IFG & UCALIFG) { - UCB0IFG &= ~UCALIFG; + if (UCBxIFG & UCALIFG) { + UCBxIFG &= ~UCALIFG; #endif /* TODO: Handle bus arbitration lost */ } /* Not-acknowledge received interrupt flag. * UCNACKIFG is automatically cleared when a START condition is received.*/ #if defined(__MSP430_HAS_USCI__) - if (UCB0STAT & UCNACKIFG) { - UCB0STAT &= ~UCNACKIFG; + if (UCBxSTAT & UCNACKIFG) { + UCBxSTAT &= ~UCNACKIFG; #else - if (UCB0IFG & UCNACKIFG) { - UCB0IFG &= ~UCNACKIFG; + if (UCBxIFG & UCNACKIFG) { + UCBxIFG &= ~UCNACKIFG; #endif - UCB0CTL1 |= UCTXSTP; + UCBxCTL1 |= UCTXSTP; twi_state = TWI_IDLE; /* TODO: This can just as well be an address NACK. * Figure out a way to distinguish between ANACK and DNACK */ @@ -747,14 +746,14 @@ void i2c_state_isr(void) // I2C Service /* Start condition interrupt flag. * UCSTTIFG is automatically cleared if a STOP condition is received. */ #if defined(__MSP430_HAS_USCI__) - if (UCB0STAT & UCSTTIFG) { - UCB0STAT &= ~UCSTTIFG; + if (UCBxSTAT & UCSTTIFG) { + UCBxSTAT &= ~UCSTTIFG; #else - if (UCB0IFG & UCSTTIFG) { - UCB0IFG &= ~UCSTTIFG; + if (UCBxIFG & UCSTTIFG) { + UCBxIFG &= ~UCSTTIFG; #endif /* UCTR is automagically set by the USCI module upon a START condition. */ - if (UCB0CTL1 & UCTR) { + if (UCBxCTL1 & UCTR) { /* Slave TX mode. */ twi_state = TWI_STX; /* Ready the tx buffer index for iteration. */ @@ -780,11 +779,11 @@ void i2c_state_isr(void) // I2C Service /* Stop condition interrupt flag. * UCSTPIFG is automatically cleared when a START condition is received. */ #if defined(__MSP430_HAS_USCI__) - if (UCB0STAT & UCSTPIFG) { - UCB0STAT &= ~UCSTPIFG; + if (UCBxSTAT & UCSTPIFG) { + UCBxSTAT &= ~UCSTPIFG; #else - if (UCB0IFG & UCSTPIFG) { - UCB0IFG &= ~UCSTPIFG; + if (UCBxIFG & UCSTPIFG) { + UCBxIFG &= ~UCSTPIFG; #endif if (twi_state == TWI_SRX) { /* Callback to user defined callback */ @@ -862,7 +861,7 @@ void USCI_B0_ISR(void) } break; case USCI_I2C_UCSTPIFG: // USCI I2C Mode: UCSTPIFG - UCB0IFG &= ~UCSTPIFG; + UCB0IFG &= ~UCSTPIFG; if (twi_state == TWI_SRX){ // callback to user defined callback twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex); @@ -890,7 +889,7 @@ void USCI_B0_ISR(void) case USCI_I2C_UCTXIFG1: // USCI I2C Mode: UCTXIFG1 break; case USCI_I2C_UCRXIFG0: // USCI I2C Mode: UCRXIFG0 - UCB0IFG &= ~UCRXIFG; // Clear USCI_B0 TX int flag + UCB0IFG &= ~UCRXIFG; // Clear USCI_Bx TX int flag if (twi_state == TWI_MRX) { // Master receive mode twi_masterBuffer[twi_masterBufferIndex++] = UCB0RXBUF; // Get RX data if(twi_masterBufferIndex == twi_masterBufferLength ) @@ -911,7 +910,7 @@ void USCI_B0_ISR(void) } break; case USCI_I2C_UCTXIFG0: // USCI I2C Mode: UCTXIFG0 - UCB0IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag + UCB0IFG &= ~UCTXIFG; // Clear USCI_Bx TX int flag if (twi_state == TWI_MTX) { // Master receive mode // if there is data to send, send it, otherwise stop if(twi_masterBufferIndex < twi_masterBufferLength){ @@ -925,7 +924,7 @@ void USCI_B0_ISR(void) // don't enable the interrupt. We'll generate the start, but we // avoid handling the interrupt until we're in the next transaction, // at the point where we would normally issue the start. - UCB0CTLW0 |= UCTXSTT; + UCB0CTLW0 |= UCTXSTT; twi_state = TWI_IDLE; } } From fbea1ce95ac4ff297e96d675f14440d6dc16f212 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alf=20H=C3=B8gemark?= Date: Fri, 27 Mar 2015 12:19:47 +0100 Subject: [PATCH 05/13] msp430: twi: Add defines for COA and CSA registers --- hardware/msp430/cores/msp430/twi.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/hardware/msp430/cores/msp430/twi.c b/hardware/msp430/cores/msp430/twi.c index d125ee81a3a..bf46aef8856 100644 --- a/hardware/msp430/cores/msp430/twi.c +++ b/hardware/msp430/cores/msp430/twi.c @@ -93,6 +93,8 @@ static uint8_t twi_my_addr; #define UCBxIE UCB0IE #define UCBxIFG UCB0IFG #define UCBxIV UCB0IV +#define UCBxI2COA UCB0I2COA +#define UCBxI2CSA UCB0I2CSA #else #define UCBxCTLW0 UCB1CTLW0 #define UCBxCTL0 UCB1CTL0 @@ -113,6 +115,8 @@ static uint8_t twi_my_addr; #define UCBxIE UCB1IE #define UCBxIFG UCB1IFG #define UCBxIV UCB1IV +#define UCBxI2COA UCB1I2COA +#define UCBxI2CSA UCB1I2CSA #endif #endif @@ -246,7 +250,7 @@ void twi_setAddress(uint8_t address) #endif #if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) /* UCGCEN = respond to general Call */ - UCB0I2COA = (address | UCGCEN); + UCBxI2COA = (address | UCGCEN); #endif #if defined(__MSP430_HAS_EUSCI_B0__) /* UCGCEN = respond to general Call */ @@ -278,7 +282,7 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen UCBxCTL1 |= (UCSSEL_2); // I2C Master, synchronous mode UCBxCTL0 |= (UCMST | UCMODE_3 | UCSYNC); // I2C Master, synchronous mode UCBxCTL1 &= ~(UCTR); // Configure in receive mode - UCB0I2CSA = address; // Set Slave Address + UCBxI2CSA = address; // Set Slave Address UCBxCTL1 &= ~UCSWRST; // Clear SW reset, resume operation #if defined(__MSP430_HAS_USCI__) UCB0I2CIE |= (UCALIE|UCNACKIE|UCSTPIE); // Enable I2C interrupts @@ -384,7 +388,7 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait UCBxCTL1 |= UCSSEL_2; // SMCLK UCBxCTL0 |= (UCMST | UCMODE_3 | UCSYNC); // I2C Master, synchronous mode UCBxCTL1 |= UCTR; // Configure in transmit mode - UCB0I2CSA = address; // Set Slave Address + UCBxI2CSA = address; // Set Slave Address UCBxCTL1 &= ~UCSWRST; // Clear SW reset, resume operation #if defined(__MSP430_HAS_USCI__) UCB0I2CIE |= (UCALIE|UCNACKIE|UCSTPIE); // Enable I2C interrupts @@ -642,11 +646,12 @@ void USI_ISR(void) #if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) void i2c_txrx_isr(void) // RX/TX Service { - /* USCI I2C mode. USCI_Bx receive interrupt flag. - * UCBxRXIFG is set when UCBxRXBUF has received a complete character. */ + /* USCI I2C mode. USCI_Bx receive interrupt flag. */ #if defined(__MSP430_HAS_USCI__) + /* UCB0RXIFG is set when UCBxRXBUF has received a complete character. */ if (UC0IFG & UCB0RXIFG){ #else + /* UCRXIFG is set when UCBxRXBUF has received a complete character. */ if (UCBxIFG & UCRXIFG){ #endif /* Master receive mode. */ @@ -673,11 +678,12 @@ void i2c_txrx_isr(void) // RX/TX Service } } } - /* USCI I2C mode. USCI_Bx transmit interrupt flag. - * UCB0TXIFG is set when UCBxTXBUF is empty.*/ + /* USCI I2C mode. USCI_Bx transmit interrupt flag. */ #if defined(__MSP430_HAS_USCI__) + /* UCB0TXIFG is set when UCBxTXBUF is empty.*/ if (UC0IFG & UCB0TXIFG){ #else + /* UCTXIFG is set when UCBxTXBUF is empty.*/ if (UCBxIFG & UCTXIFG){ #endif /* Master transmit mode */ From c690503c537706dc241bf572eab67ad323b732f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alf=20H=C3=B8gemark?= Date: Fri, 27 Mar 2015 13:50:04 +0100 Subject: [PATCH 06/13] msp430: twi: Add pin and port selection for USCI_B1 --- hardware/msp430/cores/msp430/twi.c | 12 ++++++++++-- .../msp430/variants/launchpad_f5529/pins_energia.h | 7 +++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/hardware/msp430/cores/msp430/twi.c b/hardware/msp430/cores/msp430/twi.c index bf46aef8856..d03988425ea 100644 --- a/hardware/msp430/cores/msp430/twi.c +++ b/hardware/msp430/cores/msp430/twi.c @@ -95,6 +95,10 @@ static uint8_t twi_my_addr; #define UCBxIV UCB0IV #define UCBxI2COA UCB0I2COA #define UCBxI2CSA UCB0I2CSA +#define TWISDAx TWISDA +#define TWISCLx TWISCL +#define TWISDA_SET_MODEx TWISDA_SET_MODE +#define TWISCL_SET_MODEx TWISCL_SET_MODE #else #define UCBxCTLW0 UCB1CTLW0 #define UCBxCTL0 UCB1CTL0 @@ -117,6 +121,10 @@ static uint8_t twi_my_addr; #define UCBxIV UCB1IV #define UCBxI2COA UCB1I2COA #define UCBxI2CSA UCB1I2CSA +#define TWISDAx TWISDA1 +#define TWISCLx TWISCL1 +#define TWISDA_SET_MODEx TWISDA_SET_MODE1 +#define TWISCL_SET_MODEx TWISCL_SET_MODE1 #endif #endif @@ -169,8 +177,8 @@ void twi_init(void) usci_isr_install(); /* Set pins to I2C mode */ - pinMode_int(TWISDA, TWISDA_SET_MODE); - pinMode_int(TWISCL, TWISCL_SET_MODE); + pinMode_int(TWISDAx, TWISDA_SET_MODEx); + pinMode_int(TWISCLx, TWISCL_SET_MODEx); //Disable the USCI module and clears the other bits of control register UCBxCTL1 = UCSWRST; diff --git a/hardware/msp430/variants/launchpad_f5529/pins_energia.h b/hardware/msp430/variants/launchpad_f5529/pins_energia.h index 801a1e5b4fa..203f2c57117 100644 --- a/hardware/msp430/variants/launchpad_f5529/pins_energia.h +++ b/hardware/msp430/variants/launchpad_f5529/pins_energia.h @@ -43,12 +43,19 @@ static const uint8_t MOSI = 15; /* P3.0 */ static const uint8_t MISO = 14; /* P3.1 */ static const uint8_t TWISDA = 15; /* P3.0 */ static const uint8_t TWISCL = 14; /* P3.1 */ +static const uint8_t TWISDA1 = 10; /* P4.1 */ +static const uint8_t TWISCL1 = 9; /* P4.2 */ static const uint8_t DEBUG_UARTRXD = 45; /* Receive Data (RXD) at P4.5 */ static const uint8_t DEBUG_UARTTXD = 46; /* Transmit Data (TXD) at P4.4 */ static const uint8_t AUX_UARTRXD = 3; /* Receive Data (RXD) at P4.5 */ static const uint8_t AUX_UARTTXD = 4; /* Transmit Data (TXD) at P4.4 */ #define TWISDA_SET_MODE (PORT_SELECTION0) #define TWISCL_SET_MODE (PORT_SELECTION0) +#if defined(__MSP430_HAS_USCI_B1__) +/* For USCI_B1 */ +#define TWISDA_SET_MODE1 (PORT_SELECTION0 | (PM_UCB1SDA << 8) | INPUT) +#define TWISCL_SET_MODE1 (PORT_SELECTION0 | (PM_UCB1SCL << 8) | INPUT) +#endif #define DEBUG_UARTRXD_SET_MODE (PORT_SELECTION0 | (PM_UCA1RXD << 8) | INPUT) #define DEBUG_UARTTXD_SET_MODE (PORT_SELECTION0 | (PM_UCA1TXD << 8) | OUTPUT) #define AUX_UARTRXD_SET_MODE (PORT_SELECTION0 | INPUT) From 82e8e838e96a452df0cdfd9f1eaa30c13419c3ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alf=20H=C3=B8gemark?= Date: Fri, 27 Mar 2015 15:01:35 +0100 Subject: [PATCH 07/13] msp430: twi: i2c set pin mode just before enabling module The family guide suggests that pin mode should be set just before enabling the module. --- hardware/msp430/cores/msp430/twi.c | 11 +++++++---- hardware/msp430/cores/msp430/usci_isr_handler.c | 2 ++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/hardware/msp430/cores/msp430/twi.c b/hardware/msp430/cores/msp430/twi.c index d03988425ea..df45dba7f23 100644 --- a/hardware/msp430/cores/msp430/twi.c +++ b/hardware/msp430/cores/msp430/twi.c @@ -29,6 +29,8 @@ #include #include #include "Energia.h" // for digitalWrite + +#define USE_USCI_B1 #if !defined(cbi) #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) @@ -176,10 +178,6 @@ void twi_init(void) * from stripping the USCI interupt vectors.*/ usci_isr_install(); - /* Set pins to I2C mode */ - pinMode_int(TWISDAx, TWISDA_SET_MODEx); - pinMode_int(TWISCLx, TWISCL_SET_MODEx); - //Disable the USCI module and clears the other bits of control register UCBxCTL1 = UCSWRST; @@ -199,6 +197,11 @@ void twi_init(void) UCBxBR0 = (unsigned char)((F_CPU / TWI_FREQ) & 0xFF); UCBxBR1 = (unsigned char)((F_CPU / TWI_FREQ) >> 8); + /* Set pins to I2C mode */ + pinMode_int(TWISDAx, TWISDA_SET_MODEx); + pinMode_int(TWISCLx, TWISCL_SET_MODEx); + + /* Enable the USCI module */ UCBxCTL1 &= ~(UCSWRST); #if defined(__MSP430_HAS_USCI__) diff --git a/hardware/msp430/cores/msp430/usci_isr_handler.c b/hardware/msp430/cores/msp430/usci_isr_handler.c index f081ea8a4ed..481abbd8179 100644 --- a/hardware/msp430/cores/msp430/usci_isr_handler.c +++ b/hardware/msp430/cores/msp430/usci_isr_handler.c @@ -60,6 +60,8 @@ void USCIA1_ISR(void) } #endif +#define USE_USCI_B1 + #if defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) #ifndef USE_USCI_B1 __attribute__((interrupt(USCI_B0_VECTOR))) From 17d90c432a90fcee9516985c79e3fae0b9624302 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alf=20H=C3=B8gemark?= Date: Sat, 28 Mar 2015 10:24:32 +0100 Subject: [PATCH 08/13] msp430: twi: Make code for different module types more readable Each MSP430 have just one type of module, USI, USCI, USCI_Bx, or EUSCI_Bx, so make code more readable by using #if #elif for the code that is different for the different modules. --- hardware/msp430/cores/msp430/twi.c | 62 ++++++++---------------------- 1 file changed, 17 insertions(+), 45 deletions(-) diff --git a/hardware/msp430/cores/msp430/twi.c b/hardware/msp430/cores/msp430/twi.c index df45dba7f23..feb75f838ef 100644 --- a/hardware/msp430/cores/msp430/twi.c +++ b/hardware/msp430/cores/msp430/twi.c @@ -56,6 +56,8 @@ static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH]; static volatile uint8_t twi_masterBufferIndex; static uint8_t twi_masterBufferLength; +static volatile uint8_t twi_error; + static uint8_t twi_txBuffer[TWI_BUFFER_LENGTH]; static volatile uint8_t twi_txBufferIndex; static volatile uint8_t twi_txBufferLength; @@ -63,14 +65,9 @@ static volatile uint8_t twi_txBufferLength; || defined(__MSP430_HAS_USCI_B1__) || defined(__MSP430_HAS_EUSCI_B0__) static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH]; static volatile uint8_t twi_rxBufferIndex; -#endif - -static volatile uint8_t twi_error; - -#if defined(__MSP430_HAS_USI__) +#elif defined(__MSP430_HAS_USI__) static uint8_t twi_slarw; static uint8_t twi_my_addr; - #endif #if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) \ @@ -130,12 +127,6 @@ static uint8_t twi_my_addr; #endif #endif -#if defined(__MSP430_HAS_USCI__) -#endif - -#if defined(__MSP430_HAS_EUSCI_B0__) -#endif - /* * Function twi_init * Desc readys twi pins and sets twi bitrate @@ -150,7 +141,6 @@ void twi_init(void) twi_inRepStart = false; #if defined(__MSP430_HAS_USI__) - /* 100 KHz for all */ #if (F_CPU >= 16000000L) || (F_CPU >= 12000000L) USICKCTL = USIDIV_7; @@ -171,9 +161,7 @@ void twi_init(void) USICTL0 &= ~USISWRST; /* Counter interrupt enable */ USICTL1 |= USIIE; -#endif - -#if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) +#elif defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) /* Calling this dummy function prevents the linker * from stripping the USCI interupt vectors.*/ usci_isr_install(); @@ -213,9 +201,7 @@ void twi_init(void) /* Set I2C state change interrupt mask and TX/RX interrupts */ UCBxIE |= (UCALIE|UCNACKIE|UCSTTIE|UCSTPIE|UCRXIE|UCTXIE); #endif - -#endif -#if defined(__MSP430_HAS_EUSCI_B0__) +#elif defined(__MSP430_HAS_EUSCI_B0__) P1SEL1 |= BIT6 + BIT7; // Pin init //Disable the USCI module and clears the other bits of control register @@ -258,12 +244,10 @@ void twi_setAddress(uint8_t address) { #if defined(__MSP430_HAS_USI__) twi_my_addr = address << 1; -#endif -#if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) +#elif defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) /* UCGCEN = respond to general Call */ UCBxI2COA = (address | UCGCEN); -#endif -#if defined(__MSP430_HAS_EUSCI_B0__) +#elif defined(__MSP430_HAS_EUSCI_B0__) /* UCGCEN = respond to general Call */ UCB0I2COA0 = (address | UCOAEN | UCGCEN); #endif @@ -287,8 +271,7 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen USICTL1 &= ~USISTTIE; /* I2C master mode */ USICTL0 |= USIMST; -#endif -#if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) +#elif defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) UCBxCTL1 = UCSWRST; // Enable SW reset UCBxCTL1 |= (UCSSEL_2); // I2C Master, synchronous mode UCBxCTL0 |= (UCMST | UCMODE_3 | UCSYNC); // I2C Master, synchronous mode @@ -301,8 +284,7 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen #else UCBxIE |= (UCALIE|UCNACKIE|UCSTPIE|UCRXIE|UCTXIE); // Enable I2C interrupts #endif -#endif -#if defined(__MSP430_HAS_EUSCI_B0__) +#elif defined(__MSP430_HAS_EUSCI_B0__) UCB0CTLW0 = UCSWRST; // Enable SW reset UCB0CTLW0 |= (UCMST | UCMODE_3 | UCSYNC | UCSSEL__SMCLK); // I2C Master, synchronous mode UCB0CTLW0 &= ~(UCTR); // Configure in receive mode @@ -333,8 +315,7 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen twi_state = TWI_SND_START; // this will trigger an interrupt kicking off the state machine in the isr USICTL1 |= USIIFG; -#endif -#if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) +#elif defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) twi_state = TWI_MRX; // Master receive mode UCBxCTL1 |= UCTXSTT; // I2C start condition @@ -342,8 +323,7 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen while(UCBxCTL1 & UCTXSTT); // Wait for start bit to be sent UCBxCTL1 |= UCTXSTP; // Send I2C stop condition after recv } -#endif -#if defined(__MSP430_HAS_EUSCI_B0__) +#elif defined(__MSP430_HAS_EUSCI_B0__) twi_state = TWI_MRX; // Master receive mode while (UCB0CTLW0 & UCTXSTP); // Ensure stop condition got sent UCB0CTLW0 |= UCTXSTT; // I2C start condition @@ -393,8 +373,7 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait USICTL1 &= ~USISTTIE; /* I2C master mode */ USICTL0 |= USIMST; -#endif -#if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) +#elif defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) UCBxCTL1 = UCSWRST; // Enable SW reset UCBxCTL1 |= UCSSEL_2; // SMCLK UCBxCTL0 |= (UCMST | UCMODE_3 | UCSYNC); // I2C Master, synchronous mode @@ -407,8 +386,7 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait #else UCBxIE |= (UCALIE|UCNACKIE|UCSTPIE|UCTXIE); // Enable I2C interrupts #endif -#endif -#if defined(__MSP430_HAS_EUSCI_B0__) +#elif defined(__MSP430_HAS_EUSCI_B0__) UCB0CTLW0 = UCSWRST; // Enable SW reset UCB0CTLW0 |= (UCMST | UCMODE_3 | UCSSEL__SMCLK | UCSYNC); // I2C Master, synchronous mode UCB0CTLW0 |= UCTR; // Configure in transmit mode @@ -442,12 +420,10 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait twi_state = TWI_SND_START; /* This will trigger an interrupt kicking off the state machine in the isr */ USICTL1 |= USIIFG; -#endif -#if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) +#elif defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) twi_state = TWI_MTX; // Master Transmit mode UCBxCTL1 |= UCTXSTT; // I2C start condition -#endif -#if defined(__MSP430_HAS_EUSCI_B0__) +#elif defined(__MSP430_HAS_EUSCI_B0__) twi_state = TWI_MTX; // Master Transmit mode while (UCB0CTLW0 & UCTXSTP); // Ensure stop condition got sent UCB0CTLW0 |= UCTXSTT; // I2C start condition @@ -652,9 +628,7 @@ void USI_ISR(void) USICTL1 &= ~USIIFG; } -#endif /* __MSP430_HAS_USI__ */ - -#if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) +#elif defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) void i2c_txrx_isr(void) // RX/TX Service { /* USCI I2C mode. USCI_Bx receive interrupt flag. */ @@ -809,9 +783,7 @@ void i2c_state_isr(void) // I2C Service twi_state = TWI_IDLE; } } -#endif - -#if defined(__MSP430_HAS_EUSCI_B0__) +#elif defined(__MSP430_HAS_EUSCI_B0__) __attribute__((interrupt(USCI_B0_VECTOR))) void USCI_B0_ISR(void) { From 35a869675d156b9859a2f06d9ba2f9ceef9ca6ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alf=20H=C3=B8gemark?= Date: Sun, 29 Mar 2015 10:33:39 +0200 Subject: [PATCH 09/13] msp430: twi: move interrupt handler for USCI_Bx to twi.c --- hardware/msp430/cores/msp430/twi.c | 41 ++++++++++++++++++ .../msp430/cores/msp430/usci_isr_handler.c | 43 ++----------------- 2 files changed, 44 insertions(+), 40 deletions(-) diff --git a/hardware/msp430/cores/msp430/twi.c b/hardware/msp430/cores/msp430/twi.c index feb75f838ef..acb13eab099 100644 --- a/hardware/msp430/cores/msp430/twi.c +++ b/hardware/msp430/cores/msp430/twi.c @@ -45,6 +45,10 @@ #include "twi.h" #include "usci_isr_handler.h" +#if defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) || defined(__MSP430_HAS_EUSCI_B0__) +static boolean still_asleep; // Used to validate whether a user ISR has issued wakeup() inside LPM3/LPM4 sleep modes. +#endif + static volatile uint8_t twi_state; static volatile uint8_t twi_sendStop; // should the transaction end with a stop static volatile uint8_t twi_inRepStart; // in the middle of a repeated start @@ -783,6 +787,43 @@ void i2c_state_isr(void) // I2C Service twi_state = TWI_IDLE; } } + +#if defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) +#ifndef USE_USCI_B1 +__attribute__((interrupt(USCI_B0_VECTOR))) +void USCIB0_ISR(void) +{ + still_asleep = stay_asleep; + + /* USCI_B0 I2C state change interrupt. */ + if ((UCB0CTL0 & UCMODE_3) == UCMODE_3 && (UCB0IFG & (UCALIFG | UCNACKIFG | UCSTTIFG | UCSTPIFG)) != 0) + i2c_state_isr(); + /* USCI_B0 I2C TX RX interrupt. */ + if ((UCB0CTL0 & UCMODE_3) == UCMODE_3 && (UCB0IFG & (UCTXIFG | UCRXIFG)) != 0) + i2c_txrx_isr(); + + if (still_asleep != stay_asleep) + __bic_SR_register_on_exit(LPM4_bits); +} +#else +__attribute__((interrupt(USCI_B1_VECTOR))) +void USCIB1_ISR(void) +{ + still_asleep = stay_asleep; + + /* USCI_B1 I2C state change interrupt. */ + if ((UCB1CTL0 & UCMODE_3) == UCMODE_3 && (UCB1IFG & (UCALIFG | UCNACKIFG | UCSTTIFG | UCSTPIFG)) != 0) + i2c_state_isr(); + /* USCI_B1 I2C TX RX interrupt. */ + if ((UCB1CTL0 & UCMODE_3) == UCMODE_3 && (UCB1IFG & (UCTXIFG | UCRXIFG)) != 0) + i2c_txrx_isr(); + + if (still_asleep != stay_asleep) + __bic_SR_register_on_exit(LPM4_bits); +} +#endif +#endif + #elif defined(__MSP430_HAS_EUSCI_B0__) __attribute__((interrupt(USCI_B0_VECTOR))) void USCI_B0_ISR(void) diff --git a/hardware/msp430/cores/msp430/usci_isr_handler.c b/hardware/msp430/cores/msp430/usci_isr_handler.c index 481abbd8179..e421e069613 100644 --- a/hardware/msp430/cores/msp430/usci_isr_handler.c +++ b/hardware/msp430/cores/msp430/usci_isr_handler.c @@ -1,6 +1,6 @@ #include "Energia.h" #if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_A0__) || defined(__MSP430_HAS_USCI_A1__) \ - || defined(__MSP430_HAS_EUSCI_A0__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) + || defined(__MSP430_HAS_EUSCI_A0__) #include "usci_isr_handler.h" /* This dummy function ensures that, when called from any module that * is interested in having the USCIAB0TX_VECTOR and USCIAB0TX_VECTOR @@ -60,44 +60,6 @@ void USCIA1_ISR(void) } #endif -#define USE_USCI_B1 - -#if defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) -#ifndef USE_USCI_B1 -__attribute__((interrupt(USCI_B0_VECTOR))) -void USCIB0_ISR(void) -{ - still_asleep = stay_asleep; - - /* USCI_B0 I2C state change interrupt. */ - if ((UCB0CTL0 & UCMODE_3) == UCMODE_3 && (UCB0IFG & (UCALIFG | UCNACKIFG | UCSTTIFG | UCSTPIFG)) != 0) - i2c_state_isr(); - /* USCI_B0 I2C TX RX interrupt. */ - if ((UCB0CTL0 & UCMODE_3) == UCMODE_3 && (UCB0IFG & (UCTXIFG | UCRXIFG)) != 0) - i2c_txrx_isr(); - - if (still_asleep != stay_asleep) - __bic_SR_register_on_exit(LPM4_bits); -} -#else -__attribute__((interrupt(USCI_B1_VECTOR))) -void USCIB1_ISR(void) -{ - still_asleep = stay_asleep; - - /* USCI_B1 I2C state change interrupt. */ - if ((UCB1CTL0 & UCMODE_3) == UCMODE_3 && (UCB1IFG & (UCALIFG | UCNACKIFG | UCSTTIFG | UCSTPIFG)) != 0) - i2c_state_isr(); - /* USCI_B1 I2C TX RX interrupt. */ - if ((UCB1CTL0 & UCMODE_3) == UCMODE_3 && (UCB1IFG & (UCTXIFG | UCRXIFG)) != 0) - i2c_txrx_isr(); - - if (still_asleep != stay_asleep) - __bic_SR_register_on_exit(LPM4_bits); -} -#endif -#endif - #endif //defined(__MSP430_HAS_USCI_A0__) || defined(__MSP430_HAS_USCI_A1__) || defined(__MSP430_HAS_EUSCI_A0__) #ifdef __MSP430_HAS_USCI__ @@ -139,10 +101,11 @@ void USCIAB0RX_ISR(void) /* USCI_B0 I2C state change interrupt. */ if ((UCB0STAT & (UCALIFG | UCNACKIFG | UCSTTIFG | UCSTPIFG)) != 0) - i2c_state_isr(); + i2c_state_isr(); if (still_asleep != stay_asleep) __bic_SR_register_on_exit(LPM4_bits); } #endif // __MSP430_HAS_USCI__ #endif // entire file + From d9165f5ec0a0d803932fddef9fa903311fd5d63c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alf=20H=C3=B8gemark?= Date: Sun, 29 Mar 2015 10:37:18 +0200 Subject: [PATCH 10/13] msp430: twi: Enable interrupt handler for USCI_B0 and USCI_B1 if they exist --- hardware/msp430/cores/msp430/twi.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/hardware/msp430/cores/msp430/twi.c b/hardware/msp430/cores/msp430/twi.c index acb13eab099..4774e88f144 100644 --- a/hardware/msp430/cores/msp430/twi.c +++ b/hardware/msp430/cores/msp430/twi.c @@ -630,7 +630,6 @@ void USI_ISR(void) /* Clear counter interrupt */ USICTL1 &= ~USIIFG; - } #elif defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) void i2c_txrx_isr(void) // RX/TX Service @@ -788,8 +787,7 @@ void i2c_state_isr(void) // I2C Service } } -#if defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) -#ifndef USE_USCI_B1 +#if defined(__MSP430_HAS_USCI_B0__) __attribute__((interrupt(USCI_B0_VECTOR))) void USCIB0_ISR(void) { @@ -805,7 +803,9 @@ void USCIB0_ISR(void) if (still_asleep != stay_asleep) __bic_SR_register_on_exit(LPM4_bits); } -#else +#endif + +#if defined(__MSP430_HAS_USCI_B1__) __attribute__((interrupt(USCI_B1_VECTOR))) void USCIB1_ISR(void) { @@ -822,7 +822,6 @@ void USCIB1_ISR(void) __bic_SR_register_on_exit(LPM4_bits); } #endif -#endif #elif defined(__MSP430_HAS_EUSCI_B0__) __attribute__((interrupt(USCI_B0_VECTOR))) From 9fae9e7d85486aaa27bdec89c09979d4f220327f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alf=20H=C3=B8gemark?= Date: Sun, 29 Mar 2015 10:40:57 +0200 Subject: [PATCH 11/13] msp430: twi: remove unused defines --- hardware/msp430/cores/msp430/twi.c | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/hardware/msp430/cores/msp430/twi.c b/hardware/msp430/cores/msp430/twi.c index 4774e88f144..8e97771ba71 100644 --- a/hardware/msp430/cores/msp430/twi.c +++ b/hardware/msp430/cores/msp430/twi.c @@ -77,25 +77,15 @@ static uint8_t twi_my_addr; #if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) \ || defined(__MSP430_HAS_USCI_B1__) #if !defined(USE_USCI_B1) -#define UCBxCTLW0 UCB0CTLW0 #define UCBxCTL0 UCB0CTL0 #define UCBxCTL1 UCB0CTL1 -#define UCBxBRW UCB0BRW #define UCBxBR0 UCB0BR0 #define UCBxBR1 UCB0BR1 -#define UCBxMCTL UCB0MCTL -#define UCBxMCTLW UCB0MCTLW #define UCBxSTAT UCB0STAT #define UCBxRXBUF UCB0RXBUF #define UCBxTXBUF UCB0TXBUF -#define UCBxABCTL UCB0ABCTL -#define UCBxIRCTL UCB0IRCTL -#define UCBxIRTCTL UCB0IRTCTL -#define UCBxIRRCTL UCB0IRRCTL -#define UCBxICTL UCB0ICTL #define UCBxIE UCB0IE #define UCBxIFG UCB0IFG -#define UCBxIV UCB0IV #define UCBxI2COA UCB0I2COA #define UCBxI2CSA UCB0I2CSA #define TWISDAx TWISDA @@ -103,25 +93,15 @@ static uint8_t twi_my_addr; #define TWISDA_SET_MODEx TWISDA_SET_MODE #define TWISCL_SET_MODEx TWISCL_SET_MODE #else -#define UCBxCTLW0 UCB1CTLW0 #define UCBxCTL0 UCB1CTL0 #define UCBxCTL1 UCB1CTL1 -#define UCBxBRW UCB1BRW #define UCBxBR0 UCB1BR0 #define UCBxBR1 UCB1BR1 -#define UCBxMCTL UCB1MCTL -#define UCBxMCTLW UCB1MCTLW #define UCBxSTAT UCB1STAT #define UCBxRXBUF UCB1RXBUF #define UCBxTXBUF UCB1TXBUF -#define UCBxABCTL UCB1ABCTL -#define UCBxIRCTL UCB1IRCTL -#define UCBxIRTCTL UCB1IRTCTL -#define UCBxIRRCTL UCB1IRRCTL -#define UCBxICTL UCB1ICTL #define UCBxIE UCB1IE #define UCBxIFG UCB1IFG -#define UCBxIV UCB1IV #define UCBxI2COA UCB1I2COA #define UCBxI2CSA UCB1I2CSA #define TWISDAx TWISDA1 From a988bc40103b1d7d548a515c8eddf67d1b51de7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alf=20H=C3=B8gemark?= Date: Sun, 29 Mar 2015 13:00:26 +0200 Subject: [PATCH 12/13] msp430: twi/Wire: allow setting of module to use --- hardware/msp430/cores/msp430/Wire.cpp | 8 +- hardware/msp430/cores/msp430/Wire.h | 4 + hardware/msp430/cores/msp430/twi.c | 207 ++++++++++++++------------ hardware/msp430/cores/msp430/twi.h | 2 +- 4 files changed, 120 insertions(+), 101 deletions(-) diff --git a/hardware/msp430/cores/msp430/Wire.cpp b/hardware/msp430/cores/msp430/Wire.cpp index d7d74a67a15..299b1dbd853 100644 --- a/hardware/msp430/cores/msp430/Wire.cpp +++ b/hardware/msp430/cores/msp430/Wire.cpp @@ -51,6 +51,7 @@ uint8_t TwoWire::txBufferLength = 0; uint8_t TwoWire::transmitting = 0; void (*TwoWire::user_onRequest)(void); void (*TwoWire::user_onReceive)(int); +uint8_t TwoWire::i2cModule = 0; // Constructors //////////////////////////////////////////////////////////////// @@ -68,7 +69,7 @@ void TwoWire::begin(void) txBufferIndex = 0; txBufferLength = 0; - twi_init(); + twi_init(i2cModule); } void TwoWire::begin(uint8_t address) @@ -301,6 +302,11 @@ void TwoWire::onRequest( void (*function)(void) ) user_onRequest = function; } +void TwoWire::setModule(unsigned long _i2cModule) +{ + i2cModule = _i2cModule; +} + // Preinstantiate Objects ////////////////////////////////////////////////////// TwoWire Wire = TwoWire(); diff --git a/hardware/msp430/cores/msp430/Wire.h b/hardware/msp430/cores/msp430/Wire.h index 27ed8c92f08..4af1517acb0 100644 --- a/hardware/msp430/cores/msp430/Wire.h +++ b/hardware/msp430/cores/msp430/Wire.h @@ -53,6 +53,8 @@ class TwoWire : public Stream static void (*user_onReceive)(int); static void onRequestService(void); static void onReceiveService(uint8_t*, int); + + static uint8_t i2cModule; public: TwoWire(); void begin(); @@ -86,6 +88,8 @@ class TwoWire : public Stream inline size_t write(unsigned int n) { return write((uint8_t)n); } inline size_t write(int n) { return write((uint8_t)n); } using Print::write; + + void setModule(unsigned long); }; extern TwoWire Wire; diff --git a/hardware/msp430/cores/msp430/twi.c b/hardware/msp430/cores/msp430/twi.c index 8e97771ba71..497d5e336af 100644 --- a/hardware/msp430/cores/msp430/twi.c +++ b/hardware/msp430/cores/msp430/twi.c @@ -30,8 +30,6 @@ #include #include "Energia.h" // for digitalWrite -#define USE_USCI_B1 - #if !defined(cbi) #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #endif @@ -74,41 +72,19 @@ static uint8_t twi_slarw; static uint8_t twi_my_addr; #endif -#if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) \ - || defined(__MSP430_HAS_USCI_B1__) -#if !defined(USE_USCI_B1) -#define UCBxCTL0 UCB0CTL0 -#define UCBxCTL1 UCB0CTL1 -#define UCBxBR0 UCB0BR0 -#define UCBxBR1 UCB0BR1 -#define UCBxSTAT UCB0STAT -#define UCBxRXBUF UCB0RXBUF -#define UCBxTXBUF UCB0TXBUF -#define UCBxIE UCB0IE -#define UCBxIFG UCB0IFG -#define UCBxI2COA UCB0I2COA -#define UCBxI2CSA UCB0I2CSA -#define TWISDAx TWISDA -#define TWISCLx TWISCL -#define TWISDA_SET_MODEx TWISDA_SET_MODE -#define TWISCL_SET_MODEx TWISCL_SET_MODE -#else -#define UCBxCTL0 UCB1CTL0 -#define UCBxCTL1 UCB1CTL1 -#define UCBxBR0 UCB1BR0 -#define UCBxBR1 UCB1BR1 -#define UCBxSTAT UCB1STAT -#define UCBxRXBUF UCB1RXBUF -#define UCBxTXBUF UCB1TXBUF -#define UCBxIE UCB1IE -#define UCBxIFG UCB1IFG -#define UCBxI2COA UCB1I2COA -#define UCBxI2CSA UCB1I2CSA -#define TWISDAx TWISDA1 -#define TWISCLx TWISCL1 -#define TWISDA_SET_MODEx TWISDA_SET_MODE1 -#define TWISCL_SET_MODEx TWISCL_SET_MODE1 -#endif +#if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) + volatile unsigned char* UCBxCTL0; + volatile unsigned char* UCBxCTL1; + volatile unsigned char* UCBxBR0; + volatile unsigned char* UCBxBR1; + volatile unsigned char* UCBxSTAT; + const volatile unsigned char* UCBxRXBUF; + volatile unsigned char* UCBxTXBUF; + volatile unsigned char* UCBxIE; + volatile unsigned char* UCBxIFG; + volatile unsigned int* UCBxIV; + volatile unsigned int* UCBxI2COA; + volatile unsigned int* UCBxI2CSA; #endif /* @@ -117,7 +93,7 @@ static uint8_t twi_my_addr; * Input none * Output none */ -void twi_init(void) +void twi_init(uint8_t module) { // initialize state twi_state = TWI_IDLE; @@ -150,8 +126,36 @@ void twi_init(void) * from stripping the USCI interupt vectors.*/ usci_isr_install(); + /* Set pointers to correct USCI registers based on which module is being used */ + UCBxCTL0 = &UCB0CTL0; + UCBxCTL1 = &UCB0CTL1; + UCBxBR0 = &UCB0BR0; + UCBxBR1 = &UCB0BR1; + UCBxSTAT = &UCB0STAT; + UCBxRXBUF = &UCB0RXBUF; + UCBxTXBUF = &UCB0TXBUF; + UCBxIE = &UCB0IE; + UCBxIFG = &UCB0IFG; + UCBxI2COA = &UCB0I2COA; + UCBxI2CSA = &UCB0I2CSA; +#if defined(__MSP430_HAS_USCI_B1__) + if(module == 1) { + UCBxCTL0 = &UCB1CTL0; + UCBxCTL1 = &UCB1CTL1; + UCBxBR0 = &UCB1BR0; + UCBxBR1 = &UCB1BR1; + UCBxSTAT = &UCB1STAT; + UCBxRXBUF = &UCB1RXBUF; + UCBxTXBUF = &UCB1TXBUF; + UCBxIE = &UCB1IE; + UCBxIFG = &UCB1IFG; + UCBxI2COA = &UCB1I2COA; + UCBxI2CSA = &UCB1I2CSA; + } +#endif + //Disable the USCI module and clears the other bits of control register - UCBxCTL1 = UCSWRST; + *UCBxCTL1 = UCSWRST; /* * Configure as I2C Slave. @@ -159,22 +163,27 @@ void twi_init(void) * UCSYNC = Synchronous mode * UCCLK = SMCLK */ - UCBxCTL0 = UCMODE_3 | UCSYNC; + *UCBxCTL0 = UCMODE_3 | UCSYNC; /* * Compute the clock divider that achieves less than or * equal to 100kHz. The numerator is biased to favor a larger * clock divider so that the resulting clock is always less than or equal * to the desired clock, never greater. */ - UCBxBR0 = (unsigned char)((F_CPU / TWI_FREQ) & 0xFF); - UCBxBR1 = (unsigned char)((F_CPU / TWI_FREQ) >> 8); + *UCBxBR0 = (unsigned char)((F_CPU / TWI_FREQ) & 0xFF); + *UCBxBR1 = (unsigned char)((F_CPU / TWI_FREQ) >> 8); /* Set pins to I2C mode */ - pinMode_int(TWISDAx, TWISDA_SET_MODEx); - pinMode_int(TWISCLx, TWISCL_SET_MODEx); + if(module == 1) { + pinMode_int(TWISDA1, TWISDA_SET_MODE1); + pinMode_int(TWISCL1, TWISCL_SET_MODE1); + } else { + pinMode_int(TWISDA, TWISDA_SET_MODE); + pinMode_int(TWISCL, TWISCL_SET_MODE); + } /* Enable the USCI module */ - UCBxCTL1 &= ~(UCSWRST); + *UCBxCTL1 &= ~(UCSWRST); #if defined(__MSP430_HAS_USCI__) /* Set I2C state change interrupt mask */ @@ -183,7 +192,7 @@ void twi_init(void) UC0IE |= UCB0RXIE | UCB0TXIE; #else /* Set I2C state change interrupt mask and TX/RX interrupts */ - UCBxIE |= (UCALIE|UCNACKIE|UCSTTIE|UCSTPIE|UCRXIE|UCTXIE); + *UCBxIE |= (UCALIE|UCNACKIE|UCSTTIE|UCSTPIE|UCRXIE|UCTXIE); #endif #elif defined(__MSP430_HAS_EUSCI_B0__) P1SEL1 |= BIT6 + BIT7; // Pin init @@ -230,7 +239,7 @@ void twi_setAddress(uint8_t address) twi_my_addr = address << 1; #elif defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) /* UCGCEN = respond to general Call */ - UCBxI2COA = (address | UCGCEN); + *UCBxI2COA = (address | UCGCEN); #elif defined(__MSP430_HAS_EUSCI_B0__) /* UCGCEN = respond to general Call */ UCB0I2COA0 = (address | UCOAEN | UCGCEN); @@ -256,17 +265,17 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen /* I2C master mode */ USICTL0 |= USIMST; #elif defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) - UCBxCTL1 = UCSWRST; // Enable SW reset - UCBxCTL1 |= (UCSSEL_2); // I2C Master, synchronous mode - UCBxCTL0 |= (UCMST | UCMODE_3 | UCSYNC); // I2C Master, synchronous mode - UCBxCTL1 &= ~(UCTR); // Configure in receive mode - UCBxI2CSA = address; // Set Slave Address - UCBxCTL1 &= ~UCSWRST; // Clear SW reset, resume operation + *UCBxCTL1 = UCSWRST; // Enable SW reset + *UCBxCTL1 |= (UCSSEL_2); // I2C Master, synchronous mode + *UCBxCTL0 |= (UCMST | UCMODE_3 | UCSYNC); // I2C Master, synchronous mode + *UCBxCTL1 &= ~(UCTR); // Configure in receive mode + *UCBxI2CSA = address; // Set Slave Address + *UCBxCTL1 &= ~UCSWRST; // Clear SW reset, resume operation #if defined(__MSP430_HAS_USCI__) UCB0I2CIE |= (UCALIE|UCNACKIE|UCSTPIE); // Enable I2C interrupts UC0IE |= (UCB0RXIE | UCB0TXIE); // Enable I2C interrupts #else - UCBxIE |= (UCALIE|UCNACKIE|UCSTPIE|UCRXIE|UCTXIE); // Enable I2C interrupts + *UCBxIE |= (UCALIE|UCNACKIE|UCSTPIE|UCRXIE|UCTXIE); // Enable I2C interrupts #endif #elif defined(__MSP430_HAS_EUSCI_B0__) UCB0CTLW0 = UCSWRST; // Enable SW reset @@ -301,11 +310,11 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen USICTL1 |= USIIFG; #elif defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) twi_state = TWI_MRX; // Master receive mode - UCBxCTL1 |= UCTXSTT; // I2C start condition + *UCBxCTL1 |= UCTXSTT; // I2C start condition if(length == 1) { // When only receiving 1 byte.. - while(UCBxCTL1 & UCTXSTT); // Wait for start bit to be sent - UCBxCTL1 |= UCTXSTP; // Send I2C stop condition after recv + while(*UCBxCTL1 & UCTXSTT); // Wait for start bit to be sent + *UCBxCTL1 |= UCTXSTP; // Send I2C stop condition after recv } #elif defined(__MSP430_HAS_EUSCI_B0__) twi_state = TWI_MRX; // Master receive mode @@ -327,7 +336,7 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen #if defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) /* Ensure stop condition got sent before we exit. */ - while (UCBxCTL1 & UCTXSTP); + while (*UCBxCTL1 & UCTXSTP); #endif return length; } @@ -358,17 +367,17 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait /* I2C master mode */ USICTL0 |= USIMST; #elif defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) - UCBxCTL1 = UCSWRST; // Enable SW reset - UCBxCTL1 |= UCSSEL_2; // SMCLK - UCBxCTL0 |= (UCMST | UCMODE_3 | UCSYNC); // I2C Master, synchronous mode - UCBxCTL1 |= UCTR; // Configure in transmit mode - UCBxI2CSA = address; // Set Slave Address - UCBxCTL1 &= ~UCSWRST; // Clear SW reset, resume operation + *UCBxCTL1 = UCSWRST; // Enable SW reset + *UCBxCTL1 |= UCSSEL_2; // SMCLK + *UCBxCTL0 |= (UCMST | UCMODE_3 | UCSYNC); // I2C Master, synchronous mode + *UCBxCTL1 |= UCTR; // Configure in transmit mode + *UCBxI2CSA = address; // Set Slave Address + *UCBxCTL1 &= ~UCSWRST; // Clear SW reset, resume operation #if defined(__MSP430_HAS_USCI__) UCB0I2CIE |= (UCALIE|UCNACKIE|UCSTPIE); // Enable I2C interrupts UC0IE |= UCB0TXIE; // Enable I2C interrupts #else - UCBxIE |= (UCALIE|UCNACKIE|UCSTPIE|UCTXIE); // Enable I2C interrupts + *UCBxIE |= (UCALIE|UCNACKIE|UCSTPIE|UCTXIE); // Enable I2C interrupts #endif #elif defined(__MSP430_HAS_EUSCI_B0__) UCB0CTLW0 = UCSWRST; // Enable SW reset @@ -406,7 +415,7 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait USICTL1 |= USIIFG; #elif defined(__MSP430_HAS_USCI__) || defined(__MSP430_HAS_USCI_B0__) || defined(__MSP430_HAS_USCI_B1__) twi_state = TWI_MTX; // Master Transmit mode - UCBxCTL1 |= UCTXSTT; // I2C start condition + *UCBxCTL1 |= UCTXSTT; // I2C start condition #elif defined(__MSP430_HAS_EUSCI_B0__) twi_state = TWI_MTX; // Master Transmit mode while (UCB0CTLW0 & UCTXSTP); // Ensure stop condition got sent @@ -422,11 +431,11 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait /* Ensure stop/start condition got sent before we exit. */ if(sendStop) { - while (UCBxCTL1 & UCTXSTP); // end with stop condition + while (*UCBxCTL1 & UCTXSTP); // end with stop condition } else { - while (UCBxCTL1 & UCTXSTT); // end with (re)start condition + while (*UCBxCTL1 & UCTXSTT); // end with (re)start condition } #endif @@ -616,19 +625,19 @@ void i2c_txrx_isr(void) // RX/TX Service { /* USCI I2C mode. USCI_Bx receive interrupt flag. */ #if defined(__MSP430_HAS_USCI__) - /* UCB0RXIFG is set when UCBxRXBUF has received a complete character. */ + /* UCB0RXIFG is set when UCB0RXBUF has received a complete character. */ if (UC0IFG & UCB0RXIFG){ #else /* UCRXIFG is set when UCBxRXBUF has received a complete character. */ - if (UCBxIFG & UCRXIFG){ + if (*UCBxIFG & UCRXIFG){ #endif /* Master receive mode. */ if (twi_state == TWI_MRX) { - twi_masterBuffer[twi_masterBufferIndex++] = UCBxRXBUF; + twi_masterBuffer[twi_masterBufferIndex++] = *UCBxRXBUF; if(twi_masterBufferIndex == twi_masterBufferLength ) /* Only one byte left. Generate STOP condition. * In master mode a STOP is preceded by a NACK */ - UCBxCTL1 |= UCTXSTP; + *UCBxCTL1 |= UCTXSTP; if(twi_masterBufferIndex > twi_masterBufferLength ) { /* All bytes received. We are idle*/ __bic_SR_register(LPM0_bits); @@ -639,31 +648,31 @@ void i2c_txrx_isr(void) // RX/TX Service // if there is still room in the rx buffer if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){ // put byte in buffer and ack - twi_rxBuffer[twi_rxBufferIndex++] = UCBxRXBUF; + twi_rxBuffer[twi_rxBufferIndex++] = *UCBxRXBUF; }else{ // otherwise nack - UCBxCTL1 |= UCTXNACK; // Generate NACK condition + *UCBxCTL1 |= UCTXNACK; // Generate NACK condition } } } /* USCI I2C mode. USCI_Bx transmit interrupt flag. */ #if defined(__MSP430_HAS_USCI__) - /* UCB0TXIFG is set when UCBxTXBUF is empty.*/ + /* UCB0TXIFG is set when UCB0TXBUF is empty.*/ if (UC0IFG & UCB0TXIFG){ #else /* UCTXIFG is set when UCBxTXBUF is empty.*/ - if (UCBxIFG & UCTXIFG){ + if (*UCBxIFG & UCTXIFG){ #endif /* Master transmit mode */ if (twi_state == TWI_MTX) { // if there is data to send, send it, otherwise stop if(twi_masterBufferIndex < twi_masterBufferLength){ // Copy data to output register and ack. - UCBxTXBUF = twi_masterBuffer[twi_masterBufferIndex++]; + *UCBxTXBUF = twi_masterBuffer[twi_masterBufferIndex++]; }else{ if (twi_sendStop) { /* All done. Generate STOP condition and IDLE */ - UCBxCTL1 |= UCTXSTP; + *UCBxCTL1 |= UCTXSTP; twi_state = TWI_IDLE; __bic_SR_register(LPM0_bits); } else { @@ -671,7 +680,7 @@ void i2c_txrx_isr(void) // RX/TX Service // don't enable the interrupt. We'll generate the start, but we // avoid handling the interrupt until we're in the next transaction, // at the point where we would normally issue the start. - UCBxCTL1 |= UCTXSTT; + *UCBxCTL1 |= UCTXSTT; twi_state = TWI_IDLE; __bic_SR_register(LPM0_bits); } @@ -679,11 +688,11 @@ void i2c_txrx_isr(void) // RX/TX Service /* Slave transmit mode (twi_state = TWI_STX) */ } else { // copy data to output register - UCBxTXBUF = twi_txBuffer[twi_txBufferIndex++]; + *UCBxTXBUF = twi_txBuffer[twi_txBufferIndex++]; // if there is more to send, ack, otherwise nack if(twi_txBufferIndex < twi_txBufferLength){ }else{ - UCBxCTL1 |= UCTXNACK; // Generate NACK condition + *UCBxCTL1 |= UCTXNACK; // Generate NACK condition } } } @@ -693,24 +702,24 @@ void i2c_state_isr(void) // I2C Service { /* Arbitration lost interrupt flag */ #if defined(__MSP430_HAS_USCI__) - if (UCBxSTAT & UCALIFG) { - UCBxSTAT &= ~UCALIFG; + if (*UCBxSTAT & UCALIFG) { + *UCBxSTAT &= ~UCALIFG; #else - if (UCBxIFG & UCALIFG) { - UCBxIFG &= ~UCALIFG; + if (*UCBxIFG & UCALIFG) { + *UCBxIFG &= ~UCALIFG; #endif /* TODO: Handle bus arbitration lost */ } /* Not-acknowledge received interrupt flag. * UCNACKIFG is automatically cleared when a START condition is received.*/ #if defined(__MSP430_HAS_USCI__) - if (UCBxSTAT & UCNACKIFG) { - UCBxSTAT &= ~UCNACKIFG; + if (*UCBxSTAT & UCNACKIFG) { + *UCBxSTAT &= ~UCNACKIFG; #else - if (UCBxIFG & UCNACKIFG) { - UCBxIFG &= ~UCNACKIFG; + if (*UCBxIFG & UCNACKIFG) { + *UCBxIFG &= ~UCNACKIFG; #endif - UCBxCTL1 |= UCTXSTP; + *UCBxCTL1 |= UCTXSTP; twi_state = TWI_IDLE; /* TODO: This can just as well be an address NACK. * Figure out a way to distinguish between ANACK and DNACK */ @@ -720,14 +729,14 @@ void i2c_state_isr(void) // I2C Service /* Start condition interrupt flag. * UCSTTIFG is automatically cleared if a STOP condition is received. */ #if defined(__MSP430_HAS_USCI__) - if (UCBxSTAT & UCSTTIFG) { - UCBxSTAT &= ~UCSTTIFG; + if (*UCBxSTAT & UCSTTIFG) { + *UCBxSTAT &= ~UCSTTIFG; #else - if (UCBxIFG & UCSTTIFG) { - UCBxIFG &= ~UCSTTIFG; + if (*UCBxIFG & UCSTTIFG) { + *UCBxIFG &= ~UCSTTIFG; #endif /* UCTR is automagically set by the USCI module upon a START condition. */ - if (UCBxCTL1 & UCTR) { + if (*UCBxCTL1 & UCTR) { /* Slave TX mode. */ twi_state = TWI_STX; /* Ready the tx buffer index for iteration. */ @@ -753,11 +762,11 @@ void i2c_state_isr(void) // I2C Service /* Stop condition interrupt flag. * UCSTPIFG is automatically cleared when a START condition is received. */ #if defined(__MSP430_HAS_USCI__) - if (UCBxSTAT & UCSTPIFG) { - UCBxSTAT &= ~UCSTPIFG; + if (*UCBxSTAT & UCSTPIFG) { + *UCBxSTAT &= ~UCSTPIFG; #else - if (UCBxIFG & UCSTPIFG) { - UCBxIFG &= ~UCSTPIFG; + if (*UCBxIFG & UCSTPIFG) { + *UCBxIFG &= ~UCSTPIFG; #endif if (twi_state == TWI_SRX) { /* Callback to user defined callback */ diff --git a/hardware/msp430/cores/msp430/twi.h b/hardware/msp430/cores/msp430/twi.h index 5216f5b0164..b3d769a211e 100644 --- a/hardware/msp430/cores/msp430/twi.h +++ b/hardware/msp430/cores/msp430/twi.h @@ -89,7 +89,7 @@ -void twi_init(void); +void twi_init(uint8_t module); void twi_setAddress(uint8_t); uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t, uint8_t); uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t, uint8_t); From f1d6a1f890276d5ebc8e38ded34523f7dd9982ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alf=20H=C3=B8gemark?= Date: Mon, 30 Mar 2015 10:09:19 +0200 Subject: [PATCH 13/13] msp430: twi: fix datatype for paramter to setModule --- hardware/msp430/cores/msp430/Wire.cpp | 2 +- hardware/msp430/cores/msp430/Wire.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hardware/msp430/cores/msp430/Wire.cpp b/hardware/msp430/cores/msp430/Wire.cpp index 299b1dbd853..b8cb2b26ac2 100644 --- a/hardware/msp430/cores/msp430/Wire.cpp +++ b/hardware/msp430/cores/msp430/Wire.cpp @@ -302,7 +302,7 @@ void TwoWire::onRequest( void (*function)(void) ) user_onRequest = function; } -void TwoWire::setModule(unsigned long _i2cModule) +void TwoWire::setModule(uint8_t _i2cModule) { i2cModule = _i2cModule; } diff --git a/hardware/msp430/cores/msp430/Wire.h b/hardware/msp430/cores/msp430/Wire.h index 4af1517acb0..924e634e47d 100644 --- a/hardware/msp430/cores/msp430/Wire.h +++ b/hardware/msp430/cores/msp430/Wire.h @@ -89,7 +89,7 @@ class TwoWire : public Stream inline size_t write(int n) { return write((uint8_t)n); } using Print::write; - void setModule(unsigned long); + void setModule(uint8_t module); }; extern TwoWire Wire;