From 300a2517e69d972201c2cb80b1dd1f014c4451bc Mon Sep 17 00:00:00 2001 From: Riku Viitanen Date: Mon, 28 Aug 2023 00:22:13 +0300 Subject: [PATCH 01/24] Document performance Signed-off-by: Riku Viitanen --- readme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/readme.md b/readme.md index ef43e64..422db96 100644 --- a/readme.md +++ b/readme.md @@ -4,6 +4,8 @@ Slightly less terrible serprog implementation for the Raspberry Pi Pico and possibly other RP2040 based boards. Based on pico-serprog by GitHub user "stacksmashing". Further improved by "kukrimate". +This takes about 17 seconds to read the 8MiB BIOS chip of an X200. + Pinout for the SPI lines: | Pin | Function | |-----|----------| From 51a50ac9db8c90e4e66f35e820da26875b807908 Mon Sep 17 00:00:00 2001 From: Riku Viitanen Date: Fri, 1 Sep 2023 05:28:01 +0300 Subject: [PATCH 02/24] Add pinout.png Based on pico-pinout.svg by Raspberry Pi Ltd, released under the Creative Commons Attribution-ShareAlike 4.0 International license. https://www.raspberrypi.com/documentation/microcontrollers/images/pico-pinout.svg https://creativecommons.org/licenses/by-sa/4.0/ Signed-off-by: Riku Viitanen --- pinout.png | Bin 0 -> 11540 bytes readme.md | 16 ++++++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 pinout.png diff --git a/pinout.png b/pinout.png new file mode 100644 index 0000000000000000000000000000000000000000..86776680e614b88d6b49e6edc874d3948437f770 GIT binary patch literal 11540 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 literal 0 HcmV?d00001 diff --git a/readme.md b/readme.md index 422db96..b452a1f 100644 --- a/readme.md +++ b/readme.md @@ -9,10 +9,12 @@ This takes about 17 seconds to read the 8MiB BIOS chip of an X200. Pinout for the SPI lines: | Pin | Function | |-----|----------| -| GP5 | CS | -| GP4 | MISO | -| GP3 | MOSI | -| GP2 | SCK | +| 7 | CS | +| 6 | MISO | +| 5 | MOSI | +| 4 | SCK | + +![Pico pinout](pinout.png) ## Compiling @@ -53,3 +55,9 @@ flashrom -p serprog:dev=/dev/ttyACMx,spispeed=32M -w flash.bin As a lot of the code itself was heavily inspired/influenced by `stm32-vserprog` this code is licensed under GPLv3. +pinout.png is based on +[pico-pinout.svg](https://www.raspberrypi.com/documentation/microcontrollers/images/pico-pinout.svg) +by Raspberry Pi Ltd, under the +[Creative Commons Attribution-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-sa/4.0/) +license. + From c8c16e9c11fe9e5b7230ff358f79de3f1951e1d9 Mon Sep 17 00:00:00 2001 From: Riku Viitanen Date: Fri, 1 Sep 2023 05:34:27 +0300 Subject: [PATCH 03/24] Add CC-BY-SA 4.0 International license Source: https://creativecommons.org/licenses/by-sa/4.0/legalcode.txt --- COPYING.CC-BY-SA | 428 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 428 insertions(+) create mode 100644 COPYING.CC-BY-SA diff --git a/COPYING.CC-BY-SA b/COPYING.CC-BY-SA new file mode 100644 index 0000000..2d58298 --- /dev/null +++ b/COPYING.CC-BY-SA @@ -0,0 +1,428 @@ +Attribution-ShareAlike 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution-ShareAlike 4.0 International Public +License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution-ShareAlike 4.0 International Public License ("Public +License"). To the extent this Public License may be interpreted as a +contract, You are granted the Licensed Rights in consideration of Your +acceptance of these terms and conditions, and the Licensor grants You +such rights in consideration of benefits the Licensor receives from +making the Licensed Material available under these terms and +conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. BY-SA Compatible License means a license listed at + creativecommons.org/compatiblelicenses, approved by Creative + Commons as essentially the equivalent of this Public License. + + d. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + e. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + f. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + g. License Elements means the license attributes listed in the name + of a Creative Commons Public License. The License Elements of this + Public License are Attribution and ShareAlike. + + h. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + i. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + j. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + k. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + l. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + m. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. Additional offer from the Licensor -- Adapted Material. + Every recipient of Adapted Material from You + automatically receives an offer from the Licensor to + exercise the Licensed Rights in the Adapted Material + under the conditions of the Adapter's License You apply. + + c. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + b. ShareAlike. + + In addition to the conditions in Section 3(a), if You Share + Adapted Material You produce, the following conditions also apply. + + 1. The Adapter's License You apply must be a Creative Commons + license with the same License Elements, this version or + later, or a BY-SA Compatible License. + + 2. You must include the text of, or the URI or hyperlink to, the + Adapter's License You apply. You may satisfy this condition + in any reasonable manner based on the medium, means, and + context in which You Share Adapted Material. + + 3. You may not offer or impose any additional or different terms + or conditions on, or apply any Effective Technological + Measures to, Adapted Material that restrict exercise of the + rights granted under the Adapter's License You apply. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material, + including for purposes of Section 3(b); and + + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + + +======================================================================= + +Creative Commons is not a party to its public +licenses. Notwithstanding, Creative Commons may elect to apply one of +its public licenses to material it publishes and in those instances +will be considered the “Licensor.” The text of the Creative Commons +public licenses is dedicated to the public domain under the CC0 Public +Domain Dedication. Except for the limited purpose of indicating that +material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the +public licenses. + +Creative Commons may be contacted at creativecommons.org. + From 030bfdfa942e609bb1a5836e3631217755e1a0a4 Mon Sep 17 00:00:00 2001 From: Riku Viitanen Date: Mon, 4 Sep 2023 20:12:50 +0300 Subject: [PATCH 04/24] Make USB descriptor less generic iManufacturer=libreboot.org iProduct=pico-serprog iInterface=serprog iSerial=64-bit ID, unique to each board (actually flash chip) Since VID and PID are unchanged, functionality stays the same. This makes it easier to identify the programmer, whether manually or in udev rules. lsusb output: Bus 002 Device 025: ID cafe:4001 libreboot.org pico-serprog dmesg output: usb 2-1.2: new full-speed USB device number 25 using ehci-pci usb 2-1.2: New USB device found, idVendor=cafe, idProduct=4001, bcdDevice= 1.00 usb 2-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3 usb 2-1.2: Product: pico-serprog usb 2-1.2: Manufacturer: libreboot.org usb 2-1.2: SerialNumber: E661A4D417788C29 cdc_acm 2-1.2:1.0: ttyACM0: USB ACM device Signed-off-by: Riku Viitanen --- CMakeLists.txt | 2 +- usb_descriptors.c | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f952409..1bf101f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,5 +7,5 @@ pico_sdk_init() add_executable(pico_serprog) target_sources(pico_serprog PRIVATE main.c usb_descriptors.c) -target_link_libraries(pico_serprog PRIVATE pico_stdlib hardware_spi tinyusb_device) +target_link_libraries(pico_serprog PRIVATE pico_stdlib pico_unique_id hardware_spi tinyusb_device) pico_add_extra_outputs(pico_serprog) diff --git a/usb_descriptors.c b/usb_descriptors.c index 895111e..e4295d7 100644 --- a/usb_descriptors.c +++ b/usb_descriptors.c @@ -24,6 +24,7 @@ */ #include "tusb.h" +#include "pico/unique_id.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. @@ -152,14 +153,16 @@ uint8_t const * tud_descriptor_configuration_cb(uint8_t index) // String Descriptors //--------------------------------------------------------------------+ +char board_serial[2 * PICO_UNIQUE_BOARD_ID_SIZE_BYTES + 1]; + // array of pointer to string descriptors -char const* string_desc_arr [] = +const char* const string_desc_arr [] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) - "TinyUSB", // 1: Manufacturer - "TinyUSB Device", // 2: Product - "123456", // 3: Serials, should use chip ID - "TinyUSB CDC", // 4: CDC Interface + "libreboot.org", // 1: Manufacturer + "pico-serprog", // 2: Product + board_serial, // 3: Serial, should use chip ID + "serprog", // 4: CDC Interface }; static uint16_t _desc_str[32]; @@ -172,6 +175,8 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) uint8_t chr_count; + pico_get_unique_board_id_string(board_serial, sizeof(board_serial)); + if ( index == 0) { memcpy(&_desc_str[1], string_desc_arr[0], 2); From 36bc681dc2a5056a42dcf6104d69d2518c3c1dc1 Mon Sep 17 00:00:00 2001 From: Riku Viitanen Date: Mon, 4 Sep 2023 22:03:35 +0300 Subject: [PATCH 05/24] Include board name in product string --- usb_descriptors.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/usb_descriptors.c b/usb_descriptors.c index e4295d7..5e9eb5f 100644 --- a/usb_descriptors.c +++ b/usb_descriptors.c @@ -158,11 +158,11 @@ char board_serial[2 * PICO_UNIQUE_BOARD_ID_SIZE_BYTES + 1]; // array of pointer to string descriptors const char* const string_desc_arr [] = { - (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) - "libreboot.org", // 1: Manufacturer - "pico-serprog", // 2: Product - board_serial, // 3: Serial, should use chip ID - "serprog", // 4: CDC Interface + (const char[]) { 0x09, 0x04 }, // 0: is English language + "libreboot.org", // 1: Manufacturer + "pico-serprog (" PICO_BOARD ")", // 2: Product + board_serial, // 3: Serial number filled later + "serprog", // 4: CDC Interface }; static uint16_t _desc_str[32]; From f9be0c789ca0aee279a4b4b12f1f27009cfcd107 Mon Sep 17 00:00:00 2001 From: Riku Viitanen Date: Tue, 5 Sep 2023 19:53:33 +0300 Subject: [PATCH 06/24] Add udev rule to create /dev/serprog0, 1, 2, ... Just copy it into /etc/udev/rules.d/ --- 99-serprog.rules | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 99-serprog.rules diff --git a/99-serprog.rules b/99-serprog.rules new file mode 100644 index 0000000..69a7f4a --- /dev/null +++ b/99-serprog.rules @@ -0,0 +1,6 @@ +# udev rule that creates symlinks like /dev/serprog0 +# +# only matches standard usb cdc-acm devices (/dev/ttyACM*) since non-standard +# (ftdi etc) uart converters will probably have a generic descriptor anyway + +DRIVERS=="cdc_acm", ATTRS{interface}=="serprog", SYMLINK+="serprog%n" From 0f4b78a83d8587a5e3e22d6c6aaca062e741135a Mon Sep 17 00:00:00 2001 From: Riku Viitanen Date: Tue, 28 Nov 2023 20:32:42 +0200 Subject: [PATCH 07/24] light led when processing a command Signed-off-by: Riku Viitanen --- main.c | 248 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 132 insertions(+), 116 deletions(-) diff --git a/main.c b/main.c index fda977d..68b5970 100644 --- a/main.c +++ b/main.c @@ -1,5 +1,6 @@ /** * Copyright (C) 2021, Mate Kukri + * Copyright (C) 2023, Riku Viitanen * Based on "pico-serprog" by Thomas Roth * * Licensed under GPLv3 @@ -23,8 +24,15 @@ #define SPI_MOSI 3 #define SPI_SCK 2 +#define PIN_LED PICO_DEFAULT_LED_PIN + + static void enable_spi(uint baud) { + // Setup status LED + gpio_init(PIN_LED); + gpio_set_dir(PIN_LED, GPIO_OUT); + // Setup chip select GPIO gpio_init(SPI_CS); gpio_put(SPI_CS, 1); @@ -117,127 +125,135 @@ static inline void sendbyte_blocking(uint8_t b) tud_cdc_n_write(CDC_ITF, &b, 1); } +static void process_command(uint8_t cmd, uint *baud) { + switch (cmd) { + case S_CMD_NOP: + sendbyte_blocking(S_ACK); + break; + case S_CMD_Q_IFACE: + sendbyte_blocking(S_ACK); + sendbyte_blocking(0x01); + sendbyte_blocking(0x00); + break; + case S_CMD_Q_CMDMAP: + { + static const uint32_t cmdmap[8] = { + (1 << S_CMD_NOP) | + (1 << S_CMD_Q_IFACE) | + (1 << S_CMD_Q_CMDMAP) | + (1 << S_CMD_Q_PGMNAME) | + (1 << S_CMD_Q_SERBUF) | + (1 << S_CMD_Q_BUSTYPE) | + (1 << S_CMD_SYNCNOP) | + (1 << S_CMD_O_SPIOP) | + (1 << S_CMD_S_BUSTYPE) | + (1 << S_CMD_S_SPI_FREQ)| + (1 << S_CMD_S_PIN_STATE) + }; + + sendbyte_blocking(S_ACK); + sendbytes_blocking((uint8_t *) cmdmap, sizeof cmdmap); + break; + } + case S_CMD_Q_PGMNAME: + { + static const char progname[16] = "pico-serprog"; + + sendbyte_blocking(S_ACK); + sendbytes_blocking(progname, sizeof progname); + break; + } + case S_CMD_Q_SERBUF: + sendbyte_blocking(S_ACK); + sendbyte_blocking(0xFF); + sendbyte_blocking(0xFF); + break; + case S_CMD_Q_BUSTYPE: + sendbyte_blocking(S_ACK); + sendbyte_blocking((1 << 3)); // BUS_SPI + break; + case S_CMD_SYNCNOP: + sendbyte_blocking(S_NAK); + sendbyte_blocking(S_ACK); + break; + case S_CMD_S_BUSTYPE: + // If SPI is among the requsted bus types we succeed, fail otherwise + if((uint8_t) readbyte_blocking() & (1 << 3)) + sendbyte_blocking(S_ACK); + else + sendbyte_blocking(S_NAK); + break; + case S_CMD_O_SPIOP: + { + static uint8_t buf[4096]; + + uint32_t wlen = 0; + readbytes_blocking(&wlen, 3); + uint32_t rlen = 0; + readbytes_blocking(&rlen, 3); + + cs_select(SPI_CS); + + while (wlen) { + uint32_t cur = MIN(wlen, sizeof buf); + readbytes_blocking(buf, cur); + spi_write_blocking(SPI_IF, buf, cur); + wlen -= cur; + } + + sendbyte_blocking(S_ACK); + + while (rlen) { + uint32_t cur = MIN(rlen, sizeof buf); + spi_read_blocking(SPI_IF, 0, buf, cur); + sendbytes_blocking(buf, cur); + rlen -= cur; + } + + cs_deselect(SPI_CS); + } + break; + case S_CMD_S_SPI_FREQ: + { + uint32_t want_baud; + readbytes_blocking(&want_baud, 4); + if (want_baud) { + // Set frequence + *baud = spi_set_baudrate(SPI_IF, want_baud); + // Send back actual value + sendbyte_blocking(S_ACK); + sendbytes_blocking(baud, 4); + } else { + // 0 Hz is reserved + sendbyte_blocking(S_NAK); + } + break; + } + case S_CMD_S_PIN_STATE: + if (readbyte_blocking()) + enable_spi(*baud); + else + disable_spi(); + sendbyte_blocking(S_ACK); + break; + default: + sendbyte_blocking(S_NAK); + break; + } + + tud_cdc_n_write_flush(CDC_ITF); + gpio_put(PIN_LED, 0); +} + static void command_loop(void) { uint baud = spi_get_baudrate(SPI_IF); for (;;) { - switch (readbyte_blocking()) { - case S_CMD_NOP: - sendbyte_blocking(S_ACK); - break; - case S_CMD_Q_IFACE: - sendbyte_blocking(S_ACK); - sendbyte_blocking(0x01); - sendbyte_blocking(0x00); - break; - case S_CMD_Q_CMDMAP: - { - static const uint32_t cmdmap[8] = { - (1 << S_CMD_NOP) | - (1 << S_CMD_Q_IFACE) | - (1 << S_CMD_Q_CMDMAP) | - (1 << S_CMD_Q_PGMNAME) | - (1 << S_CMD_Q_SERBUF) | - (1 << S_CMD_Q_BUSTYPE) | - (1 << S_CMD_SYNCNOP) | - (1 << S_CMD_O_SPIOP) | - (1 << S_CMD_S_BUSTYPE) | - (1 << S_CMD_S_SPI_FREQ)| - (1 << S_CMD_S_PIN_STATE) - }; - - sendbyte_blocking(S_ACK); - sendbytes_blocking((uint8_t *) cmdmap, sizeof cmdmap); - break; - } - case S_CMD_Q_PGMNAME: - { - static const char progname[16] = "pico-serprog"; - - sendbyte_blocking(S_ACK); - sendbytes_blocking(progname, sizeof progname); - break; - } - case S_CMD_Q_SERBUF: - sendbyte_blocking(S_ACK); - sendbyte_blocking(0xFF); - sendbyte_blocking(0xFF); - break; - case S_CMD_Q_BUSTYPE: - sendbyte_blocking(S_ACK); - sendbyte_blocking((1 << 3)); // BUS_SPI - break; - case S_CMD_SYNCNOP: - sendbyte_blocking(S_NAK); - sendbyte_blocking(S_ACK); - break; - case S_CMD_S_BUSTYPE: - // If SPI is among the requsted bus types we succeed, fail otherwise - if((uint8_t) readbyte_blocking() & (1 << 3)) - sendbyte_blocking(S_ACK); - else - sendbyte_blocking(S_NAK); - break; - case S_CMD_O_SPIOP: - { - static uint8_t buf[4096]; - - uint32_t wlen = 0; - readbytes_blocking(&wlen, 3); - uint32_t rlen = 0; - readbytes_blocking(&rlen, 3); - - cs_select(SPI_CS); - - while (wlen) { - uint32_t cur = MIN(wlen, sizeof buf); - readbytes_blocking(buf, cur); - spi_write_blocking(SPI_IF, buf, cur); - wlen -= cur; - } - - sendbyte_blocking(S_ACK); - - while (rlen) { - uint32_t cur = MIN(rlen, sizeof buf); - spi_read_blocking(SPI_IF, 0, buf, cur); - sendbytes_blocking(buf, cur); - rlen -= cur; - } - - cs_deselect(SPI_CS); - } - break; - case S_CMD_S_SPI_FREQ: - { - uint32_t want_baud; - readbytes_blocking(&want_baud, 4); - if (want_baud) { - // Set frequence - baud = spi_set_baudrate(SPI_IF, want_baud); - // Send back actual value - sendbyte_blocking(S_ACK); - sendbytes_blocking(&baud, 4); - } else { - // 0 Hz is reserved - sendbyte_blocking(S_NAK); - } - break; - } - case S_CMD_S_PIN_STATE: - if (readbyte_blocking()) - enable_spi(baud); - else - disable_spi(); - sendbyte_blocking(S_ACK); - break; - default: - sendbyte_blocking(S_NAK); - break; - } - - tud_cdc_n_write_flush(CDC_ITF); + uint8_t cmd = readbyte_blocking(); + gpio_put(PIN_LED, 1); + process_command(cmd, &baud); + gpio_put(PIN_LED, 0); } } From 4f25565a3d6483a4f4db333667179a168ba5c398 Mon Sep 17 00:00:00 2001 From: Riku Viitanen Date: Tue, 28 Nov 2023 21:26:21 +0200 Subject: [PATCH 08/24] add metadata for picotool For now, set a description and link to the code, plus pin definitions: $ picotool info -bp *.uf2 File pico_serprog.uf2: Program Information name: pico_serprog web site: https://codeberg.org/Riku_V/pico-serprog/ description: SPI flash chip programmer using Flashrom's serprog protocol Fixed Pin Information 2: SCK 3: MOSI 4: MISO 5: CS 25: Activity LED Signed-off-by: Riku Viitanen --- main.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/main.c b/main.c index 68b5970..70928bf 100644 --- a/main.c +++ b/main.c @@ -10,7 +10,11 @@ * */ +#define DESCRIPTION "SPI flash chip programmer using Flashrom's serprog protocol" +#define WEBSITE "https://codeberg.org/Riku_V/pico-serprog/" + #include "pico/stdlib.h" +#include "pico/binary_info.h" #include "hardware/spi.h" #include "tusb.h" #include "serprog.h" @@ -259,6 +263,15 @@ static void command_loop(void) int main() { + // Metadata for picotool + bi_decl(bi_program_description(DESCRIPTION)); + bi_decl(bi_program_url(WEBSITE)); + bi_decl(bi_1pin_with_name(PIN_LED, "Activity LED")); + bi_decl(bi_1pin_with_name(SPI_MISO, "MISO")); + bi_decl(bi_1pin_with_name(SPI_MOSI, "MOSI")); + bi_decl(bi_1pin_with_name(SPI_SCK, "SCK")); + bi_decl(bi_1pin_with_name(SPI_CS, "CS")); + // Setup USB tusb_init(); // Setup PL022 SPI From 74f937f86378b607dd4bfd2a759f60fa674ff3de Mon Sep 17 00:00:00 2001 From: Riku Viitanen Date: Wed, 29 Nov 2023 17:11:55 +0200 Subject: [PATCH 09/24] minor refactoring Signed-off-by: Riku Viitanen --- main.c | 49 +++++++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/main.c b/main.c index 70928bf..7eed1c0 100644 --- a/main.c +++ b/main.c @@ -30,6 +30,23 @@ #define PIN_LED PICO_DEFAULT_LED_PIN +static const char progname[16] = "pico-serprog"; + +/* Map of supported serprog commands */ +static const uint32_t cmdmap[8] = { + (1 << S_CMD_NOP) | + (1 << S_CMD_Q_IFACE) | + (1 << S_CMD_Q_CMDMAP) | + (1 << S_CMD_Q_PGMNAME) | + (1 << S_CMD_Q_SERBUF) | + (1 << S_CMD_Q_BUSTYPE) | + (1 << S_CMD_SYNCNOP) | + (1 << S_CMD_O_SPIOP) | + (1 << S_CMD_S_BUSTYPE) | + (1 << S_CMD_S_SPI_FREQ)| + (1 << S_CMD_S_PIN_STATE) +}; + static void enable_spi(uint baud) { @@ -140,33 +157,13 @@ static void process_command(uint8_t cmd, uint *baud) { sendbyte_blocking(0x00); break; case S_CMD_Q_CMDMAP: - { - static const uint32_t cmdmap[8] = { - (1 << S_CMD_NOP) | - (1 << S_CMD_Q_IFACE) | - (1 << S_CMD_Q_CMDMAP) | - (1 << S_CMD_Q_PGMNAME) | - (1 << S_CMD_Q_SERBUF) | - (1 << S_CMD_Q_BUSTYPE) | - (1 << S_CMD_SYNCNOP) | - (1 << S_CMD_O_SPIOP) | - (1 << S_CMD_S_BUSTYPE) | - (1 << S_CMD_S_SPI_FREQ)| - (1 << S_CMD_S_PIN_STATE) - }; - - sendbyte_blocking(S_ACK); - sendbytes_blocking((uint8_t *) cmdmap, sizeof cmdmap); - break; - } + sendbyte_blocking(S_ACK); + sendbytes_blocking((uint8_t *) cmdmap, sizeof cmdmap); + break; case S_CMD_Q_PGMNAME: - { - static const char progname[16] = "pico-serprog"; - - sendbyte_blocking(S_ACK); - sendbytes_blocking(progname, sizeof progname); - break; - } + sendbyte_blocking(S_ACK); + sendbytes_blocking(progname, sizeof progname); + break; case S_CMD_Q_SERBUF: sendbyte_blocking(S_ACK); sendbyte_blocking(0xFF); From f0ad99bdfa84043f6bee581826e876ea1ff0b3ee Mon Sep 17 00:00:00 2001 From: Riku Viitanen Date: Wed, 29 Nov 2023 23:39:58 +0200 Subject: [PATCH 10/24] increase gpio drive strength Signed-off-by: Riku Viitanen --- main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/main.c b/main.c index 7eed1c0..b8a2e49 100644 --- a/main.c +++ b/main.c @@ -64,6 +64,11 @@ static void enable_spi(uint baud) gpio_set_function(SPI_MISO, GPIO_FUNC_SPI); gpio_set_function(SPI_MOSI, GPIO_FUNC_SPI); gpio_set_function(SPI_SCK, GPIO_FUNC_SPI); + + gpio_set_drive_strength(SPI_MISO, GPIO_DRIVE_STRENGTH_12MA); + gpio_set_drive_strength(SPI_MOSI, GPIO_DRIVE_STRENGTH_12MA); + gpio_set_drive_strength(SPI_SCK, GPIO_DRIVE_STRENGTH_12MA); + gpio_set_drive_strength(SPI_CS, GPIO_DRIVE_STRENGTH_12MA); } static void disable_spi() From 0d49d6fcbe33a5af1bff599be6ff84ddda0bc3fe Mon Sep 17 00:00:00 2001 From: Riku Viitanen Date: Sat, 23 Dec 2023 14:58:12 +0200 Subject: [PATCH 11/24] make activity led optional some boards don't define PICO_DEFAULT_LED_PIN, so compiling would fail. let's make led commands conditional on that being defined. some boards have ws2812 addressable rgb leds, which could be supported in the future, if someone wanted to implement it. Signed-off-by: Riku Viitanen --- main.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/main.c b/main.c index b8a2e49..7dd2685 100644 --- a/main.c +++ b/main.c @@ -28,8 +28,6 @@ #define SPI_MOSI 3 #define SPI_SCK 2 -#define PIN_LED PICO_DEFAULT_LED_PIN - static const char progname[16] = "pico-serprog"; /* Map of supported serprog commands */ @@ -50,9 +48,11 @@ static const uint32_t cmdmap[8] = { static void enable_spi(uint baud) { +#ifdef PICO_DEFAULT_LED_PIN // Setup status LED - gpio_init(PIN_LED); - gpio_set_dir(PIN_LED, GPIO_OUT); + gpio_init(PICO_DEFAULT_LED_PIN); + gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT); +#endif // Setup chip select GPIO gpio_init(SPI_CS); @@ -248,7 +248,9 @@ static void process_command(uint8_t cmd, uint *baud) { } tud_cdc_n_write_flush(CDC_ITF); - gpio_put(PIN_LED, 0); +#ifdef PICO_DEFAULT_LED_PIN + gpio_put(PICO_DEFAULT_LED_PIN, 0); +#endif } static void command_loop(void) @@ -257,9 +259,13 @@ static void command_loop(void) for (;;) { uint8_t cmd = readbyte_blocking(); - gpio_put(PIN_LED, 1); +#ifdef PICO_DEFAULT_LED_PIN + gpio_put(PICO_DEFAULT_LED_PIN, 1); +#endif process_command(cmd, &baud); - gpio_put(PIN_LED, 0); +#ifdef PICO_DEFAULT_LED_PIN + gpio_put(PICO_DEFAULT_LED_PIN, 0); +#endif } } @@ -268,7 +274,9 @@ int main() // Metadata for picotool bi_decl(bi_program_description(DESCRIPTION)); bi_decl(bi_program_url(WEBSITE)); - bi_decl(bi_1pin_with_name(PIN_LED, "Activity LED")); +#ifdef PICO_DEFAULT_LED_PIN + bi_decl(bi_1pin_with_name(PICO_DEFAULT_LED_PIN, "Activity LED")); +#endif bi_decl(bi_1pin_with_name(SPI_MISO, "MISO")); bi_decl(bi_1pin_with_name(SPI_MOSI, "MOSI")); bi_decl(bi_1pin_with_name(SPI_SCK, "SCK")); From 6301fbf3ed553e61e626af2785f9e80fa6ca5524 Mon Sep 17 00:00:00 2001 From: Riku Viitanen Date: Mon, 15 Jan 2024 19:28:00 +0200 Subject: [PATCH 12/24] add support for multiple chip selects now, GP5..8 are available as cs=0..3 GP5 is still the default one, which is defaulted to on power-up. Signed-off-by: Riku Viitanen --- main.c | 100 +++++++++++++++++++++++++++++++++++++----------------- serprog.h | 2 ++ 2 files changed, 70 insertions(+), 32 deletions(-) diff --git a/main.c b/main.c index 7dd2685..1b7b5d0 100644 --- a/main.c +++ b/main.c @@ -1,6 +1,6 @@ /** * Copyright (C) 2021, Mate Kukri - * Copyright (C) 2023, Riku Viitanen + * Copyright (C) 2023, 2024, Riku Viitanen * Based on "pico-serprog" by Thomas Roth * * Licensed under GPLv3 @@ -23,29 +23,42 @@ #define SPI_IF spi0 // Which PL022 to use #define SPI_BAUD 12000000 // Default baudrate (12 MHz) -#define SPI_CS 5 +#define SPI_CS_0 5 // The default CS pin #define SPI_MISO 4 #define SPI_MOSI 3 #define SPI_SCK 2 +uint8_t spi_enabled = 0; +uint cs_pin = SPI_CS_0; +#define NUM_CS_AVAILABLE 4 // Number of usable chip selects + static const char progname[16] = "pico-serprog"; /* Map of supported serprog commands */ static const uint32_t cmdmap[8] = { - (1 << S_CMD_NOP) | - (1 << S_CMD_Q_IFACE) | - (1 << S_CMD_Q_CMDMAP) | - (1 << S_CMD_Q_PGMNAME) | - (1 << S_CMD_Q_SERBUF) | - (1 << S_CMD_Q_BUSTYPE) | - (1 << S_CMD_SYNCNOP) | - (1 << S_CMD_O_SPIOP) | - (1 << S_CMD_S_BUSTYPE) | - (1 << S_CMD_S_SPI_FREQ)| - (1 << S_CMD_S_PIN_STATE) + (1 << S_CMD_NOP) | + (1 << S_CMD_Q_IFACE) | + (1 << S_CMD_Q_CMDMAP) | + (1 << S_CMD_Q_PGMNAME) | + (1 << S_CMD_Q_SERBUF) | + (1 << S_CMD_Q_BUSTYPE) | + (1 << S_CMD_SYNCNOP) | + (1 << S_CMD_O_SPIOP) | + (1 << S_CMD_S_BUSTYPE) | + (1 << S_CMD_S_SPI_FREQ) | + (1 << S_CMD_S_PIN_STATE) | + (1 << S_CMD_S_SPI_CS) }; +static void enable_cs(uint pin) +{ + gpio_init(pin); + gpio_put(pin, 1); + gpio_set_dir(pin, GPIO_OUT); + gpio_set_drive_strength(pin, GPIO_DRIVE_STRENGTH_12MA); +} + static void enable_spi(uint baud) { #ifdef PICO_DEFAULT_LED_PIN @@ -54,10 +67,7 @@ static void enable_spi(uint baud) gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT); #endif - // Setup chip select GPIO - gpio_init(SPI_CS); - gpio_put(SPI_CS, 1); - gpio_set_dir(SPI_CS, GPIO_OUT); + enable_cs(cs_pin); // Setup PL022 spi_init(SPI_IF, baud); @@ -68,25 +78,39 @@ static void enable_spi(uint baud) gpio_set_drive_strength(SPI_MISO, GPIO_DRIVE_STRENGTH_12MA); gpio_set_drive_strength(SPI_MOSI, GPIO_DRIVE_STRENGTH_12MA); gpio_set_drive_strength(SPI_SCK, GPIO_DRIVE_STRENGTH_12MA); - gpio_set_drive_strength(SPI_CS, GPIO_DRIVE_STRENGTH_12MA); + + spi_enabled = 1; +} + +static void disable_pin(uint pin) +{ + gpio_init(pin); // Set pin to SIO input + gpio_set_pulls(pin, 0, 0); // Disable all pulls } static void disable_spi() { - // Set all pins to SIO inputs - gpio_init(SPI_CS); - gpio_init(SPI_MISO); - gpio_init(SPI_MOSI); - gpio_init(SPI_SCK); - - // Disable all pulls - gpio_set_pulls(SPI_CS, 0, 0); - gpio_set_pulls(SPI_MISO, 0, 0); - gpio_set_pulls(SPI_MOSI, 0, 0); - gpio_set_pulls(SPI_SCK, 0, 0); + disable_pin(cs_pin); + disable_pin(SPI_MISO); + disable_pin(SPI_MOSI); + disable_pin(SPI_SCK); // Disable SPI peripheral spi_deinit(SPI_IF); + + spi_enabled = 0; +} + +static void set_cs_pin(uint8_t cs) +{ + cs += SPI_CS_0; + if (spi_enabled) { + if (cs_pin != cs) { + disable_pin(cs_pin); + enable_cs(cs); + } + } + cs_pin = cs; } static inline void cs_select(uint cs_pin) @@ -198,7 +222,7 @@ static void process_command(uint8_t cmd, uint *baud) { uint32_t rlen = 0; readbytes_blocking(&rlen, 3); - cs_select(SPI_CS); + cs_select(cs_pin); while (wlen) { uint32_t cur = MIN(wlen, sizeof buf); @@ -216,7 +240,7 @@ static void process_command(uint8_t cmd, uint *baud) { rlen -= cur; } - cs_deselect(SPI_CS); + cs_deselect(cs_pin); } break; case S_CMD_S_SPI_FREQ: @@ -242,6 +266,15 @@ static void process_command(uint8_t cmd, uint *baud) { disable_spi(); sendbyte_blocking(S_ACK); break; + case S_CMD_S_SPI_CS: + uint8_t cs_index = readbyte_blocking(); + if (cs_index < NUM_CS_AVAILABLE) { + set_cs_pin(cs_index); + sendbyte_blocking(S_ACK); + } else { + sendbyte_blocking(S_NAK); + } + break; default: sendbyte_blocking(S_NAK); break; @@ -280,7 +313,10 @@ int main() bi_decl(bi_1pin_with_name(SPI_MISO, "MISO")); bi_decl(bi_1pin_with_name(SPI_MOSI, "MOSI")); bi_decl(bi_1pin_with_name(SPI_SCK, "SCK")); - bi_decl(bi_1pin_with_name(SPI_CS, "CS")); + bi_decl(bi_1pin_with_name(SPI_CS_0, "CS_0 (default)")); + bi_decl(bi_1pin_with_name(SPI_CS_0+1, "CS_1")); + bi_decl(bi_1pin_with_name(SPI_CS_0+2, "CS_2")); + bi_decl(bi_1pin_with_name(SPI_CS_0+3, "CS_3")); // Setup USB tusb_init(); diff --git a/serprog.h b/serprog.h index 70c1820..88c9aba 100644 --- a/serprog.h +++ b/serprog.h @@ -28,4 +28,6 @@ #define S_CMD_S_SPI_FREQ 0x14 /* Set SPI clock frequency */ #define S_CMD_S_PIN_STATE 0x15 /* Enable/disable output drivers */ +#define S_CMD_S_SPI_CS 0x16 /* Select Chip Select to use */ + #endif From 1dc9bb96e4c9fd311a6c1b612dcda36d0023f647 Mon Sep 17 00:00:00 2001 From: Riku Viitanen Date: Sat, 27 Jan 2024 23:55:30 +0200 Subject: [PATCH 13/24] Enable pull-ups on unused chip selects When SPI interface is enabled, no chip selects should be floating. That can cause issues, for example if such a pin is connected to a flash chip with no pull-ups on board. So, enable RP2040's internal pull-ups on those pins. Signed-off-by: Riku Viitanen --- main.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/main.c b/main.c index 1b7b5d0..16289d5 100644 --- a/main.c +++ b/main.c @@ -51,14 +51,19 @@ static const uint32_t cmdmap[8] = { }; -static void enable_cs(uint pin) +static void use_cs(uint pin) { - gpio_init(pin); gpio_put(pin, 1); gpio_set_dir(pin, GPIO_OUT); gpio_set_drive_strength(pin, GPIO_DRIVE_STRENGTH_12MA); } +static void pullup_cs(uint pin) +{ + gpio_set_dir(pin, GPIO_IN); + gpio_pull_up(pin); +} + static void enable_spi(uint baud) { #ifdef PICO_DEFAULT_LED_PIN @@ -67,7 +72,13 @@ static void enable_spi(uint baud) gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT); #endif - enable_cs(cs_pin); + /* Setup default CS as output, others as inputs with pull-ups */ + for (uint8_t i = SPI_CS_0+1; i Date: Sun, 28 Jan 2024 00:05:10 +0200 Subject: [PATCH 14/24] Document multiple Chip Selects Flashrom -> Flashprog. Currently only flashprog supports multiple CS. Signed-off-by: Riku Viitanen --- main.c | 2 +- readme.md | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/main.c b/main.c index 16289d5..f4e512a 100644 --- a/main.c +++ b/main.c @@ -10,7 +10,7 @@ * */ -#define DESCRIPTION "SPI flash chip programmer using Flashrom's serprog protocol" +#define DESCRIPTION "SPI flash chip programmer using Flashprog's serprog protocol" #define WEBSITE "https://codeberg.org/Riku_V/pico-serprog/" #include "pico/stdlib.h" diff --git a/readme.md b/readme.md index b452a1f..5de9ee0 100644 --- a/readme.md +++ b/readme.md @@ -42,12 +42,19 @@ containing something like this will appear: Read chip: ``` -flashrom -p serprog:dev=/dev/ttyACMx,spispeed=32M -r flash.bin +flashprog -p serprog:dev=/dev/ttyACMx,spispeed=32M -r flash.bin ``` Write chip: ``` -flashrom -p serprog:dev=/dev/ttyACMx,spispeed=32M -w flash.bin +flashprog -p serprog:dev=/dev/ttyACMx,spispeed=32M -w flash.bin +``` + +Multiple chips can be connected at the same time. Pins GP5-GP8 are Chip +Selects 0-3, respectively. The firmware defaults to using Chip Select 0. +``` +flashprog -p serprog:dev=/dev/ttyACMx,cs=0 -r chip0.bin +flashprog -p serprog:dev=/dev/ttyACMx,cs=1 -r chip1.bin ``` ## License From bdcb6f6f552da9dee4ec20c0c45421a2e9d08eb5 Mon Sep 17 00:00:00 2001 From: Riku Viitanen Date: Wed, 31 Jan 2024 23:01:32 +0200 Subject: [PATCH 15/24] update readme Signed-off-by: Riku Viitanen --- readme.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 5de9ee0..a0cc2e9 100644 --- a/readme.md +++ b/readme.md @@ -1,8 +1,16 @@ # pico-serprog Slightly less terrible serprog implementation for the Raspberry Pi Pico and -possibly other RP2040 based boards. Based on pico-serprog by GitHub user -"stacksmashing". Further improved by "kukrimate". +other RP2040 based boards. Based on +![pico-serprog by stacksmashing](https://github.com/stacksmashing/pico-serprog/). +Further improved by kukrimate ![here](https://github.com/kukrimate/pico-serprog). +And me (Riku\_V) here. + +Pre-compiled binaries binaries can be downloaded from the +![Libreboot project](https://libreboot.org/download.html#https). + +For a guide on how to flash a chip see +![this page](https://libreboot.org/docs/install/spi.html#raspberry-pi-pico). This takes about 17 seconds to read the 8MiB BIOS chip of an X200. From 556f99e36f0a7e8b35644d3906869b69b867f866 Mon Sep 17 00:00:00 2001 From: Riku Viitanen Date: Wed, 7 Feb 2024 20:16:51 +0200 Subject: [PATCH 16/24] refactoring, fix grammar bug Should fix bug: https://codeberg.org/libreboot/lbmk/issues/182 Declaration aren't allowed immediately after labels. Some compilers are apparently more strict about this, mine didn't even warn about it. Signed-off-by: Riku Viitanen --- main.c | 257 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 132 insertions(+), 125 deletions(-) diff --git a/main.c b/main.c index f4e512a..5c41be9 100644 --- a/main.c +++ b/main.c @@ -22,7 +22,6 @@ #define CDC_ITF 0 // USB CDC interface no #define SPI_IF spi0 // Which PL022 to use -#define SPI_BAUD 12000000 // Default baudrate (12 MHz) #define SPI_CS_0 5 // The default CS pin #define SPI_MISO 4 #define SPI_MOSI 3 @@ -32,6 +31,8 @@ uint8_t spi_enabled = 0; uint cs_pin = SPI_CS_0; #define NUM_CS_AVAILABLE 4 // Number of usable chip selects +uint baud = 12000000; /* Default to 12MHz */ + static const char progname[16] = "pico-serprog"; /* Map of supported serprog commands */ @@ -64,7 +65,7 @@ static void pullup_cs(uint pin) gpio_pull_up(pin); } -static void enable_spi(uint baud) +static void enable_spi() { #ifdef PICO_DEFAULT_LED_PIN // Setup status LED @@ -113,17 +114,6 @@ static void disable_spi() spi_enabled = 0; } -static void set_cs_pin(uint8_t cs) -{ - cs += SPI_CS_0; - if (spi_enabled) { - if (cs_pin != cs) { - pullup_cs(cs_pin); - use_cs(cs); - } - } - cs_pin = cs; -} static inline void cs_select(uint cs_pin) { @@ -187,127 +177,144 @@ static inline void sendbyte_blocking(uint8_t b) tud_cdc_n_write(CDC_ITF, &b, 1); } -static void process_command(uint8_t cmd, uint *baud) { - switch (cmd) { - case S_CMD_NOP: +void s_cmd_s_bustype() +{ + // If SPI is among the requsted bus types we succeed, fail otherwise + if ((uint8_t) readbyte_blocking() & (1 << 3)) sendbyte_blocking(S_ACK); - break; - case S_CMD_Q_IFACE: - sendbyte_blocking(S_ACK); - sendbyte_blocking(0x01); - sendbyte_blocking(0x00); - break; - case S_CMD_Q_CMDMAP: - sendbyte_blocking(S_ACK); - sendbytes_blocking((uint8_t *) cmdmap, sizeof cmdmap); - break; - case S_CMD_Q_PGMNAME: - sendbyte_blocking(S_ACK); - sendbytes_blocking(progname, sizeof progname); - break; - case S_CMD_Q_SERBUF: - sendbyte_blocking(S_ACK); - sendbyte_blocking(0xFF); - sendbyte_blocking(0xFF); - break; - case S_CMD_Q_BUSTYPE: - sendbyte_blocking(S_ACK); - sendbyte_blocking((1 << 3)); // BUS_SPI - break; - case S_CMD_SYNCNOP: + else sendbyte_blocking(S_NAK); - sendbyte_blocking(S_ACK); - break; - case S_CMD_S_BUSTYPE: - // If SPI is among the requsted bus types we succeed, fail otherwise - if((uint8_t) readbyte_blocking() & (1 << 3)) - sendbyte_blocking(S_ACK); - else - sendbyte_blocking(S_NAK); - break; - case S_CMD_O_SPIOP: - { - static uint8_t buf[4096]; - - uint32_t wlen = 0; - readbytes_blocking(&wlen, 3); - uint32_t rlen = 0; - readbytes_blocking(&rlen, 3); - - cs_select(cs_pin); - - while (wlen) { - uint32_t cur = MIN(wlen, sizeof buf); - readbytes_blocking(buf, cur); - spi_write_blocking(SPI_IF, buf, cur); - wlen -= cur; - } - - sendbyte_blocking(S_ACK); - - while (rlen) { - uint32_t cur = MIN(rlen, sizeof buf); - spi_read_blocking(SPI_IF, 0, buf, cur); - sendbytes_blocking(buf, cur); - rlen -= cur; - } - - cs_deselect(cs_pin); - } - break; - case S_CMD_S_SPI_FREQ: - { - uint32_t want_baud; - readbytes_blocking(&want_baud, 4); - if (want_baud) { - // Set frequence - *baud = spi_set_baudrate(SPI_IF, want_baud); - // Send back actual value - sendbyte_blocking(S_ACK); - sendbytes_blocking(baud, 4); - } else { - // 0 Hz is reserved - sendbyte_blocking(S_NAK); - } - break; - } - case S_CMD_S_PIN_STATE: - if (readbyte_blocking()) - enable_spi(*baud); - else - disable_spi(); - sendbyte_blocking(S_ACK); - break; - case S_CMD_S_SPI_CS: - uint8_t cs_index = readbyte_blocking(); - if (cs_index < NUM_CS_AVAILABLE) { - set_cs_pin(cs_index); - sendbyte_blocking(S_ACK); - } else { - sendbyte_blocking(S_NAK); - } - break; - default: - sendbyte_blocking(S_NAK); - break; - } - - tud_cdc_n_write_flush(CDC_ITF); -#ifdef PICO_DEFAULT_LED_PIN - gpio_put(PICO_DEFAULT_LED_PIN, 0); -#endif } -static void command_loop(void) +void s_cmd_o_spiop() { - uint baud = spi_get_baudrate(SPI_IF); + static uint8_t buf[4096]; + uint32_t wlen, rlen; + readbytes_blocking(&wlen, 3); + readbytes_blocking(&rlen, 3); - for (;;) { + cs_select(cs_pin); + + while (wlen) { + uint32_t cur = MIN(wlen, sizeof buf); + readbytes_blocking(buf, cur); + spi_write_blocking(SPI_IF, buf, cur); + wlen -= cur; + } + + sendbyte_blocking(S_ACK); + + while (rlen) { + uint32_t cur = MIN(rlen, sizeof buf); + spi_read_blocking(SPI_IF, 0, buf, cur); + sendbytes_blocking(buf, cur); + rlen -= cur; + } + + cs_deselect(cs_pin); +} + +void s_cmd_s_spi_freq() +{ + uint32_t want_baud; + readbytes_blocking(&want_baud, 4); + if (want_baud) { + // Set frequency + baud = spi_set_baudrate(SPI_IF, want_baud); + // Send back actual value + sendbyte_blocking(S_ACK); + sendbytes_blocking(&baud, 4); + } else { + // 0 Hz is reserved + sendbyte_blocking(S_NAK); + } +} + +void s_cmd_s_pin_state() +{ + if (readbyte_blocking()) + enable_spi(); + else + disable_spi(); + sendbyte_blocking(S_ACK); +} + +void s_cmd_s_spi_cs() +{ + cs = readbyte_blocking(); + if (cs >= NUM_CS_AVAILABLE) + sendbyte_blocking(S_NAK); + return; + + cs += SPI_CS_0; + if (spi_enabled) { + if (cs_pin != cs) { + pullup_cs(cs_pin); + use_cs(cs); + } + } + cs_pin = cs; + sendbyte_blocking(S_ACK); +} + + +static void command_loop() { + while (1) { uint8_t cmd = readbyte_blocking(); #ifdef PICO_DEFAULT_LED_PIN gpio_put(PICO_DEFAULT_LED_PIN, 1); #endif - process_command(cmd, &baud); + switch (cmd) { + case S_CMD_NOP: + sendbyte_blocking(S_ACK); + break; + case S_CMD_Q_IFACE: + sendbyte_blocking(S_ACK); + sendbyte_blocking(0x01); + sendbyte_blocking(0x00); + break; + case S_CMD_Q_CMDMAP: + sendbyte_blocking(S_ACK); + sendbytes_blocking((uint8_t *) cmdmap, sizeof cmdmap); + break; + case S_CMD_Q_PGMNAME: + sendbyte_blocking(S_ACK); + sendbytes_blocking(progname, sizeof progname); + break; + case S_CMD_Q_SERBUF: + sendbyte_blocking(S_ACK); + sendbyte_blocking(0xFF); + sendbyte_blocking(0xFF); + break; + case S_CMD_Q_BUSTYPE: + sendbyte_blocking(S_ACK); + sendbyte_blocking((1 << 3)); // BUS_SPI + break; + case S_CMD_SYNCNOP: + sendbyte_blocking(S_NAK); + sendbyte_blocking(S_ACK); + break; + case S_CMD_S_BUSTYPE: + s_cmd_s_bustype(); + break; + case S_CMD_O_SPIOP: + s_cmd_o_spiop(); + break; + case S_CMD_S_SPI_FREQ: + s_cmd_s_spi_freq(); + break; + case S_CMD_S_PIN_STATE: + s_cmd_s_pin_state(); + break; + case S_CMD_S_SPI_CS: + s_cmd_s_spi_cs(); + break; + default: + sendbyte_blocking(S_NAK); + } + + tud_cdc_n_write_flush(CDC_ITF); + #ifdef PICO_DEFAULT_LED_PIN gpio_put(PICO_DEFAULT_LED_PIN, 0); #endif @@ -333,7 +340,7 @@ int main() // Setup USB tusb_init(); // Setup PL022 SPI - enable_spi(SPI_BAUD); + enable_spi(baud); command_loop(); } From 3d573a01c4b8f69fb0474f95d2627db824d26e46 Mon Sep 17 00:00:00 2001 From: Riku Viitanen Date: Wed, 7 Feb 2024 20:54:23 +0200 Subject: [PATCH 17/24] reformatting Signed-off-by: Riku Viitanen --- main.c | 468 +++++++++++++++++++++++++++------------------------------ 1 file changed, 225 insertions(+), 243 deletions(-) diff --git a/main.c b/main.c index 5c41be9..23abb22 100644 --- a/main.c +++ b/main.c @@ -7,7 +7,6 @@ * * Also based on stm32-vserprog: * https://github.com/dword1511/stm32-vserprog - * */ #define DESCRIPTION "SPI flash chip programmer using Flashprog's serprog protocol" @@ -19,17 +18,17 @@ #include "tusb.h" #include "serprog.h" -#define CDC_ITF 0 // USB CDC interface no +#define CDC_ITF 0 /* USB CDC interface no */ -#define SPI_IF spi0 // Which PL022 to use -#define SPI_CS_0 5 // The default CS pin +#define SPI_IF spi0 /* Which PL022 to use */ +#define SPI_CS_0 5 /* The default CS pin */ #define SPI_MISO 4 #define SPI_MOSI 3 #define SPI_SCK 2 uint8_t spi_enabled = 0; uint cs_pin = SPI_CS_0; -#define NUM_CS_AVAILABLE 4 // Number of usable chip selects +#define NUM_CS_AVAILABLE 4 /* Number of usable chip selects */ uint baud = 12000000; /* Default to 12MHz */ @@ -37,310 +36,293 @@ static const char progname[16] = "pico-serprog"; /* Map of supported serprog commands */ static const uint32_t cmdmap[8] = { - (1 << S_CMD_NOP) | - (1 << S_CMD_Q_IFACE) | - (1 << S_CMD_Q_CMDMAP) | - (1 << S_CMD_Q_PGMNAME) | - (1 << S_CMD_Q_SERBUF) | - (1 << S_CMD_Q_BUSTYPE) | - (1 << S_CMD_SYNCNOP) | - (1 << S_CMD_O_SPIOP) | - (1 << S_CMD_S_BUSTYPE) | - (1 << S_CMD_S_SPI_FREQ) | - (1 << S_CMD_S_PIN_STATE) | - (1 << S_CMD_S_SPI_CS) + (1 << S_CMD_NOP) | + (1 << S_CMD_Q_IFACE) | + (1 << S_CMD_Q_CMDMAP) | + (1 << S_CMD_Q_PGMNAME) | + (1 << S_CMD_Q_SERBUF) | + (1 << S_CMD_Q_BUSTYPE) | + (1 << S_CMD_SYNCNOP) | + (1 << S_CMD_O_SPIOP) | + (1 << S_CMD_S_BUSTYPE) | + (1 << S_CMD_S_SPI_FREQ) | + (1 << S_CMD_S_PIN_STATE) | + (1 << S_CMD_S_SPI_CS) }; -static void use_cs(uint pin) -{ - gpio_put(pin, 1); - gpio_set_dir(pin, GPIO_OUT); - gpio_set_drive_strength(pin, GPIO_DRIVE_STRENGTH_12MA); +static void use_cs(uint pin) { + gpio_put(pin, 1); + gpio_set_dir(pin, GPIO_OUT); + gpio_set_drive_strength(pin, GPIO_DRIVE_STRENGTH_12MA); } -static void pullup_cs(uint pin) -{ - gpio_set_dir(pin, GPIO_IN); - gpio_pull_up(pin); +static void pullup_cs(uint pin) { + gpio_set_dir(pin, GPIO_IN); + gpio_pull_up(pin); } -static void enable_spi() -{ +static void enable_spi() { #ifdef PICO_DEFAULT_LED_PIN - // Setup status LED - gpio_init(PICO_DEFAULT_LED_PIN); - gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT); + /* Setup status LED */ + gpio_init(PICO_DEFAULT_LED_PIN); + gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT); #endif - /* Setup default CS as output, others as inputs with pull-ups */ - for (uint8_t i = SPI_CS_0+1; i= NUM_CS_AVAILABLE) - sendbyte_blocking(S_NAK); - return; +void s_cmd_s_spi_cs() { + cs = readbyte_blocking(); + if (cs >= NUM_CS_AVAILABLE) + sendbyte_blocking(S_NAK); + return; - cs += SPI_CS_0; - if (spi_enabled) { - if (cs_pin != cs) { - pullup_cs(cs_pin); - use_cs(cs); - } - } - cs_pin = cs; - sendbyte_blocking(S_ACK); + cs += SPI_CS_0; + if (spi_enabled) { + if (cs_pin != cs) { + pullup_cs(cs_pin); + use_cs(cs); + } + } + cs_pin = cs; + sendbyte_blocking(S_ACK); } static void command_loop() { - while (1) { - uint8_t cmd = readbyte_blocking(); + while (1) { + uint8_t cmd = readbyte_blocking(); #ifdef PICO_DEFAULT_LED_PIN - gpio_put(PICO_DEFAULT_LED_PIN, 1); + gpio_put(PICO_DEFAULT_LED_PIN, 1); #endif - switch (cmd) { - case S_CMD_NOP: - sendbyte_blocking(S_ACK); - break; - case S_CMD_Q_IFACE: - sendbyte_blocking(S_ACK); - sendbyte_blocking(0x01); - sendbyte_blocking(0x00); - break; - case S_CMD_Q_CMDMAP: - sendbyte_blocking(S_ACK); - sendbytes_blocking((uint8_t *) cmdmap, sizeof cmdmap); - break; - case S_CMD_Q_PGMNAME: - sendbyte_blocking(S_ACK); - sendbytes_blocking(progname, sizeof progname); - break; - case S_CMD_Q_SERBUF: - sendbyte_blocking(S_ACK); - sendbyte_blocking(0xFF); - sendbyte_blocking(0xFF); - break; - case S_CMD_Q_BUSTYPE: - sendbyte_blocking(S_ACK); - sendbyte_blocking((1 << 3)); // BUS_SPI - break; - case S_CMD_SYNCNOP: - sendbyte_blocking(S_NAK); - sendbyte_blocking(S_ACK); - break; - case S_CMD_S_BUSTYPE: - s_cmd_s_bustype(); - break; - case S_CMD_O_SPIOP: - s_cmd_o_spiop(); - break; - case S_CMD_S_SPI_FREQ: - s_cmd_s_spi_freq(); - break; - case S_CMD_S_PIN_STATE: - s_cmd_s_pin_state(); - break; - case S_CMD_S_SPI_CS: - s_cmd_s_spi_cs(); - break; - default: - sendbyte_blocking(S_NAK); - } + switch (cmd) { + case S_CMD_NOP: + sendbyte_blocking(S_ACK); + break; + case S_CMD_Q_IFACE: + sendbyte_blocking(S_ACK); + sendbyte_blocking(0x01); + sendbyte_blocking(0x00); + break; + case S_CMD_Q_CMDMAP: + sendbyte_blocking(S_ACK); + sendbytes_blocking((uint8_t *)cmdmap, sizeof(cmdmap)); + break; + case S_CMD_Q_PGMNAME: + sendbyte_blocking(S_ACK); + sendbytes_blocking(progname, sizeof(progname)); + break; + case S_CMD_Q_SERBUF: + sendbyte_blocking(S_ACK); + sendbyte_blocking(0xFF); + sendbyte_blocking(0xFF); + break; + case S_CMD_Q_BUSTYPE: + sendbyte_blocking(S_ACK); + sendbyte_blocking((1 << 3)); /* SPI */ + break; + case S_CMD_SYNCNOP: + sendbyte_blocking(S_NAK); + sendbyte_blocking(S_ACK); + break; + case S_CMD_S_BUSTYPE: + s_cmd_s_bustype(); + break; + case S_CMD_O_SPIOP: + s_cmd_o_spiop(); + break; + case S_CMD_S_SPI_FREQ: + s_cmd_s_spi_freq(); + break; + case S_CMD_S_PIN_STATE: + s_cmd_s_pin_state(); + break; + case S_CMD_S_SPI_CS: + s_cmd_s_spi_cs(); + break; + default: + sendbyte_blocking(S_NAK); + } - tud_cdc_n_write_flush(CDC_ITF); + tud_cdc_n_write_flush(CDC_ITF); #ifdef PICO_DEFAULT_LED_PIN - gpio_put(PICO_DEFAULT_LED_PIN, 0); + gpio_put(PICO_DEFAULT_LED_PIN, 0); #endif - } + } } -int main() -{ - // Metadata for picotool - bi_decl(bi_program_description(DESCRIPTION)); - bi_decl(bi_program_url(WEBSITE)); +int main() { + /* Metadata for picotool */ + bi_decl(bi_program_description(DESCRIPTION)); + bi_decl(bi_program_url(WEBSITE)); #ifdef PICO_DEFAULT_LED_PIN - bi_decl(bi_1pin_with_name(PICO_DEFAULT_LED_PIN, "Activity LED")); + bi_decl(bi_1pin_with_name(PICO_DEFAULT_LED_PIN, "Activity LED")); #endif - bi_decl(bi_1pin_with_name(SPI_MISO, "MISO")); - bi_decl(bi_1pin_with_name(SPI_MOSI, "MOSI")); - bi_decl(bi_1pin_with_name(SPI_SCK, "SCK")); - bi_decl(bi_1pin_with_name(SPI_CS_0, "CS_0 (default)")); - bi_decl(bi_1pin_with_name(SPI_CS_0+1, "CS_1")); - bi_decl(bi_1pin_with_name(SPI_CS_0+2, "CS_2")); - bi_decl(bi_1pin_with_name(SPI_CS_0+3, "CS_3")); + bi_decl(bi_1pin_with_name(SPI_MISO, "MISO")); + bi_decl(bi_1pin_with_name(SPI_MOSI, "MOSI")); + bi_decl(bi_1pin_with_name(SPI_SCK, "SCK")); + bi_decl(bi_1pin_with_name(SPI_CS_0, "CS_0 (default)")); + bi_decl(bi_1pin_with_name(SPI_CS_0+1, "CS_1")); + bi_decl(bi_1pin_with_name(SPI_CS_0+2, "CS_2")); + bi_decl(bi_1pin_with_name(SPI_CS_0+3, "CS_3")); - // Setup USB - tusb_init(); - // Setup PL022 SPI - enable_spi(baud); + /* Setup USB */ + tusb_init(); + /* Setup PL022 SPI */ + enable_spi(baud); - command_loop(); + command_loop(); } + From e75e3a20e63269a5e3189bc2e49a6a81d45a636a Mon Sep 17 00:00:00 2001 From: kay <> Date: Sat, 10 Feb 2024 12:45:08 -0800 Subject: [PATCH 18/24] Fix undefined `cs` variable Attempting to compile without this fix results in this error ``` main.c:226:9: error: 'cs' undeclared (first use in this function) 226 | cs = readbyte_blocking(); | ^~ ``` This fix declares `cs` as a `uint8_t`. Tested and was able to read/write to a MX25L6406E and MX25L3206E --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index 23abb22..626f584 100644 --- a/main.c +++ b/main.c @@ -223,7 +223,7 @@ void s_cmd_s_pin_state() { } void s_cmd_s_spi_cs() { - cs = readbyte_blocking(); + uint8_t cs = readbyte_blocking(); if (cs >= NUM_CS_AVAILABLE) sendbyte_blocking(S_NAK); return; From 382004a92e2e36b1980cbe8173010d781f91662c Mon Sep 17 00:00:00 2001 From: Riku Viitanen Date: Fri, 7 Jun 2024 16:50:19 +0300 Subject: [PATCH 19/24] Fix typo Signed-off-by: Riku Viitanen --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index 626f584..cc2e19a 100644 --- a/main.c +++ b/main.c @@ -164,7 +164,7 @@ static inline void sendbyte_blocking(uint8_t b) { } void s_cmd_s_bustype() { - /* If SPI is among the requsted bus types we succeed, + /* If SPI is among the requested bus types we succeed, * fail otherwise */ if ((uint8_t) readbyte_blocking() & (1 << 3)) sendbyte_blocking(S_ACK); From c88dd75da55a89fb3da0bbb6ef8f21d7c3c0634f Mon Sep 17 00:00:00 2001 From: Steffen Pankratz Date: Mon, 27 Jan 2025 16:22:39 +0100 Subject: [PATCH 20/24] Typo fixes Signed-off-by: Steffen Pankratz --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index a0cc2e9..681c755 100644 --- a/readme.md +++ b/readme.md @@ -6,7 +6,7 @@ other RP2040 based boards. Based on Further improved by kukrimate ![here](https://github.com/kukrimate/pico-serprog). And me (Riku\_V) here. -Pre-compiled binaries binaries can be downloaded from the +Pre-compiled binaries can be downloaded from the ![Libreboot project](https://libreboot.org/download.html#https). For a guide on how to flash a chip see @@ -33,7 +33,7 @@ make Plug in your Pico. Mount it as you would any other USB flash drive. Copy `pico_serprog.uf2` into it. Your programmer is now ready. -If you want to change the firwmare, you need to press the button +If you want to change the firmware, you need to press the button on the board while you plug it in. ## Usage From af14b08b0c10a575d9b97c6e7cf5690731fbc88a Mon Sep 17 00:00:00 2001 From: Steffen Pankratz Date: Mon, 27 Jan 2025 16:23:57 +0100 Subject: [PATCH 21/24] Update to the latest version from upstream See https://github.com/raspberrypi/pico-sdk/blob/master/external/pico_sdk_import.cmake Signed-off-by: Steffen Pankratz --- pico_sdk_import.cmake | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/pico_sdk_import.cmake b/pico_sdk_import.cmake index 28efe9e..a0721d0 100644 --- a/pico_sdk_import.cmake +++ b/pico_sdk_import.cmake @@ -18,9 +18,20 @@ if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_P message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") endif () +if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_TAG} AND (NOT PICO_SDK_FETCH_FROM_GIT_TAG)) + set(PICO_SDK_FETCH_FROM_GIT_TAG $ENV{PICO_SDK_FETCH_FROM_GIT_TAG}) + message("Using PICO_SDK_FETCH_FROM_GIT_TAG from environment ('${PICO_SDK_FETCH_FROM_GIT_TAG}')") +endif () + +if (PICO_SDK_FETCH_FROM_GIT AND NOT PICO_SDK_FETCH_FROM_GIT_TAG) + set(PICO_SDK_FETCH_FROM_GIT_TAG "master") + message("Using master as default value for PICO_SDK_FETCH_FROM_GIT_TAG") +endif() + set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") +set(PICO_SDK_FETCH_FROM_GIT_TAG "${PICO_SDK_FETCH_FROM_GIT_TAG}" CACHE FILEPATH "release tag for SDK") if (NOT PICO_SDK_PATH) if (PICO_SDK_FETCH_FROM_GIT) @@ -29,11 +40,22 @@ if (NOT PICO_SDK_PATH) if (PICO_SDK_FETCH_FROM_GIT_PATH) get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") endif () - FetchContent_Declare( - pico_sdk - GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk - GIT_TAG master - ) + # GIT_SUBMODULES_RECURSE was added in 3.17 + if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0") + FetchContent_Declare( + pico_sdk + GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk + GIT_TAG ${PICO_SDK_FETCH_FROM_GIT_TAG} + GIT_SUBMODULES_RECURSE FALSE + ) + else () + FetchContent_Declare( + pico_sdk + GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk + GIT_TAG ${PICO_SDK_FETCH_FROM_GIT_TAG} + ) + endif () + if (NOT pico_sdk) message("Downloading Raspberry Pi Pico SDK") FetchContent_Populate(pico_sdk) From f6c0e3b15ca5de98ad6c46b11813ca7c7a93b796 Mon Sep 17 00:00:00 2001 From: Riku Viitanen Date: Wed, 12 Feb 2025 20:31:38 +0200 Subject: [PATCH 22/24] s_cmd_o_spiop: initialise rlen and wlen correctly This should fix synchronization issues on RP2350 devices. See issue #3 on codeberg.org. Thanks to xco23sdogio32 for the tip! --- main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main.c b/main.c index cc2e19a..b06f92f 100644 --- a/main.c +++ b/main.c @@ -174,7 +174,8 @@ void s_cmd_s_bustype() { void s_cmd_o_spiop() { static uint8_t buf[4096]; - uint32_t wlen, rlen; + uint32_t wlen = 0; + uint32_t rlen = 0; readbytes_blocking(&wlen, 3); readbytes_blocking(&rlen, 3); From 49d2e8eafb0bcc636d093fd93b4d590f08383ac8 Mon Sep 17 00:00:00 2001 From: Steffen Pankratz Date: Mon, 27 Jan 2025 16:22:39 +0100 Subject: [PATCH 23/24] Typo fixes Signed-off-by: Steffen Pankratz --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index a0cc2e9..681c755 100644 --- a/readme.md +++ b/readme.md @@ -6,7 +6,7 @@ other RP2040 based boards. Based on Further improved by kukrimate ![here](https://github.com/kukrimate/pico-serprog). And me (Riku\_V) here. -Pre-compiled binaries binaries can be downloaded from the +Pre-compiled binaries can be downloaded from the ![Libreboot project](https://libreboot.org/download.html#https). For a guide on how to flash a chip see @@ -33,7 +33,7 @@ make Plug in your Pico. Mount it as you would any other USB flash drive. Copy `pico_serprog.uf2` into it. Your programmer is now ready. -If you want to change the firwmare, you need to press the button +If you want to change the firmware, you need to press the button on the board while you plug it in. ## Usage From df7e9e7287ec9cb3c149ce709b4ab486598109d7 Mon Sep 17 00:00:00 2001 From: Steffen Pankratz Date: Mon, 27 Jan 2025 16:23:57 +0100 Subject: [PATCH 24/24] Update to the latest version from upstream See https://github.com/raspberrypi/pico-sdk/blob/master/external/pico_sdk_import.cmake Signed-off-by: Steffen Pankratz --- pico_sdk_import.cmake | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/pico_sdk_import.cmake b/pico_sdk_import.cmake index 28efe9e..a0721d0 100644 --- a/pico_sdk_import.cmake +++ b/pico_sdk_import.cmake @@ -18,9 +18,20 @@ if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_P message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") endif () +if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_TAG} AND (NOT PICO_SDK_FETCH_FROM_GIT_TAG)) + set(PICO_SDK_FETCH_FROM_GIT_TAG $ENV{PICO_SDK_FETCH_FROM_GIT_TAG}) + message("Using PICO_SDK_FETCH_FROM_GIT_TAG from environment ('${PICO_SDK_FETCH_FROM_GIT_TAG}')") +endif () + +if (PICO_SDK_FETCH_FROM_GIT AND NOT PICO_SDK_FETCH_FROM_GIT_TAG) + set(PICO_SDK_FETCH_FROM_GIT_TAG "master") + message("Using master as default value for PICO_SDK_FETCH_FROM_GIT_TAG") +endif() + set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") +set(PICO_SDK_FETCH_FROM_GIT_TAG "${PICO_SDK_FETCH_FROM_GIT_TAG}" CACHE FILEPATH "release tag for SDK") if (NOT PICO_SDK_PATH) if (PICO_SDK_FETCH_FROM_GIT) @@ -29,11 +40,22 @@ if (NOT PICO_SDK_PATH) if (PICO_SDK_FETCH_FROM_GIT_PATH) get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") endif () - FetchContent_Declare( - pico_sdk - GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk - GIT_TAG master - ) + # GIT_SUBMODULES_RECURSE was added in 3.17 + if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0") + FetchContent_Declare( + pico_sdk + GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk + GIT_TAG ${PICO_SDK_FETCH_FROM_GIT_TAG} + GIT_SUBMODULES_RECURSE FALSE + ) + else () + FetchContent_Declare( + pico_sdk + GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk + GIT_TAG ${PICO_SDK_FETCH_FROM_GIT_TAG} + ) + endif () + if (NOT pico_sdk) message("Downloading Raspberry Pi Pico SDK") FetchContent_Populate(pico_sdk)