Discussion in "ARM Development" started by    Vito    Jun 19, 2009.
Fri Jun 19 2009, 02:57 pm
#1
Hi,
I am trying to setup a USB Host controller on a LPC2148-based board with the MAXIM 3421E controller, that uses SPI/SSP to communicate with the microprocessor.
i previously discussed such problem, i was using the SPI0 on the LPC, but then i decided to connect the Max3421E SSP pins to the SSP pins of the Lpc2148, using a GPIO as chip select, hoping ths would work, and in fact, i had a better result, in fact now i can write.

To write i have to send via SSP the address of the register i want to write in OR with the command for writing (0x02).
On writing i succeed, i know this by issuing the max3421 to raise and low a GPIO on the max usb controller, with the istruction -> Hwreg(rIOPINS2,GPOUT4); [Hwreg(register,value)], and it works.

To read, i must send via SSP the address of the register i want to read with no command, and it should return me the content of the register.
My problem is now in reading: i can't read anything i ask to MAX3421, or, with a little variation, i just can read what i previously wrote on the SSP, whatever register i try to read.

I will explain myself better with my code and the output i got.
This is my ssp code (most taken from the MAXIM USB LABORATORY):

void Hwreg(BYTE reg, BYTE val)	// write a host register
{
HSSEL_LO  // low chip select
SSPDR = reg+0x02;		// command byte into the FIFO. 0x02 is the write bit
SSPDR = val;				// data byte into the FIFO
while(SSPSR & SSP_BSY) ;	// hang until BUSY bit goes low
HSSEL_HI // hi chip select
}


BYTE Hrreg(BYTE reg) 	// read a host register
{
	
BYTE dum;
HSSEL_LO
SSPDR = reg;			// write the SPI command byte
SSPDR = 0x00;			// write a dummy byte to generate the 8 read clocks
while(SSPSR & SSP_BSY) ;	// hang until BUSY bit goes low
HSSEL_HI

while(SSPSR & SSP_RNE)	// flush the receive FIFO. RNE means "RCV FIFO NOT EMPTY"
	{

			dum = SSPDR;
	
	}
return (BYTE)dum;		// return the last FIFO byte
}


To test it all, i use a little external function:

void main_func(){

BYTE reading;

  Hwreg(rPINCTL, ( bmFDUPSPI | bmINTLEVEL));

//  rPINCTL is the register, (bmFDUPSPI | bmINTLEVEL)  is to set
// (full duplex SPI | the right level for the interrupt) 
// (the result of the OR is 0x18 and the address of the register rPINCTL is 0x88 )  

   wait_ms(50);


while(1){
 
 reading =  Hrreg(rREVISION); // try to read the register REVISION which address is 0x90
   wait_ms(50);
  uartPrint("reads: %x \n\r",reading); // prints out the result
  }
}


well in this case i try to read the REVISION register, after setting the MAX3421 in full duplex spi, and all i read in output is just this:

Reads: 0
Reads: 0
Reads: 0
Reads: 0
Reads: 0
Reads: 0
............ forever...

Is returned 0 whatever register i try to read.

Then, i make a little mod to the Hrreg code:


BYTE Hrreg(BYTE reg) 	// read a host register
{
	
BYTE dum;
HSSEL_LO
SSPDR = reg;			// write the SPI command byte (no command like 0x02 for reading)
SSPDR = 0x00;			// write a dummy byte to generate the 8 read clocks
while(SSPSR&SSP_BSY) ;	// hang until BUSY bit goes low
HSSEL_HI
while(SSPSR & SSP_RNE)	// flush the receive FIFO. RNE means "RCV FIFO NOT EMPTY"
	{

			dum = SSPDR;
	
	}
dum = SSPDR;     // i make another SSPDR reading after the while
return (BYTE)dum;		// return the last FIFO byte
}


In this case i read exactly what i previously wrote on the SSP.
For example:

what i get in output is these results:

Reads: 0
Reads: 0
Reads: 8a // address of register rPINCTL i write in Hwreg: in fact 0x88+0x02 = 0x8a
Reads: 90 // address of register rREVISION o want to read in Hrreg: in fact 0x90
Reads: 90
Reads: 90
Reads: 90
Reads: 90
..... and then 90 forever...

this too, happens whatever register i try to read with the exception that instead of 90 i get the address of the register i want to read, but the result is the same.

I think i missing something on the SSP and i tried to make some playing with flushing the SSP FIFO, but the better result i get is to read what i wrote in the registers too... i get exactly this:

Reads: 0
Reads: 8a // address of rPINCTL + 0x02
Reads: 18 // content i wrote for rPINCTL in Hwreg(rPINCTL, (bmFDUPSPI | bmINTLEVEL))
//--------------------------------------------------Hwreg(-0x88--,-------- 0x08--|------- 0x10 ))
Reads: 90 // address of the rREVISION register
Reads: 90
Reads: 90

... and so on forever with the address of the register to read ( in the example is 90 for the REVISION register)

or i just get only the address of the register i want to read the content:

Reads: 90
Reads: 90
Reads: 90
Reads: 90
....ecc forever

(and this was the best result ever )

what i am missing ?

I can add that the most of the code is taken from the MAXIM USB LABORATORY
My apologies for the long post, but i did all this just to explain myself well.. i hope this is understandable...

thank you in advance,
dsk
Fri Jun 19 2009, 03:02 pm
#2
P.S.
i forgot,
the original MAXIM USB LABORATORY source can be downloaded @ this address:
http://www.maxim-ic.com/tools/evkit/index.cfm?EVKit=623


thank you
Tue Jun 23 2009, 03:54 am
#3
try with this..
BYTE Hrreg(BYTE reg)    // read a host register
{
	BYTE dum;
	HSSEL_LO
	SSPDR = reg;		// write the SPI command byte (no command like 0x02 for reading)
	while(SSPSR & SSP_BSY);	// hang until BUSY bit goes low
	SSPDR = 0xFF;		// write a dummy byte to generate the 8 read clocks
	while(SSPSR & SSP_RNE); // flush the receive FIFO. RNE means "RCV FIFO NOT EMPTY"
	dum = SSPDR;		// i make another SSPDR reading after the while
	HSSEL_HI
	return (BYTE)dum;	// return the last FIFO byte
}


Edit: code edited.. previous one was wrong..


[ Edited Tue Jun 23 2009, 03:56 am ]
Tue Jun 23 2009, 01:06 pm
#4
already tried with moving the leveling of pin in the code...but it's the same..
but i have just the USB connected on the SSP so, it's not really important where the gpio chipselect is.
Wed Jun 24 2009, 04:25 pm
#5
Hi Vito,

I'm not much help to you, because i'm having similar problems! In the other thread you reported you couldn't get a reply from the 3421, did you change anything in order to get some output on GOUT4? I can't even get that to go high =/

I'm using an str91x based microprocessor, and it's going to be using in 3 wire (half duplex) mode. I'm pretty sure the max3421 operates in this as default though. The MOSIi and MISO from the 3421 are both connected to the SPI bus, of my processor, but the MISO is in high impedance (when half duplex )I believe, so that shouldn't be a problem.

What would be really useful, is knowing what SSP settings you're using, as i'm still not sure i've got these configured correctly.

here's my code, be great if you could let me know if you see any errors.

  GPIO_WriteBit(GPIO6, GPIO_Pin_4, (BitAction)0x00);  // set max3421 low (active)  

  SSP_SendData(SSP0, rIOPINS2+0x02);   // data byte into the FIFO - GPOUT registers
  SSP_SendData(SSP0, bmGPOUT4);   // data byte into the FIFO - GPOUT4 go high
  while(SSP_GetFlagStatus(SSP0, SSP_FLAG_Busy)); // wait till sent

  GPIO_WriteBit(GPIO6, GPIO_Pin_4, (BitAction)0x01);  // set max3421 high (inactive)  


[ Edited Wed Jun 24 2009, 04:27 pm ]
Thu Jun 25 2009, 04:48 pm
#6
vito, just try once again my suggestion.. i did make changes in the code not just moved the statement. well just give it a try hope it works
Fri Jun 26 2009, 08:00 pm
#7
@ajay: thank you ajay, i tried that code too, but it didn't work...

@misterPaul: you know Paul , i changed the wires from SSP and decided to use SPI0, without a FIFO, that's just that the difficult part, i don't know if you can do that, but without the SPI FIFO it works.
so i ended up using the following code successifully:
void Hwreg(BYTE reg, BYTE val)	// write a host register
{
HSSEL_LO
S0SPDR = reg|0x02;
while(!(S0SPSR & SPIF));// command byte into the FIFO. 0x02 is the write bit
S0SPDR = val;			// data byte into the FIFO

while(!(S0SPSR & SPIF));// hang until BUSY bit goes low
HSSEL_HI
}

BYTE Hrreg(BYTE reg)    // read a host register
{
        BYTE dum;
        HSSEL_LO
        S0SPDR = reg;				// send the command byte. 0x01 is the ACKSTAT bit
        while ((S0SPSR&0x80)==0x00) ;	// hang until Transfer Complete Flag = 1
        S0SPDR = 0xff	;				// send a dummy byte to generate 8 read clocks
        while ((S0SPSR&0x80)==0x00) ;	// hang until Transfer Complete Flag = 1
        HSSEL_HI
        dum = S0SPDR;

        return (BYTE)dum;       // return the last FIFO byte
}




void Hwritebytes(BYTE reg, BYTE N, unsigned char *p)
{
int j;
HSSEL_LO
S0SPDR = reg + 0x02;				// send the command byte. 0x0002 is the write bit
while ((S0SPSR & SPI_SPIF)==0x00) ;	// hang until Transfer Complete Flag = 1
for(j=0; j<N; j++)
    {

	S0SPDR = *p;						// send the next data byte
	while ((S0SPSR & SPI_SPIF)==0x00) ;
	p++;                        		// bump the pointer
		// hang until Transfer Complete Flag = 1
    }
HSSEL_HI;
}

void Hreadbytes(BYTE reg, BYTE N, unsigned char *p)
{
int j;
HSSEL_LO
S0SPDR = reg;						// send the command byte.
while ((S0SPSR & SPI_SPIF)==0x00) ;		// hang until Transfer Complete Flag = 1
for(j=0; j<N; j++)
    {
    S0SPDR = 0;							// send a dummy byte to generate the next 8 read clocks
	while ((S0SPSR & SPI_SPIF)==0x00) ;	// hang until Transfer Complete Flag = 1

	*p = S0SPDR; 						// get the next data byte
    p++;                        		// bump the pointer
    }
HSSEL_HI								// can't de-assert this until last transfer is complete
}


And now it works !!

But, you maybe know if the Maxim usb Laboratory is intended to work just with HID devices ?
I tried with a FTDI-based device that brings a USB-SERIAL protocol... and it does not work.

But with Keyboards and Mouses at Low-Speed it works great. i could not try with a HID devices at Full-Speed 'coz i haven't one.... and now i am afraid i'm not talking fine with Full-Speed devices..

what do u think ?

greetings from Italy, Vito


[ Edited Fri Jun 26 2009, 08:17 pm ]
Fri Jun 26 2009, 08:14 pm
#8
MisterPaul, this code seems to be ok, but i can't see what you do in the SSP_SendData() call.... you should use the right registers... try to check that.
check that the address of the registers are right in the macros.

Then i would put the asserting and de-asserting GPIO chip select in the same function that fills the register SSPDR (in my case is the data register of the SSP to be clear), to minimize the time delays.

then i did a thing to see if the bmGPOUT was working:
something like this:

while(1)
{
      Hwreg(rIOPINS2,bmGPOUT4);
     
     Hwreg(rIOPINS2,0x00);
   
}


supposing that Hwreg is the function like i used (using gpio chip select in the same func that the filling of the data register).
Now, if you can use an oscilloscope, you should see a square wave, pointing the tool on the GPOUT4 pin of the MAX3421.

Try something like this.. let me know.

Greetz



[ Edited Fri Jun 26 2009, 08:19 pm ]
Fri Jul 03 2009, 07:19 pm
#9
Hi vito, great to hear that from you

can you send me a finished code with some small working application? I want to see it..
I too have MAX3421 with me so will try that code..
Thu Aug 13 2009, 05:01 pm
#10
Cheers for the help Vito, found out my problem was actually in the SPI config code. Put a scope on it and realised i had the clock set wrong. Oops! Got the thing working now and i've managed to enumerate a USB device. Annoyingly, maxim has taken down the programming guide for this chip from their website. I've contacted them about it, apparently the max3421 is no longer recommended for new builds, and the programming guide was taken down in relation to that, though i'm assured they'll have it back up shortly.

Not much use for me though, i've got a month to prove data transmission to/from sectors on a usb stick, and no detailed information on the HXFR and HCTL registers operation. Such is life.

If anyone has any idea's on how sending MMC commands using a max3421 works, it'd be much appreciated. It seems most USB design guides provide source for implementations direct between SPI and USB device. Which is all well and good for seeing the low level operation of USB communication, but not so much for me!

Get Social

Information

Powered by e107 Forum System

Downloads

Comments

Clydehet
Wed May 01 2024, 06:44 pm
Davidoried
Wed May 01 2024, 06:11 pm
KevinTab
Sun Apr 28 2024, 05:35 am
Tumergix
Sun Apr 28 2024, 12:59 am
StevenDrulk
Sat Apr 27 2024, 08:47 pm
StephenHauct
Sat Apr 27 2024, 09:38 am
Adamsaf
Sat Apr 27 2024, 07:12 am
Robertphype
Sat Apr 27 2024, 12:23 am