Other Parts Discussed in Thread: DRV8838, DRV8838EVM,
Hi,
We are using MSP430G2131 on DRV8838EVM. We are using the provided DRV8838_CustomerEVM_Default_Code.c
//*****************************************************************************
// MSP430G2131 / DRV8837 Customer EVM Demo - Syncronous Rectification
//
// Description: This program operates MSP430 normally in LPM0 with WDT ISR
// used for system wake-up. Using DRV8838 Customer EVM PWM_SEL_IN open selects
// forward, closed selects reverse direction. Timer_A CCR1 drives in upmode,
// 5-bit PWM. PWM DutyCycle is measured using poti on ADC10_A0.
// LED is toggled in while()speed relative counting up LEDcounter.
// Forward Synchronous is defined as; ENABLE = modulated, PHASE = 1
// Reverse Synchronous is defined as; ENABLE = modulated, PHASE = 0
// ACLK = n/a, MCLK = TACLK = SMCLK = 1MHz calibrated DCO
// PWM frequency = TACLK/32 = 31.250Khz
//
// M. Kugele
// January 14, 2014
//******************************************************************************
#include "msp430g2131.h"
#define LED BIT1 // P1.1
#define PHASE BIT2 // P1.2
#define DIRECTION BIT3 // P1.3
#define ADC_VREF BIT4 // P1.4
#define ENABLE BIT6 // P2.6
unsigned int LEDcounter = 63; // Countdown timer for LED toggle
unsigned int DutyCycle; // 6-bit PWM duty cycle
int main(void)
{
WDTCTL = WDT_MDLY_8; // Set Watchdog Timer interval to ~30ms
IE1 |= WDTIE; // Enable WDT interrupt
BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz
DCOCTL = CALDCO_1MHZ;
P1OUT = 0x00; // P1.x Reset
P1DIR = 0xF6; // P1.3,0 inputs, else outputs
P2OUT = 0x00; // P2.x reset
P2SEL = 0x00; // P2.x no options
P2DIR = 0xFF; // P2.x outputs
P1SEL &= ~PHASE; // Make sure P1.2 peripheral functionality is disabled
P2SEL = ENABLE; // Select secondary functionality on P2.6, tying it to TA0.1
CCTL1 = OUTMOD_7; // CCR1 in set/reset mode
CCR1 = 0; // CCR1 Duty cycle to 0%
CCR0 = 64 - 1; // 6-bit PWM period
TACTL = TASSEL_2 + MC_1; // SCLK source, up mode
ADC10CTL0 = ADC10SHT_2 + ADC10ON; // VCC ref
ADC10AE0 |= INCH_0; // P1.0 ADC option select
while(1)
{
_BIS_SR(LPM0_bits + GIE); // Enter LPM0 with interrupts
P1OUT |= ADC_VREF; // Enable poti divider
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
while (ADC10IFG & ADC10CTL0); // Wait for conversion complete
ADC10CTL0 &= ~ADC10IFG; // Clear converstion flag
P1OUT &= ~ADC_VREF; // Disable poti divider
DutyCycle = 63 - (ADC10MEM>>4); // Mask upper 6-bits
CCR1 = DutyCycle; // PWM duty cycle to DRV
if (DIRECTION & P1IN) // Forward direction?
{
P1OUT |= PHASE;
}
else // Reverse
{
P1OUT &= ~PHASE;
}
if(DutyCycle >= 5)
{
LEDcounter--;
if(LEDcounter <= DutyCycle)
{
P1OUT ^= LED; // Toggle LED
LEDcounter = 63; // Reset LED Counter
}
}
}
}
// Watchdog Timer interrupt service routine
#pragma vector=WDT_VECTOR
__interrupt void watchdog_timer(void)
{
_BIC_SR_IRQ(LPM3_bits); // Clear LPM0 bits from 0(SR)
}
In addition to the above code, we have established basic SPI communication with MSP430G2131 acting as a SPI slave.
Below is our code:
#include <msp430.h>
#include "msp430g2131.h"
#define LED BIT1 // P1.1
#define PHASE BIT2 // P1.2
#define DIRECTION BIT3 // P1.3
#define ADC_VREF BIT4 // P1.4
#define ENABLE BIT6 // P2.6
unsigned int LEDcounter = 63; // Countdown timer for LED toggle
unsigned int DutyCycle; // 6-bit PWM duty cycle
int main(void)
{
WDTCTL = WDT_MDLY_8; // Set Watchdog Timer interval to ~30ms
IE1 |= WDTIE; // Enable WDT interrupt
BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz
DCOCTL = CALDCO_1MHZ;
P1OUT = 0x00; // P1.x Reset
// P1DIR = 0xF6; // P1.3,0 inputs, else outputs
P1DIR = 0x56;
P2OUT = 0x00; // P2.x reset
P2SEL = 0x00; // P2.x no options
P2DIR = 0xFF; // P2.x outputs
P1SEL &= ~PHASE; // Make sure P1.2 peripheral functionality is disabled
P2SEL = ENABLE; // Select secondary functionality on P2.6, tying it to TA0.1
CCTL1 = OUTMOD_7; // CCR1 in set/reset mode
CCR1 = 0; // CCR1 Duty cycle to 0%
CCR0 = 64 - 1; // 6-bit PWM period
TACTL = TASSEL_2 + MC_1; // SCLK source, up mode
ADC10CTL0 = ADC10SHT_2 + ADC10ON; // VCC ref
ADC10AE0 |= INCH_0; // P1.0 ADC option select
USICTL0 |= USIPE7 + USIPE6 + USIPE5 + USIOE; // Port, SPI slave
USICTL1 |= USIIE; // Counter interrupt, flag remains set
USICTL0 &= ~USISWRST; // USI released for operation
// USISRL = P1IN; // init-load data
USICNT = 8; // init-load counter
// __bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupt
while(1)
{
_BIS_SR(LPM0_bits + GIE); // Enter LPM0 with interrupts
P1OUT |= ADC_VREF; // Enable poti divider
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
while (ADC10IFG & ADC10CTL0); // Wait for conversion complete
ADC10CTL0 &= ~ADC10IFG; // Clear converstion flag
P1OUT &= ~ADC_VREF; // Disable poti divider
DutyCycle = 63 - (ADC10MEM>>4); // Mask upper 6-bits
CCR1 = DutyCycle; // PWM duty cycle to DRV
if (DIRECTION & P1IN) // Forward direction?
{
P1OUT |= PHASE;
}
else // Reverse
{
P1OUT &= ~PHASE;
}
if(DutyCycle >= 5)
{
LEDcounter--;
if(LEDcounter <= DutyCycle)
{
P1OUT ^= LED; // Toggle LED
LEDcounter = 63; // Reset LED Counter
}
}
}
}
// Watchdog Timer interrupt service routine
#pragma vector=WDT_VECTOR
__interrupt void watchdog_timer(void)
{
_BIC_SR_IRQ(LPM3_bits); // Clear LPM0 bits from 0(SR)
}
// USI interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USI_VECTOR
__interrupt void universal_serial_interface(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USI_VECTOR))) universal_serial_interface (void)
#else
#error Compiler not supported!
#endif
{
USISRL = USISRL + 0x01;
USICNT = 8; // re-load counter
}
However, we are aiming to read the data from the ADC10MEM register and transfer it to the master. We tried copying the contents of the ADC10MEM register to USISRL and transfer the data through SPI. But the transferred data is not right as MSP430G2131 keeps sending random values that sometimes repeat, sometimes don't.
We also tried converting the data from ADC10MEM register to integer before transferring it, but this gives errors/ wrong output.
Any assistance on this issue will be appreciated.
Piyusha