Hi,
I'm tying to communicate the SPI0 with a Digital potentiometer AD5293, I send it the commands from SPI0 but when the digital potentiometer sends me its status I can't read in the POP register, It appears empty but I see the correct data in the oscilloscope that the digital potentiometer sends me. When I go to see the value in POP register its content is empty or the value or data isn't correct. When I'm debugging the code first I send a command to write the resistance for this Potentiometer, second I hope to receive the correct data that it sends me but this isn't.
What is happening with the POP register?? or How I can fix it? I wait for yours answers.
Hi Ivan,
If you are enabling Spi Interrupts in your program, you need to enable the SPI interrupt corresponding to SPI0 or SPI1 in NVIC as well. Then You need to add the vector location of this interrupt in your code. After this put a breakpoint in your Receive ISR and check if the program does indeed come to your ISR. And then read the value of POP register.
I am attaching a sample code and Kinetis_sys_init file which has an example of ISR Vector for SPI. The attached files are for K10 but most of it should be same for K60 as well.
I don't have problem whit the interrupt, it is ok. The interrupt is executing all the time, I think the problem is my digital potentiometer AD5293 because If I don't send the dummy the potentiometer always is sending its data for this reason I think that I can't read well. The PoP regsiter always is updating and I think for this reason the pop register doesn't keep the data.
Hi Ivan,
Going through the AD5293 I found that the Potentiometer sends data if the Slave select is low and sclk is available and for command 0x0000. Configure the Salve select as GPIO and pull it high and see If you still get data continously in POP register.Next check that your K60 sends clock pulses only when it is transmitting and reading data and not continously. Check the following bits in debug mode in SPI_MCR register -->CONT_SCKE, PCSSE, PCSIS[5:0].
I have other case:
I can read but I don't know what's happening when the microcontroller saves the data in a global variable from SPI0_POPR. The problem is the SPI0_POPR doesn't keep the value that is enter throught SIN. I can see the MISO signal in the oscilloscope and the data that entry is correct but I can't see in the register POP.
This function config the spi module:
void SpiConfig(uint08 u08SPIModule, uint08 u08SPIMode, uint08 u08SPIInterruptEnable, uint08 u08SPICpol, uint08 u08SPICpha, uint08 u08SPIFrameSizeSlave, uint08 u08SPIBRPrescaler, uint08 u08SPIBRScaler)
{
switch(u08SPIModule)
{
case 0 : /* clock gate */
SIM_SCGC6 |= SIM_SCGC6_DSPI0_MASK;
SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK;
/* pin mux */
PORTA_PCR14 &= ~PORT_PCR_MUX_MASK;
PORTA_PCR14 |= PORT_PCR_MUX(2); //SPI0_PCS0 //PTC4, PTE16, PTD0
PORTA_PCR15 &= ~PORT_PCR_MUX_MASK;
PORTA_PCR15 |= PORT_PCR_MUX(2); //SPI0_SCK //PTC5, PTD1, PTE17
PORTA_PCR16 &= ~PORT_PCR_MUX_MASK;
PORTA_PCR16 |= PORT_PCR_MUX(2); //SPI0_SOUT //PTC6, PTD2, PTE18
PORTA_PCR17 &= ~PORT_PCR_MUX_MASK;
PORTA_PCR17 |= PORT_PCR_MUX(2); //SPI0_SIN //PTC7, PTD3, PTE19
break;
case 1 : /* clock gate */
SIM_SCGC6 |= SIM_SCGC6_DSPI1_MASK;
SIM_SCGC5 |= SIM_SCGC5_PORTB_MASK;
/* pin mux */
PORTB_PCR10 &= ~PORT_PCR_MUX_MASK;
PORTB_PCR10 |= PORT_PCR_MUX(2); //SPI1_PCS0 //PTE4
PORTB_PCR11 &= ~PORT_PCR_MUX_MASK;
PORTB_PCR11 |= PORT_PCR_MUX(2); //SPI1_SCK //PTE2
PORTB_PCR16 &= ~PORT_PCR_MUX_MASK;
PORTB_PCR16 |= PORT_PCR_MUX(2); //SPI1_SOUT //PTE1, PTE3
PORTB_PCR17 &= ~PORT_PCR_MUX_MASK;
PORTB_PCR17 |= PORT_PCR_MUX(2); //SPI1_SIN //PTE1, PTE3
break;
case 2 : /* clock gate */
SIM_SCGC3 |= SIM_SCGC3_DSPI2_MASK;
SIM_SCGC5 |= SIM_SCGC5_PORTD_MASK;
/* pin mux */
PORTD_PCR11 &= ~PORT_PCR_MUX_MASK;
PORTD_PCR11 |= PORT_PCR_MUX(2); //SPI2_PCS0 //PTF16, PTB20
PORTD_PCR12 &= ~PORT_PCR_MUX_MASK;
PORTD_PCR12 |= PORT_PCR_MUX(2); //SPI2_SCK //PTF17, PTB21
PORTD_PCR13 &= ~PORT_PCR_MUX_MASK;
PORTD_PCR13 |= PORT_PCR_MUX(2); //SPI2_SOUT //PTF18, PTB22
PORTD_PCR14 &= ~PORT_PCR_MUX_MASK;
PORTD_PCR14 |= PORT_PCR_MUX(2); //SPI2_SIN //PTF19, PTB23
break;
default: break;
}
ptrSPI[u08SPIModule]->MCR = SPI_MCR_INITIAL_STATE; //set initial state 0x0010001
ptrSPI[u08SPIModule]->CTAR[0] = SPI_CTAR0_INITIAL_STATE; //set initial state 0x0000000
ptrSPI[u08SPIModule]->MCR |= SPI_MCR_MSTR(u08SPIMode); //Configure the module as Master or Slave mode.
if (u08SPIMode == 0 )
ptrSPI[u08SPIModule]->CTAR_SLAVE[0] |= SPI_CTAR_SLAVE_CPHA(u08SPICpha) | SPI_CTAR_SLAVE_CPOL(u08SPICpol) | SPI_CTAR_SLAVE_FMSZ(u08SPIFrameSizeSlave) ;//Configure as Slave Mode with all parameters for configuration.
else
{
ptrSPI[u08SPIModule]->CTAR[0] |= SPI_CTAR_CPHA(u08SPICpha) | SPI_CTAR_CPOL(u08SPICpol) | SPI_CTAR_PBR(u08SPIBRPrescaler) | SPI_CTAR_BR(u08SPIBRScaler); //Configure as Master Mode with all parameters for configuration.
if(u08SPIInterruptEnable == 1) //Check if interrupts will be enabled
SpiInterruptInit(u08SPIModule); //Enable interrupt in SPIx module
}
} //end switch case
} //end function
With this function I receive the data, but the data is saving in the interrupt for SPI0. I add the function interrupt SPI0 ISR.
void SpiMasterReceiveData(uint32 u32SPIValueData[], uint08 u08SPINbytes, uint08 u08SPIModule, uint16 u16SPIDummy[])
{
uint08 i=0;
u08spi_rx_Nbytes_Flag = 1;
//u16SPI_TX_BUFFER = u08Dummy;
for(i=0 ; i < u08SPINbytes ; i++)
{
SpiMasterSendData(u16SPIDummy,1,u08SPIModule,0x0F);
while(u08SpiRxflag == 0){}
//while(Is_busy());
}
for(i=0; i< u08SPINbytes; i++)
{
u32SPIValueData[i] = u32SPI_RX_BUFFER[i];
}
u08spi_rx_index = 0;
i=0;
}
void SPI0_ISR(void)
{
uint32 u32SpiValueRec;
u08SpiRxflag = 1;
u08spi_rx_Nbytes_Flag = 0;
while(!(SPI0_SR & SPI_SR_TCF_MASK)){}
u32SpiValueRec = ptrSPI[SPI0]->POPR ; //read data
u32SPI_RX_BUFFER[u08spi_rx_index] = u32SpiValueRec;
ptrSPI[SPI0]->SR = 0xFFFF0000; //clear Interrupt flag of SPI0
ptrSPI[SPI0]->MCR |= SPI_MCR_HALT_MASK; //stop transmission
u08spi_rx_index++; //Increments the index of the Rx Buffer
}
}
Hi Ivan,
Would you mind posting some of your code so that I may see how you are initializing your SPI0 and how you are getting data from SPI0_POPR? Thank you.
Also, you may want to try the method in the following function for reading SPI0 data:
uint32_t dspi_rx(void)
{
while((SPI0_BASE_PTR->SR & SPI_SR_RFDF_MASK) == 0)
{
//Do Nothing
}
return (SPI0_BASE_PTR->POPR & 0xFFFFFFFF);
}
Let me know if that helps.
Best regards,
Martyn