-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathusciB1spi.c
executable file
·114 lines (99 loc) · 4.95 KB
/
usciB1spi.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
* usciB1spi.c
*
* Created on: 2024/12/02
* Author: Jamie Boyd
*/
#include <msp430.h>
#include "usciB1spi.h"
/*************************** Function: usciB1spiInit ******************************************************
* - configures USCI B1 for use as an SPI controller
* argument 1: spiMST if 1 the USCIB1 is configured as a master, otherwise it is a slave.
* argument 2: sclkDIV defines the 16 bit clock divisor used to divide 2^20 Hz SMCLK, which is used as the clock source
* argument 3: sclkMode clock mode. bit 0 is clock polarity, bit 1 is phase. 0-3 are valid arguments
* argument 4: nssMode
* return: nothing
* Author: Jamie Boyd
* Date: 2022/01/23
*********************************************************************************************************/
void usciB1spiInit (SPIinitStruct initStruct, unsigned int sclkDiv){
UCB1CTL1 |= UCSWRST; // put state machine into reset
UCB1CTL0 = UCMST | UCSYNC; // Synchronous mode always enabled for SPI, and always Master
UCB1CTL0 |= initStruct.clockPhase;
UCB1CTL0 |= initStruct.clockPol;
UCB1CTL0 |= initStruct.shiftDir;
UCB1CTL0 |= initStruct.charLen;
UCB1STAT |= initStruct.loopBack;
// clock config
UCB1CTL1 |= initStruct.clockSrc;
UCB1BR0 = (sclkDiv & 0xFF); // UCB1BR0 is the low byte. ANDing with 255 removes the high byte
UCB1BR1 = (sclkDiv >> 8); // UCB1BR0 is the high byte. right shifting 8 bits replaces low bye with high byte
// configure the SPI pins with P4SEL register to select peripheral function
P4DIR |= (SPI_MOSI | SPI_CLK); // these are outputs controlled by Master
P4DIR &= ~SPI_MISO; // input from the slave device
P4SEL |= (SPI_MISO | SPI_MOSI | SPI_CLK); // select special function mode for MOSI, MISO, and clock
UCB1CTL1 &= ~UCSWRST; // Enable USCI state machine
// set P2.0 as output and set high
P2DIR |= SPI_NSS;
P2OUT |= SPI_NSS;
}
/************************ Function: usciB1SpiClkDiv *************************************
* - divides down smclk to make clock for SPI. If you want to change clock speed after initing
* Arguments:2
* argument 1: sclkDiv – 16 bit value for clock divisor
* return: nothing
* Author: Jamie Boyd
* Date: 2022/01/23
* ****************************************************************************************/
void usciB1spiSetClock(unsigned int sclkDiv){
UCB1CTL1 |= UCSWRST; // you always need to put state machine into reset when configuring USC module
// SCLKDIV is a 16 bit value, it gets spread out over 2 8-bit control registers
UCB1BR0 = (sclkDiv & 0xFF); // UCB1BR0 is the low byte. ANDing with 255 removes the high byte
UCB1BR1 = (sclkDiv >> 8); // UCB1BR0 is the high byte. right shifting 8 bits replaces low bye with high byte
UCB1CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
}
// when the TXBUFFER is ready, load it.
void usciB1spiPutChar(unsigned char txByte) {
while (!(UCB1IFG & UCTXIFG)){}; // poll, waiting for an opportunity to send
UCB1TXBUF =txByte; // write the byte to the TX buffer register
}
// when RXBUFFER is ready, get the value and return it.
unsigned char usciB1spiGetChar (void) {
while (!(UCB1IFG & UCRXIFG)){}; // poll, waiting for an opportunity to read
return UCB1RXBUF;
}
/*
#pragma vector=USCI_B1_VECTOR
__interrupt void usciB1spiIsr(void) {
// UCB1IV interrupt handler. __even_in_range will optimize the C code so efficient jumps are implemented.
switch(__even_in_range(UCB1IV,4)) // this will clear the current highest priority flag. TXIFG or RXIFG.
{
case 0: break; // Vector 0 - no interrupt
case 2: // Vector 2 - RXIFG. Highest priority
// process RXIFG
spiRxBuffer [spiRxPos++] = UCB1RXBUF;
if (spiRxPos == RX_BUF_SIZE){
P2OUT |= SPI_NSS; // de-assert slave select
UCB1IE &= ~UCRXIE; // disable interrupt
spiRxPos=0;
}
break;
case 4: // Vector 4 - TXIFG
// process TXIFG
spiTxBuffer [spiTxPos++] = UCB1RXBUF;
if (spiTxPos == TX_BUF_SIZE){
// last char has been put in the TX buffer, but all bits will not be transmitted till UCRXIFG is set
// If and only if you have UCTXIE set and not UCRXIE, you will need to clear the received flag,
// and wait for it to be set again to be sure that all transmitted data has been shifted.
// to do so, un-comment the next three lines
//UCB1IFG &= ~UCRXIFG;
// while (!(UCB1IFG & UCRXIFG)){};
//P2OUT |= SPI_NSS; // de-assert slave select
UCB1IE &= ~UCTXIE; // disable interrupt
spiTxPos=0;
}
break;
default: break;
}
}
*/