Hello Werner, Thanks a lot Werner for all the explanations!!!. And for the hardware part.
I will write a test program to set the registers like you explained below (and I will use as base the ubb-vga code). Then, my idea, after to talk with you, is to use some timer to control the time between values. Then I would be ready to start to check the pins with the scope, in order to know if the D+ D- values are correct. Those are my first items in my TODO list. Thanks again, Rafa On Wed, Oct 05, 2011 at 09:41:40AM -0300, Werner Almesberger wrote: > One more item: the Ingenic SoCs have the somewhat unusual feature > that many registers are implemented as set/reset flip-flops, and > to change a bit you have to write a 1 to the corresponding set or > clear register. > > For example, to set pin PD09 to "1", you would write the value > 1 << 9 to PDDATS. To set it back to "0", you would write 1 << 9 > to PDDATC instead. > > To set pins PD08 and PD09, you would write 1 << 8 | 1 << 9 to > PDDATS, etc. > > USB uses differential signaling. This means that if D+ is 0, D- > must be 1, and vice versa. The exception to this rule are some > special conditions, like the end-of-packet indication, where > both are set to 0. This is called a "single-ended 0", abbreviated > as "SE0". All this is summarized in table 7-2 on page 145 of the > USB 2.0 specification. > > Changing a pair of pins where one goes 0 -> 1 and the other goes > 1 -> 0 requires two writes - one to PxDATS to set the pin that > should become "1", and another one to PxDATC to clear the pin > that should become "0". > > This has two undesirable properties: 1) port register accesses > are slow and this therefore burns quite a few CPU cycles, > 2) there will be a small delay between the pin changes. > > For USB, this means that during this short delay, the bus will > be in an invalid configuration. I don't know if this will cause > trouble for low-speed USB, but I wouldn't be surprised if it did. > > Here's an idea for how one could perhaps avoid this problem: > > - configure the GPIO to output D+ = 1, D- = 0 (or the opposite) > > - configure the MMC controller to output, on the same pins, > D+ = 0, D- = 1. > > - to send a differential "1" (D+ = 1, D- = 0), let the GPIOs > have the pins > > - to send a differential "0" (D+ = 0, D- = 1), let the MMC > controller have the pins > > A pin is switched between GPIO and a funcion, e.g., MMC, through > the "function" register. Again, this register is not set > directly, but its bits are set or cleared through a set and a > clear register, respectively. > > With the above approach, the bits in the function register > both change in the same direction with switching between > differential 0 and differential 1, so only a single write is > needed. > > To send a single-ended "0" (SE0) (D+ = 0, D- = 0), one would > clear the GPIO data bit for D+ and switch to GPIOs. To return > from SE0 to differential "1", one would simply set the D+ data > bit again. > > I've illustrated this here: > http://downloads.qi-hardware.com/people/werner/ubb/usb/pin-change.pdf > > The two flip-flops on top are for the GPIO data. In the middle > is the MMC controller. The two flip-flops at the bottom are > for selecting whether a pin is used as GPIO or for a function. > The pair of multiplexers right of the MMC controller switch to > GPIO if the corresponding PDFUN bit is 0 and to MMC if the bit > is 1. > > A few detail remarks and clarifications: > > - the naming convention for the port registers is > P<port><purpose><access> where > <port> is A, B, ... > <purpose> is DAT for the value output on the GPIO, FUN is the > GPIO/function selection, and so on (see the section on > "General-Purpose I/O Ports" in the JZ4720 or JZ4740 > Programming Manual) > <access> is S for set, C for clean, or nothing for reading > the register's current value. > > - all the MMC pins are on port D. The register names and bit > numbers shown in the drawing are the ones that actually > correspond to CLK and CMD. > > - in the Ingenic CPU, whether a function block has access to a > given pin is controlled on that pin. Enabling or disabling the > function block per se is independent from its access to pins. > > This is different from the way some microcontrollers handle > this, where enabling a function block automatically assigns a > set of I/O pins to it. > > - it should be relatively easy to make the MMC controller > output a constant bit pattern by setting it to a low clock > frequency and making it begin sending an MMC command. Then, > when CMD and CLK have the desired value, stop the clock. > > All the necessary ingredients for selecting the clock and, > erm, controlling the controller can be found in ubb-vga.c > Note that the MMC bus clock is the 336 MHZ main clock divided > first by 1...32 according to register MSCCDR and then by > 2^0...2^7 according to register MSC_CLKRT. > > - I haven't thought this through enough to be sure whether it's > more convenient to configure the GPIOs for a differential "1" > and MMC for a differential "0", or the other way around. I > think the best choice - if it makes a difference at all - will > automatically emerge during development. > > - I don't know whether switching a pin between function and GPIO > is "smooth" or whether there can be glitches. And I also don't > know if such a switch is, as I assume here, as fast as > setting/clearing the port's data bit would be. > > All this would have to be verified by measurement. > > - Werner _______________________________________________ Qi Hardware Discussion List Mail to list (members only): [email protected] Subscribe or Unsubscribe: http://lists.en.qi-hardware.com/mailman/listinfo/discussion

