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-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
|
||||
|
|
22
cmd-spi.c
22
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) {
|
||||
if (argc > 0 && !_strcasecmp(argv[0], "id")) {
|
||||
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));
|
||||
}
|
||||
|
||||
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("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");
|
||||
|
|
|
@ -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__ */
|
||||
|
|
19
main.c
19
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",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
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