Other Parts Discussed in Thread: BOOST-DRV8711, DRV8711
Tool/software:
Hello,
So, I am currently trying to establish SPI communication between the msp430G2 launch pad and the BOOST-DRV8711. The data is being sent out from the msp430G2(master), which is correct, but when I try to read the data out of the drv8711 IC (slave), nothing is read.
Can you review my code and guide me in the right direction? Also, if you need any further documentation, please let me know.
Below is my current code for establishing SPI communication:
#include <msp430.h>
#include <stdint.h>
#define DUMMY 0x0000
#define SLAVE_CS_OUT P2OUT
#define SLAVE_CS_DIR P2DIR
#define SLAVE_CS_PIN BIT0
//*********************************
// 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;
uint8_t SendUCA0Data(uint8_t val) {
while (!(IFG2 & UCA0TXIFG)); // Wait for TX buffer readiness
UCA0TXBUF = val; // Send the data byte
while (!(IFG2 & UCA0RXIFG)); // Wait for RX buffer to fill
return UCA0RXBUF; // Return received data byte
}
SPI_Mode DRV8711_Write(uint8_t reg_addr, uint16_t data){
MasterMode = TX_REG_ADDRESS_MODE;
uint16_t command = (0 << 15) | ((reg_addr & 0x07) << 12) | (data & 0x0FFF); // Construct 16-bit command
SLAVE_CS_OUT |= SLAVE_CS_PIN; // Activate the slave (CS high)
SendUCA0Data((command >> 8) & 0xFF); // Send upper 8 bits
SendUCA0Data(command & 0xFF); // Send lower 8 bits
//__bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
SLAVE_CS_OUT &= ~SLAVE_CS_PIN; // Deactivate the slave (CS low)
return MasterMode;
}
uint16_t DRV8711_Read(uint8_t reg_addr) {
uint16_t command = (1 << 15) | ((reg_addr & 0x07) << 12); // Construct 16-bit command for read
uint16_t received_data = 0;
SLAVE_CS_OUT |= SLAVE_CS_PIN; // Activate the slave (CS high)
// Send the command (Read request)
SendUCA0Data((command >> 8) & 0xFF); // Send upper 8 bits
SendUCA0Data(command & 0xFF); // Send lower 8 bits
// Receive the data
received_data = ((uint16_t)SendUCA0Data(DUMMY) << 8); // Send dummy and receive upper 8 bits
received_data |= SendUCA0Data(DUMMY); // Send dummy and receive lower 8 bits
SLAVE_CS_OUT &= ~SLAVE_CS_PIN; // deactivate the slave (CS low)
return received_data & 0x0FFF; // Return only the 12 data bits
}
//*******************************
// Device Initialization ********
//*******************************
// calibrating the clock to 16MHz
void initClockTo16MHz()
{
if (CALBC1_16MHZ==0xFF) // If calibration constant erased
{
while(1); // do not load, trap CPU!!
}
DCOCTL = 0; // Select lowest DCOx and MODx settings
BCSCTL1 = CALBC1_16MHZ; // Set DCO
DCOCTL = CALDCO_16MHZ;
}
void initGPIO() {
// Configure GPIO for SPI
P1SEL = BIT1 + BIT2 + BIT4; // Assign SPI pins
P1SEL2 = BIT1 + BIT2 + BIT4; // pins 1.1(MISO), 1.2(MOSI), and 1.4(CLK)
// Configure chip select pin
SLAVE_CS_DIR |= SLAVE_CS_PIN; // GPIO pin 2.0 is CS
SLAVE_CS_OUT &= ~SLAVE_CS_PIN; // CS low by default
}
void initSPI() {
UCA0CTL0 |= UCCKPL + UCMSB + UCMST + UCSYNC; // SPI master, MSB first, synchronous
UCA0CTL1 |= UCSSEL_2; // Use SMCLK
UCA0BR0 = 0x03; // SPI clock divider ~ 5.3MHz
UCA0BR1 = 0;
UCA0MCTL = 0; // No modulation must be cleared for SPI
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
}
//*****************************
// Main ***********************
// Sends messages *************
//*****************************
int main(void) {
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
initClockTo16MHz(); // calibrate clock to 16MHz
initGPIO(); // initiate the GPIO pins
initSPI(); // initiate SPI commands
//Write to a DRV8711 register
uint8_t reg_addr = 0x00; // register 0x00
uint16_t write_data = 0xC39; //data transmitted
DRV8711_Write(reg_addr, write_data);
reg_addr = 0x01; // register 0x01
write_data = 0xA13; // data transmitted
DRV8711_Write(reg_addr, write_data);
//Read from a DRV8711 register
uint8_t reg_addr = 0x07; // register 0x07
uint16_t read_data = DRV8711_Read(reg_addr);
}