Hi
I believe that I've looked through all relevant posts already as well as read relevant chapters of the TRM, but I'm stuck.
I'm using the IDK base board as a starting point to start some software development while waiting for the guys to finish our own hardware. I've taken the daughter board off as I needed access to pins more than I needed the stuff on this board, at least for now.
I'm trying to get SPI1 working as a master transmitter to begin with.
I'm stuck working in IAR EWARM with board support files supplied by Micro Digital for their smx RTOS, so I cannot reference starterware functions and definitions.
My SPI1_Init function sets up clocks and pins.
Resets the SPI1 module and configures it. All this can be seen below
#define MODULEMODE (0x03u)
#define MODULEMODE_ENABLE (0x02u)
#define MODULECTRL (0x03u)
#define MODULECTRL_WKUP (0x02u)
void SPI1_ModuleClkConfig(void)
{
/* Configuring L4 Interface Clocks. */
/* Writing to CLKTRCTRL field of CM_PER_L3S_CLKSTCTRL register. */
CM_PER_L3S_CLKSTCTRL = MODULECTRL_WKUP;
/*Waiting for CLKTRCTRL field to reflect the written value. */
while((CM_PER_L3S_CLKSTCTRL & MODULECTRL) != MODULECTRL_WKUP);
/* Writing to CLKTRCTRL field of CM_PER_L3_CLKSTCTRL register. */
CM_PER_L3_CLKSTCTRL = MODULECTRL_WKUP;
/* Waiting for CLKTRCTRL field to reflect the written value. */
while((CM_PER_L3_CLKSTCTRL & MODULECTRL) != MODULECTRL_WKUP);
/* Writing to MODULEMODE field of CM_PER_L3_INSTR_CLKCTRL register. */
CM_PER_L3_INSTR_CLKCTRL = MODULEMODE_ENABLE;
/* Waiting for MODULEMODE field to reflect the written value. */
while((CM_PER_L3_INSTR_CLKCTRL & MODULEMODE) != MODULEMODE_ENABLE);
/* Writing to MODULEMODE field of CM_PER_L3_CLKCTRL register. */
CM_PER_L3_CLKCTRL = MODULEMODE_ENABLE;
/* Waiting for MODULEMODE field to reflect the written value. */
while((CM_PER_L3_CLKCTRL & MODULEMODE) != MODULEMODE_ENABLE);
/* Writing to CLKTRCTRL field of CM_PER_OCPWP_L3_CLKSTCTRL register. */
CM_PER_OCPWP_L3_CLKSTCTRL = MODULECTRL_WKUP;
/*Waiting for CLKTRCTRL field to reflect the written value. */
while((CM_PER_OCPWP_L3_CLKSTCTRL & MODULECTRL) != MODULECTRL_WKUP);
CM_PER_L4LS_CLKSTCTRL = MODULECTRL_WKUP;
while((CM_PER_L4LS_CLKSTCTRL & MODULECTRL) != MODULECTRL_WKUP);
CM_PER_L4LS_CLKCTRL = MODULEMODE_ENABLE;
while((CM_PER_L4LS_CLKCTRL & MODULEMODE) != MODULEMODE_ENABLE);
CM_PER_SPI1_CLKCTRL &= ~MODULEMODE;
CM_PER_SPI1_CLKCTRL |= MODULEMODE_ENABLE;
while((CM_PER_SPI1_CLKCTRL & MODULEMODE) != MODULEMODE_ENABLE);
/* Checking fields for necessary values. */
// wait until all wakeups are done and clks are active
while(!(CM_PER_L3S_CLKSTCTRL & 0x08u));
while(!(CM_PER_L3_CLKSTCTRL & 0x10u));
while(!(CM_PER_OCPWP_L3_CLKSTCTRL & (0x10u | 0x20u)));
while(!(CM_PER_L4LS_CLKSTCTRL & (0x100u | 0x02000000u)));
}
void SPI1_ModulePinConfig(void)
{
/* Set pins multiplexing for SPI1 */
//SPICLK: receiver enabled, pullup selected and enabled, mode 3
CONF_MCASP0_ACLKX = 0x33;
//SPID0 MISO: receiver enabled, pullup selected and enabled, mode 3
CONF_MCASP0_FSX = 0x33;
//SPID1 MOSI: receiver enabled, pullup selected and enabled, mode 3
CONF_MCASP0_AXR0 = 0x33;
//SPICS0: receiver enabled, pullup selected and enabled, mode 2
CONF_RMII1_REFCLK = 0x32;
//SPICS1: receiver enabled, pullup selected and enabled, mode 2
CONF_ECAP0_IN_PWM0_OUT = 0x32;
}
/**
* \brief This API will reset the McSPI peripheral.
*
*
* \return none.
**/
#define MCSPI_SYSCONFIG_SOFTRESET (0x02u)
#define MCSPI_SYSSTATUS_RESETDONE_COMPLETED (0x01u)
void SPI1_Reset(void)
{
/* Set the SOFTRESET field of MCSPI_SYSCONFIG register. */
MCSPI1_SYSCONFIG |= MCSPI_SYSCONFIG_SOFTRESET;
/* Stay in the loop until reset is done. */
while(!(MCSPI_SYSSTATUS_RESETDONE_COMPLETED & MCSPI1_SYSSTATUS));
}
void SPI1_Init(void){
//set up clk
SPI1_ModuleClkConfig();
//set up pins
SPI1_ModulePinConfig();
//reset
SPI1_Reset();
//set to master single channel mode
MCSPI1_MODULCTRL = 0x03;
//see pp 4593 in SPRUH73i
MCSPI1_CH0CONF_bit.PHA = 0;
MCSPI1_CH0CONF_bit.POL = 0;
MCSPI1_CH0CONF_bit.CLKD = 0xF;
MCSPI1_CH0CONF_bit.EPOL = 1;
MCSPI1_CH0CONF_bit.WL = 7;
MCSPI1_CH0CONF_bit.TRM = 2; //2 Tx only, 0 Tx and Rx
MCSPI1_CH0CONF_bit.DMAW = 0;//tx dma
MCSPI1_CH0CONF_bit.DMAR = 0;
MCSPI1_CH0CONF_bit.DPE0 = 1;
MCSPI1_CH0CONF_bit.DPE1 = 0;
MCSPI1_CH0CONF_bit.IS = 0;
MCSPI1_CH0CONF_bit.TURBO = 1;
MCSPI1_CH0CONF_bit.FORCE = 0;
MCSPI1_CH0CONF_bit.SPIENSLV = 0;
MCSPI1_CH0CONF_bit.SBE = 0;
MCSPI1_CH0CONF_bit.SBPOL = 0;
MCSPI1_CH0CONF_bit.TCS = 0;
MCSPI1_CH0CONF_bit.FFEW = 1;
MCSPI1_CH0CONF_bit.FFER = 0;
MCSPI1_CH0CONF_bit.CLKG = 0;
//set FIFO Level
MCSPI1_XFERLEVEL = 31; //IRQ when there's this much room (n+1) in FIFO
//clear all pending IRQs
MCSPI1_IRQSTATUS = 0x2777F;
}
From my task I enable TX IRQ and enables the SPI module
void SPI1_EnableIRQ(void){
/* Hook SPI1 ISR to vector and unmask it. */
sb_IRQVectSet(INT_MCSPI1INT, SPI1_ISR);
sb_IRQConfig(INT_MCSPI1INT);
sb_IRQUnmask(INT_MCSPI1INT);
MCSPI1_IRQENABLE = 0x0001;//NIJ enable TX0_EMPTY_ENABLE
MCSPI1_CH0CTRL_bit.EN = 1;// enable channel
}
This brings me to my ISR which fills in data in the FIFO
void SPI1_ISR_FPGA_config(void)
{
static uint32_t counter = 0;
counter++;
//smx_RTC_ISR_START(); //profiling. remember smx_RTC_ISR_END(); if uncommented Should only be instrumented if necessary as it adds quite a bit of code to the ISR.
smx_EVB_LOG_ISR(Spi1ISRH); //event buffer log.
sb_IRQClear(INT_MCSPI1INT);
while( (!MCSPI1_CH0STAT_bit.TXFFF) & (Spi1TxArrayindex<Spi1TxArrayLength) ){
MCSPI1_TX0 = *(Spi1TxArrayPtr+Spi1TxArrayindex++);
}
if(Spi1TxArrayindex == Spi1TxArrayLength){
MCSPI1_IRQENABLE = 0x0;//disable interrupts
}
MCSPI1_IRQSTATUS = 0x01;//clear irq
sb_IRQEnd(INT_MCSPI1INT);
smx_EVB_LOG_ISR_RET(Spi1ISRH);
//smx_RTC_ISR_END();//profiling. Must be used with smx_RTC_ISR_START();
}
When I execute the code I get to the interrupt and it fulls up the FIFO, but I only get there once. the stuff never gets transmitted.
When I look at the signals on a logic analyzer I see no movement on any of the lines.
If I change polarity I do see the clk stuck high or low depending on setting, as expected.
This leads me to believe that the pin mux part is ok.
In a debugger I can see all my registers and read them so I believe the relevant modules are powered and clocked.
I'm sure this is something simple I just missed, but I can't seem to find out what.
If any more information is desired or any register values should be posted to help me please let me know
Any pointers is greatly appreciated.