After several days of confusing,finally,I had figured out the reason of CS8900A's tx problem,and fix this bug.
This bug actives on almost ARM9 and ARM7 development board with the CS8900A network controller.
It is funny,because all the drivers of CS8900A I have found is not right.
Here comes my analysis.
Some days ago,I had ported the CS8900A driver to the ARM9 develop board of my work,this driver is not basing the OS.
And I wrote a little program for testing,sth. like this:
| TransmitPkt(sendbuf,1024); |
Everything seems to be fine.I could capture the datas without error from my develop board by network,it showed that the CS8900A had sent out the datas correctly.
But,when I wanted to test the data -sending speed,I wroted down sth. like this:
TransmitPkt(sendbuf,1024); TransmitPkt(sendbuf,1024); |
Sth. I haven't expected came out.
The program stucked.
From the debug imformations,the program stucked in the second 'TransmitPkt(sendbuf,1024);'.
More imformations showed that the first 1024Bytes datas were sent out quickly and correctly,but the second 1024Byes datas could not be sent out.Because the Rdy4txNow flag of the BUS_status register could not be set.From the datasheet of CS8900A,this means the CS8900A's buffer was not ready for transfering yet,thought the datas in buffer had been sent out.
From the datasheet,the driver should continue checking the Rdy4txNow flag and wait for it was being setting.And the problem was,it seen that after the first 1024 Bytes datas had sent out,the Rdy4txNow flag could not be set,however long time the driver waited.It was completely stucked.
Because this driver ran without OS,I thougt maybe the OS had done sth. else.So I checked the source codes of linux driver,I found that it is almost the same as my codes.And when I tried the
| 'ping -c 500 -s 1024 localhost' |
under the linux running on the develop board,I received this:
NETDEV WATCHDOG: eth0: transmit timed out eth0: Transmit buffer not free! |
It means that there is the same problem in the linux driver of the develop board.
I maked a phone call to the support of the Cirrus company,which produced this CS8900A chip.But the support didn't get this case yet.
I also tried the same codes on my own develop board,it doesn't work fine either.
I tried to collect the imformations about CS8900A on the internet.
Sth. below:
It seens these poor guys met the same problem just like me,but no solutions.
We are all GOD DAMNED confused!Because the driver fullfilled the logic requirements of the datasheet from the Cirrus company.
And I had to keep thinking and searching...
New messages I found today morinig,it shoot me.The messages were here:
In this message,there was a very useful and important key point which I had miss before:
我在2和3之间加入csReadPacketPage( 0x0108 ); 读出Tx状态寄存器发现是0x0009(bit8位为0)似乎是传输命令没有写到TxCMD寄存器中去 |
This message had save my poor brain from the crash --_--!!!!!!!!!!!!!!!!!!
It shown that maybe because the CPU's speed was too fast,when the datas had not been all sent out and writing the send CMD to TxCMD register would fail,and the Rdy4txNow flag would keep being clear,because the chip would answer the buffer-free request(set Rdy4txNow flag) only when it receive the legal TxCMD .So,the key point of solution is:resend the CMD to TxCMD register again and again,until the Rdy4txNow flag is set!
So,I modified these codes:
/* Send Command */ IOWRITE(IO_TX_CMD, TX_CMD_START_ALL | TX_CMD_LOW_BITS); IOWRITE(IO_TX_LENGTH, slen); /* Wait */ for (i = 0; i < MAX_COUNT; i++) {
data = READ_REG2(PKTPG_BUS_ST); if (data & BUS_ST_RDY_4_TX_NOW) break;
} if (i >= MAX_COUNT) return TIMEOUT_EVENT; |
to these codes:(resend the TXcmd)
/* Wait */ for (i = 0; i < MAX_COUNT; i++)
{ /* Send Command */
IOWRITE(IO_TX_CMD, TX_CMD_START_ALL | TX_CMD_LOW_BITS);
IOWRITE(IO_TX_LENGTH, slen);
data = READ_REG2(PKTPG_BUS_ST);
if (data & BUS_ST_RDY_4_TX_NOW) break;
}
if (i >= MAX_COUNT) return TIMEOUT_EVENT;
|
And, Bingo!
Finally,It works!
Here comes the diagram:
