├── .gitignore ├── CONTRIBUTING.txt ├── ICLA.txt ├── LICENSE-3rdParty.txt ├── LICENSE-Apache2.txt ├── LICENSE-GPL3.txt ├── LICENSE-LGPL3.txt ├── README.txt ├── apps ├── bootloader │ ├── README.txt │ ├── common │ │ └── bootloader_protocol.h │ ├── firmware │ │ ├── .gitignore │ │ ├── MPLAB.X │ │ │ ├── Makefile │ │ │ └── nbproject │ │ │ │ ├── configurations.xml │ │ │ │ └── project.xml │ │ ├── gld │ │ │ ├── p32MX460F512L.ld │ │ │ ├── pic24fj256da206-bootloader.gld │ │ │ ├── pic24fj32gb002-bootloader.gld │ │ │ └── pic24fj64gb002-bootloader.gld │ │ ├── main.c │ │ ├── main_pic32mx.c │ │ ├── usb_config.h │ │ └── usb_descriptors.c │ └── software │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── bootloader.c │ │ ├── bootloader.h │ │ ├── c99.h │ │ ├── hex.c │ │ ├── hex.h │ │ ├── log.h │ │ ├── main.c │ │ └── msvc │ │ ├── bootloader.sln │ │ ├── bootloader.vcproj │ │ └── libusb.vsprops ├── cdc_acm │ ├── .gitignore │ ├── MPLAB.X │ │ ├── Makefile │ │ └── nbproject │ │ │ ├── configurations.xml │ │ │ └── project.xml │ ├── inf │ │ └── cdc-acm.inf │ ├── main.c │ ├── usb_config.h │ └── usb_descriptors.c ├── common │ ├── hardware.c │ └── hardware.h ├── hid_composite │ ├── .gitignore │ ├── MPLAB.X │ │ ├── Makefile │ │ └── nbproject │ │ │ ├── configurations.xml │ │ │ └── project.xml │ ├── main.c │ ├── usb_config.h │ └── usb_descriptors.c ├── hid_mouse │ ├── .gitignore │ ├── MPLAB.X │ │ ├── Makefile │ │ └── nbproject │ │ │ ├── configurations.xml │ │ │ └── project.xml │ ├── main.c │ ├── usb_config.h │ └── usb_descriptors.c ├── msc_test │ ├── .gitignore │ ├── MPLAB.X │ │ ├── Makefile │ │ └── nbproject │ │ │ ├── configurations.xml │ │ │ └── project.xml │ ├── board.c │ ├── board.h │ ├── main.c │ ├── mmc_config.h │ ├── spi.c │ ├── spi.h │ ├── timer.c │ ├── timer.h │ ├── usb_config.h │ └── usb_descriptors.c └── unit_test │ ├── .gitignore │ ├── MPLAB.X │ ├── Makefile │ └── nbproject │ │ ├── configurations.xml │ │ └── project.xml │ ├── main.c │ ├── usb_config.h │ └── usb_descriptors.c ├── docs ├── msc.txt └── winusb.txt ├── doxygen ├── Doxyfile └── main_page.c ├── host_test ├── .gitignore ├── Makefile ├── control_transfer_in.c ├── control_transfer_out.c ├── feature.c ├── feature_test.c └── test.c ├── storage ├── include │ ├── crc.h │ └── mmc.h └── src │ ├── crc.c │ └── mmc.c └── usb ├── include ├── usb.h ├── usb_cdc.h ├── usb_ch9.h ├── usb_hid.h ├── usb_microsoft.h └── usb_msc.h └── src ├── usb.c ├── usb_cdc.c ├── usb_hal.h ├── usb_hid.c ├── usb_msc.c ├── usb_priv.h ├── usb_winusb.c └── usb_winusb.h /.gitignore: -------------------------------------------------------------------------------- 1 | html/ 2 | latex/ 3 | *~ 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.txt: -------------------------------------------------------------------------------- 1 | Contributions to M-Stack will require a signed copy of the Individual 2 | Contributor License Agreement (ICLA) which is present in this directory. 3 | This contributor agreement is borrowed from the Apache Software Foundation, 4 | and modified to suit this project. 5 | 6 | When you contribute the first time, a maintainer will send you the ICLA. 7 | Replying with the information requested and the text "I Agree" is 8 | sufficient. The information requested can be in one block at the top of the 9 | email; the form doesn't have to be filled out in the traditional sense. 10 | 11 | Each patch sent to this project requires a sign-off in the commit message, 12 | certifying that the person who submitted it either wrote it or has 13 | authorization to pass it on as Open Source software. A sign-off line looks 14 | like the following: 15 | 16 | Signed-off-by: Alan Ott 17 | 18 | Place the sign-off as the last line of your commit message. The sign-off 19 | indicates that you agree to the Developer's Certificate of Origin, which was 20 | created for the Linux kernel. Its text follows: 21 | 22 | Developer's Certificate of Origin 1.1 23 | 24 | By making a contribution to this project, I certify that: 25 | 26 | (a) The contribution was created in whole or in part by me and I 27 | have the right to submit it under the open source license 28 | indicated in the file; or 29 | 30 | (b) The contribution is based upon previous work that, to the best 31 | of my knowledge, is covered under an appropriate open source 32 | license and I have the right under that license to submit that 33 | work with modifications, whether created in whole or in part 34 | by me, under the same open source license (unless I am 35 | permitted to submit under a different license), as indicated 36 | in the file; or 37 | 38 | (c) The contribution was provided directly to me by some other 39 | person who certified (a), (b) or (c) and I have not modified 40 | it. 41 | 42 | (d) I understand and agree that this project and the contribution 43 | are public and that a record of the contribution (including all 44 | personal information I submit with it, including my sign-off) is 45 | maintained indefinitely and may be redistributed consistent with 46 | this project or the open source license(s) involved. 47 | 48 | 49 | Thank you for your contributions to M-Stack! 50 | 51 | Alan. 52 | -------------------------------------------------------------------------------- /ICLA.txt: -------------------------------------------------------------------------------- 1 | Signal 11 Software 2 | Individual Contributor License Agreement ("Agreement") V1.0 3 | http://www.signal11.us 4 | 5 | In order to clarify the intellectual property license granted with 6 | Contributions from any person or entity, Signal 11 Software (herein Signal 7 | 11) must have a Contributor License Agreement ("CLA") on file that has been 8 | signed by each Contributor, indicating agreement to the license terms below. 9 | This license is for your protection as a Contributor as well as the 10 | protection of Signal 11 Software and its users; it does not change your 11 | rights to use your own Contributions for any other purpose. Please read 12 | this document carefully before signing and keep a copy for your records. 13 | 14 | Full name: ______________________________________________________ 15 | 16 | (optional) Public name: _________________________________________ 17 | 18 | Mailing Address: ________________________________________________ 19 | 20 | ________________________________________________ 21 | 22 | Country: ______________________________________________________ 23 | 24 | (Optional) Telephone: ___________________________________________ 25 | 26 | E-Mail: ______________________________________________________ 27 | 28 | You accept and agree to the following terms and conditions for Your present 29 | and future Contributions submitted to the Signal 11 Software. Except for 30 | the license granted herein to Signal 11 and recipients of software 31 | distributed by Signal 11, You reserve all right, title, and interest in and 32 | to Your Contributions. 33 | 34 | 1. Definitions. 35 | 36 | "You" (or "Your") shall mean the copyright owner or legal entity 37 | authorized by the copyright owner that is making this Agreement with 38 | Signal 11. For legal entities, the entity making a Contribution and all 39 | other entities that control, are controlled by, or are under common 40 | control with that entity are considered to be a single Contributor. For 41 | the purposes of this definition, "control" means (i) the power, direct or 42 | indirect, to cause the direction or management of such entity, whether by 43 | contract or otherwise, or (ii) ownership of fifty percent (50%) or more 44 | of the outstanding shares, or (iii) beneficial ownership of such entity. 45 | 46 | "Contribution" shall mean any original work of authorship, including any 47 | modifications or additions to an existing work, that is intentionally 48 | submitted by You to Signal 11 for inclusion in, or documentation of, any 49 | of the products owned or managed by Signal 11 (the "Work"). For the 50 | purposes of this definition, "submitted" means any form of electronic, 51 | verbal, or written communication sent to Signal 11 or its 52 | representatives, including but not limited to communication on electronic 53 | mailing lists, source code control systems, and issue tracking systems 54 | that are managed by, or on behalf of, Signal 11 for the purpose of 55 | discussing and improving the Work, but excluding communication that is 56 | conspicuously marked or otherwise designated in writing by You as "Not a 57 | Contribution." 58 | 59 | 2. Grant of Copyright License. Subject to the terms and conditions of 60 | this Agreement, You hereby grant to Signal 11 and to recipients of 61 | software distributed by Signal 11 a perpetual, worldwide, non-exclusive, 62 | no-charge, royalty-free, irrevocable copyright license to reproduce, 63 | prepare derivative works of, publicly display, publicly perform, 64 | sublicense, and distribute Your Contributions and such derivative works. 65 | 66 | 3. Grant of Patent License. Subject to the terms and conditions of 67 | this Agreement, You hereby grant to Signal 11 and to recipients of 68 | software distributed by Signal 11 a perpetual, worldwide, non-exclusive, 69 | no-charge, royalty-free, irrevocable (except as stated in this section) 70 | patent license to make, have made, use, offer to sell, sell, import, and 71 | otherwise transfer the Work, where such license applies only to those 72 | patent claims licensable by You that are necessarily infringed by Your 73 | Contribution(s) alone or by combination of Your Contribution(s) with the 74 | Work to which such Contribution(s) was submitted. If any entity 75 | institutes patent litigation against You or any other entity (including a 76 | cross-claim or counterclaim in a lawsuit) alleging that your 77 | Contribution, or the Work to which you have contributed, constitutes 78 | direct or contributory patent infringement, then any patent licenses 79 | granted to that entity under this Agreement for that Contribution or Work 80 | shall terminate as of the date such litigation is filed. 81 | 82 | 4. You represent that you are legally entitled to grant the above 83 | license. If your employer(s) has rights to intellectual property that you 84 | create that includes your Contributions, you represent that you have 85 | received permission to make Contributions on behalf of that employer, 86 | that your employer has waived such rights for your Contributions to 87 | Signal 11, or that your employer has executed a separate Corporate CLA 88 | with Signal 11. 89 | 90 | 5. You represent that each of Your Contributions is Your original 91 | creation (see section 7 for submissions on behalf of others). You 92 | represent that Your Contribution submissions include complete 93 | details of any third-party license or other restriction (including, 94 | but not limited to, related patents and trademarks) of which you 95 | are personally aware and which are associated with any part of Your 96 | Contributions. 97 | 98 | 6. You are not expected to provide support for Your Contributions, 99 | except to the extent You desire to provide support. You may provide 100 | support for free, for a fee, or not at all. Unless required by 101 | applicable law or agreed to in writing, You provide Your 102 | Contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 103 | OF ANY KIND, either express or implied, including, without 104 | limitation, any warranties or conditions of TITLE, NON- 105 | INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. 106 | 107 | 7. Should You wish to submit work that is not Your original creation, 108 | You may submit it to Signal 11 separately from any Contribution, 109 | identifying the complete details of its source and of any license or 110 | other restriction (including, but not limited to, related patents, 111 | trademarks, and license agreements) of which you are personally aware, 112 | and conspicuously marking the work as "Submitted on behalf of a 113 | third-party: [named here]". 114 | 115 | 8. You agree to notify Signal 11 of any facts or circumstances of which 116 | you become aware that would make these representations inaccurate in any 117 | respect. 118 | 119 | Please sign: __________________________________ Date: ________________ 120 | 121 | Text derived from the Apache Individual Contributor License Agreement 122 | ("Agreement") V2.0, available at http://apache.org/licenses/icla.txt 123 | -------------------------------------------------------------------------------- /LICENSE-3rdParty.txt: -------------------------------------------------------------------------------- 1 | 3rd Party Licenses 2 | =================== 3 | 4 | The following files in M-Stack are of 3rd Party origin and are used under 5 | their respective licenes. Depending on your configuration, these files may 6 | or may not be in use by your application. Determining whether they are in 7 | use should be fairly straight-forward. 8 | 9 | PIC32MX Linker Scripts 10 | ----------------------- 11 | Files: apps/bootloader/firmware/gld/p32MX* 12 | License: Microchip BSD License 13 | Notes: See the copyright/license header of each file. 14 | -------------------------------------------------------------------------------- /LICENSE-LGPL3.txt: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /apps/bootloader/README.txt: -------------------------------------------------------------------------------- 1 | 2 | PIC24F/32MX Bootloader 3 | ======================= 4 | 5 | This is the PIC24F/32MX USB bootloader. It contains firmware and software 6 | to implement a USB bootloader using M-Stack. It differs from the Microchip 7 | bootloaders in several key ways in both licensing and implementation. 8 | 9 | License 10 | -------- 11 | Like the rest of M-Stack, this bootloader is free software, and its firmware 12 | and software are usable under the terms of either the LGPL version 3, or the 13 | Apache License, version 2.0. 14 | 15 | The Linker scripts for the PIC24 come from the PIC Linker Script Generator 16 | (linked below) and have a permissive license. See the file header for the 17 | included linker scripts. 18 | 19 | The PIC32 linker scripts are derived from the Linker scripts which are 20 | distributed with the XC32 toolchain, version 1.40. These linker scripts are 21 | copyrighted by Microchip and are used under a BSD-style license. See the 22 | file header on these scripts for details. This is separate from the license 23 | of M-Stack. 24 | 25 | Firmware Implementation 26 | ------------------------ 27 | This bootloader's implementation does not use HID, as the Microchip 28 | bootloader does, and instead uses custom-class control transfers. This 29 | difference makes this bootloader faster, and gives it a more robust 30 | interface, since control transfers can be rejected by the firmware if they 31 | are not correct. 32 | 33 | Another difference from the Microchip bootloader is that for PIC24F it uses 34 | linker scripts from the Signal 11 PIC Linker Script Generator at 35 | https://github.com/signal11/pic_linker_script . The generated scripts for 36 | PIC24F and the hand-modified scripts for PIC32MX make use of both the C 37 | preprocessor and more advanced linker script features to create linker 38 | scripts which can be used in the same form for both the bootloader and the 39 | application to be loaded by the bootloader. This way only a single linker 40 | script is needed for both projects (bootloader and application) which is 41 | less prone to the inherent errors of manual edits. A single #define in the 42 | MPLABX project is used to select whether the linker script is being used for 43 | the bootloader or for the application (define either BOOTLOADER or 44 | BOOTLOADER_APP to select the mode). See the PIC Linker Script Generator 45 | README for more details. 46 | 47 | Also different in the implementation is that the linker script passes flash 48 | addresses to the bootloader firmware. This means that for MCUs with the 49 | same flash layout (such as the entire PIC24F family and the entire PIC32MX 50 | family), the bootloader firmware and software source code does not have to 51 | change between different MCUs. Only the linker script does, with data that 52 | comes directly from the datasheets. This means there are no #defines in the 53 | source code with memory addresses and ranges for each MCU. 54 | 55 | Software Implementation 56 | ------------------------ 57 | The software implementation is straight-forward. A hex file reader parses 58 | the program data in Intel Hex file format, and libusb is used to send the 59 | program data to the bootloader firmware. 60 | 61 | Supported Platforms 62 | -------------------- 63 | Currently tested platforms are: 64 | PIC24FJ64GB002 65 | PIC32MX460F512L (PIC32 USB Starter Board) 66 | 67 | In theory, any PIC24F or PIC32MX MCU should work as long as a suitable 68 | linker script is made. 69 | 70 | Contributing 71 | ------------- 72 | More platforms need to be added. If you want to use this bootloader on a 73 | different PIC24F MCU, please add the platform to the Linker Script 74 | Generator. See the Linker Script Generator README for more information. 75 | 76 | Future Plans 77 | ------------- 78 | Future goals include the following: 79 | * More PIC24F platforms 80 | * PIC16F PIC18F PIC24E, dsPIC33E 81 | Note that the USB stack will first have to be ported to several of those 82 | platforms before te bootloader can be ported. Patches are welcome. 83 | 84 | 85 | Alan Ott 86 | Signal 11 Software 87 | alan@signal11.us 88 | http://www.signal11.us 89 | 407-222-6975 90 | -------------------------------------------------------------------------------- /apps/bootloader/common/bootloader_protocol.h: -------------------------------------------------------------------------------- 1 | /* 2 | * M-Stack USB Bootloader 3 | * 4 | * M-Stack is free software: you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License as published by the 6 | * Free Software Foundation, version 3; or the Apache License, version 2.0 7 | * as published by the Apache Software Foundation. If you have purchased a 8 | * commercial license for this software from Signal 11 Software, your 9 | * commerical license superceeds the information in this header. 10 | * 11 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 14 | * License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this software. If not, see . 18 | * 19 | * You should have received a copy of the Apache License, verion 2.0 along 20 | * with this software. If not, see . 21 | * 22 | * Alan Ott 23 | * Signal 11 Software 24 | * 2016-04-27 25 | */ 26 | 27 | #ifndef BL_PROTOCOL_H__ 28 | #define BL_PROTOCOL_H__ 29 | 30 | #include 31 | 32 | /* This file contains the protocol used to communicate between the firmware 33 | * and software components of the bootloader. It is shared by the PIC24 and 34 | * PIC32 versions of the bootloader */ 35 | 36 | /* Protocol commands */ 37 | #define CLEAR_FLASH 100 38 | #define SEND_DATA 101 39 | #define GET_CHIP_INFO 102 40 | #define REQUEST_DATA 103 41 | #define SEND_RESET 105 42 | 43 | #define MAX_SKIP_REGIONS 10 44 | 45 | struct skip_region { 46 | uint32_t base; 47 | uint32_t top; 48 | }; 49 | 50 | struct chip_info { 51 | uint32_t user_region_base; 52 | uint32_t user_region_top; 53 | uint32_t config_words_base; 54 | uint32_t config_words_top; 55 | 56 | uint8_t bytes_per_instruction; 57 | uint8_t instructions_per_row; 58 | uint8_t number_of_skip_regions; 59 | uint8_t pad1; 60 | 61 | uint32_t reserved; 62 | uint32_t reserved2; 63 | 64 | struct skip_region skip_regions[10]; 65 | }; 66 | 67 | #endif /* BL_PROTOCOL_H__ */ 68 | -------------------------------------------------------------------------------- /apps/bootloader/firmware/.gitignore: -------------------------------------------------------------------------------- 1 | MPLAB.X/nbproject/Makefile-genesis.properties 2 | MPLAB.X/nbproject/Makefile-*.mk 3 | MPLAB.X/nbproject/Package-*.bash 4 | MPLAB.X/nbproject/private/ 5 | MPLAB.X/build/ 6 | MPLAB.X/dist 7 | MPLAB.X/funclist 8 | MPLAB.X/disassembly/ 9 | -------------------------------------------------------------------------------- /apps/bootloader/firmware/MPLAB.X/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # There exist several targets which are by default empty and which can be 3 | # used for execution of your targets. These targets are usually executed 4 | # before and after some main targets. They are: 5 | # 6 | # .build-pre: called before 'build' target 7 | # .build-post: called after 'build' target 8 | # .clean-pre: called before 'clean' target 9 | # .clean-post: called after 'clean' target 10 | # .clobber-pre: called before 'clobber' target 11 | # .clobber-post: called after 'clobber' target 12 | # .all-pre: called before 'all' target 13 | # .all-post: called after 'all' target 14 | # .help-pre: called before 'help' target 15 | # .help-post: called after 'help' target 16 | # 17 | # Targets beginning with '.' are not intended to be called on their own. 18 | # 19 | # Main targets can be executed directly, and they are: 20 | # 21 | # build build a specific configuration 22 | # clean remove built files from a configuration 23 | # clobber remove all built files 24 | # all build all configurations 25 | # help print help mesage 26 | # 27 | # Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and 28 | # .help-impl are implemented in nbproject/makefile-impl.mk. 29 | # 30 | # Available make variables: 31 | # 32 | # CND_BASEDIR base directory for relative paths 33 | # CND_DISTDIR default top distribution directory (build artifacts) 34 | # CND_BUILDDIR default top build directory (object files, ...) 35 | # CONF name of current configuration 36 | # CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration) 37 | # CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration) 38 | # CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration) 39 | # CND_PACKAGE_DIR_${CONF} directory of package (current configuration) 40 | # CND_PACKAGE_NAME_${CONF} name of package (current configuration) 41 | # CND_PACKAGE_PATH_${CONF} path to package (current configuration) 42 | # 43 | # NOCDDL 44 | 45 | 46 | # Environment 47 | MKDIR=mkdir 48 | CP=cp 49 | CCADMIN=CCadmin 50 | RANLIB=ranlib 51 | 52 | 53 | # build 54 | build: .build-post 55 | 56 | .build-pre: 57 | # Add your pre 'build' code here... 58 | 59 | .build-post: .build-impl 60 | # Add your post 'build' code here... 61 | 62 | 63 | # clean 64 | clean: .clean-post 65 | 66 | .clean-pre: 67 | # Add your pre 'clean' code here... 68 | 69 | .clean-post: .clean-impl 70 | # Add your post 'clean' code here... 71 | 72 | 73 | # clobber 74 | clobber: .clobber-post 75 | 76 | .clobber-pre: 77 | # Add your pre 'clobber' code here... 78 | 79 | .clobber-post: .clobber-impl 80 | # Add your post 'clobber' code here... 81 | 82 | 83 | # all 84 | all: .all-post 85 | 86 | .all-pre: 87 | # Add your pre 'all' code here... 88 | 89 | .all-post: .all-impl 90 | # Add your post 'all' code here... 91 | 92 | 93 | # help 94 | help: .help-post 95 | 96 | .help-pre: 97 | # Add your pre 'help' code here... 98 | 99 | .help-post: .help-impl 100 | # Add your post 'help' code here... 101 | 102 | 103 | 104 | # include project implementation makefile 105 | include nbproject/Makefile-impl.mk 106 | 107 | # include project make variables 108 | include nbproject/Makefile-variables.mk 109 | -------------------------------------------------------------------------------- /apps/bootloader/firmware/MPLAB.X/nbproject/project.xml: -------------------------------------------------------------------------------- 1 | 2 | com.microchip.mplab.nbide.embedded.makeproject 3 | 4 | 5 | bootloader 6 | d62999b6-148b-4401-bb2b-d1fe2348676c 7 | 0 8 | c 9 | 10 | h 11 | ISO-8859-1 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /apps/bootloader/firmware/usb_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Sample USB Configuration 3 | * 4 | * This file may be used by anyone for any purpose and may be used as a 5 | * starting point making your own application using M-Stack. 6 | * 7 | * It is worth noting that M-Stack itself is not under the same license as 8 | * this file. 9 | * 10 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. For details, see sections 7, 8, and 9 13 | * of the Apache License, version 2.0 which apply to this file. If you have 14 | * purchased a commercial license for this software from Signal 11 Software, 15 | * your commerical license superceeds the information in this header. 16 | * 17 | * Alan Ott 18 | * Signal 11 Software 19 | * 2013-04-08 20 | */ 21 | 22 | #ifndef USB_CONFIG_H__ 23 | #define USB_CONFIG_H__ 24 | 25 | /* Number of endpoint numbers besides endpoint zero. It's worth noting that 26 | and endpoint NUMBER does not completely describe an endpoint, but the 27 | along with the DIRECTION does (eg: EP 1 IN). The #define below turns on 28 | BOTH IN and OUT endpoints for endpoint numbers (besides zero) up to the 29 | value specified. For example, setting NUM_ENDPOINT_NUMBERS to 2 will 30 | activate endpoints EP 1 IN, EP 1 OUT, EP 2 IN, EP 2 OUT. */ 31 | #define NUM_ENDPOINT_NUMBERS 1 32 | 33 | /* Only 8, 16, 32 and 64 are supported for endpoint zero length. */ 34 | #define EP_0_LEN 8 35 | 36 | #define EP_1_OUT_LEN 64 37 | #define EP_1_IN_LEN 64 38 | 39 | #define NUMBER_OF_CONFIGURATIONS 1 40 | 41 | /* Ping-pong buffering mode. Valid values are: 42 | PPB_NONE - Do not ping-pong any endpoints 43 | PPB_EPO_OUT_ONLY - Ping-pong only endpoint 0 OUT 44 | PPB_ALL - Ping-pong all endpoints 45 | PPB_EPN_ONLY - Ping-pong all endpoints except 0 46 | */ 47 | #ifdef __PIC32MX__ 48 | #define PPB_MODE PPB_ALL 49 | #else 50 | #define PPB_MODE PPB_NONE 51 | #endif 52 | 53 | 54 | /* Comment the following line to use polling USB operation. You are responsible 55 | then for calling usb_service() periodically from your application. */ 56 | //#define USB_USE_INTERRUPTS 57 | 58 | /* Objects from usb_descriptors.c */ 59 | #define USB_DEVICE_DESCRIPTOR this_device_descriptor 60 | #define USB_CONFIG_DESCRIPTOR_MAP usb_application_config_descs 61 | #define USB_STRING_DESCRIPTOR_FUNC usb_application_get_string 62 | 63 | /* The Setup Request number (bRequest) to tell the host to use for the 64 | * Microsoft descriptors. See docs/winusb.txt for details. */ 65 | #define MICROSOFT_OS_DESC_VENDOR_CODE 0x50 66 | /* Automatically send the descriptors to bind the WinUSB driver on Windows */ 67 | #define AUTOMATIC_WINUSB_SUPPORT 68 | 69 | /* Optional callbacks from usb.c. Leave them commented if you don't want to 70 | use them. For the prototypes and documentation for each one, see usb.h. */ 71 | 72 | //#define SET_CONFIGURATION_CALLBACK app_set_configuration_callback 73 | //#define GET_DEVICE_STATUS_CALLBACK app_get_device_status_callback 74 | //#define ENDPOINT_HALT_CALLBACK app_endpoint_halt_callback 75 | //#define SET_INTERFACE_CALLBACK app_set_interface_callback 76 | //#define GET_INTERFACE_CALLBACK app_get_interface_callback 77 | //#define OUT_TRANSACTION_CALLBACK app_out_transaction_callback 78 | //#define IN_TRANSACTION_COMPLETE_CALLBACK app_in_transaction_complete_callback 79 | #define UNKNOWN_SETUP_REQUEST_CALLBACK app_unknown_setup_request_callback 80 | //#define UNKNOWN_GET_DESCRIPTOR_CALLBACK app_unknown_get_descriptor_callback 81 | //#define START_OF_FRAME_CALLBACK app_start_of_frame_callback 82 | #define USB_RESET_CALLBACK app_usb_reset_callback 83 | 84 | 85 | #endif /* USB_CONFIG_H__ */ 86 | -------------------------------------------------------------------------------- /apps/bootloader/firmware/usb_descriptors.c: -------------------------------------------------------------------------------- 1 | /* 2 | * USB Descriptors file 3 | * 4 | * This file may be used by anyone for any purpose and may be used as a 5 | * starting point making your own application using M-Stack. 6 | * 7 | * It is worth noting that M-Stack itself is not under the same license as 8 | * this file. 9 | * 10 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. For details, see sections 7, 8, and 9 13 | * of the Apache License, version 2.0 which apply to this file. If you have 14 | * purchased a commercial license for this software from Signal 11 Software, 15 | * your commerical license superceeds the information in this header. 16 | * 17 | * Alan Ott 18 | * Signal 11 Software 19 | */ 20 | 21 | #include "usb_config.h" 22 | #include "usb.h" 23 | #include "usb_ch9.h" 24 | 25 | #ifdef __C18 26 | #define ROMPTR rom 27 | #else 28 | #define ROMPTR 29 | #endif 30 | 31 | /* Configuration Packet 32 | * 33 | * This packet contains a configuration descriptor, one or more interface 34 | * descriptors, class descriptors(optional), and endpoint descriptors for a 35 | * single configuration of the device. This struct is specific to the 36 | * device, so the application will need to add any interfaces, classes and 37 | * endpoints it intends to use. It is sent to the host in response to a 38 | * GET_DESCRIPTOR[CONFIGURATION] request. 39 | * 40 | * While Most devices will only have one configuration, a device can have as 41 | * many configurations as it needs. To have more than one, simply make as 42 | * many of these structs as are required, one for each configuration. 43 | * 44 | * An instance of each configuration packet must be put in the 45 | * usb_application_config_descs[] array below (which is #defined in 46 | * usb_config.h) so that the USB stack can find it. 47 | * 48 | * See Chapter 9 of the USB specification from usb.org for details. 49 | * 50 | * It's worth noting that adding endpoints here does not automatically 51 | * enable them in the USB stack. To use an endpoint, it must be declared 52 | * here and also in usb_config.h. 53 | * 54 | * The configuration packet below is for the demo application. Yours will 55 | * of course vary. 56 | */ 57 | struct configuration_1_packet { 58 | struct configuration_descriptor config; 59 | struct interface_descriptor interface; 60 | struct endpoint_descriptor ep; 61 | struct endpoint_descriptor ep1_out; 62 | }; 63 | 64 | 65 | /* Device Descriptor 66 | * 67 | * Each device has a single device descriptor describing the device. The 68 | * format is described in Chapter 9 of the USB specification from usb.org. 69 | * USB_DEVICE_DESCRIPTOR needs to be defined to the name of this object in 70 | * usb_config.h. For more information, see USB_DEVICE_DESCRIPTOR in usb.h. 71 | */ 72 | const ROMPTR struct device_descriptor this_device_descriptor = 73 | { 74 | sizeof(struct device_descriptor), // bLength 75 | DESC_DEVICE, // bDescriptorType 76 | 0x0200, // 0x0200 = USB 2.0, 0x0110 = USB 1.1 77 | 0x00, // Device class 78 | 0x00, // Device Subclass 79 | 0x00, // Protocol. 80 | EP_0_LEN, // bMaxPacketSize0 81 | 0xA0A0, // Vendor 82 | 0x0002, // Product 83 | //0x0c12, 0x0005, // Vendor,Product for zeroplus joystick 84 | 0x0001, // device release (1.0) 85 | 1, // Manufacturer 86 | 2, // Product 87 | 0, // Serial 88 | NUMBER_OF_CONFIGURATIONS // NumConfigurations 89 | }; 90 | 91 | /* Configuration Packet Instance 92 | * 93 | * This is an instance of the configuration_packet struct containing all the 94 | * data describing a single configuration of this device. It is wise to use 95 | * as much C here as possible, such as sizeof() operators, and #defines from 96 | * usb_config.h. When stuff is wrong here, it can be difficult to track 97 | * down exactly why, so it's good to get the compiler to do as much of it 98 | * for you as it can. 99 | */ 100 | static const ROMPTR struct configuration_1_packet configuration_1 = 101 | { 102 | { 103 | // Members from struct configuration_descriptor 104 | sizeof(struct configuration_descriptor), 105 | DESC_CONFIGURATION, 106 | sizeof(configuration_1), //wTotalLength (length of the whole packet) 107 | 1, // bNumInterfaces 108 | 1, // bConfigurationValue 109 | 2, // iConfiguration (index of string descriptor) 110 | 0b10000000, 111 | 100/2, // 100/2 indicates 100mA 112 | }, 113 | 114 | { 115 | // Members from struct interface_descriptor 116 | sizeof(struct interface_descriptor), // bLength; 117 | DESC_INTERFACE, 118 | 0x0, // InterfaceNumber 119 | 0x0, // AlternateSetting 120 | 0x2, // bNumEndpoints (num besides endpoint 0) 121 | 0xff, // bInterfaceClass 3=HID, 0xFF=VendorDefined 122 | 0x00, // bInterfaceSubclass (0=NoBootInterface for HID) 123 | 0x00, // bInterfaceProtocol 124 | 0x02, // iInterface (index of string describing interface) 125 | }, 126 | 127 | { 128 | // Members of the Endpoint Descriptor (EP1 IN) 129 | sizeof(struct endpoint_descriptor), 130 | DESC_ENDPOINT, 131 | 0x01 | 0x80, // endpoint #1 0x80=IN 132 | EP_BULK, // bmAttributes 133 | 64, // wMaxPacketSize 134 | 1, // bInterval in ms. 135 | }, 136 | 137 | { 138 | // Members of the Endpoint Descriptor (EP1 OUT) 139 | sizeof(struct endpoint_descriptor), 140 | DESC_ENDPOINT, 141 | 0x01 /*| 0x00*/, // endpoint #1 0x00=IN 142 | EP_BULK, // bmAttributes 143 | 64, // wMaxPacketSize 144 | 1, // bInterval in ms. 145 | }, 146 | }; 147 | 148 | /* String Descriptors 149 | * 150 | * String descriptors are optional. If strings are used, string #0 is 151 | * required, and must contain the language ID of the other strings. See 152 | * Chapter 9 of the USB specification from usb.org for more info. 153 | * 154 | * Strings are UTF-16 Unicode, and are not NULL-terminated, hence the 155 | * unusual syntax. 156 | */ 157 | 158 | /* String index 0, only has one character in it, which is to be set to the 159 | language ID of the language which the other strings are in. */ 160 | static const ROMPTR struct {uint8_t bLength;uint8_t bDescriptorType; uint16_t lang; } str00 = { 161 | sizeof(str00), 162 | DESC_STRING, 163 | 0x0409 // US English 164 | }; 165 | 166 | static const ROMPTR struct {uint8_t bLength;uint8_t bDescriptorType; uint16_t chars[23]; } vendor_string = { 167 | sizeof(vendor_string), 168 | DESC_STRING, 169 | {'S','i','g','n','a','l',' ','1','1',' ','S','o','f','t','w','a','r','e',' ','L','L','C','.'} 170 | }; 171 | 172 | static const ROMPTR struct {uint8_t bLength;uint8_t bDescriptorType; uint16_t chars[14]; } product_string = { 173 | sizeof(product_string), 174 | DESC_STRING, 175 | {'U','S','B',' ','B','o','o','t','l','o','a','d','e','r'} 176 | }; 177 | 178 | 179 | /* Get String function 180 | * 181 | * This function is called by the USB stack to get a pointer to a string 182 | * descriptor. If using strings, USB_STRING_DESCRIPTOR_FUNC must be defined 183 | * to the name of this function in usb_config.h. See 184 | * USB_STRING_DESCRIPTOR_FUNC in usb.h for information about this function. 185 | * This is a function, and not simply a list or map, because it is useful, 186 | * and advisable, to have a serial number string which may be read from 187 | * EEPROM or somewhere that's not part of static program memory. 188 | */ 189 | int16_t usb_application_get_string(uint8_t string_number, const void **ptr) 190 | { 191 | if (string_number == 0) { 192 | *ptr = &str00; 193 | return sizeof(str00); 194 | } 195 | else if (string_number == 1) { 196 | *ptr = &vendor_string; 197 | return sizeof(vendor_string); 198 | } 199 | else if (string_number == 2) { 200 | *ptr = &product_string; 201 | return sizeof(product_string); 202 | } 203 | else if (string_number == 3) { 204 | /* This is where you might have code to do something like read 205 | a serial number out of EEPROM and return it. */ 206 | return -1; 207 | } 208 | 209 | return -1; 210 | } 211 | 212 | /* Configuration Descriptor List 213 | * 214 | * This is the list of pointters to the device's configuration descriptors. 215 | * The USB stack will read this array looking for descriptors which are 216 | * requsted from the host. USB_CONFIG_DESCRIPTOR_MAP must be defined to the 217 | * name of this array in usb_config.h. See USB_CONFIG_DESCRIPTOR_MAP in 218 | * usb.h for information about this array. The order of the descriptors is 219 | * not important, as the USB stack reads bConfigurationValue for each 220 | * descriptor to know its index. Make sure NUMBER_OF_CONFIGURATIONS in 221 | * usb_config.h matches the number of descriptors in this array. 222 | */ 223 | const struct configuration_descriptor *usb_application_config_descs[] = 224 | { 225 | (struct configuration_descriptor*) &configuration_1, 226 | }; 227 | STATIC_SIZE_CHECK_EQUAL(USB_ARRAYLEN(USB_CONFIG_DESCRIPTOR_MAP), NUMBER_OF_CONFIGURATIONS); 228 | STATIC_SIZE_CHECK_EQUAL(sizeof(USB_DEVICE_DESCRIPTOR), 18); 229 | -------------------------------------------------------------------------------- /apps/bootloader/software/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.so 3 | bootloader 4 | *.exe 5 | msvc/Debug 6 | msvc/Release 7 | msvc/*.ncb 8 | msvc/*.suo 9 | msvc/*.vcproj.*.user 10 | -------------------------------------------------------------------------------- /apps/bootloader/software/Makefile: -------------------------------------------------------------------------------- 1 | # M-Stack Bootloader Makefile 2 | # 3 | # This file may be used under the terms of the Simplified BSD License 4 | # (2-clause), which can be found in LICENSE-bsd.txt in the parent 5 | # directory. 6 | # 7 | # It is worth noting that M-Stack itself is not under the same license as 8 | # this file. See the top-level README.txt for more information. 9 | # 10 | # Alan Ott 11 | # Signal 11 Software 12 | 13 | # This Makefile makes heavy use of GNU Make's implicit rules. On non-GNU 14 | # platforms, make sure to use gmake to build this project 15 | # 16 | OBJS= hex.o bootloader.o main.o 17 | CFLAGS= -g -Wall 18 | CXXFLAGS= $(CFLAGS) 19 | LDFLAGS= -g 20 | LDLIBS= 21 | 22 | # Debugging: See log.h 23 | #CFLAGS+= -DDEBUG 24 | #CFLAGS+= -DLOG_LIBUSB_ERRORS 25 | #CFLAGS+= -DLOG_HEX 26 | 27 | OS=$(shell uname) 28 | ifneq ($(OS), Darwin) 29 | LDLIBS+=`pkg-config --libs libusb-1.0` 30 | CFLAGS+=`pkg-config --cflags libusb-1.0` 31 | else 32 | LDLIBS+=-framework IOKit -framework CoreFoundation 33 | endif 34 | 35 | all: bootloader 36 | 37 | bootloader: $(OBJS) 38 | $(CXX) $^ $(LDFLAGS) $(LDLIBS) -o $@ 39 | 40 | clean: 41 | rm -f $(OBJS) bootloader 42 | -------------------------------------------------------------------------------- /apps/bootloader/software/bootloader.h: -------------------------------------------------------------------------------- 1 | /* 2 | * M-Stack Bootloader 3 | * 4 | * M-Stack is free software: you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License as published by the 6 | * Free Software Foundation, version 3; or the Apache License, version 2.0 7 | * as published by the Apache Software Foundation. If you have purchased a 8 | * commercial license for this software from Signal 11 Software, your 9 | * commerical license superceeds the information in this header. 10 | * 11 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 14 | * License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this software. If not, see . 18 | * 19 | * You should have received a copy of the Apache License, verion 2.0 along 20 | * with this software. If not, see . 21 | * 22 | * Alan Ott 23 | * Signal 11 Software 24 | * 2013-05-15 25 | */ 26 | 27 | #ifndef BOOTLOADER_H__ 28 | #define BOOTLOADER_H__ 29 | 30 | #if _MSC_VER && _MSC_VER < 1600 31 | #include "c99.h" 32 | #else 33 | #include 34 | #endif 35 | 36 | 37 | /* The Bootloader API functions return 0 on success and a negative error 38 | * code on error. */ 39 | 40 | #define BOOTLOADER_ERROR -1 41 | #define BOOTLOADER_CANT_OPEN_FILE -2 /* Returned from *_init() */ 42 | #define BOOTLOADER_CANT_OPEN_DEVICE -3 /* Returned from *_init() */ 43 | #define BOOTLOADER_CANT_QUERY_DEVICE -4 /* Returned from *_init() */ 44 | #define BOOTLOADER_MULTIPLE_CONNECTED -5 /* Returned from *_init() */ 45 | 46 | struct bootloader; /* opaque struct */ 47 | 48 | int bootloader_init(struct bootloader **bootl, 49 | const char *filename, 50 | uint16_t vid, 51 | uint16_t pid); 52 | int bootloader_erase(struct bootloader *bl); 53 | int bootloader_program(struct bootloader *bl); 54 | int bootloader_verify(struct bootloader *bl); 55 | int bootloader_reset(struct bootloader *bl); 56 | void bootloader_free(struct bootloader *bl); 57 | 58 | #endif /* BOOTLOADER_H__ */ 59 | -------------------------------------------------------------------------------- /apps/bootloader/software/c99.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Selected C99 Definitions, for pre-2010 versions of Visual Studio 3 | * 4 | * M-Stack is free software: you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License as published by the 6 | * Free Software Foundation, version 3; or the Apache License, version 2.0 7 | * as published by the Apache Software Foundation. If you have purchased a 8 | * commercial license for this software from Signal 11 Software, your 9 | * commerical license superceeds the information in this header. 10 | * 11 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 14 | * License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this software. If not, see . 18 | * 19 | * You should have received a copy of the Apache License, verion 2.0 along 20 | * with this software. If not, see . 21 | * 22 | * Alan Ott 23 | * Signal 11 Software 24 | * 2013-04-29 25 | */ 26 | 27 | #ifndef S11_C99_H__ 28 | #define S11_C99_H__ 29 | 30 | #if _MSC_VER && _MSC_VER >= 1600 31 | #error "c99.h shouldn't be included on Visual Studio >= 2010" 32 | #endif 33 | 34 | #if __GNUC__ 35 | #error "c99.h shouldn't be included on GCC compilers" 36 | #endif 37 | 38 | typedef unsigned __int8 uint8_t; 39 | typedef unsigned __int16 uint16_t; 40 | typedef unsigned __int32 uint32_t; 41 | typedef unsigned char bool; 42 | #define false 0 43 | #define true 1 44 | 45 | #define PRIx32 "x" 46 | 47 | #endif /* S11_C99_H__ */ 48 | -------------------------------------------------------------------------------- /apps/bootloader/software/hex.h: -------------------------------------------------------------------------------- 1 | /* 2 | * M-Stack Intel Hex File Reader 3 | * 4 | * M-Stack is free software: you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License as published by the 6 | * Free Software Foundation, version 3; or the Apache License, version 2.0 7 | * as published by the Apache Software Foundation. If you have purchased a 8 | * commercial license for this software from Signal 11 Software, your 9 | * commerical license superceeds the information in this header. 10 | * 11 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 14 | * License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this software. If not, see . 18 | * 19 | * You should have received a copy of the Apache License, verion 2.0 along 20 | * with this software. If not, see . 21 | * 22 | * Alan Ott 23 | * Signal 11 Software 24 | * 2013-04-28 25 | */ 26 | 27 | #ifndef HEX_H__ 28 | #define HEX_H__ 29 | 30 | struct hex_data_region { 31 | size_t address; 32 | unsigned char *data; 33 | size_t len; 34 | 35 | struct hex_data_region *next; 36 | }; 37 | 38 | struct hex_data { 39 | /* Linked-list of data regions */ 40 | struct hex_data_region *regions; 41 | }; 42 | 43 | enum hex_error_code { 44 | HEX_ERROR_OK = 0, 45 | HEX_ERROR_CANT_OPEN_FILE = -1, 46 | HEX_ERROR_FILE_LOAD_ERROR = -2, 47 | HEX_ERROR_UNSUPPORTED_RECORD = -3, 48 | HEX_ERROR_DATA_TOO_LARGE = -4, 49 | }; 50 | 51 | enum hex_error_code hex_load(const char *filename, struct hex_data **data); 52 | void hex_init_empty(struct hex_data **data); 53 | void hex_free(struct hex_data *hd); 54 | 55 | #endif // HEX_H__ 56 | -------------------------------------------------------------------------------- /apps/bootloader/software/log.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Logging Macros 3 | * 4 | * M-Stack is free software: you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License as published by the 6 | * Free Software Foundation, version 3; or the Apache License, version 2.0 7 | * as published by the Apache Software Foundation. If you have purchased a 8 | * commercial license for this software from Signal 11 Software, your 9 | * commerical license superceeds the information in this header. 10 | * 11 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 14 | * License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this software. If not, see . 18 | * 19 | * You should have received a copy of the Apache License, verion 2.0 along 20 | * with this software. If not, see . 21 | * 22 | * Alan Ott 23 | * Signal 11 Software 24 | */ 25 | 26 | #ifndef LOG_H__ 27 | #define LOG_H__ 28 | 29 | /* Log general debugging information */ 30 | #ifdef DEBUG 31 | #define log printf 32 | #else 33 | #define log(...) 34 | #endif 35 | 36 | /* Log libusb error codes */ 37 | #ifdef LOG_LIBUSB_ERRORS 38 | #define log_libusb printf 39 | #else 40 | #define log_libusb(...) 41 | #endif 42 | 43 | /* Log Hex file parsing information */ 44 | #ifdef LOG_HEX 45 | #define log_hex printf 46 | #else 47 | #define log_hex(...) 48 | #endif 49 | 50 | 51 | #endif /* LOG_H__ */ 52 | -------------------------------------------------------------------------------- /apps/bootloader/software/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * M-Stack USB Bootloader 3 | * 4 | * M-Stack is free software: you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License as published by the 6 | * Free Software Foundation, version 3; or the Apache License, version 2.0 7 | * as published by the Apache Software Foundation. If you have purchased a 8 | * commercial license for this software from Signal 11 Software, your 9 | * commerical license superceeds the information in this header. 10 | * 11 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 14 | * License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this software. If not, see . 18 | * 19 | * You should have received a copy of the Apache License, verion 2.0 along 20 | * with this software. If not, see . 21 | * 22 | * Alan Ott 23 | * Signal 11 Software 24 | * 2013-04-29 25 | */ 26 | 27 | /* C */ 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #if _MSC_VER && _MSC_VER < 1600 34 | #include "c99.h" 35 | #else 36 | #include 37 | #include 38 | #endif 39 | 40 | #include "hex.h" 41 | #include "bootloader.h" 42 | 43 | #ifdef WIN32 44 | #include 45 | #define sleep(X) Sleep(X*1000) 46 | #else 47 | #include 48 | #endif 49 | 50 | /* Change these for your application */ 51 | #define DEFAULT_VID 0xa0a0 52 | #define DEFAULT_PID 0x0002 53 | 54 | static bool verbose_output = false; 55 | #define info(...) do { if (verbose_output) printf(__VA_ARGS__); } while(0) 56 | 57 | static void print_usage(const char *prog_name) 58 | { 59 | printf("Usage: %s [OPTION]... FILE\n", prog_name); 60 | printf("Flash firmware file.\n\n"); 61 | printf("OPTIONS can be one of:\n"); 62 | printf(" -d --dev=VID:PID USB VID/PID of the device to program\n"); 63 | printf(" -v, --verify verify program write\n"); 64 | printf(" -l --verbose Verbose (loud) output\n"); 65 | printf(" -r, --reset reset device when done\n"); 66 | printf(" -h, --help print help message and exit\n\n"); 67 | printf("Use a single hyphen (-) to read firmware hex file from stdin.\n"); 68 | } 69 | 70 | static bool parse_vid_pid(const char *str, uint16_t *vid, uint16_t *pid) 71 | { 72 | const char *colon; 73 | char *endptr; 74 | int val; 75 | 76 | /* check the format */ 77 | if (!*str) 78 | return false; 79 | colon = strchr(str, ':'); 80 | if (!colon) 81 | return false; 82 | if (!colon[1]) 83 | return false; 84 | if (colon == str) 85 | return false; 86 | 87 | /* VID */ 88 | val = strtol(str, &endptr, 16); 89 | if (*endptr != ':') 90 | return false; 91 | if (val > 0xffff) 92 | return false; 93 | *vid = val; 94 | 95 | /* PID */ 96 | val = strtol(colon+1, &endptr, 16); 97 | if (*endptr != '\0') 98 | return false; 99 | if (val > 0xffff) 100 | return false; 101 | *pid = val; 102 | 103 | return true; 104 | } 105 | 106 | int main(int argc, char **argv) 107 | { 108 | bool do_program = false; 109 | bool do_verify = false; 110 | bool do_reset = false; 111 | char **itr; 112 | const char *opt; 113 | const char *filename = NULL; 114 | uint16_t vid = 0, pid = 0; 115 | bool vidpid_valid = false; 116 | struct bootloader *bl; 117 | int res; 118 | 119 | if (argc < 2) { 120 | print_usage(argv[0]); 121 | return 1; 122 | } 123 | 124 | /* Parse the command line. */ 125 | itr = argv+1; 126 | opt = *itr; 127 | while (opt) { 128 | if (opt[0] == '-') { 129 | /* Option parameter */ 130 | if (opt[1] == '-') { 131 | /* Long option, two dashes. */ 132 | if (!strcmp(opt, "--help")) { 133 | print_usage(argv[0]); 134 | return 1; 135 | } 136 | else if (!strcmp(opt, "--reset")) 137 | do_reset = true; 138 | else if (!strcmp(opt, "--verify")) 139 | do_verify = true; 140 | else if (!strcmp(opt, "--verbose")) 141 | verbose_output = true; 142 | else if (!strncmp(opt, "--dev", 5)) { 143 | if (opt[5] != '=') { 144 | fprintf(stderr, "--dev requires vid/pid pair\n\n"); 145 | return 1; 146 | } 147 | vidpid_valid = parse_vid_pid(opt+6, &vid, &pid); 148 | if (!vidpid_valid) { 149 | fprintf(stderr, "Invalid VID/PID pair\n\n"); 150 | return 1; 151 | } 152 | } 153 | else { 154 | fprintf(stderr, "Invalid Parameter %s\n\n", opt); 155 | return 1; 156 | } 157 | } 158 | else { 159 | const char *c = opt + 1; 160 | if (!*c) { 161 | /* This is a parameter of a single 162 | hyphen, which means read from 163 | stdin. */ 164 | filename = opt; 165 | } 166 | while (*c) { 167 | /* Short option, only one dash */ 168 | switch (*c) { 169 | case 'v': 170 | do_verify = true; 171 | break; 172 | case 'r': 173 | do_reset = true; 174 | break; 175 | case 'l': 176 | verbose_output = true; 177 | break; 178 | case 'd': 179 | itr++; 180 | opt = *itr; 181 | if (!opt) { 182 | fprintf(stderr, "Must specify vid:pid after -d\n\n"); 183 | return 1; 184 | } 185 | vidpid_valid = parse_vid_pid(opt, &vid, &pid); 186 | if (!vidpid_valid) { 187 | fprintf(stderr, "Invalid VID/PID pair\n\n"); 188 | return 1; 189 | } 190 | break; 191 | default: 192 | fprintf(stderr, "Invalid parameter '%c'\n\n", *c); 193 | return 1; 194 | } 195 | c++; 196 | } 197 | } 198 | } 199 | else { 200 | /* Doesn't start with a dash. Must be the filename */ 201 | if (filename) { 202 | fprintf(stderr, "Multiple filenames listed. This is not supported\n\n"); 203 | return 1; 204 | } 205 | 206 | filename = opt; 207 | do_program = true; 208 | } 209 | itr++; 210 | opt = *itr; 211 | } 212 | 213 | vid = vidpid_valid? vid: DEFAULT_VID; 214 | pid = vidpid_valid? pid: DEFAULT_PID; 215 | 216 | if (!filename && !do_reset) { 217 | fprintf(stderr, "No Filename specified. Specify a filename of use \"-\" to read from stdin.\n"); 218 | return 1; 219 | } 220 | 221 | /* Command line parsing is done. Do the programming of the device. */ 222 | 223 | /* Open the device */ 224 | info("Opening the bootloader device.\n"); 225 | res = bootloader_init(&bl, filename, vid, pid); 226 | if (res == BOOTLOADER_CANT_OPEN_FILE) { 227 | fprintf(stderr, "Unable to open file %s\n", filename); 228 | return 1; 229 | } 230 | else if (res == BOOTLOADER_CANT_OPEN_DEVICE) { 231 | fprintf(stderr, "\nUnable to open device %04hx:%04hx " 232 | "for programming.\n" 233 | "Make sure that the device is connected " 234 | "and that you have proper permissions\nto " 235 | "open it.\n", vid, pid); 236 | return 1; 237 | } 238 | else if (res == BOOTLOADER_CANT_QUERY_DEVICE) { 239 | fprintf(stderr, "Unable to query device parameters\n"); 240 | return 1; 241 | } 242 | else if (res == BOOTLOADER_MULTIPLE_CONNECTED) { 243 | fprintf(stderr, "Multiple devices are connected. Remove all but one.\n"); 244 | } 245 | else if (res < 0) { 246 | fprintf(stderr, "Unspecified error initializing bootloader %d\n", res); 247 | return 1; 248 | } 249 | 250 | if (do_program) { 251 | /* Erase */ 252 | info("Erasing flash.\n"); 253 | res = bootloader_erase(bl); 254 | if (res < 0) { 255 | fprintf(stderr, "Erasing of device failed\n"); 256 | return 1; 257 | } 258 | 259 | /* Program */ 260 | info("Programming.\n"); 261 | res = bootloader_program(bl); 262 | if (res < 0) { 263 | fprintf(stderr, "Programming of device failed\n"); 264 | return 1; 265 | } 266 | } 267 | 268 | /* Verify */ 269 | if (do_verify) { 270 | info("Verifying.\n"); 271 | res = bootloader_verify(bl); 272 | if (res < 0) { 273 | fprintf(stderr, "Verification of programmed memory failed\n"); 274 | return 1; 275 | } 276 | } 277 | 278 | /* Reset */ 279 | if (do_reset) { 280 | info("Resetting the device.\n"); 281 | res = bootloader_reset(bl); 282 | if (res < 0) { 283 | fprintf(stderr, "Device Reset failed\n"); 284 | return 1; 285 | } 286 | } 287 | 288 | /* Close */ 289 | bootloader_free(bl); 290 | 291 | return 0; 292 | } 293 | -------------------------------------------------------------------------------- /apps/bootloader/software/msvc/bootloader.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual C++ Express 2008 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bootloader", "bootloader.vcproj", "{89040FDD-1862-489A-860E-B52CA00B28A6}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {89040FDD-1862-489A-860E-B52CA00B28A6}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {89040FDD-1862-489A-860E-B52CA00B28A6}.Debug|Win32.Build.0 = Debug|Win32 14 | {89040FDD-1862-489A-860E-B52CA00B28A6}.Release|Win32.ActiveCfg = Release|Win32 15 | {89040FDD-1862-489A-860E-B52CA00B28A6}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /apps/bootloader/software/msvc/bootloader.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 15 | 16 | 17 | 18 | 19 | 27 | 30 | 33 | 36 | 39 | 42 | 54 | 57 | 60 | 63 | 74 | 77 | 80 | 83 | 86 | 89 | 92 | 95 | 96 | 105 | 108 | 111 | 114 | 117 | 120 | 129 | 132 | 135 | 138 | 151 | 154 | 157 | 160 | 163 | 166 | 169 | 172 | 173 | 174 | 175 | 176 | 177 | 182 | 185 | 186 | 189 | 190 | 193 | 194 | 197 | 198 | 201 | 202 | 205 | 206 | 209 | 210 | 211 | 216 | 217 | 220 | 221 | 222 | 223 | 224 | 225 | -------------------------------------------------------------------------------- /apps/bootloader/software/msvc/libusb.vsprops: -------------------------------------------------------------------------------- 1 | 2 | 7 | 11 | 12 | -------------------------------------------------------------------------------- /apps/cdc_acm/.gitignore: -------------------------------------------------------------------------------- 1 | MPLAB.X/nbproject/Makefile-genesis.properties 2 | MPLAB.X/nbproject/Makefile-*.mk 3 | MPLAB.X/nbproject/Package-*.bash 4 | MPLAB.X/nbproject/private/ 5 | MPLAB.X/build/ 6 | MPLAB.X/dist 7 | MPLAB.X/funclist 8 | MPLAB.X/disassembly/ 9 | -------------------------------------------------------------------------------- /apps/cdc_acm/MPLAB.X/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # There exist several targets which are by default empty and which can be 3 | # used for execution of your targets. These targets are usually executed 4 | # before and after some main targets. They are: 5 | # 6 | # .build-pre: called before 'build' target 7 | # .build-post: called after 'build' target 8 | # .clean-pre: called before 'clean' target 9 | # .clean-post: called after 'clean' target 10 | # .clobber-pre: called before 'clobber' target 11 | # .clobber-post: called after 'clobber' target 12 | # .all-pre: called before 'all' target 13 | # .all-post: called after 'all' target 14 | # .help-pre: called before 'help' target 15 | # .help-post: called after 'help' target 16 | # 17 | # Targets beginning with '.' are not intended to be called on their own. 18 | # 19 | # Main targets can be executed directly, and they are: 20 | # 21 | # build build a specific configuration 22 | # clean remove built files from a configuration 23 | # clobber remove all built files 24 | # all build all configurations 25 | # help print help mesage 26 | # 27 | # Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and 28 | # .help-impl are implemented in nbproject/makefile-impl.mk. 29 | # 30 | # Available make variables: 31 | # 32 | # CND_BASEDIR base directory for relative paths 33 | # CND_DISTDIR default top distribution directory (build artifacts) 34 | # CND_BUILDDIR default top build directory (object files, ...) 35 | # CONF name of current configuration 36 | # CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration) 37 | # CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration) 38 | # CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration) 39 | # CND_PACKAGE_DIR_${CONF} directory of package (current configuration) 40 | # CND_PACKAGE_NAME_${CONF} name of package (current configuration) 41 | # CND_PACKAGE_PATH_${CONF} path to package (current configuration) 42 | # 43 | # NOCDDL 44 | 45 | 46 | # Environment 47 | MKDIR=mkdir 48 | CP=cp 49 | CCADMIN=CCadmin 50 | RANLIB=ranlib 51 | 52 | 53 | # build 54 | build: .build-post 55 | 56 | .build-pre: 57 | # Add your pre 'build' code here... 58 | 59 | .build-post: .build-impl 60 | # Add your post 'build' code here... 61 | 62 | 63 | # clean 64 | clean: .clean-post 65 | 66 | .clean-pre: 67 | # Add your pre 'clean' code here... 68 | 69 | .clean-post: .clean-impl 70 | # Add your post 'clean' code here... 71 | 72 | 73 | # clobber 74 | clobber: .clobber-post 75 | 76 | .clobber-pre: 77 | # Add your pre 'clobber' code here... 78 | 79 | .clobber-post: .clobber-impl 80 | # Add your post 'clobber' code here... 81 | 82 | 83 | # all 84 | all: .all-post 85 | 86 | .all-pre: 87 | # Add your pre 'all' code here... 88 | 89 | .all-post: .all-impl 90 | # Add your post 'all' code here... 91 | 92 | 93 | # help 94 | help: .help-post 95 | 96 | .help-pre: 97 | # Add your pre 'help' code here... 98 | 99 | .help-post: .help-impl 100 | # Add your post 'help' code here... 101 | 102 | 103 | 104 | # include project implementation makefile 105 | include nbproject/Makefile-impl.mk 106 | 107 | # include project make variables 108 | include nbproject/Makefile-variables.mk 109 | -------------------------------------------------------------------------------- /apps/cdc_acm/MPLAB.X/nbproject/project.xml: -------------------------------------------------------------------------------- 1 | 2 | com.microchip.mplab.nbide.embedded.makeproject 3 | 4 | 5 | usb_cdc_acm_demo 6 | d62999b6-148b-4401-bb2b-d1fe2348676c 7 | 0 8 | c 9 | 10 | h 11 | ISO-8859-1 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /apps/cdc_acm/inf/cdc-acm.inf: -------------------------------------------------------------------------------- 1 | ; M-Stack CDC-ACM Windows INF file 2 | ; 3 | ; This file has been tested on Windows 7, 64-bit. It may or may not work on 4 | ; Windows versions earlier than 7. Improvements and bug reports are welcome. 5 | ; 6 | ; Change the VID and PID (VID_PID_STRING) below to match the VID and PID 7 | ; of your device. You may or may not need the MI_00. Have a look at 8 | ; "Hardware Ids" in your device's properties page (details tab) in the device 9 | ; manager. 10 | 11 | 12 | [Version] 13 | Signature="$Windows NT$" 14 | Class=Ports 15 | ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} 16 | Provider=%MFGNAME% 17 | DriverVer=05/16/2014,1.0.0.18 18 | 19 | [Manufacturer] 20 | %MFGNAME%=DeviceList, NTx86, NTamd64, NTia64, NTarm 21 | 22 | 23 | [DeviceList.NTamd64] 24 | %DESC_CDC_DEMO% = DriverInstall, %VID_PID_STRING% 25 | 26 | [DeviceList.NTx86] 27 | %DESC_CDC_DEMO% = DriverInstall, %VID_PID_STRING% 28 | 29 | [DeviceList.NTia64] 30 | %DESC_CDC_DEMO% = DriverInstall, %VID_PID_STRING% 31 | 32 | [DeviceList.NTarm] 33 | %DESC_CDC_DEMO% = DriverInstall, %VID_PID_STRING% 34 | 35 | ; For the DriverInstall sections below see: 36 | ; http://support.microsoft.com/kb/837637 37 | ; http://www.microchip.com/forums/m488342.aspx 38 | ; 39 | ; This INF file includes mdmcpq.inf, which is a standard Windows 40 | ; INF file that you can find by searching for it recursively from 41 | ; %WINDIR%. It's in the WinSxS folders. In that file, you can see 42 | ; the symbols referenced here (eg: FakeModemCopyFileSection, etc). 43 | 44 | [DriverInstall.NT] 45 | include=mdmcpq.inf 46 | CopyFiles=FakeModemCopyFileSection 47 | 48 | [DriverInstall.NT.Services] 49 | include=mdmcpq.inf 50 | AddService=usbser, 0x00000002, LowerFilter_Service_Inst 51 | 52 | [DriverInstall.HW] 53 | include=mdmcpq.inf 54 | AddReg=LowerFilterAddReg 55 | 56 | [Strings] 57 | MFGNAME = "Signal 11 Software" 58 | DESC_CDC_DEMO = "M-Stack CDC Demo" 59 | VID_PID_STRING = "USB\VID_A0A0&PID_0004&MI_00" 60 | -------------------------------------------------------------------------------- /apps/cdc_acm/usb_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * USB CDC ACM Demo Configuration 3 | * 4 | * This file may be used by anyone for any purpose and may be used as a 5 | * starting point making your own application using M-Stack. 6 | * 7 | * It is worth noting that M-Stack itself is not under the same license 8 | * as this file. 9 | * 10 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. For details, see sections 7, 8, and 9 13 | * of the Apache License, version 2.0 which apply to this file. If you have 14 | * purchased a commercial license for this software from Signal 11 Software, 15 | * your commerical license superceeds the information in this header. 16 | * 17 | * Alan Ott 18 | * Signal 11 Software 19 | * 2013-04-08 20 | */ 21 | 22 | #ifndef USB_CONFIG_H__ 23 | #define USB_CONFIG_H__ 24 | 25 | /* Number of endpoint numbers besides endpoint zero. It's worth noting that 26 | and endpoint NUMBER does not completely describe an endpoint, but the 27 | along with the DIRECTION does (eg: EP 1 IN). The #define below turns on 28 | BOTH IN and OUT endpoints for endpoint numbers (besides zero) up to the 29 | value specified. For example, setting NUM_ENDPOINT_NUMBERS to 2 will 30 | activate endpoints EP 1 IN, EP 1 OUT, EP 2 IN, EP 2 OUT. */ 31 | #define NUM_ENDPOINT_NUMBERS 2 32 | 33 | /* Only 8, 16, 32 and 64 are supported for endpoint zero length. */ 34 | #define EP_0_LEN 8 35 | 36 | #define EP_1_OUT_LEN 1 37 | #define EP_1_IN_LEN 10 /* May need to be longer, depending 38 | * on the notifications you support. */ 39 | /* The code in the demo app assumes that EP2 IN and OUT are the same length */ 40 | #define EP_2_LEN 64 41 | #define EP_2_OUT_LEN EP_2_LEN 42 | #define EP_2_IN_LEN EP_2_LEN 43 | 44 | #define NUMBER_OF_CONFIGURATIONS 1 45 | 46 | /* Ping-pong buffering mode. Valid values are: 47 | PPB_NONE - Do not ping-pong any endpoints 48 | PPB_EPO_OUT_ONLY - Ping-pong only endpoint 0 OUT 49 | PPB_ALL - Ping-pong all endpoints 50 | PPB_EPN_ONLY - Ping-pong all endpoints except 0 51 | */ 52 | #ifdef __PIC32MX__ 53 | /* PIC32MX only supports PPB_ALL */ 54 | #define PPB_MODE PPB_ALL 55 | #else 56 | #define PPB_MODE PPB_NONE 57 | #endif 58 | 59 | /* Comment the following line to use polling USB operation. When using polling, 60 | You are responsible for calling usb_service() periodically from your 61 | application. */ 62 | #define USB_USE_INTERRUPTS 63 | 64 | /* Uncomment if you have a composite device which has multiple different types 65 | * of device classes. For example a device which has HID+CDC or 66 | * HID+VendorDefined, but not a device which has multiple of the same class 67 | * (such as HID+HID). Device class implementations have additional requirements 68 | * for multi-class devices. See the documentation for each device class for 69 | * details. */ 70 | //#define MULTI_CLASS_DEVICE 71 | 72 | 73 | /* Objects from usb_descriptors.c */ 74 | #define USB_DEVICE_DESCRIPTOR this_device_descriptor 75 | #define USB_CONFIG_DESCRIPTOR_MAP usb_application_config_descs 76 | #define USB_STRING_DESCRIPTOR_FUNC usb_application_get_string 77 | 78 | /* Optional callbacks from usb.c. Leave them commented if you don't want to 79 | use them. For the prototypes and documentation for each one, see usb.h. */ 80 | 81 | #define SET_CONFIGURATION_CALLBACK app_set_configuration_callback 82 | #define GET_DEVICE_STATUS_CALLBACK app_get_device_status_callback 83 | #define ENDPOINT_HALT_CALLBACK app_endpoint_halt_callback 84 | #define SET_INTERFACE_CALLBACK app_set_interface_callback 85 | #define GET_INTERFACE_CALLBACK app_get_interface_callback 86 | #define OUT_TRANSACTION_CALLBACK app_out_transaction_callback 87 | #define IN_TRANSACTION_COMPLETE_CALLBACK app_in_transaction_complete_callback 88 | #define UNKNOWN_SETUP_REQUEST_CALLBACK app_unknown_setup_request_callback 89 | #define UNKNOWN_GET_DESCRIPTOR_CALLBACK app_unknown_get_descriptor_callback 90 | #define START_OF_FRAME_CALLBACK app_start_of_frame_callback 91 | #define USB_RESET_CALLBACK app_usb_reset_callback 92 | 93 | /* CDC Configuration functions. See usb_cdc.h for documentation. */ 94 | #define CDC_SEND_ENCAPSULATED_COMMAND_CALLBACK app_send_encapsulated_command 95 | #define CDC_GET_ENCAPSULATED_RESPONSE_CALLBACK app_get_encapsulated_response 96 | #define CDC_SET_COMM_FEATURE_CALLBACK app_set_comm_feature_callback 97 | #define CDC_CLEAR_COMM_FEATURE_CALLBACK app_clear_comm_feature_callback 98 | #define CDC_GET_COMM_FEATURE_CALLBACK app_get_comm_feature_callback 99 | #define CDC_SET_LINE_CODING_CALLBACK app_set_line_coding_callback 100 | #define CDC_GET_LINE_CODING_CALLBACK app_get_line_coding_callback 101 | #define CDC_SET_CONTROL_LINE_STATE_CALLBACK app_set_control_line_state_callback 102 | #define CDC_SEND_BREAK_CALLBACK app_send_break_callback 103 | 104 | #endif /* USB_CONFIG_H__ */ 105 | -------------------------------------------------------------------------------- /apps/common/hardware.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Hardware Initialization 3 | * 4 | * This file may be used by anyone for any purpose and may be used as a 5 | * starting point making your own application using M-Stack. 6 | * 7 | * It is worth noting that M-Stack itself is not under the same license as 8 | * this file. 9 | * 10 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. For details, see sections 7, 8, and 9 13 | * of the Apache License, version 2.0 which apply to this file. If you have 14 | * purchased a commercial license for this software from Signal 11 Software, 15 | * your commerical license superceeds the information in this header. 16 | * 17 | * Alan Ott 18 | * Signal 11 Software 19 | * 2016-05-02 20 | */ 21 | 22 | #ifndef HARDWARE_H__ 23 | #define HARDWARE_H__ 24 | 25 | /* Initialize the hardware. This of course varies widely by MCU and board */ 26 | void hardware_init(void); 27 | 28 | #endif /* HARDWARE_H__ */ 29 | -------------------------------------------------------------------------------- /apps/hid_composite/.gitignore: -------------------------------------------------------------------------------- 1 | MPLAB.X/nbproject/Makefile-genesis.properties 2 | MPLAB.X/nbproject/Makefile-*.mk 3 | MPLAB.X/nbproject/Package-*.bash 4 | MPLAB.X/nbproject/private/ 5 | MPLAB.X/build/ 6 | MPLAB.X/dist 7 | MPLAB.X/funclist 8 | MPLAB.X/disassembly/ 9 | -------------------------------------------------------------------------------- /apps/hid_composite/MPLAB.X/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # There exist several targets which are by default empty and which can be 3 | # used for execution of your targets. These targets are usually executed 4 | # before and after some main targets. They are: 5 | # 6 | # .build-pre: called before 'build' target 7 | # .build-post: called after 'build' target 8 | # .clean-pre: called before 'clean' target 9 | # .clean-post: called after 'clean' target 10 | # .clobber-pre: called before 'clobber' target 11 | # .clobber-post: called after 'clobber' target 12 | # .all-pre: called before 'all' target 13 | # .all-post: called after 'all' target 14 | # .help-pre: called before 'help' target 15 | # .help-post: called after 'help' target 16 | # 17 | # Targets beginning with '.' are not intended to be called on their own. 18 | # 19 | # Main targets can be executed directly, and they are: 20 | # 21 | # build build a specific configuration 22 | # clean remove built files from a configuration 23 | # clobber remove all built files 24 | # all build all configurations 25 | # help print help mesage 26 | # 27 | # Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and 28 | # .help-impl are implemented in nbproject/makefile-impl.mk. 29 | # 30 | # Available make variables: 31 | # 32 | # CND_BASEDIR base directory for relative paths 33 | # CND_DISTDIR default top distribution directory (build artifacts) 34 | # CND_BUILDDIR default top build directory (object files, ...) 35 | # CONF name of current configuration 36 | # CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration) 37 | # CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration) 38 | # CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration) 39 | # CND_PACKAGE_DIR_${CONF} directory of package (current configuration) 40 | # CND_PACKAGE_NAME_${CONF} name of package (current configuration) 41 | # CND_PACKAGE_PATH_${CONF} path to package (current configuration) 42 | # 43 | # NOCDDL 44 | 45 | 46 | # Environment 47 | MKDIR=mkdir 48 | CP=cp 49 | CCADMIN=CCadmin 50 | RANLIB=ranlib 51 | 52 | 53 | # build 54 | build: .build-post 55 | 56 | .build-pre: 57 | # Add your pre 'build' code here... 58 | 59 | .build-post: .build-impl 60 | # Add your post 'build' code here... 61 | 62 | 63 | # clean 64 | clean: .clean-post 65 | 66 | .clean-pre: 67 | # Add your pre 'clean' code here... 68 | 69 | .clean-post: .clean-impl 70 | # Add your post 'clean' code here... 71 | 72 | 73 | # clobber 74 | clobber: .clobber-post 75 | 76 | .clobber-pre: 77 | # Add your pre 'clobber' code here... 78 | 79 | .clobber-post: .clobber-impl 80 | # Add your post 'clobber' code here... 81 | 82 | 83 | # all 84 | all: .all-post 85 | 86 | .all-pre: 87 | # Add your pre 'all' code here... 88 | 89 | .all-post: .all-impl 90 | # Add your post 'all' code here... 91 | 92 | 93 | # help 94 | help: .help-post 95 | 96 | .help-pre: 97 | # Add your pre 'help' code here... 98 | 99 | .help-post: .help-impl 100 | # Add your post 'help' code here... 101 | 102 | 103 | 104 | # include project implementation makefile 105 | include nbproject/Makefile-impl.mk 106 | 107 | # include project make variables 108 | include nbproject/Makefile-variables.mk 109 | -------------------------------------------------------------------------------- /apps/hid_composite/MPLAB.X/nbproject/project.xml: -------------------------------------------------------------------------------- 1 | 2 | com.microchip.mplab.nbide.embedded.makeproject 3 | 4 | 5 | usb_stack_hid_mouse_composite_demo 6 | d62999b6-148b-4401-bb2b-d1fe2348676c 7 | 0 8 | c 9 | 10 | h 11 | ISO-8859-1 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /apps/hid_composite/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * USB HID Mouse 3 | * 4 | * This file may be used by anyone for any purpose and may be used as a 5 | * starting point making your own application using M-Stack. 6 | * 7 | * It is worth noting that M-Stack itself is not under the same license as 8 | * this file. 9 | * 10 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. For details, see sections 7, 8, and 9 13 | * of the Apache License, version 2.0 which apply to this file. If you have 14 | * purchased a commercial license for this software from Signal 11 Software, 15 | * your commerical license superceeds the information in this header. 16 | * 17 | * Alan Ott 18 | * Signal 11 Software 19 | * 2013-08-13 20 | */ 21 | 22 | #include "usb.h" 23 | #include 24 | #include 25 | #include "usb_config.h" 26 | #include "usb_ch9.h" 27 | #include "usb_hid.h" 28 | #include "hardware.h" 29 | 30 | #ifdef MULTI_CLASS_DEVICE 31 | static uint8_t hid_interfaces[] = { 0 }; 32 | #endif 33 | 34 | int main(void) 35 | { 36 | hardware_init(); 37 | 38 | #ifdef MULTI_CLASS_DEVICE 39 | hid_set_interface_list(hid_interfaces, sizeof(hid_interfaces)); 40 | #endif 41 | usb_init(); 42 | 43 | /* Setup mouse movement. This implementation sends back data for every 44 | * IN packet, but sends no movement for all but every delay-th frame. 45 | * Adjusting delay will slow down or speed up the movement, which is 46 | * also dependent upon the rate at which the host sends IN packets, 47 | * which varies between implementations. 48 | * 49 | * In real life, you wouldn't want to send back data that hadn't 50 | * changed, but since there's no real hardware to poll, and since this 51 | * example is about showing the HID class, and not about creative ways 52 | * to do timing, we send back data every frame. The interested reader 53 | * may want to modify it to use the start-of-frame callback for 54 | * timing. 55 | */ 56 | uint8_t x_delay = 14; 57 | uint8_t x_count = 100; 58 | int8_t x_direc = 1; 59 | uint8_t y_delay = 14; 60 | uint8_t y_count = 25; 61 | int8_t y_direc = 1; 62 | 63 | while (1) { 64 | if (usb_is_configured() && 65 | !usb_in_endpoint_halted(1) && 66 | !usb_in_endpoint_busy(1)) { 67 | 68 | /* Interface 1: Move mouse Left and Right. This 69 | * interface only has an X axis. */ 70 | unsigned char *buf = usb_get_in_buffer(1); 71 | buf[0] = 0x0; 72 | buf[1] = (--x_delay)? 0: x_direc; 73 | buf[2] = 0; /* Don't move Y */ 74 | usb_send_in_buffer(1, 3); 75 | 76 | if (x_delay == 0) { 77 | if (--x_count == 0) { 78 | x_count = 100; 79 | x_direc *= -1; 80 | } 81 | x_delay = 14; 82 | } 83 | } 84 | 85 | if (usb_is_configured() && 86 | !usb_in_endpoint_halted(2) && 87 | !usb_in_endpoint_busy(2)) { 88 | 89 | /* Interface 2: Move mouse up and Down. This 90 | * interface only has a Y axis. */ 91 | unsigned char *buf = usb_get_in_buffer(2); 92 | buf[0] = 0x0; 93 | buf[1] = 0; /* Don't move X */ 94 | buf[2] = (--y_delay)? 0: y_direc; 95 | buf[3] = 0; /* Don't move Z */ 96 | usb_send_in_buffer(2, 4); 97 | 98 | if (y_delay == 0) { 99 | if (--y_count == 0) { 100 | y_count = 25; 101 | y_direc *= -1; 102 | } 103 | y_delay = 14; 104 | } 105 | } 106 | 107 | #ifndef USB_USE_INTERRUPTS 108 | usb_service(); 109 | #endif 110 | } 111 | 112 | return 0; 113 | } 114 | 115 | /* Callbacks. These function names are set in usb_config.h. */ 116 | void app_set_configuration_callback(uint8_t configuration) 117 | { 118 | 119 | } 120 | 121 | uint16_t app_get_device_status_callback() 122 | { 123 | return 0x0000; 124 | } 125 | 126 | void app_endpoint_halt_callback(uint8_t endpoint, bool halted) 127 | { 128 | 129 | } 130 | 131 | int8_t app_set_interface_callback(uint8_t interface, uint8_t alt_setting) 132 | { 133 | return 0; 134 | } 135 | 136 | int8_t app_get_interface_callback(uint8_t interface) 137 | { 138 | return 0; 139 | } 140 | 141 | void app_out_transaction_callback(uint8_t endpoint) 142 | { 143 | 144 | } 145 | 146 | void app_in_transaction_complete_callback(uint8_t endpoint) 147 | { 148 | 149 | } 150 | 151 | int8_t app_unknown_setup_request_callback(const struct setup_packet *setup) 152 | { 153 | /* To use the HID device class, have a handler for unknown setup 154 | * requests and call process_hid_setup_request() (as shown here), 155 | * which will check if the setup request is HID-related, and will 156 | * call the HID application callbacks defined in usb_hid.h. For 157 | * composite devices containing other device classes, make sure 158 | * MULTI_CLASS_DEVICE is defined in usb_config.h and call all 159 | * appropriate device class setup request functions here. 160 | */ 161 | return process_hid_setup_request(setup); 162 | } 163 | 164 | int16_t app_unknown_get_descriptor_callback(const struct setup_packet *pkt, const void **descriptor) 165 | { 166 | return -1; 167 | } 168 | 169 | void app_start_of_frame_callback(void) 170 | { 171 | 172 | } 173 | 174 | void app_usb_reset_callback(void) 175 | { 176 | 177 | } 178 | 179 | /* HID Callbacks. See usb_hid.h for documentation. */ 180 | 181 | static uint8_t report_buf[4]; 182 | 183 | static int8_t get_report_callback(bool transfer_ok, void *context) 184 | { 185 | /* Nothing to do here really. It either succeeded or failed. If it 186 | * failed, the host will ask for it again. It's nice to be on the 187 | * device side in USB. */ 188 | return 0; 189 | } 190 | 191 | int16_t app_get_report_callback(uint8_t interface, uint8_t report_type, 192 | uint8_t report_id, const void **report, 193 | usb_ep0_data_stage_callback *callback, 194 | void **context) 195 | { 196 | /* Set report, callback, and context; and the USB stack will send 197 | * the report, calling our callback (get_report_callback()) when 198 | * it has finished. 199 | */ 200 | if (interface == 1) { 201 | *report = report_buf; 202 | *callback = get_report_callback; 203 | *context = NULL; 204 | return 3; 205 | } 206 | else if (interface == 2) { 207 | *report = report_buf; 208 | *callback = get_report_callback; 209 | *context = NULL; 210 | return 4; 211 | } 212 | 213 | return -1; 214 | } 215 | 216 | int8_t app_set_report_callback(uint8_t interface, uint8_t report_type, 217 | uint8_t report_id) 218 | { 219 | /* To handle Set_Report, call usb_start_receive_ep0_data_stage() 220 | * here. See the documentation for HID_SET_REPORT_CALLBACK() in 221 | * usb_hid.h. For this device though, there are no output or 222 | * feature reports. */ 223 | return -1; 224 | } 225 | 226 | uint8_t app_get_idle_callback(uint8_t interface, uint8_t report_id) 227 | { 228 | return 0; 229 | } 230 | 231 | int8_t app_set_idle_callback(uint8_t interface, uint8_t report_id, 232 | uint8_t idle_rate) 233 | { 234 | return -1; 235 | } 236 | 237 | int8_t app_get_protocol_callback(uint8_t interface) 238 | { 239 | return 1; 240 | } 241 | 242 | int8_t app_set_protocol_callback(uint8_t interface, uint8_t report_id) 243 | { 244 | return -1; 245 | } 246 | 247 | 248 | #ifdef _PIC14E 249 | void interrupt isr() 250 | { 251 | usb_service(); 252 | } 253 | #elif _PIC18 254 | 255 | #ifdef __XC8 256 | void interrupt high_priority isr() 257 | { 258 | usb_service(); 259 | } 260 | #elif _PICC18 261 | #error need to make ISR 262 | #endif 263 | 264 | #endif -------------------------------------------------------------------------------- /apps/hid_composite/usb_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * USB HID Mouse Configuration 3 | * 4 | * This file may be used by anyone for any purpose and may be used as a 5 | * starting point making your own application using M-Stack. 6 | * 7 | * It is worth noting that M-Stack itself is not under the same license 8 | * as this file. 9 | * 10 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. For details, see sections 7, 8, and 9 13 | * of the Apache License, version 2.0 which apply to this file. If you have 14 | * purchased a commercial license for this software from Signal 11 Software, 15 | * your commerical license superceeds the information in this header. 16 | * 17 | * Alan Ott 18 | * Signal 11 Software 19 | * 2013-04-08 20 | */ 21 | 22 | #ifndef USB_CONFIG_H__ 23 | #define USB_CONFIG_H__ 24 | 25 | /* Number of endpoint numbers besides endpoint zero. It's worth noting that 26 | and endpoint NUMBER does not completely describe an endpoint, but the 27 | along with the DIRECTION does (eg: EP 1 IN). The #define below turns on 28 | BOTH IN and OUT endpoints for endpoint numbers (besides zero) up to the 29 | value specified. For example, setting NUM_ENDPOINT_NUMBERS to 2 will 30 | activate endpoints EP 1 IN, EP 1 OUT, EP 2 IN, EP 2 OUT. */ 31 | #define NUM_ENDPOINT_NUMBERS 2 32 | 33 | /* Only 8, 16, 32 and 64 are supported for endpoint zero length. */ 34 | #define EP_0_LEN 8 35 | 36 | #define EP_1_OUT_LEN 8 37 | #define EP_1_IN_LEN 8 38 | #define EP_2_OUT_LEN 8 39 | #define EP_2_IN_LEN 8 40 | 41 | #define NUMBER_OF_CONFIGURATIONS 1 42 | 43 | /* Ping-pong buffering mode. Valid values are: 44 | PPB_NONE - Do not ping-pong any endpoints 45 | PPB_EPO_OUT_ONLY - Ping-pong only endpoint 0 OUT 46 | PPB_ALL - Ping-pong all endpoints 47 | PPB_EPN_ONLY - Ping-pong all endpoints except 0 48 | */ 49 | #ifdef __PIC32MX__ 50 | /* PIC32MX only supports PPB_ALL */ 51 | #define PPB_MODE PPB_ALL 52 | #else 53 | #define PPB_MODE PPB_NONE 54 | #endif 55 | 56 | /* Comment the following line to use polling USB operation. When using polling, 57 | You are responsible for calling usb_service() periodically from your 58 | application. */ 59 | #define USB_USE_INTERRUPTS 60 | 61 | /* Uncomment if you have a composite device which has multiple different types 62 | * of device classes. For example a device which has HID+CDC or 63 | * HID+VendorDefined, but not a device which has multiple of the same class 64 | * (such as HID+HID). Device class implementations have additional requirements 65 | * for multi-class devices. See the documentation for each device class for 66 | * details. */ 67 | //#define MULTI_CLASS_DEVICE 68 | 69 | 70 | /* Objects from usb_descriptors.c */ 71 | #define USB_DEVICE_DESCRIPTOR this_device_descriptor 72 | #define USB_CONFIG_DESCRIPTOR_MAP usb_application_config_descs 73 | #define USB_STRING_DESCRIPTOR_FUNC usb_application_get_string 74 | 75 | /* Optional callbacks from usb.c. Leave them commented if you don't want to 76 | use them. For the prototypes and documentation for each one, see usb.h. */ 77 | 78 | #define SET_CONFIGURATION_CALLBACK app_set_configuration_callback 79 | #define GET_DEVICE_STATUS_CALLBACK app_get_device_status_callback 80 | #define ENDPOINT_HALT_CALLBACK app_endpoint_halt_callback 81 | #define SET_INTERFACE_CALLBACK app_set_interface_callback 82 | #define GET_INTERFACE_CALLBACK app_get_interface_callback 83 | #define OUT_TRANSACTION_CALLBACK app_out_transaction_callback 84 | #define IN_TRANSACTION_COMPLETE_CALLBACK app_in_transaction_complete_callback 85 | #define UNKNOWN_SETUP_REQUEST_CALLBACK app_unknown_setup_request_callback 86 | #define UNKNOWN_GET_DESCRIPTOR_CALLBACK app_unknown_get_descriptor_callback 87 | #define START_OF_FRAME_CALLBACK app_start_of_frame_callback 88 | #define USB_RESET_CALLBACK app_usb_reset_callback 89 | 90 | /* HID Configuration functions. See usb_hid.h for documentation. */ 91 | #define USB_HID_DESCRIPTOR_FUNC usb_application_get_hid_descriptor 92 | #define USB_HID_REPORT_DESCRIPTOR_FUNC usb_application_get_hid_report_descriptor 93 | //#define USB_HID_PHYSICAL_DESCRIPTOR_FUNC usb_application_get_hid_physical_descriptor 94 | 95 | /* HID Callbacks. See usb_hid.h for documentation. */ 96 | #define HID_GET_REPORT_CALLBACK app_get_report_callback 97 | #define HID_SET_REPORT_CALLBACK app_set_report_callback 98 | #define HID_GET_IDLE_CALLBACK app_get_idle_callback 99 | #define HID_SET_IDLE_CALLBACK app_set_idle_callback 100 | #define HID_GET_PROTOCOL_CALLBACK app_get_protocol_callback 101 | #define HID_SET_PROTOCOL_CALLBACK app_set_protocol_callback 102 | 103 | #endif /* USB_CONFIG_H__ */ 104 | -------------------------------------------------------------------------------- /apps/hid_mouse/.gitignore: -------------------------------------------------------------------------------- 1 | MPLAB.X/nbproject/Makefile-genesis.properties 2 | MPLAB.X/nbproject/Makefile-*.mk 3 | MPLAB.X/nbproject/Package-*.bash 4 | MPLAB.X/nbproject/private/ 5 | MPLAB.X/build/ 6 | MPLAB.X/dist 7 | MPLAB.X/funclist 8 | MPLAB.X/disassembly/ 9 | -------------------------------------------------------------------------------- /apps/hid_mouse/MPLAB.X/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # There exist several targets which are by default empty and which can be 3 | # used for execution of your targets. These targets are usually executed 4 | # before and after some main targets. They are: 5 | # 6 | # .build-pre: called before 'build' target 7 | # .build-post: called after 'build' target 8 | # .clean-pre: called before 'clean' target 9 | # .clean-post: called after 'clean' target 10 | # .clobber-pre: called before 'clobber' target 11 | # .clobber-post: called after 'clobber' target 12 | # .all-pre: called before 'all' target 13 | # .all-post: called after 'all' target 14 | # .help-pre: called before 'help' target 15 | # .help-post: called after 'help' target 16 | # 17 | # Targets beginning with '.' are not intended to be called on their own. 18 | # 19 | # Main targets can be executed directly, and they are: 20 | # 21 | # build build a specific configuration 22 | # clean remove built files from a configuration 23 | # clobber remove all built files 24 | # all build all configurations 25 | # help print help mesage 26 | # 27 | # Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and 28 | # .help-impl are implemented in nbproject/makefile-impl.mk. 29 | # 30 | # Available make variables: 31 | # 32 | # CND_BASEDIR base directory for relative paths 33 | # CND_DISTDIR default top distribution directory (build artifacts) 34 | # CND_BUILDDIR default top build directory (object files, ...) 35 | # CONF name of current configuration 36 | # CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration) 37 | # CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration) 38 | # CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration) 39 | # CND_PACKAGE_DIR_${CONF} directory of package (current configuration) 40 | # CND_PACKAGE_NAME_${CONF} name of package (current configuration) 41 | # CND_PACKAGE_PATH_${CONF} path to package (current configuration) 42 | # 43 | # NOCDDL 44 | 45 | 46 | # Environment 47 | MKDIR=mkdir 48 | CP=cp 49 | CCADMIN=CCadmin 50 | RANLIB=ranlib 51 | 52 | 53 | # build 54 | build: .build-post 55 | 56 | .build-pre: 57 | # Add your pre 'build' code here... 58 | 59 | .build-post: .build-impl 60 | # Add your post 'build' code here... 61 | 62 | 63 | # clean 64 | clean: .clean-post 65 | 66 | .clean-pre: 67 | # Add your pre 'clean' code here... 68 | 69 | .clean-post: .clean-impl 70 | # Add your post 'clean' code here... 71 | 72 | 73 | # clobber 74 | clobber: .clobber-post 75 | 76 | .clobber-pre: 77 | # Add your pre 'clobber' code here... 78 | 79 | .clobber-post: .clobber-impl 80 | # Add your post 'clobber' code here... 81 | 82 | 83 | # all 84 | all: .all-post 85 | 86 | .all-pre: 87 | # Add your pre 'all' code here... 88 | 89 | .all-post: .all-impl 90 | # Add your post 'all' code here... 91 | 92 | 93 | # help 94 | help: .help-post 95 | 96 | .help-pre: 97 | # Add your pre 'help' code here... 98 | 99 | .help-post: .help-impl 100 | # Add your post 'help' code here... 101 | 102 | 103 | 104 | # include project implementation makefile 105 | include nbproject/Makefile-impl.mk 106 | 107 | # include project make variables 108 | include nbproject/Makefile-variables.mk 109 | -------------------------------------------------------------------------------- /apps/hid_mouse/MPLAB.X/nbproject/project.xml: -------------------------------------------------------------------------------- 1 | 2 | com.microchip.mplab.nbide.embedded.makeproject 3 | 4 | 5 | usb_stack_hid_mouse_demo 6 | d62999b6-148b-4401-bb2b-d1fe2348676c 7 | 0 8 | c 9 | 10 | h 11 | ISO-8859-1 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /apps/hid_mouse/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * USB HID Mouse 3 | * 4 | * This file may be used by anyone for any purpose and may be used as a 5 | * starting point making your own application using M-Stack. 6 | * 7 | * It is worth noting that M-Stack itself is not under the same license as 8 | * this file. 9 | * 10 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. For details, see sections 7, 8, and 9 13 | * of the Apache License, version 2.0 which apply to this file. If you have 14 | * purchased a commercial license for this software from Signal 11 Software, 15 | * your commerical license superceeds the information in this header. 16 | * 17 | * Alan Ott 18 | * Signal 11 Software 19 | * 2013-08-13 20 | */ 21 | 22 | #include "usb.h" 23 | #include 24 | #include 25 | #include "usb_config.h" 26 | #include "usb_ch9.h" 27 | #include "usb_hid.h" 28 | #include "hardware.h" 29 | 30 | #ifdef MULTI_CLASS_DEVICE 31 | static uint8_t hid_interfaces[] = { 0 }; 32 | #endif 33 | 34 | int main(void) 35 | { 36 | hardware_init(); 37 | 38 | #ifdef MULTI_CLASS_DEVICE 39 | hid_set_interface_list(hid_interfaces, sizeof(hid_interfaces)); 40 | #endif 41 | usb_init(); 42 | 43 | /* Setup mouse movement. This implementation sends back data for every 44 | * IN packet, but sends no movement for all but every delay-th frame. 45 | * Adjusting delay will slow down or speed up the movement, which is 46 | * also dependent upon the rate at which the host sends IN packets, 47 | * which varies between implementations. 48 | * 49 | * In real life, you wouldn't want to send back data that hadn't 50 | * changed, but since there's no real hardware to poll, and since this 51 | * example is about showing the HID class, and not about creative ways 52 | * to do timing, we send back data every frame. The interested reader 53 | * may want to modify it to use the start-of-frame callback for 54 | * timing. 55 | */ 56 | uint8_t x_count = 100; 57 | uint8_t delay = 7; 58 | int8_t x_direc = 1; 59 | 60 | while (1) { 61 | if (usb_is_configured() && 62 | !usb_in_endpoint_halted(1) && 63 | !usb_in_endpoint_busy(1)) { 64 | 65 | unsigned char *buf = usb_get_in_buffer(1); 66 | buf[0] = 0x0; 67 | buf[1] = (--delay)? 0: x_direc; 68 | buf[2] = 0; 69 | usb_send_in_buffer(1, 3); 70 | 71 | if (delay == 0) { 72 | if (--x_count == 0) { 73 | x_count = 100; 74 | x_direc *= -1; 75 | } 76 | delay = 7; 77 | } 78 | } 79 | 80 | #ifndef USB_USE_INTERRUPTS 81 | usb_service(); 82 | #endif 83 | } 84 | 85 | return 0; 86 | } 87 | 88 | /* Callbacks. These function names are set in usb_config.h. */ 89 | void app_set_configuration_callback(uint8_t configuration) 90 | { 91 | 92 | } 93 | 94 | uint16_t app_get_device_status_callback() 95 | { 96 | return 0x0000; 97 | } 98 | 99 | void app_endpoint_halt_callback(uint8_t endpoint, bool halted) 100 | { 101 | 102 | } 103 | 104 | int8_t app_set_interface_callback(uint8_t interface, uint8_t alt_setting) 105 | { 106 | return 0; 107 | } 108 | 109 | int8_t app_get_interface_callback(uint8_t interface) 110 | { 111 | return 0; 112 | } 113 | 114 | void app_out_transaction_callback(uint8_t endpoint) 115 | { 116 | 117 | } 118 | 119 | void app_in_transaction_complete_callback(uint8_t endpoint) 120 | { 121 | 122 | } 123 | 124 | int8_t app_unknown_setup_request_callback(const struct setup_packet *setup) 125 | { 126 | /* To use the HID device class, have a handler for unknown setup 127 | * requests and call process_hid_setup_request() (as shown here), 128 | * which will check if the setup request is HID-related, and will 129 | * call the HID application callbacks defined in usb_hid.h. For 130 | * composite devices containing other device classes, make sure 131 | * MULTI_CLASS_DEVICE is defined in usb_config.h and call all 132 | * appropriate device class setup request functions here. 133 | */ 134 | return process_hid_setup_request(setup); 135 | } 136 | 137 | int16_t app_unknown_get_descriptor_callback(const struct setup_packet *pkt, const void **descriptor) 138 | { 139 | return -1; 140 | } 141 | 142 | void app_start_of_frame_callback(void) 143 | { 144 | 145 | } 146 | 147 | void app_usb_reset_callback(void) 148 | { 149 | 150 | } 151 | 152 | /* HID Callbacks. See usb_hid.h for documentation. */ 153 | 154 | static uint8_t report_buf[3]; 155 | 156 | static int8_t get_report_callback(bool transfer_ok, void *context) 157 | { 158 | /* Nothing to do here really. It either succeeded or failed. If it 159 | * failed, the host will ask for it again. It's nice to be on the 160 | * device side in USB. */ 161 | return 0; 162 | } 163 | 164 | int16_t app_get_report_callback(uint8_t interface, uint8_t report_type, 165 | uint8_t report_id, const void **report, 166 | usb_ep0_data_stage_callback *callback, 167 | void **context) 168 | { 169 | /* This isn't a composite device, so there's no need to check the 170 | * interface here. Also, we know that there's only one report for 171 | * this device, so there's no need to check report_type or report_id. 172 | * 173 | * Set report, callback, and context; and the USB stack will send 174 | * the report, calling our callback (get_report_callback()) when 175 | * it has finished. 176 | */ 177 | *report = report_buf; 178 | *callback = get_report_callback; 179 | *context = NULL; 180 | return sizeof(report_buf); 181 | } 182 | 183 | int8_t app_set_report_callback(uint8_t interface, uint8_t report_type, 184 | uint8_t report_id) 185 | { 186 | /* To handle Set_Report, call usb_start_receive_ep0_data_stage() 187 | * here. See the documentation for HID_SET_REPORT_CALLBACK() in 188 | * usb_hid.h. For this device though, there are no output or 189 | * feature reports. */ 190 | return -1; 191 | } 192 | 193 | uint8_t app_get_idle_callback(uint8_t interface, uint8_t report_id) 194 | { 195 | return 0; 196 | } 197 | 198 | int8_t app_set_idle_callback(uint8_t interface, uint8_t report_id, 199 | uint8_t idle_rate) 200 | { 201 | return -1; 202 | } 203 | 204 | int8_t app_get_protocol_callback(uint8_t interface) 205 | { 206 | return 1; 207 | } 208 | 209 | int8_t app_set_protocol_callback(uint8_t interface, uint8_t report_id) 210 | { 211 | return -1; 212 | } 213 | 214 | 215 | #ifdef _PIC14E 216 | void interrupt isr() 217 | { 218 | usb_service(); 219 | } 220 | #elif _PIC18 221 | 222 | #ifdef __XC8 223 | void interrupt high_priority isr() 224 | { 225 | usb_service(); 226 | } 227 | #elif _PICC18 228 | #error need to make ISR 229 | #endif 230 | 231 | #endif -------------------------------------------------------------------------------- /apps/hid_mouse/usb_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * USB HID Mouse Configuration 3 | * 4 | * This file may be used by anyone for any purpose and may be used as a 5 | * starting point making your own application using M-Stack. 6 | * 7 | * It is worth noting that M-Stack itself is not under the same license 8 | * as this file. 9 | * 10 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. For details, see sections 7, 8, and 9 13 | * of the Apache License, version 2.0 which apply to this file. If you have 14 | * purchased a commercial license for this software from Signal 11 Software, 15 | * your commerical license superceeds the information in this header. 16 | * 17 | * Alan Ott 18 | * Signal 11 Software 19 | * 2013-04-08 20 | */ 21 | 22 | #ifndef USB_CONFIG_H__ 23 | #define USB_CONFIG_H__ 24 | 25 | /* Number of endpoint numbers besides endpoint zero. It's worth noting that 26 | and endpoint NUMBER does not completely describe an endpoint, but the 27 | along with the DIRECTION does (eg: EP 1 IN). The #define below turns on 28 | BOTH IN and OUT endpoints for endpoint numbers (besides zero) up to the 29 | value specified. For example, setting NUM_ENDPOINT_NUMBERS to 2 will 30 | activate endpoints EP 1 IN, EP 1 OUT, EP 2 IN, EP 2 OUT. */ 31 | #define NUM_ENDPOINT_NUMBERS 1 32 | 33 | /* Only 8, 16, 32 and 64 are supported for endpoint zero length. */ 34 | #define EP_0_LEN 8 35 | 36 | #define EP_1_OUT_LEN 8 37 | #define EP_1_IN_LEN 8 38 | 39 | #define NUMBER_OF_CONFIGURATIONS 1 40 | 41 | /* Ping-pong buffering mode. Valid values are: 42 | PPB_NONE - Do not ping-pong any endpoints 43 | PPB_EPO_OUT_ONLY - Ping-pong only endpoint 0 OUT 44 | PPB_ALL - Ping-pong all endpoints 45 | PPB_EPN_ONLY - Ping-pong all endpoints except 0 46 | */ 47 | #ifdef __PIC32MX__ 48 | /* PIC32MX only supports PPB_ALL */ 49 | #define PPB_MODE PPB_ALL 50 | #else 51 | #define PPB_MODE PPB_NONE 52 | #endif 53 | 54 | /* Comment the following line to use polling USB operation. When using polling, 55 | You are responsible for calling usb_service() periodically from your 56 | application. */ 57 | #define USB_USE_INTERRUPTS 58 | 59 | /* Uncomment if you have a composite device which has multiple different types 60 | * of device classes. For example a device which has HID+CDC or 61 | * HID+VendorDefined, but not a device which has multiple of the same class 62 | * (such as HID+HID). Device class implementations have additional requirements 63 | * for multi-class devices. See the documentation for each device class for 64 | * details. */ 65 | //#define MULTI_CLASS_DEVICE 66 | 67 | 68 | /* Objects from usb_descriptors.c */ 69 | #define USB_DEVICE_DESCRIPTOR this_device_descriptor 70 | #define USB_CONFIG_DESCRIPTOR_MAP usb_application_config_descs 71 | #define USB_STRING_DESCRIPTOR_FUNC usb_application_get_string 72 | 73 | /* Optional callbacks from usb.c. Leave them commented if you don't want to 74 | use them. For the prototypes and documentation for each one, see usb.h. */ 75 | 76 | #define SET_CONFIGURATION_CALLBACK app_set_configuration_callback 77 | #define GET_DEVICE_STATUS_CALLBACK app_get_device_status_callback 78 | #define ENDPOINT_HALT_CALLBACK app_endpoint_halt_callback 79 | #define SET_INTERFACE_CALLBACK app_set_interface_callback 80 | #define GET_INTERFACE_CALLBACK app_get_interface_callback 81 | #define OUT_TRANSACTION_CALLBACK app_out_transaction_callback 82 | #define IN_TRANSACTION_COMPLETE_CALLBACK app_in_transaction_complete_callback 83 | #define UNKNOWN_SETUP_REQUEST_CALLBACK app_unknown_setup_request_callback 84 | #define UNKNOWN_GET_DESCRIPTOR_CALLBACK app_unknown_get_descriptor_callback 85 | #define START_OF_FRAME_CALLBACK app_start_of_frame_callback 86 | #define USB_RESET_CALLBACK app_usb_reset_callback 87 | 88 | /* HID Configuration functions. See usb_hid.h for documentation. */ 89 | #define USB_HID_DESCRIPTOR_FUNC usb_application_get_hid_descriptor 90 | #define USB_HID_REPORT_DESCRIPTOR_FUNC usb_application_get_hid_report_descriptor 91 | //#define USB_HID_PHYSICAL_DESCRIPTOR_FUNC usb_application_get_hid_physical_descriptor 92 | 93 | /* HID Callbacks. See usb_hid.h for documentation. */ 94 | #define HID_GET_REPORT_CALLBACK app_get_report_callback 95 | #define HID_SET_REPORT_CALLBACK app_set_report_callback 96 | #define HID_GET_IDLE_CALLBACK app_get_idle_callback 97 | #define HID_SET_IDLE_CALLBACK app_set_idle_callback 98 | #define HID_GET_PROTOCOL_CALLBACK app_get_protocol_callback 99 | #define HID_SET_PROTOCOL_CALLBACK app_set_protocol_callback 100 | 101 | #endif /* USB_CONFIG_H__ */ 102 | -------------------------------------------------------------------------------- /apps/msc_test/.gitignore: -------------------------------------------------------------------------------- 1 | MPLAB.X/nbproject/Makefile-genesis.properties 2 | MPLAB.X/nbproject/Makefile-*.mk 3 | MPLAB.X/nbproject/Package-*.bash 4 | MPLAB.X/nbproject/private/ 5 | MPLAB.X/build/ 6 | MPLAB.X/dist 7 | MPLAB.X/funclist 8 | MPLAB.X/disassembly/ 9 | MPLAB.X/*.obj 10 | -------------------------------------------------------------------------------- /apps/msc_test/MPLAB.X/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # There exist several targets which are by default empty and which can be 3 | # used for execution of your targets. These targets are usually executed 4 | # before and after some main targets. They are: 5 | # 6 | # .build-pre: called before 'build' target 7 | # .build-post: called after 'build' target 8 | # .clean-pre: called before 'clean' target 9 | # .clean-post: called after 'clean' target 10 | # .clobber-pre: called before 'clobber' target 11 | # .clobber-post: called after 'clobber' target 12 | # .all-pre: called before 'all' target 13 | # .all-post: called after 'all' target 14 | # .help-pre: called before 'help' target 15 | # .help-post: called after 'help' target 16 | # 17 | # Targets beginning with '.' are not intended to be called on their own. 18 | # 19 | # Main targets can be executed directly, and they are: 20 | # 21 | # build build a specific configuration 22 | # clean remove built files from a configuration 23 | # clobber remove all built files 24 | # all build all configurations 25 | # help print help mesage 26 | # 27 | # Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and 28 | # .help-impl are implemented in nbproject/makefile-impl.mk. 29 | # 30 | # Available make variables: 31 | # 32 | # CND_BASEDIR base directory for relative paths 33 | # CND_DISTDIR default top distribution directory (build artifacts) 34 | # CND_BUILDDIR default top build directory (object files, ...) 35 | # CONF name of current configuration 36 | # CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration) 37 | # CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration) 38 | # CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration) 39 | # CND_PACKAGE_DIR_${CONF} directory of package (current configuration) 40 | # CND_PACKAGE_NAME_${CONF} name of package (current configuration) 41 | # CND_PACKAGE_PATH_${CONF} path to package (current configuration) 42 | # 43 | # NOCDDL 44 | 45 | 46 | # Environment 47 | MKDIR=mkdir 48 | CP=cp 49 | CCADMIN=CCadmin 50 | RANLIB=ranlib 51 | 52 | 53 | # build 54 | build: .build-post 55 | 56 | .build-pre: 57 | # Add your pre 'build' code here... 58 | 59 | .build-post: .build-impl 60 | # Add your post 'build' code here... 61 | 62 | 63 | # clean 64 | clean: .clean-post 65 | 66 | .clean-pre: 67 | # Add your pre 'clean' code here... 68 | 69 | .clean-post: .clean-impl 70 | # Add your post 'clean' code here... 71 | 72 | 73 | # clobber 74 | clobber: .clobber-post 75 | 76 | .clobber-pre: 77 | # Add your pre 'clobber' code here... 78 | 79 | .clobber-post: .clobber-impl 80 | # Add your post 'clobber' code here... 81 | 82 | 83 | # all 84 | all: .all-post 85 | 86 | .all-pre: 87 | # Add your pre 'all' code here... 88 | 89 | .all-post: .all-impl 90 | # Add your post 'all' code here... 91 | 92 | 93 | # help 94 | help: .help-post 95 | 96 | .help-pre: 97 | # Add your pre 'help' code here... 98 | 99 | .help-post: .help-impl 100 | # Add your post 'help' code here... 101 | 102 | 103 | 104 | # include project implementation makefile 105 | include nbproject/Makefile-impl.mk 106 | 107 | # include project make variables 108 | include nbproject/Makefile-variables.mk 109 | -------------------------------------------------------------------------------- /apps/msc_test/MPLAB.X/nbproject/project.xml: -------------------------------------------------------------------------------- 1 | 2 | com.microchip.mplab.nbide.embedded.makeproject 3 | 4 | 5 | usb_stack_msc_test 6 | d62999b6-148b-4401-bb2b-d1fe2348676c 7 | 0 8 | c 9 | 10 | h 11 | ISO-8859-1 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /apps/msc_test/board.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Board-Related Definitions and Pin Assignments 3 | * 4 | * Copyright (C) 2014 Alan Ott 5 | * Signal 11 Software 6 | * 7 | * 2014-08-08 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation, version 3. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include "board.h" 23 | 24 | void board_setup_spi_pins(void) 25 | { 26 | #ifdef CHIPKIT_MAX32_BOARD 27 | /* Initialization. Make sure to turn off Analog if need be here. */ 28 | TRISGCLR = (1 << 6); 29 | TRISGCLR = (1 << 8); 30 | TRISGCLR = (1 << 1); 31 | TRISGSET = 0x1; 32 | 33 | #elif PIC24_BREADBOARD 34 | /* Set up peripheral pin select (PPS) */ 35 | /* unlock registers */ 36 | __asm(" \n \ 37 | push w1;\n \ 38 | push w2;\n \ 39 | push w3;\n \ 40 | mov #OSCCON, w1;\n \ 41 | mov #0x46, w2;\n \ 42 | mov #0x57, w3;\n \ 43 | mov.b w2, [w1];\n \ 44 | mov.b w3, [w1];\n \ 45 | bclr OSCCON, #6;\n"); 46 | 47 | #define SCK_PIN _RP15R /* OUT */ 48 | #define SDI_PIN 14 /* IN */ 49 | #define SDO_PIN _RP13R /* OUT */ 50 | #define INT_PIN 8 /* IN */ 51 | 52 | /* Outputs (Table 10-3 in the datasheet (Selectable Output Sources)) */ 53 | SCK_PIN = 8; /* 8 = SCK1OUT (table 10-3) */ 54 | SDO_PIN = 7; /* 7 = SDO1 (table 10-3) */ 55 | 56 | /* Inputs (Table 10-2 in the datasheet (Selectable Input Sources)) */ 57 | _SDI1R = SDI_PIN; 58 | 59 | /* lock registers */ 60 | __asm("\n \ 61 | mov #OSCCON, w1;\n \ 62 | mov #0x46, w2;\n \ 63 | mov #0x57, w3;\n \ 64 | mov.b w2, [w1];\n \ 65 | mov.b w3, [w1];\n \ 66 | bset OSCCON, #6;\n \ 67 | pop w3;\n \ 68 | pop w2;\n \ 69 | pop w1;\n"); 70 | 71 | SET_ANALOG_CONFIG(); 72 | 73 | SPI_CS_PIN = 1; 74 | SPI_CS_TRIS = 0; /* 0 = OUTPUT */ 75 | CD_TRIS = 1; /* 1 = INPUT */ 76 | 77 | /* Enable the pull-up on the card-detect pin. Pull-ups are indexed 78 | * by their change-notification number. */ 79 | CD_CN = 1; 80 | 81 | #elif PIC18F_STARTER_KIT 82 | /* Set appropriate pins to be digital instead of analog. */ 83 | ANCON1bits.PCFG9 = 1; /* RB3 and AN9 share a pin */ 84 | ANCON1bits.PCFG11 = 1; /* RC2 and AN11 share a pin */ 85 | 86 | /* Set up the tri-state registers */ 87 | TRISDbits.TRISD6 = 1; /* RD6 (SDI) is input */ 88 | TRISBbits.TRISB3 = 0; /* RB3 (SDO) is output */ 89 | TRISCbits.TRISC2 = 0; /* RC2 (SCK) is output */ 90 | TRISCbits.TRISC6 = 0; /* RC6 (CS) is output */ 91 | 92 | /* Set the peripheral PIN Select to put the SPI peripheral on the 93 | * appropriate pins. */ 94 | INTCONbits.GIE = 0; 95 | EECON2 = 0x55; 96 | EECON2 = 0xAA; 97 | PPSCONbits.IOLOCK = 0; 98 | 99 | /* Set the Inputs. PIC18F46J50 Datasheet sec 10.7.3.1, Table 10-13 */ 100 | RPINR21 = 23; /* Put SDI on RD6 which is RP23 */ 101 | 102 | /* Set the Outputs. PIC18F46J50 Datasheet sec 10.7.3.1, Table 10-14 */ 103 | RPOR6 = 9; /* Put SDO on RB3 which is RP6 */ 104 | RPOR13 = 10; /* Put SCK on RC2 which is RP13 */ 105 | /* CS is on RC6 (RP17), but since it's handled manually there's 106 | * no need to do anything here. */ 107 | 108 | EECON2 = 0x55; 109 | EECON2 = 0xAA; 110 | PPSCONbits.IOLOCK = 1; 111 | INTCONbits.GIE = 1; 112 | #else 113 | #error "Board not supported. Add a section in board_setup_spi_pins() for your board here." 114 | #endif 115 | } 116 | -------------------------------------------------------------------------------- /apps/msc_test/board.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Board-Related Definitions and Pin Assignments 3 | * 4 | * Copyright (C) 2014 Alan Ott 5 | * Signal 11 Software 6 | * 7 | * 2014-05-31 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation, version 3. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #ifndef BOARD_H__ 23 | #define BOARD_H__ 24 | 25 | #include 26 | 27 | /* SPI Board definitions for Supported demo boards */ 28 | 29 | #ifdef CHIPKIT_MAX32_BOARD 30 | 31 | /* Definitions for spi.c */ 32 | #define SPI_ASSERT_CS() LATGCLR = (1<<1) 33 | #define SPI_RELEASE_CS() LATGSET = (1<<1) 34 | #define SPI_MMC_CARD_PRESENT() (!(PORTG & 0x1)) 35 | 36 | #define OSCILLATOR_HZ 60000000 37 | 38 | /* SPI Registers. The demo uses SPI2, but this can easily be changed 39 | * to use other SPI controllers. */ 40 | #define SPInCONCLR SPI2CONCLR 41 | #define SPInCONSET SPI2CONSET 42 | #define SPInSTAT SPI2STAT 43 | #define SPInSTATCLR SPI2STATCLR 44 | #define SPInSTATSET SPI2STATSET 45 | #define SPInBRG SPI2BRG 46 | #define SPInBUF SPI2BUF 47 | 48 | #elif PIC24_BREADBOARD 49 | #define SPI_CS_PIN PORTBbits.RB9 50 | #define SPI_CS_TRIS TRISBbits.TRISB9 51 | #define CD_TRIS TRISBbits.TRISB8 52 | #define CD_PIN PORTBbits.RB8 53 | #define CD_CN CNPU2bits.CN22PUE /* Change-notification address for CD pin */ 54 | #define SET_ANALOG_CONFIG() do { AD1PCFG |= 0xe00 ; } while(0) 55 | 56 | /* SPI Registers. The demo uses SPI1, but this can easily be changed 57 | * to use other SPI controllers. */ 58 | #define SPInCON1bits SPI1CON1bits 59 | #define SPInCON2bits SPI1CON2bits 60 | #define SPInSTATbits SPI1STATbits 61 | #define SPInBUF SPI1BUF 62 | #define SPInIF IFS0bits.SPI1IF 63 | 64 | /* Definitions for spi.c */ 65 | #define SPI_ASSERT_CS() SPI_CS_PIN = 0 66 | #define SPI_RELEASE_CS() SPI_CS_PIN = 1 67 | #define SPI_MMC_CARD_PRESENT() (!CD_PIN) 68 | 69 | #define OSCILLATOR_HZ 32000000 70 | 71 | #elif PIC18F_STARTER_KIT 72 | 73 | /* Definitions for spi.c */ 74 | #define SPI_ASSERT_CS() LATCbits.LATC6 = 0 75 | #define SPI_RELEASE_CS() LATCbits.LATC6 = 1 76 | #define SPI_MMC_CARD_PRESENT() (1) /* PIC18F Starter Kit has no card detect */ 77 | 78 | #define OSCILLATOR_HZ 48000000 79 | 80 | /* SPI Registers. This board must use SPI2, as the board is wired 81 | * with the MMC socket on remappable pins and SPI2 is connected to 82 | * the remappable pins. */ 83 | #define SSPnSTATbits SSP2STATbits 84 | #define SSPnCON1bits SSP2CON1bits 85 | #define SSPnBUF SSP2BUF 86 | #define SSPnIF PIR3bits.SSP2IF 87 | 88 | #else 89 | #error "Board not supported. Add a section and definitions for your board here." 90 | #endif 91 | 92 | /* Board-specific SPI pin setup */ 93 | void board_setup_spi_pins(void); 94 | 95 | #endif /* BOARD_H__ */ 96 | -------------------------------------------------------------------------------- /apps/msc_test/mmc_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Sample MMC Configuration 3 | * 4 | * This file may be used by anyone for any purpose and may be used as a 5 | * starting point making your own application using M-Stack. 6 | * 7 | * It is worth noting that M-Stack itself is not under the same license 8 | * as this file. 9 | * 10 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. For details, see sections 7, 8, and 9 13 | * of the Apache License, version 2.0 which apply to this file. If you have 14 | * purchased a commercial license for this software from Signal 11 Software, 15 | * your commerical license superceeds the information in this header. 16 | * 17 | * Alan Ott 18 | * Signal 11 Software 19 | * 2014-07-17 20 | */ 21 | 22 | #ifndef MMC_CONFIG_H__ 23 | #define MMC_CONFIG_H__ 24 | 25 | /* Callbacks from mmc.h */ 26 | #define MMC_SPI_TRANSFER app_spi_transfer 27 | #define MMC_SPI_SET_SPEED app_spi_set_speed 28 | #define MMC_SPI_SET_CS app_spi_set_cs 29 | 30 | #define MMC_USE_TIMER 31 | #define MMC_TIMER_START app_timer_start 32 | #define MMC_TIMER_EXPIRED app_timer_expired 33 | #define MMC_TIMER_STOP app_timer_stop 34 | 35 | #endif /* MMC_CONFIG_H__ */ 36 | -------------------------------------------------------------------------------- /apps/msc_test/spi.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPI driver for PIC16F1459 and PIC24FJ32GB002 3 | * 4 | * Copyright (C) 2013 Alan Ott 5 | * Signal 11 Software 6 | * 7 | * 2013-02-08 8 | * 9 | * M-Stack is free software: you can redistribute it and/or modify it under 10 | * the terms of the GNU Lesser General Public License as published by the 11 | * Free Software Foundation, version 3; or the Apache License, version 2.0 12 | * as published by the Apache Software Foundation. If you have purchased a 13 | * commercial license for this software from Signal 11 Software, your 14 | * commerical license superceeds the information in this header. 15 | * 16 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 17 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 18 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 19 | * License for more details. 20 | * 21 | * You should have received a copy of the GNU Lesser General Public License 22 | * along with this software. If not, see . 23 | * 24 | * You should have received a copy of the Apache License, verion 2.0 along 25 | * with this software. If not, see . 26 | */ 27 | 28 | #include "board.h" 29 | #include "spi.h" 30 | 31 | #if defined(__XC8) || defined (__XC16__) || defined (__XC32__) 32 | #include 33 | #else 34 | #error "Compiler not supported" 35 | #endif 36 | 37 | #define MIN(x,y) (((x)<(y))?(x):(y)) 38 | 39 | /* The device uses mode 0,0. SDI/SDO leads SCK, and SCK is idle LOW. 40 | CKP = 0, CKE = 1 */ 41 | 42 | void spi_init(void) 43 | { 44 | #ifdef _PIC18 45 | board_setup_spi_pins(); 46 | 47 | SSPnSTATbits.CKE = 1; /* SPI Mode (edge) */ 48 | 49 | SSPnCON1bits.CKP = 0; /* SPI Mode (polarity) */ 50 | spi_set_speed_hz(40000); 51 | SSPnCON1bits.WCOL = 0; /* Clear write-collision */ 52 | 53 | SSPnCON1bits.SSPEN = 1; /* Enable SSP Module */ 54 | 55 | #elif __XC16__ 56 | board_setup_spi_pins(); 57 | 58 | SPInCON1bits.CKE = 1; /* Data is valid before clock edge on SCK */ 59 | SPInCON1bits.SSEN = 0; /* Slave Select (chip select) is manual (GPIO) */ 60 | SPInCON1bits.MSTEN = 1; /* 1= SPIn is master mode. */ 61 | 62 | SPInCON2bits.FRMEN = 0; /* Framed support is disabled (do it manually)*/ 63 | SPInCON2bits.SPIBEN = 0; /* Enhanced Buffer Disabled */ 64 | 65 | SPInSTATbits.SPIROV = 0; /* Clear overflow indication */ 66 | SPInSTATbits.SPIEN = 1; /* Enable SPI operation */ 67 | spi_set_speed_hz(40000); 68 | 69 | #elif __PIC32MX__ 70 | board_setup_spi_pins(); 71 | 72 | SPInCONCLR = _SPI1CON_ON_MASK; 73 | SPInCONCLR = _SPI1CON_ENHBUF_MASK; 74 | spi_set_speed_hz(40000); 75 | SPInSTATCLR = _SPI1STAT_SPIROV_MASK; 76 | SPInCONSET = _SPI1CON_CKE_MASK |_SPI1CON_MSTEN_MASK | _SPI1CON_SMP_MASK; 77 | SPInCONSET = _SPI1CON_ON_MASK; 78 | #else 79 | #error "Processor family not supported" 80 | #endif 81 | } 82 | 83 | void spi_set_speed_hz(uint32_t speed_hz) 84 | { 85 | #ifdef _PIC18 86 | /* On the PIC18, there are 4 speeds at which the SPI module 87 | * can operate, Fosc/4, Fosc/16, Fosc/64, and using TMR2. */ 88 | T2CONbits.TMR2ON = 0; 89 | if (speed_hz >= OSCILLATOR_HZ / 4) 90 | SSPnCON1bits.SSPM = 0b0000; /* SPI Master, Clock = Fosc/4 */ 91 | else if (speed_hz >= OSCILLATOR_HZ / 16) 92 | SSPnCON1bits.SSPM = 0b0001; /* SPI Master, Clock = Fosc/16 */ 93 | else if (speed_hz >= OSCILLATOR_HZ / 64) 94 | SSPnCON1bits.SSPM = 0b0010; /* SPI Master, Clock = Fosc/64 */ 95 | else { 96 | /* Use Timer2 for the SPI timing. 97 | * 98 | * When using Timer2, the SPI clock will run at the frequency 99 | * of TMR2/2. With a 1:16 pre-scalar, the frequency of TMR2 100 | * is determined as: 101 | * 102 | * TMR2 = Fosc / 4 / 16 / PR2 103 | * 104 | * The SPI peripheral will run at (in Hz): 105 | * 106 | * SPI_SPEED = TMR2 / 2 107 | * 108 | * Combining and solving for PR2, we get: 109 | * PR2 = Fosc / (SPI_SPEED * 128) 110 | * 111 | * Take the ceiling value of the above equation. That way if the 112 | * division doesn't come out even, we end up below the target 113 | * frequency rather than above it. 114 | * 115 | * Note that on an 8-bit processor with no hardware divider, 116 | * doing this 32-bit math is going to be really slow. 117 | * Fortunately it isn't done very often. 118 | */ 119 | 120 | T2CONbits.T2CKPS = 0b10; /* Timer2 Prescale to 1:16 */ 121 | PR2 = OSCILLATOR_HZ / (speed_hz * 128); 122 | 123 | /* Take the ceiling */ 124 | if (OSCILLATOR_HZ % (speed_hz * 128)) 125 | PR2++; 126 | T2CONbits.TMR2ON = 1; 127 | } 128 | 129 | #elif __PIC24F__ 130 | const uint8_t pri_scalars[] = { 1, 4, 16, 64 }; 131 | uint8_t p, s; 132 | 133 | /* Find the scalar combination that best matches, looping over the 134 | * secondary scalars first (since there are more of them and they 135 | * are closer together). Break at the first one which is under the 136 | * target frequency. 137 | * 138 | * Valid secondary scalar values go from 1 to 8, while primary scalar 139 | * values are shown in pri_scalars[]. */ 140 | for (p = 0; p < sizeof(pri_scalars); p++) { 141 | for (s = 1; s < 8; s++) { 142 | uint32_t fsck = ((uint32_t)OSCILLATOR_HZ / 2) / 143 | (pri_scalars[p] * s); 144 | if (fsck < speed_hz) 145 | goto loops_break; 146 | } 147 | } 148 | 149 | loops_break: 150 | 151 | /* For some reason (as stated in the family reference manual), it 152 | * is invalid to have both the prescalar and the postscalar be set 153 | * to 1:1. */ 154 | if (p == 0 && s == 1) 155 | s = 2; 156 | 157 | /* Pass the bitwise-negation of the scalars to SPInCON1. The SPI 158 | * module must be disabled to change the scalars. */ 159 | SPInSTATbits.SPIEN = 0; /* Disable SPI */ 160 | SPInCON1bits.SPRE = ~(s - 1) & 0x7; /* Values 1-8 are encoded as 0-7 */ 161 | SPInCON1bits.PPRE = ~p & 0x3; 162 | SPInSTATbits.SPIEN = 1; /* Enable SPI */ 163 | 164 | #elif __PIC32MX__ 165 | /* On the PIC32, as configured by spi_init() above, the SPI clock 166 | * frequency is calculated as: 167 | * SPIBRG = [Fpb / (Fsck * 2)] - 1 168 | * where: 169 | * Fpb = The peripheral bus frequency, 170 | * in this case the main clock. 171 | * Fsck = The desired SPI clock frequency. 172 | * 173 | * Take the ceiling value of the above equation. That way if the 174 | * division doesn't come out even, we end up below the target 175 | * frequency rather than above it. 176 | */ 177 | 178 | uint32_t brg_val = OSCILLATOR_HZ / (speed_hz * 2) - 1; 179 | 180 | /* Take the ceiling */ 181 | if (OSCILLATOR_HZ % (speed_hz * 2)) 182 | brg_val++; 183 | 184 | SPInBRG = brg_val; 185 | 186 | #else 187 | #error "Processor family not supported" 188 | #endif 189 | } 190 | 191 | 192 | static inline uint8_t spi_transfer(uint8_t out) 193 | { 194 | #ifdef _PIC18 195 | SSPnIF = 0; 196 | 197 | SSPnBUF = out; 198 | Nop(); 199 | Nop(); 200 | while (!SSPnIF && !SSPnSTATbits.BF) 201 | ; 202 | return SSPnBUF; 203 | #elif __XC16__ 204 | SPInBUF = out; 205 | Nop(); 206 | Nop(); 207 | while (!SPInIF) 208 | ; 209 | SPInIF = 0; 210 | return SPInBUF; 211 | #elif __PIC32MX__ 212 | uint32_t read_byte; 213 | while (SPInSTAT & _SPI1STAT_SPIRBF_MASK) 214 | read_byte = SPInBUF; 215 | SPInBUF = out; 216 | Nop(); 217 | Nop(); 218 | while (SPInSTAT & _SPI1STAT_SPIBUSY_MASK) 219 | ; 220 | 221 | /* Wait until the RX Buffer has data. This happens a few instructions 222 | * after the SPIBUSY mask gets cleared. */ 223 | while (!(SPInSTAT & _SPI1STAT_SPIRBF_MASK)) 224 | ; 225 | read_byte = SPInBUF; 226 | 227 | return read_byte & 0xff; 228 | #else 229 | #error "Processor family not supported" 230 | #endif 231 | } 232 | 233 | int8_t spi_transfer_block(const uint8_t *out_buf, uint8_t *in_buf, uint16_t len) 234 | { 235 | uint16_t i; 236 | 237 | if (in_buf && out_buf) { 238 | for (i = 0; i < len; i++) { 239 | in_buf[i] = spi_transfer(out_buf[i]); 240 | } 241 | } 242 | else if (!in_buf && out_buf) { 243 | for (i = 0; i < len; i++) { 244 | spi_transfer(out_buf[i]); 245 | } 246 | } 247 | else if (in_buf && !out_buf) { 248 | for (i = 0; i < len; i++) { 249 | in_buf[i] = spi_transfer(0xff); 250 | } 251 | } 252 | else if (!in_buf && !out_buf) { 253 | /* No in or out buffer; just move the clock line. */ 254 | for (i = 0; i < len; i++) { 255 | spi_transfer(0xff); 256 | } 257 | } 258 | 259 | return 0; 260 | } 261 | -------------------------------------------------------------------------------- /apps/msc_test/spi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPI driver for PIC18, PIC24, and PIC32MX 3 | * 4 | * Copyright (C) 2013 Alan Ott 5 | * Signal 11 Software 6 | * 7 | * 2013-02-08 8 | * 9 | * M-Stack is free software: you can redistribute it and/or modify it under 10 | * the terms of the GNU Lesser General Public License as published by the 11 | * Free Software Foundation, version 3; or the Apache License, version 2.0 12 | * as published by the Apache Software Foundation. If you have purchased a 13 | * commercial license for this software from Signal 11 Software, your 14 | * commerical license superceeds the information in this header. 15 | * 16 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 17 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 18 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 19 | * License for more details. 20 | * 21 | * You should have received a copy of the GNU Lesser General Public License 22 | * along with this software. If not, see . 23 | * 24 | * You should have received a copy of the Apache License, verion 2.0 along 25 | * with this software. If not, see . 26 | */ 27 | 28 | #ifndef S11_PIC_SPI_H__ 29 | #define S11_PIC_SPI_H__ 30 | 31 | #include 32 | #include 33 | #include "board.h" 34 | 35 | /* SPI Interface for MMC 36 | * 37 | * This is an SPI interface intended to be the back-end for the MMC component. 38 | * It is not a generic SPI implementation. To create such an implementation 39 | * is beyond the scope of M-Stack. Further, a generic implementation of SPI 40 | * would require more code space than would be acceptable on some of the 41 | * smaller supported microcontrollers (namely the 8-bit PICs). 42 | * 43 | * Thus, this implementation really only exists to serve the supported boards 44 | * in their specific configurations. However, modification for a custom board 45 | * should be easy and straight forward. 46 | * 47 | * This SPI interface is configured from board.h, which contains definitions 48 | * specific to the supported boards. 49 | */ 50 | 51 | /* Set the chip select line, 0 for low and 1 for high. This SPI implementation 52 | * is active-low, and that's how the MMC component will call this function. */ 53 | #define spi_set_cs_line(value/*0=low,1=high*/) \ 54 | do { \ 55 | if (value) { \ 56 | SPI_RELEASE_CS(); \ 57 | } \ 58 | else { \ 59 | SPI_ASSERT_CS(); \ 60 | } \ 61 | } while(0); 62 | 63 | /* Initialize the SPI interface. */ 64 | void spi_init(void); 65 | 66 | /* Set the SPI speed. In the common case where the speed cannot be matched 67 | * exactly, the closest speed below the target speed will be selected. */ 68 | void spi_set_speed_hz(uint32_t speed_hz); 69 | 70 | /* Perform a bi-directional transfer of data over the SPI interface. The 71 | * parameters in_buf and out_buf can either or both be NULL if data is not 72 | * required to be sent in the respective direction. This is common in the 73 | * MMC card protocol. Also common in the MMC protocol is where out_buf and 74 | * in_buf are both NULL, which will send 0xff and ignore the input. */ 75 | int8_t spi_transfer_block(const uint8_t *out_buf, uint8_t *in_buf, uint16_t len); 76 | 77 | #endif /* S11_PIC_SPI_H__ */ 78 | -------------------------------------------------------------------------------- /apps/msc_test/timer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Timer driver for PIC32 and PIC24 3 | * 4 | * Copyright (C) 2013 Alan Ott 5 | * Signal 11 Software 6 | * 7 | * 2015-04-17 8 | * 9 | * M-Stack is free software: you can redistribute it and/or modify it under 10 | * the terms of the GNU Lesser General Public License as published by the 11 | * Free Software Foundation, version 3; or the Apache License, version 2.0 12 | * as published by the Apache Software Foundation. If you have purchased a 13 | * commercial license for this software from Signal 11 Software, your 14 | * commerical license superceeds the information in this header. 15 | * 16 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 17 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 18 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 19 | * License for more details. 20 | * 21 | * You should have received a copy of the GNU Lesser General Public License 22 | * along with this software. If not, see . 23 | * 24 | * You should have received a copy of the Apache License, verion 2.0 along 25 | * with this software. If not, see . 26 | */ 27 | 28 | #include "board.h" 29 | #include "timer.h" 30 | 31 | #if defined(__XC8) || defined (__XC16__) || defined (__XC32__) 32 | #include 33 | #else 34 | #error "Compiler not supported" 35 | #endif 36 | 37 | void timer_start(uint16_t timeout_milliseconds) 38 | { 39 | #ifdef _PIC18 40 | uint16_t timeout = OSCILLATOR_HZ / 4 / 41 | 256 / 1000 * timeout_milliseconds; 42 | 43 | /* Timer sets TMR0IF at overflow, so TMR0 needs to be set to the 44 | * number of ticks _before_ overflow. */ 45 | timeout = 65535 - timeout + 1; 46 | 47 | INTCONbits.TMR0IF = 0; /* Turn off the interrupt flag */ 48 | T0CONbits.TMR0ON = 0; /* 0 = timer off */ 49 | T0CONbits.T08BIT = 0; /* 0 = 16-bit timer */ 50 | T0CONbits.T0CS = 0; /* clock select: 0 = Fosc/4 */ 51 | T0CONbits.PSA = 0; /* 0 = use prescaler */ 52 | T0CONbits.T0PS= 7; /* 7 = 1:256 prescaler */ 53 | TMR0H = timeout >> 8 & 0xff; 54 | TMR0L = timeout & 0xff; 55 | T0CONbits.TMR0ON = 1; /* timer on */ 56 | 57 | #elif __XC16__ 58 | uint16_t timeout = OSCILLATOR_HZ / 2 / 59 | 256 / 1000 * timeout_milliseconds; 60 | IFS0bits.T1IF = 0; /* Turn off the interrupt flag */ 61 | TMR1 = 0; 62 | T1CONbits.TON = 1; 63 | T1CONbits.TCKPS = 3; /* Prescalar: 3 = 1:256 */ 64 | PR1 = timeout; 65 | 66 | #elif __PIC32MX__ 67 | uint8_t divisor = 1 << OSCCONbits.PBDIV; 68 | uint32_t peripheral_clock = OSCILLATOR_HZ / divisor; 69 | uint32_t timeout = peripheral_clock / 256 / 1000 * timeout_milliseconds; 70 | 71 | /* Use timers 2 and 3 combined to get a 32-bit timer. In this mode 72 | * TMR2 gets the configuration values and the interrupt flag will 73 | * come on TMR3. */ 74 | IFS0bits.T3IF = 0; /* Turn off the interrupt flag */ 75 | TMR2 = 0; 76 | TMR3 = 0; 77 | T2CONbits.T32 = 1; /* 1 = 32-bit timer combining T2 and T3 */ 78 | T2CONbits.TCKPS = 7; /* Prescalar: 7 = 1:256 */ 79 | PR2 = timeout & 0xffff; 80 | PR3 = timeout >> 16 & 0xffff; 81 | T2CONbits.ON = 1; 82 | 83 | #else 84 | #error "Processor family not supported" 85 | 86 | #endif 87 | } 88 | 89 | bool timer_expired(void) 90 | { 91 | #ifdef _PIC18 92 | return (INTCONbits.TMR0IF != 0); 93 | 94 | #elif __XC16__ 95 | return (IFS0bits.T1IF != 0); 96 | 97 | #elif __PIC32MX__ 98 | return (IFS0bits.T3IF != 0); 99 | 100 | #else 101 | #error "Processor family not supported" 102 | #endif 103 | } 104 | 105 | void timer_stop(void) 106 | { 107 | #ifdef _PIC18 108 | T0CONbits.TMR0ON = 0; 109 | 110 | #elif __XC16__ 111 | T1CONbits.TON = 0; 112 | 113 | #elif __PIC32MX__ 114 | T2CONbits.ON = 0; 115 | 116 | #else 117 | #error "Processor family not supported" 118 | #endif 119 | } 120 | -------------------------------------------------------------------------------- /apps/msc_test/timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPI driver for PIC18, PIC24, and PIC32MX 3 | * 4 | * Copyright (C) 2013 Alan Ott 5 | * Signal 11 Software 6 | * 7 | * 2015-04-17 8 | * 9 | * M-Stack is free software: you can redistribute it and/or modify it under 10 | * the terms of the GNU Lesser General Public License as published by the 11 | * Free Software Foundation, version 3; or the Apache License, version 2.0 12 | * as published by the Apache Software Foundation. If you have purchased a 13 | * commercial license for this software from Signal 11 Software, your 14 | * commerical license superceeds the information in this header. 15 | * 16 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 17 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 18 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 19 | * License for more details. 20 | * 21 | * You should have received a copy of the GNU Lesser General Public License 22 | * along with this software. If not, see . 23 | * 24 | * You should have received a copy of the Apache License, verion 2.0 along 25 | * with this software. If not, see . 26 | */ 27 | 28 | #ifndef S11_PIC_TIMER_H__ 29 | #define S11_PIC_TIMER_H__ 30 | 31 | #include 32 | #include 33 | #include "board.h" 34 | 35 | /* Basic Timer Implementation for MMC 36 | * 37 | * This is a simple timer implementation intended to be used for the 38 | * timeouts in the MMC component. It has millisecond resolution. 39 | * 40 | * This timer interface intended to be the back-end for the MMC component. 41 | * It is not a generic timer implementation. To create such an implementation 42 | * is beyond the scope of M-Stack. Further, a more generic implementation 43 | * would require more code space than would be acceptable on some of the 44 | * smaller supported microcontrollers (namely the 8-bit PICs). 45 | * 46 | * Thus, this implementation really only exists to serve the supported boards 47 | * in their specific configurations. However, modification for a custom 48 | * project should be easy and straight forward. 49 | * 50 | * The following hardware timer resources are used: 51 | * PIC18: Timer 1 is used (16-bit timer) 52 | * PIC24: Timer 1 is used (16-bit timer) 53 | * PIC32: Timers 2 and 3 are combined to form a 32-bit timer 54 | * 55 | * The following are the maximum supported timeouts: 56 | * PIC18: 2^16 / (OSCILLATOR_HZ / 4 / 256) seconds 57 | * PIC24: 2^16 / (OSCILLATOR_HZ / 2 / 256) seconds 58 | * PIC32: 2^32 / (OSCILLATOR_HZ / peripheral_clock_divisor / 256) seconds 59 | * 60 | * On all architectures, this timer is good for at least 1 second, which is 61 | * what is necessary for the MMC implementation. 62 | * 63 | * This timer interface is configured from board.h, which contains definitions 64 | * specific to the supported boards. 65 | */ 66 | 67 | /* Start the timer and set it to expire in timeout_milliseconds */ 68 | void timer_start(uint16_t timeout_milliseconds); 69 | 70 | /* Return true if the timer has expired or false if it has not */ 71 | bool timer_expired(void); 72 | 73 | /* Stop the timer from running */ 74 | void timer_stop(void); 75 | 76 | #endif /* S11_PIC_TIMER_H__ */ 77 | -------------------------------------------------------------------------------- /apps/msc_test/usb_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Sample USB Configuration 3 | * 4 | * This file may be used by anyone for any purpose and may be used as a 5 | * starting point making your own application using M-Stack. 6 | * 7 | * It is worth noting that M-Stack itself is not under the same license 8 | * as this file. 9 | * 10 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. For details, see sections 7, 8, and 9 13 | * of the Apache License, version 2.0 which apply to this file. If you have 14 | * purchased a commercial license for this software from Signal 11 Software, 15 | * your commerical license superceeds the information in this header. 16 | * 17 | * Alan Ott 18 | * Signal 11 Software 19 | * 2013-04-08 20 | */ 21 | 22 | #ifndef USB_CONFIG_H__ 23 | #define USB_CONFIG_H__ 24 | 25 | /* Number of endpoint numbers besides endpoint zero. It's worth noting that 26 | and endpoint NUMBER does not completely describe an endpoint, but the 27 | along with the DIRECTION does (eg: EP 1 IN). The #define below turns on 28 | BOTH IN and OUT endpoints for endpoint numbers (besides zero) up to the 29 | value specified. For example, setting NUM_ENDPOINT_NUMBERS to 2 will 30 | activate endpoints EP 1 IN, EP 1 OUT, EP 2 IN, EP 2 OUT. */ 31 | #define NUM_ENDPOINT_NUMBERS 1 32 | 33 | /* Only 8, 16, 32 and 64 are supported for endpoint zero length. */ 34 | #define EP_0_LEN 8 35 | 36 | #define EP_1_OUT_LEN 64 37 | #define EP_1_IN_LEN 64 38 | 39 | #define NUMBER_OF_CONFIGURATIONS 1 40 | 41 | /* Ping-pong buffering mode. Valid values are: 42 | PPB_NONE - Do not ping-pong any endpoints 43 | PPB_EPO_OUT_ONLY - Ping-pong only endpoint 0 OUT 44 | PPB_ALL - Ping-pong all endpoints 45 | PPB_EPN_ONLY - Ping-pong all endpoints except 0 46 | */ 47 | #ifdef __PIC32MX__ 48 | /* PIC32MX only supports PPB_ALL */ 49 | #define PPB_MODE PPB_ALL 50 | #else 51 | #define PPB_MODE PPB_NONE 52 | #endif 53 | 54 | /* Comment the following line to use polling USB operation. When using polling, 55 | You are responsible for calling usb_service() periodically from your 56 | application. */ 57 | #define USB_USE_INTERRUPTS 58 | 59 | /* Objects from usb_descriptors.c */ 60 | #define USB_DEVICE_DESCRIPTOR this_device_descriptor 61 | #define USB_CONFIG_DESCRIPTOR_MAP usb_application_config_descs 62 | #define USB_STRING_DESCRIPTOR_FUNC usb_application_get_string 63 | 64 | /* Optional callbacks from usb.c. Leave them commented if you don't want to 65 | use them. For the prototypes and documentation for each one, see usb.h. */ 66 | 67 | #define SET_CONFIGURATION_CALLBACK app_set_configuration_callback 68 | #define GET_DEVICE_STATUS_CALLBACK app_get_device_status_callback 69 | #define ENDPOINT_HALT_CALLBACK app_endpoint_halt_callback 70 | #define SET_INTERFACE_CALLBACK app_set_interface_callback 71 | #define GET_INTERFACE_CALLBACK app_get_interface_callback 72 | #define OUT_TRANSACTION_CALLBACK app_out_transaction_callback 73 | #define IN_TRANSACTION_COMPLETE_CALLBACK app_in_transaction_complete_callback 74 | #define UNKNOWN_SETUP_REQUEST_CALLBACK app_unknown_setup_request_callback 75 | #define UNKNOWN_GET_DESCRIPTOR_CALLBACK app_unknown_get_descriptor_callback 76 | #define START_OF_FRAME_CALLBACK app_start_of_frame_callback 77 | #define USB_RESET_CALLBACK app_usb_reset_callback 78 | 79 | /* Configuration from the MSC Class (usb_msc.h) */ 80 | #define MSC_MAX_LUNS_PER_INTERFACE 1 81 | //#define MSC_SUPPORT_MULTIPLE_MSC_INTERFACES 82 | #define MSC_WRITE_SUPPORT 83 | 84 | /* Callbacks from the MSC class (usb_msc.h) */ 85 | #define MSC_GET_MAX_LUN_CALLBACK app_get_max_lun 86 | #define MSC_BULK_ONLY_MASS_STORAGE_RESET_CALLBACK app_msc_reset 87 | #define MSC_GET_STORAGE_INFORMATION app_get_storage_info 88 | #define MSC_UNIT_READY app_get_unit_ready 89 | #define MSC_START_STOP_UNIT app_start_stop_unit 90 | #define MSC_START_READ app_msc_start_read 91 | #define MSC_START_WRITE app_msc_start_write 92 | 93 | /* Application callbacks, not used by the MSC class or USB stack, but used 94 | * for the application. */ 95 | #define APP_MSC_INTERFACE 0 96 | #define APP_MSC_IN_ENDPOINT 1 97 | #define APP_MSC_OUT_ENDPOINT 1 98 | 99 | #endif /* USB_CONFIG_H__ */ 100 | -------------------------------------------------------------------------------- /apps/unit_test/.gitignore: -------------------------------------------------------------------------------- 1 | MPLAB.X/nbproject/Makefile-genesis.properties 2 | MPLAB.X/nbproject/Makefile-*.mk 3 | MPLAB.X/nbproject/Package-*.bash 4 | MPLAB.X/nbproject/private/ 5 | MPLAB.X/build/ 6 | MPLAB.X/dist 7 | MPLAB.X/funclist 8 | MPLAB.X/disassembly/ 9 | -------------------------------------------------------------------------------- /apps/unit_test/MPLAB.X/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # There exist several targets which are by default empty and which can be 3 | # used for execution of your targets. These targets are usually executed 4 | # before and after some main targets. They are: 5 | # 6 | # .build-pre: called before 'build' target 7 | # .build-post: called after 'build' target 8 | # .clean-pre: called before 'clean' target 9 | # .clean-post: called after 'clean' target 10 | # .clobber-pre: called before 'clobber' target 11 | # .clobber-post: called after 'clobber' target 12 | # .all-pre: called before 'all' target 13 | # .all-post: called after 'all' target 14 | # .help-pre: called before 'help' target 15 | # .help-post: called after 'help' target 16 | # 17 | # Targets beginning with '.' are not intended to be called on their own. 18 | # 19 | # Main targets can be executed directly, and they are: 20 | # 21 | # build build a specific configuration 22 | # clean remove built files from a configuration 23 | # clobber remove all built files 24 | # all build all configurations 25 | # help print help mesage 26 | # 27 | # Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and 28 | # .help-impl are implemented in nbproject/makefile-impl.mk. 29 | # 30 | # Available make variables: 31 | # 32 | # CND_BASEDIR base directory for relative paths 33 | # CND_DISTDIR default top distribution directory (build artifacts) 34 | # CND_BUILDDIR default top build directory (object files, ...) 35 | # CONF name of current configuration 36 | # CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration) 37 | # CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration) 38 | # CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration) 39 | # CND_PACKAGE_DIR_${CONF} directory of package (current configuration) 40 | # CND_PACKAGE_NAME_${CONF} name of package (current configuration) 41 | # CND_PACKAGE_PATH_${CONF} path to package (current configuration) 42 | # 43 | # NOCDDL 44 | 45 | 46 | # Environment 47 | MKDIR=mkdir 48 | CP=cp 49 | CCADMIN=CCadmin 50 | RANLIB=ranlib 51 | 52 | 53 | # build 54 | build: .build-post 55 | 56 | .build-pre: 57 | # Add your pre 'build' code here... 58 | 59 | .build-post: .build-impl 60 | # Add your post 'build' code here... 61 | 62 | 63 | # clean 64 | clean: .clean-post 65 | 66 | .clean-pre: 67 | # Add your pre 'clean' code here... 68 | 69 | .clean-post: .clean-impl 70 | # Add your post 'clean' code here... 71 | 72 | 73 | # clobber 74 | clobber: .clobber-post 75 | 76 | .clobber-pre: 77 | # Add your pre 'clobber' code here... 78 | 79 | .clobber-post: .clobber-impl 80 | # Add your post 'clobber' code here... 81 | 82 | 83 | # all 84 | all: .all-post 85 | 86 | .all-pre: 87 | # Add your pre 'all' code here... 88 | 89 | .all-post: .all-impl 90 | # Add your post 'all' code here... 91 | 92 | 93 | # help 94 | help: .help-post 95 | 96 | .help-pre: 97 | # Add your pre 'help' code here... 98 | 99 | .help-post: .help-impl 100 | # Add your post 'help' code here... 101 | 102 | 103 | 104 | # include project implementation makefile 105 | include nbproject/Makefile-impl.mk 106 | 107 | # include project make variables 108 | include nbproject/Makefile-variables.mk 109 | -------------------------------------------------------------------------------- /apps/unit_test/MPLAB.X/nbproject/project.xml: -------------------------------------------------------------------------------- 1 | 2 | com.microchip.mplab.nbide.embedded.makeproject 3 | 4 | 5 | usb_stack_unit_test 6 | d62999b6-148b-4401-bb2b-d1fe2348676c 7 | 0 8 | c 9 | 10 | h 11 | ISO-8859-1 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /apps/unit_test/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * USB Test Program 3 | * 4 | * This file may be used by anyone for any purpose and may be used as a 5 | * starting point making your own application using M-Stack. 6 | * 7 | * It is worth noting that M-Stack itself is not under the same license as 8 | * this file. 9 | * 10 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. For details, see sections 7, 8, and 9 13 | * of the Apache License, version 2.0 which apply to this file. If you have 14 | * purchased a commercial license for this software from Signal 11 Software, 15 | * your commerical license superceeds the information in this header. 16 | * 17 | * Alan Ott 18 | * Signal 11 Software 19 | * 2013-04-08 20 | */ 21 | 22 | #include "usb.h" 23 | #include 24 | #include 25 | #include "usb_config.h" 26 | #include "usb_ch9.h" 27 | #include "hardware.h" 28 | 29 | int main(void) 30 | { 31 | hardware_init(); 32 | 33 | usb_init(); 34 | 35 | unsigned char *buf = usb_get_in_buffer(1); 36 | memset(buf, 0xa0, EP_1_IN_LEN); 37 | 38 | while (1) { 39 | if (usb_is_configured() && usb_out_endpoint_has_data(1)) { 40 | uint8_t len; 41 | const unsigned char *data; 42 | /* Data received from host */ 43 | 44 | if (!usb_in_endpoint_halted(1)) { 45 | /* Wait for EP 1 IN to become free then send. This of 46 | * course only works using interrupts. */ 47 | while (usb_in_endpoint_busy(1)) 48 | ; 49 | 50 | len = usb_get_out_buffer(1, &data); 51 | memcpy(usb_get_in_buffer(1), data, EP_1_IN_LEN); 52 | usb_send_in_buffer(1, len); 53 | } 54 | usb_arm_out_endpoint(1); 55 | } 56 | 57 | #ifndef USB_USE_INTERRUPTS 58 | usb_service(); 59 | #endif 60 | } 61 | 62 | return 0; 63 | } 64 | 65 | /* Callbacks. These function names are set in usb_config.h. */ 66 | void app_set_configuration_callback(uint8_t configuration) 67 | { 68 | 69 | } 70 | uint16_t app_get_device_status_callback() 71 | { 72 | return 0x0000; 73 | } 74 | 75 | void app_endpoint_halt_callback(uint8_t endpoint, bool halted) 76 | { 77 | 78 | } 79 | 80 | int8_t app_set_interface_callback(uint8_t interface, uint8_t alt_setting) 81 | { 82 | return 0; 83 | } 84 | 85 | int8_t app_get_interface_callback(uint8_t interface) 86 | { 87 | return 0; 88 | } 89 | 90 | void app_out_transaction_callback(uint8_t endpoint) 91 | { 92 | 93 | } 94 | 95 | void app_in_transaction_complete_callback(uint8_t endpoint) 96 | { 97 | 98 | } 99 | 100 | static char buf[512]; 101 | 102 | static int8_t data_cb(bool transfer_ok, void *context) 103 | { 104 | /* For OUT control transfers, data from the data stage of the request 105 | * is in buf[]. */ 106 | return 0; 107 | } 108 | 109 | int8_t app_unknown_setup_request_callback(const struct setup_packet *setup) 110 | { 111 | #define MIN(X,Y) ((X)<(Y)?(X):(Y)) 112 | 113 | /* This handler handles request 254/dest=other/type=vendor only.*/ 114 | if (setup->bRequest != 245 || 115 | setup->REQUEST.destination != 3 /*other*/ || 116 | setup->REQUEST.type != 2 /*vendor*/) 117 | return -1; 118 | 119 | if (setup->REQUEST.direction == 0/*OUT*/) { 120 | if (setup->wLength == 0) { 121 | /* There will be NO data stage. This sends back the 122 | * STATUS stage packet. */ 123 | usb_send_data_stage(NULL, 0, data_cb, NULL); 124 | } 125 | memset(buf,0,sizeof(buf)); 126 | 127 | /* Set up an OUT data stage (we will receive data) */ 128 | if (setup->wLength > sizeof(buf)) { 129 | /* wLength is too big. Return -1 to 130 | refuse this transfer*/ 131 | return -1; 132 | } 133 | usb_start_receive_ep0_data_stage(buf, setup->wLength, &data_cb, NULL); 134 | } 135 | else { 136 | /* Direction is 1 (IN) */ 137 | size_t i; 138 | 139 | for (i = 0; i < sizeof(buf); i++) { 140 | buf[i] = sizeof(buf)-i; 141 | } 142 | 143 | /* Set up an OUT data stage (we will receive data) */ 144 | if (setup->wLength > sizeof(buf)) { 145 | /* wLength is too big. Return -1 to 146 | refuse this transfer*/ 147 | return -1; 148 | } 149 | usb_send_data_stage(buf ,setup->wLength, data_cb, NULL); 150 | } 151 | 152 | return 0; /* 0 = can handle this request. */ 153 | #undef MIN 154 | } 155 | 156 | int16_t app_unknown_get_descriptor_callback(const struct setup_packet *pkt, const void **descriptor) 157 | { 158 | return -1; 159 | } 160 | 161 | void app_start_of_frame_callback(void) 162 | { 163 | 164 | } 165 | 166 | void app_usb_reset_callback(void) 167 | { 168 | 169 | } 170 | 171 | #ifdef _PIC14E 172 | void interrupt isr() 173 | { 174 | usb_service(); 175 | } 176 | #elif _PIC18 177 | 178 | #ifdef __XC8 179 | void interrupt high_priority isr() 180 | { 181 | usb_service(); 182 | } 183 | #elif _PICC18 184 | #error need to make ISR 185 | #endif 186 | 187 | #endif -------------------------------------------------------------------------------- /apps/unit_test/usb_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Sample USB Configuration 3 | * 4 | * This file may be used by anyone for any purpose and may be used as a 5 | * starting point making your own application using M-Stack. 6 | * 7 | * It is worth noting that M-Stack itself is not under the same license 8 | * as this file. 9 | * 10 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. For details, see sections 7, 8, and 9 13 | * of the Apache License, version 2.0 which apply to this file. If you have 14 | * purchased a commercial license for this software from Signal 11 Software, 15 | * your commerical license superceeds the information in this header. 16 | * 17 | * Alan Ott 18 | * Signal 11 Software 19 | * 2013-04-08 20 | */ 21 | 22 | #ifndef USB_CONFIG_H__ 23 | #define USB_CONFIG_H__ 24 | 25 | /* Number of endpoint numbers besides endpoint zero. It's worth noting that 26 | and endpoint NUMBER does not completely describe an endpoint, but the 27 | along with the DIRECTION does (eg: EP 1 IN). The #define below turns on 28 | BOTH IN and OUT endpoints for endpoint numbers (besides zero) up to the 29 | value specified. For example, setting NUM_ENDPOINT_NUMBERS to 2 will 30 | activate endpoints EP 1 IN, EP 1 OUT, EP 2 IN, EP 2 OUT. */ 31 | #define NUM_ENDPOINT_NUMBERS 1 32 | 33 | /* Only 8, 16, 32 and 64 are supported for endpoint zero length. */ 34 | #define EP_0_LEN 8 35 | 36 | #define EP_1_OUT_LEN 64 37 | #define EP_1_IN_LEN 64 38 | 39 | #define EP_2_OUT_LEN 64 40 | #define EP_2_IN_LEN 64 41 | 42 | #define NUMBER_OF_CONFIGURATIONS 1 43 | 44 | /* Ping-pong buffering mode. Valid values are: 45 | PPB_NONE - Do not ping-pong any endpoints 46 | PPB_EPO_OUT_ONLY - Ping-pong only endpoint 0 OUT 47 | PPB_ALL - Ping-pong all endpoints 48 | PPB_EPN_ONLY - Ping-pong all endpoints except 0 49 | */ 50 | #ifdef __PIC32MX__ 51 | /* PIC32MX only supports PPB_ALL */ 52 | #define PPB_MODE PPB_ALL 53 | #else 54 | #define PPB_MODE PPB_NONE 55 | #endif 56 | 57 | /* Comment the following line to use polling USB operation. When using polling, 58 | You are responsible for calling usb_service() periodically from your 59 | application. */ 60 | #define USB_USE_INTERRUPTS 61 | 62 | /* Objects from usb_descriptors.c */ 63 | #define USB_DEVICE_DESCRIPTOR this_device_descriptor 64 | #define USB_CONFIG_DESCRIPTOR_MAP usb_application_config_descs 65 | #define USB_STRING_DESCRIPTOR_FUNC usb_application_get_string 66 | 67 | /* The Setup Request number (bRequest) to tell the host to use for the 68 | * Microsoft descriptors. See docs/winusb.txt for details. */ 69 | #define MICROSOFT_OS_DESC_VENDOR_CODE 0x50 70 | /* Automatically send the descriptors to bind the WinUSB driver on Windows */ 71 | #define AUTOMATIC_WINUSB_SUPPORT 72 | 73 | /* Optional callbacks from usb.c. Leave them commented if you don't want to 74 | use them. For the prototypes and documentation for each one, see usb.h. */ 75 | 76 | #define SET_CONFIGURATION_CALLBACK app_set_configuration_callback 77 | #define GET_DEVICE_STATUS_CALLBACK app_get_device_status_callback 78 | #define ENDPOINT_HALT_CALLBACK app_endpoint_halt_callback 79 | #define SET_INTERFACE_CALLBACK app_set_interface_callback 80 | #define GET_INTERFACE_CALLBACK app_get_interface_callback 81 | #define OUT_TRANSACTION_CALLBACK app_out_transaction_callback 82 | #define IN_TRANSACTION_COMPLETE_CALLBACK app_in_transaction_complete_callback 83 | #define UNKNOWN_SETUP_REQUEST_CALLBACK app_unknown_setup_request_callback 84 | #define UNKNOWN_GET_DESCRIPTOR_CALLBACK app_unknown_get_descriptor_callback 85 | #define START_OF_FRAME_CALLBACK app_start_of_frame_callback 86 | #define USB_RESET_CALLBACK app_usb_reset_callback 87 | 88 | 89 | #endif /* USB_CONFIG_H__ */ 90 | -------------------------------------------------------------------------------- /docs/winusb.txt: -------------------------------------------------------------------------------- 1 | 2 | Libusb and WinUSB on Windows with M-Stack 3 | ========================================== 4 | 5 | Userspace software can make use of WinUSB for communication with M-Stack 6 | devices from Windows hosts. In addition, Libusb can use WinUSB as a filter 7 | driver, allowing easy creation of cross-platform applications using Libusb. 8 | 9 | While the source code for libusb applications can be the same across 10 | platforms, Libusb and WinUSB on Windows will not support isochronous 11 | endpoints. This is a limitation of WinUSB. 12 | 13 | INF Files 14 | ---------- 15 | On Windows, an INF file is used to bind a hardware device to a driver. For 16 | WinUSB applications, an INF file is required for each type of device which 17 | the WinUSB driver is to be bound to. This INF file must be "installed" on 18 | each computer where it will be used. Further, signing by Microsoft is 19 | required if annoying popups are to be avoided. Signing by Microsoft is 20 | expensive. 21 | 22 | On Windows 8, a device may include the Windows-specific Operating System 23 | descriptor along with both the Extended CompatID Descriptor, and the 24 | Extended Properties Descriptor (both Windows-specific and non-standard) to 25 | bind WinUSB to a device without creating and installing an INF file. 26 | Support for this method has been pushed down to Windows 7 as well (and maybe 27 | Vista), but not Windows XP. Connecting a device with the Windows Operating 28 | System Descriptor (henceforth a WinUSB device) will work properly out of the 29 | box on Windows 8. On Windows 7, it will require the computer to be 30 | connected to the internet and have Windows Update enabled for driver 31 | downloads (which is the default) so that Windows can automatically download 32 | and install the WinUSB driver the first time a WinUSB device is connected. 33 | 34 | Mechanism 35 | ---------- 36 | When a USB device is connected to a Windows computer for the first time, 37 | Windows will ask the new device for string descriptor 0xee. If this 38 | descriptor is of a specified format, Windows will assume that the device is 39 | a WinUSB device, causing Windows to treat string descriptor 0xee as a 40 | Windows Operating System Descriptor, and causing it to read the requestID 41 | field from this descriptor. Windows will then issue control transfers, 42 | using the requestID as a bRequest, to request both the Extended CompatID 43 | Descriptor and the Extended Properties Descriptor. The Extended CompatID 44 | Descriptor contains a compatibleID string which Windows will use to bind a 45 | specific driver to the device. Setting compatibleID to "WINUSB" will bind 46 | WinUSB to the device. The unit_test example which comes with M-Stack 47 | provides an example of a WinUSB device. 48 | 49 | See the documents in the references section below for more details. 50 | 51 | Tricks 52 | ------- 53 | Windows will only read the Microsoft-specific descriptors the first time the 54 | device is connected, which is undisrable during development of a WinUSB 55 | device. Windows can be forced to re-read the descriptors by performing the 56 | following steps: 57 | 1. In the Device Manager, right-click the device (which will show 58 | as "WinUSB Device" under "Universal Serial Bus Devices") and 59 | select "Uninstall." This will unbind the driver. 60 | 2. In the registry, delete the section associated with your device in 61 | HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\UsbFlags . 62 | The device keys in UsbFlags begin with the VID and PID of the 63 | device they describe. 64 | 3. Disconnect and re-connect your device. The next time the device 65 | is connected, Windows will request the WinUSB descriptors. 66 | 67 | References 68 | ----------- 69 | http://blogs.msdn.com/b/usbcoreblog/archive/2012/09/26/how-to-install-winusb-sys-without-a-custom-inf.aspx 70 | http://msdn.microsoft.com/library/windows/hardware/gg463182 71 | (Search MSDN for "Microsoft OS Descriptors" if the above link fails) 72 | -------------------------------------------------------------------------------- /doxygen/main_page.c: -------------------------------------------------------------------------------- 1 | /** 2 | @mainpage M-Stack 3 | 4 | @section Intro 5 | This is M-Stack, a free USB Device Stack for PIC Microcontrollers. 6 | 7 | For more information, see the main web page. 8 | 9 | For API documentation, see the Public API Page. 10 | 11 | */ 12 | 13 | -------------------------------------------------------------------------------- /host_test/.gitignore: -------------------------------------------------------------------------------- 1 | test 2 | feature 3 | control_transfer_in 4 | control_transfer_out 5 | -------------------------------------------------------------------------------- /host_test/Makefile: -------------------------------------------------------------------------------- 1 | # M-Stack Host Test Software Makefile 2 | # 3 | # This file may be used by anyone for any purpose and may be used as a 4 | # starting point making your own application using M-Stack. 5 | # 6 | # It is worth noting that M-Stack itself is not under the same license as 7 | # this file. See the top-level README.txt for more information. 8 | # 9 | # Alan Ott 10 | # Signal 11 Software 11 | 12 | all: test feature feature_test control_transfer_out control_transfer_in 13 | 14 | test: test.c 15 | gcc -Wall -g -o test test.c `pkg-config libusb-1.0 --cflags --libs` 16 | 17 | feature: feature.c 18 | gcc -Wall -g -o feature feature.c `pkg-config libusb-1.0 --cflags --libs` 19 | 20 | feature_test: feature_test.c 21 | gcc -Wall -g -o feature_test feature_test.c `pkg-config libusb-1.0 --cflags --libs` 22 | 23 | control_transfer_out: control_transfer_out.c 24 | gcc -Wall -g -o control_transfer_out control_transfer_out.c `pkg-config libusb-1.0 --cflags --libs` 25 | 26 | control_transfer_in: control_transfer_in.c 27 | gcc -Wall -g -o control_transfer_in control_transfer_in.c `pkg-config libusb-1.0 --cflags --libs` 28 | -------------------------------------------------------------------------------- /host_test/control_transfer_in.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Libusb Control Transfer Test for M-Stack 3 | * 4 | * This file may be used by anyone for any purpose and may be used as a 5 | * starting point making your own application using M-Stack. 6 | * 7 | * It is worth noting that M-Stack itself is not under the same license as 8 | * this file. See the top-level README.txt for more information. 9 | * 10 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. For details, see sections 7, 8, and 9 13 | * of the Apache License, version 2.0 which apply to this file. If you have 14 | * purchased a commercial license for this software from Signal 11 Software, 15 | * your commerical license superceeds the information in this header. 16 | * 17 | * Alan Ott 18 | * Signal 11 Software 19 | * 2013-04-17 20 | */ 21 | 22 | /* C */ 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | /* Unix */ 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | /* GNU / LibUSB */ 41 | #include "libusb.h" 42 | 43 | 44 | int main(int argc, char **argv) 45 | { 46 | libusb_device_handle *handle; 47 | unsigned char buf[1024]; 48 | int length; 49 | int i; 50 | int res; 51 | 52 | if (argc < 2) { 53 | fprintf(stderr, "%s: [bytes to request]\n", argv[0]); 54 | return 1; 55 | } 56 | 57 | length = atoi(argv[1]); 58 | if (length > sizeof(buf)) 59 | length = sizeof(buf); 60 | 61 | printf("Asking for %d bytes\n", length); 62 | 63 | 64 | /* Init Libusb */ 65 | if (libusb_init(NULL)) 66 | return -1; 67 | 68 | handle = libusb_open_device_with_vid_pid(NULL, 0xa0a0, 0x0001); 69 | if (!handle) { 70 | perror("libusb_open failed: "); 71 | return 1; 72 | } 73 | 74 | res = libusb_claim_interface(handle, 0); 75 | if (res < 0) { 76 | return 1; 77 | } 78 | 79 | for (i = 0; i < sizeof(buf); i++) { 80 | buf[i] = i; 81 | } 82 | 83 | res = libusb_control_transfer(handle, 84 | LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_VENDOR|LIBUSB_RECIPIENT_OTHER, 85 | 245, 86 | 0, /*wValue: 0=endpoint_halt*/ 87 | 0, /*wIndex: Endpoint num*/ 88 | buf, length/*wLength*/, 89 | 1000/*timeout millis*/); 90 | 91 | if (res < 0) { 92 | fprintf(stderr, "control transfer (in): %s\n", libusb_error_name(res)); 93 | return 1; 94 | } 95 | 96 | for (i = 0; i < length; i++) { 97 | printf("%02hhx ", buf[i]); 98 | if ((i + 1) % 8 == 0) 99 | printf(" "); 100 | if ((i + 1) % 16 == 0) 101 | printf("\n"); 102 | } 103 | puts("\n"); 104 | 105 | return 0; 106 | } 107 | -------------------------------------------------------------------------------- /host_test/control_transfer_out.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Libusb Control Transfer Test for M-Stack 3 | * 4 | * This file may be used by anyone for any purpose and may be used as a 5 | * starting point making your own application using M-Stack. 6 | * 7 | * It is worth noting that M-Stack itself is not under the same license as 8 | * this file. See the top-level README.txt for more information. 9 | * 10 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. For details, see sections 7, 8, and 9 13 | * of the Apache License, version 2.0 which apply to this file. If you have 14 | * purchased a commercial license for this software from Signal 11 Software, 15 | * your commerical license superceeds the information in this header. 16 | * 17 | * Alan Ott 18 | * Signal 11 Software 19 | * 2013-04-15 20 | */ 21 | 22 | /* C */ 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | /* Unix */ 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | /* GNU / LibUSB */ 41 | #include "libusb.h" 42 | 43 | 44 | int main(int argc, char **argv) 45 | { 46 | libusb_device_handle *handle; 47 | unsigned char buf[1024]; 48 | int length; 49 | int i; 50 | int res; 51 | 52 | if (argc < 2) { 53 | fprintf(stderr, "%s: [bytes to send]\n", argv[0]); 54 | return 1; 55 | } 56 | 57 | length = atoi(argv[1]); 58 | if (length > sizeof(buf)) 59 | length = sizeof(buf); 60 | 61 | printf("Sending %d bytes\n", length); 62 | 63 | /* Init Libusb */ 64 | if (libusb_init(NULL)) 65 | return -1; 66 | 67 | handle = libusb_open_device_with_vid_pid(NULL, 0xa0a0, 0x0001); 68 | if (!handle) { 69 | perror("libusb_open failed: "); 70 | return 1; 71 | } 72 | 73 | res = libusb_claim_interface(handle, 0); 74 | if (res < 0) { 75 | perror("claim interface"); 76 | return 1; 77 | } 78 | 79 | for (i = 0; i < sizeof(buf); i++) { 80 | buf[i] = i; 81 | } 82 | 83 | res = libusb_control_transfer(handle, 84 | LIBUSB_ENDPOINT_OUT|LIBUSB_REQUEST_TYPE_VENDOR|LIBUSB_RECIPIENT_OTHER, 85 | 245, 86 | 0, /*wValue: 0=endpoint_halt*/ 87 | 0, /*wIndex: Endpoint num*/ 88 | buf, length/*wLength*/, 89 | 1000/*timeout millis*/); 90 | 91 | if (res < 0) { 92 | fprintf(stderr, "control transfer: %s\n", libusb_error_name(res)); 93 | return 1; 94 | } 95 | 96 | return 0; 97 | } 98 | -------------------------------------------------------------------------------- /host_test/feature.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Libusb set/clear feature test for M-Stack 3 | * 4 | * This file may be used by anyone for any purpose and may be used as a 5 | * starting point making your own application using M-Stack. 6 | * 7 | * It is worth noting that M-Stack itself is not under the same license as 8 | * this file. See the top-level README.txt for more information. 9 | * 10 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. For details, see sections 7, 8, and 9 13 | * of the Apache License, version 2.0 which apply to this file. If you have 14 | * purchased a commercial license for this software from Signal 11 Software, 15 | * your commerical license superceeds the information in this header. 16 | * 17 | * Alan Ott 18 | * Signal 11 Software 19 | * 2013-04-13 20 | */ 21 | 22 | /* 23 | Libusb set/clear feature test for M-Stack 24 | 25 | This program will set/clear the endpoint halt feature for an endpoint. Run 26 | with no arguments to set the endpoint halt feature, and run with a single 27 | parameter of "clear" to clear the endpoint halt feature. The endpoint is 28 | hard-coded with a #define (MY_ENDPOINT) lower in the file. 29 | 30 | This is just program for exercising the one of the less-commonly encountered 31 | requests and verifying functionality. 32 | 33 | What I do: 34 | ./test # see that data is received from EP 1 IN 35 | ./feature # set endpoint halt on EP 1 IN 36 | ./test # verify no data is received (verify STALL packets on EP 1 IN) 37 | ./feature clear # clear the endpoint halt on EP 1 IN 38 | ./test # see that data is received from EP 1 IN 39 | */ 40 | 41 | /* C */ 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | 49 | /* Unix */ 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include 57 | #include 58 | 59 | /* GNU / LibUSB */ 60 | #include "libusb.h" 61 | 62 | 63 | int main(int argc, char **argv) 64 | { 65 | libusb_device_handle *handle; 66 | unsigned char buf[64]; 67 | int res; 68 | int clear = 0; 69 | 70 | if (argc == 2) { 71 | if (!strcmp(argv[1], "clear")) 72 | clear = 1; 73 | else { 74 | fprintf(stderr, "invalid arg\n"); 75 | return 1; 76 | } 77 | } 78 | 79 | /* Init Libusb */ 80 | if (libusb_init(NULL)) 81 | return -1; 82 | 83 | handle = libusb_open_device_with_vid_pid(NULL, 0xa0a0, 0x0001); 84 | if (!handle) { 85 | perror("libusb_open failed: "); 86 | return 1; 87 | } 88 | 89 | res = libusb_claim_interface(handle, 0); 90 | if (res < 0) { 91 | perror("claim interface"); 92 | return 1; 93 | } 94 | 95 | #define MY_ENDPOINT 0x81 96 | 97 | /* Set or clear endpoint halt condition */ 98 | if (clear) { 99 | res = libusb_clear_halt(handle, MY_ENDPOINT); 100 | } 101 | else { 102 | res = libusb_control_transfer(handle, 103 | LIBUSB_ENDPOINT_OUT|LIBUSB_REQUEST_TYPE_STANDARD|LIBUSB_RECIPIENT_ENDPOINT, 104 | LIBUSB_REQUEST_SET_FEATURE, 105 | 0, /*wValue: 0=endpoint_halt*/ 106 | MY_ENDPOINT, /*wIndex: Endpoint num*/ 107 | 0, 0/*wLength*/, 108 | 1000/*timeout millis*/); 109 | } 110 | 111 | if (res < 0) { 112 | fprintf(stderr, "libusb_control_transfer (set feature): %s\n", libusb_error_name(res)); 113 | return 1; 114 | } 115 | 116 | /* Read the endpoint halt condition */ 117 | res = libusb_control_transfer(handle, 118 | LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_STANDARD|LIBUSB_RECIPIENT_ENDPOINT, 119 | LIBUSB_REQUEST_GET_STATUS, 120 | 0, /*wValue: */ 121 | MY_ENDPOINT, /*wIndex: Endpoint num*/ 122 | buf, 2/*wLength*/, 123 | 1000/*timeout millis*/); 124 | 125 | if (res < 0) { 126 | fprintf(stderr, "libusb_control_transfer (get status (endpoint)): %s\n", libusb_error_name(res)); 127 | return 1; 128 | } 129 | printf("EP Status %02hx\n", *(uint16_t*)buf); 130 | 131 | return 0; 132 | } 133 | -------------------------------------------------------------------------------- /host_test/test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Libusb Bulk Endpoint Test for M-Stack 3 | * 4 | * This file may be used by anyone for any purpose and may be used as a 5 | * starting point making your own application using M-Stack. 6 | * 7 | * It is worth noting that M-Stack itself is not under the same license as 8 | * this file. See the top-level README.txt for more information. 9 | * 10 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. For details, see sections 7, 8, and 9 13 | * of the Apache License, version 2.0 which apply to this file. If you have 14 | * purchased a commercial license for this software from Signal 11 Software, 15 | * your commerical license superceeds the information in this header. 16 | * 17 | * Alan Ott 18 | * Signal 11 Software 19 | * 2013-04-09 20 | 21 | */ 22 | 23 | /* C */ 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | /* Unix */ 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | /* GNU / LibUSB */ 42 | #include "libusb.h" 43 | 44 | 45 | int main(int argc, char **argv) 46 | { 47 | libusb_device_handle *handle; 48 | unsigned char buf[1024]; 49 | int length; 50 | int actual_length; 51 | int i; 52 | int res; 53 | 54 | if (argc < 2) { 55 | fprintf(stderr, "%s: [bytes to send]\n", argv[0]); 56 | return 1; 57 | } 58 | 59 | length = atoi(argv[1]); 60 | if (length > sizeof(buf)) 61 | length = sizeof(buf); 62 | 63 | printf("Sending %d bytes\n", length); 64 | 65 | /* Init Libusb */ 66 | if (libusb_init(NULL)) 67 | return -1; 68 | 69 | handle = libusb_open_device_with_vid_pid(NULL, 0xa0a0, 0x0001); 70 | if (!handle) { 71 | perror("libusb_open failed: "); 72 | return 1; 73 | } 74 | 75 | res = libusb_claim_interface(handle, 0); 76 | if (res < 0) { 77 | perror("claim interface"); 78 | return 1; 79 | } 80 | 81 | for (i = 0; i < sizeof(buf); i++) { 82 | buf[i] = i; 83 | } 84 | 85 | /* Send some data to the device */ 86 | res = libusb_bulk_transfer(handle, 0x01, buf, length, &actual_length, 5000); 87 | if (res < 0) { 88 | fprintf(stderr, "bulk transfer (out): %s\n", libusb_error_name(res)); 89 | return 1; 90 | } 91 | 92 | /* Receive data from the device */ 93 | res = libusb_bulk_transfer(handle, 0x81, buf, length, &actual_length, 5000); 94 | if (res < 0) { 95 | fprintf(stderr, "bulk transfer (in): %s\n", libusb_error_name(res)); 96 | return 1; 97 | } 98 | for (i = 0; i < actual_length; i++) { 99 | printf("%02hhx ", buf[i]); 100 | if ((i+1) % 8 == 0) 101 | printf(" "); 102 | if ((i+1) % 16 == 0) 103 | printf("\n"); 104 | } 105 | printf("\n\n"); 106 | 107 | 108 | return 0; 109 | } 110 | -------------------------------------------------------------------------------- /storage/include/crc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * M-Stack CRC Implementations 3 | * Copyright (C) 2013 Alan Ott 4 | * Copyright (C) 2013 Signal 11 Software 5 | * 6 | * 2014-06-01 7 | * 8 | * M-Stack is free software: you can redistribute it and/or modify it under 9 | * the terms of the GNU Lesser General Public License as published by the 10 | * Free Software Foundation, version 3; or the Apache License, version 2.0 11 | * as published by the Apache Software Foundation. If you have purchased a 12 | * commercial license for this software from Signal 11 Software, your 13 | * commerical license superceeds the information in this header. 14 | * 15 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 16 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 18 | * License for more details. 19 | * 20 | * You should have received a copy of the GNU Lesser General Public License 21 | * along with this software. If not, see . 22 | * 23 | * You should have received a copy of the Apache License, verion 2.0 along 24 | * with this software. If not, see . 25 | */ 26 | 27 | 28 | #ifndef M_STACK_CRC_H__ 29 | #define M_STACK_CRC_H__ 30 | 31 | /** @file crc.h 32 | * @brief M-Stack CRC Implementations 33 | * @defgroup public_api Public API 34 | * 35 | * CRC7 and CRC16 implementations. 36 | * 37 | */ 38 | 39 | /** @addtogroup public_api 40 | * @{ 41 | */ 42 | 43 | /** @brief Update a CRC7 checksum with additional input data 44 | * 45 | * Update a CRC7 checksum with an additional input byte. For example, to 46 | * checksum an array, call this function for each member of the array. 47 | * 48 | * @param csum The original checksum 49 | * @param input The additional value with which to update the checksum. 50 | * 51 | * @returns 52 | * Return the CRC7 checksum of @p csum updated by @p input. 53 | */ 54 | uint8_t add_crc7(uint8_t csum, uint8_t input); 55 | 56 | /** @brief Update a CRC16 checksum with additional input data 57 | * 58 | * Update a CRC16 checksum with an additional input byte. For example, to 59 | * checksum an array, call this function for each member of the array. 60 | * 61 | * @param csum The original checksum 62 | * @param input The additional value with which to update the checksum. 63 | * 64 | * @returns 65 | * Return the CRC16 checksum of @p csum updated by @p input. 66 | */ 67 | uint16_t add_crc16(uint16_t csum, uint8_t input); 68 | 69 | /** @brief Update a CRC16 checksum with an array of data 70 | * 71 | * Update a CRC16 checksum with an additional array of input data. 72 | * 73 | * @param csum The original checksum 74 | * @param data The additional array with which to update the checksum. 75 | * @param len The length of the @p data array. 76 | * 77 | * @returns 78 | * Return the CRC16 checksum of @p csum updated by @p data. 79 | */ 80 | uint16_t add_crc16_array(uint16_t csum, uint8_t *data, uint16_t len); 81 | 82 | /* Doxygen end-of-group for public_api */ 83 | /** @}*/ 84 | 85 | #endif /* M_STACK_CRC_H__ */ 86 | -------------------------------------------------------------------------------- /storage/src/crc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * M-Stack CRC Implementations 3 | * Copyright (C) 2013 Alan Ott 4 | * Copyright (C) 2013 Signal 11 Software 5 | * 6 | * 2014-06-01 7 | * 8 | * M-Stack is free software: you can redistribute it and/or modify it under 9 | * the terms of the GNU Lesser General Public License as published by the 10 | * Free Software Foundation, version 3; or the Apache License, version 2.0 11 | * as published by the Apache Software Foundation. If you have purchased a 12 | * commercial license for this software from Signal 11 Software, your 13 | * commerical license superceeds the information in this header. 14 | * 15 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 16 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 18 | * License for more details. 19 | * 20 | * You should have received a copy of the GNU Lesser General Public License 21 | * along with this software. If not, see . 22 | * 23 | * You should have received a copy of the Apache License, verion 2.0 along 24 | * with this software. If not, see . 25 | */ 26 | 27 | #include 28 | #include 29 | 30 | static uint8_t crc7_table[] = { 31 | 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 32 | 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77, 33 | 0x19, 0x10, 0x0b, 0x02, 0x3d, 0x34, 0x2f, 0x26, 34 | 0x51, 0x58, 0x43, 0x4a, 0x75, 0x7c, 0x67, 0x6e, 35 | 0x32, 0x3b, 0x20, 0x29, 0x16, 0x1f, 0x04, 0x0d, 36 | 0x7a, 0x73, 0x68, 0x61, 0x5e, 0x57, 0x4c, 0x45, 37 | 0x2b, 0x22, 0x39, 0x30, 0x0f, 0x06, 0x1d, 0x14, 38 | 0x63, 0x6a, 0x71, 0x78, 0x47, 0x4e, 0x55, 0x5c, 39 | 0x64, 0x6d, 0x76, 0x7f, 0x40, 0x49, 0x52, 0x5b, 40 | 0x2c, 0x25, 0x3e, 0x37, 0x08, 0x01, 0x1a, 0x13, 41 | 0x7d, 0x74, 0x6f, 0x66, 0x59, 0x50, 0x4b, 0x42, 42 | 0x35, 0x3c, 0x27, 0x2e, 0x11, 0x18, 0x03, 0x0a, 43 | 0x56, 0x5f, 0x44, 0x4d, 0x72, 0x7b, 0x60, 0x69, 44 | 0x1e, 0x17, 0x0c, 0x05, 0x3a, 0x33, 0x28, 0x21, 45 | 0x4f, 0x46, 0x5d, 0x54, 0x6b, 0x62, 0x79, 0x70, 46 | 0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31, 0x38, 47 | 0x41, 0x48, 0x53, 0x5a, 0x65, 0x6c, 0x77, 0x7e, 48 | 0x09, 0x00, 0x1b, 0x12, 0x2d, 0x24, 0x3f, 0x36, 49 | 0x58, 0x51, 0x4a, 0x43, 0x7c, 0x75, 0x6e, 0x67, 50 | 0x10, 0x19, 0x02, 0x0b, 0x34, 0x3d, 0x26, 0x2f, 51 | 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c, 52 | 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, 53 | 0x6a, 0x63, 0x78, 0x71, 0x4e, 0x47, 0x5c, 0x55, 54 | 0x22, 0x2b, 0x30, 0x39, 0x06, 0x0f, 0x14, 0x1d, 55 | 0x25, 0x2c, 0x37, 0x3e, 0x01, 0x08, 0x13, 0x1a, 56 | 0x6d, 0x64, 0x7f, 0x76, 0x49, 0x40, 0x5b, 0x52, 57 | 0x3c, 0x35, 0x2e, 0x27, 0x18, 0x11, 0x0a, 0x03, 58 | 0x74, 0x7d, 0x66, 0x6f, 0x50, 0x59, 0x42, 0x4b, 59 | 0x17, 0x1e, 0x05, 0x0c, 0x33, 0x3a, 0x21, 0x28, 60 | 0x5f, 0x56, 0x4d, 0x44, 0x7b, 0x72, 0x69, 0x60, 61 | 0x0e, 0x07, 0x1c, 0x15, 0x2a, 0x23, 0x38, 0x31, 62 | 0x46, 0x4f, 0x54, 0x5d, 0x62, 0x6b, 0x70, 0x79, 63 | }; 64 | 65 | static uint16_t crc16_table[] = { 66 | 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 67 | 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 68 | 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 69 | 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 70 | 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 71 | 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 72 | 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 73 | 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 74 | 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 75 | 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 76 | 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 77 | 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 78 | 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 79 | 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 80 | 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 81 | 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 82 | 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 83 | 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, 84 | 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 85 | 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 86 | 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 87 | 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 88 | 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 89 | 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 90 | 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 91 | 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 92 | 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 93 | 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 94 | 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 95 | 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 96 | 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 97 | 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0, 98 | }; 99 | 100 | 101 | uint8_t add_crc7(uint8_t csum, uint8_t input) 102 | { 103 | csum = crc7_table[(csum << 1) ^ input]; 104 | return csum; 105 | } 106 | 107 | uint16_t add_crc16(uint16_t csum, uint8_t input) 108 | { 109 | return crc16_table[((csum >> 8) ^ input) & 0xff] ^ (csum << 8); 110 | } 111 | 112 | uint16_t add_crc16_array(uint16_t csum, uint8_t *data, uint16_t len) 113 | { 114 | while (len--) { 115 | csum = crc16_table[((csum >> 8) ^ *data) & 0xff] ^ (csum << 8); 116 | data++; 117 | } 118 | 119 | return csum; 120 | } 121 | 122 | #if PC_CODE_TO_GENERATE_THE_TABLES 123 | /* This code is designed to run on a PC and will generate the tables above */ 124 | 125 | #define POLY 0x89 126 | #define POLY16 0x1021 127 | 128 | uint8_t add_crc7(uint8_t csum, uint8_t input) 129 | { 130 | int i; 131 | 132 | csum = (csum << 1) ^ input; 133 | for (i = 0; i < 8; i++) { 134 | if (csum & 0x80) { 135 | csum ^= POLY; 136 | } 137 | csum <<= 1; 138 | } 139 | 140 | csum = (csum >> 1) & 0x7f; 141 | return csum; 142 | } 143 | 144 | uint16_t add_crc16(uint16_t csum, uint8_t input) 145 | { 146 | int i; 147 | 148 | csum = csum ^ (input << 8); 149 | for (i = 0; i < 8; i++) { 150 | if (csum & 0x8000) { 151 | csum <<= 1; 152 | csum ^= POLY16; 153 | } 154 | else 155 | csum <<= 1; 156 | } 157 | 158 | return csum; 159 | } 160 | 161 | 162 | int main(void) 163 | { 164 | FILE *fp = fopen("crc_table.c", "w"); 165 | if (!fp) { 166 | printf("Can't open crc_table.c\n"); 167 | return 1; 168 | } 169 | 170 | fprintf(fp, "static uint8_t crc7_table[] = {\n"); 171 | int i; 172 | for (i = 0; i < 256; i++) { 173 | if (i % 8 == 0) 174 | fprintf(fp, "\t"); 175 | fprintf(fp, "0x%02hhx,", add_crc7(0, i)); 176 | if ((i + 1) % 8 == 0) 177 | fprintf(fp, "\n"); 178 | else 179 | fprintf(fp, " "); 180 | } 181 | fprintf(fp, "};\n\n"); 182 | 183 | fprintf(fp, "static uint16_t crc16_table[] = {\n"); 184 | for (i = 0; i < 256; i++) { 185 | if (i % 8 == 0) 186 | fprintf(fp, "\t"); 187 | fprintf(fp, "0x%04hx,", add_crc16(0, i)); 188 | if ((i + 1) % 8 == 0) 189 | fprintf(fp, "\n"); 190 | else 191 | fprintf(fp, " "); 192 | } 193 | fprintf(fp, "};\n"); 194 | fclose(fp); 195 | 196 | return 0; 197 | } 198 | #endif 199 | -------------------------------------------------------------------------------- /usb/include/usb_ch9.h: -------------------------------------------------------------------------------- 1 | /* 2 | * M-Stack USB Chapter 9 Structures 3 | * Copyright (C) 2013 Alan Ott 4 | * Copyright (C) 2013 Signal 11 Software 5 | * 6 | * 2013-04-26 7 | * 8 | * M-Stack is free software: you can redistribute it and/or modify it under 9 | * the terms of the GNU Lesser General Public License as published by the 10 | * Free Software Foundation, version 3; or the Apache License, version 2.0 11 | * as published by the Apache Software Foundation. If you have purchased a 12 | * commercial license for this software from Signal 11 Software, your 13 | * commerical license superceeds the information in this header. 14 | * 15 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 16 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 18 | * License for more details. 19 | * 20 | * You should have received a copy of the GNU Lesser General Public License 21 | * along with this software. If not, see . 22 | * 23 | * You should have received a copy of the Apache License, verion 2.0 along 24 | * with this software. If not, see . 25 | */ 26 | 27 | #ifndef USB_CH9_H__ 28 | #define USB_CH9_H__ 29 | 30 | /** @file usb.h 31 | * @brief USB Chapter 9 Enumerations and Structures 32 | * @defgroup public_api Public API 33 | */ 34 | 35 | /** @addtogroup public_api 36 | * @{ 37 | */ 38 | 39 | #include 40 | 41 | #if defined(__XC16__) || defined(__XC32__) 42 | #pragma pack(push, 1) 43 | #elif __XC8 44 | #else 45 | #error "Compiler not supported" 46 | #endif 47 | 48 | /** @defgroup ch9_items USB Chapter 9 Enumerations and Descriptors 49 | * @brief Packet structs from Chapter 9 of the USB spec which deals with 50 | * device enumeration. 51 | * 52 | * For more information about these structures, see Chapter 9 of the USB 53 | * specification, available from http://www.usb.org . 54 | * @addtogroup ch9_items 55 | * @{ 56 | */ 57 | 58 | /** USB PIDs */ 59 | enum PID { 60 | PID_OUT = 0x01, 61 | PID_IN = 0x09, 62 | PID_SOF = 0x05, 63 | PID_SETUP = 0x0D, 64 | PID_DATA0 = 0x03, 65 | PID_DATA1 = 0x0B, 66 | PID_DATA2 = 0x07, 67 | PID_MDATA = 0x0F, 68 | PID_ACK = 0x02, 69 | PID_NAK = 0x0A, 70 | PID_STALL = 0x0E, 71 | PID_NYET = 0x06, 72 | PID_PRE = 0x0C, 73 | PID_ERR = 0x0C, 74 | PID_SPLIT = 0x08, 75 | PID_PING = 0x04, 76 | PID_RESERVED = 0x00, 77 | }; 78 | 79 | /** Destination type 80 | * 81 | * This is present in the SETUP packet's bmRequestType field as Direction. 82 | */ 83 | enum DestinationType { 84 | DEST_DEVICE = 0, 85 | DEST_INTERFACE = 1, 86 | DEST_ENDPOINT = 2, 87 | DEST_OTHER_ELEMENT = 3, 88 | }; 89 | 90 | /** Request type 91 | * 92 | * These are present in the SETUP packet's bmRequestType field as Type. 93 | */ 94 | enum RequestType { 95 | REQUEST_TYPE_STANDARD = 0, 96 | REQUEST_TYPE_CLASS = 1, 97 | REQUEST_TYPE_VENDOR = 2, 98 | REQUEST_TYPE_RESERVED = 3, 99 | }; 100 | 101 | /** Control Request 102 | * 103 | * These are requests sent in the SETUP packet's bRequest field. 104 | */ 105 | enum StandardControlRequest { 106 | GET_STATUS = 0x0, 107 | CLEAR_FEATURE = 0x1, 108 | SET_FEATURE = 0x3, 109 | SET_ADDRESS = 0x5, 110 | GET_DESCRIPTOR = 0x6, 111 | SET_DESCRIPTOR = 0x7, 112 | GET_CONFIGURATION = 0x8, 113 | SET_CONFIGURATION = 0x9, 114 | GET_INTERFACE = 0xA, 115 | SET_INTERFACE = 0xB, 116 | SYNCH_FRAME = 0xC, 117 | }; 118 | 119 | /** Standard Descriptor Types */ 120 | enum DescriptorTypes { 121 | DESC_DEVICE = 0x1, 122 | DESC_CONFIGURATION = 0x2, 123 | DESC_STRING = 0x3, 124 | DESC_INTERFACE = 0x4, 125 | DESC_ENDPOINT = 0x5, 126 | DESC_DEVICE_QUALIFIER = 0x6, 127 | DESC_OTHER_SPEED_CONFIGURATION = 0x7, 128 | DESC_INTERFACE_POWER = 0x8, 129 | DESC_OTG = 0x9, 130 | DESC_DEBUG = 0xA, 131 | DESC_INTERFACE_ASSOCIATION = 0xB, 132 | }; 133 | 134 | /** Device Classes 135 | * 136 | * Some Device class constants which don't correspond to actual 137 | * classes. 138 | * 139 | * Device class codes which correspond to actual device classes are 140 | * defined in that device class's header file (for M-Stack supported 141 | * device classes). 142 | */ 143 | enum DeviceClassCodes { 144 | DEVICE_CLASS_DEFINED_AT_INTERFACE_LEVEL = 0x0, 145 | DEVICE_CLASS_MISC = 0xef, 146 | DEVICE_CLASS_APPLICATION_SPECIFIC = 0xfe, 147 | DEVICE_CLASS_VENDOR_SPECIFIC = 0xff, 148 | }; 149 | 150 | /** Endpoint Attributes */ 151 | enum EndpointAttributes { 152 | EP_CONTROL = 0x0, 153 | EP_ISOCHRONOUS = 0x1, 154 | EP_BULK = 0x2, 155 | EP_INTERRUPT = 0x3, 156 | 157 | /* More bits here for ISO endpoints only. */ 158 | }; 159 | 160 | /** The SETUP packet, as defined by the USB specification. 161 | * 162 | * The contents of the packet sent from the host during the SETUP stage of 163 | * every control transfer 164 | */ 165 | struct setup_packet { 166 | union { 167 | struct { 168 | uint8_t destination : 5; /**< @see enum DestinationType */ 169 | uint8_t type : 2; /**< @see enum RequestType */ 170 | uint8_t direction : 1; /**< 0=out, 1=in */ 171 | }; 172 | uint8_t bmRequestType; 173 | } REQUEST; 174 | uint8_t bRequest; /**< Dependent on @p type. @see enum StandardControlRequest */ 175 | uint16_t wValue; 176 | uint16_t wIndex; 177 | uint16_t wLength; 178 | }; 179 | 180 | /** Device Descriptor */ 181 | struct device_descriptor { 182 | uint8_t bLength; 183 | uint8_t bDescriptorType; /**< set to DESC_DEVICE */ 184 | uint16_t bcdUSB; /**< Set to 0x0200 for USB 2.0 */ 185 | uint8_t bDeviceClass; 186 | uint8_t bDeviceSubclass; 187 | uint8_t bDeviceProtocol; 188 | uint8_t bMaxPacketSize0; /**< Max packet size for ep 0. Must be 8, 16, 32, or 64. */ 189 | uint16_t idVendor; 190 | uint16_t idProduct; 191 | uint16_t bcdDevice; 192 | uint8_t iManufacturer; /**< index of manufacturer string descriptor */ 193 | uint8_t iProduct; /**< index of product string descriptor */ 194 | uint8_t iSerialNumber; /**< index of serial number string descriptor */ 195 | uint8_t bNumConfigurations; 196 | }; 197 | 198 | /** Configuration Descriptor */ 199 | struct configuration_descriptor { 200 | uint8_t bLength; 201 | uint8_t bDescriptorType; /**< Set to DESC_CONFIGURATION */ 202 | uint16_t wTotalLength; 203 | uint8_t bNumInterfaces; 204 | uint8_t bConfigurationValue; 205 | uint8_t iConfiguration; /**< index of string descriptor */ 206 | uint8_t bmAttributes; 207 | uint8_t bMaxPower; /**< one-half the max power required by this device. */ 208 | }; 209 | 210 | /** Interface Descriptor */ 211 | struct interface_descriptor { 212 | uint8_t bLength; 213 | uint8_t bDescriptorType; /**< Set to DESC_INTERFACE */ 214 | uint8_t bInterfaceNumber; 215 | uint8_t bAlternateSetting; 216 | uint8_t bNumEndpoints; 217 | uint8_t bInterfaceClass; 218 | uint8_t bInterfaceSubclass; 219 | uint8_t bInterfaceProtocol; 220 | uint8_t iInterface; 221 | }; 222 | 223 | /** Endpoint Descriptor */ 224 | struct endpoint_descriptor { 225 | // ... 226 | uint8_t bLength; 227 | uint8_t bDescriptorType; /**< Set to DESC_ENDPOINT */ 228 | uint8_t bEndpointAddress; 229 | uint8_t bmAttributes; 230 | uint16_t wMaxPacketSize; 231 | uint8_t bInterval; 232 | }; 233 | 234 | /** String Descriptor */ 235 | struct string_descriptor { 236 | uint8_t bLength; 237 | uint8_t bDescriptorType; /**< Set to DESC_STRING */ 238 | uint16_t chars[]; 239 | }; 240 | 241 | /** Interface Association Descriptor 242 | * 243 | * See the Interface Association Descriptors Engineering Change Note (ECN) 244 | * available from www.usb.org . 245 | */ 246 | struct interface_association_descriptor { 247 | uint8_t bLength; /**< Set to 8 bytes */ 248 | uint8_t bDescriptorType; /**< Set to DESC_INTERFACE_ASSOCIATION = 0xB */ 249 | uint8_t bFirstInterface; 250 | uint8_t bInterfaceCount; 251 | uint8_t bFunctionClass; 252 | uint8_t bFunctionSubClass; 253 | uint8_t bFunctionProtocol; 254 | uint8_t iFunction; /**< String Descriptor Index */ 255 | }; 256 | 257 | /* Doxygen end-of-group for ch9_items */ 258 | /** @}*/ 259 | 260 | 261 | /** @cond INTERNAL */ 262 | 263 | /* So far this is the best place for these macros because they are used in 264 | * usb.c and also in the application's usb_descriptors.c. Most applications 265 | * will not need to include this file outside their usb_descriptors.c, so 266 | * there isn't much namespace pollution. 267 | */ 268 | #define USB_ARRAYLEN(X) (sizeof(X)/sizeof(*X)) 269 | #define STATIC_SIZE_CHECK_EQUAL(X,Y) typedef char USB_CONCAT(STATIC_SIZE_CHECK_LINE_,__LINE__) [(X==Y)?1:-1] 270 | #define USB_CONCAT(X,Y) USB_CONCAT_HIDDEN(X,Y) 271 | #define USB_CONCAT_HIDDEN(X,Y) X ## Y 272 | 273 | /** @endcond */ 274 | 275 | 276 | #if defined(__XC16__) || defined(__XC32__) 277 | #pragma pack(pop) 278 | #elif __XC8 279 | #else 280 | #error "Compiler not supported" 281 | #endif 282 | 283 | /* Doxygen end-of-group for public_api */ 284 | /** @}*/ 285 | 286 | #endif /* USB_CH9_H__ */ 287 | -------------------------------------------------------------------------------- /usb/include/usb_microsoft.h: -------------------------------------------------------------------------------- 1 | /* 2 | * M-Stack Microsoft-Specific OS Descriptors 3 | * Copyright (C) 2013 Alan Ott 4 | * Copyright (C) 2013 Signal 11 Software 5 | * 6 | * 2013-08-27 7 | * 8 | * M-Stack is free software: you can redistribute it and/or modify it under 9 | * the terms of the GNU Lesser General Public License as published by the 10 | * Free Software Foundation, version 3; or the Apache License, version 2.0 11 | * as published by the Apache Software Foundation. If you have purchased a 12 | * commercial license for this software from Signal 11 Software, your 13 | * commerical license superceeds the information in this header. 14 | * 15 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 16 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 18 | * License for more details. 19 | * 20 | * You should have received a copy of the GNU Lesser General Public License 21 | * along with this software. If not, see . 22 | * 23 | * You should have received a copy of the Apache License, verion 2.0 along 24 | * with this software. If not, see . 25 | */ 26 | 27 | #ifndef USB_MICROSOFT_H__ 28 | #define USB_MICROSOFT_H__ 29 | 30 | /** @file usb.h 31 | * @brief Microsoft-Specific OS Descriptors 32 | * @defgroup public_api Public API 33 | */ 34 | 35 | /** @addtogroup public_api 36 | * @{ 37 | */ 38 | 39 | #include 40 | 41 | #if defined(__XC16__) || defined(__XC32__) 42 | #pragma pack(push, 1) 43 | #elif __XC8 44 | #else 45 | #error "Compiler not supported" 46 | #endif 47 | 48 | /** @defgroup microsoft_items Microsoft-Specific Descriptors 49 | * @brief Packet structs from Microsoft's documentation which deal with 50 | * the Microsoft OS String Descriptor and the Extended Compat Descriptors. 51 | * 52 | * For more information about these structures, see the Microsoft 53 | * documentation at http://msdn.microsoft.com/library/windows/hardware/gg463182 54 | * or search for "Microsoft OS Descriptors" on http://msdn.microsoft.com . 55 | * Also see docs/winusb.txt in the M-Stack distribution. 56 | * 57 | * @addtogroup microsoft_items 58 | * @{ 59 | */ 60 | 61 | /** OS String Descriptor 62 | * 63 | * This is the first descriptor Windows will request, as string number 0xee. 64 | */ 65 | struct microsoft_os_descriptor { 66 | uint8_t bLength; /**< set to 0x12 */ 67 | uint8_t bDescriptorType; /**< set to 0x3 */ 68 | uint16_t qwSignature[7]; /**< set to "MSFT100" (Unicode) (no NULL) */ 69 | uint8_t bMS_VendorCode; /**< Set to the bRequest by which the host 70 | should ask for the Compat ID and 71 | Property descriptors. */ 72 | uint8_t bPad; /**< Set to 0x0 */ 73 | }; 74 | 75 | /** Extended Compat ID Header 76 | * 77 | * This is the header for the Extended Compat ID Descriptor 78 | */ 79 | struct microsoft_extended_compat_header { 80 | uint32_t dwLength; /**< Total length of descriptor (header + functions) */ 81 | uint16_t bcdVersion; /**< Descriptor version number, 0x0100. */ 82 | uint16_t wIndex; /**< This OS feature descriptor; set to 0x04. */ 83 | uint8_t bCount; /**< Number of custom property sections */ 84 | uint8_t reserved[7]; 85 | }; 86 | 87 | /** Extended Compat ID Function 88 | * 89 | * This is the function struct for the Extended Compat ID Descriptor 90 | */ 91 | struct microsoft_extended_compat_function { 92 | uint8_t bFirstInterfaceNumber; /**< The interface or function number */ 93 | uint8_t reserved; 94 | uint8_t compatibleID[8]; /**< Compatible String */ 95 | uint8_t subCompatibleID[8]; /**< Subcompatible String */ 96 | uint8_t reserved2[6]; 97 | }; 98 | 99 | /** Extended Properties Header 100 | * 101 | * This is the header for the Extended Properties Descriptor 102 | */ 103 | struct microsoft_extended_properties_header { 104 | uint32_t dwLength; /**< Total length of descriptor (header + functions) */ 105 | uint16_t bcdVersion; /**< Descriptor version number, 0x0100. */ 106 | uint16_t wIndex; /**< This OS feature descriptor; set to 0x04. */ 107 | uint16_t bCount; /**< Number of custom property sections */ 108 | }; 109 | 110 | /** Extended Property Section header 111 | * 112 | * This is the first part of the Extended Property Section, which is a 113 | * variable-length descriptor. The Variable-length types must be packed 114 | * manually after this section header. 115 | * 116 | */ 117 | struct microsoft_extended_property_section_header { 118 | uint32_t dwSize; /**< Size of this section (this struct + data) */ 119 | uint32_t dwPropertyDataType; /**< Property Data Format */ 120 | 121 | /* Variable-length fields and lengths: 122 | uint16_t wPropertyNameLength; 123 | uint16_t bPropertyName[]; 124 | uint32_t dwPropertyDataLength; 125 | uint8_t bPropertyData[]; 126 | */ 127 | }; 128 | 129 | #ifdef MICROSOFT_COMPAT_ID_DESCRIPTOR_FUNC 130 | /** @brief Callback for the GET_MS_DESCRIPTOR/CompatID request 131 | * 132 | * MICROSOFT_COMPAT_ID_DESCRIPTOR_FUNC() is called when a @p 133 | * GET_MS_DESCRIPTOR request is received from the host with a wIndex of 0x0004. 134 | * The value of MS_GET_DESCRIPTOR request is defined by 135 | * MICROSOFT_OS_DESC_VENDOR_CODE which is set in usb_config.h, and reported to 136 | * the host as part of the @p microsoft_os_descriptor. See the MSDN 137 | * documentation on "Microsoft OS Descriptors" for more information. 138 | * 139 | * @param interface The interface for which the descriptor is queried 140 | * @param descriptor a pointer to a pointer which should be set to the 141 | * descriptor data. 142 | * @returns 143 | * Return the length of the descriptor pointed to by @p *descriptor, or -1 144 | * if the descriptor does not exist. 145 | */ 146 | uint16_t MICROSOFT_COMPAT_ID_DESCRIPTOR_FUNC(uint8_t interface, 147 | const void **descriptor); 148 | #endif 149 | 150 | #ifdef MICROSOFT_CUSTOM_PROPERTY_DESCRIPTOR_FUNC 151 | /** @brief Callback for the GET_MS_DESCRIPTOR/Custom_Property request 152 | * 153 | * MICROSOFT_CUSTOM_PROPERTY_DESCRIPTOR_FUNC() is called when a @p 154 | * GET_MS_DESCRIPTOR request with a wIndex of 0x0005 is received from the host. 155 | * The value of the MS_GET_DESCRIPTOR request is defined by 156 | * MICROSOFT_OS_DESC_VENDOR_CODE which is set in usb_config.h, and reported to 157 | * the host as part of the @p microsoft_os_descriptor. See the MSDN 158 | * documentation on "Microsoft OS Descriptors" for more information. 159 | * 160 | * @param interface The interface for which the descriptor is queried 161 | * @param descriptor a pointer to a pointer which should be set to the 162 | * descriptor data. 163 | * @returns 164 | * Return the length of the descriptor pointed to by @p *descriptor, or -1 165 | * if the descriptor does not exist. 166 | */ 167 | uint16_t MICROSOFT_CUSTOM_PROPERTY_DESCRIPTOR_FUNC(uint8_t interface, 168 | const void **descriptor); 169 | #endif 170 | 171 | /* Doxygen end-of-group for microsoft_items */ 172 | /** @}*/ 173 | 174 | #if defined(__XC16__) || defined(__XC32__) 175 | #pragma pack(pop) 176 | #elif __XC8 177 | #else 178 | #error "Compiler not supported" 179 | #endif 180 | 181 | /* Doxygen end-of-group for public_api */ 182 | /** @}*/ 183 | 184 | #endif /* USB_MICROSOFT_H__ */ 185 | -------------------------------------------------------------------------------- /usb/src/usb_hid.c: -------------------------------------------------------------------------------- 1 | /* 2 | * M-Stack USB Device Stack Implementation 3 | * Copyright (C) 2013 Alan Ott 4 | * Copyright (C) 2013 Signal 11 Software 5 | * 6 | * Initial version for PIC18, 2008-02-24 7 | * PIC24 port, 2013-08-13 8 | * 9 | * M-Stack is free software: you can redistribute it and/or modify it under 10 | * the terms of the GNU Lesser General Public License as published by the 11 | * Free Software Foundation, version 3; or the Apache License, version 2.0 12 | * as published by the Apache Software Foundation. If you have purchased a 13 | * commercial license for this software from Signal 11 Software, your 14 | * commerical license superceeds the information in this header. 15 | * 16 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 17 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 18 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 19 | * License for more details. 20 | * 21 | * You should have received a copy of the GNU Lesser General Public License 22 | * along with this software. If not, see . 23 | * 24 | * You should have received a copy of the Apache License, verion 2.0 along 25 | * with this software. If not, see . 26 | */ 27 | 28 | #include 29 | 30 | #include 31 | #include 32 | #include 33 | 34 | #define MIN(x,y) (((x)<(y))?(x):(y)) 35 | 36 | STATIC_SIZE_CHECK_EQUAL(sizeof(struct hid_descriptor), 9); 37 | STATIC_SIZE_CHECK_EQUAL(sizeof(struct hid_optional_descriptor), 3); 38 | 39 | #ifdef MULTI_CLASS_DEVICE 40 | static uint8_t *hid_interfaces; 41 | static uint8_t num_hid_interfaces; 42 | 43 | void hid_set_interface_list(uint8_t *interfaces, uint8_t num_interfaces) 44 | { 45 | hid_interfaces = interfaces; 46 | num_hid_interfaces = num_interfaces; 47 | } 48 | #endif 49 | 50 | uint8_t process_hid_setup_request(const struct setup_packet *setup) 51 | { 52 | /* The following comes from the HID spec 1.11, section 7.1.1 */ 53 | 54 | uint8_t interface = setup->wIndex; 55 | 56 | #ifdef MULTI_CLASS_DEVICE 57 | /* Check the interface first to make sure the destination is a 58 | * HID interface. Composite devices will need to call 59 | * hid_set_interface_list() first. 60 | */ 61 | uint8_t i; 62 | for (i = 0; i < num_hid_interfaces; i++) { 63 | if (interface == hid_interfaces[i]) 64 | break; 65 | } 66 | 67 | /* Return if interface is not in the list of HID interfaces. */ 68 | if (i == num_hid_interfaces) 69 | return -1; 70 | #endif 71 | 72 | if (setup->bRequest == GET_DESCRIPTOR && 73 | setup->REQUEST.bmRequestType == 0x81) { 74 | uint8_t descriptor = ((setup->wValue >> 8) & 0x00ff); 75 | 76 | const void *desc; 77 | int16_t len = -1; 78 | 79 | if (descriptor == DESC_HID) { 80 | len = USB_HID_DESCRIPTOR_FUNC(interface, &desc); 81 | } 82 | else if (descriptor == DESC_REPORT) { 83 | len = USB_HID_REPORT_DESCRIPTOR_FUNC(interface, &desc); 84 | } 85 | #ifdef USB_HID_PHYSICAL_DESCRIPTOR_FUNC 86 | else if (descriptor == DESC_PHYSICAL) { 87 | uint8_t descriptor_index = setup->wValue & 0x00ff; 88 | len = USB_HID_PHYSICAL_DESCRIPTOR_FUNC(interface, descriptor_index, &desc); 89 | } 90 | #endif 91 | if (len < 0) 92 | return -1; 93 | 94 | usb_send_data_stage((void*) desc, min(len, setup->wLength), NULL, NULL); 95 | return 0; 96 | } 97 | 98 | /* No support for Set_Descriptor */ 99 | 100 | #ifdef HID_GET_REPORT_CALLBACK 101 | const void *desc; 102 | int16_t len = -1; 103 | usb_ep0_data_stage_callback callback; 104 | void *context; 105 | if (setup->bRequest == HID_GET_REPORT && 106 | setup->REQUEST.bmRequestType == 0xa1) { 107 | uint8_t report_type = (setup->wValue >> 8) & 0x00ff; 108 | uint8_t report_id = setup->wValue & 0x00ff; 109 | len = HID_GET_REPORT_CALLBACK(interface/*interface*/, 110 | report_type, report_id, 111 | &desc, &callback, &context); 112 | if (len < 0) 113 | return -1; 114 | 115 | usb_send_data_stage((void*)desc, min(len, setup->wLength), callback, context); 116 | return 0; 117 | } 118 | #endif 119 | 120 | #ifdef HID_SET_REPORT_CALLBACK 121 | if (setup->bRequest == HID_SET_REPORT && 122 | setup->REQUEST.bmRequestType == 0x21) { 123 | uint8_t report_type = (setup->wValue >> 8) & 0x00ff; 124 | uint8_t report_id = setup->wValue & 0x00ff; 125 | int8_t res = HID_SET_REPORT_CALLBACK(interface, 126 | report_type, report_id); 127 | return res; 128 | } 129 | #endif 130 | 131 | #ifdef HID_GET_IDLE_CALLBACK 132 | if (setup->bRequest == HID_GET_IDLE && 133 | setup->REQUEST.bmRequestType == 0xa1) { 134 | uint8_t report_id = setup->wValue & 0x00ff; 135 | uint8_t res = HID_GET_IDLE_CALLBACK(interface, report_id); 136 | 137 | usb_send_data_stage((char*)&res, 1, NULL, NULL); 138 | return 0; 139 | } 140 | #endif 141 | 142 | #ifdef HID_SET_IDLE_CALLBACK 143 | if (setup->bRequest == HID_SET_IDLE && 144 | setup->REQUEST.bmRequestType == 0x21) { 145 | uint8_t duration = (setup->wValue >> 8) & 0x00ff; 146 | uint8_t report_id = setup->wValue & 0x00ff; 147 | uint8_t res = HID_SET_IDLE_CALLBACK(interface, report_id, 148 | duration); 149 | 150 | return res; 151 | } 152 | #endif 153 | 154 | #ifdef HID_GET_PROTOCOL_CALLBACK 155 | if (setup->bRequest == HID_GET_PROTOCOL && 156 | setup->REQUEST.bmRequestType == 0xa1) { 157 | int8_t res = HID_GET_PROTOCOL_CALLBACK(interface); 158 | if (res < 0) 159 | return -1; 160 | 161 | usb_send_data_stage((char*)&res, 1, NULL, NULL); 162 | return 0; 163 | } 164 | #endif 165 | 166 | #ifdef HID_SET_PROTOCOL_CALLBACK 167 | if (setup->bRequest == HID_SET_PROTOCOL && 168 | setup->REQUEST.bmRequestType == 0x21) { 169 | int8_t res = HID_SET_PROTOCOL_CALLBACK(interface, 170 | setup->wValue); 171 | return res; 172 | } 173 | #endif 174 | 175 | return -1; 176 | } 177 | -------------------------------------------------------------------------------- /usb/src/usb_priv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * M-Stack Private Header File - Don't use outside of this directory 3 | * Copyright (C) 2013 Alan Ott 4 | * Copyright (C) 2013 Signal 11 Software 5 | * 6 | * 2015-04-04 7 | * 8 | * M-Stack is free software: you can redistribute it and/or modify it under 9 | * the terms of the GNU Lesser General Public License as published by the 10 | * Free Software Foundation, version 3; or the Apache License, version 2.0 11 | * as published by the Apache Software Foundation. If you have purchased a 12 | * commercial license for this software from Signal 11 Software, your 13 | * commerical license superceeds the information in this header. 14 | * 15 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 16 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 18 | * License for more details. 19 | * 20 | * You should have received a copy of the GNU Lesser General Public License 21 | * along with this software. If not, see . 22 | * 23 | * You should have received a copy of the Apache License, verion 2.0 along 24 | * with this software. If not, see . 25 | */ 26 | 27 | #ifndef USB_PRIV_H__ 28 | #define USB_PRIV_H__ 29 | 30 | #include 31 | 32 | /* Private M-Stack functions */ 33 | #ifdef USB_USE_INTERRUPTS 34 | /* Manipulate the transaction (token) interrupt. There is no stack used 35 | * here, so care must be used to ensure that calls to these functions are 36 | * not nested. */ 37 | void usb_disable_transaction_interrupt(); 38 | void usb_enable_transaction_interrupt(); 39 | #else 40 | #define usb_disable_transaction_interrupt 41 | #define usb_enable_transaction_interrupt 42 | #endif 43 | 44 | #endif /* USB_PRIV_H__ */ 45 | -------------------------------------------------------------------------------- /usb/src/usb_winusb.c: -------------------------------------------------------------------------------- 1 | /* 2 | * M-Stack Automatic WinUSB Support 3 | * Copyright (C) 2013 Alan Ott 4 | * Copyright (C) 2013 Signal 11 Software 5 | * 6 | * 2013-10-12 7 | * 8 | * M-Stack is free software: you can redistribute it and/or modify it under 9 | * the terms of the GNU Lesser General Public License as published by the 10 | * Free Software Foundation, version 3; or the Apache License, version 2.0 11 | * as published by the Apache Software Foundation. If you have purchased a 12 | * commercial license for this software from Signal 11 Software, your 13 | * commerical license superceeds the information in this header. 14 | * 15 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 16 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 18 | * License for more details. 19 | * 20 | * You should have received a copy of the GNU Lesser General Public License 21 | * along with this software. If not, see . 22 | * 23 | * You should have received a copy of the Apache License, verion 2.0 along 24 | * with this software. If not, see . 25 | */ 26 | 27 | #include 28 | #include "usb_config.h" 29 | #include "usb_microsoft.h" 30 | #include "usb_winusb.h" 31 | 32 | #ifdef AUTOMATIC_WINUSB_SUPPORT 33 | 34 | /* Microsoft-specific descriptors for automatic binding of the WinUSB driver. 35 | * See docs/winusb.txt for details. */ 36 | struct extended_compat_descriptor_packet { 37 | struct microsoft_extended_compat_header header; 38 | struct microsoft_extended_compat_function function; 39 | }; 40 | 41 | static struct extended_compat_descriptor_packet 42 | this_extended_compat_descriptor = 43 | { 44 | /* Header */ 45 | { 46 | sizeof(struct extended_compat_descriptor_packet), /* dwLength */ 47 | 0x0100, /* dwVersion*/ 48 | 0x0004, /* wIndex: 0x0004 = Extended Compat ID */ 49 | 1, /* bCount, number of custom property sections */ 50 | {0}, /* reserved[7] */ 51 | }, 52 | 53 | /* Function */ 54 | { 55 | 0x0, /* bFirstInterfaceNumber */ 56 | 0x1, /* reserved. Set to 1 in the Microsoft example */ 57 | "WINUSB", /* compatibleID[8] */ 58 | "", /* subCompatibleID[8] */ 59 | {0}, /* reserved2[6] */ 60 | }, 61 | }; 62 | 63 | static struct microsoft_extended_properties_header 64 | interface_0_property_descriptor = 65 | { 66 | sizeof(interface_0_property_descriptor), /* dwLength */ 67 | 0x0100, /* bcdVersion */ 68 | 0x0005, /* wIndex, Extended Properties descriptor */ 69 | 0x0, /* bCount, Number of custom property sections */ 70 | }; 71 | 72 | uint16_t m_stack_winusb_get_microsoft_compat(uint8_t interface, 73 | const void **descriptor) 74 | { 75 | /* Check the interface here for composite devices. */ 76 | *descriptor = &this_extended_compat_descriptor; 77 | return sizeof(this_extended_compat_descriptor); 78 | } 79 | 80 | uint16_t m_stack_winusb_get_microsoft_property(uint8_t interface, 81 | const void **descriptor) 82 | { 83 | /* Check the interface here for composite devices. */ 84 | *descriptor = &interface_0_property_descriptor; 85 | return sizeof(interface_0_property_descriptor); 86 | } 87 | 88 | #endif /* AUTOMATIC_WINUSB_SUPPORT */ 89 | -------------------------------------------------------------------------------- /usb/src/usb_winusb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * M-Stack Automatic WinUSB Support 3 | * Copyright (C) 2013 Alan Ott 4 | * Copyright (C) 2013 Signal 11 Software 5 | * 6 | * 2013-10-12 7 | * 8 | * M-Stack is free software: you can redistribute it and/or modify it under 9 | * the terms of the GNU Lesser General Public License as published by the 10 | * Free Software Foundation, version 3; or the Apache License, version 2.0 11 | * as published by the Apache Software Foundation. If you have purchased a 12 | * commercial license for this software from Signal 11 Software, your 13 | * commerical license superceeds the information in this header. 14 | * 15 | * M-Stack is distributed in the hope that it will be useful, but WITHOUT 16 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 18 | * License for more details. 19 | * 20 | * You should have received a copy of the GNU Lesser General Public License 21 | * along with this software. If not, see . 22 | * 23 | * You should have received a copy of the Apache License, verion 2.0 along 24 | * with this software. If not, see . 25 | */ 26 | 27 | #ifndef USB_WINUSB_H__ 28 | #define USB_WINUSB_H__ 29 | 30 | #include 31 | 32 | /* Functions for automatic WinUSB support */ 33 | 34 | uint16_t m_stack_winusb_get_microsoft_compat(uint8_t interface, 35 | const void **descriptor); 36 | 37 | uint16_t m_stack_winusb_get_microsoft_property(uint8_t interface, 38 | const void **descriptor); 39 | 40 | #endif /* USB_WINUSB_H__ */ 41 | --------------------------------------------------------------------------------