Problem with chip select line with qspi on mcf52233

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Problem with chip select line with qspi on mcf52233

2,307 Views
admin
Specialist II
I am having problems with the chip select line. I need it to be active low and can only get it to work active high. When I set the  MCF_QSPI_QWR[CSIV] bit the line doesn't do anything. If I don't set the bit the chip select line works but is active high. I am trying to use an external a-d chip and when I use the cs line as an I/O it is too slow so I need to use the qspi chip select. I also tried another board to make sure it wasn't the chip without any luck. Any help would be great.
Here is my code:
 
void   spi_init()
{
 int temp_buff[2];
 
 
 /* Enable QSPI Pins Primary Functions */
  MCF_GPIO_PQSPAR =
   MCF_GPIO_PQSPAR_DOUT_DOUT|
   MCF_GPIO_PQSPAR_DIN_DIN|
   MCF_GPIO_PQSPAR_SCK_SCK|
   MCF_GPIO_PQSPAR_CS0_CS0;
   
 MCF_QSPI_QMR = MCF_QSPI_QMR_MSTR
     | MCF_QSPI_QMR_CPOL
     | MCF_QSPI_QMR_BAUD(3);                    
                  
 MCF_QSPI_QIR    = MCF_QSPI_QIR_ABRTL
     | MCF_QSPI_QIR_ABRTB                 
      | MCF_QSPI_QIR_WCEFB 
     | MCF_QSPI_QIR_ABRT
     | MCF_QSPI_QIR_WCEF
     | MCF_QSPI_QIR_SPIF;
 MCF_QSPI_QWR  = MCF_QSPI_QWR_NEWQP(0)  
     | MCF_QSPI_QWR_ENDQP(0)
     | MCF_QSPI_QWR_CSIV ; //**//
     
 MCF_QSPI_QDLYR  = MCF_QSPI_QDLYR_DTL(1) 
     | MCF_QSPI_QDLYR_QCD(3)  ;
///////////************************//////////////
 //command pointer set
 MCF_QSPI_QAR    =   0x0020; 
 MCF_QSPI_QDR  =  0x4100;
 MCF_QSPI_QAR  =  0x0000;
 MCF_QSPI_QDR   = 0x8030; 

 //start transfer
 MCF_QSPI_QDLYR |= MCF_QSPI_QDLYR_SPE;
 // wait for transfer to complete
 while(!(MCF_QSPI_QIR & MCF_QSPI_QIR_SPIF)) {}
 
 MCF_QSPI_QIR |= MCF_QSPI_QIR_SPIF;
  
 MCF_QSPI_QAR = 0x0010;
  
 temp_buff[0] = MCF_QSPI_QDR & 0x1FFF; 
 
///////////************************//////////////
 //command pointer set
 MCF_QSPI_QAR    =   0x0020;         
 MCF_QSPI_QDR  =  0x4100;
 MCF_QSPI_QAR  =  0x0000;
 MCF_QSPI_QDR  = 0xBFE0;
 
 //start transfer
 MCF_QSPI_QDLYR |= MCF_QSPI_QDLYR_SPE;
 // wait for transfer to complete
 while(!(MCF_QSPI_QIR & MCF_QSPI_QIR_SPIF)) {}
 
 MCF_QSPI_QIR |= MCF_QSPI_QIR_SPIF;
 MCF_QSPI_QAR = 0x0010;  
 temp_buff[1] = MCF_QSPI_QDR & 0x1FFF; 
}

void  a2d_spi()
{
 int i = 0;
 
 MCF_QSPI_QAR    =   0x0020;      
 MCF_QSPI_QDR  =  0x7100;  
 MCF_QSPI_QAR  =  0x0000;
 MCF_QSPI_QDR  = 0x0000;
 
 MCF_QSPI_QWR |= MCF_QSPI_QWR_WREN;
  MCF_QSPI_QWR &= ~MCF_QSPI_QWR_HALT;
  //start transfer
  MCF_QSPI_QDLYR |=  MCF_QSPI_QDLYR_SPE ;
 // 
   
 while(1)//i<5000)  
 {
 
  // wait for transfer to complete
  while(!(MCF_QSPI_QIR & MCF_QSPI_QIR_SPIF)) {}
  
  MCF_QSPI_QIR = 0xD00F;
 
  MCF_QSPI_QAR = 0x0010; 
  
  data_buff[0/*i++*/ ] = MCF_QSPI_QDR; 
    
 }
 
 
 MCF_QSPI_QWR |= MCF_QSPI_QWR_HALT;
 
}  
Labels (1)
0 Kudos
5 Replies

358 Views
Technoman64
Contributor III
I use the following code to write to a Digital to Analog device using MCF52223 Coldfire device using CS Active low interface. The Chip Select 4-bit nibble in Command register should be set to what the CSx pin state should be when active. For example CS0 would be binary %1110 or 0xE hex. Hope this helps.
 
Code:
INT8U SetAnalogOut(INT8U Data){ /* Local variables */ int Timeout; INT16U SerialData, Value;   /* Convert volt data to binary */ Value = Data / 10;   SerialData = (Data * 5) + Value;   SerialData <<= 4; /* Check for QSPI in operation */ if(MCF_QSPI_QDLYR & MCF_QSPI_QDLYR_SPE) {  for(Timeout = 0; Timeout <= QSPI_TIMEOUT; Timeout++)  {   /* Check for QSPI in operation */   if(MCF_QSPI_QDLYR & MCF_QSPI_QDLYR_SPE)    /* Timeout elapsed— */    if(Timeout >= QSPI_TIMEOUT)     /* Exit with timeout err */     return QSPI_TIMEOUT_ERR;    else    /* Exit loop, QSPI is free */    break;  } } /* Setup for 16-bit transfer */ MCF_QSPI_QMR = 0x8004; /* No error interrupts */ MCF_QSPI_QIR = 0x0000; /* Point to first command entry */ MCF_QSPI_QAR = 0x0020; /* Setup SPI transfer command */ MCF_QSPI_QDR = 0x4b00; /* Point to first data entry */ MCF_QSPI_QAR = 0x0000; /* Setup SPI transfer data */ MCF_QSPI_QDR = SerialData; /* Just use first entry in queue */ MCF_QSPI_QWR = 0x1000; /* Start spi transfer */ MCF_QSPI_QDLYR = 0x8001; for(Timeout = 0; Timeout <= QSPI_TIMEOUT; Timeout++) {  /* Check for QSPI in operation */  if(MCF_QSPI_QIR & MCF_QSPI_QIR_SPIF)   break;  else   if(Timeout >= QSPI_TIMEOUT)    /* Exit with timeout err */    return;  }}

 
0 Kudos

358 Views
bkatt
Contributor IV
The CSIV bit worked for me on the 52233 chip. You have to set it on every write to the QWR register; early in initialization I send just that bit to the QWR.

I noticed in your code you have &= and |= into device registers. I found out the hard way that doesn't always work (on the 5282 you cannot |= into QDLYR for example). It is safer to construct the entire write value and use a simple = assignment for device output.

0 Kudos

358 Views
admin
Specialist II
I went back and changed all the &= and |=. Thats good to know so I don't run into that later. It didn't fix the problem. I went into debug mode and verified that that CSIV bit is set but I just get a high output the entire time. I unset the bit and got the chipselect line working but active high.
0 Kudos

358 Views
bkatt
Contributor IV
As technoman said, the chip select pattern written into the QDR must also be inverted. In the CSIV case I use these chip select defines:

#define CS0     0xE00
#define CS1     0xD00
#define CS2     0xB00
#define CS3     0x700

It would be reasonable to expect the device to do this for you when you have CSIV on, but for whatever reason the hardware requires the software to account for it.

0 Kudos

358 Views
admin
Specialist II
That was it. I didn't invert the chip select bit in the QDR. I don't think I would have figured that out. I guess this is one of those small things that are big when you don't know it. Thank you all for all your help. That saved me a lot of time and headaches.
0 Kudos