1 | #include <msp430.h>
|
2 | #include "init.h"
|
3 |
|
4 | unsigned char *pTXData = 0x0; // Pointer to TX data
|
5 | unsigned char TXByteCounter = 0;
|
6 | unsigned char *pRXData = 0x0; // Pointer to RX data
|
7 | unsigned char RXByteCounter = 0;
|
8 | volatile unsigned int TEMP = 0;
|
9 | volatile float celsius = 0;
|
10 |
|
11 | void receive();
|
12 | void transmit();
|
13 | void i2c_master_receiver();
|
14 | void i2c_master_transmitter()
|
15 |
|
16 | int main(void)
|
17 | {
|
18 | msp430fr5729_ports();
|
19 | msp430fr5729_clock();
|
20 |
|
21 | //Transmit
|
22 | i2c_master_transmitter();
|
23 | __enable_interrupt();
|
24 | transmit();
|
25 |
|
26 | //Receive
|
27 | __disable_interrupt();
|
28 | i2c_master_receiver();
|
29 | __enable_interrupt();
|
30 |
|
31 |
|
32 |
|
33 | while(1)
|
34 | {
|
35 | receive();
|
36 | }
|
37 |
|
38 | }
|
39 |
|
40 |
|
41 | //===================================================================================//
|
42 | // ISR2: USCIB0_ISR
|
43 | //===================================================================================//
|
44 | #pragma vector = USCI_B0_VECTOR
|
45 | __interrupt void USCIB0_ISR(void)
|
46 | {
|
47 | switch(__even_in_range(UCB0IV,12))
|
48 | {
|
49 | case 0x04:
|
50 | UCB0CTLW0 |= UCTXSTT; // Resend start if NACK
|
51 | break; // Vector 4: NACKIFG break;
|
52 | case 0x16:
|
53 | RXByteCounter--; // Decrement RX byte counter
|
54 |
|
55 | if (RXByteCounter)
|
56 | {
|
57 | *pRXData++= UCB0RXBUF; // Multiple bytes left to receive
|
58 | }
|
59 | else
|
60 | {
|
61 | *pRXData= UCB0RXBUF; // Last byte to be received
|
62 | __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
|
63 | RXFlag = FLAG_SUCCESS; // Set Data Received RX Flag to success
|
64 | }
|
65 |
|
66 | if(RXByteCounter == 1) // Only one byte left?
|
67 | UCB0CTL1 |= UCTXSTP; // Generate I2C stop condition
|
68 | // If reading only 1 byte, stop condition
|
69 | // should have already been sent
|
70 | // Receive and calculate temperature
|
71 | slave_temperature = i2c_Data_From_Slave[1] << 8 | i2c_Data_From_Slave[0];
|
72 | celsius = ((slave_temperature-2730)/10);
|
73 | break; // Vector 24: RXIFG0 break;
|
74 |
|
75 | case 0x18:
|
76 | if (TXByteCounter) // If there's something to transmit
|
77 | {
|
78 | UCB0TXBUF = 0x08;*pTXData++; // Load TX buffer
|
79 | TXByteCounter--; // Decrement TX byte counter
|
80 | TXFlag = FLAG_SUCCESS;
|
81 | }
|
82 | else
|
83 | {
|
84 | UCB0CTL1 |= UCTXSTP; // I2C stop condition
|
85 | UCB0IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag
|
86 | __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
|
87 | TXFlag = FLAG_SUCCESS;
|
88 | }
|
89 |
|
90 | break; // Vector 26: TXIFG0 break;
|
91 | default: break;
|
92 | }
|
93 | }
|
94 |
|
95 |
|
96 | //===================================================================================//
|
97 | // FUNCTION: i2c_MASTER_TRANSMITTER
|
98 | //===================================================================================//
|
99 | void i2c_master_transmitter()
|
100 | {
|
101 | UCB0CTL1 |= UCSWRST; // Enable SW reset
|
102 | UCB0CTLW0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
|
103 | UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
|
104 | UCB0BR0 = 0; // fSCL = SMCLK/256 ~ 100kHz
|
105 | UCB0BR1 = 1; // Buad Rate Prescalar = UCB1BR1 * 256 + UCB1BR0
|
106 | UCB0I2CSA = i2c_BATTERY_ADDRESS; // Assign Slave Address
|
107 | UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
|
108 | UCB0IE |= UCTXIE + UCRXIE + UCNACKIE; // Enable TX, RX, NACK interrupt
|
109 | }
|
110 |
|
111 | //===================================================================================//
|
112 | // FUNCTION: TRANSMIT
|
113 | //===================================================================================//
|
114 | void transmit()
|
115 | {
|
116 | __delay_cycles(1000); // Delay between transmissions
|
117 | TXByteCounter = 1; // Load TX byte counter
|
118 | while (UCB0CTLW0 & UCTXSTP); // Ensure stop condition got sent
|
119 | UCB0CTLW0 |= UCTR + UCTXSTT; // I2C TX, start condition
|
120 |
|
121 | __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
|
122 | }
|
123 |
|
124 |
|
125 | //===================================================================================//
|
126 | // FUNCTION: i2c_MASTER_TRANSMITTER
|
127 | //===================================================================================//
|
128 | void i2c_master_receiver()
|
129 | {
|
130 | UCB0CTLW0 |= UCSWRST; // Software reset enabled
|
131 | UCB0CTLW0 |= UCMODE_3 + UCMST + UCSYNC; // I2C mode, Master mode, sync
|
132 | UCB0CTLW1 |= UCASTP_2; // Automatic stop generated
|
133 | // After UCB0TBCNT is reached
|
134 | UCB0BR0 = 0; // fSCL = SMCLK/256 ~ 100kHz
|
135 | UCB0BR1 = 1; // Buad Rate Prescalar = UCB1BR1 * 256 + UCB1BR0
|
136 | UCB0I2CSA = i2c_BATTERY_ADDRESS; // Slave address
|
137 | UCB0CTL1 &=~UCSWRST;
|
138 | UCB0IE |= UCRXIE+UCNACKIE+UCBCNTIE;
|
139 | }
|
140 |
|
141 |
|
142 | //===================================================================================//
|
143 | // FUNCTION: RECEIVE
|
144 | //===================================================================================//
|
145 | void receive()
|
146 | {
|
147 | __delay_cycles(2000);
|
148 | pRXData = (unsigned char *) i2c_Data_From_Slave;
|
149 | RXByteCounter = 2; // Load RX byte counter
|
150 | while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent
|
151 | UCB0CTL1 |= UCTXSTT; // I2C start condition
|
152 |
|
153 | __bis_SR_register(CPUOFF+GIE); // Enter LPM0 w/ interrupt
|
154 | }
|