CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

USB driver problem

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
naughty_mark



Joined: 29 Aug 2012
Posts: 97

View user's profile Send private message

USB driver problem
PostPosted: Wed Feb 06, 2013 4:20 pm     Reply with quote

Hi, there

I am using dsPIC33EP256MU814 with CCS compiler version 4.133.
Currently I am writing a USB driver code. I can not use CCS function because I found in their code, they use delay_ms in their get/put string functions, and delay_ms() built_in function can not fit in my ms task cycle code structure.

So I tried to understand USB protocol, microchip USB module principle and write my code.
Firstly, I use primary oscillator 20MHz as source to generate 48MHz clock for USB module by auxiliary PLL.

the code is:
Code:

   ACLKCON3 = 0x0000;
   ACLKCON3 |= BIT10; //auxiliary clock source is primary oscillator
   ACLKCON3 |= BIT13; //auxiliary PLL used for auxiliary clock divider
   ACLKCON3 |= (BIT7|BIT6); //PLL post is 2, N2 = 2;
   ACLKCON3 |= BIT2; //PLL pre is 5, N1 = 5
   ACLKDIV3 = (BIT2|BIT1|BIT0); //clock multipier is 24, M = 24;

   ACLKCON3 |= BIT15; //enable Auxiliary PLL;


And I also use the fuse APLK (I think this is for auxiliary PLL clock, I can not find this fuse description in CCS manual)

I believe the above code can make USB clock set to 48MHz (If not, please comment it).

Then I tried to implement USB protocol, I created Buffer Descriptor structure:
Code:

typedef struct _BUFFER_DESCRIPTOR
{
   unsigned int16 BD_CONFIG;    //BD configuration
   unsigned int16 BD_COUNT;     //BD byte count, how many bytes will be read from the data buffer
   unsigned int16 BD_ADDR_LO;   //data buffer address (lower 16 bits)
   unsigned int16 BD_ADDR_HI;   //data buffer address (higher 16 bits)
} BUFFER_DESCRIPTOR;

and I defined
Code:

static BUFFER_DESCRIPTOR BufferDescrArry[16];

Then I grab the start address of this array and give it to U1BDTP1, U1BDTP2 and U1BDTP3.
I checked those registers, the value is correct, and the buffer descriptor's section(config, count, addr_lo, addr_hi) also in correct memory order ( as my understanding, Buffer Descriptor made by four Word with consequencial memory address)
My USB module is in host mode, so the U1CON = C8 after initialization. And after an USB device attached and reset power for initilization, SOF bit in U1CON also be set.

Then I tried to write a command like "get configuration". I wrote the relative Data Buffer of Buffer Decspritor(BD) first, set U1EP0 = 0x0D, and change UOWN to 1 in BD's config word, change the count in BD's count, and before write into U1TOK, I check TOKBUSY bit in U1CON, then I monitor some registers by sending then via RS232 showing on the screen, the strange thing happened:
after the code implement U1TOK = xxxxx; my code waiting the TRNIF bit set for 10 secs which indicate the token trans complete. But nothing hanppened, and the U1CON changed to 0x29 which means the TOKBUSY is 1 and never gone. The U1STAT register always 0 before and after Token command implement.
Rolling Eyes Anyone knows what's wrong with my code or method? 48MHz didn't set properly or something else.

Thanks a lot
Mark
naughty_mark



Joined: 29 Aug 2012
Posts: 97

View user's profile Send private message

PostPosted: Wed Feb 06, 2013 7:45 pm     Reply with quote

Some updates:

I monitored the D+/D- signals, looks weird, it is not square shape wave, the shape some parts like sin wave. and if SOF set, this wave sent out regularly.

If I comment out the auxiliary clock setup code, including "AUX: clock = 48M" in #use delay, and my code. Then the wave is perfect square wave, the width of one bit is about 4.4us.. Rolling Eyes Now I get confused......It looks the USB clock somehow not setting correctly. Anyone has any idea?

Thanks

EDIT: sorry, my stupid, the wave problem is because long wire on prob, The wave now under correct au clock setting is acceptable. Looks something wrong somewhere else. After write U1TOKE, it is always in trans, the TOKENBUSY bit always set in U1CON, and TRNIF never happen.

Regards
naughty_mark



Joined: 29 Aug 2012
Posts: 97

View user's profile Send private message

PostPosted: Thu Feb 07, 2013 6:26 pm     Reply with quote

Some updates today.

The first time I write to U1TOK can generate TRNIF and TOKBUSY will be cleared, but this only happen once after hardware reset(power reconnect). After that once successful transmition, the TRNIF neven happen, TOKBUSY never be cleared even with a software reset.

I noticed the value of PID in U1TOK can only be Token In, Token Out, Token Setup, there is no DATA0 and DATA1, and even no ACK PIDs, and the datasheet says onlyToken In, Token Out, Token Setup PIDs accepted, all other PIDs are not valid value. So I was wondering how can this USB module send command to get data from USB device? And is there anyone know if I wana creat a file in the USB stick, want command do I need to send? Or any docs I can get answer about it?

Thanks a lot
Mark
naughty_mark



Joined: 29 Aug 2012
Posts: 97

View user's profile Send private message

PostPosted: Sun Feb 10, 2013 6:06 pm     Reply with quote

Sad
no one can help??~~
Ttelmah



Joined: 11 Mar 2010
Posts: 19469

View user's profile Send private message

PostPosted: Mon Feb 11, 2013 12:50 am     Reply with quote

The TOK here, is 'token'. U1TOK, is only involved in token transfers.
Are you clearing U1IR<TRNIF>?. Unless this is done, the FIFO won't advance and the data in U1TOK will be invalid.
When a data packet is received, you'll get a transfer done interrupt, nothing in U1TOK.

Best Wishes
naughty_mark



Joined: 29 Aug 2012
Posts: 97

View user's profile Send private message

PostPosted: Mon Feb 11, 2013 3:16 pm     Reply with quote

Ttelmah wrote:
The TOK here, is 'token'. U1TOK, is only involved in token transfers.
Are you clearing U1IR<TRNIF>?. Unless this is done, the FIFO won't advance and the data in U1TOK will be invalid.
When a data packet is received, you'll get a transfer done interrupt, nothing in U1TOK.

Best Wishes


Thanks Ttelmah.
Yeah, I am sure that before I write into the U1TOK, TRNIF is clear, because I check TOKBUSY bit in U1CON. After I write to U1TOK, the TOKBUSY is set but never cleared by hardware and the TRNIF never set. and I know TRNIF is a bit in register U1IR, not in U1TOK...
Crying or Very sad I tried many days....don't know why. I followed the instruction in document "Section 25, USB On The Go", I doubt the description of Buffer Descriptor in its document is correct or not. some parts looks conflict.

So any other suggestion?
Ttelmah



Joined: 11 Mar 2010
Posts: 19469

View user's profile Send private message

PostPosted: Mon Feb 11, 2013 3:29 pm     Reply with quote

I do remember some people having similar problems in some of the MicroChip forums. You might want to look there. It was something to do with the retry disabled bit. Unless it was set TRNIF didn't get set.

Best Wishes
naughty_mark



Joined: 29 Aug 2012
Posts: 97

View user's profile Send private message

PostPosted: Mon Feb 11, 2013 3:47 pm     Reply with quote

Ttelmah wrote:
I do remember some people having similar problems in some of the MicroChip forums. You might want to look there. It was something to do with the retry disabled bit. Unless it was set TRNIF didn't get set.

Best Wishes


Shocked Really?
I tried to search the Microchip forum, the thing is many people using PIC18 microchip which has dedicated USB Buffer Descriptor Stack, and PIC24E and dsPIC33E using the way that user need to define a stack in RAM. I also searched some posts said using PIC24E and successful, but those posts were 1year ago, and the poster just asked question but on one answer, then finally the poster got it and said "I solved it", but no more details. I tried to message those guy, but....
I am looking some demo code from microchip website, but I can not find its lower layer code..
Anyway, thanks mate. I try to search again and if anyone have any suggestion, welcome.
naughty_mark



Joined: 29 Aug 2012
Posts: 97

View user's profile Send private message

PostPosted: Mon Feb 11, 2013 4:41 pm     Reply with quote

I REALLY REALLY doubt if the microchip document "Section 25 USB On The Go" is correct or not about U1BDTP1, U1BDTP2 and U1BDTP3.

I check a sample code from Microchip
Following is the way it defines BD(Buffer Descriptor) for dsPIC33E which I am using now
Code:

typedef union __attribute__ ((packed)) _BD_STAT
{
    struct __attribute__ ((packed)){
        unsigned            :2;
        unsigned    BSTALL  :1;     //Buffer Stall Enable
        unsigned    DTSEN   :1;     //Data Toggle Synch Enable
        unsigned            :2;     //Reserved - write as 00
        unsigned    DTS     :1;     //Data Toggle Synch Value
        unsigned    UOWN    :1;     //USB Ownership
    };
    struct __attribute__ ((packed)){
        unsigned            :2;
        unsigned    PID0    :1;
        unsigned    PID1    :1;
        unsigned    PID2    :1;
        unsigned    PID3    :1;

    };
    struct __attribute__ ((packed)){
        unsigned            :2;
        unsigned    PID     :4;         //Packet Identifier
    };
    WORD           Val;
} BD_STAT;

// BDT Entry Layout
typedef union __attribute__ ((packed))__BDT
{
    struct __attribute__ ((packed))
    {
        BD_STAT     STAT;
        WORD        CNT:10;
        WORD        ADR;                     
        WORD        ADRH;                   
    };
    struct __attribute__ ((packed))
    {
        DWORD       res  :16;
        DWORD       count:10;
    };
    DWORD           w[2];
    WORD            v[4];
    QWORD           Val;
} BDT_ENTRY;

BDT_ENTRY           *pBDT;
static BDT_ENTRY __attribute__ ((aligned(512)))    BDT[2];

Then the set U1BDTP1 - U1BDTP3 as:
Code:

U1BDTP1 = ((DWORD)KVA_TO_PA(&BDT) & 0x0000FF00) >> 8;
U1BDTP2 = ((DWORD)KVA_TO_PA(&BDT) & 0x00FF0000) >> 16;
U1BDTP3 = ((DWORD)KVA_TO_PA(&BDT) & 0xFF000000) >> 24;


I am not quite sure what is "KVA_TO_PA", it might be some other compiler build in function, whatever, the way it fetch address and load to those three registers is not as the same as its description in document.

It also happened in CCS USB file.
However, the BIT0 in U1BDTP1 should be UNIMPLEMENTED!

EDIT: actually I tried their way to define those three registers, but still the same.. Crying or Very sad
naughty_mark



Joined: 29 Aug 2012
Posts: 97

View user's profile Send private message

PostPosted: Mon Feb 11, 2013 11:10 pm     Reply with quote

Some update:

After I doubt BDs, now I doubt USB clock. In the post I said I believe the code should work because there is no APLL Phace Lock Status bit any more, before this bit was BIT14 in ACLKCON3 register, now it is "UNIMPLEMENTED".

I used EYE_PATTEN bit in U1CNFG1 to check the USB clock. The result is negative, it is only 500Hz which means USB clock is only 2000Hz!

Then I tried to use CCS way to define that USB clock as:
Code:

#use delay(clock=120M, xtal=20M, AUX:clock=48M) // Actual crystal is 20M

The fuse I use is
Code:

#if defined(__PCD__)
#include <33EP256MU814.h>
#fuses HS,PR,NOWDT,ICSP2,NOGSSK,NOPROTECT,NOAPROTECT,NOAPLK,PR_PLL

But I got the same result!

I also read out ACLKCON3 value through RS232, both methods give me value E4C4 which supposed to be A4C4, and the different is BIT14, which was APLL Phace Lock Status Bit before, and now it is UNIMPLEMENTED. So I guess I can ignore it.

Moreover, I stop using both methods above, just leave it blank, the USB clock has about 1MHz clock now. And under this senario, after I pluged in a USB stick and tried to send the first token out, the TOKBUSY is cleared but TRNIF never happens as usual. and U1EIR = 0x30...DMA error flag and Bus turn around time out flag set.

Anyone has any idea based on these fact?
Thanks a lot~ Embarassed
Ttelmah



Joined: 11 Mar 2010
Posts: 19469

View user's profile Send private message

PostPosted: Tue Feb 12, 2013 1:52 am     Reply with quote

As a comment, I'd go back to using the CCS code, but just rewrite the bit using the delays. Probably 1000* easier than trying to do the whole stack. You ought to be able to just buffer this section using a timer interrupt.
Just a thought....

Best Wishes
naughty_mark



Joined: 29 Aug 2012
Posts: 97

View user's profile Send private message

PostPosted: Tue Feb 12, 2013 3:46 pm     Reply with quote

Ttelmah wrote:
As a comment, I'd go back to using the CCS code, but just rewrite the bit using the delays. Probably 1000* easier than trying to do the whole stack. You ought to be able to just buffer this section using a timer interrupt.
Just a thought....

Best Wishes


You may be right. I also consider to use CCS function, but I got confused which .c and .h files I need to include, and trying to understand those function is another problem... Sad

Yesterday, I used FRC as USB clock source, and the EYE pattern can give me about 12MHz signal, which means the USB clock now is 48MHz. However, the signal shape looks not good, it is more like sine wave rather then a square wave. And the problem I mentioned in the beginning is still there. TOKEN always busy after U1TOK written and TRNIF never set.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group