Difference between revisions of "83Plus:USB"
(Creation!) |
(→How to Disable & Re-enable USB to Prevent USB Interrupts from Freezing Your Program/App) |
||
(4 intermediate revisions by the same user not shown) | |||
Line 11: | Line 11: | ||
It would be super-awesome if somebody wrote a general overview of USB here. | It would be super-awesome if somebody wrote a general overview of USB here. | ||
+ | |||
+ | |||
+ | == How to Disable & Re-enable USB to Prevent USB Interrupts from Freezing Your Program/App == | ||
+ | |||
+ | If you have a program/app that installs an IM2 interrupt and doesn't chain to the OS ISR, your program will freeze any time a USB cable is inserted or removed. This is because doing so issues a USB interrupt, which your program isn't handling. To fix this, use the following code before setting up your custom ISR: | ||
+ | <nowiki> in a, (2) | ||
+ | and 80h | ||
+ | jr z, noUsb | ||
+ | ; Technically, yes, the TI-83+SE has no USB, but it also doesn't have port mirroring, so this is safe. | ||
+ | xor a | ||
+ | out (57h), a | ||
+ | out (5Bh), a | ||
+ | noUsb: | ||
+ | ; Continue doing stuff</nowiki> | ||
+ | This will simply mask-out USB interrupts. The calculator will remain "connected" if it's connected to a host. Apparently, the OS USB ISR will re-enable these interrupts for you whenever you happen to call it. | ||
+ | |||
+ | If you want to fully disable USB: | ||
+ | <nowiki> out (57h), a | ||
+ | out (5Bh), a | ||
+ | out (4Ch), a | ||
+ | ld a, 2 | ||
+ | out (54h), a</nowiki> | ||
+ | This kills the 48 MHz crystal, which also disables the charge pump for major power savings. If you want to re-enable USB, write 50 to port 57h to re-enable USB interrupts and have the user disconnect and reconnect the USB cable, if connected. |
Latest revision as of 17:59, 13 November 2014
The USB driver of the TI-84+ line is divided into no fewer than three parts: A low-level physical level controller (PHY), a charge pump for generating the 5 V VBUS rail the calculator must provide in host mode, and a high-level USB controller (called the IP because it is intellectual property licensed from a 3rd party). The IP is known to be the Mentor Graphics MUSBFDRC. There is no readily available datasheet on any of those three parts; however, Mentor Graphics has published an open source Linux driver for a related IP, the MUSBHDRC, which is similar but definitely different. You can download the driver from http://sourceforge.net/projects/musb-driver/ .
All of the ports defined in musbhdrc.h begin in the Z80 port address space starting at 80h, so port 0x01 is Z80 port 81h and so on. Somebody should browse the Linux driver source and use that information to update the Wiki.
The port 4A through 7F are related to the PHY and charge pump. The PHY and IP need a 48 MHz clock signal, provided by an external crystal, which is easily visible on the PCB. (Too bad TI doesn't use this for the CPU clock; a 2x divisor would provide 24 MHz, 3x 16 MHz, and 8x 6 MHz, giving much more stable CPU clock speeds.) Setting bit 1 of port 54 will stop the USB controller parts from getting the 48 MHz, effectively turning all USB activity off. During an emergency shutdown due to battery removal, for good measure, TI also disables all USB interrupts, kills the View Screen screen DMA thingy, and places the controller into a reset state.
The IP has a built-in charge pump, but TI also has the option of using a charge pump external to the IP. BrandonW believes that the low three bits of the GPIO array control that charge pump, if present. So there really aren't two USB driver version, just two charge pump versions. This is probably at least partially dependent on the ASIC version. Disabling the clock to the PHY and IP also disables the clock to the charge pump, effectively disabling it.
It would be super-awesome if somebody wrote a general overview of USB here.
How to Disable & Re-enable USB to Prevent USB Interrupts from Freezing Your Program/App
If you have a program/app that installs an IM2 interrupt and doesn't chain to the OS ISR, your program will freeze any time a USB cable is inserted or removed. This is because doing so issues a USB interrupt, which your program isn't handling. To fix this, use the following code before setting up your custom ISR:
in a, (2) and 80h jr z, noUsb ; Technically, yes, the TI-83+SE has no USB, but it also doesn't have port mirroring, so this is safe. xor a out (57h), a out (5Bh), a noUsb: ; Continue doing stuff
This will simply mask-out USB interrupts. The calculator will remain "connected" if it's connected to a host. Apparently, the OS USB ISR will re-enable these interrupts for you whenever you happen to call it.
If you want to fully disable USB:
out (57h), a out (5Bh), a out (4Ch), a ld a, 2 out (54h), a
This kills the 48 MHz crystal, which also disables the charge pump for major power savings. If you want to re-enable USB, write 50 to port 57h to re-enable USB interrupts and have the user disconnect and reconnect the USB cable, if connected.