[USB HOST]: LPC2148 & MAX3421E problem with SSP (reading from MAX3421)
Fri Jun 19 2009, 02:57 pm
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):
To test it all, i use a little external function:
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:
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
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
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
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
try with this..
Edit: code edited.. previous one was wrong..
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
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.
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
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.
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
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
@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:
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
@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
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:
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
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
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..
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
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!
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!
Powered by e107 Forum System