Giter Club home page Giter Club logo

cypress-usb-i2c-bridge's Introduction

== Version ==
0.0.1

== Steps to compile ==
This code requires libhid, libhid-dev, and libusb:

To compile, use the standard GNU Autotools build procedure
 $ autoreconf
 $ ./configure
 $ make
 $ sudo make install


== Steps to debug ==
Since this library is now compiled with libtool, you must specify the
mode in libtool before starting your ddd or gdb debuggger.

 $ libtool --mode=execute ddd ./cy3240_i2c

== Introduction ==
The library has been modified from the original version from WingNut

FIXIT wingnut dot foss FIXIT @ gmail dot FIXIT com
(remove the words FIXIT and the space and change dot to . for a valid address)

     --Angrytuna

Below are the comments from the original post:

=== Overview ===
This code exercises the CY3240 development kit from Cypress Semiconductor.  
The kit contains 2 boards.  The primary board contains the controller that
switches on and off 3.3V and 5V power, a couple LEDs and has a couple pads for
GPIO pins.  The primary board and I2C to USB path is controlled by a Cypress
Semiconductor CY8C24894-24L (http://www.cypress.com/?rID=3371).  There is also
a Maxim MAX3378 (http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3253/t/al) level
translator and a Littlefuse SP721
(http://www.littelfuse.com/data/en/Data_Sheets/SP721.pdf) overvoltage /
undervoltage protection IC.

The kit also ships with an example board, carrying a Cypress Semiconductor
CY8C21123-24SXI (http://www.cypress.com/?rID=3335) 8 pin PSoC and a couple
LEDs.

The example code defines some of the registers, control bits to send, etc.  It
also powers the example device to 5V, blinks both LEDs on the example device,
then powers off the device.


=== Notes of the how the underlying USB HID interfaces works ===

1. Determine usage paths
using the notes in test_hidlib.c for how to read and write from a device, run:
libhid_detach_device 04b4:f232
lsusb -d 0x04b4:0f232 -vvv

it should output something like this:

Bus 002 Device 007: ID 04b4:f232 Cypress Semiconductor Corp. 
Device Descriptor:
  [...]
  Configuration Descriptor:
    [...]
    Interface Descriptor:
      [...]
      iInterface              3 HID R_W8
        HID Device Descriptor:
          [...]
          Report Descriptor: (length is 37)
            Item(Global): Usage Page, data= [ 0xa0 0xff ] 65440
            [...]
            Item(Local ): Usage, data= [ 0x01 ] 1
            [...]
            Item(Local ): Usage, data= [ 0x02 ] 2
            [...]
            Item(Local ): Usage, data= [ 0x03 ] 3
            [...]
            Item(Main  ): Output, data= [ 0x02 ] 2
            [...]
            Item(Local ): Usage, data= [ 0x04 ] 4
            [...]
            Item(Main  ): Input, data= [ 0x02 ] 2

So working backwards:
  "Item(Main  ): Input, data= [ 0x02 ] 2" is usage 4 of usage page 65440
  which is rooted at "Item(Local ): Usage, data= [ 0x02 ] 2"
  which is rooted at "Item(Local ): Usage, data= [ 0x01 ] 1"

giving the input path of:
  65440 << 16 + 1  -> 0xffa0 0001
  65440 << 16 + 2  -> 0xffa0 0002
  65440 << 16 + 4  -> 0xffa0 0004

And the output path of
  65440 << 16 + 1  -> 0xffa0 0001
  65440 << 16 + 2  -> 0xffa0 0002
  65440 << 16 + 3  -> 0xffa0 0003

These are the paths to the control nodes in the device.  However, the code that
is shipped with the device doesn't use these paths.  Instead, the interrupt 
endpoints are used, and we'll see in the captured USB packets.  Later on in the
same lsusb dump are the lines:
Endpoint Descriptor:
  bLength                 7
  bDescriptorType         5
  bEndpointAddress     0x01  EP 1 OUT
  bmAttributes            3
    Transfer Type            Interrupt
    Synch Type               None
    Usage Type               Data
  wMaxPacketSize     0x0040  1x 64 bytes
  bInterval               1
Endpoint Descriptor:
  bLength                 7
  bDescriptorType         5
  bEndpointAddress     0x82  EP 2 IN
  bmAttributes            3
    Transfer Type            Interrupt
    Synch Type               None
    Usage Type               Data
  wMaxPacketSize     0x0040  1x 64 bytes
  bInterval               1

Which means that there are 2 interrupts, one input interrupt (EP 2 IN at
endpoint address 0x82) and one output interrupt (EP 1 OUT at endpoint address
0x01).  As Cypress defines in their datasheet, these accept packets of 64
bytes.  This means that communication should take place using the
hid_interrupt_read() and hid_interrupt_write() functions.

----
3. Use USBSnoop to get control packet information
I used the one from:
http://www.pcausa.com/Utilities/UsbSnoop/
because they have a 64 bit windows compile, and i only have 64 bit win2k3

A couple things to look at:
a.) There are periodic reads:
[43665 ms]  >>>  URB 17 going down  >>> 
-- URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
  PipeHandle           = e79e99c8 [endpoint 0x00000001]
  TransferFlags        = 00000002 (USBD_TRANSFER_DIRECTION_OUT, USBD_SHORT_TRANS
  TransferBufferLength = 00000040
  TransferBuffer       = e51f82da
  TransferBufferMDL    = 00000000
    00000000: 03 02 80 00 00 00 00 00 00 00 00 00 00 00 00 00
    00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  UrbLink              = 00000000
[43667 ms] UsbSnoop - MyInternalIOCTLCompletion(e2d37ddc) : fido=ff503830, Irp=f
[43667 ms]  <<<  URB 17 coming back  <<<

Looks like it happens every 250 ms.  According to the Cyress Documentation,
this is a read and start condition (0x03), length of 2 bytes (0x02) and the
last word in the packet, using address 0x80, and the data is 0x0000.  This is
to check the status of the device and update the GUI.

b.) Following every read is the returned status of the device:
[43668 ms]  >>>  URB 18 going down  >>> 
-- URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
  PipeHandle           = e79e99f8 [endpoint 0x00000082]
  TransferFlags        = 00000003 (USBD_TRANSFER_DIRECTION_IN, USBD_SHORT_TRANSF
  TransferBufferLength = 00000040
  TransferBuffer       = e7176a70
  TransferBufferMDL    = 00000000
  UrbLink              = 00000000
[43920 ms] UsbSnoop - FilterDispatchAny(e2d37b90) : IRP_MJ_INTERNAL_DEVICE_CONTR
[43920 ms] UsbSnoop - FdoHookDispatchInternalIoctl(e2d37f8c) : fdo=ff4bd960, Irp

which takes a while (about 500 ms) to return:

[44184 ms]  <<<  URB 18 coming back  <<< 
-- URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
  PipeHandle           = e79e99f8 [endpoint 0x00000082]
  TransferFlags        = 00000003 (USBD_TRANSFER_DIRECTION_IN, USBD_SHORT_TRANSF
  TransferBufferLength = 00000040
  TransferBuffer       = e7176a70
  TransferBufferMDL    = e6dcabf0
    00000000: 01 00 00 00 01 01 16 00 a5 00 00 00 00 00 00 00
    00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  UrbLink              = 00000000
[44184 ms] UsbSnoop - FilterDispatchAny(e2d37b90) : IRP_MJ_INTERNAL_DEVICE_CONTR

Again, according to the Cypress documentation, this is a status of 0x01, and
the data returned is 0x0000 0001 0116 00a5

c.) Here's a write...apply 5v power
[83953 ms]  >>>  URB 97 going down  >>> 
-- URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
  PipeHandle           = e79e99c8 [endpoint 0x00000001]
  TransferFlags        = 00000002 (USBD_TRANSFER_DIRECTION_OUT, USBD_SHORT_TRANS
  TransferBufferLength = 00000040
  TransferBuffer       = e50b32da
  TransferBufferMDL    = 00000000
    00000000: 02 01 80 01 00 00 00 00 00 00 00 00 00 00 00 00
    00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  UrbLink              = 00000000
[83955 ms] UsbSnoop - MyInternalIOCTLCompletion(e2d37ddc) : fido=ff503830, Irp=e
[83955 ms]  <<<  URB 97 coming back  <<< 

This is a write and start (0x02), length of 0x01, address of 0x80, and data of
0x01

d.) This is setting one of the LEDs
[158175 ms]  >>>  URB 765 going down  >>> 
-- URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
  PipeHandle           = e79e99c8 [endpoint 0x00000001]
  TransferFlags        = 00000002 (USBD_TRANSFER_DIRECTION_OUT,
USBD_SHORT_TRANS
  TransferBufferLength = 00000040
  TransferBuffer       = e51612da
  TransferBufferMDL    = 00000000
    00000000: 0a 08 00 00 00 00 00 00 02 ff 01 00 00 00 00 00
    00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  UrbLink              = 00000000
[158176 ms] UsbSnoop - MyInternalIOCTLCompletion(e2d37ddc) : fido=ff503830,
Irp=
[158177 ms]  <<<  URB 765 coming back  <<< 

This is a start and stop (0x0a), length of 0x08, address 0x00, data of 
0x0000 0000 0002 ff01.  This is setting LED 2 to a value of 0xFF

---
4. Using this information and the datasheet, we extract the info we need:
All transfers occur as:
URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER

Every packet is 64 bytes.

Only the interrupt endpoints are read / written:
  PipeHandle           = e79e99f8 [endpoint 0x00000082]
  PipeHandle           = e79e99c8 [endpoint 0x00000001]

And the data is defined in the datasheet.  With all that info, the reads and
writes look something like:

    SEND_PACKET[0] = I2C_WRITE | I2C_START | I2C_STOP;
    SEND_PACKET[1] = I2C_LAST_PACKET | 0x08;
    SEND_PACKET[2] = PSOC;
    SEND_PACKET[3] = 0x00;
    SEND_PACKET[LED_NUMBER] = 0x01;
    SEND_PACKET[BRIGHTNESS] = ~SEND_PACKET[BRIGHTNESS];
    SEND_PACKET[UNK_7] = 0x01;
    ret = hid_interrupt_write(hid, OUTPUT_ENDPOINT, SEND_PACKET, SEND_PACKET_LEN, timeout);

    ret = hid_interrupt_read(hid, INPUT_ENDPOINT, &RECV_PACKET, RECV_PACKET_LEN, timeout);

cypress-usb-i2c-bridge's People

Contributors

bluetiger9 avatar kevinkirkup avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.