Created
May 30, 2021 14:29
-
-
Save profi200/55119e74d2439ad87060941eec42c07d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//#include "types.h" | |
#include <stdio.h> | |
#include <inttypes.h> | |
#include "pico/stdlib.h" | |
#include "hardware/gpio.h" | |
#include "hardware/spi.h" | |
#include "pico/bootrom.h" | |
#define LED_PIN (25u) | |
#define SPI_PIN_MISO (0u) | |
#define SPI_PIN_CS (1u) | |
#define SPI_PIN_CLK (2u) | |
#define SPI_PIN_MOSI (3u) | |
// Shamelessly stolen from the button example. | |
#include "hardware/sync.h" // save_and_disable_interrupts()... | |
#include "hardware/structs/ioqspi.h" | |
#include "hardware/structs/sio.h" | |
bool __no_inline_not_in_flash_func(get_bootsel_button)(void) | |
{ | |
const uint CS_PIN_INDEX = 1; | |
// Must disable interrupts, as interrupt handlers may be in flash, and we | |
// are about to temporarily disable flash access! | |
uint32_t flags = save_and_disable_interrupts(); | |
// Set chip select to Hi-Z | |
hw_write_masked(&ioqspi_hw->io[CS_PIN_INDEX].ctrl, | |
GPIO_OVERRIDE_LOW << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB, | |
IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS); | |
// Note we can't call into any sleep functions in flash right now | |
for (volatile int i = 0; i < 1000; ++i); | |
// The HI GPIO registers in SIO can observe and control the 6 QSPI pins. | |
// Note the button pulls the pin *low* when pressed. | |
bool button_state = !(sio_hw->gpio_hi_in & (1u << CS_PIN_INDEX)); | |
// Need to restore the state of chip select, else we are going to have a | |
// bad time when we return to code in flash! | |
hw_write_masked(&ioqspi_hw->io[CS_PIN_INDEX].ctrl, | |
GPIO_OVERRIDE_NORMAL << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB, | |
IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS); | |
restore_interrupts(flags); | |
return button_state; | |
} | |
int main(void) | |
{ | |
stdio_init_all(); | |
gpio_init(LED_PIN); | |
gpio_put(LED_PIN, 0); | |
gpio_set_dir(LED_PIN, GPIO_OUT); | |
// The 3DS uses 16.756991 MHz. | |
// The SDK for some reason picks the next lowest (15625000) clock | |
// instead of the next highest (20833333). | |
// 15625000 seems to work though. | |
spi_init(spi0, 16756991); | |
spi_set_format(spi0, 8, SPI_CPOL_1, SPI_CPHA_1, SPI_MSB_FIRST); | |
spi_set_slave(spi0, true); | |
gpio_set_function(SPI_PIN_MISO, GPIO_FUNC_SPI); | |
gpio_set_function(SPI_PIN_CS, GPIO_FUNC_SPI); | |
gpio_set_function(SPI_PIN_CLK, GPIO_FUNC_SPI); | |
gpio_set_function(SPI_PIN_MOSI, GPIO_FUNC_SPI); | |
sleep_ms(1); | |
/*do | |
{ | |
gpio_put(LED_PIN, 1); | |
uint8_t rxbuf[2]; | |
const uint8_t resp[2] = {0xBA, 0xBE}; | |
spi_read_blocking(spi0, 0xE1, rxbuf, 2); | |
spi_write_blocking(spi0, resp, 2); | |
printf("Hello from 3DS: %02" PRIX8 "%02" PRIX8 "\n", rxbuf[0], rxbuf[1]); | |
gpio_put(LED_PIN, 0); | |
sleep_ms(1000); | |
} while(!get_bootsel_button());*/ | |
// SPICARD autopoll test. | |
do | |
{ | |
sleep_ms(1000); | |
} while(!get_bootsel_button()); | |
gpio_put(LED_PIN, 1); | |
uint8_t rxbuf; | |
const uint8_t resp = 0x02; | |
spi_read_blocking(spi0, 0xE2, &rxbuf, 1); | |
spi_write_blocking(spi0, &resp, 1); | |
printf("Hello from 3DS: %02" PRIX8 "\n", rxbuf); | |
sleep_ms(1000); | |
gpio_put(LED_PIN, 0); | |
reset_usb_boot(0, 0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment