From dcb5462501c54cf647def358bfa33d878769ab52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=5B=20Kristjan=20Komlo=C5=A1i=20HomePC=20=5D?= <[ kristjan.komlosi@gmail.com ]> Date: Wed, 28 Jun 2017 18:56:19 +0200 Subject: [PATCH] Ready to release 0.1! cheers to myself! --- docs/manual.md | 201 ++++++++++++++---- tinio/5-5_decrypted.cyusbd | Bin 0 -> 528 bytes tinio/flash/3-3cs_decrypted.cyusbd | Bin 0 -> 528 bytes .../flash/3in-3out-capsense_decrypted.cyusbd | Bin 528 -> 0 bytes tinio/flash/5-5_decrypted.cyusbd | Bin 0 -> 528 bytes tinio/flash/5in-5out.cyusbd | Bin 528 -> 0 bytes tinio/tinio | Bin 0 -> 18720 bytes 7 files changed, 157 insertions(+), 44 deletions(-) create mode 100755 tinio/5-5_decrypted.cyusbd create mode 100755 tinio/flash/3-3cs_decrypted.cyusbd delete mode 100755 tinio/flash/3in-3out-capsense_decrypted.cyusbd create mode 100755 tinio/flash/5-5_decrypted.cyusbd delete mode 100755 tinio/flash/5in-5out.cyusbd create mode 100755 tinio/tinio diff --git a/docs/manual.md b/docs/manual.md index 274847f..4d14d8b 100644 --- a/docs/manual.md +++ b/docs/manual.md @@ -10,7 +10,8 @@ TinI/O (or tinio) is a program that makes Linux computers with USB GPIO-capable ## 1.2 What features does TinI/O have? -- It can make any linux computer GPIO enabled +- It can make any Linux computer GPIO enabled +- It's tremendously easy to install and use - It runs as a standalone program that can be easily integrated into other programs via system() calls - It consumes almost none of the host computer's resources, because it never runs in the background - It's compatible with almost every Linux system that has USB, including the embedded and older ones @@ -18,17 +19,16 @@ TinI/O (or tinio) is a program that makes Linux computers with USB GPIO-capable ## 1.3 How does it work? -TinI/O can't provide GPIO by itself. Its capabilites rely on its chip companion ([CY7C65211][chip]), libusb and cyrozap's libcyusbserial library. When TinI/O is ran, it processes its arguments and sends commands to the chip via the before mentioned libraries. The chip then changes its GPIO pins' states accordingly. - -## 1.4 Under what license can it be used? +TinI/O can't provide GPIO by itself. Its capabilites rely on its chip companion, the Cypress ([CY7C65211][chip]), libusb and cyrozap's libcyusbserial library. When TinI/O is ran, it processes its arguments and sends commands to the chip with those libraries. The chip then changes its GPIO pins' states accordingly. However, there are some hardware limitations to that. The GPIO is digital-only, with no PWM, interrupts or ADCs. It's designed to be simple to minimize the amount of experience and knowledge needed, to straighten learning curves and not to be another conglomerate of libraries and C-like languages that some MCU platforms have become over the last decade. +## 1.4 Under what license can I use it? TinI/O is licensed under the GNU General Public License, which is publicly available at and in the COPYING file in the `docs` directory in the project's root. - +The library it depends on is licensed under LGPL. Refer to the `cylib` subfolder fore more info. # 2. Installing ## 2.1 What you should know -TinI/O binaries aren't available yet, but that isn't a problem, because TinI/O is very easy to build, even for people not familiar with program building procedures. +TinI/O binaries aren't available yet, but that shouldn't pose a problem, because TinI/O is very easy to build, even for people not familiar with program building procedures. TinI/O requires some quite basic system requirements, so before you proceed, make sure that you have: @@ -42,12 +42,12 @@ _This chapter explains how to build TinI/O manually. If you don't feel comfortab The TinI/O build process is pretty common. It's automated with a makefile, common to most *nix build processes. It has 4 build targets: -| **Target** | **Description** | -| -----------| ----------------| -| _default_ | The default target. Calls _utils_ and _tinio_ targets. | -| _tinio_ | Builds main TinI/O program. | -| _utils_ | Builds the flasher utility. | -| _install_ | Installs TinI/O and the flasher utility to /usr/bin and the flash files to /usr/bin/tinio/flashes | + | **Target** | **Description** | + | ----------- | ---------------- | + | _default_ | The default target. Calls _utils_ and _tinio_ targets. | + | _tinio_ | Builds main TinI/O program. | + | _utils_ | Builds the flasher utility. | + | _install_ | Installs TinI/O and the flasher utility to /usr/bin and the flash files to /usr/bin/tinio/flashes | ### 2.2.1 Building the Library @@ -76,43 +76,156 @@ Cypress CY7C65211 can be flashed only from Windows with a dedicated Cypress util - `3-3cs_decoded.cyusbd`, that provides 3 input and 3 output ports, plus a CapSense button with its dedicated input. And they provide the following configurations: +_Table 3.1.1: Flash files configuration_ + + | parameter | value in `5-5_decoded.cyusbd` | value in `3-3cs_decoded.cyusbd` | + | ----------- | ----------- | ------------ | + | **USB** | | | + | Max. current drawn from USB | 350 mA | 350 mA | + | USB device class | PHDC | PHDC | + | USB ID (vid:pid) | 0x04b4:0004 (Cypress) | 0x04b4:0004 (Cypress) | + | Manufacturer string | TinI/O | TinI/O | + | Product string | 5/5 | 3/3CS | + | **Serial** | | | + | UART Tx/Rx pins | 5(Tx)/6(Rx) | 5/6 | + | UART Speed | 9600 baud | 9600 baud | + | UART Data/Stop bits | 8/1 | 8/1 | + | UART Parity | None | None | + | **I/O** | | | + | I/O logic level | LVTTL | LVTTL | + | Pin 0 | Input | **RESERVED for CapSense** Should be decoupled to ground by a 2n2 capacitor | + | Pin 1 | Input | Input | + | Pin 2 | Input | **RESERVED for CapSense** CapSense sense (connect to your button) | + | Pin 3 | Input | **RESERVED for CapSense** CapSense output (the output of your button) | + | Pin 4 | Input | Input | + | Pin 5 | **RESERVED** UART Tx | UART Tx | + | Pin 6 | **RESERVED** UART Rx | UART Rx | + | Pin 7 | Output | Input | + | Pin 8 | Output | Output | + | Pin 9 | Output | Output | + | Pin 10 | Output | Output | + | Pin 11 | Output | Input | -| parameter | value in `5-5_decoded.cyusbd` | value in `3-3cs_decoded.cyusbd` | -|----|----|----| -| **USB** | | | -| Max. current drawn from USB | 350 mA | 350 mA | -| USB device class | PHDC | PHDC | -| USB ID (vid:pid) | 0x04b4:0004 (Cypress) | 0x04b4:0004 (Cypress) | -| Manufacturer string | TinI/O | TinI/O | -| Product string | 5/5 | 3/3CS | -| **Serial** | | | -| UART Tx/Rx pins | 5(Tx)/6(Rx) | 5/6 | -| UART Speed | 9600 baud | 9600 baud | -| UART Data/Stop bits | 8/1 | 8/1 | -| UART Parity | None | None | -| **I/O** | | | -| I/O logic level | LVTTL | LVTTL | -| Pin 0 | Input | **RESERVED for CapSense** Should be decoupled to ground by a 2n2 capacitor | -| Pin 1 | Input | Input | -| Pin 2 | Input | **RESERVED for CapSense** CapSense sense (connect to your button) | -| Pin 3 | Input | **RESERVED for CapSense** CapSense output (the output of your button) | -| Pin 4 | Input | Input | -| Pin 5 | **RESERVED** UART Tx | UART Tx | -| Pin 6 | **RESERVED** UART Rx | UART Rx | -| Pin 7 | Output | Input | -| Pin 8 | Output | Output | -| Pin 9 | Output | Output | -| Pin 10 | Output | Output | -| Pin 11 | Output | Input | _Note: Not all of the information here is neccesary to know when using TinI/O. For a stripped-down version refer to the next chapter, "Using TinI/O"_ -Please notice that flashing of these files isn't the only way of configuring chips. They can be also customized with the Windows utility. The important thing is that you should -configure the USB settings as described in the table above. +Please notice that flashing of these files isn't the only way of configuring chips. They can be also customized with the Windows utility. When configuring chips with it, you should pay attention to keeping USB settings as described in the table, as TinI/O can't communicate with unproperly configured devices. -## 3.3 Flashing with the `cy-config` utility -The flash files I covered in the previous chapter can be flashed with the `cy-config` utility that installs with TinI/O. The utility is text-based. It can be used by running `cy-config`. +## 3.2 The `cy-config` utility +The flash files I covered in the previous chapter can be flashed with the `cy-config` utility that installs with TinI/O. The utility is text-based. It can be used by running `cy-config`. Upon execution, it prints out a list of USB devices +``` +#cy-config -Upon execution, + +--------------------------------------------------------------------------------- +Device Number | VID | PID | INTERFACE NUMBER | FUNCTIONALITY +--------------------------------------------------------------------------------- +0 | 1d6b | 1 | 0 | NA +1 | 8bb | 2902 | 0 | NA +1 | 8bb | 2902 | 1 | NA +1 | 8bb | 2902 | 2 | NA +1 | 8bb | 2902 | 3 | NA +2 | 17e9 | 101 | 0 | NA +3 | 1d6b | 1 | 0 | NA +4 | 424 | 2504 | 0 | NA +5 | 1d6b | 1 | 0 | NA +6 | 413c | 3016 | 0 | NA +7 | 1d6b | 2 | 0 | NA +8 | 1d6b | 1 | 0 | NA +9 | 4b4 | 4 | 0 | NA +9 | 4b4 | 4 | 1 | NA +10 | 1d6b | 1 | 0 | NA +11 | 461 | 10 | 0 | NA +11 | 461 | 10 | 1 | NA +12 | d8c | c | 0 | NA +12 | d8c | c | 1 | NA +12 | d8c | c | 2 | NA +12 | d8c | c | 3 | NA +13 | 1d6b | 2 | 0 | NA +14 | bda | 111 | 0 | NA +--------------------------------------------------------------------------------- + +Cydevices 15------------------------------------------------------------------- +1: Print list of devices +2: Select device...No device selected !! +``` +At this point, you can either choose to rescan (1) or to choose a device to program (2). The rescan may help detecting new devices, but the second option should be selected for (re)programing the chip. Upon selecting it, it requests a device number: +``` +2 +Enter Device number to be selected.. + +``` +At this point should look at the device printout and search for a device with a Cypress VID (`4b4`, refer to the table 3.1.1) and enter its number (in this case 9). After that, the utility will ask for the interface number to use: +``` +9 +Enter interface number.. + +``` +You should enter the last interface number listed in the printout, for devices already programmed for use with TinI/O this would usually be 1, for factory programmed devices from Cypress it's usually 2, but those predictions aren't always right. In this case, it's 1 because the device is already programmed for TinI/O. +``` +1 + + File opened successfully + + Bytes successfully read + Programming Flash is done + File stream closed +------------------------------------------------------------------- +1: Print list of devices +2: Change device selection--selected device: [Device number 9] : [Interface No 1] : NA +``` +Such output indicates that the chip was succesfully programmed and the utility can be exited (Ctrl-C). + +# 4.Using TinI/O +## 4.1 The hardware +There is no dedicated TinI/O board out there, instead, the ([Cypress CY8CKIT-049][cykit]) is used. Its smaller part provides you with 12 GPIO pins, which can be configured in those two ways as described in the previous chapter: + +| Pin | 5in/5out config | 3in/3out config w/Capsense | +| --- | --- | --- | +| 0 | Input | RESERVED decouple to ground with a 2n2 capacitor | +| 1 | Input | Input | +| 2 | Input | Capsense button | +| 3 | Input | Capsense out | +| 4 | Input | Input| +| 5 | UART Tx | | +| 6 | UART Rx | | +| 7 | Output | Input | +| 8 | Output | Output | +| 9 | Output | Output | +| 10 | Output | Output | +| 11 | Output | Input | + + +## 4.2 The software +TinI/O isn't particularly difficult to use, because it's very simple in its design (Like, common guys, how complex and obfuscated can a code written by a 14-years-old kid be?). The bare minimum that you need to know to use TinI/O is only its name. Example: +``` +#tinio +TinI/0 0.1 +Usage: +tinio +The supported options are: +-d - specifies the desired device - integer 0 to 15 +-i - sets the specified pin to the value specified with -v - integer 0 to 11 +-r - reads the specified pin's value and prints it to the stdout - integer 0 to 11 +-v - value for -s option - integer 0 to 1 +-e - enables expert mode (enables additional pins) +``` +As you can clearly see, there isn't a lot to memorize, but if that's still too much for you, memorize the `-s`,`-r` and the `-v` option that are used to read and write to the chip's GPIO. +A few examples: +`tinio -r8` -Reads the state of the pin 8 and outputs it to the stdout +`tinio -s7 -v1` -Turns the 7th pin on + +The other options that you may use are `-d`, `-i` and `-e`. The `-d` option can be used when dealing with more than one connected device to select the one you want to work on. It's also important to know that there is absolutely no assurance that the devices will stay in order, which is the reason why wouldn't recommend using this option. +The `-i` option selects the USB interface number and doesn't need to be used in a typical used case as it defaults to 0, which is tested to work with chips flashed with the provided flash files. +The `-e` option is used to enable expert mode. Expert mode allows tampering with already-occupied pins, for example the UART transciever pins (5 and 6). It's never needed in a typical use case. +#5. Legal stuff +Windows is a registered trademark of Microsoft +Linux is a registered trademark of the Linux Foundation +Cypress is a registered trademark of Cypress +All trademarks are property of their rightful owners. This document does not intend to violate them. If I accidentaly do that, please email me at thecodingkid.devel@gmail.com and I will do my best to fix my mistakes. +This document is part of TinI/O, and is licensed under GNU GPL. Fell free to distribute! +Oh, and F*ck expensive proprietary software (unless it's a dope game)! [chip]: http://www.cypress.com/part/cy7c65211-24ltxi [cylib]: http://github.com/cyrozap/libcyusbserial +[cykit]: http://www.cypress.com/documentation/development-kitsboards/psoc-4-cy8ckit-049-4xxx-prototyping-kits diff --git a/tinio/5-5_decrypted.cyusbd b/tinio/5-5_decrypted.cyusbd new file mode 100755 index 0000000000000000000000000000000000000000..7ca20920090b02b454cabe31d8adb88690757e45 GIT binary patch literal 528 zcmZ3?!NA}g85+#Uz`*ctPwNRo1t0^2B^Vg)h`Y{VWMW|W|NlQjgDOyr1EdN8K;jsH zk?}uB1CU?@68JENR*(S1Oh(}?EG!HRjO)Qhfs6wIkUR@BCs2YCz{ecIkjaq8;K`uR o;7^u89L%Oby{2U8g=k`8ra&`TYXd*T1bMhY|4}0cE>0Q)0K@Y*(*OVf literal 0 HcmV?d00001 diff --git a/tinio/flash/3-3cs_decrypted.cyusbd b/tinio/flash/3-3cs_decrypted.cyusbd new file mode 100755 index 0000000000000000000000000000000000000000..87dec952eb46daa42e02309a3cff0283c9298408 GIT binary patch literal 528 zcmZ3?!NA}g85+#Uz`$U8;PMGW1t0^2B^Vg)h`Y{VWMW|W|NlQjgDOyr1EdN8K;r0t zk&*E~BQr?mKO@tB21XzQ7e?0#=0nV66yCzZ!oa||9%MHhfE2JWa{?tO0es9M44Djh x44w@74E|&p#KUY1)N9P(%n(eLeg+06W->J*w6Q~&lYsFD0sm1W2PRA+4FLBsHueAj literal 0 HcmV?d00001 diff --git a/tinio/flash/3in-3out-capsense_decrypted.cyusbd b/tinio/flash/3in-3out-capsense_decrypted.cyusbd deleted file mode 100755 index 4d1697502132e6b0a9d84af09e4c3e5100a886af..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 528 zcmbtRF$%&!5S+~gjJ1W9DHXJ^vo`pGkit@8(11pXTKJ9Bc0Rzy#?}w`0snH&<-mww zV`f>H+1=SK_Ur+{GztYk5#Js|pTuMbc(x}eaR99~aOZ?)rYe;6N|sDSv?$Zj;%ErT zul#aaX?IHN>bihj%0Q)0K@Y*(*OVf literal 0 HcmV?d00001 diff --git a/tinio/flash/5in-5out.cyusbd b/tinio/flash/5in-5out.cyusbd deleted file mode 100755 index f4864de1a22e53333cd56f566d46236b99413b82..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 528 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 literal 0 HcmV?d00001