free 8051 Microcontroller Projects AVR PIC Microcontroller Projects Tutorials Ebooks Libraries, interfacing tutorials, lcd tutorial, stepper motor, dc motor 8051 assembly language programming electronics and communication ECE CSE pdf ebooks library BE final year project ideas Embedded systems

 
8051 microcontroller 8051 microcontroller
Forums

Rickey's World :: Discussion Forums :: Discuss and Learn :: ARM Development
 
<< Previous thread | Next thread >>
[USB HOST]: LPC2148 & MAX3421E problem with SSP (reading from MAX3421)
Go to page       >>  
Moderators: Ajay Bhargav, Arun Kumar V, pdi33, Shailesh NAYAK, ۞ TPS ۞, shyam, sashijoseph, ExperimenterUK, DavesGarage
Author Post
Vito.dsk
Fri Jun 19 2009, 02:27AM

 User Offline
Registered Member #18520
Joined: Thu May 14 2009, 03:44AM

Posts: 23
Thanked 0 times in 0 posts
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):

CODE:

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:

CODE:

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:
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



---------------------------------------------------------------------------------
--------------------------------------------------
------------------------
Exchanging knowledge makes it possible to keep wonderful this world.
Back to top

Vito.dsk
Fri Jun 19 2009, 02:32AM

 User Offline
Registered Member #18520
Joined: Thu May 14 2009, 03:44AM

Posts: 23
Thanked 0 times in 0 posts
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

---------------------------------------------------------------------------------
--------------------------------------------------
------------------------
Exchanging knowledge makes it possible to keep wonderful this world.
Back to top

Ajay Bhargav
Mon Jun 22 2009, 03:24PM
Rickey's World Admin

 User Offline

Registered Member #1
Joined: Fri Feb 24 2006, 04:56AM

Posts: 7567
Thanked 1331 times in 1255 posts
try with this..
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)
        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 Mon Jun 22 2009, 03:26PM ]

www.rickeyworld.info
If you feel satisfied with the user's forum reply please click on the thank button.

Obey forum rules!
Respect others!
Back to top

Vito.dsk
Tue Jun 23 2009, 12:36AM

 User Offline
Registered Member #18520
Joined: Thu May 14 2009, 03:44AM

Posts: 23
Thanked 0 times in 0 posts
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.

---------------------------------------------------------------------------------
--------------------------------------------------
------------------------
Exchanging knowledge makes it possible to keep wonderful this world.
Back to top

misterPaul
Wed Jun 24 2009, 03:55AM
 User Offline
Registered Member #19631
Joined: Wed Jun 24 2009, 03:45AM

Posts: 2
Thanked 0 times in 0 posts
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.

CODE:
  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, 03:57AM ]
Back to top

Ajay Bhargav
Thu Jun 25 2009, 04:18AM
Rickey's World Admin

 User Offline

Registered Member #1
Joined: Fri Feb 24 2006, 04:56AM

Posts: 7567
Thanked 1331 times in 1255 posts
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

www.rickeyworld.info
If you feel satisfied with the user's forum reply please click on the thank button.

Obey forum rules!
Respect others!
Back to top

Vito.dsk
Fri Jun 26 2009, 07:30AM

 User Offline
Registered Member #18520
Joined: Thu May 14 2009, 03:44AM

Posts: 23
Thanked 0 times in 0 posts
@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:
CODE:

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
}

 


CODE:


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, 07:47AM ]

---------------------------------------------------------------------------------
--------------------------------------------------
------------------------
Exchanging knowledge makes it possible to keep wonderful this world.
Back to top

Vito.dsk
Fri Jun 26 2009, 07:44AM

 User Offline
Registered Member #18520
Joined: Thu May 14 2009, 03:44AM

Posts: 23
Thanked 0 times in 0 posts
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:

CODE:

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, 07:49AM ]

---------------------------------------------------------------------------------
--------------------------------------------------
------------------------
Exchanging knowledge makes it possible to keep wonderful this world.
Back to top

Ajay Bhargav
Fri Jul 03 2009, 06:49AM
Rickey's World Admin

 User Offline

Registered Member #1
Joined: Fri Feb 24 2006, 04:56AM

Posts: 7567
Thanked 1331 times in 1255 posts
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..

www.rickeyworld.info
If you feel satisfied with the user's forum reply please click on the thank button.

Obey forum rules!
Respect others!
Back to top

misterPaul
Thu Aug 13 2009, 04:31AM
 User Offline
Registered Member #19631
Joined: Wed Jun 24 2009, 03:45AM

Posts: 2
Thanked 0 times in 0 posts
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!
Back to top

Go to page       >>   

Jump:     Back to top

Syndicate this thread: rss 0.92 Syndicate this thread: rss 2.0 Syndicate this thread: RDF
Powered by e107 Forum System

8051 Microcontroller Projects 8051 AVR tutorials PIC microcontroller, 8051 assembly language programming electronics and communication ECE CSE pdf ebooks library BE final year project ideas Embedded systems