I haven't had a chance to look over your code yet, but I plan on it soon.
One of the biggest things to recognize when it works on emulators, whom are horrible at absolute timing, and real hardware, which is excellent at real timing, is, well you guessed it, timing.
You must allow the hardware to actually do what it is asked to do. On an emulator, the emulation is already there. i.e.: as soon as you request the data, the data is already there waiting to be sent. On real hardware, this is not necessarily the case.
Also, the reset of the device has a lot of differences between emulators and hardware. On an emulator, it simply is the setting and clearing of the reset bit. Done. On real hardware, it is the timing between the time the reset bit is set, then cleared, as well as which other bits are set or cleared at the same time. If my memory serves, one of the bits in the Ports register *must* be cleared before or at the same time you clear the reset bit or a device will not reset.
Welcome to the art of real hardware testing. I will tell you, a hardware analyzer, such as the Beagle I got, is a wonderful piece of hardware to help with this stuff, if you can afford the expense.
When I get a chance, I will have a look at your code. In the meantime, check your reset timing and other timing code.
code, you acknowledge the Master before the Slave. This is backwards. You should acknowledge the slave first. If not, the master might try to "fire" the slave pin while the slave is still "busy".
you say that you are initializing the port. However, you are writing to the first register of the address space, yes? This isn't where the first port is.
I send the Global Reset (bit 2) instead of the HCReset (bit 1). This makes sure that all devices attached also see a reset.
i.e.: Using "(1<<8)" is much easier to read than "0b0000000100000000". You don't have to count bits with (1<<8).
- Some controllers/devices require the schedule to be running before a port reset.
- You *must* check the "HcHalted" bit after starting/stopping the schedule. Simply setting or clearing the "Run" bit does not mean it is started/stopped. The "HcHalted" bit indicates if the schedule is running or not.
All routines that manipulate a port should have an index such as this.
This is so much easier to read, allowing the reader (you) to know which register you are writing to. Go a little further and use #define's for each bit as well.
I tried to add the things you have said.
I uploaded the new code to GitHub.
-elcome to the Sanderslando Kernel!!
Also, must I set the runbit in order to detect the devices? since I have no commands for my queue.
Because the controller will not clear bit 2 when it is done. You must clear it after 10ms. Please note that this is 10 milliseconds, not 10 seconds. Your code suggests that you are waiting one (1) second per tick. This is way too long. Also, after the reset, clearing the bit, you need to delay again for USB_TRSTRCY milliseconds. This is the recovery wait.
Also, must I set the run bit in order to detect the devices? since I have no commands for my queue.
You shouldn't have to, per the specification, but I have found that if the run bit is not set, some controllers don't perform as advertised. I have seen comments to this in other code/documentation as well.
Just curious to see if you made any progress on this?
No, I have not made any progress.
I had a small pause and then started again with hope this time it would go better.
Still, on the emulators (BOCHS and QEMU) it is working while on real hardware it is still refusing.
I am currently working on a way to make the queue work and maybe it is detected that way.
The system is booted from USB, but LEGACY says it is 0xFFFF so probably it will not change the outcome of my code.