请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
器件型号:MSP430FR5994 大家好、社区、
过去几周我一直在 LoRa 工作。 我使用 SPI 通信协议进行通信。 今天、我遇到了一些有线问题、即我能够正确地从一个特定的寄存器中写入和读取、并且无法正确地与另一组寄存器通信。 每当我尝试读取这些寄存器时、我都会得到相同的常量值0x09。
以便检查 SPI 代码。 我把从器件更改为 ADXL345 (加速计)、也遇到了同样的问题。 当我读取数据寄存器0x31、0x32 --0x36.我得到一个常量值0x03
我在下面共享两个代码、请仔细阅读并告知我修复方法
Lora 代码
//******************************************************************************
// MSP430FR599x Demo - eUSCI_B1, SPI 4-Wire Master multiple byte RX/TX
//
// Description: SPI master communicates to SPI slave sending and receiving
// 3 different messages of different length. SPI master will enter LPM0 mode
// while waiting for the messages to be sent/receiving using SPI interrupt.
// SPI Master will initially wait for a port interrupt in LPM0 mode before
// starting the SPI communication.
// ACLK = NA, MCLK = SMCLK = DCO 16MHz.
//
//
// MSP430FR5994
// -----------------
// /|\ | P1.0|-> Comms LED
// | | |
// ---|RST P1.4|-> Slave Reset (GPIO)
// | |
// | P5.0|-> Data Out (UCB1SIMO) // not required
// | |
// Button ->|P5.5 P5.1|<- Data In (UCB1SOMI)
// Button LED <-|P1.1 |
// | P5.2|-> Serial Clock Out (UCB1CLK)
// | |
// | P5.3|-> Slave Chip Select (GPIO)
//
// Nima Eskandari and Ryan Meredith
// Texas Instruments Inc.
// January 2018
// Built with CCS V7.0
//******************************************************************************
#include <msp430.h>
#include <stdint.h>
//******************************************************************************
// Pin Config ******************************************************************
//******************************************************************************
#define SLAVE_CS_OUT P5OUT
#define SLAVE_CS_DIR P5DIR
#define SLAVE_CS_PIN BIT3
#define SLAVE_RST_OUT P6OUT
#define SLAVE_RST_DIR P6DIR
#define SLAVE_RST_PIN BIT3
#define BUTTON_DIR P5DIR
#define BUTTON_OUT P5OUT
#define BUTTON_REN P5REN
#define BUTTON_PIN BIT5
#define BUTTON_IES P5IES
#define BUTTON_IE P5IE
#define BUTTON_IFG P5IFG
#define BUTTON_VECTOR PORT5_VECTOR
#define BUTTON_LED_OUT P1OUT
#define BUTTON_LED_DIR P1DIR
#define BUTTON_LED_PIN BIT1
#define COMMS_LED_OUT P1OUT
#define COMMS_LED_DIR P1DIR
#define COMMS_LED_PIN BIT0
//******************************************************************************
// Example Commands ************************************************************
//******************************************************************************
#define DUMMY 0xFF
/* CMD_TYPE_X_SLAVE are example commands the master sends to the slave.
* The slave will send example SlaveTypeX buffers in response.
*
* CMD_TYPE_X_MASTER are example commands the master sends to the slave.
* The slave will initialize itself to receive MasterTypeX example buffers.
* */
#define CMD_TYPE_0_SLAVE 0x01
#define CMD_TYPE_1_SLAVE 1
#define CMD_TYPE_2_SLAVE 2
#define CMD_TYPE_0_MASTER 0x01
#define CMD_TYPE_1_MASTER 4
#define CMD_TYPE_2_MASTER 5
#define TYPE_0_LENGTH 1
#define TYPE_1_LENGTH 2
#define TYPE_2_LENGTH 6
#define MAX_BUFFER_SIZE 20
/* MasterTypeX are example buffers initialized in the master, they will be
* sent by the master to the slave.
* SlaveTypeX are example buffers initialized in the slave, they will be
* sent by the slave to the master.
* */
uint8_t MasterType0 [TYPE_0_LENGTH] = {0x80};
uint8_t MasterType1 [TYPE_1_LENGTH] = {0x01, 0x80};
uint8_t MasterType2 [TYPE_2_LENGTH] = {'F', '4' , '1' , '9', '2', 'B'};
uint8_t SlaveType2 [TYPE_2_LENGTH] = {0};
uint8_t SlaveType1 [TYPE_1_LENGTH] = {0};
uint8_t SlaveType0 [TYPE_0_LENGTH] = {0};
uint8_t ucb1_rx_val = 0;
//******************************************************************************
// General SPI State Machine ***************************************************
//******************************************************************************
typedef enum SPI_ModeEnum{
IDLE_MODE,
TX_REG_ADDRESS_MODE,
RX_REG_ADDRESS_MODE,
TX_DATA_MODE,
RX_DATA_MODE,
TIMEOUT_MODE
} SPI_Mode;
/* Used to track the state of the software state machine*/
SPI_Mode MasterMode = IDLE_MODE;
/* The Register Address/Command to use*/
uint8_t TransmitRegAddr = 0;
/* ReceiveBuffer: Buffer used to receive data in the ISR
* RXByteCtr: Number of bytes left to receive
* ReceiveIndex: The index of the next byte to be received in ReceiveBuffer
* TransmitBuffer: Buffer used to transmit data in the ISR
* TXByteCtr: Number of bytes left to transfer
* TransmitIndex: The index of the next byte to be transmitted in TransmitBuffer
* */
uint8_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0};
uint8_t RXByteCtr = 0;
uint8_t ReceiveIndex = 0;
uint8_t TransmitBuffer[MAX_BUFFER_SIZE] = {0};
uint8_t TXByteCtr = 0;
uint8_t TransmitIndex = 0;
/* SPI Write and Read Functions */
/* For slave device, writes the data specified in *reg_data
*
* reg_addr: The register or command to send to the slave.
* Example: CMD_TYPE_0_MASTER
* *reg_data: The buffer to write
* Example: MasterType0
* count: The length of *reg_data
* Example: TYPE_0_LENGTH
* */
SPI_Mode SPI_Master_WriteReg(uint8_t reg_addr, uint8_t *reg_data, uint8_t count);
/* For slave device, read the data specified in slaves reg_addr.
* The received data is available in ReceiveBuffer
*
* reg_addr: The register or command to send to the slave.
* Example: CMD_TYPE_0_SLAVE
* count: The length of data to read
* Example: TYPE_0_LENGTH
* */
SPI_Mode SPI_Master_ReadReg(uint8_t reg_addr, uint8_t count);
void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count);
void SendUCB1Data(uint8_t val);
void SendUCB1Data(uint8_t val)
{
while (!(UCB1IFG & UCTXIFG)); // USCI_B1 TX buffer ready?
UCB1TXBUF = val;
}
void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count)
{
uint8_t copyIndex = 0;
for (copyIndex = 0; copyIndex < count; copyIndex++)
{
dest[copyIndex] = source[copyIndex];
}
}
SPI_Mode SPI_Master_WriteReg(uint8_t reg_addr, uint8_t *reg_data, uint8_t count)
{
MasterMode = TX_REG_ADDRESS_MODE;
TransmitRegAddr = reg_addr ;
//Copy register data to TransmitBuffer
CopyArray(reg_data, TransmitBuffer, count);
TXByteCtr = count;
RXByteCtr = 0;
ReceiveIndex = 0;
TransmitIndex = 0;
SLAVE_CS_OUT &= ~(SLAVE_CS_PIN);
SendUCB1Data(TransmitRegAddr);
__bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
SLAVE_CS_OUT |= SLAVE_CS_PIN;
return MasterMode;
}
SPI_Mode SPI_Master_ReadReg(uint8_t reg_addr, uint8_t count)
{
MasterMode = TX_REG_ADDRESS_MODE;
TransmitRegAddr = reg_addr & 0x7F;
RXByteCtr = count;
TXByteCtr = 0;
ReceiveIndex = 0;
TransmitIndex = 0;
SLAVE_CS_OUT &= ~(SLAVE_CS_PIN); // working
SendUCB1Data(TransmitRegAddr);
__bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
SLAVE_CS_OUT |= SLAVE_CS_PIN;
return MasterMode;
}
//******************************************************************************
// Device Initialization *******************************************************
//******************************************************************************
void initSPI()
{
//Clock Polarity: The inactive state is high
//MSB First, 8-bit, Master, 3-pin mode, Synchronous
UCB1CTLW0 = UCSWRST; // **Put state machine in reset**
UCB1CTLW0 |= UCCKPL | UCMSB | UCSYNC
| UCMST | UCSSEL__SMCLK; // 3-pin, 8-bit SPI Slave
UCB1BRW = 0x01;
//UCB1MCTLW = 0;
UCB1CTLW0 &= ~UCSWRST; // **Initialize USCI state machine**
UCB1IE |= UCRXIE; // Enable USCI0 RX interrupt
}
void initGPIO()
{
//LEDs
COMMS_LED_DIR |= COMMS_LED_PIN;
COMMS_LED_OUT &= ~COMMS_LED_PIN;
BUTTON_LED_DIR |= BUTTON_LED_PIN;
BUTTON_LED_OUT &= ~BUTTON_LED_PIN;
// Configure SPI
P5SEL0 |= BIT0 | BIT1 | BIT2;
SLAVE_RST_DIR |= SLAVE_RST_PIN;
SLAVE_RST_OUT |= SLAVE_RST_PIN;
SLAVE_CS_DIR |= SLAVE_CS_PIN;
SLAVE_CS_OUT |= SLAVE_CS_PIN;
//Button to initiate transfer
BUTTON_DIR &= ~(BUTTON_PIN); // button input
BUTTON_OUT |= BUTTON_PIN; // button pull up
BUTTON_REN |= BUTTON_PIN; // button pull up/down resistor enable
BUTTON_IES |= BUTTON_PIN; // button Hi/lo edge
BUTTON_IE |= BUTTON_PIN; // button interrupt enabled
// Disable the GPIO power-on default high-impedance mode to activate
// previously configured port settings
PM5CTL0 &= ~LOCKLPM5;
BUTTON_IFG &= ~BUTTON_PIN; // button IFG cleared
}
void initClockTo16MHz()
{
// Configure one FRAM waitstate as required by the device datasheet for MCLK
// operation beyond 8MHz _before_ configuring the clock system.
FRCTL0 = FRCTLPW | NWAITS_1;
// Clock System Setup
CSCTL0_H = CSKEY_H; // Unlock CS registers
CSCTL1 = DCOFSEL_0; // Set DCO to 1MHz
// Set SMCLK = MCLK = DCO, ACLK = VLOCLK
CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK;
// Per Device Errata set divider to 4 before changing frequency to
// prevent out of spec operation from overshoot transient
CSCTL3 = DIVA__4 | DIVS__4 | DIVM__4; // Set all corresponding clk sources to divide by 4 for errata
CSCTL1 = DCOFSEL_4 | DCORSEL; // Set DCO to 16MHz
// Delay by ~10us to let DCO settle. 60 cycles = 20 cycles buffer + (10us / (1/4MHz))
__delay_cycles(60);
CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1; // Set all dividers to 1 for 16MHz operation
CSCTL0_H = 0; // Lock CS registers
}
//******************************************************************************
// Main ************************************************************************
// Send and receive three messages containing the example commands *************
//******************************************************************************
//void sx1276_set_opmode(uint8_t opmode) {
// uint8_t slave_data;
// SPI_Master_ReadReg((0x01 & 0xF8), TYPE_0_LENGTH);
// CopyArray(ReceiveBuffer, slave_data, TYPE_0_LENGTH);
// uint8_t add[] = (slave_data | opmode);
// SPI_Master_WriteReg(CMD_TYPE_2_MASTER, (0x01, add), TYPE_2_LENGTH);
//}
int main(void) {
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
// initClockTo16MHz();
initGPIO();
initSPI();
SLAVE_RST_OUT &= ~SLAVE_RST_PIN; // Now with SPI signals initialized,
__delay_cycles(100000);
SLAVE_RST_OUT |= SLAVE_RST_PIN; // reset slave
__delay_cycles(100000); // Wait for slave to initialize
COMMS_LED_OUT |= COMMS_LED_PIN;
SPI_Master_WriteReg(CMD_TYPE_0_MASTER, MasterType0, TYPE_0_LENGTH);
SPI_Master_ReadReg(CMD_TYPE_0_MASTER, TYPE_0_LENGTH);
CopyArray(ReceiveBuffer, SlaveType0, TYPE_0_LENGTH);
__delay_cycles(10000);
return 0;
}
//******************************************************************************
// SPI Interrupt ***************************************************************
//******************************************************************************
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_B1_VECTOR
__interrupt void USCI_B1_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B1_VECTOR))) USCI_B1_ISR (void)
#else
#error Compiler not supported!
#endif
{
switch(__even_in_range(UCB1IV, USCI_SPI_UCTXIFG))
{
case USCI_NONE: break;
case USCI_SPI_UCRXIFG:
ucb1_rx_val = UCB1RXBUF;
UCB1IFG &= ~UCRXIFG;
switch (MasterMode)
{
case TX_REG_ADDRESS_MODE:
if (RXByteCtr)
{
MasterMode = RX_DATA_MODE; // Need to start receiving now
//Send Dummy To Start
// __delay_cycles(2000000);
SendUCB1Data(DUMMY);
}
else
{
MasterMode = TX_DATA_MODE; // Continue to transmision with the data in Transmit Buffer
//Send First
SendUCB1Data(TransmitBuffer[TransmitIndex++]);
TXByteCtr--;
}
break;
case TX_DATA_MODE:
if (TXByteCtr)
{
SendUCB1Data(TransmitBuffer[TransmitIndex++]);
TXByteCtr--;
}
else
{
//Done with transmission
MasterMode = IDLE_MODE;
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
break;
case RX_DATA_MODE:
if (RXByteCtr)
{
ReceiveBuffer[ReceiveIndex++] = ucb1_rx_val;
//Transmit a dummy
RXByteCtr--;
}
if (RXByteCtr == 0)
{
MasterMode = IDLE_MODE;
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
else
{
SendUCB1Data(DUMMY);
}
break;
default:
__no_operation();
break;
}
// __delay_cycles(1000);
break;
case USCI_SPI_UCTXIFG:
break;
default: break;
}
}
//******************************************************************************
// Button Port Interrupt *************************************************************
// Interrupt occurs on button press and initiates the SPI data transfer ********
//******************************************************************************
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=BUTTON_VECTOR
__interrupt void Button_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(BUTTON_VECTOR))) Button_ISR (void)
#else
#error Compiler not supported!
#endif
{
BUTTON_LED_OUT |= BUTTON_LED_PIN;
BUTTON_IFG &= ~BUTTON_PIN; // button IFG cleared
BUTTON_IE &= ~BUTTON_PIN;
//Initiate
__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
}
ADXL345代码
//******************************************************************************
// MSP430FR599x Demo - eUSCI_B1, SPI 4-Wire Master multiple byte RX/TX
//
// Description: SPI master communicates to SPI slave sending and receiving
// 3 different messages of different length. SPI master will enter LPM0 mode
// while waiting for the messages to be sent/receiving using SPI interrupt.
// SPI Master will initially wait for a port interrupt in LPM0 mode before
// starting the SPI communication.
// ACLK = NA, MCLK = SMCLK = DCO 16MHz.
//
//
// MSP430FR5994
// -----------------
// /|\ | P1.0|-> Comms LED
// | | |
// ---|RST P1.4|-> Slave Reset (GPIO)
// | |
// | P5.0|-> Data Out (UCB1SIMO)
// | |
// Button ->|P5.5 P5.1|<- Data In (UCB1SOMI)
// Button LED <-|P1.1 |
// | P5.2|-> Serial Clock Out (UCB1CLK)
// | |
// | P5.3|-> Slave Chip Select (GPIO)
//
// Nima Eskandari and Ryan Meredith
// Texas Instruments Inc.
// January 2018
// Built with CCS V7.0
//******************************************************************************
#include <msp430.h>
#include <stdint.h>
//******************************************************************************
// Pin Config ******************************************************************
//******************************************************************************
#define SLAVE_CS_OUT P5OUT
#define SLAVE_CS_DIR P5DIR
#define SLAVE_CS_PIN BIT3
#define SLAVE_RST_OUT P1OUT
#define SLAVE_RST_DIR P1DIR
#define SLAVE_RST_PIN BIT4
#define BUTTON_DIR P5DIR
#define BUTTON_OUT P5OUT
#define BUTTON_REN P5REN
#define BUTTON_PIN BIT5
#define BUTTON_IES P5IES
#define BUTTON_IE P5IE
#define BUTTON_IFG P5IFG
#define BUTTON_VECTOR PORT5_VECTOR
#define BUTTON_LED_OUT P1OUT
#define BUTTON_LED_DIR P1DIR
#define BUTTON_LED_PIN BIT1
#define COMMS_LED_OUT P1OUT
#define COMMS_LED_DIR P1DIR
#define COMMS_LED_PIN BIT0
//******************************************************************************
// Example Commands ************************************************************
//******************************************************************************
#define DUMMY 0xFF
/* CMD_TYPE_X_SLAVE are example commands the master sends to the slave.
* The slave will send example SlaveTypeX buffers in response.
*
* CMD_TYPE_X_MASTER are example commands the master sends to the slave.
* The slave will initialize itself to receive MasterTypeX example buffers.
* */
#define CMD_TYPE_0_SLAVE 0X32
#define CMD_TYPE_1_SLAVE 1
#define CMD_TYPE_2_SLAVE 2
#define CMD_TYPE_0_MASTER 0X2D
#define CMD_TYPE_1_MASTER 4
#define CMD_TYPE_2_MASTER 5
#define TYPE_0_LENGTH 1
#define TYPE_1_LENGTH 2
#define TYPE_2_LENGTH 6
#define MAX_BUFFER_SIZE 20
/* MasterTypeX are example buffers initialized in the master, they will be
* sent by the master to the slave.
* SlaveTypeX are example buffers initialized in the slave, they will be
* sent by the slave to the master.
* */
uint8_t MasterType0 [TYPE_0_LENGTH] = {0x08};
uint8_t MasterType1 [TYPE_1_LENGTH] = {8, 9};
uint8_t MasterType2 [TYPE_2_LENGTH] = {'F', '4' , '1' , '9', '2', 'B'};
uint8_t SlaveType2 [TYPE_2_LENGTH] = {0};
uint8_t SlaveType1 [TYPE_1_LENGTH] = {0};
uint8_t SlaveType0 [TYPE_0_LENGTH] = {0};
//******************************************************************************
// General SPI State Machine ***************************************************
//******************************************************************************
typedef enum SPI_ModeEnum{
IDLE_MODE,
TX_REG_ADDRESS_MODE,
RX_REG_ADDRESS_MODE,
TX_DATA_MODE,
RX_DATA_MODE,
TIMEOUT_MODE
} SPI_Mode;
/* Used to track the state of the software state machine*/
SPI_Mode MasterMode = IDLE_MODE;
/* The Register Address/Command to use*/
uint8_t TransmitRegAddr = 0;
/* ReceiveBuffer: Buffer used to receive data in the ISR
* RXByteCtr: Number of bytes left to receive
* ReceiveIndex: The index of the next byte to be received in ReceiveBuffer
* TransmitBuffer: Buffer used to transmit data in the ISR
* TXByteCtr: Number of bytes left to transfer
* TransmitIndex: The index of the next byte to be transmitted in TransmitBuffer
* */
uint8_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0};
uint8_t RXByteCtr = 0;
uint8_t ReceiveIndex = 0;
uint8_t TransmitBuffer[MAX_BUFFER_SIZE] = {0};
uint8_t TXByteCtr = 0;
uint8_t TransmitIndex = 0;
/* SPI Write and Read Functions */
/* For slave device, writes the data specified in *reg_data
*
* reg_addr: The register or command to send to the slave.
* Example: CMD_TYPE_0_MASTER
* *reg_data: The buffer to write
* Example: MasterType0
* count: The length of *reg_data
* Example: TYPE_0_LENGTH
* */
SPI_Mode SPI_Master_WriteReg(uint8_t reg_addr, uint8_t *reg_data, uint8_t count);
/* For slave device, read the data specified in slaves reg_addr.
* The received data is available in ReceiveBuffer
*
* reg_addr: The register or command to send to the slave.
* Example: CMD_TYPE_0_SLAVE
* count: The length of data to read
* Example: TYPE_0_LENGTH
* */
SPI_Mode SPI_Master_ReadReg(uint8_t reg_addr, uint8_t count);
void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count);
void SendUCB1Data(uint8_t val);
void SendUCB1Data(uint8_t val)
{
while (!(UCB1IFG & UCTXIFG)); // USCI_B1 TX buffer ready?
UCB1TXBUF = val;
}
void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count)
{
uint8_t copyIndex = 0;
for (copyIndex = 0; copyIndex < count; copyIndex++)
{
dest[copyIndex] = source[copyIndex];
}
}
SPI_Mode SPI_Master_WriteReg(uint8_t reg_addr, uint8_t *reg_data, uint8_t count)
{
MasterMode = TX_REG_ADDRESS_MODE;
TransmitRegAddr = reg_addr;
//Copy register data to TransmitBuffer
CopyArray(reg_data, TransmitBuffer, count);
TXByteCtr = count;
RXByteCtr = 0;
ReceiveIndex = 0;
TransmitIndex = 0;
SLAVE_CS_OUT &= ~(SLAVE_CS_PIN);
SendUCB1Data(TransmitRegAddr);
__bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
SLAVE_CS_OUT |= SLAVE_CS_PIN;
return MasterMode;
}
SPI_Mode SPI_Master_ReadReg(uint8_t reg_addr, uint8_t count)
{
MasterMode = TX_REG_ADDRESS_MODE;
TransmitRegAddr = reg_addr;
RXByteCtr = count;
TXByteCtr = 0;
ReceiveIndex = 0;
TransmitIndex = 0;
SLAVE_CS_OUT &= ~(SLAVE_CS_PIN);
SendUCB1Data(TransmitRegAddr);
__bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
SLAVE_CS_OUT |= SLAVE_CS_PIN;
return MasterMode;
}
//******************************************************************************
// Device Initialization *******************************************************
//******************************************************************************
void initSPI()
{
//Clock Polarity: The inactive state is high
//MSB First, 8-bit, Master, 3-pin mode, Synchronous
UCB1CTLW0 = UCSWRST; // **Put state machine in reset**
UCB1CTLW0 |= UCCKPL /*| UCCKPH*/|UCMSB | UCSYNC
| UCMST | UCSSEL__SMCLK; // 3-pin, 8-bit SPI Slave
UCB1BRW = 0x20;
//UCB1MCTLW = 0;
UCB1CTLW0 &= ~UCSWRST; // **Initialize USCI state machine**
UCB1IE |= UCRXIE; // Enable USCI0 RX interrupt
}
void initGPIO()
{
//LEDs
COMMS_LED_DIR |= COMMS_LED_PIN;
COMMS_LED_OUT &= ~COMMS_LED_PIN;
BUTTON_LED_DIR |= BUTTON_LED_PIN;
BUTTON_LED_OUT &= ~BUTTON_LED_PIN;
// Configure SPI
P5SEL0 |= BIT0 | BIT1 | BIT2;
SLAVE_RST_DIR |= SLAVE_RST_PIN;
SLAVE_RST_OUT |= SLAVE_RST_PIN;
SLAVE_CS_DIR |= SLAVE_CS_PIN;
SLAVE_CS_OUT |= SLAVE_CS_PIN;
//Button to initiate transfer
BUTTON_DIR &= ~(BUTTON_PIN); // button input
BUTTON_OUT |= BUTTON_PIN; // button pull up
BUTTON_REN |= BUTTON_PIN; // button pull up/down resistor enable
BUTTON_IES |= BUTTON_PIN; // button Hi/lo edge
BUTTON_IE |= BUTTON_PIN; // button interrupt enabled
// Disable the GPIO power-on default high-impedance mode to activate
// previously configured port settings
PM5CTL0 &= ~LOCKLPM5;
BUTTON_IFG &= ~BUTTON_PIN; // button IFG cleared
}
void initClockTo16MHz()
{
// Configure one FRAM waitstate as required by the device datasheet for MCLK
// operation beyond 8MHz _before_ configuring the clock system.
FRCTL0 = FRCTLPW | NWAITS_1;
// Clock System Setup
CSCTL0_H = CSKEY_H; // Unlock CS registers
CSCTL1 = DCOFSEL_0; // Set DCO to 1MHz
// Set SMCLK = MCLK = DCO, ACLK = VLOCLK
CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK;
// Per Device Errata set divider to 4 before changing frequency to
// prevent out of spec operation from overshoot transient
CSCTL3 = DIVA__4 | DIVS__4 | DIVM__4; // Set all corresponding clk sources to divide by 4 for errata
CSCTL1 = DCOFSEL_4 | DCORSEL; // Set DCO to 16MHz
// Delay by ~10us to let DCO settle. 60 cycles = 20 cycles buffer + (10us / (1/4MHz))
__delay_cycles(60);
CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1; // Set all dividers to 1 for 16MHz operation
CSCTL0_H = 0; // Lock CS registers
}
//******************************************************************************
// Main ************************************************************************
// Send and receive three messages containing the example commands *************
//******************************************************************************
int main(void) {
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
initClockTo16MHz();
initGPIO();
initSPI();
SLAVE_RST_OUT &= ~SLAVE_RST_PIN; // Now with SPI signals initialized,
__delay_cycles(100000);
SLAVE_RST_OUT |= SLAVE_RST_PIN; // reset slave
__delay_cycles(100000); // Wait for slave to initialize
COMMS_LED_OUT |= COMMS_LED_PIN;
__bis_SR_register(LPM0_bits + GIE); // CPU off, enable interrupts
// SPI_Master_ReadReg(CMD_TYPE_0_SLAVE, TYPE_0_LENGTH);
// CopyArray(ReceiveBuffer, SlaveType0, TYPE_0_LENGTH);
while(1)
{
SPI_Master_WriteReg(CMD_TYPE_0_MASTER, MasterType0, TYPE_0_LENGTH);
uint8_t address =0x80|CMD_TYPE_0_MASTER;
SPI_Master_ReadReg(address, TYPE_0_LENGTH);
CopyArray(ReceiveBuffer, SlaveType0, TYPE_0_LENGTH);
}
//
// SPI_Master_ReadReg(CMD_TYPE_1_SLAVE, TYPE_1_LENGTH);
// CopyArray(ReceiveBuffer, SlaveType1, TYPE_1_LENGTH);
//
// SPI_Master_ReadReg(CMD_TYPE_0_SLAVE, TYPE_0_LENGTH);
// CopyArray(ReceiveBuffer, SlaveType0, TYPE_0_LENGTH);
//
// SPI_Master_WriteReg(CMD_TYPE_2_MASTER, MasterType2, TYPE_2_LENGTH);
// SPI_Master_WriteReg(CMD_TYPE_1_MASTER, MasterType1, TYPE_1_LENGTH);
// SPI_Master_WriteReg(CMD_TYPE_0_MASTER, MasterType0, TYPE_0_LENGTH);
__bis_SR_register(LPM0_bits + GIE);
__no_operation();
return 0;
}
//******************************************************************************
// SPI Interrupt ***************************************************************
//******************************************************************************
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_B1_VECTOR
__interrupt void USCI_B1_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B1_VECTOR))) USCI_B1_ISR (void)
#else
#error Compiler not supported!
#endif
{
uint8_t ucb1_rx_val = 0;
switch(__even_in_range(UCB1IV, USCI_SPI_UCTXIFG))
{
case USCI_NONE: break;
case USCI_SPI_UCRXIFG:
ucb1_rx_val = UCB1RXBUF;
UCB1IFG &= ~UCRXIFG;
switch (MasterMode)
{
case TX_REG_ADDRESS_MODE:
if (RXByteCtr)
{
MasterMode = RX_DATA_MODE; // Need to start receiving now
//Send Dummy To Start
__delay_cycles(2000000);
SendUCB1Data(DUMMY);
}
else
{
MasterMode = TX_DATA_MODE; // Continue to transmision with the data in Transmit Buffer
//Send First
SendUCB1Data(TransmitBuffer[TransmitIndex++]);
TXByteCtr--;
}
break;
case TX_DATA_MODE:
if (TXByteCtr)
{
SendUCB1Data(TransmitBuffer[TransmitIndex++]);
TXByteCtr--;
}
else
{
//Done with transmission
MasterMode = IDLE_MODE;
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
break;
case RX_DATA_MODE:
if (RXByteCtr)
{
ReceiveBuffer[ReceiveIndex++] = ucb1_rx_val;
//Transmit a dummy
RXByteCtr--;
}
if (RXByteCtr == 0)
{
MasterMode = IDLE_MODE;
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
else
{
SendUCB1Data(DUMMY);
}
break;
default:
__no_operation();
break;
}
__delay_cycles(1000);
break;
case USCI_SPI_UCTXIFG:
break;
default: break;
}
}
//******************************************************************************
// Button Port Interrupt *************************************************************
// Interrupt occurs on button press and initiates the SPI data transfer ********
//******************************************************************************
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=BUTTON_VECTOR
__interrupt void Button_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(BUTTON_VECTOR))) Button_ISR (void)
#else
#error Compiler not supported!
#endif
{
BUTTON_LED_OUT |= BUTTON_LED_PIN;
BUTTON_IFG &= ~BUTTON_PIN; // button IFG cleared
BUTTON_IE &= ~BUTTON_PIN;
//Initiate
__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
}