spi: Get basic SPI commands working
This commit is contained in:
parent
8d0e780508
commit
43a1517aec
8 changed files with 118 additions and 77 deletions
4
Makefile
4
Makefile
|
@ -15,11 +15,13 @@ SRC_C = \
|
||||||
cmd-peekpoke.c \
|
cmd-peekpoke.c \
|
||||||
cmd-reboot.c \
|
cmd-reboot.c \
|
||||||
cmd-sleep.c \
|
cmd-sleep.c \
|
||||||
|
cmd-spi.c \
|
||||||
emi.c \
|
emi.c \
|
||||||
irq.c \
|
irq.c \
|
||||||
main.c \
|
main.c \
|
||||||
scriptic.c \
|
scriptic.c \
|
||||||
serial.c \
|
serial.c \
|
||||||
|
spi.c \
|
||||||
utils.c \
|
utils.c \
|
||||||
vectors.c \
|
vectors.c \
|
||||||
vsprintf.c
|
vsprintf.c
|
||||||
|
@ -27,6 +29,8 @@ SRC_C = \
|
||||||
SRC_S = \
|
SRC_S = \
|
||||||
scriptic/set-plls.S \
|
scriptic/set-plls.S \
|
||||||
scriptic/enable-psram.S \
|
scriptic/enable-psram.S \
|
||||||
|
scriptic/spi.S \
|
||||||
|
scriptic/spi-blockmode.S \
|
||||||
_udivsi3.S \
|
_udivsi3.S \
|
||||||
_divsi3.S \
|
_divsi3.S \
|
||||||
start.S
|
start.S
|
||||||
|
|
22
cmd-spi.c
22
cmd-spi.c
|
@ -4,30 +4,30 @@
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
#include "spi.h"
|
#include "spi.h"
|
||||||
|
|
||||||
#define SPI_CSEL 0
|
|
||||||
|
|
||||||
int cmd_spi(int argc, char **argv)
|
int cmd_spi(int argc, char **argv)
|
||||||
{
|
{
|
||||||
uint32_t recv_bytes_count;
|
uint32_t recv_bytes_count;
|
||||||
uint8_t xmit_bytes[argc - 1];
|
uint8_t xmit_bytes[argc - 1];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (argc == 1 && !_strcasecmp(argv[0], "loop")) {
|
if (argc > 0 && !_strcasecmp(argv[0], "id")) {
|
||||||
printf("Repeatedly sending 0x9f -- id\n");
|
|
||||||
while(1) {
|
|
||||||
uint8_t out[1] = {0x9f};
|
uint8_t out[1] = {0x9f};
|
||||||
uint8_t in[3];
|
uint8_t in[3];
|
||||||
spi_cmd_txrx(0, sizeof(out), sizeof(in), out, in);
|
|
||||||
printf("ID: ");
|
spi_cmd_txrx(sizeof(out), sizeof(in), out, in);
|
||||||
serial_print_hex(in, sizeof(in));
|
|
||||||
}
|
printf("ID: %02x %02x %02x\n", in[0], in[1], in[2]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
printf("Send SPI bytes out and read the response.\n");
|
printf("Send SPI bytes out and read the response.\n");
|
||||||
printf("Usage: spi [count] [byte 1] [byte 2] ...\n");
|
printf("Usage:\n");
|
||||||
|
printf(" spi [count] [byte 1] [byte 2] ...\n");
|
||||||
printf(" Where \"count\" is the number of bytes to expect"
|
printf(" Where \"count\" is the number of bytes to expect"
|
||||||
" in response.\n");
|
" in response.\n");
|
||||||
|
printf(" spi id -- get device id\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ int cmd_spi(int argc, char **argv)
|
||||||
sizeof(xmit_bytes), sizeof(recv_bytes));
|
sizeof(xmit_bytes), sizeof(recv_bytes));
|
||||||
serial_print_hex(xmit_bytes, sizeof(xmit_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);
|
xmit_bytes, recv_bytes);
|
||||||
|
|
||||||
printf("Response:\n");
|
printf("Response:\n");
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#ifndef __SPI_H__
|
#ifndef __SPI_H__
|
||||||
#define __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__ */
|
#endif /* __SPI_H__ */
|
||||||
|
|
19
main.c
19
main.c
|
@ -184,8 +184,6 @@ static int list_registers(void)
|
||||||
|
|
||||||
static int do_init(void)
|
static int do_init(void)
|
||||||
{
|
{
|
||||||
const struct scriptic *script;
|
|
||||||
|
|
||||||
list_registers();
|
list_registers();
|
||||||
|
|
||||||
/* Disable system watchdog */
|
/* Disable system watchdog */
|
||||||
|
@ -197,11 +195,8 @@ static int do_init(void)
|
||||||
/* Disable battery watchdog */
|
/* Disable battery watchdog */
|
||||||
writew(0x2, PMIC_CTRL9);
|
writew(0x2, PMIC_CTRL9);
|
||||||
|
|
||||||
script = scriptic_get("set_plls");
|
scriptic_run("set_plls");
|
||||||
scriptic_execute(script);
|
scriptic_run("enable_psram");
|
||||||
|
|
||||||
script = scriptic_get("enable_psram");
|
|
||||||
scriptic_execute(script);
|
|
||||||
|
|
||||||
serial_puts("\n\nFernly shell\n");
|
serial_puts("\n\nFernly shell\n");
|
||||||
|
|
||||||
|
@ -337,12 +332,13 @@ static int loop(void)
|
||||||
|
|
||||||
static int cmd_help(int argc, char **argv);
|
static int cmd_help(int argc, char **argv);
|
||||||
extern int cmd_hex(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_peek(int argc, char **argv);
|
||||||
extern int cmd_poke(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_swi(int argc, char **argv);
|
||||||
extern int cmd_reboot(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 {
|
static const struct {
|
||||||
int (*func)(int argc, char **argv);
|
int (*func)(int argc, char **argv);
|
||||||
|
@ -384,6 +380,11 @@ static const struct {
|
||||||
.name = "irq",
|
.name = "irq",
|
||||||
.help = "Manipulate IRQs",
|
.help = "Manipulate IRQs",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.func = cmd_spi,
|
||||||
|
.name = "spi",
|
||||||
|
.help = "Manipulate on-board SPI",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.func = cmd_swi,
|
.func = cmd_swi,
|
||||||
.name = "swi",
|
.name = "swi",
|
||||||
|
|
|
@ -3,14 +3,19 @@
|
||||||
#include "bionic.h"
|
#include "bionic.h"
|
||||||
#include "memio.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 set_plls;
|
||||||
extern struct scriptic enable_psram;
|
extern struct scriptic enable_psram;
|
||||||
|
extern struct scriptic spi_run;
|
||||||
|
extern struct scriptic spi_run;
|
||||||
|
extern struct scriptic spi_init;
|
||||||
|
|
||||||
static struct scriptic *scripts[] = {
|
static struct scriptic *scripts[] = {
|
||||||
&set_plls,
|
&set_plls,
|
||||||
&enable_psram,
|
&enable_psram,
|
||||||
|
&spi_run,
|
||||||
|
&spi_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef SCRIPTIC_DEBUG
|
#ifdef SCRIPTIC_DEBUG
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#include "fernvale-spi.h"
|
#include "fernvale-spi.h"
|
||||||
|
|
||||||
/* Enable block mode for SPI CS0 */
|
/* 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 */
|
/* Wait for channel 2 to be idle */
|
||||||
sc_write32 SPI_CTRL3_CHANNEL2_MASK, SPI_CTRL3_CHANNEL2_MASK, SPI_CTRL3
|
sc_write32 SPI_CTRL3_CHANNEL2_MASK, SPI_CTRL3_CHANNEL2_MASK, SPI_CTRL3
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
/* Trigger the transfer */
|
/* Trigger the transfer */
|
||||||
sc_write32 \
|
sc_write32 \
|
||||||
SPI_BLOCKMODE_TRIGGER | SPI_BLOCKMODE_CS0, \
|
SPI_BLOCKMODE_TRIGGER | SPI_BLOCKMODE_CS0, \
|
||||||
SPI_BLOCKMODE_TRIGGER | SPI_BLOCKMODE_CS0, \
|
SPI_BLOCKMODE_TRIGGER | SPI_BLOCKMODE_CS, \
|
||||||
SPI_BLOCKMODE
|
SPI_BLOCKMODE
|
||||||
|
|
||||||
/* Wait for the device to prepare itself */
|
/* Wait for the device to prepare itself */
|
||||||
|
@ -25,48 +25,7 @@
|
||||||
sc_read32 0, SPI_BLOCKMODE_BUSY, SPI_BLOCKMODE
|
sc_read32 0, SPI_BLOCKMODE_BUSY, SPI_BLOCKMODE
|
||||||
|
|
||||||
/* Stop the transfer */
|
/* Stop the transfer */
|
||||||
sc_write32 0, SPI_BLOCKMODE_TRIGGER | SPI_BLOCKMODE_CS0, 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
|
|
||||||
|
|
||||||
/* 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
|
|
||||||
|
|
||||||
/* Wait for it to be disabled */
|
/* Wait for it to be disabled */
|
||||||
sc_read32 0, SPI_BLOCKMODE_PREP, SPI_BLOCKMODE
|
sc_read32 0, SPI_BLOCKMODE_PREP, SPI_BLOCKMODE
|
||||||
|
|
|
@ -1,22 +1,57 @@
|
||||||
#include "scriptic.h"
|
#include "scriptic.h"
|
||||||
#include "fernvale-spi.h"
|
#include "fernvale-spi.h"
|
||||||
|
#include "fernvale-gpio.h"
|
||||||
|
|
||||||
sc_new "spi_init", 1, 0, 0
|
sc_new "spi_init", 1, 0, 0
|
||||||
|
|
||||||
/* Ungate the clock */
|
/* Ungate the clock */
|
||||||
sc_write16 0x800, 0x800, 0x80000320
|
sc_write16 0x800, 0x800, 0x80000320
|
||||||
|
|
||||||
/* Switch to SPI NOR */ /* (XXX Might need to invert this) */
|
/* Switch to SPI NOR */
|
||||||
sc_write16 0, 1, 0x80000230
|
sc_write16 0, 1, 0x80000230
|
||||||
|
|
||||||
/* Remap GPIOs to be SPI */
|
/* Remap GPIOs to be SPI */
|
||||||
sc_write32 0x11111100, 0x77777700, 0xa0020c80
|
sc_write32 \
|
||||||
sc_write32 0x00000011, 0x00000077, 0xa0020c90
|
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 */
|
/* Enable high-impedence for GPIO mode */
|
||||||
sc_write16 0, 0x3fff, 0xa0020b10
|
sc_write16 0, \
|
||||||
sc_write16 0, 0x3fff, 0xa0020b40
|
GPIO_CTRL_PULL_CTRL1_IO66 | \
|
||||||
sc_write16 0, 0xdff1, 0xa0020b20
|
GPIO_CTRL_PULL_CTRL1_IO67 | \
|
||||||
sc_write16 0, 0xdff1, 0xa0020b50
|
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
|
sc_end
|
||||||
|
|
36
spi.c
Normal file
36
spi.c
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#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;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue