Part Number: MSP432P401R
Other Parts Discussed in Thread: ADS131A02
Hi,
i am using the MSP432 to get 48kHz samples from the ADS131A02.
The problem is that the MSP432 is losing some interrupts and not reacting fast enought.
This is what i want to do: Get 48kHz samples via SPI and send it via UART to PC (FDTI chip)
So the problem is that the MSP432 is too slow to receive and send the samples:
Here is my code:
/*
* main.c
*/
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>
#include <ti/devices/msp432p4xx/inc/msp.h>
#include "ADS131A02.h"
#include "UART.h"
#define RX_TASKS 9
#define TX_TASKS 7
Timer_A_PWMConfig pwmConfig =
{
TIMER_A_CLOCKSOURCE_SMCLK,
TIMER_A_CLOCKSOURCE_DIVIDER_1,//8MHz= TIMER_A_CLOCKSOURCE_DIVIDER_3 4MHz=TIMER_A_CLOCKSOURCE_DIVIDER_6 2MHz=TIMER_A_CLOCKSOURCE_DIVIDER_12
2,
TIMER_A_CAPTURECOMPARE_REGISTER_1,
TIMER_A_OUTPUTMODE_TOGGLE_SET,
1
};
Timer_A_PWMConfig pwmConfig1 =
{
TIMER_A_CLOCKSOURCE_SMCLK,
TIMER_A_CLOCKSOURCE_DIVIDER_1,//8MHz= TIMER_A_CLOCKSOURCE_DIVIDER_3 4MHz=TIMER_A_CLOCKSOURCE_DIVIDER_6 2MHz=TIMER_A_CLOCKSOURCE_DIVIDER_12
1,
TIMER_A_CAPTURECOMPARE_REGISTER_1,
TIMER_A_OUTPUTMODE_TOGGLE_RESET,//TIMER_A_OUTPUTMODE_TOGGLE,
1
};
void main(void)
{
/* Halt watchdog timer */
MAP_WDT_A_holdTimer();
GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_PJ, GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);
CS_setExternalClockSourceFrequency(32768,48000000);
PCM_setCoreVoltageLevel(PCM_VCORE1);
FlashCtl_setWaitState(FLASH_BANK0, 2);
FlashCtl_setWaitState(FLASH_BANK1, 2);
CS_startHFXT(false);
CS_initClockSignal(CS_MCLK , CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);
CS_initClockSignal(CS_SMCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);// MHz
/* Configuring GPIO2.4 as peripheral output for PWM */
MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2, GPIO_PIN4,GPIO_PRIMARY_MODULE_FUNCTION);
MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5, GPIO_PIN6,GPIO_PRIMARY_MODULE_FUNCTION);
/* Configuring Timer_A */
MAP_Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig);
MAP_Timer_A_generatePWM(TIMER_A2_BASE, &pwmConfig1);
/*Power Up Board*/
MAP_GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN7);
MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN7);
ADS131A02_SPI_Setup();
ADS131A02_START();
UART_init_Communication();
while(1)
{
MAP_PCM_gotoLPM0();
}
}
/*
* ADS131A02.c
*/
#include "ADS131A02.h"
#include "UART.h"
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>
#include <stdio.h>
#include <string.h>
/* DMA Control Table */
/* DMA Control Table */
#pragma DATA_ALIGN(controlTable, 256)
uint8_t controlTable[256];
uint8_t DMA_recBuffer[9];
uint8_t DMA_sendBuffer[9];
int count_value=0;
uint8_t data_array[9]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
int adc_value=0;
int adc_value1=0;
#define DMATX DMA_CH2_EUSCIB1TX0
#define DMARX DMA_CH3_EUSCIB1RX0
#define DMATX_Channel 2
#define DMARX_Channel 3
void ADS131A02_SPI_Setup(void)
{
switch_data=0;
GPIO_setAsOutputPin(GPIO_PORT_P3, GPIO_PIN0);
GPIO_setAsOutputPin(GPIO_PORT_P3, GPIO_PIN6);
GPIO_setAsInputPin(GPIO_PORT_P3, GPIO_PIN2);
GPIO_setOutputHighOnPin(GPIO_PORT_P3, GPIO_PIN0); // CS Disable
GPIO_setOutputLowOnPin(GPIO_PORT_P3, GPIO_PIN6); // Reset Enable
// SPI Master Configuration Parameter
const eUSCI_SPI_MasterConfig spiMasterConfig =
{
EUSCI_A_SPI_CLOCKSOURCE_SMCLK, // SMCLK Clock Source
48000000, // SMCLK = HFXT = 48Mhz
24000000, // SPICLK =12000000
EUSCI_A_SPI_MSB_FIRST, // MSB First
EUSCI_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT, // Phase EUSCI_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT / EUSCI_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT
EUSCI_A_SPI_CLOCKPOLARITY_INACTIVITY_LOW, // High polarity
EUSCI_A_SPI_3PIN
};
GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P6, GPIO_PIN3 | GPIO_PIN4 | GPIO_PIN5 , GPIO_PRIMARY_MODULE_FUNCTION);
/* Configuring SPI in 4wire master mode */
SPI_initMaster(EUSCI_B1_BASE, &spiMasterConfig);
SPI_enableModule(EUSCI_B1_BASE);
/* Enable Interrupt */
GPIO_clearInterruptFlag(GPIO_PORT_P3, GPIO_PIN2);
GPIO_enableInterrupt(GPIO_PORT_P3, GPIO_PIN2);
GPIO_interruptEdgeSelect(GPIO_PORT_P3, GPIO_PIN2,GPIO_HIGH_TO_LOW_TRANSITION);//
SPI_clearInterruptFlag(EUSCI_B1_BASE, EUSCI_B_SPI_TRANSMIT_INTERRUPT);
}
void ADS131A02_CS_Disable(void)
{
GPIO_setOutputHighOnPin(GPIO_PORT_P3, GPIO_PIN0); // CS Disable
}
void ADS131A02_CS_Enable(void)
{
GPIO_setOutputLowOnPin(GPIO_PORT_P3, GPIO_PIN0); // CS Enable
}
void write_Command(uint16_t ADSregister)
{
uint8_t valueMSB=(ADSregister>>8)&0xFF;
uint8_t valueLSB=(ADSregister)&0xFF;
ADS131A02_CS_Enable();
__delay_cycles(10);
EUSCI_A_SPI_transmitData(EUSCI_B1_BASE,valueMSB);
EUSCI_A_SPI_transmitData(EUSCI_B1_BASE, valueLSB);
// EUSCI_A_SPI_transmitData(EUSCI_B1_BASE, 0x00);
ADS131A02_CS_Disable();
}
void write_register(uint8_t ADSregister,uint8_t ADSregisterValue)
{
ADS131A02_CS_Enable();
__delay_cycles(10);
EUSCI_A_SPI_transmitData(EUSCI_B1_BASE, (0x40 | ADSregister));
EUSCI_A_SPI_transmitData(EUSCI_B1_BASE, ADSregisterValue);
// EUSCI_A_SPI_transmitData(EUSCI_B1_BASE, 0x00);
ADS131A02_CS_Disable();
}
uint16_t read_register(uint8_t ADSregister)
{
uint16_t ret=0;
ADS131A02_CS_Enable();
EUSCI_A_SPI_transmitData(EUSCI_B1_BASE, (0x20 | ADSregister));
ret=EUSCI_A_SPI_receiveData(EUSCI_B1_BASE);
EUSCI_A_SPI_transmitData(EUSCI_B1_BASE, 0x00);
ret=ret<<8;
ret=ret | EUSCI_A_SPI_receiveData(EUSCI_B1_BASE);
//EUSCI_A_SPI_transmitData(EUSCI_B1_BASE, 0x00);
ADS131A02_CS_Disable();
return ret;
}
void ADS131A02_START(void)
{
GPIO_setOutputLowOnPin(GPIO_PORT_P3, GPIO_PIN6); // Reset
__delay_cycles(240000);
GPIO_setOutputHighOnPin(GPIO_PORT_P3, GPIO_PIN6); // Reset Disable
__delay_cycles(240000);
__delay_cycles(240000);
while(1)//(GPIO_getInputPinValue(GPIO_PORT_P7, GPIO_PIN0)!=0)
{
//wait until ready
write_Command(0x0000);
write_Command(UNLOCK);//UnLock Reg
uint16_t myValue=read_register(REG_STAT_1);
if(myValue!= 0xFF02)
break;
}
write_register(REG_CLK1,REG_CLK1_VALUE);//Set CLK1
write_register(REG_CLK2,REG_CLK2_VALUE);//Set CLK2
write_register(REG_A_SYS_CFG,REG_A_SYS_CFG_VALUE);//Set CLK2
write_register(REG_ADC1,REG_ADC1_VALUE);//GAIN ADC
write_register(REG_ADC2,REG_ADC2_VALUE);//GAIN ADC
write_register(REG_ADC_ENA,REG_ADC_ENA_VALUE);//Enbale ADC
//uint8_t myValue=read_register(REG_STAT_1);
write_Command(WAKEUP);//Wake ADC
write_Command(LOCK);//Lock Reg
ADS131A02_DMASetup();
}
void ADS131A02_DATA(void)
{
//READ Values
}
void ADS131A02_DMASetup(void)
{
//Assigning DMA to SPI Channels
DMA_enableModule();
DMA_setControlBase(controlTable);
DMA_assignChannel(DMATX);
DMA_assignChannel(DMARX);
// Disabling channel attributes
DMA_disableChannelAttribute(DMATX,UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |UDMA_ATTR_HIGH_PRIORITY |UDMA_ATTR_REQMASK);
DMA_disableChannelAttribute(DMARX,UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |UDMA_ATTR_HIGH_PRIORITY |UDMA_ATTR_REQMASK);
// Setup the TX transfer characteristics & buffers
DMA_setChannelControl (DMATX | UDMA_PRI_SELECT,UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_NONE | UDMA_ARB_1);
DMA_setChannelTransfer(DMATX | UDMA_PRI_SELECT,UDMA_MODE_BASIC, data_array,(void *) MAP_SPI_getTransmitBufferAddressForDMA(EUSCI_B1_BASE),6);
DMA_setChannelControl (DMARX | UDMA_PRI_SELECT,UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_1);
DMA_setChannelTransfer(DMARX | UDMA_PRI_SELECT,UDMA_MODE_BASIC,(void *) MAP_SPI_getReceiveBufferAddressForDMA(EUSCI_B1_BASE),data_array1,SIZE_BUFF_TX);
DMA_enableChannel(DMARX_Channel);
DMA_assignInterrupt(DMA_INT1, DMATX_Channel);
DMA_clearInterruptFlag(INT_DMA_INT1);
Interrupt_enableInterrupt(DMA_INT1);
DMA_assignInterrupt(DMA_INT2, DMARX_Channel);
DMA_clearInterruptFlag(INT_DMA_INT2);
Interrupt_enableInterrupt(DMA_INT2);
Interrupt_enableInterrupt(INT_PORT3);
Interrupt_enableMaster();
}
void DMA_INT2_IRQHandler(void)
{
ADS131A02_CS_Disable();
DMA_clearInterruptFlag(INT_DMA_INT2);
DMA_setChannelControl (DMARX | UDMA_PRI_SELECT,UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_1);
DMA_setChannelTransfer(DMARX | UDMA_PRI_SELECT,UDMA_MODE_BASIC,(void *) SPI_getReceiveBufferAddressForDMA(EUSCI_B1_BASE),data_array1,SIZE_BUFF_TX);
DMA_enableChannel(DMARX_Channel);
if(Flag_UART==1)
{
memcpy(zUI8_BUFF_TX, data_array1, sizeof(data_array1[0])*SIZE_BUFF_TX);
DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH0_EUSCIA0TX,UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_1);
DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH0_EUSCIA0TX, UDMA_MODE_BASIC, zUI8_BUFF_TX,(void*)UART_getTransmitBufferAddressForDMA(EUSCI_A0_BASE), SIZE_BUFF_TX);
DMA_enableChannel(0);
}
}
void DMA_INT1_IRQHandler(void)
{
DMA_clearInterruptFlag(INT_DMA_INT1);
ADS131A02_CS_Disable();
}
void PORT3_IRQHandler(void)
{
uint_fast16_t status = GPIO_getEnabledInterruptStatus(GPIO_PORT_P3);
GPIO_clearInterruptFlag(GPIO_PORT_P3, status);
if(status & GPIO_PIN2)
{
GPIO_clearInterruptFlag(GPIO_PORT_P3, GPIO_PIN2);
ADS131A02_CS_Enable();
DMA_SPI_TX();
}
}
void DMA_SPI_TX(void)
{
// Setup the TX transfer characteristics & buffers
DMA_setChannelControl (DMATX | UDMA_PRI_SELECT,UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_NONE | UDMA_ARB_1);
DMA_setChannelTransfer(DMATX | UDMA_PRI_SELECT,UDMA_MODE_BASIC, data_array,(void *) SPI_getTransmitBufferAddressForDMA(EUSCI_B1_BASE),6);
DMA_enableChannel(DMATX_Channel);
}
/*
* UART.c
*/
#include "UART.h"
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>
#include <string.h>
#include <stdio.h>
extern char Receive_UART[100]={};
void UART_DMASetup(void);
void UART_Send_OUT(char* read_buf);
uint8_t BufferRead[2] ={};
#define zCHAN_DMA_UART_TX DMA_CHANNEL_0
uint8_t wert_inc=0;
char UART_Wert;
//*****************************************************************************
// DMA Control Table
//*****************************************************************************
#ifdef ewarm
#pragma data_alignment=1024
#else
#pragma DATA_ALIGN(controlTable, 1024)
#endif
uint8_t controlTable[1024];
//*****************************************************************************
//
// 115200 Baudrate
//software-dl.ti.com/.../index.html
//*****************************************************************************
const eUSCI_UART_Config uartConfig =
{
EUSCI_A_UART_CLOCKSOURCE_SMCLK, // SMCLK Clock Source
26, // BRDIV = 26
0, // UCxBRF = 0
111, // UCxBRS = 111
EUSCI_A_UART_NO_PARITY, // No Parity
EUSCI_A_UART_LSB_FIRST, // LSB First
EUSCI_A_UART_ONE_STOP_BIT, // One stop bit
EUSCI_A_UART_MODE, // UART mode
EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION // Oversampling
};
//*****************************************************************************
//
//
//*****************************************************************************
void UART_init_Communication(void)
{
MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1, GPIO_PIN1 | GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);
MAP_UART_initModule(EUSCI_A0_BASE, &uartConfig);
MAP_UART_enableModule(EUSCI_A0_BASE);
MAP_UART_enableInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);
MAP_Interrupt_enableInterrupt(INT_EUSCIA0);
// Interrupt_disableSleepOnIsrExit();
//char info[]= "UART";
//UART_Send_OUT(info);
// memset(zUI8_BUFF_TX, 0x00, SIZE_BUFF_TX);
UART_DMASetup();
}
//*****************************************************************************
//
void UART_DMASetup(void)
{
//Assigning DMA to SPI Channels
//MAP_DMA_enableModule();
//MAP_DMA_setControlBase(controlTable);
MAP_DMA_assignChannel(DMA_CH0_EUSCIA0TX);
// Disabling channel attributes
MAP_DMA_disableChannelAttribute(DMA_CH0_EUSCIA0TX,UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |UDMA_ATTR_HIGH_PRIORITY |UDMA_ATTR_REQMASK);
MAP_DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH0_EUSCIA0TX,UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_1);
MAP_DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH0_EUSCIA0TX, UDMA_MODE_BASIC, zUI8_BUFF_TX,(void*)MAP_UART_getTransmitBufferAddressForDMA(EUSCI_A0_BASE), SIZE_BUFF_TX);
}
/**********************************************************************************************************
* void UART_DMA(void) *
**********************************************************************************************************/
void UART_DMA(void)
{
MAP_DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH0_EUSCIA0TX,UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_1);
MAP_DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH0_EUSCIA0TX, UDMA_MODE_BASIC, zUI8_BUFF_TX,(void*)MAP_UART_getTransmitBufferAddressForDMA(EUSCI_A0_BASE), SIZE_BUFF_TX);
MAP_DMA_enableChannel(0);
}
/**********************************************************************************************************
* void UART_Send_OUT(void) *
**********************************************************************************************************/
void UART_Send_OUT(char* read_buf)
{
int i;
for(i=0; i < strlen(read_buf) ; i++)
{
while (!(EUSCI_A_IFG_TXIFG & EUSCI_A0->IFG));
MAP_UART_transmitData(EUSCI_A0_BASE, read_buf[i]);
}
}
void COM(void)
{
if(strcmp(Receive_UART,"START") == 0)
{
Flag_UART=1;
}
else if(strcmp(Receive_UART,"STOP") == 0 || strcmp(Receive_UART,"STOPT") == 0)
{
Flag_UART=0;
}
memset(Receive_UART, 0x00, 100);
}
/*******************************************************************************
* EUSCI_A0_INT_BASE ISR. .
*******************************************************************************/
void EUSCIA0_IRQHandler(void)
{
uint32_t status = MAP_UART_getEnabledInterruptStatus(EUSCI_A0_BASE);
MAP_UART_clearInterruptFlag(EUSCI_A0_BASE, status);
if(status & EUSCI_A_UART_RECEIVE_INTERRUPT)
{
UART_Wert = UART_receiveData(EUSCI_A0_BASE);
if(UART_Wert == 10 || UART_Wert == 13 || UART_Wert == 58)
{
COM();
wert_inc=0;
}
else
{
if(UART_Wert != 0)
{
Receive_UART[wert_inc] = UART_Wert;
wert_inc++;
}
}
MAP_Interrupt_disableSleepOnIsrExit();
}
}
My question is how to increase performace on MSP432? Is it possible?
The problem is that the DMA TX always have to be reconfigured and Chip select must be enable/disable.
