请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
器件型号: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 }