diff --git a/Makefile b/Makefile index 98afc39..e3087be 100644 --- a/Makefile +++ b/Makefile @@ -15,11 +15,13 @@ SRC_C = \ cmd-peekpoke.c \ cmd-reboot.c \ cmd-sleep.c \ + cmd-spi.c \ emi.c \ irq.c \ main.c \ scriptic.c \ serial.c \ + spi.c \ utils.c \ vectors.c \ vsprintf.c @@ -27,6 +29,8 @@ SRC_C = \ SRC_S = \ scriptic/set-plls.S \ scriptic/enable-psram.S \ + scriptic/spi.S \ + scriptic/spi-blockmode.S \ _udivsi3.S \ _divsi3.S \ start.S diff --git a/cmd-spi.c b/cmd-spi.c index a2db547..6383ada 100644 --- a/cmd-spi.c +++ b/cmd-spi.c @@ -4,30 +4,30 @@ #include "printf.h" #include "spi.h" -#define SPI_CSEL 0 - int cmd_spi(int argc, char **argv) { uint32_t recv_bytes_count; uint8_t xmit_bytes[argc - 1]; int i; - if (argc == 1 && !_strcasecmp(argv[0], "loop")) { - printf("Repeatedly sending 0x9f -- id\n"); - while(1) { - uint8_t out[1] = {0x9f}; - uint8_t in[3]; - spi_cmd_txrx(0, sizeof(out), sizeof(in), out, in); - printf("ID: "); - serial_print_hex(in, sizeof(in)); - } + if (argc > 0 && !_strcasecmp(argv[0], "id")) { + uint8_t out[1] = {0x9f}; + uint8_t in[3]; + + spi_cmd_txrx(sizeof(out), sizeof(in), out, in); + + printf("ID: %02x %02x %02x\n", in[0], in[1], in[2]); + + return 0; } if (argc < 2) { printf("Send SPI bytes out and read the response.\n"); - printf("Usage: spi [count] [byte 1] [byte 2] ...\n"); - printf(" Where \"count\" is the number of bytes to expect" - " in response.\n"); + printf("Usage:\n"); + printf(" spi [count] [byte 1] [byte 2] ...\n"); + printf(" Where \"count\" is the number of bytes to expect" + " in response.\n"); + printf(" spi id -- get device id\n"); return 1; } @@ -41,7 +41,7 @@ int cmd_spi(int argc, char **argv) sizeof(xmit_bytes), sizeof(recv_bytes)); serial_print_hex(xmit_bytes, sizeof(xmit_bytes)); - spi_cmd_txrx(SPI_CSEL, sizeof(xmit_bytes), sizeof(recv_bytes), + spi_cmd_txrx(sizeof(xmit_bytes), sizeof(recv_bytes), xmit_bytes, recv_bytes); printf("Response:\n"); diff --git a/include/spi.h b/include/spi.h index 6d63d00..3421947 100644 --- a/include/spi.h +++ b/include/spi.h @@ -2,6 +2,7 @@ #ifndef __SPI_H__ #define __SPI_H__ -#define SPI_ADDR 0xa0140000 +int spi_cmd_txrx(uint8_t tx_size, uint8_t rx_size, + uint8_t *tx_buf, uint8_t *rx_buf); #endif /* __SPI_H__ */ diff --git a/main.c b/main.c index e01bf2c..2d54698 100644 --- a/main.c +++ b/main.c @@ -184,8 +184,6 @@ static int list_registers(void) static int do_init(void) { - const struct scriptic *script; - list_registers(); /* Disable system watchdog */ @@ -197,11 +195,8 @@ static int do_init(void) /* Disable battery watchdog */ writew(0x2, PMIC_CTRL9); - script = scriptic_get("set_plls"); - scriptic_execute(script); - - script = scriptic_get("enable_psram"); - scriptic_execute(script); + scriptic_run("set_plls"); + scriptic_run("enable_psram"); serial_puts("\n\nFernly shell\n"); @@ -337,12 +332,13 @@ static int loop(void) static int cmd_help(int argc, char **argv); extern int cmd_hex(int argc, char **argv); +extern int cmd_irq(int argc, char **argv); +extern int cmd_msleep(int argc, char **argv); extern int cmd_peek(int argc, char **argv); extern int cmd_poke(int argc, char **argv); +extern int cmd_spi(int argc, char **argv); extern int cmd_swi(int argc, char **argv); extern int cmd_reboot(int argc, char **argv); -extern int cmd_msleep(int argc, char **argv); -extern int cmd_irq(int argc, char **argv); static const struct { int (*func)(int argc, char **argv); @@ -384,6 +380,11 @@ static const struct { .name = "irq", .help = "Manipulate IRQs", }, + { + .func = cmd_spi, + .name = "spi", + .help = "Manipulate on-board SPI", + }, { .func = cmd_swi, .name = "swi", diff --git a/scriptic.c b/scriptic.c index bd305ea..23db4fa 100644 --- a/scriptic.c +++ b/scriptic.c @@ -3,14 +3,19 @@ #include "bionic.h" #include "memio.h" -#define SCRIPTIC_DEBUG /* Enable this to print commands as they're executed */ +//#define SCRIPTIC_DEBUG /* Enable this to print commands as they're executed */ extern struct scriptic set_plls; extern struct scriptic enable_psram; +extern struct scriptic spi_run; +extern struct scriptic spi_run; +extern struct scriptic spi_init; static struct scriptic *scripts[] = { &set_plls, &enable_psram, + &spi_run, + &spi_init, }; #ifdef SCRIPTIC_DEBUG diff --git a/scriptic/spi-blockmode.S b/scriptic/spi-blockmode.S index 866edec..483f28a 100644 --- a/scriptic/spi-blockmode.S +++ b/scriptic/spi-blockmode.S @@ -2,7 +2,7 @@ #include "fernvale-spi.h" /* Enable block mode for SPI CS0 */ - sc_new "spi_run_cs0", 1, 0, 0 + sc_new "spi_run", 1, 0, 0 /* Wait for channel 2 to be idle */ sc_write32 SPI_CTRL3_CHANNEL2_MASK, SPI_CTRL3_CHANNEL2_MASK, SPI_CTRL3 @@ -15,7 +15,7 @@ /* Trigger the transfer */ sc_write32 \ SPI_BLOCKMODE_TRIGGER | SPI_BLOCKMODE_CS0, \ - SPI_BLOCKMODE_TRIGGER | SPI_BLOCKMODE_CS0, \ + SPI_BLOCKMODE_TRIGGER | SPI_BLOCKMODE_CS, \ SPI_BLOCKMODE /* Wait for the device to prepare itself */ @@ -25,48 +25,7 @@ sc_read32 0, SPI_BLOCKMODE_BUSY, SPI_BLOCKMODE /* Stop the transfer */ - sc_write32 0, SPI_BLOCKMODE_TRIGGER | SPI_BLOCKMODE_CS0, SPI_BLOCKMODE - - /* Wait for it to be disabled */ - sc_read32 0, SPI_BLOCKMODE_PREP, SPI_BLOCKMODE - - /* Exit block mode */ - sc_write32 0, SPI_BLOCKMODE_ENABLE, SPI_BLOCKMODE - - /* Wait for the chip to actually exit block mode */ - sc_read32 0, SPI_BLOCKMODE_ENABLE, SPI_BLOCKMODE - - /* Allow channel 2 to contain data */ - sc_write32 0, SPI_CTRL3_CHANNEL2_MASK, SPI_CTRL3 - - sc_end - - - /* Enable block mode for SPI CS1 */ - sc_new "spi_run_cs1", 1, 0, 0 - - /* Wait for channel 2 to be idle */ - sc_write32 SPI_CTRL3_CHANNEL2_MASK, SPI_CTRL3_CHANNEL2_MASK, SPI_CTRL3 - sc_read32 SPI_CTRL3_CHANNEL2_IDLE, SPI_CTRL3_CHANNEL2_IDLE, SPI_CTRL3 - sc_read32 SPI_CTRL1_BUS_IDLE, SPI_CTRL1_BUS_IDLE, SPI_CTRL1 - - /* Turn on block mode */ - sc_write32 SPI_BLOCKMODE_ENABLE, SPI_BLOCKMODE_ENABLE, SPI_BLOCKMODE - - /* Trigger the transfer */ - sc_write32 \ - SPI_BLOCKMODE_TRIGGER | SPI_BLOCKMODE_CS1, \ - SPI_BLOCKMODE_TRIGGER | SPI_BLOCKMODE_CS1, \ - SPI_BLOCKMODE - - /* Wait for the device to prepare itself */ - sc_read32 SPI_BLOCKMODE_PREP, SPI_BLOCKMODE_PREP, SPI_BLOCKMODE - - /* Wait for it to finish */ - sc_read32 0, SPI_BLOCKMODE_BUSY, SPI_BLOCKMODE - - /* Stop the transfer */ - sc_write32 0, SPI_BLOCKMODE_TRIGGER | SPI_BLOCKMODE_CS1, SPI_BLOCKMODE + sc_write32 0, SPI_BLOCKMODE_TRIGGER | SPI_BLOCKMODE_CS, SPI_BLOCKMODE /* Wait for it to be disabled */ sc_read32 0, SPI_BLOCKMODE_PREP, SPI_BLOCKMODE diff --git a/scriptic/spi.S b/scriptic/spi.S index b309713..86fdd6d 100644 --- a/scriptic/spi.S +++ b/scriptic/spi.S @@ -1,22 +1,57 @@ #include "scriptic.h" #include "fernvale-spi.h" +#include "fernvale-gpio.h" sc_new "spi_init", 1, 0, 0 /* Ungate the clock */ sc_write16 0x800, 0x800, 0x80000320 - /* Switch to SPI NOR */ /* (XXX Might need to invert this) */ + /* Switch to SPI NOR */ sc_write16 0, 1, 0x80000230 /* Remap GPIOs to be SPI */ - sc_write32 0x11111100, 0x77777700, 0xa0020c80 - sc_write32 0x00000011, 0x00000077, 0xa0020c90 + sc_write32 \ + GPIO_CTRL_MODE8_IO66_SFCS1 | \ + GPIO_CTRL_MODE8_IO67_SFWP | \ + GPIO_CTRL_MODE8_IO68_SFCS0 | \ + GPIO_CTRL_MODE8_IO69_SFCK | \ + GPIO_CTRL_MODE8_IO70_SFIN | \ + GPIO_CTRL_MODE8_IO71_SFOUT, \ + GPIO_CTRL_MODE8_IO66_MASK | \ + GPIO_CTRL_MODE8_IO67_MASK | \ + GPIO_CTRL_MODE8_IO68_MASK | \ + GPIO_CTRL_MODE8_IO69_MASK | \ + GPIO_CTRL_MODE8_IO70_MASK | \ + GPIO_CTRL_MODE8_IO71_MASK, \ + GPIO_CTRL_MODE8 + sc_write32 \ + GPIO_CTRL_MODE9_IO72_SFSHOLD, \ + GPIO_CTRL_MODE9_IO72_MASK, \ + GPIO_CTRL_MODE9 /* Enable high-impedence for GPIO mode */ - sc_write16 0, 0x3fff, 0xa0020b10 - sc_write16 0, 0x3fff, 0xa0020b40 - sc_write16 0, 0xdff1, 0xa0020b20 - sc_write16 0, 0xdff1, 0xa0020b50 + sc_write16 0, \ + GPIO_CTRL_PULL_CTRL1_IO66 | \ + GPIO_CTRL_PULL_CTRL1_IO67 | \ + GPIO_CTRL_PULL_CTRL1_IO72, \ + GPIO_CTRL_RESEN1_R0 + sc_write16 0, \ + GPIO_CTRL_PULL_CTRL1_IO66 | \ + GPIO_CTRL_PULL_CTRL1_IO67 | \ + GPIO_CTRL_PULL_CTRL1_IO72, \ + GPIO_CTRL_RESEN1_R1 + sc_write16 0, \ + GPIO_CTRL_PULL_CTRL2_IO68 | \ + GPIO_CTRL_PULL_CTRL2_IO69 | \ + GPIO_CTRL_PULL_CTRL2_IO70 | \ + GPIO_CTRL_PULL_CTRL2_IO71, \ + GPIO_CTRL_RESEN2_R0 + sc_write16 0, \ + GPIO_CTRL_PULL_CTRL2_IO68 | \ + GPIO_CTRL_PULL_CTRL2_IO69 | \ + GPIO_CTRL_PULL_CTRL2_IO70 | \ + GPIO_CTRL_PULL_CTRL2_IO71, \ + GPIO_CTRL_RESEN2_R1 sc_end diff --git a/spi.c b/spi.c new file mode 100644 index 0000000..4fd00f6 --- /dev/null +++ b/spi.c @@ -0,0 +1,36 @@ +#include +#include +#include "printf.h" +#include "bionic.h" +#include "memio.h" +#include "spi.h" +#include "fernvale-spi.h" +#include "scriptic.h" + +static void spi_init(void) +{ + static int spi_initted = 0; + + if (spi_initted) + return; + + spi_initted = 1; + scriptic_run("spi_init"); +} + +int spi_cmd_txrx(uint8_t tx_size, uint8_t rx_size, + uint8_t *tx_buf, uint8_t *rx_buf) +{ + spi_init(); + + _memcpy(SPI_DATA, tx_buf, tx_size); + + writel(tx_size, SPI_WRITE_COUNT); + writel(rx_size, SPI_READ_COUNT); + + scriptic_run("spi_run"); + + _memcpy(rx_buf, SPI_DATA + tx_size, rx_size); + + return 0; +}