This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Baremetal - Beaglebone SPI interface - ADC - trouble getting code working correctly / stable outputs (CS / SPI_DATA / SPI_CLK)

Other Parts Discussed in Thread: SYSBIOS

Hello,

I'm working on a project involving a SPI interface between an ADC (AD7606) and a Beaglebone Black and I'm having a lot of trouble getting a stable output for the different signals coming from the BBB. 

I've done all the different steps correctly and I don't understand why the whole thing isn't working..

I used StarterWare's McSPI to build my program, taking in account that not all functions are supported/described for the BBB.

Here is a copy of my main code, if someone could help it would be great, I tried a lot of things but the result is still not convenient.

***************************************************************************************************************************************************************

/* Include the necessary header files */
#include "consoleUtils.h"
#include "soc_AM335x.h"
#include "beaglebone.h"
#include "interrupt.h"
#include "hw_types.h"
#include "mcspi.h"
#include "error.h"
#include "gpio_v2.h"
#include "hw_control_AM335x.h"
#include "hw_cm_per.h"
#include "hw_types.h"

/* EVM Profile setting for McSPI */
#define MCSPI_EVM_PROFILE (2)


unsigned int profile = 0;
int status = E_INST_NOT_SUPP;


/******************************************************************************
** INTERNAL MACRO DEFINITIONS
******************************************************************************/
#define GPIO_INSTANCE_ADDRESS (SOC_GPIO_1_REGS)
#define FLASH_WRITE_IN_PROGRESS (0x01u)
#define FLASH_SECTOR_ADD_HIGH (0x3Fu)
#define FLASH_SECTOR_ADD_LOW (0x00u)
#define FLASH_SECTOR_ADD_MID (0x00u)
#define FLASH_READ_STAT_REG1 (0x05u)
#define FLASH_WRITE_ENABLE (0x06u)
#define FLASH_SECTOR_ERASE (0x20u)
#define FLASH_PAGE_PROGRAM (0x02u)
#define FLASH_DUMMY_BYTE (0xFFu)
#define FLASH_DATA_READ (0x03u)
#define MCSPI_OUT_FREQ (1200000u)
#define MCSPI_IN_CLK (48000000u)

/******************************************************************************
** INTERNAL FUNCTION PROTOTYPES
******************************************************************************/
static unsigned int IsWriteSuccess(void);
static void McSPI0AintcConfigure(void);
static void FlashStatusGet(void);
static void ReadFromFlash(void);
static void McSPITransfer(void);
static void WriteToFlash(void);
static void WriteEnable(void);
static void SectorErase(void);
static void IsFlashBusy(void);
static void McSPISetUp(void);
static void VerifyData(void);
static void McSPIIsr(void);
static void Delay(unsigned int count);


/******************************************************************************
** GLOBAL VARIABLE DEFINITIONS
******************************************************************************/
volatile unsigned int flag = 1;
unsigned char rxBuffer[260];
unsigned char vrfyData[256];
unsigned int length = 0;
unsigned int chNum = 0;
unsigned char *p_rx;
unsigned char txBuffer[260];
unsigned char *p_tx;

/******************************************************************************
** INTERNAL FUNCTION DEFINITIONS
******************************************************************************/
int main(void)
{
volatile unsigned int count = 0x0FFFu;
unsigned char choice = 0;

/* Enable the clocks for GPIO module.*/

GPIO1ModuleClkConfig();

/* Enabling the GPIO module. */

GPIOModuleEnable(GPIO_INSTANCE_ADDRESS);

/* Resetting the GPIO module. */

GPIOModuleReset(GPIO_INSTANCE_ADDRESS);

/* Setting the GPIO pin as an output pin. */

GPIODirModeSet(GPIO_INSTANCE_ADDRESS,2,GPIO_DIR_OUTPUT); // CONVST Signal
GPIODirModeSet(GPIO_INSTANCE_ADDRESS,3,GPIO_DIR_OUTPUT); // ADC_RESET
GPIODirModeSet(GPIO_INSTANCE_ADDRESS,7,GPIO_DIR_OUTPUT); // ADC_STDBY

GPIOPinWrite(GPIO_INSTANCE_ADDRESS, 2, GPIO_PIN_HIGH);
GPIOPinWrite(GPIO_INSTANCE_ADDRESS, 3, GPIO_PIN_LOW);

// McSPI0ModuleClkConfig();

HWREG(SOC_CM_PER_REGS + CM_PER_L3S_CLKSTCTRL) =
CM_PER_L3S_CLKSTCTRL_CLKTRCTRL_SW_WKUP;

while((HWREG(SOC_CM_PER_REGS + CM_PER_L3S_CLKSTCTRL) &
CM_PER_L3S_CLKSTCTRL_CLKTRCTRL) != CM_PER_L3S_CLKSTCTRL_CLKTRCTRL_SW_WKUP);

HWREG(SOC_CM_PER_REGS + CM_PER_L3_CLKSTCTRL) =
CM_PER_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP;

while((HWREG(SOC_CM_PER_REGS + CM_PER_L3_CLKSTCTRL) &
CM_PER_L3_CLKSTCTRL_CLKTRCTRL) != CM_PER_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP);

HWREG(SOC_CM_PER_REGS + CM_PER_L3_INSTR_CLKCTRL) =
CM_PER_L3_INSTR_CLKCTRL_MODULEMODE_ENABLE;

while((HWREG(SOC_CM_PER_REGS + CM_PER_L3_INSTR_CLKCTRL) &
CM_PER_L3_INSTR_CLKCTRL_MODULEMODE) !=
CM_PER_L3_INSTR_CLKCTRL_MODULEMODE_ENABLE);

HWREG(SOC_CM_PER_REGS + CM_PER_L3_CLKCTRL) =
CM_PER_L3_CLKCTRL_MODULEMODE_ENABLE;

while((HWREG(SOC_CM_PER_REGS + CM_PER_L3_CLKCTRL) &
CM_PER_L3_CLKCTRL_MODULEMODE) != CM_PER_L3_CLKCTRL_MODULEMODE_ENABLE);

HWREG(SOC_CM_PER_REGS + CM_PER_OCPWP_L3_CLKSTCTRL) =
CM_PER_OCPWP_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP;

while((HWREG(SOC_CM_PER_REGS + CM_PER_OCPWP_L3_CLKSTCTRL) &
CM_PER_OCPWP_L3_CLKSTCTRL_CLKTRCTRL) !=
CM_PER_OCPWP_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP);

HWREG(SOC_CM_PER_REGS + CM_PER_L4LS_CLKSTCTRL) =
CM_PER_L4LS_CLKSTCTRL_CLKTRCTRL_SW_WKUP;

while((HWREG(SOC_CM_PER_REGS + CM_PER_L4LS_CLKSTCTRL) &
CM_PER_L4LS_CLKSTCTRL_CLKTRCTRL) !=
CM_PER_L4LS_CLKSTCTRL_CLKTRCTRL_SW_WKUP);

HWREG(SOC_CM_PER_REGS + CM_PER_L4LS_CLKCTRL) =
CM_PER_L4LS_CLKCTRL_MODULEMODE_ENABLE;

while((HWREG(SOC_CM_PER_REGS + CM_PER_L4LS_CLKCTRL) &
CM_PER_L4LS_CLKCTRL_MODULEMODE) != CM_PER_L4LS_CLKCTRL_MODULEMODE_ENABLE);

HWREG(SOC_CM_PER_REGS + CM_PER_SPI0_CLKCTRL) &= ~CM_PER_SPI0_CLKCTRL_MODULEMODE;

HWREG(SOC_CM_PER_REGS + CM_PER_SPI0_CLKCTRL) |=
CM_PER_SPI0_CLKCTRL_MODULEMODE_ENABLE;

while((HWREG(SOC_CM_PER_REGS + CM_PER_SPI0_CLKCTRL) &
CM_PER_SPI0_CLKCTRL_MODULEMODE) != CM_PER_SPI0_CLKCTRL_MODULEMODE_ENABLE);

while(!(HWREG(SOC_CM_PER_REGS + CM_PER_L3S_CLKSTCTRL) &
CM_PER_L3S_CLKSTCTRL_CLKACTIVITY_L3S_GCLK));

while(!(HWREG(SOC_CM_PER_REGS + CM_PER_L3_CLKSTCTRL) &
CM_PER_L3_CLKSTCTRL_CLKACTIVITY_L3_GCLK));

while(!(HWREG(SOC_CM_PER_REGS + CM_PER_OCPWP_L3_CLKSTCTRL) &
(CM_PER_OCPWP_L3_CLKSTCTRL_CLKACTIVITY_OCPWP_L3_GCLK |
CM_PER_OCPWP_L3_CLKSTCTRL_CLKACTIVITY_OCPWP_L4_GCLK)));

while(!(HWREG(SOC_CM_PER_REGS + CM_PER_L4LS_CLKSTCTRL) &
(CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_L4LS_GCLK |
CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_SPI_GCLK)));

//McSPIPinMuxSetup(0);

HWREG(SOC_CONTROL_REGS + CONTROL_CONF_SPI0_SCLK) =
(CONTROL_CONF_SPI0_SCLK_CONF_SPI0_SCLK_PUTYPESEL |
CONTROL_CONF_SPI0_SCLK_CONF_SPI0_SCLK_RXACTIVE);
HWREG(SOC_CONTROL_REGS + CONTROL_CONF_SPI0_D0) =
(CONTROL_CONF_SPI0_SCLK_CONF_SPI0_SCLK_PUTYPESEL |
CONTROL_CONF_SPI0_SCLK_CONF_SPI0_SCLK_RXACTIVE);
HWREG(SOC_CONTROL_REGS + CONTROL_CONF_SPI0_D1) =
(CONTROL_CONF_SPI0_SCLK_CONF_SPI0_SCLK_PUTYPESEL |
CONTROL_CONF_SPI0_SCLK_CONF_SPI0_SCLK_RXACTIVE);

/* chip select mux*/

HWREG(SOC_CONTROL_REGS + CONTROL_CONF_SPI0_CS0) =
(CONTROL_CONF_SPI0_SCLK_CONF_SPI0_SCLK_PUTYPESEL |
CONTROL_CONF_SPI0_SCLK_CONF_SPI0_SCLK_RXACTIVE);

/* Do the necessary set up configurations for McSPI.*/

McSPISetUp();

ConsoleUtilsPrintf("Here the McSPI controller on the SoC");
ConsoleUtilsPrintf(" communicates with the SPI Flash.\r\n\r\n", -1);

/* Enable IRQ in CPSR.*/

IntMasterIRQEnable();

/* Map McSPI Interrupts to AINTC */

McSPI0AintcConfigure();
ConsoleUtilsPrintf(" McSPI0AintcConfigure\r\n\r\n", -1);

ConsoleUtilsPrintf(" McSPISetUp\r\n\r\n", -1);

/* STDBY -> FullShutdown Mode */

GPIOPinWrite(GPIO_INSTANCE_ADDRESS, 7, GPIO_PIN_HIGH);
Delay(0xFFF);
GPIOPinWrite(GPIO_INSTANCE_ADDRESS, 7, GPIO_PIN_LOW);
Delay(0xF);
GPIOPinWrite(GPIO_INSTANCE_ADDRESS, 7, GPIO_PIN_HIGH);

/* RST_AD */

Delay(0xFF);
GPIOPinWrite(GPIO_INSTANCE_ADDRESS, 3, GPIO_PIN_HIGH);
Delay(0xF);
GPIOPinWrite(GPIO_INSTANCE_ADDRESS, 3, GPIO_PIN_LOW);
Delay(0xF);


/* Pass the write enable command to flash.*/

WriteEnable();
ConsoleUtilsPrintf(" WriteEnable\r\n\r\n", -1);
/* Wait until write enable command is successfully written to flash.*/
while(FALSE == IsWriteSuccess());

/* Write data of 1 page size to flash.*/

WriteToFlash();

while(count--);
count = 0x0FFFu;

/* Read data of 1 page size from flash.*/

ReadFromFlash();
while(count--);

/* Verify the data written to and read from flash are same or not.*/

VerifyData();

while(1);
}

/***************************************************************************************************

FUNCTIONS USED IN THE MAIN PROGRAM

***************************************************************************************************/

/* Interrupt mapping to AINTC and registering McSPI ISR */
static void McSPI0AintcConfigure(void)
{
/* Initialze ARM interrupt controller */
IntAINTCInit();

/* Register McSPIIsr interrupt handler */
IntRegister(SYS_INT_SPI0INT, McSPIIsr);

/* Set Interrupt Priority */
IntPrioritySet(SYS_INT_SPI0INT, 0, AINTC_HOSTINT_ROUTE_IRQ);

/* Enable system interrupt in AINTC */
IntSystemEnable(SYS_INT_SPI0INT);
}

/*
** This function will write data of 1 page size on to a page of a specific
** sector.
*/
static void WriteToFlash(void)
{
unsigned int index = 0;

txBuffer[0] = FLASH_PAGE_PROGRAM;
txBuffer[1] = FLASH_SECTOR_ADD_HIGH;
txBuffer[2] = FLASH_SECTOR_ADD_MID;
txBuffer[3] = FLASH_SECTOR_ADD_LOW;

for(index = 0; index < 256; index++)
{
txBuffer[index + 4] = (unsigned char) index;
vrfyData[index] = (unsigned char) index;
}

length = 260;

McSPITransfer();
}

/*
** This function will verify the data written to and read from flash and print
** the appropriate message.
*/
static void VerifyData(void)
{
unsigned int index = 0;

for(index = 4; index < 260; index++)
{
if(rxBuffer[index] != vrfyData[index - 4])
{
ConsoleUtilsPrintf("\r\n");
ConsoleUtilsPrintf("VerifyData: Comparing the data");
ConsoleUtilsPrintf(" written to and read");
ConsoleUtilsPrintf(" from Flash.\r\nThe two data blocks are");
ConsoleUtilsPrintf(" unequal. Mismatch found at index ", -1);
ConsoleUtilsPrintf("%d", index);
ConsoleUtilsPrintf("\r\n", -1);

break;
}
}

if(260 == index)
{
ConsoleUtilsPrintf("\r\nThe data in the Flash and the one", -1);
ConsoleUtilsPrintf(" written to it are equal.\r\n", -1);

}
}

/*
** This function will read data of 1 page size from a specific sector of flash.
*/
static void ReadFromFlash(void)
{
unsigned int index = 0;

txBuffer[0] = FLASH_DATA_READ;
txBuffer[1] = FLASH_SECTOR_ADD_HIGH;
txBuffer[2] = FLASH_SECTOR_ADD_MID;
txBuffer[3] = FLASH_SECTOR_ADD_LOW;

for(index = 4; index < 260; index++)
{
txBuffer[index] = 0;
}

length = 260;

McSPITransfer();
}

/*
** This function will check whether the write enable command is successfully
** latched on to flash or not.
*/
static unsigned int IsWriteSuccess(void)
{
unsigned int retVal = FALSE;

txBuffer[0] = FLASH_READ_STAT_REG1;
txBuffer[1] = FLASH_DUMMY_BYTE;

length = 2;

McSPITransfer();

if(0x02 == rxBuffer[1])
{
retVal = TRUE;
}

return retVal;

return true;
}

/*
** This function will send the write enable command to the flash device.
*/
static void WriteEnable(void)
{
txBuffer[0] = FLASH_WRITE_ENABLE;

length = 1;

McSPITransfer();
}

/*
** This function will activate/deactivate CS line and also enable Tx and Rx
** interrupts of McSPI peripheral.
*/
static void McSPITransfer(void)
{
p_tx = txBuffer;
p_rx = rxBuffer;

/* SPIEN line is forced to low state.*/
McSPICSAssert(SOC_SPI_0_REGS, chNum);

/* CONVST*/
GPIOPinWrite(GPIO_INSTANCE_ADDRESS, 2, GPIO_PIN_LOW);
Delay(0x1F);
GPIOPinWrite(GPIO_INSTANCE_ADDRESS, 2, GPIO_PIN_HIGH);

/* Enable the Tx/Rx interrupts of McSPI.*/
McSPIIntEnable(SOC_SPI_0_REGS, MCSPI_INT_TX_EMPTY(chNum) | MCSPI_INT_RX_FULL(chNum));

/* Enable the McSPI channel for communication.*/
McSPIChannelEnable(SOC_SPI_0_REGS, chNum);

/* Wait until control returns back from McSPI ISR.*/
while(flag);

flag = 1;

/* Force SPIEN line to the inactive state.*/
McSPICSDeAssert(SOC_SPI_0_REGS, chNum);

/* Disable the McSPI channel.*/
McSPIChannelDisable(SOC_SPI_0_REGS, chNum);
}

/*
** This function will erase a sector of flash.
*/
static void SectorErase(void)
{
txBuffer[0] = FLASH_SECTOR_ERASE;
txBuffer[1] = FLASH_SECTOR_ADD_HIGH;
txBuffer[2] = FLASH_SECTOR_ADD_MID;
txBuffer[3] = FLASH_SECTOR_ADD_LOW;

length = 4;

McSPITransfer();

IsFlashBusy();
}

/*
** This function will send the flash status register bits on to the receive
** buffer.
*/
static void FlashStatusGet(void)
{
txBuffer[0] = FLASH_READ_STAT_REG1;
txBuffer[1] = 0xFF;

length = 2;

McSPITransfer();

}

/*
** This function will check whether write enable command is still in progress
** or not.
*/
static void IsFlashBusy(void)
{
do{
FlashStatusGet();
} while(rxBuffer[1] & FLASH_WRITE_IN_PROGRESS);

}

/*
** This function will call the necessary McSPI APIs which will configure the
** McSPI controller.
*/
static void McSPISetUp(void)
{

/* Reset the McSPI instance.*/
McSPIReset(SOC_SPI_0_REGS);

/* Enable chip select pin.*/
McSPICSEnable(SOC_SPI_0_REGS);

/* Enable master mode of operation.*/
McSPIMasterModeEnable(SOC_SPI_0_REGS);

/* Perform the necessary configuration for master mode.*/
McSPIMasterModeConfig(SOC_SPI_0_REGS, MCSPI_MULTI_CH,
MCSPI_TX_RX_MODE, MCSPI_DATA_LINE_COMM_MODE_0,
chNum);

/* Configure the McSPI bus clock depending on clock mode. */
McSPIClkConfig(SOC_SPI_0_REGS, MCSPI_IN_CLK, MCSPI_OUT_FREQ, chNum,
MCSPI_CLK_MODE_0);

/* Configure the word length.*/
McSPIWordLengthSet(SOC_SPI_0_REGS, MCSPI_WORD_LENGTH(16), chNum);

/* Set polarity of SPIEN to low.*/
McSPICSPolarityConfig(SOC_SPI_0_REGS, MCSPI_CS_POL_LOW, chNum);

/* Enable the transmitter FIFO of McSPI peripheral.*/
McSPITxFIFOConfig(SOC_SPI_0_REGS, MCSPI_TX_FIFO_ENABLE, chNum);

/* Enable the receiver FIFO of McSPI peripheral.*/
McSPIRxFIFOConfig(SOC_SPI_0_REGS, MCSPI_RX_FIFO_ENABLE, chNum);
}

/*
** McSPI Interrupt Service Routine. This function will clear the status of the
** Tx/Rx interrupts when generated. Will write the Tx data on transmit data
** register and also will put the received data from receive data register to
** a location in memory.
*/
static void McSPIIsr(void)
{
unsigned int intCode = 0;

intCode = McSPIIntStatusGet(SOC_SPI_0_REGS);

while(intCode)
{
if(MCSPI_INT_TX_EMPTY(chNum) == (intCode & MCSPI_INT_TX_EMPTY(chNum)))
{
McSPIIntStatusClear(SOC_SPI_0_REGS, MCSPI_INT_TX_EMPTY(chNum));

length--;

McSPITransmitData(SOC_SPI_0_REGS,(unsigned int)(*p_tx++), chNum);

if(!length)
{
McSPIIntDisable(SOC_SPI_0_REGS, MCSPI_INT_TX_EMPTY(chNum));

McSPIIntStatusClear(SOC_SPI_0_REGS, MCSPI_INT_TX_EMPTY(chNum));
}
}

if(MCSPI_INT_RX_FULL(chNum) == (intCode & MCSPI_INT_RX_FULL(chNum)))
{
McSPIIntStatusClear(SOC_SPI_0_REGS, MCSPI_INT_RX_FULL(chNum));

*p_rx++ = (unsigned char) McSPIReceiveData(SOC_SPI_0_REGS, chNum);

if(!(length))
{
McSPIIntDisable(SOC_SPI_0_REGS, MCSPI_INT_RX_FULL(chNum));

flag = 0;
}
}

intCode = McSPIIntStatusGet(SOC_SPI_0_REGS);
}
}
static void Delay(volatile unsigned int count)
{
while(count--);
}
/********************************* End Of File ******************************/

Thanks by advance to who ever could help me,

Cedric.

RESET