1 | #include <msp430.h>
|
2 |
|
3 | #define NUM_BYTES_TX 1 // How many bytes?
|
4 | #define NUM_BYTES_RX 2
|
5 |
|
6 | int RXByteCtr, RPT_Flag = 0; // enables repeated start when 1
|
7 | volatile unsigned char RxBuffer[128]; // Allocate 128 byte of RAM
|
8 | unsigned char *PTxData; // Pointer to TX data
|
9 | unsigned char *PRxData; // Pointer to RX data
|
10 | unsigned char TXByteCtr, RX = 0, UX = 0;
|
11 | unsigned char MSData = 0x00;
|
12 |
|
13 | void setupUART(void);
|
14 | void Setup_TX(void);
|
15 | void Setup_RX(void);
|
16 | void Transmit(void);
|
17 | void Receive(void);
|
18 |
|
19 | int main(void)
|
20 | {
|
21 | WDTCTL = WDTPW + WDTHOLD; // Stop WDT
|
22 | P1SEL |= BIT6 + BIT7; // Assign I2C pins to USCI_B0
|
23 | P1SEL2|= BIT6 + BIT7; // Assign I2C pins to USCI_B0
|
24 |
|
25 | while(1){
|
26 |
|
27 | setupUART();
|
28 | UX = 0;
|
29 | RX = 0;
|
30 | //Transmit process
|
31 | Setup_TX();
|
32 | RPT_Flag = 1;
|
33 | Transmit();
|
34 | while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent
|
35 |
|
36 | //Receive process
|
37 | Setup_RX();
|
38 | Receive();
|
39 | while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent
|
40 | }
|
41 | }
|
42 |
|
43 | //---------------------------------------------------------------------------------------
|
44 |
|
45 | #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
|
46 | #pragma vector = USCIAB0RX_VECTOR
|
47 | __interrupt void USCIAB0RX_ISR(void)
|
48 | #elif defined(__GNUC__)
|
49 | void __attribute__ ((interrupt(USCIAB0TX_VECTOR))) USCIAB0TX_ISR (void)
|
50 | #else
|
51 | #error Compiler not supported!
|
52 | #endif
|
53 | {
|
54 | if((UX==1) && (RX == 1) && (UCA0RXBUF == 'u'))
|
55 | {
|
56 | UX=0;
|
57 | IE2 &= ~UCA0RXIE;
|
58 | //IFG2 &=~(UCA0TXIFG + UCA0RXIFG);
|
59 | IFG2 &=~(UCA0TXIFG);
|
60 | __bic_SR_register_on_exit(CPUOFF);
|
61 | }
|
62 | }
|
63 |
|
64 | //-------------------------------------------------------------------------------
|
65 | // The USCI_B0 data ISR is used to move received data from the I2C slave
|
66 | // to the MSP430 memory. It is structured such that it can be used to receive
|
67 | // any 2+ number of bytes by pre-loading RXByteCtr with the byte count.
|
68 | //-------------------------------------------------------------------------------
|
69 | #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
|
70 | #pragma vector = USCIAB0TX_VECTOR
|
71 | __interrupt void USCIAB0TX_ISR(void)
|
72 | #elif defined(__GNUC__)
|
73 | void __attribute__ ((interrupt(USCIAB0TX_VECTOR))) USCIAB0TX_ISR (void)
|
74 | #else
|
75 | #error Compiler not supported!
|
76 | #endif
|
77 | {
|
78 | if(RX == 1){ // Master Recieve?
|
79 | RXByteCtr--; // Decrement RX byte counter
|
80 | if (RXByteCtr)
|
81 | {
|
82 | *PRxData++ = UCB0RXBUF; // Move RX data to address PRxData
|
83 | UCA0TXBUF = RxBuffer[0];
|
84 | }
|
85 | else
|
86 | {
|
87 | if(RPT_Flag == 0)
|
88 | UCB0CTL1 |= UCTXSTP; // No Repeated Start: stop condition
|
89 | if(RPT_Flag == 1){ // if Repeated Start: do nothing
|
90 | RPT_Flag = 0;
|
91 | }
|
92 | *PRxData = UCB0RXBUF; // Move final RX data to PRxData
|
93 | UCA0TXBUF = RxBuffer[1];
|
94 | __bic_SR_register_on_exit(CPUOFF); // Exit LPM0
|
95 | }}
|
96 |
|
97 | else{ // Master Transmit
|
98 | if (TXByteCtr) // Check TX byte counter
|
99 | {
|
100 | UCB0TXBUF = MSData; // Load TX buffer
|
101 | TXByteCtr--; // Decrement TX byte counter
|
102 | }
|
103 | else
|
104 | {
|
105 | if(RPT_Flag == 1){
|
106 | RPT_Flag = 0;
|
107 | PTxData = &MSData; // TX array start address
|
108 | TXByteCtr = NUM_BYTES_TX; // Load TX byte counter
|
109 | __bic_SR_register_on_exit(CPUOFF);
|
110 | }
|
111 | else{
|
112 | UCB0CTL1 |= UCTXSTP; // I2C stop condition
|
113 | IFG2 &= ~UCB0TXIFG; // Clear USCI_B0 TX int flag
|
114 | __bic_SR_register_on_exit(CPUOFF); // Exit LPM0
|
115 | }
|
116 | }
|
117 | }
|
118 |
|
119 | }
|
120 |
|
121 | void Setup_TX(void){
|
122 | __disable_interrupt();
|
123 | RX = 0;
|
124 | IE2 &= ~UCB0RXIE;
|
125 | while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent// Disable RX interrupt
|
126 | UCB0CTL1 |= UCSWRST; // Enable SW reset
|
127 | UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
|
128 | UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
|
129 | UCB0BR0 = 12; // fSCL = SMCLK/12 = ~100kHz
|
130 | UCB0BR1 = 0;
|
131 | UCB0I2CSA = 0x20; // Slave Address is 048h
|
132 | UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
|
133 | IE2 |= UCB0TXIE; // Enable TX interrupt
|
134 | }
|
135 | void Setup_RX(void){
|
136 | __disable_interrupt();
|
137 | RX = 1;
|
138 | IE2 &= ~UCB0TXIE;
|
139 | UCB0CTL1 |= UCSWRST; // Enable SW reset
|
140 | UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
|
141 | UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
|
142 | UCB0BR0 = 12; // fSCL = SMCLK/12 = ~100kHz
|
143 | UCB0BR1 = 0;
|
144 | UCB0I2CSA = 0x20; // Slave Address is 048h
|
145 | UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
|
146 | IE2 |= UCB0RXIE; // Enable RX interrupt
|
147 | }
|
148 | void Transmit(void){
|
149 | PTxData = &MSData; // TX array start address
|
150 | TXByteCtr = NUM_BYTES_TX; // Load TX byte counter
|
151 | while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent
|
152 | UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
|
153 | __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
|
154 | }
|
155 | void Receive(void){
|
156 | PRxData = (unsigned char *)RxBuffer; // Start of RX buffer
|
157 | RXByteCtr = NUM_BYTES_RX-1; // Load RX byte counter
|
158 | while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent
|
159 | UCB0CTL1 |= UCTXSTT; // I2C start condition
|
160 | __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
|
161 | }
|
162 |
|
163 | void setupUART(){
|
164 | IE2 &= ~UCA0RXIE;
|
165 | IE2 &= ~UCB0RXIE;
|
166 | IE2 &= ~UCA0TXIE;
|
167 | IE2 &= ~UCB0TXIE;
|
168 | UX = 1;
|
169 | RX = 1;
|
170 | DCOCTL = 0; // Select lowest DCOx and MODx settings
|
171 | BCSCTL1 = CALBC1_1MHZ; // Set DCO
|
172 | DCOCTL = CALDCO_1MHZ;
|
173 | P1SEL = BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD
|
174 | P1SEL2 = BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD
|
175 | UCA0CTL1 |= UCSSEL_2; // SMCLK
|
176 | UCA0BR0 = 104; // 1MHz 9600
|
177 | UCA0BR1 = 0; // 1MHz 9600
|
178 | UCA0MCTL = UCBRS0; // Modulation UCBRSx = 1
|
179 | UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
|
180 | IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt
|
181 |
|
182 | __bis_SR_register(CPUOFF + GIE); // Enter LPM0, interrupts enabled
|
183 | }
|