|
|
View previous topic :: View next topic |
Author |
Message |
naughty_mark
Joined: 29 Aug 2012 Posts: 97
|
USB driver problem |
Posted: Wed Feb 06, 2013 4:20 pm |
|
|
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.
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
|
|
Posted: Wed Feb 06, 2013 7:45 pm |
|
|
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.. 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
|
|
Posted: Thu Feb 07, 2013 6:26 pm |
|
|
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
|
|
Posted: Sun Feb 10, 2013 6:06 pm |
|
|
no one can help??~~ |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Mon Feb 11, 2013 12:50 am |
|
|
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
|
|
Posted: Mon Feb 11, 2013 3:16 pm |
|
|
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...
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: 19518
|
|
Posted: Mon Feb 11, 2013 3:29 pm |
|
|
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
|
|
Posted: Mon Feb 11, 2013 3:47 pm |
|
|
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 |
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
|
|
Posted: Mon Feb 11, 2013 4:41 pm |
|
|
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.. |
|
|
naughty_mark
Joined: 29 Aug 2012 Posts: 97
|
|
Posted: Mon Feb 11, 2013 11:10 pm |
|
|
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~ |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Tue Feb 12, 2013 1:52 am |
|
|
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
|
|
Posted: Tue Feb 12, 2013 3:46 pm |
|
|
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...
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. |
|
|
|
|
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
|