Hi,
Code:
uint cmd = ROR(usbCmdO);
WOR(usbCmdO, 2 | cmd & ~(CMD_ASE | CMD_PSE));
kprintf("!%x!", ROR(usbCmdO));
while (ROR(usbCmdO) & 2);
while ((ROR(usbCmdO) & STS_HCHALTED));
The STS_HCHALTED bit is in the Status Register, not the Command Register. Besides, if you actually were reading the Status Register, your code would not get past this point...
Also, if the HcHalted bit is indeed set, there is no need to clear the Run bit below.
Code:
cmd = ROR(usbCmdO);
WOR(usbCmdO, 2 | cmd & ~(1));
With the above code, you reset the controller again...
I am guessing you are copy/pasting code here and forget to make the modifications after the paste.
It is very wise and very recommended that you comment your code for many reasons, two that I can recommend:
1) So that if you ever come back to this code in a few years, and/or someone else reads it, they have an idea what you are doing.
and, especially for a beginners point of view:
2) So that you "verbally" write out what you are going to do, then code the code.
For example:
Code:
// Read the Command register
uint cmd = ROR(usbCmdO);
// Write it back, setting bit 2 (the Reset bit)
// and making sure the two schedule Enable bits are clear.
WOR(usbCmdO, 2 | cmd & ~(CMD_ASE | CMD_PSE));
// A small delay here would be good. You don't want to read
// the register before it has a chance to actually set the bit
ROR(usbCmndO);
// Now wait for the controller to clear the reset bit.
// Note: A timeout would be a good idea too in case the bit
// never becomes clear. (Bad controller: Bad address: etc.) (See note 1 below)
while (ROR(usbCmdO) & 2);
// Again, a small delay here would be good to allow the
// reset to actually become complete.
ROR(usbCmndO);
// wait for the halted bit to become set
// again, see note 1 below)
while (!(ROR(usbStatO) & STS_HCHALTED));
Please look over your code and make sure it is actually doing what you expect it to do.
- Ben
Note 1:
A good implementation of a driver/kernel/etc. will have a "WaitForBit" implementation. For example, if the controller takes a considerable amount of time to reset, say 50ms, the kernel can let something else proceed while it is waiting for this bit.
Also, something such as:
Code:
while (ROR(usbCmdO) & 2);
will never advance if the bit never becomes clear, and you will never know about it. Whereas a "WaitForBit" implementation can have a default timeout value, say 5000ms, and throw a kernel panic if the bit never becomes clear (or set).