├── .gitignore ├── .gitmodules ├── LICENSE.md ├── README.md ├── asf ├── doc ├── DonglePi Features.pdf ├── DonglePi General.pdf ├── README ├── mapping-donglepi-rpi-1.png ├── mapping-donglepi-rpi-2.png ├── mapping-donglepi-rpi.html ├── mapping-donglepi-rpi.ods └── mapping-donglepi-rpi.pdf ├── firmware ├── Makefile ├── asf.h ├── conf_board.h ├── conf_clocks.h ├── conf_extint.h ├── conf_sleepmgr.h ├── conf_spi.h ├── conf_usb.h ├── config.mk ├── copy.sh ├── dbg.c ├── dbg.h ├── donglepi.c ├── donglepi.h ├── gpio.c ├── gpio.h ├── i2c.c ├── i2c.h ├── lz4 │ ├── LICENSE │ ├── Makefile │ ├── liblz4.pc.in │ ├── lz4.c │ ├── lz4.h │ ├── lz4frame.c │ ├── lz4frame.h │ ├── lz4frame_static.h │ ├── lz4hc.c │ ├── lz4hc.h │ ├── xxhash.c │ └── xxhash.h ├── openocd.cfg ├── pins.c ├── pins.h ├── protocol │ └── Makefile ├── spi.c ├── spi.h ├── uart.c ├── uart.h └── ui.h ├── pcb ├── DESCRIPTION ├── DonglePi.brd ├── DonglePi.sch ├── eagle.epf └── gbin.lbr ├── protocol └── donglepi.proto └── python ├── DPi ├── GPIO.py ├── __init__.py └── smbus.py ├── Makefile ├── requirements.txt └── test.py /.gitignore: -------------------------------------------------------------------------------- 1 | pcb/*.?#? 2 | firmware/protocol/donglepi.pb.c 3 | firmware/protocol/donglepi.pb.h 4 | firmware/**/*.d 5 | firmware/**/*.o 6 | firmware/**/*.hex 7 | firmware/*.bin 8 | firmware/*.elf 9 | firmware/*.lss 10 | firmware/*.map 11 | firmware/*.sym 12 | **/*.pyc 13 | python/DPi/donglepi_pb2.py 14 | python/DPi/nanopb_pb2.py 15 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "firmware/nanopb"] 2 | path = firmware/nanopb 3 | url = https://code.google.com/p/nanopb/ 4 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # Creative Commons — Attribution-NonCommercial 4.0 International — CC BY-NC 4.0 2 | 3 | Creative Commons Corporation ("Creative Commons") is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an "as-is" basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible. 4 | 5 | **Using Creative Commons Public Licenses** 6 | 7 | Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses. 8 | 9 | > **Considerations for licensors:** Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation to copyright. [More considerations for licensors.][2] 10 | 11 | > **Considerations for the public:** By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensor's permission is not necessary for any reason–for example, because of any applicable exception or limitation to copyright–then that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. [More considerations for the public.][3] 12 | 13 | ### Creative Commons Attribution-NonCommercial 4.0 International Public License 14 | 15 | By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution-NonCommercial 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions. 16 | 17 | **Section 1 – Definitions.** 18 | 19 | 1. **Adapted Material** means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image. 20 | 2. **Adapter's License** means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License. 21 | 3. **Copyright and Similar Rights** means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section [2(b)(1)-(2)][4] are not Copyright and Similar Rights. 22 | 4. **Effective Technological Measures** means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements. 23 | 5. **Exceptions and Limitations** means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material. 24 | 6. **Licensed Material** means the artistic or literary work, database, or other material to which the Licensor applied this Public License. 25 | 7. **Licensed Rights** means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license. 26 | 8. **Licensor** means the individual(s) or entity(ies) granting rights under this Public License. 27 | 9. **NonCommercial** means not primarily intended for or directed towards commercial advantage or monetary compensation. For purposes of this Public License, the exchange of the Licensed Material for other material subject to Copyright and Similar Rights by digital file-sharing or similar means is NonCommercial provided there is no payment of monetary compensation in connection with the exchange. 28 | 10. **Share** means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them. 29 | 11. **Sui Generis Database Rights** means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world. 30 | 12. **You** means the individual or entity exercising the Licensed Rights under this Public License. **Your** has a corresponding meaning. 31 | 32 | **Section 2 – Scope.** 33 | 34 | 1. **License grant**. 35 | 1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to: 36 | 1. reproduce and Share the Licensed Material, in whole or in part, for NonCommercial purposes only; and 37 | 2. produce, reproduce, and Share Adapted Material for NonCommercial purposes only. 38 | 2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions. 39 | 3. Term. The term of this Public License is specified in Section [6(a)][5]. 40 | 4. Media and formats; technical modifications allowed. The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section [2(a)(4)][6] never produces Adapted Material. 41 | 5. Downstream recipients. 42 | 43 | 1. Offer from the Licensor – Licensed Material. Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License. 44 | 2. No downstream restrictions. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material. 45 | 46 | 6. No endorsement. Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section [3(a)(1)(A)(i)][7]. 47 | 2. **Other rights**. 48 | 49 | 1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise. 50 | 2. Patent and trademark rights are not licensed under this Public License. 51 | 3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties, including when the Licensed Material is used other than for NonCommercial purposes. 52 | 53 | **Section 3 – License Conditions.** 54 | 55 | Your exercise of the Licensed Rights is expressly made subject to the following conditions. 56 | 57 | 1. **Attribution**. 58 | 59 | 1. If You Share the Licensed Material (including in modified form), You must: 60 | 61 | 1. retain the following if it is supplied by the Licensor with the Licensed Material: 62 | 1. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated); 63 | 2. a copyright notice; 64 | 3. a notice that refers to this Public License; 65 | 4. a notice that refers to the disclaimer of warranties; 66 | 5. a URI or hyperlink to the Licensed Material to the extent reasonably practicable; 67 | 2. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and 68 | 3. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License. 69 | 2. You may satisfy the conditions in Section [3(a)(1)][8] in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information. 70 | 3. If requested by the Licensor, You must remove any of the information required by Section [3(a)(1)(A)][9] to the extent reasonably practicable. 71 | 4. If You Share Adapted Material You produce, the Adapter's License You apply must not prevent recipients of the Adapted Material from complying with this Public License. 72 | 73 | **Section 4 – Sui Generis Database Rights.** 74 | 75 | Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material: 76 | 77 | 1. for the avoidance of doubt, Section [2(a)(1)][10] grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database for NonCommercial purposes only; 78 | 2. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material; and 79 | 3. You must comply with the conditions in Section [3(a)][11] if You Share all or a substantial portion of the contents of the database. 80 | For the avoidance of doubt, this Section [4][12] supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights. 81 | 82 | **Section 5 – Disclaimer of Warranties and Limitation of Liability.** 83 | 84 | 1. **Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.** 85 | 2. **To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.** 86 | 3. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability. 87 | 88 | **Section 6 – Term and Termination.** 89 | 90 | 1. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically. 91 | 2. Where Your right to use the Licensed Material has terminated under Section [6(a)][5], it reinstates: 92 | 93 | 1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or 94 | 2. upon express reinstatement by the Licensor. 95 | For the avoidance of doubt, this Section [6(b)][13] does not affect any right the Licensor may have to seek remedies for Your violations of this Public License. 96 | 3. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License. 97 | 4. Sections [1][14], [5][15], [6][16], [7][17], and [8][18] survive termination of this Public License. 98 | 99 | **Section 7 – Other Terms and Conditions.** 100 | 101 | 1. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed. 102 | 2. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License. 103 | 104 | **Section 8 – Interpretation.** 105 | 106 | 1. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License. 107 | 2. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions. 108 | 3. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor. 109 | 4. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority. 110 | 111 | Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the "Licensor." Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at [creativecommons.org/policies][19], Creative Commons does not authorize the use of the trademark "Creative Commons" or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses. 112 | 113 | Creative Commons may be contacted at [creativecommons.org][20]. 114 | 115 | [1]: http://creativecommons.org/images/international/unported.png 116 | [2]: http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensors 117 | [3]: http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensees 118 | [4]: http://creativecommons.org#s2b 119 | [5]: http://creativecommons.org#s6a 120 | [6]: http://creativecommons.org#s2a4 121 | [7]: http://creativecommons.org#s3a1Ai 122 | [8]: http://creativecommons.org#s3a1 123 | [9]: http://creativecommons.org#s3a1A 124 | [10]: http://creativecommons.org#s2a1 125 | [11]: http://creativecommons.org#s3a 126 | [12]: http://creativecommons.org#s4 127 | [13]: http://creativecommons.org#s6b 128 | [14]: http://creativecommons.org#s1 129 | [15]: http://creativecommons.org#s5 130 | [16]: http://creativecommons.org#s6 131 | [17]: http://creativecommons.org#s7 132 | [18]: http://creativecommons.org#s8 133 | [19]: http://creativecommons.org/policies 134 | [20]: http://creativecommons.org/ 135 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ![pcb](http://gbin.github.io/DonglePi/images/pcb.png) 3 | 4 | DonglePi is a device that gives you a Raspberry Pi P1 compatible connector for your PC. 5 | 6 | The RPi P1 is a defacto standard connector on all models with pins for: 7 | - GPIO 8 | - I2C 9 | - SPI 10 | - Serial 11 | - PWM 12 | 13 | [More info about it.](http://elinux.org/RPi_Low-level_peripherals) 14 | 15 | On the software side, it exposes APIs that are compatible with the ones you can use on the Raspberry Pi like [GPIO](https://pypi.python.org/pypi/RPi.GPIO/) and [smbus](http://www.raspberry-projects.com/pi/programming-in-python/i2c-programming-in-python/using-the-i2c-interface-2) under python. 16 | 17 | ## Why ? 18 | 19 | With DonglePi: 20 | - you can use your familiar PC or Mac to directly develop & debug your RPi embedded applications (with an IDE for example) 21 | - you can use peripherals made for the Raspberry Pi ecosystem on your PC. You can find a list of those [here](http://elinux.org/RPi_VerifiedPeripherals). 22 | 23 | DonglePi can also be used to easily setup students for an embedded development course in a preexisting computer lab. 24 | 25 | The fidelity with the original hardware won't be 100% but it doesn't need to be to be useful. 26 | 27 | ## Current Status 28 | 29 | It is a prototype working on a breadboard. 30 | The goal is to make a PCB like the one above. 31 | 32 | On the software side: 33 | - GPIOs are working. 34 | - I2C is working. 35 | - SPI is in progress. 36 | - PWM needs to be done. 37 | - Serial is currently used for debug but should be easy after all that :). 38 | 39 | ## Hardware 40 | 41 | It can be plugged on any USB2 port. 42 | 43 | You can build a prototype on a breadboard using an Atmel SAMD21 development board. 44 | I recommend [this one](http://www.ebay.com/itm/131296219501?_trksid=p2060778.m2749.l2649&var=430589049056&ssPageName=STRK%3AMEBIDX%3AIT). Be sure to take the one with the bootloader if you are not comfortable playing with an Arm/JTAG probe. 45 | 46 | For the RPi connector, you can use a [Pi cobbler kit](https://learn.adafruit.com/adafruit-pi-cobbler-kit/overview) from adafruit. 47 | 48 | ![breadboard](http://gbin.github.io/DonglePi/images/breadboard.jpg) 49 | 50 | You can find [here](http://gbin.github.io/DonglePi/video/i2c_demo.mp4) a little demo of it driving an i2c device. 51 | 52 | ## Software 53 | 54 | ### Dependencies 55 | 56 | Get the [asf sdk](http://www.atmel.com/System/GetBinary.ashx?target=tcm:26-49230&type=soft&actualTarget=tcm:26-65233) 57 | It needs to be linked to the asf directory in the root of the project (by default it looks for the latest version in your home directory). 58 | 59 | Sync the submodule: 60 | 61 | git submodule update --init firmware/nanopb 62 | 63 | Install google protobuf: 64 | 65 | pip install -user protobuf 66 | #(or under arch for example) 67 | sudo pacman -S protobuf python2-protobuf 68 | 69 | Install gcc for arm bare metal: 70 | 71 | # (under arch) 72 | sudo pacman -S arm-none-eabi-gcc 73 | # Otherwise you can always get the binaries there: 74 | https://launchpad.net/gcc-arm-embedded/+download 75 | 76 | Install pyserial: 77 | 78 | pip install pyserial 79 | 80 | ### Building the firmware 81 | 82 | From firmware/: 83 | 84 | make 85 | 86 | It will produce a flash.bin file. 87 | 88 | ### Installing the fimware 89 | 90 | If you have the recommanded dev board, connect it on USB, press Reset + Button B. It will appear as a standard USB storage device. 91 | The red led from the board should slowly blink. 92 | Copy flash.bin to the root of it. 93 | Unmount the disk. 94 | Reset it, the led should switch to solid red = it has correctly initialized and wait for commands. 95 | 96 | ### Building the client side support. 97 | 98 | From python/: 99 | 100 | make 101 | 102 | This should generate some files from tht protobuf so the bindings could talk to the hardware. 103 | 104 | Here you have a test.py showing how to use the bindings. 105 | 106 | ### Debug logs. 107 | 108 | For the moment, I have dedicated the serial output to that, you can connect it for example to a real RPi at 115200 BPS and use minicom to see the debug logs. 109 | 110 | ## Help Wanted ! 111 | 112 | Any contribution or contributor is welcomed ! 113 | If you want to contribute some code, feel free to open a pull request. 114 | If you have some experience developing PCBs, feel free to contribute to the Eagle project. 115 | 116 | ## And the license ? 117 | 118 | This is under CC-NY-NC 4.0 (see LICENSE.md). 119 | If this license doesn't fit your need: feel free to contact me at gbin@gootz.net. 120 | 121 | -------------------------------------------------------------------------------- /asf: -------------------------------------------------------------------------------- 1 | ../../asf-3.21.0 -------------------------------------------------------------------------------- /doc/DonglePi Features.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbin/DonglePi/82f61dc66d3b4f4d6407ef872ad0284fe2aa39ff/doc/DonglePi Features.pdf -------------------------------------------------------------------------------- /doc/DonglePi General.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbin/DonglePi/82f61dc66d3b4f4d6407ef872ad0284fe2aa39ff/doc/DonglePi General.pdf -------------------------------------------------------------------------------- /doc/README: -------------------------------------------------------------------------------- 1 | General 2 | ------- 3 | DonglePi General.pdf : General presentation of the project. 4 | DonglePi Features.pdf : List of projected features. 5 | 6 | 7 | Technical 8 | --------- 9 | Mapping RPi J8 header -- D21E.ods : The pin mapping between the SAMD21 and the connector. 10 | -------------------------------------------------------------------------------- /doc/mapping-donglepi-rpi-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbin/DonglePi/82f61dc66d3b4f4d6407ef872ad0284fe2aa39ff/doc/mapping-donglepi-rpi-1.png -------------------------------------------------------------------------------- /doc/mapping-donglepi-rpi-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbin/DonglePi/82f61dc66d3b4f4d6407ef872ad0284fe2aa39ff/doc/mapping-donglepi-rpi-2.png -------------------------------------------------------------------------------- /doc/mapping-donglepi-rpi.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbin/DonglePi/82f61dc66d3b4f4d6407ef872ad0284fe2aa39ff/doc/mapping-donglepi-rpi.ods -------------------------------------------------------------------------------- /doc/mapping-donglepi-rpi.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbin/DonglePi/82f61dc66d3b4f4d6407ef872ad0284fe2aa39ff/doc/mapping-donglepi-rpi.pdf -------------------------------------------------------------------------------- /firmware/Makefile: -------------------------------------------------------------------------------- 1 | # List of available make goals: 2 | # 3 | # all Default target, builds the project 4 | # clean Clean up the project 5 | # rebuild Rebuild the project 6 | # debug_flash Builds the project and debug in flash 7 | # debug_sram Builds the project and debug in sram 8 | # 9 | # doc Build the documentation 10 | # cleandoc Clean up the documentation 11 | # rebuilddoc Rebuild the documentation 12 | # 13 | # \file 14 | # 15 | # Copyright (c) 2011 - 2014 Atmel Corporation. All rights reserved. 16 | # 17 | # \asf_license_start 18 | # 19 | # \page License 20 | # 21 | # Redistribution and use in source and binary forms, with or without 22 | # modification, are permitted provided that the following conditions are met: 23 | # 24 | # 1. Redistributions of source code must retain the above copyright notice, 25 | # this list of conditions and the following disclaimer. 26 | # 27 | # 2. Redistributions in binary form must reproduce the above copyright notice, 28 | # this list of conditions and the following disclaimer in the documentation 29 | # and/or other materials provided with the distribution. 30 | # 31 | # 3. The name of Atmel may not be used to endorse or promote products derived 32 | # from this software without specific prior written permission. 33 | # 34 | # 4. This software may only be redistributed and used in connection with an 35 | # Atmel microcontroller product. 36 | # 37 | # THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED 38 | # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 39 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 40 | # EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR 41 | # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 42 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 43 | # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44 | # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 45 | # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 46 | # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 47 | # POSSIBILITY OF SUCH DAMAGE. 48 | # 49 | # \asf_license_stop 50 | # 51 | 52 | # Include the config.mk file from the current working path, e.g., where the 53 | # user called make. 54 | include config.mk 55 | 56 | # Tool to use to generate documentation from the source code 57 | DOCGEN ?= doxygen 58 | 59 | # Look for source files relative to the top-level source directory 60 | VPATH := $(PRJ_PATH) 61 | 62 | # Output target file 63 | project_type := $(PROJECT_TYPE) 64 | 65 | # Output target file 66 | ifeq ($(project_type),flash) 67 | target := $(TARGET_FLASH) 68 | linker_script := $(PRJ_PATH)/$(LINKER_SCRIPT_FLASH) 69 | debug_script := $(PRJ_PATH)/$(DEBUG_SCRIPT_FLASH) 70 | else 71 | target := $(TARGET_SRAM) 72 | linker_script := $(PRJ_PATH)/$(LINKER_SCRIPT_SRAM) 73 | debug_script := $(PRJ_PATH)/$(DEBUG_SCRIPT_SRAM) 74 | endif 75 | 76 | # Output project name (target name minus suffix) 77 | project := $(basename $(target)) 78 | 79 | # Output target file (typically ELF or static library) 80 | ifeq ($(suffix $(target)),.a) 81 | target_type := lib 82 | else 83 | ifeq ($(suffix $(target)),.elf) 84 | target_type := elf 85 | else 86 | $(error "Target type $(target_type) is not supported") 87 | endif 88 | endif 89 | 90 | # Allow override of operating system detection. The user can add OS=Linux or 91 | # OS=Windows on the command line to explicit set the host OS. 92 | # 93 | # This allows to work around broken uname utility on certain systems. 94 | ifdef OS 95 | ifeq ($(strip $(OS)), Linux) 96 | os_type := Linux 97 | endif 98 | ifeq ($(strip $(OS)), Windows) 99 | os_type := windows32_64 100 | endif 101 | endif 102 | 103 | os_type ?= $(strip $(shell uname)) 104 | 105 | ifeq ($(os_type),windows32) 106 | os := Windows 107 | else 108 | ifeq ($(os_type),windows64) 109 | os := Windows 110 | else 111 | ifeq ($(os_type),windows32_64) 112 | os ?= Windows 113 | else 114 | ifeq ($(os_type),) 115 | os := Windows 116 | else 117 | # Default to Linux style operating system. Both Cygwin and mingw are fully 118 | # compatible (for this Makefile) with Linux. 119 | os := Linux 120 | endif 121 | endif 122 | endif 123 | endif 124 | 125 | # Output documentation directory and configuration file. 126 | docdir := ../doxygen/html 127 | doccfg := ../doxygen/doxyfile.doxygen 128 | 129 | CROSS ?= arm-none-eabi- 130 | AR := $(CROSS)ar 131 | AS := $(CROSS)as 132 | CC := $(CROSS)gcc 133 | CPP := $(CROSS)gcc -E 134 | CXX := $(CROSS)g++ 135 | LD := $(CROSS)g++ 136 | NM := $(CROSS)nm 137 | OBJCOPY := $(CROSS)objcopy 138 | OBJDUMP := $(CROSS)objdump 139 | SIZE := $(CROSS)size 140 | GDB := $(CROSS)gdb 141 | 142 | RM := rm 143 | ifeq ($(os),Windows) 144 | RMDIR := rmdir /S /Q 145 | else 146 | RMDIR := rmdir -p --ignore-fail-on-non-empty 147 | endif 148 | 149 | # On Windows, we need to override the shell to force the use of cmd.exe 150 | ifeq ($(os),Windows) 151 | SHELL := cmd 152 | endif 153 | 154 | # Strings for beautifying output 155 | MSG_CLEAN_FILES = "RM *.o *.d" 156 | MSG_CLEAN_DIRS = "RMDIR $(strip $(clean-dirs))" 157 | MSG_CLEAN_DOC = "RMDIR $(docdir)" 158 | MSG_MKDIR = "MKDIR $(dir $@)" 159 | 160 | MSG_INFO = "INFO " 161 | MSG_PREBUILD = "PREBUILD $(PREBUILD_CMD)" 162 | MSG_POSTBUILD = "POSTBUILD $(POSTBUILD_CMD)" 163 | 164 | MSG_ARCHIVING = "AR $@" 165 | MSG_ASSEMBLING = "AS $@" 166 | MSG_BINARY_IMAGE = "OBJCOPY $@" 167 | MSG_COMPILING = "CC $@" 168 | MSG_COMPILING_CXX = "CXX $@" 169 | MSG_EXTENDED_LISTING = "OBJDUMP $@" 170 | MSG_IHEX_IMAGE = "OBJCOPY $@" 171 | MSG_LINKING = "LN $@" 172 | MSG_PREPROCESSING = "CPP $@" 173 | MSG_SIZE = "SIZE $@" 174 | MSG_SYMBOL_TABLE = "NM $@" 175 | 176 | MSG_GENERATING_DOC = "DOXYGEN $(docdir)" 177 | 178 | # Don't use make's built-in rules and variables 179 | MAKEFLAGS += -rR 180 | 181 | # Don't print 'Entering directory ...' 182 | MAKEFLAGS += --no-print-directory 183 | 184 | # Function for reversing the order of a list 185 | reverse = $(if $(1),$(call reverse,$(wordlist 2,$(words $(1)),$(1)))) $(firstword $(1)) 186 | 187 | # Hide command output by default, but allow the user to override this 188 | # by adding V=1 on the command line. 189 | # 190 | # This is inspired by the Kbuild system used by the Linux kernel. 191 | ifdef V 192 | ifeq ("$(origin V)", "command line") 193 | VERBOSE = $(V) 194 | endif 195 | endif 196 | ifndef VERBOSE 197 | VERBOSE = 0 198 | endif 199 | 200 | ifeq ($(VERBOSE), 1) 201 | Q = 202 | else 203 | Q = @ 204 | endif 205 | 206 | arflags-gnu-y := $(ARFLAGS) 207 | asflags-gnu-y := $(ASFLAGS) 208 | cflags-gnu-y := $(CFLAGS) 209 | cxxflags-gnu-y := $(CXXFLAGS) 210 | cppflags-gnu-y := $(CPPFLAGS) 211 | cpuflags-gnu-y := 212 | dbgflags-gnu-y := $(DBGFLAGS) 213 | libflags-gnu-y := $(foreach LIB,$(LIBS),-l$(LIB)) 214 | ldflags-gnu-y := $(LDFLAGS) 215 | flashflags-gnu-y := 216 | clean-files := 217 | clean-dirs := 218 | 219 | clean-files += $(wildcard $(target) $(project).map) 220 | clean-files += $(wildcard $(project).hex $(project).bin) 221 | clean-files += $(wildcard $(project).lss $(project).sym) 222 | clean-files += $(wildcard $(build)) 223 | 224 | # Use pipes instead of temporary files for communication between processes 225 | cflags-gnu-y += -pipe 226 | asflags-gnu-y += -pipe 227 | ldflags-gnu-y += -pipe 228 | 229 | # Archiver flags. 230 | arflags-gnu-y += rcs 231 | 232 | # Always enable warnings. And be very careful about implicit 233 | # declarations. 234 | cflags-gnu-y += -Wall -Wstrict-prototypes -Wmissing-prototypes 235 | cflags-gnu-y += -Werror-implicit-function-declaration 236 | cxxflags-gnu-y += -Wall 237 | # IAR doesn't allow arithmetic on void pointers, so warn about that. 238 | cflags-gnu-y += -Wpointer-arith 239 | cxxflags-gnu-y += -Wpointer-arith 240 | 241 | # Preprocessor flags. 242 | cppflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),-I$(INC)) 243 | asflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),'-Wa,-I$(INC)') 244 | 245 | # CPU specific flags. 246 | cpuflags-gnu-y += -mcpu=$(ARCH) -mthumb -D=__$(PART)__ 247 | 248 | # Dependency file flags. 249 | depflags = -MD -MP -MQ $@ 250 | 251 | # Debug specific flags. 252 | ifdef BUILD_DEBUG_LEVEL 253 | dbgflags-gnu-y += -g$(BUILD_DEBUG_LEVEL) 254 | else 255 | dbgflags-gnu-y += -g3 256 | endif 257 | 258 | # Optimization specific flags. 259 | ifdef BUILD_OPTIMIZATION 260 | optflags-gnu-y = -O$(BUILD_OPTIMIZATION) 261 | else 262 | optflags-gnu-y = $(OPTIMIZATION) 263 | endif 264 | 265 | # Always preprocess assembler files. 266 | asflags-gnu-y += -x assembler-with-cpp 267 | # Compile C files using the GNU99 standard. 268 | cflags-gnu-y += -std=gnu99 269 | # Compile C++ files using the GNU++98 standard. 270 | cxxflags-gnu-y += -std=gnu++98 271 | 272 | # Don't use strict aliasing (very common in embedded applications). 273 | cflags-gnu-y += -fno-strict-aliasing 274 | cxxflags-gnu-y += -fno-strict-aliasing 275 | 276 | # Separate each function and data into its own separate section to allow 277 | # garbage collection of unused sections. 278 | cflags-gnu-y += -ffunction-sections -fdata-sections 279 | cxxflags-gnu-y += -ffunction-sections -fdata-sections 280 | 281 | # Various cflags. 282 | cflags-gnu-y += -Wchar-subscripts -Wcomment -Wformat=2 -Wimplicit-int 283 | cflags-gnu-y += -Wmain -Wparentheses 284 | cflags-gnu-y += -Wsequence-point -Wreturn-type -Wswitch -Wtrigraphs -Wunused 285 | cflags-gnu-y += -Wuninitialized -Wunknown-pragmas -Wfloat-equal -Wundef 286 | cflags-gnu-y += -Wshadow -Wbad-function-cast -Wwrite-strings 287 | cflags-gnu-y += -Wsign-compare -Waggregate-return 288 | cflags-gnu-y += -Wmissing-declarations 289 | cflags-gnu-y += -Wformat -Wmissing-format-attribute -Wno-deprecated-declarations 290 | cflags-gnu-y += -Wpacked -Wredundant-decls -Wnested-externs -Wlong-long 291 | cflags-gnu-y += -Wunreachable-code 292 | cflags-gnu-y += -Wcast-align 293 | cflags-gnu-y += --param max-inline-insns-single=500 294 | 295 | # To reduce application size use only integer printf function. 296 | cflags-gnu-y += -Dprintf=iprintf 297 | 298 | # Use newlib-nano to reduce application size 299 | ldflags-gnu-y += --specs=nano.specs 300 | 301 | # Garbage collect unreferred sections when linking. 302 | ldflags-gnu-y += -Wl,--gc-sections 303 | 304 | # Use the linker script if provided by the project. 305 | ifneq ($(strip $(linker_script)),) 306 | ldflags-gnu-y += -Wl,-T $(linker_script) 307 | endif 308 | 309 | # Output a link map file and a cross reference table 310 | ldflags-gnu-y += -Wl,-Map=$(project).map,--cref 311 | 312 | # Add library search paths relative to the top level directory. 313 | ldflags-gnu-y += $(foreach _LIB_PATH,$(addprefix $(PRJ_PATH)/,$(LIB_PATH)),-L$(_LIB_PATH)) 314 | 315 | a_flags = $(cpuflags-gnu-y) $(depflags) $(cppflags-gnu-y) $(asflags-gnu-y) -D__ASSEMBLY__ 316 | c_flags = $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cflags-gnu-y) 317 | cxx_flags= $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cxxflags-gnu-y) 318 | l_flags = -Wl,--entry=Reset_Handler -Wl,--cref $(cpuflags-gnu-y) $(optflags-gnu-y) $(ldflags-gnu-y) 319 | ar_flags = $(arflags-gnu-y) 320 | 321 | # Source files list and part informations must already be included before 322 | # running this makefile 323 | 324 | # If a custom build directory is specified, use it -- force trailing / in directory name. 325 | ifdef BUILD_DIR 326 | build-dir := $(dir $(BUILD_DIR))$(if $(notdir $(BUILD_DIR)),$(notdir $(BUILD_DIR))/) 327 | else 328 | build-dir = 329 | endif 330 | 331 | # Create object files list from source files list. 332 | obj-y := $(addprefix $(build-dir), $(addsuffix .o,$(basename $(CSRCS) $(ASSRCS)))) 333 | # Create dependency files list from source files list. 334 | dep-files := $(wildcard $(foreach f,$(obj-y),$(basename $(f)).d)) 335 | 336 | clean-files += $(wildcard $(obj-y)) 337 | clean-files += $(dep-files) 338 | 339 | clean-dirs += $(call reverse,$(sort $(wildcard $(dir $(obj-y))))) 340 | 341 | # Default target. 342 | .PHONY: all 343 | ifeq ($(project_type),all) 344 | all: 345 | $(MAKE) all PROJECT_TYPE=flash 346 | $(MAKE) all PROJECT_TYPE=sram 347 | else 348 | ifeq ($(target_type),lib) 349 | all: $(target) $(project).lss $(project).sym 350 | else 351 | ifeq ($(target_type),elf) 352 | all: prebuild $(target) $(project).lss $(project).sym $(project).hex $(project).bin postbuild 353 | endif 354 | endif 355 | endif 356 | 357 | prebuild: 358 | ifneq ($(strip $(PREBUILD_CMD)),) 359 | @echo $(MSG_PREBUILD) 360 | $(Q)$(PREBUILD_CMD) 361 | endif 362 | 363 | postbuild: 364 | ifneq ($(strip $(POSTBUILD_CMD)),) 365 | @echo $(MSG_POSTBUILD) 366 | $(Q)$(POSTBUILD_CMD) 367 | endif 368 | 369 | # Clean up the project. 370 | .PHONY: clean 371 | clean: 372 | @$(if $(strip $(clean-files)),echo $(MSG_CLEAN_FILES)) 373 | $(if $(strip $(clean-files)),$(Q)$(RM) $(clean-files),) 374 | @$(if $(strip $(clean-dirs)),echo $(MSG_CLEAN_DIRS)) 375 | # Remove created directories, and make sure we only remove existing 376 | # directories, since recursive rmdir might help us a bit on the way. 377 | ifeq ($(os),Windows) 378 | $(Q)$(if $(strip $(clean-dirs)), \ 379 | $(RMDIR) $(strip $(subst /,\,$(clean-dirs)))) 380 | else 381 | $(Q)$(if $(strip $(clean-dirs)), \ 382 | for directory in $(strip $(clean-dirs)); do \ 383 | if [ -d "$$directory" ]; then \ 384 | $(RMDIR) $$directory; \ 385 | fi \ 386 | done \ 387 | ) 388 | endif 389 | 390 | # Rebuild the project. 391 | .PHONY: rebuild 392 | rebuild: clean all 393 | 394 | # Debug the project in flash. 395 | .PHONY: debug_flash 396 | debug_flash: all 397 | $(GDB) -x "$(PRJ_PATH)/$(DEBUG_SCRIPT_FLASH)" -ex "reset" -readnow -se $(TARGET_FLASH) 398 | 399 | # Debug the project in sram. 400 | .PHONY: debug_sram 401 | debug_sram: all 402 | $(GDB) -x "$(PRJ_PATH)/$(DEBUG_SCRIPT_SRAM)" -ex "reset" -readnow -se $(TARGET_SRAM) 403 | 404 | .PHONY: objfiles 405 | objfiles: $(obj-y) 406 | 407 | # Create object files from C source files. 408 | $(build-dir)%.o: %.c $(MAKEFILE_PATH) config.mk 409 | $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) 410 | ifeq ($(os),Windows) 411 | $(Q)test -d $(patsubst %/,%,$(dir $@)) || mkdir $(subst /,\,$(dir $@)) 412 | else 413 | $(Q)test -d $(dir $@) || mkdir -p $(dir $@) 414 | endif 415 | @echo $(MSG_COMPILING) 416 | $(Q)$(CC) $(c_flags) -c $< -o $@ 417 | 418 | # Create object files from C++ source files. 419 | $(build-dir)%.o: %.cpp $(MAKEFILE_PATH) config.mk 420 | $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) 421 | ifeq ($(os),Windows) 422 | $(Q)test -d $(patsubst %/,%,$(dir $@)) || mkdir $(subst /,\,$(dir $@)) 423 | else 424 | $(Q)test -d $(dir $@) || mkdir -p $(dir $@) 425 | endif 426 | @echo $(MSG_COMPILING_CXX) 427 | $(Q)$(CXX) $(cxx_flags) -c $< -o $@ 428 | 429 | # Preprocess and assemble: create object files from assembler source files. 430 | $(build-dir)%.o: %.S $(MAKEFILE_PATH) config.mk 431 | $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) 432 | ifeq ($(os),Windows) 433 | $(Q)test -d $(patsubst %/,%,$(dir $@)) || mkdir $(subst /,\,$(dir $@)) 434 | else 435 | $(Q)test -d $(dir $@) || mkdir -p $(dir $@) 436 | endif 437 | @echo $(MSG_ASSEMBLING) 438 | $(Q)$(CC) $(a_flags) -c $< -o $@ 439 | 440 | # Include all dependency files to add depedency to all header files in use. 441 | include $(dep-files) 442 | 443 | ifeq ($(target_type),lib) 444 | # Archive object files into an archive 445 | $(target): $(MAKEFILE_PATH) config.mk $(obj-y) 446 | @echo $(MSG_ARCHIVING) 447 | $(Q)$(AR) $(ar_flags) $@ $(obj-y) 448 | @echo $(MSG_SIZE) 449 | $(Q)$(SIZE) -Bxt $@ 450 | else 451 | ifeq ($(target_type),elf) 452 | # Link the object files into an ELF file. Also make sure the target is rebuilt 453 | # if the common Makefile.sam.in or project config.mk is changed. 454 | $(target): $(linker_script) $(MAKEFILE_PATH) config.mk $(obj-y) 455 | @echo $(MSG_LINKING) 456 | $(Q)$(LD) $(l_flags) $(obj-y) $(libflags-gnu-y) -o $@ 457 | @echo $(MSG_SIZE) 458 | $(Q)$(SIZE) -Ax $@ 459 | $(Q)$(SIZE) -Bx $@ 460 | endif 461 | endif 462 | 463 | # Create extended function listing from target output file. 464 | %.lss: $(target) 465 | @echo $(MSG_EXTENDED_LISTING) 466 | $(Q)$(OBJDUMP) -h -S $< > $@ 467 | 468 | # Create symbol table from target output file. 469 | %.sym: $(target) 470 | @echo $(MSG_SYMBOL_TABLE) 471 | $(Q)$(NM) -n $< > $@ 472 | 473 | # Create Intel HEX image from ELF output file. 474 | %.hex: $(target) 475 | @echo $(MSG_IHEX_IMAGE) 476 | $(Q)$(OBJCOPY) -O ihex $(flashflags-gnu-y) $< $@ 477 | 478 | # Create binary image from ELF output file. 479 | %.bin: $(target) 480 | @echo $(MSG_BINARY_IMAGE) 481 | $(Q)$(OBJCOPY) -O binary $< $@ 482 | 483 | # Provide information about the detected host operating system. 484 | .SECONDARY: info-os 485 | info-os: 486 | @echo $(MSG_INFO)$(os) build host detected 487 | 488 | # Build Doxygen generated documentation. 489 | .PHONY: doc 490 | doc: 491 | @echo $(MSG_GENERATING_DOC) 492 | $(Q)cd $(dir $(doccfg)) && $(DOCGEN) $(notdir $(doccfg)) 493 | 494 | # Clean Doxygen generated documentation. 495 | .PHONY: cleandoc 496 | cleandoc: 497 | @$(if $(wildcard $(docdir)),echo $(MSG_CLEAN_DOC)) 498 | $(Q)$(if $(wildcard $(docdir)),$(RM) --recursive $(docdir)) 499 | 500 | # Rebuild the Doxygen generated documentation. 501 | .PHONY: rebuilddoc 502 | rebuilddoc: cleandoc doc 503 | 504 | print-% : ; @echo $* = $($*) 505 | -------------------------------------------------------------------------------- /firmware/asf.h: -------------------------------------------------------------------------------- 1 | #ifndef ASF_H 2 | #define ASF_H 3 | 4 | // From module: Common SAM0 compiler driver 5 | #include 6 | #include 7 | 8 | // From module: EXTINT - External Interrupt (Callback APIs) 9 | #include 10 | #include 11 | 12 | // From module: Generic board support 13 | #include 14 | 15 | // From module: Interrupt management - SAM implementation 16 | #include 17 | 18 | // From module: PORT - GPIO Pin Control 19 | #include 20 | 21 | // From module: Part identification macros 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | // From module: SYSTEM - Clock Management for SAMD21 32 | #include 33 | #include 34 | 35 | // From module: SYSTEM - Core System Driver 36 | #include 37 | 38 | // From module: SYSTEM - I/O Pin Multiplexer 39 | #include 40 | 41 | // From module: SYSTEM - Interrupt Driver 42 | #include 43 | 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | 51 | #include 52 | #endif // ASF_H 53 | -------------------------------------------------------------------------------- /firmware/conf_board.h: -------------------------------------------------------------------------------- 1 | #ifndef CONF_BOARD_H_INCLUDED 2 | #define CONF_BOARD_H_INCLUDED 3 | 4 | #endif 5 | -------------------------------------------------------------------------------- /firmware/conf_clocks.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifndef CONF_CLOCKS_H_INCLUDED 4 | #define CONF_CLOCKS_H_INCLUDED 5 | 6 | /* System clock bus configuration */ 7 | #define CONF_CLOCK_CPU_CLOCK_FAILURE_DETECT false 8 | #define CONF_CLOCK_FLASH_WAIT_STATES 2 // gbin: if this is 0, it doesn't boot completely 9 | #define CONF_CLOCK_CPU_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1 10 | #define CONF_CLOCK_APBA_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1 11 | #define CONF_CLOCK_APBB_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1 12 | 13 | /* SYSTEM_CLOCK_SOURCE_OSC8M configuration - Internal 8MHz oscillator */ 14 | #define CONF_CLOCK_OSC8M_PRESCALER SYSTEM_OSC8M_DIV_1 15 | #define CONF_CLOCK_OSC8M_ON_DEMAND true 16 | #define CONF_CLOCK_OSC8M_RUN_IN_STANDBY false 17 | 18 | /* SYSTEM_CLOCK_SOURCE_XOSC configuration - External clock/oscillator */ 19 | #define CONF_CLOCK_XOSC_ENABLE false 20 | #define CONF_CLOCK_XOSC_EXTERNAL_CRYSTAL SYSTEM_CLOCK_EXTERNAL_CRYSTAL 21 | #define CONF_CLOCK_XOSC_EXTERNAL_FREQUENCY 12000000UL 22 | #define CONF_CLOCK_XOSC_STARTUP_TIME SYSTEM_XOSC_STARTUP_32768 23 | #define CONF_CLOCK_XOSC_AUTO_GAIN_CONTROL true 24 | #define CONF_CLOCK_XOSC_ON_DEMAND true 25 | #define CONF_CLOCK_XOSC_RUN_IN_STANDBY false 26 | 27 | /* SYSTEM_CLOCK_SOURCE_XOSC32K configuration - External 32KHz crystal/clock oscillator */ 28 | #define CONF_CLOCK_XOSC32K_ENABLE false 29 | #define CONF_CLOCK_XOSC32K_EXTERNAL_CRYSTAL SYSTEM_CLOCK_EXTERNAL_CRYSTAL 30 | #define CONF_CLOCK_XOSC32K_STARTUP_TIME SYSTEM_XOSC32K_STARTUP_65536 31 | #define CONF_CLOCK_XOSC32K_AUTO_AMPLITUDE_CONTROL false 32 | #define CONF_CLOCK_XOSC32K_ENABLE_1KHZ_OUPUT false 33 | #define CONF_CLOCK_XOSC32K_ENABLE_32KHZ_OUTPUT true 34 | #define CONF_CLOCK_XOSC32K_ON_DEMAND true 35 | #define CONF_CLOCK_XOSC32K_RUN_IN_STANDBY false 36 | 37 | /* SYSTEM_CLOCK_SOURCE_OSC32K configuration - Internal 32KHz oscillator */ 38 | #define CONF_CLOCK_OSC32K_ENABLE false 39 | #define CONF_CLOCK_OSC32K_STARTUP_TIME SYSTEM_OSC32K_STARTUP_130 40 | #define CONF_CLOCK_OSC32K_ENABLE_1KHZ_OUTPUT true 41 | #define CONF_CLOCK_OSC32K_ENABLE_32KHZ_OUTPUT true 42 | #define CONF_CLOCK_OSC32K_ON_DEMAND true 43 | #define CONF_CLOCK_OSC32K_RUN_IN_STANDBY false 44 | 45 | /* SYSTEM_CLOCK_SOURCE_DFLL configuration - Digital Frequency Locked Loop */ 46 | #define CONF_CLOCK_DFLL_ENABLE true 47 | #define CONF_CLOCK_DFLL_LOOP_MODE SYSTEM_CLOCK_DFLL_LOOP_MODE_USB_RECOVERY 48 | #define CONF_CLOCK_DFLL_ON_DEMAND true 49 | 50 | /* DFLL open loop mode configuration */ 51 | #define CONF_CLOCK_DFLL_COARSE_VALUE (0x1f / 4) 52 | #define CONF_CLOCK_DFLL_FINE_VALUE (0xff / 4) 53 | 54 | /* DFLL closed loop mode configuration */ 55 | #define CONF_CLOCK_DFLL_SOURCE_GCLK_GENERATOR GCLK_GENERATOR_1 56 | #define CONF_CLOCK_DFLL_MULTIPLY_FACTOR 6 57 | #define CONF_CLOCK_DFLL_QUICK_LOCK true 58 | #define CONF_CLOCK_DFLL_TRACK_AFTER_FINE_LOCK true 59 | #define CONF_CLOCK_DFLL_KEEP_LOCK_ON_WAKEUP true 60 | #define CONF_CLOCK_DFLL_ENABLE_CHILL_CYCLE true 61 | #define CONF_CLOCK_DFLL_MAX_COARSE_STEP_SIZE (0x1f / 4) 62 | #define CONF_CLOCK_DFLL_MAX_FINE_STEP_SIZE (0xff / 4) 63 | 64 | /* SYSTEM_CLOCK_SOURCE_DPLL configuration - Digital Phase-Locked Loop */ 65 | #define CONF_CLOCK_DPLL_ENABLE false 66 | #define CONF_CLOCK_DPLL_ON_DEMAND true 67 | #define CONF_CLOCK_DPLL_RUN_IN_STANDBY false 68 | #define CONF_CLOCK_DPLL_LOCK_BYPASS false 69 | #define CONF_CLOCK_DPLL_WAKE_UP_FAST false 70 | #define CONF_CLOCK_DPLL_LOW_POWER_ENABLE false 71 | 72 | #define CONF_CLOCK_DPLL_LOCK_TIME SYSTEM_CLOCK_SOURCE_DPLL_LOCK_TIME_NO_TIMEOUT 73 | #define CONF_CLOCK_DPLL_REFERENCE_CLOCK SYSTEM_CLOCK_SOURCE_DPLL_REFERENCE_CLOCK_REF0 74 | #define CONF_CLOCK_DPLL_FILTER SYSTEM_CLOCK_SOURCE_DPLL_FILTER_DEFAULT 75 | 76 | #define CONF_CLOCK_DPLL_REFERENCE_FREQUENCY 32768 77 | #define CONF_CLOCK_DPLL_REFEREMCE_DIVIDER 1 78 | #define CONF_CLOCK_DPLL_OUTPUT_FREQUENCY 48000000 79 | 80 | /* Set this to true to configure the GCLK when running clocks_init. If set to 81 | * false, none of the GCLK generators will be configured in clocks_init(). */ 82 | #define CONF_CLOCK_CONFIGURE_GCLK true 83 | 84 | /* Configure GCLK generator 0 (Main Clock) */ 85 | #define CONF_CLOCK_GCLK_0_ENABLE true 86 | #define CONF_CLOCK_GCLK_0_RUN_IN_STANDBY false 87 | #define CONF_CLOCK_GCLK_0_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_DFLL 88 | #define CONF_CLOCK_GCLK_0_PRESCALER 1 89 | #define CONF_CLOCK_GCLK_0_OUTPUT_ENABLE false 90 | 91 | /* Configure GCLK generator 1 */ 92 | #define CONF_CLOCK_GCLK_1_ENABLE false 93 | #define CONF_CLOCK_GCLK_1_RUN_IN_STANDBY false 94 | #define CONF_CLOCK_GCLK_1_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M 95 | #define CONF_CLOCK_GCLK_1_PRESCALER 1 96 | #define CONF_CLOCK_GCLK_1_OUTPUT_ENABLE false 97 | 98 | /* Configure GCLK generator 2 (RTC) */ 99 | #define CONF_CLOCK_GCLK_2_ENABLE false 100 | #define CONF_CLOCK_GCLK_2_RUN_IN_STANDBY false 101 | #define CONF_CLOCK_GCLK_2_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC32K 102 | #define CONF_CLOCK_GCLK_2_PRESCALER 32 103 | #define CONF_CLOCK_GCLK_2_OUTPUT_ENABLE false 104 | 105 | /* Configure GCLK generator 3 */ 106 | #define CONF_CLOCK_GCLK_3_ENABLE false 107 | #define CONF_CLOCK_GCLK_3_RUN_IN_STANDBY false 108 | #define CONF_CLOCK_GCLK_3_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M 109 | #define CONF_CLOCK_GCLK_3_PRESCALER 1 110 | #define CONF_CLOCK_GCLK_3_OUTPUT_ENABLE false 111 | 112 | /* Configure GCLK generator 4 */ 113 | #define CONF_CLOCK_GCLK_4_ENABLE false 114 | #define CONF_CLOCK_GCLK_4_RUN_IN_STANDBY false 115 | #define CONF_CLOCK_GCLK_4_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M 116 | #define CONF_CLOCK_GCLK_4_PRESCALER 1 117 | #define CONF_CLOCK_GCLK_4_OUTPUT_ENABLE false 118 | 119 | /* Configure GCLK generator 5 */ 120 | #define CONF_CLOCK_GCLK_5_ENABLE false 121 | #define CONF_CLOCK_GCLK_5_RUN_IN_STANDBY false 122 | #define CONF_CLOCK_GCLK_5_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M 123 | #define CONF_CLOCK_GCLK_5_PRESCALER 1 124 | #define CONF_CLOCK_GCLK_5_OUTPUT_ENABLE false 125 | 126 | /* Configure GCLK generator 6 */ 127 | #define CONF_CLOCK_GCLK_6_ENABLE false 128 | #define CONF_CLOCK_GCLK_6_RUN_IN_STANDBY false 129 | #define CONF_CLOCK_GCLK_6_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M 130 | #define CONF_CLOCK_GCLK_6_PRESCALER 1 131 | #define CONF_CLOCK_GCLK_6_OUTPUT_ENABLE false 132 | 133 | /* Configure GCLK generator 7 */ 134 | #define CONF_CLOCK_GCLK_7_ENABLE false 135 | #define CONF_CLOCK_GCLK_7_RUN_IN_STANDBY false 136 | #define CONF_CLOCK_GCLK_7_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M 137 | #define CONF_CLOCK_GCLK_7_PRESCALER 1 138 | #define CONF_CLOCK_GCLK_7_OUTPUT_ENABLE false 139 | 140 | #endif 141 | 142 | -------------------------------------------------------------------------------- /firmware/conf_extint.h: -------------------------------------------------------------------------------- 1 | #ifndef CONF_EXTINT_H_INCLUDED 2 | #define CONF_EXTINT_H_INCLUDED 3 | 4 | #define EXTINT_CLOCK_SOURCE GCLK_GENERATOR_0 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /firmware/conf_sleepmgr.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef CONF_SLEEPMGR_H_INCLUDED 3 | #define CONF_SLEEPMGR_H_INCLUDED 4 | 5 | #endif /* CONF_SLEEPMGR_H_INCLUDED */ 6 | -------------------------------------------------------------------------------- /firmware/conf_spi.h: -------------------------------------------------------------------------------- 1 | #ifndef CONF_SPI_H_INCLUDED 2 | #define CONF_SPI_H_INCLUDED 3 | 4 | #define CONF_SPI_MASTER_ENABLE true 5 | #define CONF_SPI_SLAVE_ENABLE false 6 | #define CONF_SPI_TIMEOUT 10000 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /firmware/conf_usb.h: -------------------------------------------------------------------------------- 1 | #ifndef _CONF_USB_H_ 2 | #define _CONF_USB_H_ 3 | 4 | #include "compiler.h" 5 | #include "board.h" 6 | 7 | /** 8 | * USB Device Configuration 9 | * @{ 10 | */ 11 | 12 | //! Device definition (mandatory) 13 | #define USB_DEVICE_VENDOR_ID USB_VID_ATMEL 14 | #define USB_DEVICE_PRODUCT_ID USB_PID_ATMEL_ASF_CDC 15 | #define USB_DEVICE_MAJOR_VERSION 1 16 | #define USB_DEVICE_MINOR_VERSION 0 17 | #define USB_DEVICE_POWER 100 // Consumption on Vbus line (mA) 18 | #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_SELF_POWERED) 19 | // (USB_CONFIG_ATTR_BUS_POWERED) 20 | // (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_SELF_POWERED) 21 | // (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_BUS_POWERED) 22 | 23 | //! USB Device string definitions (Optional) 24 | #define USB_DEVICE_MANUFACTURE_NAME "ATMEL ASF" 25 | #define USB_DEVICE_PRODUCT_NAME "DonglePI" 26 | // #define USB_DEVICE_SERIAL_NAME "12...EF" 27 | 28 | /** 29 | * USB Device Callbacks definitions (Optional) 30 | * @{ 31 | */ 32 | #define UDC_VBUS_EVENT(b_vbus_high) 33 | #define UDC_SOF_EVENT() main_sof_action() 34 | #define UDC_SUSPEND_EVENT() main_suspend_action() 35 | #define UDC_RESUME_EVENT() main_resume_action() 36 | //! Mandatory when USB_DEVICE_ATTR authorizes remote wakeup feature 37 | // #define UDC_REMOTEWAKEUP_ENABLE() user_callback_remotewakeup_enable() 38 | // extern void user_callback_remotewakeup_enable(void); 39 | // #define UDC_REMOTEWAKEUP_DISABLE() user_callback_remotewakeup_disable() 40 | // extern void user_callback_remotewakeup_disable(void); 41 | //! When a extra string descriptor must be supported 42 | //! other than manufacturer, product and serial string 43 | // #define UDC_GET_EXTRA_STRING() 44 | //@} 45 | 46 | //@} 47 | 48 | /** 49 | * USB Interface Configuration 50 | * @{ 51 | */ 52 | /** 53 | * Configuration of CDC interface 54 | * @{ 55 | */ 56 | 57 | //! Define two USB communication ports 58 | #define UDI_CDC_PORT_NB 1 59 | 60 | //! Interface callback definition 61 | #define UDI_CDC_ENABLE_EXT(port) main_cdc_enable(port) 62 | #define UDI_CDC_DISABLE_EXT(port) main_cdc_disable(port) 63 | #define UDI_CDC_RX_NOTIFY(port) cdc_rx_notify(port) 64 | #define UDI_CDC_TX_EMPTY_NOTIFY(port) 65 | #define UDI_CDC_SET_CODING_EXT(port, cfg) cdc_config(port, cfg) 66 | #define UDI_CDC_SET_DTR_EXT(port, set) main_cdc_set_dtr(port, set) 67 | #define UDI_CDC_SET_RTS_EXT(port, set) 68 | 69 | //! Define it when the transfer CDC Device to Host is a low rate (<512000 bauds) 70 | //! to reduce CDC buffers size 71 | //#define UDI_CDC_LOW_RATE 72 | 73 | //! Default configuration of communication port 74 | #if BOARD == UC3B_BOARD_CONTROLLER 75 | #define UDI_CDC_DEFAULT_RATE 57600 76 | #else 77 | #define UDI_CDC_DEFAULT_RATE 115200 78 | #endif 79 | #define UDI_CDC_DEFAULT_STOPBITS CDC_STOP_BITS_1 80 | #define UDI_CDC_DEFAULT_PARITY CDC_PAR_NONE 81 | #define UDI_CDC_DEFAULT_DATABITS 8 82 | //@} 83 | //@} 84 | 85 | /** 86 | * USB Device Driver Configuration 87 | * @{ 88 | */ 89 | //@} 90 | 91 | //! The includes of classes and other headers must be done at the end of this 92 | //file to avoid compile error 93 | #include "udi_cdc_conf.h" 94 | #include "donglepi.h" // we need the protos defined there 95 | 96 | #endif // _CONF_USB_H_ 97 | -------------------------------------------------------------------------------- /firmware/config.mk: -------------------------------------------------------------------------------- 1 | # Path to top level ASF directory relative to this project directory. 2 | PRJ_PATH = ../asf 3 | 4 | # Target CPU architecture: cortex-m3, cortex-m4 5 | ARCH = cortex-m0plus 6 | 7 | # Target part: none, sam3n4 or sam4l4aa 8 | PART = samd21e17a 9 | 10 | # Application target name. Given with suffix .a for library and .elf for a 11 | # standalone application. 12 | TARGET_FLASH = flash.elf 13 | TARGET_SRAM = donglepi_sram.elf 14 | 15 | # lz4/lz4.c \ 16 | # List of C source files. 17 | CSRCS = \ 18 | sam0/utils/cmsis/samd21/source/gcc/startup_samd21.c \ 19 | sam0/utils/cmsis/samd21/source/system_samd21.c \ 20 | sam0/utils/syscalls/gcc/syscalls.c \ 21 | common/services/sleepmgr/samd/sleepmgr.c \ 22 | common/services/usb/class/cdc/device/udi_cdc.c \ 23 | common/services/usb/class/cdc/device/udi_cdc_desc.c \ 24 | common/services/usb/udc/udc.c \ 25 | common/utils/interrupt/interrupt_sam_nvic.c \ 26 | common2/services/delay/sam0/cycle_counter.c \ 27 | sam0/drivers/extint/extint_sam_d_r/extint.c \ 28 | sam0/drivers/extint/extint_callback.c \ 29 | sam0/drivers/port/port.c \ 30 | sam0/drivers/sercom/i2c/i2c_samd21_r21_d10_d11_l21/i2c_master.c \ 31 | sam0/drivers/sercom/spi/spi.c \ 32 | sam0/drivers/sercom/usart/usart.c \ 33 | sam0/drivers/sercom/sercom.c \ 34 | sam0/drivers/system/clock/clock_samd21_r21/clock.c \ 35 | sam0/drivers/system/clock/clock_samd21_r21/gclk.c \ 36 | sam0/drivers/system/interrupt/system_interrupt.c \ 37 | sam0/drivers/system/pinmux/pinmux.c \ 38 | sam0/drivers/system/system.c \ 39 | sam0/drivers/usb/stack_interface/usb_device_udd.c \ 40 | sam0/drivers/usb/stack_interface/usb_dual.c \ 41 | sam0/drivers/usb/usb_sam_d_r/usb.c \ 42 | nanopb/pb_encode.c \ 43 | nanopb/pb_decode.c \ 44 | nanopb/pb_common.c \ 45 | protocol/donglepi.pb.c\ 46 | donglepi.c \ 47 | pins.c\ 48 | dbg.c\ 49 | i2c.c\ 50 | spi.c\ 51 | gpio.c\ 52 | uart.c 53 | 54 | 55 | # List of assembler source files. 56 | ASSRCS = 57 | 58 | # List of include paths. 59 | INC_PATH = \ 60 | sam0/utils \ 61 | sam0/utils/cmsis/samd21/include \ 62 | sam0/utils/cmsis/samd21/source \ 63 | sam0/utils/header_files \ 64 | sam0/utils/preprocessor \ 65 | sam0/boards \ 66 | sam0/boards/dummy \ 67 | sam0/drivers/extint \ 68 | sam0/drivers/sercom \ 69 | sam0/drivers/port \ 70 | sam0/drivers/system/power/power_sam_d_r \ 71 | sam0/drivers/system/reset/reset_sam_d_r \ 72 | sam0/drivers/sercom/usart \ 73 | sam0/drivers/sercom/i2c \ 74 | sam0/drivers/sercom/spi \ 75 | sam0/drivers/system \ 76 | sam0/drivers/system/clock \ 77 | sam0/drivers/system/clock/clock_samd21_r21 \ 78 | sam0/drivers/system/interrupt \ 79 | sam0/drivers/system/interrupt/system_interrupt_samd21 \ 80 | sam0/drivers/system/pinmux \ 81 | sam0/drivers/usb \ 82 | sam0/drivers/usb/stack_interface \ 83 | common2/services/delay \ 84 | common2/services/delay/sam0 \ 85 | common/boards \ 86 | common/services/sleepmgr \ 87 | common/services/usb \ 88 | common/services/usb/class/cdc \ 89 | common/services/usb/class/cdc/device \ 90 | common/services/usb/udc \ 91 | common/utils \ 92 | thirdparty/CMSIS/Include \ 93 | thirdparty/CMSIS/Lib/GCC 94 | 95 | 96 | # Additional search paths for libraries. 97 | LIB_PATH = thirdparty/CMSIS/Lib/GCC 98 | 99 | # List of libraries to use during linking. 100 | LIBS = arm_cortexM0l_math 101 | 102 | # Path relative to top level directory pointing to a linker script. 103 | LINKER_SCRIPT_FLASH = sam0/utils/linker_scripts/samd21/gcc/samd21e17a_flash.ld 104 | LINKER_SCRIPT_SRAM = sam0/utils/linker_scripts/samd21/gcc/samd21e17a_sram.ld 105 | 106 | # Path relative to top level directory pointing to a linker script. 107 | DEBUG_SCRIPT_FLASH = sam0/boards/samd21_xplained_pro/debug_scripts/gcc/samd21_xplained_pro_flash.gdb 108 | DEBUG_SCRIPT_SRAM = sam0/boards/samd21_xplained_pro/debug_scripts/gcc/samd21_xplained_pro_sram.gdb 109 | 110 | # Project type parameter: all, sram or flash 111 | PROJECT_TYPE = flash 112 | 113 | # Additional options for debugging. By default the common Makefile.in will 114 | # add -g3. 115 | DBGFLAGS = 116 | 117 | # Application optimization used during compilation and linking: 118 | # -O0, -O1, -O2, -O3 or -Os 119 | OPTIMIZATION = -O1 120 | 121 | # Extra flags to use when archiving. 122 | ARFLAGS = 123 | 124 | # Extra flags to use when assembling. 125 | ASFLAGS = 126 | 127 | # Extra flags to use when compiling. 128 | CFLAGS = -I. -Inanopb 129 | # 130 | # Extra flags to use when preprocessing. 131 | # 132 | # Preprocessor symbol definitions 133 | # To add a definition use the format "-D name[=definition]". 134 | # To cancel a definition use the format "-U name". 135 | # 136 | # The most relevant symbols to define for the preprocessor are: 137 | # BOARD Target board in use, see boards/board.h for a list. 138 | # EXT_BOARD Optional extension board in use, see boards/board.h for a list. 139 | CPPFLAGS = \ 140 | -D ARM_MATH_CM0=true \ 141 | -D BOARD=DUMMY_BOARD \ 142 | -D CONFIG_SLEEPMGR_ENABLE \ 143 | -D SPI_CALLBACK_MODE=false \ 144 | -D CYCLE_MODE \ 145 | -D USART_CALLBACK_MODE=false \ 146 | -D EXTINT_CALLBACK_MODE=true \ 147 | -D I2C_MASTER_CALLBACK_MODE=false \ 148 | -D __SAMD21E17A__ 149 | 150 | # Extra flags to use when linking 151 | # gbin: stuff for the bootloader 152 | LDFLAGS = -Wl,--section-start=.text=0x4000 153 | 154 | # Pre- and post-build commands 155 | PREBUILD_CMD = make -C protocol 156 | POSTBUILD_CMD = 157 | -------------------------------------------------------------------------------- /firmware/copy.sh: -------------------------------------------------------------------------------- 1 | cp flash.bin /run/media/gbin/MT-D21E\ MSD/FLASH.BIN 2 | sync 3 | umount /run/media/gbin/MT-D21E\ MSD 4 | 5 | -------------------------------------------------------------------------------- /firmware/dbg.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "dbg.h" 3 | 4 | #define DEBUG_LED1 PIN_PA28 5 | #define DEBUG_BUTTON PIN_PA27 6 | 7 | #if SERIAL_DEBUG 8 | struct usart_module usart_module; 9 | struct usart_config usart_conf; 10 | #endif 11 | 12 | void l(const char *format, ...) { 13 | #if SERIAL_DEBUG 14 | char string[512]; 15 | va_list argptr; 16 | va_start(argptr, format); 17 | int size = vsprintf(string, format, argptr); 18 | va_end(argptr); 19 | usart_write_buffer_wait(&usart_module, (const uint8_t *)string, size); 20 | usart_write_buffer_wait(&usart_module, (const uint8_t *)"\r\n", 2); 21 | #endif 22 | } 23 | 24 | void log_init() { 25 | #if SERIAL_DEBUG 26 | usart_get_config_defaults(&usart_conf); 27 | usart_conf.stopbits = USART_STOPBITS_1; 28 | usart_conf.parity = USART_PARITY_NONE; 29 | usart_conf.character_size = USART_CHARACTER_SIZE_8BIT; 30 | 31 | usart_conf.baudrate = 115200; 32 | usart_conf.mux_setting = USART_RX_3_TX_2_XCK_3; 33 | usart_conf.pinmux_pad0 = PINMUX_UNUSED; 34 | usart_conf.pinmux_pad1 = PINMUX_UNUSED; 35 | usart_conf.pinmux_pad2 = PINMUX_PA14C_SERCOM2_PAD2; 36 | usart_conf.pinmux_pad3 = PINMUX_PA15C_SERCOM2_PAD3; 37 | while (usart_init(&usart_module, SERCOM2, &usart_conf) != STATUS_OK) { 38 | } 39 | usart_enable(&usart_module); 40 | l("----------- DonglePi debug console ------------"); 41 | #endif 42 | } 43 | 44 | void on1() { port_pin_set_output_level(DEBUG_LED1, 1); } 45 | 46 | void off1() { port_pin_set_output_level(DEBUG_LED1, 0); } 47 | 48 | bool get_button() { return port_pin_get_input_level(DEBUG_BUTTON); } 49 | -------------------------------------------------------------------------------- /firmware/dbg.h: -------------------------------------------------------------------------------- 1 | #ifndef _DBG_H_ 2 | #define _DBG_H_ 3 | #include 4 | #include 5 | 6 | #ifndef SERIAL_DEBUG 7 | #define SERIAL_DEBUG true 8 | #endif 9 | void log_init(void); 10 | void l(const char* format, ...); 11 | void on1(void); 12 | void off1(void); 13 | void on2(void); 14 | void off2(void); 15 | bool get_button(void); 16 | #endif 17 | -------------------------------------------------------------------------------- /firmware/donglepi.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "protocol/donglepi.pb.h" 5 | #include "conf_usb.h" 6 | #include "board.h" 7 | #include "ui.h" 8 | #include "uart.h" 9 | #include "dbg.h" 10 | #include "i2c.h" 11 | #include "gpio.h" 12 | #include "spi.h" 13 | #include "pins.h" 14 | 15 | // This main module takes care of initialization, protocol handling and 16 | // dispatching. 17 | 18 | static volatile bool main_b_cdc_enable = false; 19 | 20 | static void setup_led(void) { 21 | // Configure main LED as output 22 | struct port_config config_port_pin; 23 | port_get_config_defaults(&config_port_pin); 24 | config_port_pin.direction = PORT_PIN_DIR_OUTPUT; 25 | port_pin_set_config(PIN_PA28, &config_port_pin); 26 | } 27 | 28 | int main(void) { 29 | irq_initialize_vectors(); 30 | cpu_irq_enable(); 31 | sleepmgr_init(); 32 | system_init(); 33 | log_init(); 34 | l("configure_pins"); 35 | setup_led(); 36 | l("ui_init"); 37 | ui_init(); 38 | 39 | l("ui_powerdown"); 40 | ui_powerdown(); 41 | 42 | // Start USB stack to authorize VBus monitoring 43 | l("udc_start"); 44 | udc_start(); 45 | 46 | while (true) { 47 | sleepmgr_enter_sleep(); 48 | } 49 | } 50 | 51 | void main_suspend_action(void) { 52 | l("main_suspend_action"); 53 | off1(); 54 | ui_powerdown(); 55 | } 56 | 57 | void main_resume_action(void) { 58 | l("main_resume_action"); 59 | on1(); 60 | ui_wakeup(); 61 | } 62 | 63 | void main_sof_action(void) { 64 | if (!main_b_cdc_enable) return; 65 | // l("Frame number %d", udd_get_frame_number()); 66 | } 67 | 68 | uint8_t sbuffer[] = {0, 0, 0}; 69 | 70 | bool main_cdc_enable(uint8_t port) { 71 | l("main_cdc_enable %d", port); 72 | main_b_cdc_enable = true; 73 | 74 | // DC mapping 75 | struct port_config config_port_pin; 76 | port_get_config_defaults(&config_port_pin); 77 | config_port_pin.direction = PORT_PIN_DIR_OUTPUT; 78 | port_pin_set_config(PIN_PA00, &config_port_pin); // GPIO17 D/C 79 | port_pin_set_config(PIN_PA22, &config_port_pin); // GPIO04 RESET 80 | 81 | return true; 82 | } 83 | 84 | void main_cdc_disable(uint8_t port) { 85 | l("main_cdc_disable %d", port); 86 | main_b_cdc_enable = false; 87 | } 88 | 89 | void main_cdc_set_dtr(uint8_t port, bool b_enable) {} 90 | 91 | void ui_powerdown(void) {} 92 | 93 | void ui_init(void) {} 94 | 95 | void ui_wakeup(void) {} 96 | 97 | void cdc_config(uint8_t port, usb_cdc_line_coding_t* cfg) { 98 | l("cdc_config [%d]", port); 99 | } 100 | 101 | #define USB_BUFFER_SIZE 1024 102 | static uint8_t buffer[USB_BUFFER_SIZE]; 103 | 104 | void cdc_rx_notify(uint8_t port) { 105 | l("cdc_rx_notify [%d]", port); 106 | 107 | uint8_t b = udi_cdc_getc(); 108 | if (b != 0x08) { 109 | l("Protocol desync"); 110 | } 111 | l("First byte ok"); 112 | uint32_t offset = 0; 113 | do { 114 | buffer[offset++] = b; 115 | b = udi_cdc_getc(); 116 | l("-> 0x%02x", b); 117 | } while (b & 0x80); 118 | buffer[offset++] = b; 119 | // Now we have enough to know the size 120 | l("Length read, decoding..."); 121 | l("... 0x%02x 0x%02x", buffer[0], buffer[1]); 122 | 123 | pb_istream_t istream = pb_istream_from_buffer(buffer + 1, USB_BUFFER_SIZE); 124 | l("istream bytes_left before %d", istream.bytes_left); 125 | uint64_t len = 0; 126 | pb_decode_varint(&istream, &len); 127 | l("message_length %d", (uint32_t)len); 128 | l("offset %d", offset); 129 | udi_cdc_read_buf(buffer + offset, len); 130 | l("decode message"); 131 | istream = pb_istream_from_buffer(buffer + offset, len); 132 | DonglePiRequest request = {0}; 133 | request.config.i2c.funcs.decode = handle_i2c_config_cb; 134 | request.config.uart.funcs.decode = handle_uart_config_cb; 135 | request.config.spi.funcs.decode = handle_spi_config_cb; 136 | request.config.gpio.pins.funcs.decode = handle_gpio_pin_config_cb; 137 | request.data.i2c.writes.funcs.decode = handle_i2c_write_cb; 138 | 139 | if (!pb_decode(&istream, DonglePiRequest_fields, &request)) { 140 | l("failed to decode the packet, wait for more data"); 141 | return; 142 | } 143 | 144 | l("Request #%d received", request.message_nb); 145 | 146 | if (request.has_data && request.data.has_gpio) { 147 | handle_gpio_write(request.data.gpio); 148 | } 149 | 150 | pb_ostream_t ostream = pb_ostream_from_buffer(buffer, USB_BUFFER_SIZE); 151 | DonglePiResponse response = {}; 152 | response.message_nb = request.message_nb; 153 | l("Create response for #%d", response.message_nb); 154 | 155 | handle_gpio_read(&response); 156 | 157 | pb_encode_delimited(&ostream, DonglePiResponse_fields, &response); 158 | l("Write response nb_bytes = %d", ostream.bytes_written); 159 | uint32_t wrote = udi_cdc_write_buf(buffer, ostream.bytes_written); 160 | l("Done. wrote %d bytes", wrote); 161 | } 162 | 163 | /* compression test 164 | // const char *source = "This is my input !"; 165 | //char dest[200]; 166 | //char restored[17]; 167 | //LZ4_compress (source, dest, 17); 168 | //LZ4_decompress_fast(dest, restored, 17); 169 | */ 170 | -------------------------------------------------------------------------------- /firmware/donglepi.h: -------------------------------------------------------------------------------- 1 | #ifndef _DONGLEPI_H_ 2 | #define _DONGLEPI_H_ 3 | 4 | #include "usb_protocol_cdc.h" 5 | 6 | /*! \brief Opens the communication port 7 | * This is called by CDC interface when USB Host enable it. 8 | * 9 | * \retval true if cdc startup is successfully done 10 | */ 11 | bool main_cdc_enable(uint8_t port); 12 | 13 | /*! \brief Closes the communication port 14 | * This is called by CDC interface when USB Host disable it. 15 | */ 16 | void main_cdc_disable(uint8_t port); 17 | 18 | /*! \brief Manages the leds behaviors 19 | * Called when a start of frame is received on USB line each 1ms. 20 | */ 21 | void main_sof_action(void); 22 | 23 | /*! \brief Enters the application in low power mode 24 | * Callback called when USB host sets USB line in suspend state 25 | */ 26 | void main_suspend_action(void); 27 | 28 | /*! \brief Turn on a led to notify active mode 29 | * Called when the USB line is resumed from the suspend state 30 | */ 31 | void main_resume_action(void); 32 | 33 | /*! \brief Save new DTR state to change led behavior. 34 | * The DTR notify that the terminal have open or close the communication port. 35 | */ 36 | void main_cdc_set_dtr(uint8_t port, bool b_enable); 37 | 38 | void cdc_rx_notify(uint8_t port); 39 | 40 | /*! \brief Configures communication line 41 | * 42 | * \param cfg line configuration 43 | */ 44 | void cdc_config(uint8_t port, usb_cdc_line_coding_t* cfg); 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /firmware/gpio.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "gpio.h" 4 | #include "dbg.h" 5 | #include "pins.h" 6 | #include "protocol/donglepi.pb.h" 7 | 8 | void handle_gpio_write(Data_GPIO gpio) { 9 | l("Data received mask = %x values = %x", gpio.mask, gpio.values); 10 | for (uint32_t pin = 2; gpio.mask; pin++) { 11 | uint32_t bit = 1 << pin; 12 | if (gpio.mask & bit) { 13 | gpio.mask ^= bit; 14 | bool value = gpio.values & bit; 15 | l("Pin GPIO%02d set to %d", pin, value); 16 | port_pin_set_output_level(pin_map[pin], value); 17 | } 18 | } 19 | } 20 | 21 | void handle_gpio_read(DonglePiResponse *response) { 22 | l("Read input pins"); 23 | uint32_t mask = 0; 24 | uint32_t values = 0; 25 | for (int i = 0; i < 28; i++) { 26 | pinconfig_t *pin = get_pin_GPIO_config(i); 27 | if (pin->active && pin->direction == Config_GPIO_Pin_Direction_IN) { 28 | l("pin %d active and input", i); 29 | mask |= 1 << i; 30 | l("before values %x", values); 31 | values |= port_pin_get_input_level(pin_map[i]) << i; 32 | l("after values %x", values); 33 | } 34 | } 35 | if (mask) { 36 | response->has_data = true; 37 | response->data.has_gpio = true; 38 | response->data.gpio.mask = mask; 39 | response->data.gpio.values = values; 40 | } 41 | } 42 | 43 | bool handle_gpio_pin_config_cb(pb_istream_t *stream, const pb_field_t *field, 44 | void **arg) { 45 | l("Received a pin configuration callback"); 46 | Config_GPIO_Pin pin; 47 | if (!pb_decode(stream, Config_GPIO_Pin_fields, &pin)) { 48 | l("Failed to decode a pin configuration"); 49 | } 50 | l("Pin active %d", pin.active); 51 | l("Pin number %d", pin.number); 52 | l("Pin direction %d", pin.direction); 53 | 54 | pinconfig_t config = {pin.active, pin.direction, pin.pull, pin.trigger}; 55 | if (!set_pin_GPIO_config(pin.number, config)) { 56 | l("Error switching pin %d", pin.number); 57 | return false; 58 | } 59 | 60 | struct port_config config_port_pin; 61 | port_get_config_defaults(&config_port_pin); 62 | if (pin.direction == Config_GPIO_Pin_Direction_OUT) { 63 | config_port_pin.direction = PORT_PIN_DIR_OUTPUT; 64 | } else { 65 | config_port_pin.direction = PORT_PIN_DIR_INPUT; 66 | if (pin.has_pull) { 67 | if (pin.pull == Config_GPIO_Pin_Pull_OFF) { 68 | config_port_pin.input_pull = PORT_PIN_PULL_NONE; 69 | l("Pull None"); 70 | } else if (pin.pull == Config_GPIO_Pin_Pull_UP) { 71 | config_port_pin.input_pull = PORT_PIN_PULL_UP; 72 | l("Pull Up"); 73 | } else if (pin.pull == Config_GPIO_Pin_Pull_DOWN) { 74 | config_port_pin.input_pull = PORT_PIN_PULL_DOWN; 75 | l("Pull Down"); 76 | } 77 | } else { 78 | l("No pull config for this pin"); 79 | } 80 | } 81 | port_pin_set_config(pin_map[pin.number], &config_port_pin); 82 | return true; 83 | } 84 | -------------------------------------------------------------------------------- /firmware/gpio.h: -------------------------------------------------------------------------------- 1 | #ifndef _GPIO_H_ 2 | #define _GPIO_H_ 3 | #include "protocol/donglepi.pb.h" 4 | void handle_gpio_write(Data_GPIO gpio); 5 | bool handle_gpio_pin_config_cb(pb_istream_t *stream, const pb_field_t *field, 6 | void **arg); 7 | void handle_gpio_read(DonglePiResponse *response); 8 | #endif 9 | -------------------------------------------------------------------------------- /firmware/i2c.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "dbg.h" 3 | #include "i2c.h" 4 | #include "pins.h" 5 | 6 | struct i2c_master_module i2c_master; 7 | 8 | static void i2c_config(Config_I2C i2c_proto_config) { 9 | struct i2c_master_config config_i2c_master; 10 | i2c_master_get_config_defaults(&config_i2c_master); 11 | config_i2c_master.buffer_timeout = 10000; 12 | config_i2c_master.pinmux_pad0 = PINMUX_PA16C_SERCOM1_PAD0; 13 | config_i2c_master.pinmux_pad1 = PINMUX_PA17C_SERCOM1_PAD1; 14 | if (i2c_proto_config.speed == Config_I2C_Speed_BAUD_RATE_100KHZ) { 15 | config_i2c_master.baud_rate = I2C_MASTER_BAUD_RATE_100KHZ; 16 | } else { 17 | config_i2c_master.baud_rate = I2C_MASTER_BAUD_RATE_400KHZ; 18 | } 19 | 20 | if (i2c_master_init(&i2c_master, SERCOM1, &config_i2c_master) != STATUS_OK) { 21 | l("I2C Init Error"); 22 | } 23 | i2c_master_enable(&i2c_master); 24 | l("I2C enabled"); 25 | } 26 | 27 | static void i2c_disable(void) { 28 | i2c_master_disable(&i2c_master); 29 | l("I2C disabled"); 30 | } 31 | 32 | bool handle_i2c_config_cb(pb_istream_t *stream, const pb_field_t *field, 33 | void **arg) { 34 | l("Configuration for i2c..."); 35 | Config_I2C i2c; 36 | if (!pb_decode(stream, Config_I2C_fields, &i2c)) { 37 | l("Failed to decode a i2c configuration"); 38 | } 39 | 40 | if (switch_i2c(i2c.enabled)) { 41 | if (i2c.enabled) { 42 | i2c_config(i2c); 43 | } else { 44 | i2c_disable(); 45 | } 46 | } else { 47 | l("I2C cannot be enabled/disabled"); 48 | } 49 | return true; 50 | } 51 | 52 | static bool handle_i2c_write_data_cb(pb_istream_t *stream, 53 | const pb_field_t *field, void **arg) { 54 | l("Received a i2c write DATA callback"); 55 | Data_I2C_Write *write = (Data_I2C_Write *)(*arg); 56 | l("Addr %02x", write->addr); 57 | size_t len = stream->bytes_left; 58 | l("Length %d", len); 59 | uint8_t buf[255]; 60 | if (len > sizeof(buf) - 1 || !pb_read(stream, buf, len)) return false; 61 | 62 | l("Data %02x %02x", buf[0], buf[1]); 63 | struct i2c_master_packet packet = { 64 | .address = write->addr, .data_length = len, .data = buf, 65 | }; 66 | if (i2c_master_write_packet_wait(&i2c_master, &packet) != STATUS_OK) 67 | l("w not OK"); 68 | 69 | return true; 70 | } 71 | 72 | bool handle_i2c_write_cb(pb_istream_t *stream, const pb_field_t *field, 73 | void **arg) { 74 | l("Received a i2c write callback"); 75 | Data_I2C_Write write; 76 | write.buffer.funcs.decode = handle_i2c_write_data_cb; 77 | write.buffer.arg = &write; 78 | if (!pb_decode(stream, Data_I2C_Write_fields, &write)) { 79 | l("Failed to decode an I2C write"); 80 | } 81 | return true; 82 | } 83 | -------------------------------------------------------------------------------- /firmware/i2c.h: -------------------------------------------------------------------------------- 1 | #ifndef _I2C_H_ 2 | #define _I2C_H_ 3 | #include 4 | #include "protocol/donglepi.pb.h" 5 | bool handle_i2c_config_cb(pb_istream_t *stream, const pb_field_t *field, 6 | void **arg); 7 | bool handle_i2c_write_cb(pb_istream_t *stream, const pb_field_t *field, 8 | void **arg); 9 | #endif 10 | -------------------------------------------------------------------------------- /firmware/lz4/LICENSE: -------------------------------------------------------------------------------- 1 | LZ4 Library 2 | Copyright (c) 2011-2014, Yann Collet 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or 13 | other materials provided with the distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 19 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /firmware/lz4/Makefile: -------------------------------------------------------------------------------- 1 | # ################################################################ 2 | # LZ4 library - Makefile 3 | # Copyright (C) Yann Collet 2011-2015 4 | # All rights reserved. 5 | # 6 | # BSD license 7 | # Redistribution and use in source and binary forms, with or without modification, 8 | # are permitted provided that the following conditions are met: 9 | # 10 | # * Redistributions of source code must retain the above copyright notice, this 11 | # list of conditions and the following disclaimer. 12 | # 13 | # * Redistributions in binary form must reproduce the above copyright notice, this 14 | # list of conditions and the following disclaimer in the documentation and/or 15 | # other materials provided with the distribution. 16 | # 17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 21 | # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 24 | # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | # 28 | # You can contact the author at : 29 | # - LZ4 source repository : http://code.google.com/p/lz4/ 30 | # - LZ4 source mirror : https://github.com/Cyan4973/lz4 31 | # - LZ4 forum froup : https://groups.google.com/forum/#!forum/lz4c 32 | # ################################################################ 33 | 34 | # Version numbers 35 | VERSION ?= 126 36 | LIBVER_MAJOR=`sed -n '/define LZ4_VERSION_MAJOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < lz4.h` 37 | LIBVER_MINOR=`sed -n '/define LZ4_VERSION_MINOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < lz4.h` 38 | LIBVER_PATCH=`sed -n '/define LZ4_VERSION_RELEASE/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < lz4.h` 39 | LIBVER=$(LIBVER_MAJOR).$(LIBVER_MINOR).$(LIBVER_PATCH) 40 | 41 | DESTDIR?= 42 | PREFIX ?= /usr 43 | CFLAGS ?= -O3 44 | CFLAGS += -I. -std=c99 -Wall -Wextra -Wundef -Wshadow -Wcast-align -Wstrict-prototypes -pedantic 45 | 46 | LIBDIR?= $(PREFIX)/lib 47 | INCLUDEDIR=$(PREFIX)/include 48 | 49 | 50 | # OS X linker doesn't support -soname, and use different extension 51 | # see : https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/DynamicLibraryDesignGuidelines.html 52 | ifeq ($(shell uname), Darwin) 53 | SHARED_EXT = dylib 54 | SHARED_EXT_MAJOR = $(LIBVER_MAJOR).$(SHARED_EXT) 55 | SHARED_EXT_VER = $(LIBVER).$(SHARED_EXT) 56 | SONAME_FLAGS = -install_name $(PREFIX)/lib/liblz4.$(SHARED_EXT_MAJOR) -compatibility_version $(LIBVER_MAJOR) -current_version $(LIBVER) 57 | else 58 | SONAME_FLAGS = -Wl,-soname=liblz4.$(SHARED_EXT).$(LIBVER_MAJOR) 59 | SHARED_EXT = so 60 | SHARED_EXT_MAJOR = $(SHARED_EXT).$(LIBVER_MAJOR) 61 | SHARED_EXT_VER = $(SHARED_EXT).$(LIBVER) 62 | endif 63 | 64 | default: liblz4 65 | 66 | all: liblz4 67 | 68 | liblz4: lz4.c lz4hc.c lz4frame.c xxhash.c 69 | @echo compiling static library 70 | @$(CC) $(CPPFLAGS) $(CFLAGS) -c $^ 71 | @$(AR) rcs liblz4.a lz4.o lz4hc.o lz4frame.o xxhash.o 72 | @echo compiling dynamic library $(LIBVER) 73 | @$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -shared $^ -fPIC $(SONAME_FLAGS) -o $@.$(SHARED_EXT_VER) 74 | @echo creating versioned links 75 | @ln -sf $@.$(SHARED_EXT_VER) $@.$(SHARED_EXT_MAJOR) 76 | @ln -sf $@.$(SHARED_EXT_VER) $@.$(SHARED_EXT) 77 | 78 | clean: 79 | @rm -f core *.o *.a *.$(SHARED_EXT) *.$(SHARED_EXT).* liblz4.pc 80 | @echo Cleaning library completed 81 | 82 | 83 | #------------------------------------------------------------------------ 84 | #make install is validated only for Linux, OSX, kFreeBSD and Hurd targets 85 | ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU)) 86 | 87 | liblz4.pc: liblz4.pc.in Makefile 88 | @echo creating pkgconfig 89 | @sed -e 's|@PREFIX@|$(PREFIX)|' \ 90 | -e 's|@LIBDIR@|$(LIBDIR)|' \ 91 | -e 's|@INCLUDEDIR@|$(INCLUDEDIR)|' \ 92 | -e 's|@VERSION@|$(VERSION)|' \ 93 | $< >$@ 94 | 95 | install: liblz4 liblz4.pc 96 | @install -d -m 755 $(DESTDIR)$(LIBDIR)/pkgconfig/ $(DESTDIR)$(INCLUDEDIR)/ 97 | @install -m 755 liblz4.$(SHARED_EXT_VER) $(DESTDIR)$(LIBDIR)/liblz4.$(SHARED_EXT_VER) 98 | @cp -a liblz4.$(SHARED_EXT_MAJOR) $(DESTDIR)$(LIBDIR) 99 | @cp -a liblz4.$(SHARED_EXT) $(DESTDIR)$(LIBDIR) 100 | @cp -a liblz4.pc $(DESTDIR)$(LIBDIR)/pkgconfig/ 101 | @install -m 644 liblz4.a $(DESTDIR)$(LIBDIR)/liblz4.a 102 | @install -m 644 lz4.h $(DESTDIR)$(INCLUDEDIR)/lz4.h 103 | @install -m 644 lz4hc.h $(DESTDIR)$(INCLUDEDIR)/lz4hc.h 104 | @install -m 644 lz4frame.h $(DESTDIR)$(INCLUDEDIR)/lz4frame.h 105 | @echo lz4 static and shared library installed 106 | 107 | uninstall: 108 | @rm -f $(DESTDIR)$(LIBDIR)/liblz4.$(SHARED_EXT) 109 | @rm -f $(DESTDIR)$(LIBDIR)/liblz4.$(SHARED_EXT_MAJOR) 110 | @rm -f $(DESTDIR)$(LIBDIR)/pkgconfig/liblz4.pc 111 | @[ -x $(DESTDIR)$(LIBDIR)/liblz4.$(SHARED_EXT_VER) ] && rm -f $(DESTDIR)$(LIBDIR)/liblz4.$(SHARED_EXT_VER) 112 | @[ -f $(DESTDIR)$(LIBDIR)/liblz4.a ] && rm -f $(DESTDIR)$(LIBDIR)/liblz4.a 113 | @[ -f $(DESTDIR)$(INCLUDEDIR)/lz4.h ] && rm -f $(DESTDIR)$(INCLUDEDIR)/lz4.h 114 | @[ -f $(DESTDIR)$(INCLUDEDIR)/lz4hc.h ] && rm -f $(DESTDIR)$(INCLUDEDIR)/lz4hc.h 115 | @echo lz4 libraries successfully uninstalled 116 | 117 | endif 118 | -------------------------------------------------------------------------------- /firmware/lz4/liblz4.pc.in: -------------------------------------------------------------------------------- 1 | # LZ4 - Fast LZ compression algorithm 2 | # Copyright (C) 2011-2014, Yann Collet. 3 | # BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 4 | 5 | prefix=@PREFIX@ 6 | libdir=@LIBDIR@ 7 | includedir=@INCLUDEDIR@ 8 | 9 | Name: lz4 10 | Description: fast lossless compression algorithm library 11 | URL: http://code.google.com/p/lz4/ 12 | Version: @VERSION@ 13 | Libs: -L@LIBDIR@ -llz4 14 | Cflags: -I@INCLUDEDIR@ 15 | -------------------------------------------------------------------------------- /firmware/lz4/lz4.h: -------------------------------------------------------------------------------- 1 | /* 2 | LZ4 - Fast LZ compression algorithm 3 | Header File 4 | Copyright (C) 2011-2014, Yann Collet. 5 | BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are 9 | met: 10 | 11 | * Redistributions of source code must retain the above copyright 12 | notice, this list of conditions and the following disclaimer. 13 | * Redistributions in binary form must reproduce the above 14 | copyright notice, this list of conditions and the following disclaimer 15 | in the documentation and/or other materials provided with the 16 | distribution. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | You can contact the author at : 31 | - LZ4 source repository : http://code.google.com/p/lz4/ 32 | - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c 33 | */ 34 | #pragma once 35 | 36 | #if defined (__cplusplus) 37 | extern "C" { 38 | #endif 39 | 40 | /* 41 | * lz4.h provides raw compression format functions, for optimal performance and integration into programs. 42 | * If you need to generate data using an inter-operable format (respecting the framing specification), 43 | * please use lz4frame.h instead. 44 | */ 45 | 46 | /************************************** 47 | Version 48 | **************************************/ 49 | #define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */ 50 | #define LZ4_VERSION_MINOR 5 /* for new (non-breaking) interface capabilities */ 51 | #define LZ4_VERSION_RELEASE 0 /* for tweaks, bug-fixes, or development */ 52 | #define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE) 53 | int LZ4_versionNumber (void); 54 | 55 | /************************************** 56 | Tuning parameter 57 | **************************************/ 58 | /* 59 | * LZ4_MEMORY_USAGE : 60 | * Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.) 61 | * Increasing memory usage improves compression ratio 62 | * Reduced memory usage can improve speed, due to cache effect 63 | * Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache 64 | */ 65 | #define LZ4_MEMORY_USAGE 14 66 | 67 | 68 | /************************************** 69 | Simple Functions 70 | **************************************/ 71 | 72 | int LZ4_compress (const char* source, char* dest, int sourceSize); 73 | int LZ4_decompress_safe (const char* source, char* dest, int compressedSize, int maxDecompressedSize); 74 | 75 | /* 76 | LZ4_compress() : 77 | Compresses 'sourceSize' bytes from 'source' into 'dest'. 78 | Destination buffer must be already allocated, 79 | and must be sized to handle worst cases situations (input data not compressible) 80 | Worst case size evaluation is provided by function LZ4_compressBound() 81 | inputSize : Max supported value is LZ4_MAX_INPUT_SIZE 82 | return : the number of bytes written in buffer dest 83 | or 0 if the compression fails 84 | 85 | LZ4_decompress_safe() : 86 | compressedSize : is obviously the source size 87 | maxDecompressedSize : is the size of the destination buffer, which must be already allocated. 88 | return : the number of bytes decompressed into the destination buffer (necessarily <= maxDecompressedSize) 89 | If the destination buffer is not large enough, decoding will stop and output an error code (<0). 90 | If the source stream is detected malformed, the function will stop decoding and return a negative result. 91 | This function is protected against buffer overflow exploits, 92 | and never writes outside of output buffer, nor reads outside of input buffer. 93 | It is also protected against malicious data packets. 94 | */ 95 | 96 | 97 | /************************************** 98 | Advanced Functions 99 | **************************************/ 100 | #define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */ 101 | #define LZ4_COMPRESSBOUND(isize) ((unsigned int)(isize) > (unsigned int)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16) 102 | 103 | /* 104 | LZ4_compressBound() : 105 | Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible) 106 | This function is primarily useful for memory allocation purposes (output buffer size). 107 | Macro LZ4_COMPRESSBOUND() is also provided for compilation-time evaluation (stack memory allocation for example). 108 | 109 | isize : is the input size. Max supported value is LZ4_MAX_INPUT_SIZE 110 | return : maximum output size in a "worst case" scenario 111 | or 0, if input size is too large ( > LZ4_MAX_INPUT_SIZE) 112 | */ 113 | int LZ4_compressBound(int isize); 114 | 115 | 116 | /* 117 | LZ4_compress_limitedOutput() : 118 | Compress 'sourceSize' bytes from 'source' into an output buffer 'dest' of maximum size 'maxOutputSize'. 119 | If it cannot achieve it, compression will stop, and result of the function will be zero. 120 | This saves time and memory on detecting non-compressible (or barely compressible) data. 121 | This function never writes outside of provided output buffer. 122 | 123 | sourceSize : Max supported value is LZ4_MAX_INPUT_VALUE 124 | maxOutputSize : is the size of the destination buffer (which must be already allocated) 125 | return : the number of bytes written in buffer 'dest' 126 | or 0 if compression fails 127 | */ 128 | int LZ4_compress_limitedOutput (const char* source, char* dest, int sourceSize, int maxOutputSize); 129 | 130 | 131 | /* 132 | LZ4_compress_withState() : 133 | Same compression functions, but using an externally allocated memory space to store compression state. 134 | Use LZ4_sizeofState() to know how much memory must be allocated, 135 | and then, provide it as 'void* state' to compression functions. 136 | */ 137 | int LZ4_sizeofState(void); 138 | int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize); 139 | int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize); 140 | 141 | 142 | /* 143 | LZ4_decompress_fast() : 144 | originalSize : is the original and therefore uncompressed size 145 | return : the number of bytes read from the source buffer (in other words, the compressed size) 146 | If the source stream is detected malformed, the function will stop decoding and return a negative result. 147 | Destination buffer must be already allocated. Its size must be a minimum of 'originalSize' bytes. 148 | note : This function fully respect memory boundaries for properly formed compressed data. 149 | It is a bit faster than LZ4_decompress_safe(). 150 | However, it does not provide any protection against intentionally modified data stream (malicious input). 151 | Use this function in trusted environment only (data to decode comes from a trusted source). 152 | */ 153 | int LZ4_decompress_fast (const char* source, char* dest, int originalSize); 154 | 155 | 156 | /* 157 | LZ4_decompress_safe_partial() : 158 | This function decompress a compressed block of size 'compressedSize' at position 'source' 159 | into destination buffer 'dest' of size 'maxDecompressedSize'. 160 | The function tries to stop decompressing operation as soon as 'targetOutputSize' has been reached, 161 | reducing decompression time. 162 | return : the number of bytes decoded in the destination buffer (necessarily <= maxDecompressedSize) 163 | Note : this number can be < 'targetOutputSize' should the compressed block to decode be smaller. 164 | Always control how many bytes were decoded. 165 | If the source stream is detected malformed, the function will stop decoding and return a negative result. 166 | This function never writes outside of output buffer, and never reads outside of input buffer. It is therefore protected against malicious data packets 167 | */ 168 | int LZ4_decompress_safe_partial (const char* source, char* dest, int compressedSize, int targetOutputSize, int maxDecompressedSize); 169 | 170 | 171 | /*********************************************** 172 | Streaming Compression Functions 173 | ***********************************************/ 174 | 175 | #define LZ4_STREAMSIZE_U64 ((1 << (LZ4_MEMORY_USAGE-3)) + 4) 176 | #define LZ4_STREAMSIZE (LZ4_STREAMSIZE_U64 * sizeof(long long)) 177 | /* 178 | * LZ4_stream_t 179 | * information structure to track an LZ4 stream. 180 | * important : init this structure content before first use ! 181 | * note : only allocated directly the structure if you are statically linking LZ4 182 | * If you are using liblz4 as a DLL, please use below construction methods instead. 183 | */ 184 | typedef struct { long long table[LZ4_STREAMSIZE_U64]; } LZ4_stream_t; 185 | 186 | /* 187 | * LZ4_resetStream 188 | * Use this function to init an allocated LZ4_stream_t structure 189 | */ 190 | void LZ4_resetStream (LZ4_stream_t* LZ4_streamPtr); 191 | 192 | /* 193 | * LZ4_createStream will allocate and initialize an LZ4_stream_t structure 194 | * LZ4_freeStream releases its memory. 195 | * In the context of a DLL (liblz4), please use these methods rather than the static struct. 196 | * They are more future proof, in case of a change of LZ4_stream_t size. 197 | */ 198 | LZ4_stream_t* LZ4_createStream(void); 199 | int LZ4_freeStream (LZ4_stream_t* LZ4_streamPtr); 200 | 201 | /* 202 | * LZ4_loadDict 203 | * Use this function to load a static dictionary into LZ4_stream. 204 | * Any previous data will be forgotten, only 'dictionary' will remain in memory. 205 | * Loading a size of 0 is allowed. 206 | * Return : dictionary size, in bytes (necessarily <= 64 KB) 207 | */ 208 | int LZ4_loadDict (LZ4_stream_t* LZ4_streamPtr, const char* dictionary, int dictSize); 209 | 210 | /* 211 | * LZ4_compress_continue 212 | * Compress data block 'source', using blocks compressed before as dictionary to improve compression ratio 213 | * Previous data blocks are assumed to still be present at their previous location. 214 | */ 215 | int LZ4_compress_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize); 216 | 217 | /* 218 | * LZ4_compress_limitedOutput_continue 219 | * Same as before, but also specify a maximum target compressed size (maxOutputSize) 220 | * If objective cannot be met, compression exits, and returns a zero. 221 | */ 222 | int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize, int maxOutputSize); 223 | 224 | /* 225 | * LZ4_saveDict 226 | * If previously compressed data block is not guaranteed to remain available at its memory location 227 | * save it into a safer place (char* safeBuffer) 228 | * Note : you don't need to call LZ4_loadDict() afterwards, 229 | * dictionary is immediately usable, you can therefore call again LZ4_compress_continue() 230 | * Return : dictionary size in bytes, or 0 if error 231 | * Note : any dictSize > 64 KB will be interpreted as 64KB. 232 | */ 233 | int LZ4_saveDict (LZ4_stream_t* LZ4_streamPtr, char* safeBuffer, int dictSize); 234 | 235 | 236 | /************************************************ 237 | Streaming Decompression Functions 238 | ************************************************/ 239 | 240 | #define LZ4_STREAMDECODESIZE_U64 4 241 | #define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U64 * sizeof(unsigned long long)) 242 | typedef struct { unsigned long long table[LZ4_STREAMDECODESIZE_U64]; } LZ4_streamDecode_t; 243 | /* 244 | * LZ4_streamDecode_t 245 | * information structure to track an LZ4 stream. 246 | * init this structure content using LZ4_setStreamDecode or memset() before first use ! 247 | * 248 | * In the context of a DLL (liblz4) please prefer usage of construction methods below. 249 | * They are more future proof, in case of a change of LZ4_streamDecode_t size in the future. 250 | * LZ4_createStreamDecode will allocate and initialize an LZ4_streamDecode_t structure 251 | * LZ4_freeStreamDecode releases its memory. 252 | */ 253 | LZ4_streamDecode_t* LZ4_createStreamDecode(void); 254 | int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream); 255 | 256 | /* 257 | * LZ4_setStreamDecode 258 | * Use this function to instruct where to find the dictionary. 259 | * Setting a size of 0 is allowed (same effect as reset). 260 | * Return : 1 if OK, 0 if error 261 | */ 262 | int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize); 263 | 264 | /* 265 | *_continue() : 266 | These decoding functions allow decompression of multiple blocks in "streaming" mode. 267 | Previously decoded blocks *must* remain available at the memory position where they were decoded (up to 64 KB) 268 | If this condition is not possible, save the relevant part of decoded data into a safe buffer, 269 | and indicate where is its new address using LZ4_setStreamDecode() 270 | */ 271 | int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxDecompressedSize); 272 | int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize); 273 | 274 | 275 | /* 276 | Advanced decoding functions : 277 | *_usingDict() : 278 | These decoding functions work the same as 279 | a combination of LZ4_setDictDecode() followed by LZ4_decompress_x_continue() 280 | They are stand-alone and don't use nor update an LZ4_streamDecode_t structure. 281 | */ 282 | int LZ4_decompress_safe_usingDict (const char* source, char* dest, int compressedSize, int maxDecompressedSize, const char* dictStart, int dictSize); 283 | int LZ4_decompress_fast_usingDict (const char* source, char* dest, int originalSize, const char* dictStart, int dictSize); 284 | 285 | 286 | 287 | /************************************** 288 | Obsolete Functions 289 | **************************************/ 290 | /* 291 | Obsolete decompression functions 292 | These function names are deprecated and should no longer be used. 293 | They are only provided here for compatibility with older user programs. 294 | - LZ4_uncompress is the same as LZ4_decompress_fast 295 | - LZ4_uncompress_unknownOutputSize is the same as LZ4_decompress_safe 296 | These function prototypes are now disabled; uncomment them if you really need them. 297 | It is highly recommended to stop using these functions and migrate to newer ones */ 298 | /* int LZ4_uncompress (const char* source, char* dest, int outputSize); */ 299 | /* int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize); */ 300 | 301 | 302 | /* Obsolete streaming functions; use new streaming interface whenever possible */ 303 | void* LZ4_create (const char* inputBuffer); 304 | int LZ4_sizeofStreamState(void); 305 | int LZ4_resetStreamState(void* state, const char* inputBuffer); 306 | char* LZ4_slideInputBuffer (void* state); 307 | 308 | /* Obsolete streaming decoding functions */ 309 | int LZ4_decompress_safe_withPrefix64k (const char* source, char* dest, int compressedSize, int maxOutputSize); 310 | int LZ4_decompress_fast_withPrefix64k (const char* source, char* dest, int originalSize); 311 | 312 | // gbin:missing prototypes 313 | int LZ4_compress_forceExtDict (LZ4_stream_t* LZ4_dict, const char* source, char* dest, int inputSize); 314 | int LZ4_decompress_safe_forceExtDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize); 315 | int LZ4_uncompress (const char* source, char* dest, int outputSize); 316 | int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize); 317 | 318 | #if defined (__cplusplus) 319 | } 320 | #endif 321 | -------------------------------------------------------------------------------- /firmware/lz4/lz4frame.h: -------------------------------------------------------------------------------- 1 | /* 2 | LZ4 auto-framing library 3 | Header File 4 | Copyright (C) 2011-2015, Yann Collet. 5 | BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are 9 | met: 10 | 11 | * Redistributions of source code must retain the above copyright 12 | notice, this list of conditions and the following disclaimer. 13 | * Redistributions in binary form must reproduce the above 14 | copyright notice, this list of conditions and the following disclaimer 15 | in the documentation and/or other materials provided with the 16 | distribution. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | You can contact the author at : 31 | - LZ4 source repository : http://code.google.com/p/lz4/ 32 | - LZ4 source mirror : https://github.com/Cyan4973/lz4 33 | - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c 34 | */ 35 | 36 | /* LZ4F is a stand-alone API to create LZ4-compressed frames 37 | * fully conformant to specification v1.4.1. 38 | * All related operations, including memory management, are handled by the library. 39 | * You don't need lz4.h when using lz4frame.h. 40 | * */ 41 | 42 | #pragma once 43 | 44 | #if defined (__cplusplus) 45 | extern "C" { 46 | #endif 47 | 48 | /************************************** 49 | Includes 50 | **************************************/ 51 | #include /* size_t */ 52 | 53 | 54 | /************************************** 55 | * Error management 56 | * ************************************/ 57 | typedef size_t LZ4F_errorCode_t; 58 | 59 | unsigned LZ4F_isError(LZ4F_errorCode_t code); 60 | const char* LZ4F_getErrorName(LZ4F_errorCode_t code); /* return error code string; useful for debugging */ 61 | 62 | 63 | /************************************** 64 | * Frame compression types 65 | * ************************************/ 66 | typedef enum { LZ4F_default=0, max64KB=4, max256KB=5, max1MB=6, max4MB=7 } blockSizeID_t; 67 | typedef enum { blockLinked=0, blockIndependent} blockMode_t; 68 | typedef enum { noContentChecksum=0, contentChecksumEnabled } contentChecksum_t; 69 | 70 | typedef struct { 71 | blockSizeID_t blockSizeID; /* max64KB, max256KB, max1MB, max4MB ; 0 == default */ 72 | blockMode_t blockMode; /* blockLinked, blockIndependent ; 0 == default */ 73 | contentChecksum_t contentChecksumFlag; /* noContentChecksum, contentChecksumEnabled ; 0 == default */ 74 | unsigned reserved[5]; 75 | } LZ4F_frameInfo_t; 76 | 77 | typedef struct { 78 | LZ4F_frameInfo_t frameInfo; 79 | unsigned compressionLevel; /* 0 == default (fast mode); values above 16 count as 16 */ 80 | unsigned autoFlush; /* 1 == always flush : reduce need for tmp buffer */ 81 | unsigned reserved[4]; 82 | } LZ4F_preferences_t; 83 | 84 | 85 | /*********************************** 86 | * Simple compression function 87 | * *********************************/ 88 | size_t LZ4F_compressFrameBound(size_t srcSize, const LZ4F_preferences_t* preferencesPtr); 89 | 90 | size_t LZ4F_compressFrame(void* dstBuffer, size_t dstMaxSize, const void* srcBuffer, size_t srcSize, const LZ4F_preferences_t* preferencesPtr); 91 | /* LZ4F_compressFrame() 92 | * Compress an entire srcBuffer into a valid LZ4 frame, as defined by specification v1.4.1. 93 | * The most important rule is that dstBuffer MUST be large enough (dstMaxSize) to ensure compression completion even in worst case. 94 | * You can get the minimum value of dstMaxSize by using LZ4F_compressFrameBound() 95 | * If this condition is not respected, LZ4F_compressFrame() will fail (result is an errorCode) 96 | * The LZ4F_preferences_t structure is optional : you can provide NULL as argument. All preferences will be set to default. 97 | * The result of the function is the number of bytes written into dstBuffer. 98 | * The function outputs an error code if it fails (can be tested using LZ4F_isError()) 99 | */ 100 | 101 | 102 | 103 | /********************************** 104 | * Advanced compression functions 105 | * ********************************/ 106 | typedef void* LZ4F_compressionContext_t; 107 | 108 | typedef struct { 109 | unsigned stableSrc; /* 1 == src content will remain available on future calls to LZ4F_compress(); avoid saving src content within tmp buffer as future dictionary */ 110 | unsigned reserved[3]; 111 | } LZ4F_compressOptions_t; 112 | 113 | /* Resource Management */ 114 | 115 | #define LZ4F_VERSION 100 116 | LZ4F_errorCode_t LZ4F_createCompressionContext(LZ4F_compressionContext_t* LZ4F_compressionContextPtr, unsigned version); 117 | LZ4F_errorCode_t LZ4F_freeCompressionContext(LZ4F_compressionContext_t LZ4F_compressionContext); 118 | /* LZ4F_createCompressionContext() : 119 | * The first thing to do is to create a compressionContext object, which will be used in all compression operations. 120 | * This is achieved using LZ4F_createCompressionContext(), which takes as argument a version and an LZ4F_preferences_t structure. 121 | * The version provided MUST be LZ4F_VERSION. It is intended to track potential version differences between different binaries. 122 | * The function will provide a pointer to a fully allocated LZ4F_compressionContext_t object. 123 | * If the result LZ4F_errorCode_t is not zero, there was an error during context creation. 124 | * Object can release its memory using LZ4F_freeCompressionContext(); 125 | */ 126 | 127 | 128 | /* Compression */ 129 | 130 | size_t LZ4F_compressBegin(LZ4F_compressionContext_t compressionContext, void* dstBuffer, size_t dstMaxSize, const LZ4F_preferences_t* preferencesPtr); 131 | /* LZ4F_compressBegin() : 132 | * will write the frame header into dstBuffer. 133 | * dstBuffer must be large enough to accommodate a header (dstMaxSize). Maximum header size is 19 bytes. 134 | * The LZ4F_preferences_t structure is optional : you can provide NULL as argument, all preferences will then be set to default. 135 | * The result of the function is the number of bytes written into dstBuffer for the header 136 | * or an error code (can be tested using LZ4F_isError()) 137 | */ 138 | 139 | size_t LZ4F_compressBound(size_t srcSize, const LZ4F_preferences_t* preferencesPtr); 140 | /* LZ4F_compressBound() : 141 | * Provides the minimum size of Dst buffer given srcSize to handle worst case situations. 142 | * preferencesPtr is optional : you can provide NULL as argument, all preferences will then be set to default. 143 | * Note that different preferences will produce in different results. 144 | */ 145 | 146 | size_t LZ4F_compressUpdate(LZ4F_compressionContext_t compressionContext, void* dstBuffer, size_t dstMaxSize, const void* srcBuffer, size_t srcSize, const LZ4F_compressOptions_t* compressOptionsPtr); 147 | /* LZ4F_compressUpdate() 148 | * LZ4F_compressUpdate() can be called repetitively to compress as much data as necessary. 149 | * The most important rule is that dstBuffer MUST be large enough (dstMaxSize) to ensure compression completion even in worst case. 150 | * If this condition is not respected, LZ4F_compress() will fail (result is an errorCode) 151 | * You can get the minimum value of dstMaxSize by using LZ4F_compressBound() 152 | * The LZ4F_compressOptions_t structure is optional : you can provide NULL as argument. 153 | * The result of the function is the number of bytes written into dstBuffer : it can be zero, meaning input data was just buffered. 154 | * The function outputs an error code if it fails (can be tested using LZ4F_isError()) 155 | */ 156 | 157 | size_t LZ4F_flush(LZ4F_compressionContext_t compressionContext, void* dstBuffer, size_t dstMaxSize, const LZ4F_compressOptions_t* compressOptionsPtr); 158 | /* LZ4F_flush() 159 | * Should you need to create compressed data immediately, without waiting for a block to be filled, 160 | * you can call LZ4_flush(), which will immediately compress any remaining data buffered within compressionContext. 161 | * The LZ4F_compressOptions_t structure is optional : you can provide NULL as argument. 162 | * The result of the function is the number of bytes written into dstBuffer 163 | * (it can be zero, this means there was no data left within compressionContext) 164 | * The function outputs an error code if it fails (can be tested using LZ4F_isError()) 165 | */ 166 | 167 | size_t LZ4F_compressEnd(LZ4F_compressionContext_t compressionContext, void* dstBuffer, size_t dstMaxSize, const LZ4F_compressOptions_t* compressOptionsPtr); 168 | /* LZ4F_compressEnd() 169 | * When you want to properly finish the compressed frame, just call LZ4F_compressEnd(). 170 | * It will flush whatever data remained within compressionContext (like LZ4_flush()) 171 | * but also properly finalize the frame, with an endMark and a checksum. 172 | * The result of the function is the number of bytes written into dstBuffer (necessarily >= 4 (endMark size)) 173 | * The function outputs an error code if it fails (can be tested using LZ4F_isError()) 174 | * The LZ4F_compressOptions_t structure is optional : you can provide NULL as argument. 175 | * compressionContext can then be used again, starting with LZ4F_compressBegin(). 176 | */ 177 | 178 | 179 | /*********************************** 180 | * Decompression functions 181 | * *********************************/ 182 | 183 | typedef void* LZ4F_decompressionContext_t; 184 | 185 | typedef struct { 186 | unsigned stableDst; /* guarantee that decompressed data will still be there on next function calls (avoid storage into tmp buffers) */ 187 | unsigned reserved[3]; 188 | } LZ4F_decompressOptions_t; 189 | 190 | 191 | /* Resource management */ 192 | 193 | LZ4F_errorCode_t LZ4F_createDecompressionContext(LZ4F_decompressionContext_t* ctxPtr, unsigned version); 194 | LZ4F_errorCode_t LZ4F_freeDecompressionContext(LZ4F_decompressionContext_t ctx); 195 | /* LZ4F_createDecompressionContext() : 196 | * The first thing to do is to create a decompressionContext object, which will be used in all decompression operations. 197 | * This is achieved using LZ4F_createDecompressionContext(). 198 | * The version provided MUST be LZ4F_VERSION. It is intended to track potential version differences between different binaries. 199 | * The function will provide a pointer to a fully allocated and initialized LZ4F_decompressionContext_t object. 200 | * If the result LZ4F_errorCode_t is not OK_NoError, there was an error during context creation. 201 | * Object can release its memory using LZ4F_freeDecompressionContext(); 202 | */ 203 | 204 | 205 | /* Decompression */ 206 | 207 | size_t LZ4F_getFrameInfo(LZ4F_decompressionContext_t ctx, 208 | LZ4F_frameInfo_t* frameInfoPtr, 209 | const void* srcBuffer, size_t* srcSizePtr); 210 | /* LZ4F_getFrameInfo() 211 | * This function decodes frame header information, such as blockSize. 212 | * It is optional : you could start by calling directly LZ4F_decompress() instead. 213 | * The objective is to extract header information without starting decompression, typically for allocation purposes. 214 | * LZ4F_getFrameInfo() can also be used *after* starting decompression, on a valid LZ4F_decompressionContext_t. 215 | * The number of bytes read from srcBuffer will be provided within *srcSizePtr (necessarily <= original value). 216 | * You are expected to resume decompression from where it stopped (srcBuffer + *srcSizePtr) 217 | * The function result is an hint of how many srcSize bytes LZ4F_decompress() expects for next call, 218 | * or an error code which can be tested using LZ4F_isError(). 219 | */ 220 | 221 | size_t LZ4F_decompress(LZ4F_decompressionContext_t ctx, 222 | void* dstBuffer, size_t* dstSizePtr, 223 | const void* srcBuffer, size_t* srcSizePtr, 224 | const LZ4F_decompressOptions_t* optionsPtr); 225 | /* LZ4F_decompress() 226 | * Call this function repetitively to regenerate data compressed within srcBuffer. 227 | * The function will attempt to decode *srcSizePtr bytes from srcBuffer, into dstBuffer of maximum size *dstSizePtr. 228 | * 229 | * The number of bytes regenerated into dstBuffer will be provided within *dstSizePtr (necessarily <= original value). 230 | * 231 | * The number of bytes read from srcBuffer will be provided within *srcSizePtr (necessarily <= original value). 232 | * If number of bytes read is < number of bytes provided, then decompression operation is not completed. 233 | * It typically happens when dstBuffer is not large enough to contain all decoded data. 234 | * LZ4F_decompress() must be called again, starting from where it stopped (srcBuffer + *srcSizePtr) 235 | * The function will check this condition, and refuse to continue if it is not respected. 236 | * 237 | * dstBuffer is supposed to be flushed between each call to the function, since its content will be overwritten. 238 | * dst arguments can be changed at will with each consecutive call to the function. 239 | * 240 | * The function result is an hint of how many srcSize bytes LZ4F_decompress() expects for next call. 241 | * Schematically, it's the size of the current (or remaining) compressed block + header of next block. 242 | * Respecting the hint provides some boost to performance, since it does skip intermediate buffers. 243 | * This is just a hint, you can always provide any srcSize you want. 244 | * When a frame is fully decoded, the function result will be 0. (no more data expected) 245 | * If decompression failed, function result is an error code, which can be tested using LZ4F_isError(). 246 | */ 247 | 248 | 249 | 250 | #if defined (__cplusplus) 251 | } 252 | #endif 253 | -------------------------------------------------------------------------------- /firmware/lz4/lz4frame_static.h: -------------------------------------------------------------------------------- 1 | /* 2 | LZ4 auto-framing library 3 | Header File for static linking only 4 | Copyright (C) 2011-2015, Yann Collet. 5 | 6 | BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are 10 | met: 11 | 12 | * Redistributions of source code must retain the above copyright 13 | notice, this list of conditions and the following disclaimer. 14 | * Redistributions in binary form must reproduce the above 15 | copyright notice, this list of conditions and the following disclaimer 16 | in the documentation and/or other materials provided with the 17 | distribution. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | You can contact the author at : 32 | - LZ4 source repository : http://code.google.com/p/lz4/ 33 | - LZ4 source mirror : https://github.com/Cyan4973/lz4 34 | - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c 35 | */ 36 | 37 | #pragma once 38 | 39 | #if defined (__cplusplus) 40 | extern "C" { 41 | #endif 42 | 43 | /* lz4frame_static.h should be used solely in the context of static linking. 44 | * */ 45 | 46 | 47 | /************************************** 48 | * Error management 49 | * ************************************/ 50 | #define LZ4F_LIST_ERRORS(ITEM) \ 51 | ITEM(OK_NoError) ITEM(ERROR_GENERIC) \ 52 | ITEM(ERROR_maxBlockSize_invalid) ITEM(ERROR_blockMode_invalid) ITEM(ERROR_contentChecksumFlag_invalid) \ 53 | ITEM(ERROR_compressionLevel_invalid) \ 54 | ITEM(ERROR_allocation_failed) \ 55 | ITEM(ERROR_srcSize_tooLarge) ITEM(ERROR_dstMaxSize_tooSmall) \ 56 | ITEM(ERROR_decompressionFailed) \ 57 | ITEM(ERROR_checksum_invalid) \ 58 | ITEM(ERROR_maxCode) 59 | 60 | #define LZ4F_GENERATE_ENUM(ENUM) ENUM, 61 | typedef enum { LZ4F_LIST_ERRORS(LZ4F_GENERATE_ENUM) } LZ4F_errorCodes; /* enum is exposed, to handle specific errors; compare function result to -enum value */ 62 | 63 | 64 | /************************************** 65 | Includes 66 | **************************************/ 67 | #include "lz4frame.h" 68 | 69 | 70 | #if defined (__cplusplus) 71 | } 72 | #endif 73 | -------------------------------------------------------------------------------- /firmware/lz4/lz4hc.c: -------------------------------------------------------------------------------- 1 | /* 2 | LZ4 HC - High Compression Mode of LZ4 3 | Copyright (C) 2011-2014, Yann Collet. 4 | BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are 8 | met: 9 | 10 | * Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above 13 | copyright notice, this list of conditions and the following disclaimer 14 | in the documentation and/or other materials provided with the 15 | distribution. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | You can contact the author at : 30 | - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html 31 | - LZ4 source repository : http://code.google.com/p/lz4/ 32 | */ 33 | 34 | 35 | 36 | /************************************** 37 | Tuning Parameter 38 | **************************************/ 39 | static const int LZ4HC_compressionLevel_default = 8; 40 | 41 | 42 | /************************************** 43 | Includes 44 | **************************************/ 45 | #include "lz4hc.h" 46 | 47 | 48 | /************************************** 49 | Local Compiler Options 50 | **************************************/ 51 | #if defined(__GNUC__) 52 | # pragma GCC diagnostic ignored "-Wunused-function" 53 | #endif 54 | 55 | #if defined (__clang__) 56 | # pragma clang diagnostic ignored "-Wunused-function" 57 | #endif 58 | 59 | 60 | /************************************** 61 | Common LZ4 definition 62 | **************************************/ 63 | #define LZ4_COMMONDEFS_ONLY 64 | #include "lz4.c" 65 | 66 | 67 | /************************************** 68 | Local Constants 69 | **************************************/ 70 | #define DICTIONARY_LOGSIZE 16 71 | #define MAXD (1<> ((MINMATCH*8)-HASH_LOG)) 105 | #define DELTANEXT(p) chainTable[(size_t)(p) & MAXD_MASK] 106 | #define GETNEXT(p) ((p) - (size_t)DELTANEXT(p)) 107 | 108 | static U32 LZ4HC_hashPtr(const void* ptr) { return HASH_FUNCTION(LZ4_read32(ptr)); } 109 | 110 | 111 | 112 | /************************************** 113 | HC Compression 114 | **************************************/ 115 | static void LZ4HC_init (LZ4HC_Data_Structure* hc4, const BYTE* start) 116 | { 117 | MEM_INIT((void*)hc4->hashTable, 0, sizeof(hc4->hashTable)); 118 | MEM_INIT(hc4->chainTable, 0xFF, sizeof(hc4->chainTable)); 119 | hc4->nextToUpdate = 64 KB; 120 | hc4->base = start - 64 KB; 121 | hc4->inputBuffer = start; 122 | hc4->end = start; 123 | hc4->dictBase = start - 64 KB; 124 | hc4->dictLimit = 64 KB; 125 | hc4->lowLimit = 64 KB; 126 | } 127 | 128 | 129 | /* Update chains up to ip (excluded) */ 130 | FORCE_INLINE void LZ4HC_Insert (LZ4HC_Data_Structure* hc4, const BYTE* ip) 131 | { 132 | U16* chainTable = hc4->chainTable; 133 | U32* HashTable = hc4->hashTable; 134 | const BYTE* const base = hc4->base; 135 | const U32 target = (U32)(ip - base); 136 | U32 idx = hc4->nextToUpdate; 137 | 138 | while(idx < target) 139 | { 140 | U32 h = LZ4HC_hashPtr(base+idx); 141 | size_t delta = idx - HashTable[h]; 142 | if (delta>MAX_DISTANCE) delta = MAX_DISTANCE; 143 | chainTable[idx & 0xFFFF] = (U16)delta; 144 | HashTable[h] = idx; 145 | idx++; 146 | } 147 | 148 | hc4->nextToUpdate = target; 149 | } 150 | 151 | 152 | FORCE_INLINE int LZ4HC_InsertAndFindBestMatch (LZ4HC_Data_Structure* hc4, /* Index table will be updated */ 153 | const BYTE* ip, const BYTE* const iLimit, 154 | const BYTE** matchpos, 155 | const int maxNbAttempts) 156 | { 157 | U16* const chainTable = hc4->chainTable; 158 | U32* const HashTable = hc4->hashTable; 159 | const BYTE* const base = hc4->base; 160 | const BYTE* const dictBase = hc4->dictBase; 161 | const U32 dictLimit = hc4->dictLimit; 162 | const U32 lowLimit = (hc4->lowLimit + 64 KB > (U32)(ip-base)) ? hc4->lowLimit : (U32)(ip - base) - (64 KB - 1); 163 | U32 matchIndex; 164 | const BYTE* match; 165 | int nbAttempts=maxNbAttempts; 166 | size_t ml=0; 167 | 168 | /* HC4 match finder */ 169 | LZ4HC_Insert(hc4, ip); 170 | matchIndex = HashTable[LZ4HC_hashPtr(ip)]; 171 | 172 | while ((matchIndex>=lowLimit) && (nbAttempts)) 173 | { 174 | nbAttempts--; 175 | if (matchIndex >= dictLimit) 176 | { 177 | match = base + matchIndex; 178 | if (*(match+ml) == *(ip+ml) 179 | && (LZ4_read32(match) == LZ4_read32(ip))) 180 | { 181 | size_t mlt = LZ4_count(ip+MINMATCH, match+MINMATCH, iLimit) + MINMATCH; 182 | if (mlt > ml) { ml = mlt; *matchpos = match; } 183 | } 184 | } 185 | else 186 | { 187 | match = dictBase + matchIndex; 188 | if (LZ4_read32(match) == LZ4_read32(ip)) 189 | { 190 | size_t mlt; 191 | const BYTE* vLimit = ip + (dictLimit - matchIndex); 192 | if (vLimit > iLimit) vLimit = iLimit; 193 | mlt = LZ4_count(ip+MINMATCH, match+MINMATCH, vLimit) + MINMATCH; 194 | if ((ip+mlt == vLimit) && (vLimit < iLimit)) 195 | mlt += LZ4_count(ip+mlt, base+dictLimit, iLimit); 196 | if (mlt > ml) { ml = mlt; *matchpos = base + matchIndex; } /* virtual matchpos */ 197 | } 198 | } 199 | matchIndex -= chainTable[matchIndex & 0xFFFF]; 200 | } 201 | 202 | return (int)ml; 203 | } 204 | 205 | 206 | FORCE_INLINE int LZ4HC_InsertAndGetWiderMatch ( 207 | LZ4HC_Data_Structure* hc4, 208 | const BYTE* ip, 209 | const BYTE* iLowLimit, 210 | const BYTE* iHighLimit, 211 | int longest, 212 | const BYTE** matchpos, 213 | const BYTE** startpos, 214 | const int maxNbAttempts) 215 | { 216 | U16* const chainTable = hc4->chainTable; 217 | U32* const HashTable = hc4->hashTable; 218 | const BYTE* const base = hc4->base; 219 | const U32 dictLimit = hc4->dictLimit; 220 | const U32 lowLimit = (hc4->lowLimit + 64 KB > (U32)(ip-base)) ? hc4->lowLimit : (U32)(ip - base) - (64 KB - 1); 221 | const BYTE* const dictBase = hc4->dictBase; 222 | const BYTE* match; 223 | U32 matchIndex; 224 | int nbAttempts = maxNbAttempts; 225 | int delta = (int)(ip-iLowLimit); 226 | 227 | 228 | /* First Match */ 229 | LZ4HC_Insert(hc4, ip); 230 | matchIndex = HashTable[LZ4HC_hashPtr(ip)]; 231 | 232 | while ((matchIndex>=lowLimit) && (nbAttempts)) 233 | { 234 | nbAttempts--; 235 | if (matchIndex >= dictLimit) 236 | { 237 | match = base + matchIndex; 238 | if (*(iLowLimit + longest) == *(match - delta + longest)) 239 | if (LZ4_read32(match) == LZ4_read32(ip)) 240 | { 241 | const BYTE* startt = ip; 242 | const BYTE* tmpMatch = match; 243 | const BYTE* const matchEnd = ip + MINMATCH + LZ4_count(ip+MINMATCH, match+MINMATCH, iHighLimit); 244 | 245 | while ((startt>iLowLimit) && (tmpMatch > iLowLimit) && (startt[-1] == tmpMatch[-1])) {startt--; tmpMatch--;} 246 | 247 | if ((matchEnd-startt) > longest) 248 | { 249 | longest = (int)(matchEnd-startt); 250 | *matchpos = tmpMatch; 251 | *startpos = startt; 252 | } 253 | } 254 | } 255 | else 256 | { 257 | match = dictBase + matchIndex; 258 | if (LZ4_read32(match) == LZ4_read32(ip)) 259 | { 260 | size_t mlt; 261 | int back=0; 262 | const BYTE* vLimit = ip + (dictLimit - matchIndex); 263 | if (vLimit > iHighLimit) vLimit = iHighLimit; 264 | mlt = LZ4_count(ip+MINMATCH, match+MINMATCH, vLimit) + MINMATCH; 265 | if ((ip+mlt == vLimit) && (vLimit < iHighLimit)) 266 | mlt += LZ4_count(ip+mlt, base+dictLimit, iHighLimit); 267 | while ((ip+back > iLowLimit) && (matchIndex+back > lowLimit) && (ip[back-1] == match[back-1])) back--; 268 | mlt -= back; 269 | if ((int)mlt > longest) { longest = (int)mlt; *matchpos = base + matchIndex + back; *startpos = ip+back; } 270 | } 271 | } 272 | matchIndex -= chainTable[matchIndex & 0xFFFF]; 273 | } 274 | 275 | return longest; 276 | } 277 | 278 | 279 | typedef enum { noLimit = 0, limitedOutput = 1 } limitedOutput_directive; 280 | 281 | #define LZ4HC_DEBUG 0 282 | #if LZ4HC_DEBUG 283 | static unsigned debug = 0; 284 | #endif 285 | 286 | FORCE_INLINE int LZ4HC_encodeSequence ( 287 | const BYTE** ip, 288 | BYTE** op, 289 | const BYTE** anchor, 290 | int matchLength, 291 | const BYTE* const match, 292 | limitedOutput_directive limitedOutputBuffer, 293 | BYTE* oend) 294 | { 295 | int length; 296 | BYTE* token; 297 | 298 | #if LZ4HC_DEBUG 299 | if (debug) printf("literal : %u -- match : %u -- offset : %u\n", (U32)(*ip - *anchor), (U32)matchLength, (U32)(*ip-match)); 300 | #endif 301 | 302 | /* Encode Literal length */ 303 | length = (int)(*ip - *anchor); 304 | token = (*op)++; 305 | if ((limitedOutputBuffer) && ((*op + (length>>8) + length + (2 + 1 + LASTLITERALS)) > oend)) return 1; /* Check output limit */ 306 | if (length>=(int)RUN_MASK) { int len; *token=(RUN_MASK< 254 ; len-=255) *(*op)++ = 255; *(*op)++ = (BYTE)len; } 307 | else *token = (BYTE)(length<>8) + (1 + LASTLITERALS) > oend)) return 1; /* Check output limit */ 319 | if (length>=(int)ML_MASK) { *token+=ML_MASK; length-=ML_MASK; for(; length > 509 ; length-=510) { *(*op)++ = 255; *(*op)++ = 255; } if (length > 254) { length-=255; *(*op)++ = 255; } *(*op)++ = (BYTE)length; } 320 | else *token += (BYTE)(length); 321 | 322 | /* Prepare next loop */ 323 | *ip += matchLength; 324 | *anchor = *ip; 325 | 326 | return 0; 327 | } 328 | 329 | 330 | static int LZ4HC_compress_generic ( 331 | void* ctxvoid, 332 | const char* source, 333 | char* dest, 334 | int inputSize, 335 | int maxOutputSize, 336 | int compressionLevel, 337 | limitedOutput_directive limit 338 | ) 339 | { 340 | LZ4HC_Data_Structure* ctx = (LZ4HC_Data_Structure*) ctxvoid; 341 | const BYTE* ip = (const BYTE*) source; 342 | const BYTE* anchor = ip; 343 | const BYTE* const iend = ip + inputSize; 344 | const BYTE* const mflimit = iend - MFLIMIT; 345 | const BYTE* const matchlimit = (iend - LASTLITERALS); 346 | 347 | BYTE* op = (BYTE*) dest; 348 | BYTE* const oend = op + maxOutputSize; 349 | 350 | unsigned maxNbAttempts; 351 | int ml, ml2, ml3, ml0; 352 | const BYTE* ref=NULL; 353 | const BYTE* start2=NULL; 354 | const BYTE* ref2=NULL; 355 | const BYTE* start3=NULL; 356 | const BYTE* ref3=NULL; 357 | const BYTE* start0; 358 | const BYTE* ref0; 359 | 360 | 361 | /* init */ 362 | if (compressionLevel > g_maxCompressionLevel) compressionLevel = g_maxCompressionLevel; 363 | if (compressionLevel < 1) compressionLevel = LZ4HC_compressionLevel_default; 364 | maxNbAttempts = 1 << (compressionLevel-1); 365 | ctx->end += inputSize; 366 | 367 | ip++; 368 | 369 | /* Main Loop */ 370 | while (ip < mflimit) 371 | { 372 | ml = LZ4HC_InsertAndFindBestMatch (ctx, ip, matchlimit, (&ref), maxNbAttempts); 373 | if (!ml) { ip++; continue; } 374 | 375 | /* saved, in case we would skip too much */ 376 | start0 = ip; 377 | ref0 = ref; 378 | ml0 = ml; 379 | 380 | _Search2: 381 | if (ip+ml < mflimit) 382 | ml2 = LZ4HC_InsertAndGetWiderMatch(ctx, ip + ml - 2, ip + 1, matchlimit, ml, &ref2, &start2, maxNbAttempts); 383 | else ml2 = ml; 384 | 385 | if (ml2 == ml) /* No better match */ 386 | { 387 | if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0; 388 | continue; 389 | } 390 | 391 | if (start0 < ip) 392 | { 393 | if (start2 < ip + ml0) /* empirical */ 394 | { 395 | ip = start0; 396 | ref = ref0; 397 | ml = ml0; 398 | } 399 | } 400 | 401 | /* Here, start0==ip */ 402 | if ((start2 - ip) < 3) /* First Match too small : removed */ 403 | { 404 | ml = ml2; 405 | ip = start2; 406 | ref =ref2; 407 | goto _Search2; 408 | } 409 | 410 | _Search3: 411 | /* 412 | * Currently we have : 413 | * ml2 > ml1, and 414 | * ip1+3 <= ip2 (usually < ip1+ml1) 415 | */ 416 | if ((start2 - ip) < OPTIMAL_ML) 417 | { 418 | int correction; 419 | int new_ml = ml; 420 | if (new_ml > OPTIMAL_ML) new_ml = OPTIMAL_ML; 421 | if (ip+new_ml > start2 + ml2 - MINMATCH) new_ml = (int)(start2 - ip) + ml2 - MINMATCH; 422 | correction = new_ml - (int)(start2 - ip); 423 | if (correction > 0) 424 | { 425 | start2 += correction; 426 | ref2 += correction; 427 | ml2 -= correction; 428 | } 429 | } 430 | /* Now, we have start2 = ip+new_ml, with new_ml = min(ml, OPTIMAL_ML=18) */ 431 | 432 | if (start2 + ml2 < mflimit) 433 | ml3 = LZ4HC_InsertAndGetWiderMatch(ctx, start2 + ml2 - 3, start2, matchlimit, ml2, &ref3, &start3, maxNbAttempts); 434 | else ml3 = ml2; 435 | 436 | if (ml3 == ml2) /* No better match : 2 sequences to encode */ 437 | { 438 | /* ip & ref are known; Now for ml */ 439 | if (start2 < ip+ml) ml = (int)(start2 - ip); 440 | /* Now, encode 2 sequences */ 441 | if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0; 442 | ip = start2; 443 | if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml2, ref2, limit, oend)) return 0; 444 | continue; 445 | } 446 | 447 | if (start3 < ip+ml+3) /* Not enough space for match 2 : remove it */ 448 | { 449 | if (start3 >= (ip+ml)) /* can write Seq1 immediately ==> Seq2 is removed, so Seq3 becomes Seq1 */ 450 | { 451 | if (start2 < ip+ml) 452 | { 453 | int correction = (int)(ip+ml - start2); 454 | start2 += correction; 455 | ref2 += correction; 456 | ml2 -= correction; 457 | if (ml2 < MINMATCH) 458 | { 459 | start2 = start3; 460 | ref2 = ref3; 461 | ml2 = ml3; 462 | } 463 | } 464 | 465 | if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0; 466 | ip = start3; 467 | ref = ref3; 468 | ml = ml3; 469 | 470 | start0 = start2; 471 | ref0 = ref2; 472 | ml0 = ml2; 473 | goto _Search2; 474 | } 475 | 476 | start2 = start3; 477 | ref2 = ref3; 478 | ml2 = ml3; 479 | goto _Search3; 480 | } 481 | 482 | /* 483 | * OK, now we have 3 ascending matches; let's write at least the first one 484 | * ip & ref are known; Now for ml 485 | */ 486 | if (start2 < ip+ml) 487 | { 488 | if ((start2 - ip) < (int)ML_MASK) 489 | { 490 | int correction; 491 | if (ml > OPTIMAL_ML) ml = OPTIMAL_ML; 492 | if (ip + ml > start2 + ml2 - MINMATCH) ml = (int)(start2 - ip) + ml2 - MINMATCH; 493 | correction = ml - (int)(start2 - ip); 494 | if (correction > 0) 495 | { 496 | start2 += correction; 497 | ref2 += correction; 498 | ml2 -= correction; 499 | } 500 | } 501 | else 502 | { 503 | ml = (int)(start2 - ip); 504 | } 505 | } 506 | if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0; 507 | 508 | ip = start2; 509 | ref = ref2; 510 | ml = ml2; 511 | 512 | start2 = start3; 513 | ref2 = ref3; 514 | ml2 = ml3; 515 | 516 | goto _Search3; 517 | } 518 | 519 | /* Encode Last Literals */ 520 | { 521 | int lastRun = (int)(iend - anchor); 522 | if ((limit) && (((char*)op - dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)) return 0; /* Check output limit */ 523 | if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK< 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; } 524 | else *op++ = (BYTE)(lastRun<base = NULL; 598 | ((LZ4HC_Data_Structure*)LZ4_streamHCPtr)->compressionLevel = (unsigned)compressionLevel; 599 | } 600 | 601 | int LZ4_loadDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, const char* dictionary, int dictSize) 602 | { 603 | LZ4HC_Data_Structure* ctxPtr = (LZ4HC_Data_Structure*) LZ4_streamHCPtr; 604 | if (dictSize > 64 KB) 605 | { 606 | dictionary += dictSize - 64 KB; 607 | dictSize = 64 KB; 608 | } 609 | LZ4HC_init (ctxPtr, (const BYTE*)dictionary); 610 | if (dictSize >= 4) LZ4HC_Insert (ctxPtr, (const BYTE*)dictionary +(dictSize-3)); 611 | ctxPtr->end = (const BYTE*)dictionary + dictSize; 612 | return dictSize; 613 | } 614 | 615 | 616 | /* compression */ 617 | 618 | static void LZ4HC_setExternalDict(LZ4HC_Data_Structure* ctxPtr, const BYTE* newBlock) 619 | { 620 | if (ctxPtr->end >= ctxPtr->base + 4) 621 | LZ4HC_Insert (ctxPtr, ctxPtr->end-3); /* Referencing remaining dictionary content */ 622 | /* Only one memory segment for extDict, so any previous extDict is lost at this stage */ 623 | ctxPtr->lowLimit = ctxPtr->dictLimit; 624 | ctxPtr->dictLimit = (U32)(ctxPtr->end - ctxPtr->base); 625 | ctxPtr->dictBase = ctxPtr->base; 626 | ctxPtr->base = newBlock - ctxPtr->dictLimit; 627 | ctxPtr->end = newBlock; 628 | ctxPtr->nextToUpdate = ctxPtr->dictLimit; /* match referencing will resume from there */ 629 | } 630 | 631 | static int LZ4_compressHC_continue_generic (LZ4HC_Data_Structure* ctxPtr, 632 | const char* source, char* dest, 633 | int inputSize, int maxOutputSize, limitedOutput_directive limit) 634 | { 635 | /* auto-init if forgotten */ 636 | if (ctxPtr->base == NULL) 637 | LZ4HC_init (ctxPtr, (const BYTE*) source); 638 | 639 | /* Check overflow */ 640 | if ((size_t)(ctxPtr->end - ctxPtr->base) > 2 GB) 641 | { 642 | size_t dictSize = (size_t)(ctxPtr->end - ctxPtr->base) - ctxPtr->dictLimit; 643 | if (dictSize > 64 KB) dictSize = 64 KB; 644 | 645 | LZ4_loadDictHC((LZ4_streamHC_t*)ctxPtr, (const char*)(ctxPtr->end) - dictSize, (int)dictSize); 646 | } 647 | 648 | /* Check if blocks follow each other */ 649 | if ((const BYTE*)source != ctxPtr->end) LZ4HC_setExternalDict(ctxPtr, (const BYTE*)source); 650 | 651 | /* Check overlapping input/dictionary space */ 652 | { 653 | const BYTE* sourceEnd = (const BYTE*) source + inputSize; 654 | const BYTE* dictBegin = ctxPtr->dictBase + ctxPtr->lowLimit; 655 | const BYTE* dictEnd = ctxPtr->dictBase + ctxPtr->dictLimit; 656 | if ((sourceEnd > dictBegin) && ((BYTE*)source < dictEnd)) 657 | { 658 | if (sourceEnd > dictEnd) sourceEnd = dictEnd; 659 | ctxPtr->lowLimit = (U32)(sourceEnd - ctxPtr->dictBase); 660 | if (ctxPtr->dictLimit - ctxPtr->lowLimit < 4) ctxPtr->lowLimit = ctxPtr->dictLimit; 661 | } 662 | } 663 | 664 | return LZ4HC_compress_generic (ctxPtr, source, dest, inputSize, maxOutputSize, ctxPtr->compressionLevel, limit); 665 | } 666 | 667 | int LZ4_compressHC_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize) 668 | { 669 | return LZ4_compressHC_continue_generic ((LZ4HC_Data_Structure*)LZ4_streamHCPtr, source, dest, inputSize, 0, noLimit); 670 | } 671 | 672 | int LZ4_compressHC_limitedOutput_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize, int maxOutputSize) 673 | { 674 | return LZ4_compressHC_continue_generic ((LZ4HC_Data_Structure*)LZ4_streamHCPtr, source, dest, inputSize, maxOutputSize, limitedOutput); 675 | } 676 | 677 | 678 | /* dictionary saving */ 679 | 680 | int LZ4_saveDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, char* safeBuffer, int dictSize) 681 | { 682 | LZ4HC_Data_Structure* streamPtr = (LZ4HC_Data_Structure*)LZ4_streamHCPtr; 683 | int prefixSize = (int)(streamPtr->end - (streamPtr->base + streamPtr->dictLimit)); 684 | if (dictSize > 64 KB) dictSize = 64 KB; 685 | if (dictSize < 4) dictSize = 0; 686 | if (dictSize > prefixSize) dictSize = prefixSize; 687 | memcpy(safeBuffer, streamPtr->end - dictSize, dictSize); 688 | { 689 | U32 endIndex = (U32)(streamPtr->end - streamPtr->base); 690 | streamPtr->end = (const BYTE*)safeBuffer + dictSize; 691 | streamPtr->base = streamPtr->end - endIndex; 692 | streamPtr->dictLimit = endIndex - dictSize; 693 | streamPtr->lowLimit = endIndex - dictSize; 694 | if (streamPtr->nextToUpdate < streamPtr->dictLimit) streamPtr->nextToUpdate = streamPtr->dictLimit; 695 | } 696 | return dictSize; 697 | } 698 | 699 | 700 | /*********************************** 701 | * Deprecated Functions 702 | ***********************************/ 703 | int LZ4_sizeofStreamStateHC(void) { return LZ4_STREAMHCSIZE; } 704 | 705 | int LZ4_resetStreamStateHC(void* state, const char* inputBuffer) 706 | { 707 | if ((((size_t)state) & (sizeof(void*)-1)) != 0) return 1; /* Error : pointer is not aligned for pointer (32 or 64 bits) */ 708 | LZ4HC_init((LZ4HC_Data_Structure*)state, (const BYTE*)inputBuffer); 709 | return 0; 710 | } 711 | 712 | void* LZ4_createHC (const char* inputBuffer) 713 | { 714 | void* hc4 = ALLOCATOR(1, sizeof(LZ4HC_Data_Structure)); 715 | LZ4HC_init ((LZ4HC_Data_Structure*)hc4, (const BYTE*)inputBuffer); 716 | return hc4; 717 | } 718 | 719 | int LZ4_freeHC (void* LZ4HC_Data) 720 | { 721 | FREEMEM(LZ4HC_Data); 722 | return (0); 723 | } 724 | 725 | /* 726 | int LZ4_compressHC_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize) 727 | { 728 | return LZ4HC_compress_generic (LZ4HC_Data, source, dest, inputSize, 0, 0, noLimit); 729 | } 730 | int LZ4_compressHC_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize) 731 | { 732 | return LZ4HC_compress_generic (LZ4HC_Data, source, dest, inputSize, maxOutputSize, 0, limitedOutput); 733 | } 734 | */ 735 | 736 | int LZ4_compressHC2_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int compressionLevel) 737 | { 738 | return LZ4HC_compress_generic (LZ4HC_Data, source, dest, inputSize, 0, compressionLevel, noLimit); 739 | } 740 | 741 | int LZ4_compressHC2_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel) 742 | { 743 | return LZ4HC_compress_generic (LZ4HC_Data, source, dest, inputSize, maxOutputSize, compressionLevel, limitedOutput); 744 | } 745 | 746 | char* LZ4_slideInputBufferHC(void* LZ4HC_Data) 747 | { 748 | LZ4HC_Data_Structure* hc4 = (LZ4HC_Data_Structure*)LZ4HC_Data; 749 | int dictSize = LZ4_saveDictHC((LZ4_streamHC_t*)LZ4HC_Data, (char*)(hc4->inputBuffer), 64 KB); 750 | return (char*)(hc4->inputBuffer + dictSize); 751 | } 752 | -------------------------------------------------------------------------------- /firmware/lz4/lz4hc.h: -------------------------------------------------------------------------------- 1 | /* 2 | LZ4 HC - High Compression Mode of LZ4 3 | Header File 4 | Copyright (C) 2011-2014, Yann Collet. 5 | BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are 9 | met: 10 | 11 | * Redistributions of source code must retain the above copyright 12 | notice, this list of conditions and the following disclaimer. 13 | * Redistributions in binary form must reproduce the above 14 | copyright notice, this list of conditions and the following disclaimer 15 | in the documentation and/or other materials provided with the 16 | distribution. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | You can contact the author at : 31 | - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html 32 | - LZ4 source repository : http://code.google.com/p/lz4/ 33 | */ 34 | #pragma once 35 | 36 | 37 | #if defined (__cplusplus) 38 | extern "C" { 39 | #endif 40 | 41 | 42 | int LZ4_compressHC (const char* source, char* dest, int inputSize); 43 | /* 44 | LZ4_compressHC : 45 | return : the number of bytes in compressed buffer dest 46 | or 0 if compression fails. 47 | note : destination buffer must be already allocated. 48 | To avoid any problem, size it to handle worst cases situations (input data not compressible) 49 | Worst case size evaluation is provided by function LZ4_compressBound() (see "lz4.h") 50 | */ 51 | 52 | int LZ4_compressHC_limitedOutput (const char* source, char* dest, int inputSize, int maxOutputSize); 53 | /* 54 | LZ4_compress_limitedOutput() : 55 | Compress 'inputSize' bytes from 'source' into an output buffer 'dest' of maximum size 'maxOutputSize'. 56 | If it cannot achieve it, compression will stop, and result of the function will be zero. 57 | This function never writes outside of provided output buffer. 58 | 59 | inputSize : Max supported value is 1 GB 60 | maxOutputSize : is maximum allowed size into the destination buffer (which must be already allocated) 61 | return : the number of output bytes written in buffer 'dest' 62 | or 0 if compression fails. 63 | */ 64 | 65 | 66 | int LZ4_compressHC2 (const char* source, char* dest, int inputSize, int compressionLevel); 67 | int LZ4_compressHC2_limitedOutput (const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel); 68 | /* 69 | Same functions as above, but with programmable 'compressionLevel'. 70 | Recommended values are between 4 and 9, although any value between 0 and 16 will work. 71 | 'compressionLevel'==0 means use default 'compressionLevel' value. 72 | Values above 16 behave the same as 16. 73 | Equivalent variants exist for all other compression functions below. 74 | */ 75 | 76 | /* Note : 77 | Decompression functions are provided within LZ4 source code (see "lz4.h") (BSD license) 78 | */ 79 | 80 | 81 | /************************************** 82 | Using an external allocation 83 | **************************************/ 84 | int LZ4_sizeofStateHC(void); 85 | int LZ4_compressHC_withStateHC (void* state, const char* source, char* dest, int inputSize); 86 | int LZ4_compressHC_limitedOutput_withStateHC (void* state, const char* source, char* dest, int inputSize, int maxOutputSize); 87 | 88 | int LZ4_compressHC2_withStateHC (void* state, const char* source, char* dest, int inputSize, int compressionLevel); 89 | int LZ4_compressHC2_limitedOutput_withStateHC(void* state, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel); 90 | 91 | /* 92 | These functions are provided should you prefer to allocate memory for compression tables with your own allocation methods. 93 | To know how much memory must be allocated for the compression tables, use : 94 | int LZ4_sizeofStateHC(); 95 | 96 | Note that tables must be aligned for pointer (32 or 64 bits), otherwise compression will fail (return code 0). 97 | 98 | The allocated memory can be provided to the compression functions using 'void* state' parameter. 99 | LZ4_compress_withStateHC() and LZ4_compress_limitedOutput_withStateHC() are equivalent to previously described functions. 100 | They just use the externally allocated memory for state instead of allocating their own (on stack, or on heap). 101 | */ 102 | 103 | 104 | 105 | /************************************** 106 | Experimental Streaming Functions 107 | **************************************/ 108 | #define LZ4_STREAMHCSIZE_U64 32774 109 | #define LZ4_STREAMHCSIZE (LZ4_STREAMHCSIZE_U64 * sizeof(unsigned long long)) 110 | typedef struct { unsigned long long table[LZ4_STREAMHCSIZE_U64]; } LZ4_streamHC_t; 111 | /* 112 | LZ4_streamHC_t 113 | This structure allows static allocation of LZ4 HC streaming state. 114 | State must then be initialized using LZ4_resetStreamHC() before first use. 115 | 116 | Static allocation should only be used with statically linked library. 117 | If you want to use LZ4 as a DLL, please use construction functions below, which are more future-proof. 118 | */ 119 | 120 | 121 | LZ4_streamHC_t* LZ4_createStreamHC(void); 122 | int LZ4_freeStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr); 123 | /* 124 | These functions create and release memory for LZ4 HC streaming state. 125 | Newly created states are already initialized. 126 | Existing state space can be re-used anytime using LZ4_resetStreamHC(). 127 | If you use LZ4 as a DLL, please use these functions instead of direct struct allocation, 128 | to avoid size mismatch between different versions. 129 | */ 130 | 131 | void LZ4_resetStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel); 132 | int LZ4_loadDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, const char* dictionary, int dictSize); 133 | 134 | int LZ4_compressHC_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize); 135 | int LZ4_compressHC_limitedOutput_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize, int maxOutputSize); 136 | 137 | int LZ4_saveDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, char* safeBuffer, int maxDictSize); 138 | 139 | /* 140 | These functions compress data in successive blocks of any size, using previous blocks as dictionary. 141 | One key assumption is that each previous block will remain read-accessible while compressing next block. 142 | 143 | Before starting compression, state must be properly initialized, using LZ4_resetStreamHC(). 144 | A first "fictional block" can then be designated as initial dictionary, using LZ4_loadDictHC() (Optional). 145 | 146 | Then, use LZ4_compressHC_continue() or LZ4_compressHC_limitedOutput_continue() to compress each successive block. 147 | They work like usual LZ4_compressHC() or LZ4_compressHC_limitedOutput(), but use previous memory blocks to improve compression. 148 | Previous memory blocks (including initial dictionary when present) must remain accessible and unmodified during compression. 149 | 150 | If, for any reason, previous data block can't be preserved in memory during next compression block, 151 | you must save it to a safer memory space, 152 | using LZ4_saveDictHC(). 153 | */ 154 | 155 | 156 | 157 | /************************************** 158 | * Deprecated Streaming Functions 159 | * ************************************/ 160 | /* Note : these streaming functions follows the older model, and should no longer be used */ 161 | void* LZ4_createHC (const char* inputBuffer); 162 | char* LZ4_slideInputBufferHC (void* LZ4HC_Data); 163 | int LZ4_freeHC (void* LZ4HC_Data); 164 | 165 | int LZ4_compressHC2_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int compressionLevel); 166 | int LZ4_compressHC2_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel); 167 | 168 | int LZ4_sizeofStreamStateHC(void); 169 | int LZ4_resetStreamStateHC(void* state, const char* inputBuffer); 170 | 171 | 172 | #if defined (__cplusplus) 173 | } 174 | #endif 175 | -------------------------------------------------------------------------------- /firmware/lz4/xxhash.h: -------------------------------------------------------------------------------- 1 | /* 2 | xxHash - Extremely Fast Hash algorithm 3 | Header File 4 | Copyright (C) 2012-2014, Yann Collet. 5 | BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are 9 | met: 10 | 11 | * Redistributions of source code must retain the above copyright 12 | notice, this list of conditions and the following disclaimer. 13 | * Redistributions in binary form must reproduce the above 14 | copyright notice, this list of conditions and the following disclaimer 15 | in the documentation and/or other materials provided with the 16 | distribution. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | You can contact the author at : 31 | - xxHash source repository : http://code.google.com/p/xxhash/ 32 | */ 33 | 34 | /* Notice extracted from xxHash homepage : 35 | 36 | xxHash is an extremely fast Hash algorithm, running at RAM speed limits. 37 | It also successfully passes all tests from the SMHasher suite. 38 | 39 | Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz) 40 | 41 | Name Speed Q.Score Author 42 | xxHash 5.4 GB/s 10 43 | CrapWow 3.2 GB/s 2 Andrew 44 | MumurHash 3a 2.7 GB/s 10 Austin Appleby 45 | SpookyHash 2.0 GB/s 10 Bob Jenkins 46 | SBox 1.4 GB/s 9 Bret Mulvey 47 | Lookup3 1.2 GB/s 9 Bob Jenkins 48 | SuperFastHash 1.2 GB/s 1 Paul Hsieh 49 | CityHash64 1.05 GB/s 10 Pike & Alakuijala 50 | FNV 0.55 GB/s 5 Fowler, Noll, Vo 51 | CRC32 0.43 GB/s 9 52 | MD5-32 0.33 GB/s 10 Ronald L. Rivest 53 | SHA1-32 0.28 GB/s 10 54 | 55 | Q.Score is a measure of quality of the hash function. 56 | It depends on successfully passing SMHasher test set. 57 | 10 is a perfect score. 58 | */ 59 | 60 | #pragma once 61 | 62 | #if defined (__cplusplus) 63 | extern "C" { 64 | #endif 65 | 66 | 67 | /***************************** 68 | Includes 69 | *****************************/ 70 | #include /* size_t */ 71 | 72 | 73 | /***************************** 74 | Type 75 | *****************************/ 76 | typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode; 77 | 78 | 79 | 80 | /***************************** 81 | Simple Hash Functions 82 | *****************************/ 83 | 84 | unsigned int XXH32 (const void* input, size_t length, unsigned seed); 85 | unsigned long long XXH64 (const void* input, size_t length, unsigned long long seed); 86 | 87 | /* 88 | XXH32() : 89 | Calculate the 32-bits hash of sequence "length" bytes stored at memory address "input". 90 | The memory between input & input+length must be valid (allocated and read-accessible). 91 | "seed" can be used to alter the result predictably. 92 | This function successfully passes all SMHasher tests. 93 | Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s 94 | XXH64() : 95 | Calculate the 64-bits hash of sequence of length "len" stored at memory address "input". 96 | */ 97 | 98 | 99 | 100 | /***************************** 101 | Advanced Hash Functions 102 | *****************************/ 103 | typedef struct { long long ll[ 6]; } XXH32_state_t; 104 | typedef struct { long long ll[11]; } XXH64_state_t; 105 | 106 | /* 107 | These structures allow static allocation of XXH states. 108 | States must then be initialized using XXHnn_reset() before first use. 109 | 110 | If you prefer dynamic allocation, please refer to functions below. 111 | */ 112 | 113 | XXH32_state_t* XXH32_createState(void); 114 | XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr); 115 | 116 | XXH64_state_t* XXH64_createState(void); 117 | XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr); 118 | 119 | /* 120 | These functions create and release memory for XXH state. 121 | States must then be initialized using XXHnn_reset() before first use. 122 | */ 123 | 124 | 125 | XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, unsigned seed); 126 | XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length); 127 | unsigned int XXH32_digest (const XXH32_state_t* statePtr); 128 | 129 | XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, unsigned long long seed); 130 | XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length); 131 | unsigned long long XXH64_digest (const XXH64_state_t* statePtr); 132 | 133 | /* 134 | These functions calculate the xxHash of an input provided in multiple smaller packets, 135 | as opposed to an input provided as a single block. 136 | 137 | XXH state space must first be allocated, using either static or dynamic method provided above. 138 | 139 | Start a new hash by initializing state with a seed, using XXHnn_reset(). 140 | 141 | Then, feed the hash state by calling XXHnn_update() as many times as necessary. 142 | Obviously, input must be valid, meaning allocated and read accessible. 143 | The function returns an error code, with 0 meaning OK, and any other value meaning there is an error. 144 | 145 | Finally, you can produce a hash anytime, by using XXHnn_digest(). 146 | This function returns the final nn-bits hash. 147 | You can nonetheless continue feeding the hash state with more input, 148 | and therefore get some new hashes, by calling again XXHnn_digest(). 149 | 150 | When you are done, don't forget to free XXH state space, using typically XXHnn_freeState(). 151 | */ 152 | 153 | 154 | #if defined (__cplusplus) 155 | } 156 | #endif 157 | -------------------------------------------------------------------------------- /firmware/openocd.cfg: -------------------------------------------------------------------------------- 1 | 2 | # source [find interface/cmsis-dap.cfg] 3 | interface jlink 4 | 5 | transport select swd 6 | 7 | set CHIPNAME at91samd21e17a 8 | 9 | source [find target/at91samdXX.cfg] 10 | 11 | gdb_port 3333 12 | -------------------------------------------------------------------------------- /firmware/pins.c: -------------------------------------------------------------------------------- 1 | #include "protocol/donglepi.pb.h" 2 | #include "pins.h" 3 | #include "board.h" 4 | #include "dbg.h" 5 | 6 | // RPI GPIO # -> SAMD pin# 7 | uint8_t pin_map[28] = { 8 | 0, 0, 9 | PIN_PA16, // GPIO02 10 | PIN_PA17, // GPIO03 11 | PIN_PA22, // GPIO04 12 | 0, 0, 13 | PIN_PA02, // GPIO07 14 | PIN_PA11, // GPIO08 15 | PIN_PA09, // GPIO09 16 | PIN_PA08, // GPIO10 17 | PIN_PA10, // GPIO11 18 | 0, 0, 19 | PIN_PA14, // GPIO14 20 | PIN_PA15, // GPIO15 21 | 0, 22 | PIN_PA00, // GPIO17 23 | PIN_PA04, // GPIO18 24 | 0, 0, 0, 25 | PIN_PA01, // GPIO22 26 | PIN_PA05, // GPIO23 27 | PIN_PA07, // GPIO24 28 | PIN_PA23, // GPIO25 29 | 0, 30 | PIN_PA06 // GPIO27 31 | }; 32 | 33 | static pinconfig_t pin_configs[28] = {0}; 34 | 35 | static bool i2c_on = false; 36 | static bool uart_on = true; 37 | static bool spi_on = false; 38 | 39 | // returns true if the pin is assignable to a GPIO 40 | bool is_available_for_GPIO(uint8_t pin) { 41 | return (pin < 28 && pin_map[pin] != 0) && !(i2c_on && is_uart_pin(pin)) && 42 | !(uart_on && is_uart_pin(pin)) && !(spi_on && is_spi_pin(pin)); 43 | } 44 | 45 | bool set_pin_GPIO_config(uint8_t pin, pinconfig_t config) { 46 | if (config.active && !is_available_for_GPIO(pin)) { 47 | return false; 48 | } 49 | pin_configs[pin] = config; 50 | return true; 51 | } 52 | 53 | bool switch_i2c(bool on) { 54 | if (on && (pin_configs[I2C_PIN1].active || pin_configs[I2C_PIN2].active)) { 55 | return false; 56 | } 57 | i2c_on = on; 58 | return true; 59 | } 60 | 61 | bool switch_spi(bool on) { 62 | if (on && (pin_configs[SPI_PIN1].active || pin_configs[SPI_PIN2].active || 63 | pin_configs[SPI_PIN3].active || pin_configs[SPI_PIN4].active)) { 64 | return false; 65 | } 66 | spi_on = on; 67 | return true; 68 | } 69 | 70 | bool switch_uart(bool on) { 71 | if (on && (pin_configs[UART_PIN1].active || pin_configs[UART_PIN2].active)) { 72 | return false; 73 | } 74 | #if SERIAL_DEBUG 75 | if (on) { 76 | l("ERROR: the uart is already used for the serial debug console, rebuild " 77 | "without SERIAL_DEBUG"); 78 | return false; 79 | } 80 | #endif 81 | uart_on = on; 82 | return true; 83 | } 84 | 85 | pinconfig_t* get_pin_GPIO_config(uint8_t pin) { return &(pin_configs[pin]); } 86 | -------------------------------------------------------------------------------- /firmware/pins.h: -------------------------------------------------------------------------------- 1 | #ifndef _PINS_H_ 2 | #define _PINS_H_ 3 | 4 | #define NB_PINS 28 5 | 6 | // everything related to pin configuration. 7 | extern uint8_t pin_map[NB_PINS]; 8 | 9 | typedef struct pinconfig { 10 | bool active; 11 | Config_GPIO_Pin_Direction direction; 12 | Config_GPIO_Pin_Pull pull; 13 | Config_GPIO_Pin_Edge trigger; 14 | } pinconfig_t; 15 | 16 | #define SPI_PIN1 8 17 | #define SPI_PIN2 9 18 | #define SPI_PIN3 10 19 | #define SPI_PIN4 11 20 | 21 | #define UART_PIN1 14 22 | #define UART_PIN2 15 23 | 24 | #define I2C_PIN1 2 25 | #define I2C_PIN2 3 26 | 27 | #define is_spi_pin(X) \ 28 | (X == SPI_PIN1 || X == SPI_PIN2 || X == SPI_PIN3 || X == SPI_PIN4) 29 | #define is_uart_pin(X) (X == UART_PIN1 || X == UART_PIN2) 30 | #define is_i2c_pin(X) (X == I2C_PIN1 || X == I2C_PIN2) 31 | 32 | bool is_available_for_GPIO(uint8_t pin); 33 | bool set_pin_GPIO_config(uint8_t pin, pinconfig_t config); 34 | pinconfig_t* get_pin_GPIO_config(uint8_t pin); 35 | 36 | bool switch_i2c(bool on); 37 | bool switch_spi(bool on); 38 | bool switch_uart(bool on); 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /firmware/protocol/Makefile: -------------------------------------------------------------------------------- 1 | # Include the nanopb provided Makefile rules 2 | include ../nanopb/extra/nanopb.mk 3 | 4 | # Build rule for the protocol 5 | donglepi.pb.c: ../../protocol/donglepi.proto 6 | cd ../nanopb/generator/proto; make 7 | $(PROTOC) $(PROTOC_OPTS) --nanopb_out=. -I../../protocol -I../../firmware/nanopb/generator/proto ../../protocol/donglepi.proto 8 | 9 | clean: 10 | rm -f donglepi.pb.c 11 | rm -f donglepi.pb.h 12 | -------------------------------------------------------------------------------- /firmware/spi.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "dbg.h" 3 | #include "spi.h" 4 | #include "pins.h" 5 | 6 | struct spi_module spi_master_instance; 7 | struct spi_slave_inst slave; 8 | 9 | static void w(uint8_t num, ...) { 10 | static uint8_t sbuffer[5]; 11 | va_list args; 12 | va_start(args, num); 13 | for (int x = 0; x < num; x++) sbuffer[x] = (uint8_t)va_arg(args, int); 14 | va_end(args); 15 | 16 | l("Write (%d) %x %x %x", num, sbuffer[0], sbuffer[1], sbuffer[2]); 17 | if (spi_write_buffer_wait(&spi_master_instance, sbuffer, num) != STATUS_OK) { 18 | l("Error writing"); 19 | } 20 | } 21 | 22 | static void spi_config(Config_SPI psi_proto_config) { 23 | // SPI test 24 | struct spi_config config_spi_master; 25 | struct spi_slave_inst_config slave_dev_config; 26 | /* Configure and initialize software device instance of peripheral slave */ 27 | spi_slave_inst_get_config_defaults(&slave_dev_config); 28 | slave_dev_config.ss_pin = PIN_PA09; 29 | spi_attach_slave(&slave, &slave_dev_config); 30 | 31 | /* Configure, initialize and enable SERCOM SPI module */ 32 | spi_get_config_defaults(&config_spi_master); 33 | config_spi_master.mux_setting = SPI_SIGNAL_MUX_SETTING_E; 34 | /* Configure pad 0 for MISO */ 35 | config_spi_master.pinmux_pad0 = PINMUX_PA08C_SERCOM0_PAD0; 36 | /* Configure pad 1 for CS */ 37 | config_spi_master.pinmux_pad1 = PINMUX_UNUSED; 38 | /* Configure pad 2 for MOSI */ 39 | config_spi_master.pinmux_pad2 = PINMUX_PA10C_SERCOM0_PAD2; 40 | /* Configure pad 3 for SCK */ 41 | config_spi_master.pinmux_pad3 = PINMUX_PA11C_SERCOM0_PAD3; 42 | 43 | l("SPI set to baudrate %d", config_spi_master.mode_specific.master.baudrate); 44 | 45 | if (spi_init(&spi_master_instance, SERCOM0, &config_spi_master) != 46 | STATUS_OK) { 47 | l("SPI init failed"); 48 | } 49 | spi_enable(&spi_master_instance); 50 | 51 | if (spi_select_slave(&spi_master_instance, &slave, true) != STATUS_OK) { 52 | l("spi_select_slave error"); 53 | } 54 | 55 | // TODO just a test push that correctly in write 56 | l("reeeeeset"); 57 | port_pin_set_output_level(PIN_PA22, 0); 58 | cpu_delay_s(1); 59 | l("done"); 60 | port_pin_set_output_level(PIN_PA22, 1); 61 | 62 | port_pin_set_output_level(PIN_PA00, 0); 63 | l("DC in command"); 64 | cpu_delay_s(1); 65 | l("Write stuff to SPI"); 66 | w(1, 0xAE); // DISPLAY_OFF 67 | w(2, 0xD5, 0x80); // SET_DISPLAY_CLOCK_DIV, 0x80 68 | w(2, 0xA8, 0x1F); // SET_MULTIPLEX, 0x1F 69 | w(2, 0xDA, 0x02); // SET_COM_PINS, 0x02 70 | w(2, 0xD3, 0x00); // SET_DISPLAY_OFFSET, 0x00 71 | w(1, 0x40); // SET_START_LINE | 0x00 72 | w(2, 0x8D, 0x14); // CHARGE_PUMP, 0x14 73 | w(2, 0x20, 0x00); // SET_MEMORY_MODE, 0x00 74 | w(1, 0xA0 | 0x01); // SEG_REMAP | 0x01 75 | w(1, 0xC8); // COM_SCAN_DEC 76 | w(2, 0x81, 0x8F); // SET_CONTRAST, 0x8f 77 | w(2, 0xD9, 0xF1); // SET_PRECHARGE, 0xF1 78 | w(2, 0xDB, 0x40); // SET_VCOM_DETECT, 0x40 79 | w(1, 0xA4); // DISPLAY_ALL_ON_RESUME 80 | w(1, 0xA6); // NORMAL_DISPLAY 81 | w(1, 0xAF); // DISPLAY_ON 82 | // Draw 83 | w(2, 0x20, 0x01); // SET_MEMORY_MODE, MEMORY_MODE_VERT 84 | w(3, 0x22, 0, 0); // SET_PAGE_ADDRESS, page_start, page_end 85 | w(3, 0x21, 0, 0); // SET_COL_ADDRESS, col_start, col_end 86 | l("Done Writing stuff to SPI"); 87 | port_pin_set_output_level(PIN_PA00, 1); 88 | l("DC in data"); 89 | cpu_delay_s(1); 90 | w(3, 0xFF, 0xFF, 0xFF); // self.data 91 | 92 | if (spi_select_slave(&spi_master_instance, &slave, false) != STATUS_OK) { 93 | l("spi_*DE*select_slave error"); 94 | } 95 | 96 | l("SPI done"); 97 | } 98 | 99 | 100 | bool handle_spi_config_cb(pb_istream_t *stream, const pb_field_t *field, 101 | void **arg) { 102 | l("Configuration for spi..."); 103 | Config_SPI spi; 104 | if (!pb_decode(stream, Config_SPI_fields, &spi)) { 105 | l("Failed to decode a SPI configuration"); 106 | } 107 | 108 | if (switch_spi(spi.enabled)) { 109 | if (spi.enabled) { 110 | spi_config(spi); 111 | l("SPI enabled"); 112 | } else { 113 | spi_disable(&spi_master_instance); 114 | l("SPI disabled"); 115 | } 116 | } else { 117 | l("SPI cannot be enabled/disabled"); 118 | } 119 | return true; 120 | } 121 | 122 | static bool handle_spi_write_data_cb(pb_istream_t *stream, 123 | const pb_field_t *field, void **arg) { 124 | return true; 125 | } 126 | 127 | 128 | bool handle_spi_write_cb(pb_istream_t *stream, const pb_field_t *field, 129 | void **arg) { 130 | return true; 131 | } 132 | -------------------------------------------------------------------------------- /firmware/spi.h: -------------------------------------------------------------------------------- 1 | #ifndef _SPI_H_ 2 | #define _SPI_H_ 3 | #include 4 | #include "protocol/donglepi.pb.h" 5 | bool handle_spi_config_cb(pb_istream_t *stream, const pb_field_t *field, 6 | void **arg); 7 | bool handle_spi_write_cb(pb_istream_t *stream, const pb_field_t *field, 8 | void **arg); 9 | #endif 10 | -------------------------------------------------------------------------------- /firmware/uart.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "uart.h" 3 | #include "pins.h" 4 | #include "dbg.h" 5 | 6 | /* 7 | message UART { 8 | enum Speed { 9 | BAUD_RATE_115200 = 115200; 10 | } 11 | enum Chr { 12 | _5 = 5; 13 | _6 = 6; 14 | _7 = 7; 15 | _8 = 8; 16 | _9 = 9; 17 | } 18 | enum Parity { 19 | NONE = 0; 20 | ODD = 1; 21 | EVEN = 2; 22 | } 23 | enum StopBits { 24 | _1 = 1; 25 | _2 = 2; 26 | } 27 | required bool enabled = 1; 28 | required Speed speed = 2 [default = BAUD_RATE_115200]; 29 | required Chr chr = 3 [default = _8]; 30 | required Parity parity = 4 [default = NONE]; 31 | required StopBits stop_bits = 5 [default = _1]; 32 | } 33 | */ 34 | 35 | #if !SERIAL_DEBUG 36 | struct usart_module usart_module; 37 | struct usart_config usart_conf; 38 | #endif 39 | 40 | static void uart_config(Config_UART config) { 41 | #if !SERIAL_DEBUG 42 | l("UART enabled"); 43 | usart_get_config_defaults(&usart_conf); 44 | switch (config.speed) { 45 | case Config_UART_Speed_BAUD_RATE_115200: 46 | usart_conf.baudrate = 115200; 47 | break; 48 | // TODO: other speeds 49 | } 50 | switch (config.chr) { 51 | case Config_UART_Chr_B5: 52 | usart_conf.character_size = USART_CHARACTER_SIZE_5BIT; 53 | break; 54 | case Config_UART_Chr_B6: 55 | usart_conf.character_size = USART_CHARACTER_SIZE_6BIT; 56 | break; 57 | case Config_UART_Chr_B7: 58 | usart_conf.character_size = USART_CHARACTER_SIZE_7BIT; 59 | break; 60 | case Config_UART_Chr_B8: 61 | usart_conf.character_size = USART_CHARACTER_SIZE_8BIT; 62 | break; 63 | case Config_UART_Chr_B9: 64 | usart_conf.character_size = USART_CHARACTER_SIZE_9BIT; 65 | break; 66 | } 67 | switch (config.parity) { 68 | case Config_UART_Parity_NONE: 69 | usart_conf.parity = USART_PARITY_NONE; 70 | break; 71 | case Config_UART_Parity_ODD: 72 | usart_conf.parity = USART_PARITY_ODD; 73 | break; 74 | case Config_UART_Parity_EVEN: 75 | usart_conf.parity = USART_PARITY_EVEN; 76 | break; 77 | } 78 | switch (config.stop_bits) { 79 | case Config_UART_StopBits_S1: 80 | usart_conf.stopbits = USART_STOPBITS_1; 81 | break; 82 | case Config_UART_StopBits_S2: 83 | usart_conf.stopbits = USART_STOPBITS_2; 84 | break; 85 | } 86 | 87 | usart_conf.mux_setting = USART_RX_3_TX_2_XCK_3; 88 | usart_conf.pinmux_pad0 = PINMUX_UNUSED; 89 | usart_conf.pinmux_pad1 = PINMUX_UNUSED; 90 | usart_conf.pinmux_pad2 = PINMUX_PA14C_SERCOM2_PAD2; 91 | usart_conf.pinmux_pad3 = PINMUX_PA15C_SERCOM2_PAD3; 92 | while (usart_init(&usart_module, SERCOM2, &usart_conf) != STATUS_OK) { 93 | } 94 | usart_enable(&usart_module); 95 | #endif 96 | } 97 | 98 | bool handle_uart_config_cb(pb_istream_t *stream, const pb_field_t *field, 99 | void **arg) { 100 | l("Configuration for uart..."); 101 | Config_UART uart; 102 | if (!pb_decode(stream, Config_UART_fields, &uart)) { 103 | l("Failed to decode a uart configuration"); 104 | } 105 | if (switch_uart(uart.enabled)) { 106 | if (uart.enabled) { 107 | uart_config(uart); 108 | } else { 109 | #if !SERIAL_DEBUG 110 | usart_disable(&usart_module); 111 | #endif 112 | l("usart disabled"); 113 | } 114 | } else { 115 | l("UART cannot be enabled/disabled"); 116 | } 117 | return true; 118 | } 119 | 120 | bool handle_uart_write_cb(pb_istream_t *stream, const pb_field_t *field, 121 | void **arg) { 122 | // usart_write_buffer_wait(&usart_module, (const uint8_t *)string, size); 123 | return true; 124 | } 125 | -------------------------------------------------------------------------------- /firmware/uart.h: -------------------------------------------------------------------------------- 1 | #ifndef _UART_H_ 2 | #define _UART_H_ 3 | 4 | #include 5 | #include "protocol/donglepi.pb.h" 6 | bool handle_uart_config_cb(pb_istream_t *stream, const pb_field_t *field, 7 | void **arg); 8 | bool handle_uart_write_cb(pb_istream_t *stream, const pb_field_t *field, 9 | void **arg); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /firmware/ui.h: -------------------------------------------------------------------------------- 1 | #ifndef _UI_H_ 2 | #define _UI_H_ 3 | 4 | //! \brief Initializes the user interface 5 | void ui_init(void); 6 | 7 | //! \brief Enters the user interface in power down mode 8 | void ui_powerdown(void); 9 | 10 | //! \brief Exits the user interface of power down mode 11 | void ui_wakeup(void); 12 | 13 | /*! \brief Called when communication port is opened 14 | */ 15 | void ui_com_open(uint8_t port); 16 | 17 | /*! \brief Called when communication port is closed 18 | */ 19 | void ui_com_close(uint8_t port); 20 | 21 | /*! \brief Called when a data is received on CDC 22 | */ 23 | void ui_com_rx_start(void); 24 | 25 | /*! \brief Called when a data is received on port com 26 | */ 27 | void ui_com_tx_start(void); 28 | 29 | /*! \brief Called when all data pending are sent on port com 30 | */ 31 | void ui_com_rx_stop(void); 32 | 33 | /*! \brief Called when all data pending are sent on CDC 34 | */ 35 | void ui_com_tx_stop(void); 36 | 37 | /*! \brief Called when a communication error occur 38 | */ 39 | void ui_com_error(void); 40 | 41 | /*! \brief Called when a overflow occur 42 | */ 43 | void ui_com_overflow(void); 44 | 45 | /*! \brief This process is called each 1ms 46 | * It is called only if the USB interface is enabled. 47 | * 48 | * \param framenumber Current frame number 49 | */ 50 | void ui_process(uint16_t framenumber); 51 | 52 | #endif // _UI_H_ 53 | -------------------------------------------------------------------------------- /pcb/DESCRIPTION: -------------------------------------------------------------------------------- 1 | Rapberry Pi your PC 2 | -------------------------------------------------------------------------------- /pcb/eagle.epf: -------------------------------------------------------------------------------- 1 | [Eagle] 2 | Version="07 02 00" 3 | Platform="Linux" 4 | Serial="62191E841E-LSR-WLM-1EL" 5 | Globals="Globals" 6 | Desktop="Desktop" 7 | 8 | [Globals] 9 | AutoSaveProject=1 10 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/19inch.lbr" 11 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/40xx.lbr" 12 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/41xx.lbr" 13 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/45xx.lbr" 14 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/74ac-logic.lbr" 15 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/74ttl-din.lbr" 16 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/74xx-eu.lbr" 17 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/74xx-little-de.lbr" 18 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/74xx-little-us.lbr" 19 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/74xx-us.lbr" 20 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/751xx.lbr" 21 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/IQD-Frequency-Products.lbr" 22 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/advanced-test-technologies.lbr" 23 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/agilent-technologies.lbr" 24 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/allegro.lbr" 25 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/altera-cyclone-II.lbr" 26 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/altera-cyclone-III.lbr" 27 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/altera-stratix-iv.lbr" 28 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/altera.lbr" 29 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/am29-memory.lbr" 30 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/amd-mach.lbr" 31 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/amd.lbr" 32 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/amis.lbr" 33 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/analog-devices.lbr" 34 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/aplus.lbr" 35 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/ase.lbr" 36 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/atmel.lbr" 37 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/austriamicrosystems.lbr" 38 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/avago.lbr" 39 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/axis.lbr" 40 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/battery.lbr" 41 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/belton-engineering.lbr" 42 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/burr-brown.lbr" 43 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/busbar.lbr" 44 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/buzzer.lbr" 45 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/c-trimm.lbr" 46 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/california-micro-devices.lbr" 47 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/capacitor-wima.lbr" 48 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/chipcard-siemens.lbr" 49 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/cirrus-logic.lbr" 50 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-3m.lbr" 51 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-4ucon.lbr" 52 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-amp-champ.lbr" 53 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-amp-micromatch.lbr" 54 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-amp-mt.lbr" 55 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-amp-mt6.lbr" 56 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-amp-quick.lbr" 57 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-amp-te.lbr" 58 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-amp.lbr" 59 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-amphenol.lbr" 60 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-avx.lbr" 61 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-berg.lbr" 62 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-bosch.lbr" 63 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-chipcard-iso7816.lbr" 64 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-coax.lbr" 65 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-commcon.lbr" 66 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-conrad.lbr" 67 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-cpci.lbr" 68 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-cui.lbr" 69 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-cypressindustries.lbr" 70 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-deutsch.lbr" 71 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-dil.lbr" 72 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-ebyelectro.lbr" 73 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-elco.lbr" 74 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-erni.lbr" 75 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-faston.lbr" 76 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-fci.lbr" 77 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-friwo.lbr" 78 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-garry.lbr" 79 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-harting-h.lbr" 80 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-harting-ml.lbr" 81 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-harting-v.lbr" 82 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-harting.lbr" 83 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-hirose.lbr" 84 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-hirschmann.lbr" 85 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-jack.lbr" 86 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-jae.lbr" 87 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-jst.lbr" 88 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-kycon.lbr" 89 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-kyocera-elco.lbr" 90 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-lemo.lbr" 91 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-leotronics.lbr" 92 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-lsta.lbr" 93 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-lstb.lbr" 94 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-lumberg.lbr" 95 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-ml.lbr" 96 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-molex.lbr" 97 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-neutrik_ag.lbr" 98 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-omron.lbr" 99 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-panasonic.lbr" 100 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-panduit.lbr" 101 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-pc.lbr" 102 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-pc104.lbr" 103 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-phoenix-254.lbr" 104 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-phoenix-3.81.lbr" 105 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-phoenix-350.lbr" 106 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-phoenix-500.lbr" 107 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-phoenix-508.lbr" 108 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-phoenix-762.lbr" 109 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-phoenix-me_max.lbr" 110 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-phoenix-mkds_5.lbr" 111 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-phoenix-smkdsp.lbr" 112 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-ptr500.lbr" 113 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-pulse.lbr" 114 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-rib.lbr" 115 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-samtec.lbr" 116 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-shallin.lbr" 117 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-shiua-chyuan.lbr" 118 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-stewart.lbr" 119 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-stocko.lbr" 120 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-subd.lbr" 121 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-sullinselectronics.lbr" 122 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-thomas-betts.lbr" 123 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-tyco.lbr" 124 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-tycoelectronics.lbr" 125 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-vg.lbr" 126 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-wago-500.lbr" 127 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-wago-508.lbr" 128 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-wago.lbr" 129 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-wago255.lbr" 130 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-weidmueller-sl35.lbr" 131 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-wenzhou-yihua.lbr" 132 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-xmultiple.lbr" 133 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/con-yamaichi.lbr" 134 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/crystal.lbr" 135 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/csr.lbr" 136 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/cypress.lbr" 137 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/davicom.lbr" 138 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/dc-dc-converter.lbr" 139 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/dimensions.lbr" 140 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/diode.lbr" 141 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/discrete.lbr" 142 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/display-hp.lbr" 143 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/display-kingbright.lbr" 144 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/display-lcd.lbr" 145 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/docu-dummy.lbr" 146 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/eagle-ltspice.lbr" 147 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/ecl.lbr" 148 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/em-microelectronic.lbr" 149 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/etx-board.lbr" 150 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/exar.lbr" 151 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/fairchild-semic.lbr" 152 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/farnell.lbr" 153 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/fiber-optic-hp.lbr" 154 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/fiber-optic-siemens.lbr" 155 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/fifo.lbr" 156 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/flexipanel.lbr" 157 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/fox-electronics.lbr" 158 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/frames.lbr" 159 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/freescale.lbr" 160 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/ftdichip.lbr" 161 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/fujitsu.lbr" 162 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/fuse.lbr" 163 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/gennum.lbr" 164 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/halo-electronics.lbr" 165 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/heatsink.lbr" 166 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/holes.lbr" 167 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/holtek.lbr" 168 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/ic-package.lbr" 169 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/inductor-coilcraft.lbr" 170 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/inductor-neosid.lbr" 171 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/inductor-nkl.lbr" 172 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/inductors.lbr" 173 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/infineon-tricore.lbr" 174 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/infineon.lbr" 175 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/intersil-techwell.lbr" 176 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/intersil.lbr" 177 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/ir.lbr" 178 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/isd.lbr" 179 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/johanson-technology.lbr" 180 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/jump-0r-smd.lbr" 181 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/jumper.lbr" 182 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/lantronix.lbr" 183 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/lattice.lbr" 184 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/lc-filter.lbr" 185 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/led-7-segment.lbr" 186 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/led-citizen-electronics.lbr" 187 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/led-lumiled.lbr" 188 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/led.lbr" 189 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/lem.lbr" 190 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/linear-technology.lbr" 191 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/linear.lbr" 192 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/linx.lbr" 193 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/logo.lbr" 194 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/lprs.lbr" 195 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/lsi-computer-systems.lbr" 196 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/lumiled.lbr" 197 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/marks.lbr" 198 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/maxim.lbr" 199 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/maxstream.lbr" 200 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/melexis.lbr" 201 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/memory-hitachi.lbr" 202 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/memory-idt.lbr" 203 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/memory-micron.lbr" 204 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/memory-motorola-dram.lbr" 205 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/memory-nec.lbr" 206 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/memory-samsung.lbr" 207 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/memory-sram.lbr" 208 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/memory.lbr" 209 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/mems.lbr" 210 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/micrel.lbr" 211 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/micro-cyrod.lbr" 212 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/micro-fujitsu.lbr" 213 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/micro-harris.lbr" 214 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/micro-hitachi.lbr" 215 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/micro-infineon.lbr" 216 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/micro-intel.lbr" 217 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/micro-mc68000.lbr" 218 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/micro-motorola.lbr" 219 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/micro-philips.lbr" 220 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/micro-renesas.lbr" 221 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/micro-samsung.lbr" 222 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/micro-siemens.lbr" 223 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/microchip.lbr" 224 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/micron.lbr" 225 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/micronas.lbr" 226 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/microphon.lbr" 227 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/microwave.lbr" 228 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/midori-sensor.lbr" 229 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/minicircuits.lbr" 230 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/mitsubishi-semiconductor.lbr" 231 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/motorola-sensor-driver.lbr" 232 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/murata-filter.lbr" 233 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/murata-sensor.lbr" 234 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/nanotec.lbr" 235 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/national-instruments.lbr" 236 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/national-semiconductor.lbr" 237 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/nec-lqfp100-pack.lbr" 238 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/nec.lbr" 239 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/nrj-semiconductor.lbr" 240 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/omnivision.lbr" 241 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/on-semiconductor.lbr" 242 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/opto-honeywell-3000.lbr" 243 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/opto-honeywell-4000.lbr" 244 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/opto-honeywell.lbr" 245 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/opto-micro-linear.lbr" 246 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/opto-trans-siemens.lbr" 247 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/opto-transmittter-hp.lbr" 248 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/opto-vishay.lbr" 249 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/optocoupler.lbr" 250 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/pal.lbr" 251 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/philips-semiconductors.lbr" 252 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/photo-elements.lbr" 253 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/piher.lbr" 254 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/pinhead.lbr" 255 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/plcc-socket.lbr" 256 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/pld-intel.lbr" 257 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/plxtech.lbr" 258 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/pot-vitrohm.lbr" 259 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/pot-xicor.lbr" 260 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/pot.lbr" 261 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/ptc-ntc.lbr" 262 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/quantum-research-group.lbr" 263 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/rcl.lbr" 264 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/recom-international.lbr" 265 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/rectifier.lbr" 266 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/ref-packages-longpad.lbr" 267 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/ref-packages.lbr" 268 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/relay.lbr" 269 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/renesas.lbr" 270 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/resistor-bourns.lbr" 271 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/resistor-dil.lbr" 272 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/resistor-net.lbr" 273 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/resistor-power.lbr" 274 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/resistor-ruf.lbr" 275 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/resistor-shunt.lbr" 276 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/resistor-sil.lbr" 277 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/resistor.lbr" 278 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/rf-micro-devices.lbr" 279 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/rf-solutions.lbr" 280 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/rohm.lbr" 281 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/roundsolutions.lbr" 282 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/semicon-smd-ipc.lbr" 283 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/sensor-comus-group.lbr" 284 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/sensor-heraeus.lbr" 285 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/sensor-infratec.lbr" 286 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/sharp.lbr" 287 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/silabs.lbr" 288 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/sim-technology.lbr" 289 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/sipex.lbr" 290 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/smd-ipc.lbr" 291 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/smd-special.lbr" 292 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/solomon-systech.lbr" 293 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/solpad.lbr" 294 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/speaker.lbr" 295 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/special-drill.lbr" 296 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/special.lbr" 297 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/st-microelectronics.lbr" 298 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/stm32xx.lbr" 299 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/supertex.lbr" 300 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/supply1.lbr" 301 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/supply2.lbr" 302 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/switch-alps.lbr" 303 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/switch-coto.lbr" 304 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/switch-dil.lbr" 305 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/switch-misc.lbr" 306 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/switch-omron.lbr" 307 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/switch-raychem.lbr" 308 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/switch-reed.lbr" 309 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/switch.lbr" 310 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/telcom.lbr" 311 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/telecontrolli.lbr" 312 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/telefunken.lbr" 313 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/testpad.lbr" 314 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/texas-sn55-sn75.lbr" 315 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/texas.lbr" 316 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/toshiba.lbr" 317 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/traco-electronic.lbr" 318 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/trafo-bei.lbr" 319 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/trafo-hammondmfg.lbr" 320 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/trafo-siemens.lbr" 321 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/trafo-xicon.lbr" 322 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/trafo.lbr" 323 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/transformer-pulse.lbr" 324 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/transistor-fet.lbr" 325 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/transistor-neu-to92.lbr" 326 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/transistor-npn.lbr" 327 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/transistor-pnp.lbr" 328 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/transistor-power.lbr" 329 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/transistor-small-signal.lbr" 330 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/transistor.lbr" 331 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/triac.lbr" 332 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/trimble.lbr" 333 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/tripas.lbr" 334 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/u-blox.lbr" 335 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/uln-udn.lbr" 336 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/v-reg-micrel.lbr" 337 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/v-reg.lbr" 338 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/varistor.lbr" 339 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/wafer-scale-psd.lbr" 340 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/wirepad.lbr" 341 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/xicor.lbr" 342 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/xilinx-virtex-v5.lbr" 343 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/xilinx-xc18v.lbr" 344 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/xilinx-xc9.lbr" 345 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/xilinx-xcv.lbr" 346 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/zetex.lbr" 347 | UsedLibrary="/usr/local/google/home/gbin/eagle-7.2.0/lbr/zilog.lbr" 348 | UsedLibrary="gbin.lbr" 349 | UsedLibrary="rpi-header.lbr" 350 | 351 | [Win_1] 352 | Type="Control Panel" 353 | Loc="2084 119 3917 1054" 354 | State=2 355 | Number=0 356 | 357 | [Desktop] 358 | Screen="4480 1600" 359 | Window="Win_1" 360 | -------------------------------------------------------------------------------- /protocol/donglepi.proto: -------------------------------------------------------------------------------- 1 | import "nanopb.proto"; 2 | 3 | message Config { 4 | message GPIO { 5 | message Pin { 6 | enum Direction { 7 | IN = 0; 8 | OUT = 1; 9 | } 10 | enum Pull { 11 | OFF = 0; 12 | UP = 1; 13 | DOWN = 2; 14 | } 15 | enum Edge { 16 | BOTH = 0; 17 | RISING = 1; 18 | FALLING = 2; 19 | } 20 | required uint32 number = 1; 21 | required bool active = 2 [default = true]; 22 | optional Direction direction = 3; 23 | optional Pull pull = 4 [default = OFF]; 24 | optional Edge trigger = 5; 25 | } 26 | repeated Pin pins = 1; 27 | } 28 | message I2C { 29 | enum Speed { 30 | BAUD_RATE_100KHZ = 100; 31 | BAUD_RATE_400KHZ = 400; 32 | } 33 | required bool enabled = 1; 34 | optional Speed speed = 2 [default = BAUD_RATE_100KHZ]; 35 | } 36 | 37 | message SPI { 38 | required bool enabled = 1; 39 | optional uint32 baudrate = 2 [default = 100000]; 40 | optional bool CPOL = 3 [default = false]; // Clock polarity leading: 0=rising, 1=falling trailing: 0=falling 1=rising 41 | optional bool CPHA = 4 [default = false]; // Clock phase leading: 0=Sample 1=setup trailing: 0=setup 1=sample 42 | optional bool CS_LEVEL = 5 [default = false]; // false : low to select 43 | } 44 | 45 | message UART { 46 | enum Speed { 47 | BAUD_RATE_115200 = 115200; 48 | } 49 | enum Chr { 50 | B5 = 5; 51 | B6 = 6; 52 | B7 = 7; 53 | B8 = 8; 54 | B9 = 9; 55 | } 56 | enum Parity { 57 | NONE = 0; 58 | ODD = 1; 59 | EVEN = 2; 60 | } 61 | enum StopBits { 62 | S1 = 1; 63 | S2 = 2; 64 | } 65 | required bool enabled = 1; 66 | required Speed speed = 2 [default = BAUD_RATE_115200]; 67 | required Chr chr = 3 [default = B8]; 68 | required Parity parity = 4 [default = NONE]; 69 | required StopBits stop_bits = 5 [default = S1]; 70 | } 71 | optional GPIO gpio = 1; // pins are already callbacks 72 | optional I2C i2c = 2 [(nanopb).type = FT_CALLBACK]; 73 | optional UART uart = 3 [(nanopb).type = FT_CALLBACK]; 74 | optional SPI spi = 4 [(nanopb).type = FT_CALLBACK]; 75 | } 76 | 77 | 78 | message Data { 79 | message GPIO { 80 | required uint32 mask = 1; 81 | required uint32 values = 2; 82 | } 83 | message I2C { 84 | message Read { 85 | required uint32 addr = 1; 86 | required uint32 size = 2; 87 | } 88 | message Write { 89 | required uint32 addr = 1; 90 | required bytes buffer = 2; 91 | } 92 | repeated Read reads = 1; 93 | repeated Write writes = 2; 94 | } 95 | message SPI { 96 | message Read { 97 | required uint32 device_number = 1; // 0 or 1 for now 98 | required uint32 size; 99 | } 100 | message Write { 101 | required uint32 device_number = 1; // 0 or 1 for now 102 | required bytes buffer = 2; 103 | } 104 | repeated Read reads = 1; 105 | repeated Write writes = 2; // TODO: repeat Data instead so the dev can interleave requests 106 | } 107 | optional GPIO gpio = 1; 108 | optional GPIO triggers = 2; 109 | optional I2C i2c = 3; 110 | optional SPI spi = 4; 111 | optional bytes uart = 5; 112 | } 113 | 114 | message Transport { 115 | required uint64 message_length = 1; 116 | } 117 | 118 | message DonglePiRequest { 119 | required uint32 message_nb = 1; 120 | optional Config config = 2; // optimization constraint: be sure config is decoded *before* the data that can relies it on. 121 | optional Data data = 3; 122 | } 123 | 124 | message DonglePiResponse { 125 | message Error { 126 | enum Type { 127 | CONFIG = 0; 128 | GPIO = 1; 129 | UART = 2; 130 | I2C = 3; 131 | SPI = 4; 132 | OTHER = 15; 133 | } 134 | required Type type = 1; 135 | optional string debug_info = 16; 136 | } 137 | required uint32 message_nb = 1; 138 | optional Data data = 2; 139 | optional Error error = 16; 140 | } 141 | -------------------------------------------------------------------------------- /python/DPi/GPIO.py: -------------------------------------------------------------------------------- 1 | import threading 2 | import DPi 3 | 4 | # Modes 5 | BCM = 11 6 | BOARD = 10 7 | 8 | # Edges 9 | RISING = 31 10 | FALLING = 32 11 | BOTH = 33 12 | 13 | # Values 14 | LOW = 0 15 | HIGH = 1 16 | 17 | # Pull 18 | PUD_OFF = 20 19 | PUD_DOWN = 21 20 | PUD_UP = 22 21 | 22 | # functions 23 | OUT = 0 # also directiom 24 | IN = 1 # also diraction 25 | HARD_PWM = 43 26 | I2C = 42 27 | SERIAL = 40 28 | SPI = 41 29 | UNKNOWN = -1 30 | 31 | # versioning 32 | RPI_REVISION = 2 33 | VERSION = '0.5.6' 34 | 35 | # This is only for the last version of the numbering (it changed tons of times) 36 | # gbin: can be optimized with a list. 37 | BCM2PI = { 38 | 2: 3, # GPIO02 = pin 3 39 | 3: 5, 40 | 4: 7, 41 | 14: 8, 42 | 15:10, 43 | 17:11, 44 | 18:12, 45 | 27:13, 46 | 22:15, 47 | 23:16, 48 | 24:18, 49 | 10:19, 50 | 9:21, 51 | 25:22, 52 | 11:23, 53 | 8:24, 54 | 7:26 55 | } 56 | 57 | current_mode = None # Runtime error if it is not set. 58 | functions = [ 59 | None, # 0 60 | None, # 1 61 | None, # 2 62 | HARD_PWM,# 3 (I2C) 63 | None, # 4 64 | HARD_PWM,# 5 (I2C) 65 | None, # 6 66 | IN, # 7 67 | SERIAL, # 8 68 | None, # 9 69 | SERIAL, # 10 70 | IN, # 11 71 | IN, # 12 72 | IN, # 13 73 | None, # 14 74 | IN, # 15 75 | IN, # 16 76 | None, # 17 77 | IN, # 18 78 | SPI, # 19 79 | None, # 20 80 | SPI, # 21 81 | IN, # 22 82 | SPI, # 23 83 | SPI, # 24 84 | None, # 25 85 | SPI, # 26 86 | ] 87 | 88 | def add_event_callback(channel, callback): 89 | raise NotImplementedError() 90 | 91 | # bouncetime in ms 92 | def add_event_detect(channel, edge, callback=None, bouncetime=None): 93 | raise NotImplementedError() 94 | 95 | class PWM(object): 96 | 97 | def __init__(self, channel, frequency): 98 | raise NotImplementedError() 99 | 100 | def ChangeDutyCycle(self, dutycycle): 101 | raise NotImplementedError() 102 | 103 | def ChangeFrequency(self, frequency): 104 | raise NotImplementedError() 105 | 106 | def start(self, dutycycle): 107 | raise NotImplementedError() 108 | 109 | def stop(self): 110 | raise NotImplementedError() 111 | 112 | # default, all channels 113 | def cleanup(channel=None): 114 | raise NotImplementedError() 115 | 116 | def event_detected(channel): 117 | # return true if an edge has been detected 118 | return False 119 | 120 | # Return the current GPIO function (IN, OUT, PWM, SERIAL, I2C, SPI) 121 | # channel - either board pin number or BCM number depending on which mode is set. 122 | def gpio_function(channel): 123 | return functions[channel] 124 | 125 | # Input from a GPIO channel. Returns HIGH=1=True or LOW=0=False 126 | # channel - either board pin number or BCM number depending on which mode is set. 127 | def input(channel): 128 | with DPi.response_lock: 129 | if not(DPi.last_response.data.gpio.mask & (1 << channel)): 130 | print("Weird the channel " + str(channel) + " is not streaming") 131 | return bool(DPi.last_response.data.gpio.values & (1 << channel)) 132 | 133 | 134 | def output(channel, value): 135 | with DPi.request_lock: 136 | DPi.pending_request.data.gpio.mask |= 1 << channel 137 | if value: 138 | DPi.pending_request.data.gpio.values |= value << channel 139 | else: 140 | DPi.pending_request.data.gpio.values &= ~(value << channel) 141 | 142 | 143 | def remove_event_detect(channel): 144 | raise NotImplementedError() 145 | 146 | # BOARD - Use Raspberry Pi board numbers 147 | # BCM - Use Broadcom GPIO 00..nn numbers 148 | def setmode(mode): 149 | if mode not in (BOARD, BCM): 150 | raise ValueError() 151 | global current_mode 152 | current_mode = mode 153 | if not comm_thread.is_alive(): 154 | DPi.pending_request = DPi.donglepi_pb2.DonglePiRequest() 155 | comm_thread.start() 156 | 157 | # setup(...) 158 | # Set up the GPIO channel, direction and (optional) pull/up down control 159 | # channel - either board pin number or BCM number depending on which mode is set. 160 | # direction - IN or OUT 161 | # [pull_up_down] - PUD_OFF (default), PUD_UP or PUD_DOWN 162 | # [initial] - Initial value for an output channel (gbin: LOW / HIGH for 163 | # OUTPUT only) 164 | def setup(channel, direction, pull_up_down = PUD_OFF, initial=None): 165 | with DPi.request_lock: 166 | new_pin = DPi.pending_request.config.gpio.pins.add() 167 | new_pin.active = True 168 | new_pin.number = channel 169 | if direction == IN: 170 | new_pin.direction = DPi.donglepi_pb2.Config.GPIO.Pin.IN 171 | if pull_up_down == PUD_OFF: 172 | new_pin.pull = DPi.donglepi_pb2.Config.GPIO.Pin.OFF 173 | elif pull_up_down == PUD_UP: 174 | new_pin.pull = DPi.donglepi_pb2.Config.GPIO.Pin.UP 175 | elif pull_up_down == PUD_DOWN: 176 | new_pin.pull = DPi.donglepi_pb2.Config.GPIO.Pin.DOWN 177 | else: 178 | raise ValueError("Unknown pullup value") 179 | else: 180 | new_pin.direction = DPi.donglepi_pb2.Config.GPIO.Pin.OUT 181 | 182 | def setwarnings(on): 183 | raise NotImplementedError() 184 | 185 | # Wait for an edge. 186 | # channel - either board pin number or BCM number depending on which mode is set. 187 | # edge - RISING, FALLING or BOTH 188 | def wait_for_edge(channel, edge): 189 | raise NotImplementedError() 190 | 191 | def dp_callback(donglepi_response): 192 | # gbin: forward to the callbacks 193 | pass 194 | 195 | comm_thread = threading.Thread(target=DPi.main_loop, 196 | name="DonglePi comm thread", 197 | args=(dp_callback,)) 198 | comm_thread.daemon = True 199 | 200 | -------------------------------------------------------------------------------- /python/DPi/__init__.py: -------------------------------------------------------------------------------- 1 | import donglepi_pb2 2 | import threading 3 | import serial 4 | import logging 5 | from google.protobuf.message import DecodeError 6 | from google.protobuf.internal.decoder import _DecodeVarint32 as DecodeVarint32 7 | from serial.tools import list_ports 8 | 9 | logging.basicConfig(level=logging.DEBUG) 10 | 11 | def hexdump(s): 12 | return " ".join("{:02x}".format(ord(c)) for c in s) 13 | 14 | def delimitedMessage(message): 15 | serializedMessage = message.SerializeToString() 16 | delimiter = donglepi_pb2.Transport() 17 | delimiter.message_length = len(serializedMessage) 18 | return delimiter.SerializeToString() + serializedMessage 19 | 20 | pending_request = donglepi_pb2.DonglePiRequest() 21 | request_lock = threading.Lock() 22 | 23 | last_response = donglepi_pb2.DonglePiResponse() 24 | response_lock = threading.Lock() 25 | 26 | 27 | def find_donglepi(): 28 | try: 29 | # TODO(gbin): fix me it broke, dunno why 30 | return '/dev/ttyACM0' 31 | # return next(list_ports.grep("DonglePI"))[0] 32 | except StopIteration: 33 | return None 34 | 35 | def main_loop(cb): 36 | global pending_request 37 | global last_response 38 | port_name = find_donglepi() 39 | if not port_name: 40 | logging.error("Could not find a plugged DonglePi.") 41 | return 42 | port = serial.Serial(port=port_name, baudrate=115200, timeout=0.5) #0.0002) 43 | logging.debug("DonglePi found on [%s]" % port_name) 44 | rcv_buffer = "" 45 | pending_request.message_nb = 314 46 | while True: 47 | with request_lock: 48 | request_number = pending_request.message_nb 49 | msg = delimitedMessage(pending_request) 50 | pending_request = donglepi_pb2.DonglePiRequest() 51 | pending_request.message_nb = (request_number + 1) % 65536 52 | 53 | logging.debug("Write message #%d" % request_number) 54 | port.write(msg) 55 | print(hexdump(msg)) 56 | logging.debug("Write message #%d OK" % request_number) 57 | 58 | 59 | delimiter = donglepi_pb2.Transport() 60 | while True: 61 | rcv_buffer += port.read(1024) 62 | print(hexdump(rcv_buffer)) 63 | try: 64 | (msg_length, offset) = DecodeVarint32(rcv_buffer, 0) 65 | logging.debug("expected message len = %s" % msg_length) 66 | except DecodeError: 67 | logging.debug("not enough for the init len") 68 | continue 69 | if len(rcv_buffer) - offset == msg_length: 70 | break 71 | 72 | response = donglepi_pb2.DonglePiResponse() 73 | response.ParseFromString( 74 | rcv_buffer[offset:offset + msg_length]) 75 | logging.debug("Response parsed #%d" % response.message_nb) 76 | rcv_buffer = rcv_buffer[msg_length + offset:] 77 | if response.message_nb != request_number: 78 | logging.warn("Donglepi desynchronized req nb = %d but resp nb = %d" % 79 | (response.message_nb, pending_request.message_nb)) 80 | 81 | # assert response.message_nb == request_number 82 | with response_lock: 83 | last_response = response 84 | cb(response) 85 | 86 | 87 | #req = donglepi_pb2.DonglePiRequest() 88 | #req.message_nb = 1 89 | #req.data.gpio.mask = 0xDEADBEEF 90 | #req.data.gpio.values = 0x13333331 91 | #print(hexdump(delimitedMessage(req))) 92 | 93 | #req2 = donglepi_pb2.DonglePiRequest() 94 | #req2.message_nb = 9 95 | #print(hexdump(delimitedMessage(req2))) 96 | 97 | 98 | -------------------------------------------------------------------------------- /python/DPi/smbus.py: -------------------------------------------------------------------------------- 1 | import DPi 2 | from struct import pack 3 | from array import array 4 | 5 | class SMBus(object): 6 | def __init__(self, bus = 0): # ignored for API compatibility. 7 | with DPi.request_lock: 8 | DPi.pending_request.config.i2c.enabled = True 9 | 10 | def _write(self, addr, buffer): 11 | with DPi.request_lock: 12 | write = DPi.pending_request.data.i2c.writes.add() 13 | write.addr = addr 14 | write.buffer = buffer 15 | 16 | # Quick transaction. int addr long 17 | def write_quick(self, addr): 18 | self._write(addr, "") 19 | return None 20 | 21 | # Read Byte transaction. int addr long 22 | def read_byte(self, addr): 23 | pass # return the read byte 24 | 25 | # Write Byte transaction. int addr,char val long 26 | def write_byte(self, addr, val): 27 | self._write(addr, pack('B', val)) 28 | return None # or PyErr_SetFromErrno(PyExc_IOError); 29 | 30 | # Read Byte Data transaction. int addr,char cmd long 31 | def read_byte_data(self, addr, cmd): 32 | pass 33 | 34 | # Write Byte Data transaction. int addr,char cmd,char val long 35 | def write_byte_data(self, addr, cmd, val): 36 | print("write " + str(val)) 37 | self._write(addr, pack('BB', cmd, val)) 38 | return None 39 | 40 | # Read Word Data transaction. int addr,char cmd long 41 | def read_word_data(self, addr, cmd): 42 | pass 43 | 44 | # Write Word Data transaction. int addr,char cmd,int val long 45 | def write_word_data(self, addr, cmd, val): 46 | self._write(addr, pack('BH', cmd, val)) 47 | 48 | # Process Call transaction. int addr,char cmd,int val long 49 | def process_call(self, addr, cmd, val): 50 | pass 51 | 52 | # Read Block Data transaction. int addr,char cmd long[] 53 | def read_block_data(self, addr, cmd): 54 | pass 55 | 56 | # Write Block Data transaction. int addr,char cmd,long[] None 57 | def write_block_data(self, addr, cmd, vals): 58 | a = array('B') 59 | a.append(cmd) 60 | a.append(len(vals)) # apparently it prepends the size of the array 61 | a.fromlist(vals) 62 | self._write(addr, a.tostring()) 63 | 64 | # Block Process Call transaction. int addr,char cmd,long[] long[] 65 | def block_process_call(self, addr, cmd, vals): 66 | pass 67 | 68 | # Block Read transaction. int addr,char cmd long[] 69 | def read_i2c_block_data(self, addr, cmd): 70 | pass 71 | 72 | # Block Write transaction. int addr,char cmd,long[] None 73 | def write_i2c_block_data(self, addr, cmd, vals): 74 | a = array('B') 75 | a.append(cmd) 76 | a.fromlist(vals) 77 | self._write(addr, a.tostring()) 78 | -------------------------------------------------------------------------------- /python/Makefile: -------------------------------------------------------------------------------- 1 | # Build rule for the protocol 2 | donglepi.pb2.py: ../protocol/donglepi.proto 3 | protoc --python_out=DPi -I../protocol -I../firmware/nanopb/generator/proto ../protocol/donglepi.proto 4 | cp ../firmware/nanopb/generator/proto/nanopb_pb2.py DPi/ 5 | 6 | clean: 7 | rm -f DPi/donglepi_pb2.py 8 | rm -f DPi/nanopb_pb2.py 9 | rm -f DPi/*.pyc 10 | -------------------------------------------------------------------------------- /python/requirements.txt: -------------------------------------------------------------------------------- 1 | pyserial 2 | protobuf 3 | -------------------------------------------------------------------------------- /python/test.py: -------------------------------------------------------------------------------- 1 | from DPi import GPIO 2 | from DPi import smbus 3 | import time 4 | import DPi 5 | 6 | def rotl(num, bits): 7 | bit = num & (1 << (bits-1)) 8 | num <<= 1 9 | if(bit): 10 | num |= 1 11 | num &= (2**bits-1) 12 | return num 13 | 14 | LED_DEV = 0x70 15 | print("setup...") 16 | GPIO.setmode(GPIO.BOARD) 17 | DPi.pending_request.config.spi.enabled = True 18 | time.sleep(90000) # <---- 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | i2c = smbus.SMBus(0) 28 | i2c.write_byte(LED_DEV, 0x21) # oscillator on 29 | i2c.write_byte(LED_DEV, 0x81) # switch on with no blink 30 | i2c.write_byte(LED_DEV, 0xEF) # brightness 31 | print("write on display done.") 32 | #GPIO.setup(25, GPIO.OUT) 33 | #GPIO.setup(22, GPIO.IN, GPIO.PUD_UP) 34 | pattern = [0] * 16 35 | for i in range(8): 36 | pattern[i*2] = 1 << i 37 | pattern[i*2+1] = 1 << (7-i) 38 | 39 | pattern[6] = 24 40 | pattern[7] = 24 41 | pattern[8] = 24 42 | pattern[9] = 24 43 | 44 | blink = 1 45 | while True: 46 | #GPIO.output(25, blink) 47 | print("INPUT = " + str(GPIO.input(22))) 48 | blink = 0 if blink == 1 else 1 49 | for i, value in enumerate(pattern): 50 | i2c.write_byte_data(LED_DEV, i, value) 51 | pattern = [rotl(val,8) for val in pattern] 52 | time.sleep(.9) 53 | --------------------------------------------------------------------------------