Initial Release
This commit is contained in:
5
system/CMakeLists.txt
Normal file
5
system/CMakeLists.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
if (NOT PICO_NO_HARDWARE)
|
||||
add_subdirectory(double_tap_usb_boot)
|
||||
add_subdirectory(narrow_io_write)
|
||||
add_subdirectory(hello_double_tap)
|
||||
endif ()
|
||||
13
system/double_tap_usb_boot/CMakeLists.txt
Normal file
13
system/double_tap_usb_boot/CMakeLists.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
add_library(double_tap_usb_boot INTERFACE)
|
||||
|
||||
# inclusion of this library will allow you to double tap reset within 100ms to launch into bootrom USB bootloader
|
||||
if (PICO_ON_DEVICE)
|
||||
target_sources(double_tap_usb_boot INTERFACE
|
||||
${CMAKE_CURRENT_LIST_DIR}/double_tap_usb_boot.c
|
||||
)
|
||||
|
||||
target_link_libraries(double_tap_usb_boot INTERFACE
|
||||
pico_bootrom
|
||||
pico_time
|
||||
)
|
||||
endif ()
|
||||
36
system/double_tap_usb_boot/double_tap_usb_boot.c
Normal file
36
system/double_tap_usb_boot/double_tap_usb_boot.c
Normal file
@@ -0,0 +1,36 @@
|
||||
#include "pico.h"
|
||||
#include "pico/time.h"
|
||||
#include "pico/bootrom.h"
|
||||
|
||||
// Allow user override of the LED mask
|
||||
#ifndef USB_BOOT_LED_ACTIVITY_MASK
|
||||
#define USB_BOOT_LED_ACTIVITY_MASK 0
|
||||
#endif
|
||||
|
||||
// Doesn't make any sense for a RAM only binary
|
||||
#if !PICO_NO_FLASH
|
||||
static const uint32_t magic_token[] = {
|
||||
0xf01681de, 0xbd729b29, 0xd359be7a,
|
||||
};
|
||||
|
||||
static uint32_t __uninitialized_ram(magic_location)[count_of(magic_token)];
|
||||
|
||||
// run at initialization time
|
||||
static void __attribute__((constructor)) boot_double_tap_check() {
|
||||
for (uint i = 0; i < count_of(magic_token); i++) {
|
||||
if (magic_location[i] != magic_token[i]) {
|
||||
// Arm for 100 ms then disarm and continue booting
|
||||
for (i = 0; i < count_of(magic_token); i++) {
|
||||
magic_location[i] = magic_token[i];
|
||||
}
|
||||
busy_wait_us(100000);
|
||||
magic_location[0] = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
magic_location[0] = 0;
|
||||
reset_usb_boot(USB_BOOT_LED_ACTIVITY_MASK, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
14
system/hello_double_tap/CMakeLists.txt
Normal file
14
system/hello_double_tap/CMakeLists.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
add_executable(hello_double_tap
|
||||
hello_double_tap.c
|
||||
)
|
||||
|
||||
# Double tap reset into bootrom is injected by linking with the double_tap_usb_boot library
|
||||
target_link_libraries(hello_double_tap
|
||||
pico_stdlib
|
||||
double_tap_usb_boot
|
||||
)
|
||||
|
||||
pico_add_extra_outputs(hello_double_tap)
|
||||
|
||||
# add url via pico_set_program_url
|
||||
example_auto_set_url(hello_double_tap)
|
||||
21
system/hello_double_tap/hello_double_tap.c
Normal file
21
system/hello_double_tap/hello_double_tap.c
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "pico/stdlib.h"
|
||||
|
||||
// This is a regular old LED blinking example, however it is linked with double_tap_usb_boot
|
||||
// so pressing reset quickly twice, will reset into USB bootloader
|
||||
int main() {
|
||||
const uint LED_PIN = 21;
|
||||
gpio_init(LED_PIN);
|
||||
gpio_set_dir(LED_PIN, GPIO_OUT);
|
||||
while (true) {
|
||||
gpio_put(LED_PIN, 1);
|
||||
sleep_ms(250);
|
||||
gpio_put(LED_PIN, 0);
|
||||
sleep_ms(250);
|
||||
}
|
||||
}
|
||||
12
system/narrow_io_write/CMakeLists.txt
Normal file
12
system/narrow_io_write/CMakeLists.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
add_executable(narrow_io_write
|
||||
narrow_io_write.c
|
||||
)
|
||||
|
||||
# Pull in our pico_stdlib which pulls in commonly used features
|
||||
target_link_libraries(narrow_io_write pico_stdlib)
|
||||
|
||||
# create map/bin/hex file etc.
|
||||
pico_add_extra_outputs(narrow_io_write)
|
||||
|
||||
# add url via pico_set_program_url
|
||||
example_auto_set_url(narrow_io_write)
|
||||
60
system/narrow_io_write/narrow_io_write.c
Normal file
60
system/narrow_io_write/narrow_io_write.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "pico/stdlib.h"
|
||||
#include "hardware/structs/watchdog.h"
|
||||
|
||||
// This app shows the effect of byte and halfword writes on IO registers. All
|
||||
// IO registers on RP2040 will sample the entire 32 bit write data bus on any
|
||||
// write; the transfer size and the 2 LSBs of the address are *ignored*.
|
||||
//
|
||||
// This can have unintuitive results, especially given the way RP2040
|
||||
// busmasters replicate narrow write data across the entire 32-bit write data
|
||||
// bus. However, this behaviour can be quite useful if you are aware of it!
|
||||
|
||||
int main() {
|
||||
stdio_init_all();
|
||||
|
||||
// We'll use WATCHDOG_SCRATCH0 as a convenient 32 bit read/write register
|
||||
// that we can assign arbitrary values to
|
||||
io_rw_32 *scratch32 = &watchdog_hw->scratch[0];
|
||||
// Alias the scratch register as two halfwords at offsets +0x0 and +0x2
|
||||
volatile uint16_t *scratch16 = (volatile uint16_t *) scratch32;
|
||||
// Alias the scratch register as four bytes at offsets +0x0, +0x1, +0x2, +0x3:
|
||||
volatile uint8_t *scratch8 = (volatile uint8_t *) scratch32;
|
||||
|
||||
// Show that we can read/write the scratch register as normal:
|
||||
printf("Writing 32 bit value\n");
|
||||
*scratch32 = 0xdeadbeef;
|
||||
printf("Should be 0xdeadbeef: 0x%08x\n", *scratch32);
|
||||
|
||||
// We can do narrow reads just fine -- IO registers treat this as a 32 bit
|
||||
// read, and the processor/DMA will pick out the correct byte lanes based
|
||||
// on transfer size and address LSBs
|
||||
printf("\nReading back 1 byte at a time\n");
|
||||
// Little-endian!
|
||||
printf("Should be ef be ad de: %02x %02x %02x %02x\n",
|
||||
scratch8[0], scratch8[1], scratch8[2], scratch8[3]);
|
||||
|
||||
// The Cortex-M0+ and the RP2040 DMA replicate byte writes across the bus,
|
||||
// and IO registers will sample the entire write bus always.
|
||||
printf("\nWriting 8 bit value 0xa5 at offset 0\n");
|
||||
scratch8[0] = 0xa5;
|
||||
// Read back the whole scratch register in one go
|
||||
printf("Should be 0xa5a5a5a5: 0x%08x\n", *scratch32);
|
||||
|
||||
// The IO register ignores the address LSBs [1:0] as well as the transfer
|
||||
// size, so it doesn't matter what byte offset we use
|
||||
printf("\nWriting 8 bit value at offset 1\n");
|
||||
scratch8[1] = 0x3c;
|
||||
printf("Should be 0x3c3c3c3c: 0x%08x\n", *scratch32);
|
||||
|
||||
// Halfword writes are also replicated across the write data bus
|
||||
printf("\nWriting 16 bit value at offset 0\n");
|
||||
scratch16[0] = 0xf00d;
|
||||
printf("Should be 0xf00df00d: 0x%08x\n", *scratch32);
|
||||
}
|
||||
Reference in New Issue
Block a user