Part Number: LP-MSP430FR2476
Hi,
I have much improved results to the MAX17841 wakeup sequence For some reason, this is currently observed with only one MAX17853 connected to the MAX17841. Previously, I could use the Maxim evaluation GUI to talk to two MAX17853 connected to the MAX17841.
All SPI transactions coming out of the MSP 430 look accurate on the scope, including responses from the MAX17853. But the INT' input from the MAX17841 is not triggering at the end of wakeup. I appreciate pointers on why this may be the case. Enabling different receive interrupt flags is not making a difference (Transaction 2).
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <driverlib.h>
#include <msp430.h>
#include "clock~.h" // Clock configurations
static uint8_t TXData = 0; //transaction count
static uint8_t RXData = 0; //SPI receive byte
typedef struct {
uint8_t Len;
uint8_t Data[5];
} spi_MaximTrans_t;
static spi_MaximTrans_t DCInit_transactions[15];
uint8_t SPI_TX_index = 0; //byte count in transaction
/**
* Initialize system clocks
*/
static void init_clock(void) {
// Configure one FRAM waitstate as required by the device datasheet for MCLK
// operation beyond 8MHz _before_ configuring the clock system.
FRAMCtl_configureWaitStateControl(FRAMCTL_ACCESS_TIME_CYCLES_1);
//Set DCO FLL reference = REFO
CS_initClockSignal(CS_FLLREF, CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1);
//Set ACLK = REFO
CS_initClockSignal(CS_ACLK, CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1);
CS_initFLLParam param = {0};
//Set Ratio/Desired MCLK Frequency, initialize DCO, save trim values
CS_initFLLCalculateTrim(CS_MCLK_DESIRED_FREQUENCY_IN_KHZ, CS_MCLK_FLLREF_RATIO, ¶m);
//Set MCLK = REFO
CS_initClockSignal(CS_MCLK, CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1);
//Set SMCLK = DCO
CS_initClockSignal(CS_SMCLK, CS_DCOCLKDIV_SELECT, CS_CLOCK_DIVIDER_1);
//Clear all OSC fault flag
CS_clearAllOscFlagsWithTimeout(1000);
}
/**
* Initialize all of the IO pins per their configuration
*/
static void init_gpio(void) {
// Set all GPIO pins to output low to prevent floating input and reduce power consumption
GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN_ALL8);
GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN_ALL8);
GPIO_setOutputLowOnPin(GPIO_PORT_P3, GPIO_PIN_ALL8);
GPIO_setOutputLowOnPin(GPIO_PORT_P4, GPIO_PIN_ALL8);
GPIO_setOutputLowOnPin(GPIO_PORT_P5, GPIO_PIN_ALL8);
GPIO_setOutputLowOnPin(GPIO_PORT_P6, GPIO_PIN0 | GPIO_PIN1 | GPIO_PIN2);
GPIO_setAsOutputPin( GPIO_PORT_P1, GPIO_PIN_ALL8);
GPIO_setAsOutputPin( GPIO_PORT_P2, GPIO_PIN_ALL8);
GPIO_setAsOutputPin( GPIO_PORT_P3, GPIO_PIN_ALL8);
GPIO_setAsOutputPin( GPIO_PORT_P4, GPIO_PIN_ALL8);
GPIO_setAsOutputPin( GPIO_PORT_P5, GPIO_PIN_ALL8);
GPIO_setAsOutputPin( GPIO_PORT_P6, GPIO_PIN0 | GPIO_PIN1 | GPIO_PIN2);
}
/*
* Initialize the SPI peripheral on EUSCI A1
*/
void init_spi_peripheral()
{
//Initialize Master
EUSCI_A_SPI_initMasterParam param = {0};
param.selectClockSource = EUSCI_A_SPI_CLOCKSOURCE_SMCLK;
param.clockSourceFrequency = CS_getSMCLK();
param.desiredSpiClock = 1000000;
param.msbFirst = UCMSB;
param.clockPhase = EUSCI_A_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT;
param.clockPolarity = EUSCI_A_SPI_CLOCKPOLARITY_INACTIVITY_LOW;
param.spiMode = EUSCI_A_SPI_3PIN;
EUSCI_A_SPI_initMaster(EUSCI_A1_BASE, ¶m);
EUSCI_A_SPI_enable(EUSCI_A1_BASE);
}
void SetUpTransactions(void){ //All transactions padded to 4 bytes
//Enable keep alive mode
DCInit_transactions[0].Len = 2;
DCInit_transactions[0].Data[0] = 0x10;
DCInit_transactions[0].Data[1] = 0x5;
DCInit_transactions[1].Len = 2;
DCInit_transactions[1].Data[0] = 0x11;
DCInit_transactions[1].Data[1] = 0x0; //Read Transaction 1 byte
//Enable Rx Interrupt flags
DCInit_transactions[2].Len = 2;
DCInit_transactions[2].Data[0] = 0x4;
DCInit_transactions[2].Data[1] = 0x89; //No Receive
DCInit_transactions[3].Len = 2;
DCInit_transactions[3].Data[0] = 0x5;
DCInit_transactions[3].Data[1] = 0x0; //Read Transaction 2 byte
//Clear receive buffer
DCInit_transactions[4].Len = 1;
DCInit_transactions[4].Data[0] = 0xe0; //No Receive
//Wakeup UART slave devices
DCInit_transactions[5].Len = 2;
DCInit_transactions[5].Data[0] = 0x0e;
DCInit_transactions[5].Data[1] = 0x30;
//No Receive
//2ms delay for each slave to wake up
DCInit_transactions[6].Len = 2;
DCInit_transactions[6].Data[0] = 0x0f;
DCInit_transactions[6].Data[1] = 0x0; //Read Transaction 4 byte
//Wait for all UART slave devices to wake up
DCInit_transactions[7].Len = 2;
DCInit_transactions[7].Data[0] = 0x01;
DCInit_transactions[7].Data[1] = 0x0;
//Receive of 0x21 expected
//End of UART slave device wake-up period
DCInit_transactions[8].Len = 2;
DCInit_transactions[8].Data[0] = 0x0e;
DCInit_transactions[8].Data[1] = 0x10;
DCInit_transactions[9].Len = 2;
DCInit_transactions[9].Data[0] = 0x0f;
DCInit_transactions[9].Data[1] = 0x0; //Read Transaction 5 byte
//No Receive
//2ms delay for each slave to report null message
//Wait for null message to be received
DCInit_transactions[10].Len = 2;
DCInit_transactions[10].Data[0] = 0x01;
DCInit_transactions[10].Data[1] = 0x0;
//Receive 0x10 or 0x12
//Clear transmit buffer
DCInit_transactions[11].Len = 1;
DCInit_transactions[11].Data[0] = 0x20;
//No Receive
//Clear receive buffer
DCInit_transactions[12].Len = 1;
DCInit_transactions[12].Data[0] = 0xe0;
//No Receive
}
/**
* main.c
*/
int main(void)
{
static uint8_t noReceive = 0;
static uint8_t noInc = 0;
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
init_clock();
init_gpio(); // Set up IO pins
GPIO_setOutputHighOnPin(GPIO_PORT_P3, GPIO_PIN1);
// Configure SPI Pins for UCA1CLK, UCA1TXD/UCA1SIMO and UCA1RXD/UCA1SOMI
/*
* Select Port 2
* Set Pin 4, Pin 5 and Pin 6 to input Secondary Module Function
*/
GPIO_setAsPeripheralModuleFunctionInputPin(
GPIO_PORT_P2,
GPIO_PIN4 + GPIO_PIN5 + GPIO_PIN6,
GPIO_PRIMARY_MODULE_FUNCTION
);
// Set P1.0 to output direction
GPIO_setAsOutputPin (GPIO_PORT_P1, GPIO_PIN0);
GPIO_setAsInputPinWithPullUpResistor (GPIO_PORT_P4, GPIO_PIN2);
GPIO_enableInterrupt (GPIO_PORT_P4, GPIO_PIN2);
GPIO_selectInterruptEdge (GPIO_PORT_P4, GPIO_PIN2, GPIO_HIGH_TO_LOW_TRANSITION);
GPIO_clearInterrupt (GPIO_PORT_P4, GPIO_PIN2);
GPIO_setAsOutputPin (GPIO_PORT_P6, GPIO_PIN2);
PMM_unlockLPM5();
SetUpTransactions();
TXData = 0x0; // Holds transaction number
// Setup peripheral(s) now that gpio and clocks are setup
init_spi_peripheral(); // Init Maxim spi peripheral
GPIO_setOutputHighOnPin (GPIO_PORT_P6, GPIO_PIN2); //SHDNL held high for 4ms to ensure all slaves are powered on
__delay_cycles(64000);
while (TXData < 13){
noInc = 0;
GPIO_setOutputLowOnPin(GPIO_PORT_P3, GPIO_PIN1); //Maxim chip select low
__delay_cycles(1000); //idle time between CS change
for(SPI_TX_index = 0; SPI_TX_index < DCInit_transactions[TXData].Len; SPI_TX_index++){
while(!(UCA1IFG & UCTXIFG));
UCA1TXBUF = DCInit_transactions[TXData].Data[SPI_TX_index];
while (!(UCA1IFG & UCRXIFG));
RXData = UCA1RXBUF;
}
if ((TXData == 6) || (TXData == 9))
__delay_cycles(64000); //wait for slaves to wake up
if (TXData == 7){
if (RXData == 0x21){
TXData++;
noReceive = 0;
noInc = 1;
}
if (RXData != 0x21){
TXData = 7;
noReceive = 1;
}
}
if (TXData == 10){
if ((RXData == 0x10) || (RXData == 0x12)){
TXData++;
noReceive = 0;
noInc = 1;
}
else{
TXData = 10;
noReceive = 1;
}
}
if (!noReceive && !noInc){
TXData++;
}
if (TXData < 13){
GPIO_setOutputHighOnPin(GPIO_PORT_P3, GPIO_PIN1); //Maxim chip select high
__delay_cycles(1000); //idle time between CS change
}
}
}
//******************************************************************************
//
//This is the PORT2_VECTOR interrupt vector service routine
//
//******************************************************************************
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=PORT4_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(PORT2_VECTOR)))
#endif
void P4_ISR (void)
{
// GPIO_setOutputHighOnPin(GPIO_PORT_P3, GPIO_PIN1);
GPIO_clearInterrupt (GPIO_PORT_P4, GPIO_PIN2);
// Toggle P1.0 output
GPIO_toggleOutputOnPin (GPIO_PORT_P1, GPIO_PIN0);
GPIO_disableInterrupt (GPIO_PORT_P4, GPIO_PIN2);
GPIO_setOutputHighOnPin(GPIO_PORT_P3, GPIO_PIN1); //Maxim chip select high
}