sunxi-fel适配原理和新芯片烧录功能的适配
·
测试方式:






移植补丁
diff --git a/.gitignore b/.gitignore
index 1db11da..7618ae1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,3 +8,7 @@ sunxi-pio
version.h
*.o
*.swp
+cscope.*
+tags
+.err
+*.fex
diff --git a/aw_spi.h b/aw_spi.h
new file mode 100644
index 0000000..5866523
--- /dev/null
+++ b/aw_spi.h
@@ -0,0 +1,868 @@
+#ifndef __AW_SPI_H__
+#define __AW_SPI_H__
+
+#include <stdint.h>
+
+//typedef unsigned int uint32_t;
+//typedef unsigned short uint16_t;
+//typedef unsigned char uint8_t;
+#ifdef __cplusplus
+extern "C" {
+#endif
+/********************** private ************************************/
+
+/**
+ * @brief Serial Peripheral Interface
+ */
+typedef struct
+{
+ volatile uint32_t RESERVED0; /* Reserved, 0x00 Address offset: 0x00 */
+ volatile uint32_t GCR; /* SPI Global Control Register, Address offset: 0x04 */
+ volatile uint32_t TCR; /* SPI Transfer Control Register, Address offset: 0x08 */
+ volatile uint32_t RESERVED1[1]; /* Reserved, 0x0C */
+ volatile uint32_t IER; /* SPI Interrupt Control Register, Address offset: 0x10 */
+ volatile uint32_t ISR; /* SPI Interrupt Status Register, Address offset: 0x14 */
+ volatile uint32_t FCR; /* SPI FIFO Control Register, Address offset: 0x18 */
+ volatile uint32_t FSR; /* SPI FIFO Status Register, Address offset: 0x1C */
+ volatile uint32_t WCR; /* SPI Wait Clock Counter Register, Address offset: 0x20 */
+ volatile uint32_t CCR; /* SPI Clock Rate Control Register, Address offset: 0x24 */
+
+ volatile uint32_t RESERVED2[2]; /* Reserved, 0x28-0x2C */
+ volatile uint32_t MBC; /* SPI Master mode Burst Control Register, Address offset: 0x30 */
+ volatile uint32_t MTC; /* SPI Master mode Transmit Counter Register, Address offset: 0x34 */
+ volatile uint32_t BCC; /* SPI Burst Control Register, Address offset: 0x38 */
+ volatile uint32_t RESERVED4[113]; /* Reserved, 0x3C-0x1FC */
+ volatile uint32_t TXD; /* SPI TX Date Register, Address offset: 0x200 */
+ volatile uint32_t RESERVED5[63]; /* Reserved, 0x204-0x2FC */
+ volatile uint32_t RXD; /* SPI RX Date Register, Address offset: 0x300 */
+} SPI_T;
+
+/*
+ * @brief SPI Global Control Register
+ */
+#define SPI_CTRL_RST_SHIFT (31)
+#define SPI_CTRL_RST_MASK (0x1U << SPI_CTRL_RST_SHIFT)
+
+#define SPI_CTRL_TP_EN_SHIFT (7)
+#define SPI_CTRL_TP_EN_MASK (0x1U << SPI_CTRL_TP_EN_SHIFT)
+
+#define SPI_CTRL_MODE_SHIFT (1)
+#define SPI_CTRL_MODE_MASK (0x1U << SPI_CTRL_MODE_SHIFT)
+typedef enum
+{
+ SPI_CTRL_MODE_SLAVE = 0 << SPI_CTRL_MODE_SHIFT,
+ SPI_CTRL_MODE_MASTER = 1 << SPI_CTRL_MODE_SHIFT
+} SPI_CTRL_Mode;
+
+#define SPI_CTRL_EN_SHIFT (0)
+#define SPI_CTRL_EN_MASK (0x1U << SPI_CTRL_EN_SHIFT)
+typedef enum
+{
+ SPI_CTRL_EN_DISABLE = 0 << SPI_CTRL_EN_SHIFT,
+ SPI_CTRL_EN_ENABLE = 1 << SPI_CTRL_EN_SHIFT
+} SPI_CTRL_En;
+
+/*
+ * @brief SPI Transfer Control Register
+ */
+#define SPI_TCTRL_XCH_SHIFT (31)
+#define SPI_TCTRL_XCH_MASK (0x1U << SPI_TCTRL_XCH_SHIFT)
+typedef enum
+{
+ SPI_TCTRL_XCH_IDLE = 0 << SPI_TCTRL_XCH_SHIFT,
+ SPI_TCTRL_XCH_START = 1 << SPI_TCTRL_XCH_SHIFT
+} SPI_TCTRL_Xch;
+
+#define SPI_TCTRL_SDM_SHIFT (13)
+#define SPI_TCTRL_SDM_MASK (0x1U << SPI_TCTRL_SDM_SHIFT)
+typedef enum
+{
+ SPI_TCTRL_SDM_SAMPLE_NODELAY = 1 << SPI_TCTRL_SDM_SHIFT,
+ SPI_TCTRL_SDM_SAMPLE_DELAY = 0 << SPI_TCTRL_SDM_SHIFT
+} SPI_TCTRL_Sdm;
+
+#define SPI_TCTRL_FBS_SHIFT (12)
+#define SPI_TCTRL_FBS_MASK (0x1U << SPI_TCTRL_FBS_SHIFT)
+typedef enum
+{
+ SPI_TCTRL_FBS_MSB = 0 << SPI_TCTRL_FBS_SHIFT,
+ SPI_TCTRL_FBS_LSB = 1 << SPI_TCTRL_FBS_SHIFT
+} SPI_TCTRL_Fbs;
+
+#define SPI_TCTRL_SDC_SHIFT (11)
+#define SPI_TCTRL_SDC_MASK (0x1U << SPI_TCTRL_SDC_SHIFT)
+
+#define SPI_TCTRL_RPSM_SHIFT (10)
+#define SPI_TCTRL_RPSM_MASK (0x1U << SPI_TCTRL_RPSM_SHIFT)
+
+#define SPI_TCTRL_DDB_SHIFT (9)
+#define SPI_TCTRL_DDB_MASK (0x1U << SPI_TCTRL_DDB_SHIFT)
+
+#define SPI_TCTRL_DHB_SHIFT (8)
+#define SPI_TCTRL_DHB_MASK (0x1U << SPI_TCTRL_DHB_SHIFT)
+typedef enum
+{
+ SPI_TCTRL_DHB_FULL_DUPLEX = 0 << SPI_TCTRL_DHB_SHIFT,
+ SPI_TCTRL_DHB_HALF_DUPLEX = 1 << SPI_TCTRL_DHB_SHIFT
+} SPI_TCTRL_DHB_Duplex;
+
+#define SPI_TCTRL_SS_LEVEL_SHIFT (7)
+#define SPI_TCTRL_SS_LEVEL_MASK (0x1U << SPI_TCTRL_SS_LEVEL_SHIFT)
+
+#define SPI_TCTRL_SS_OWNER_SHIFT (6)
+#define SPI_TCTRL_SS_OWNER_MASK (0x1U << SPI_TCTRL_SS_OWNER_SHIFT)
+typedef enum
+{
+ SPI_TCTRL_SS_OWNER_CONTROLLER = 0 << SPI_TCTRL_SS_OWNER_SHIFT,
+ SPI_TCTRL_SS_OWNER_SOFTWARE = 1 << SPI_TCTRL_SS_OWNER_SHIFT
+} SPI_TCTRL_SS_OWNER;
+
+#define SPI_TCTRL_SS_SEL_SHIFT (4)
+#define SPI_TCTRL_SS_SEL_MASK (0x3U << SPI_TCTRL_SS_SEL_SHIFT)
+typedef enum
+{
+ SPI_TCTRL_SS_SEL_SS0 = 0 << SPI_TCTRL_SS_SEL_SHIFT,
+ SPI_TCTRL_SS_SEL_SS1 = 1 << SPI_TCTRL_SS_SEL_SHIFT,
+ SPI_TCTRL_SS_SEL_SS2 = 2 << SPI_TCTRL_SS_SEL_SHIFT,
+ SPI_TCTRL_SS_SEL_SS3 = 3 << SPI_TCTRL_SS_SEL_SHIFT
+} SPI_TCTRL_SS_Sel;
+
+#define SPI_TCTRL_SS_CTL_SHIFT (3)
+#define SPI_TCTRL_SS_CTL_MASK (0x1U << SPI_TCTRL_SS_CTL_SHIFT)
+
+#define SPI_TCTRL_SPOL_SHIFT (2)
+#define SPI_TCTRL_SPOL_MASK (0x1U << SPI_TCTRL_SPOL_SHIFT)
+
+#define SPI_TCTRL_CPOL_SHIFT (1)
+#define SPI_TCTRL_CPOL_MASK (0x1U << SPI_TCTRL_CPOL_SHIFT)
+typedef enum
+{
+ SPI_TCTRL_CPOL_HIGH = 0 << SPI_TCTRL_CPOL_SHIFT,
+ SPI_TCTRL_CPOL_LOW = 1 << SPI_TCTRL_CPOL_SHIFT
+} SPI_TCTRL_Cpol;
+
+#define SPI_TCTRL_CPHA_SHIFT (0)
+#define SPI_TCTRL_CPHA_MASK (0x1U << SPI_TCTRL_CPHA_SHIFT)
+typedef enum
+{
+ SPI_TCTRL_CPHA_PHASE0 = 0 << SPI_TCTRL_CPHA_SHIFT,
+ SPI_TCTRL_CPHA_PHASE1 = 1 << SPI_TCTRL_CPHA_SHIFT
+} SPI_TCTRL_Cpha;
+
+typedef enum
+{
+ SPI_SCLK_Mode0 = 0 << SPI_TCTRL_CPHA_SHIFT,
+ SPI_SCLK_Mode1 = 1 << SPI_TCTRL_CPHA_SHIFT,
+ SPI_SCLK_Mode2 = 2 << SPI_TCTRL_CPHA_SHIFT,
+ SPI_SCLK_Mode3 = 3 << SPI_TCTRL_CPHA_SHIFT
+} SPI_SCLK_Mode;
+
+/*
+ * @brief SPI Interrupt Control Register
+ */
+#define SPI_IER_SS_INT_EN_SHIFT (13)
+#define SPI_IER_SS_INT_EN_MASK (0x1U << SPI_IER_SS_INT_EN_SHIFT)
+
+#define SPI_IER_TC_INT_EN_SHIFT (12)
+#define SPI_IER_TC_INT_EN_MASK (0x1U << SPI_IER_TC_INT_EN_SHIFT)
+
+#define SPI_IER_TF_UDR_INT_EN_SHIFT (11)
+#define SPI_IER_TF_UDR_INT_EN_MASK (0x1U << SPI_IER_TF_UDR_INT_EN_SHIFT)
+
+#define SPI_IER_TF_OVF_INT_EN_SHIFT (10)
+#define SPI_IER_TF_OVF_INT_EN_MASK (0x1U << SPI_IER_TF_OVF_INT_EN_SHIFT)
+
+#define SPI_IER_RF_UDR_INT_EN_SHIFT (9)
+#define SPI_IER_RF_UDR_INT_EN_MASK (0x1U << SPI_IER_RF_UDR_INT_EN_SHIFT)
+
+#define SPI_IER_RF_OVF_INT_EN_SHIFT (8)
+#define SPI_IER_RF_OVF_INT_EN_MASK (0x1U << SPI_IER_RF_OVF_INT_EN_SHIFT)
+
+#define SPI_IER_TF_FUL_INT_EN_SHIFT (6)
+#define SPI_IER_TF_FUL_INT_EN_MASK (0x1U << SPI_IER_TF_FUL_INT_EN_SHIFT)
+
+#define SPI_IER_TX_EMP_INT_EN_SHIFT (5)
+#define SPI_IER_TX_EMP_INT_EN_MASK (0x1U << SPI_IER_TX_EMP_INT_EN_SHIFT)
+
+#define SPI_IER_TX_ERQ_INT_EN_SHIFT (4)
+#define SPI_IER_TX_ERQ_INT_EN_MASK (0x1U << SPI_IER_TX_ERQ_INT_EN_SHIFT)
+
+#define SPI_IER_RF_FUL_INT_EN_SHIFT (2)
+#define SPI_IER_RF_FUL_INT_EN_MASK (0x1U << SPI_IER_RF_FUL_INT_EN_SHIFT)
+
+#define SPI_IER_RX_EMP_INT_EN_SHIFT (1)
+#define SPI_IER_RX_EMP_INT_EN_MASK (0x1U << SPI_IER_RX_EMP_INT_EN_SHIFT)
+
+#define SPI_IER_RF_RDY_INT_EN_SHIFT (0)
+#define SPI_IER_RF_RDY_INT_EN_MASK (0x1U << SPI_IER_RF_RDY_INT_EN_SHIFT)
+
+/*
+ * @brief SPI Interrupt Status Register
+ */
+#define SPI_STA_SSI_SHIFT (13)
+#define SPI_STA_SSI_MASK (0x1U << SPI_STA_SSI_SHIFT)
+
+#define SPI_STA_TC_SHIFT (12)
+#define SPI_STA_TC_MASK (0x1U << SPI_STA_TC_SHIFT)
+
+#define SPI_STA_TF_UDF_SHIFT (11)
+#define SPI_STA_TF_UDF_MASK (0x1U << SPI_STA_TF_UDF_SHIFT)
+
+#define SPI_STA_TF_OVF_SHIFT (10)
+#define SPI_STA_TF_OVF_MASK (0x1U << SPI_STA_TF_OVF_SHIFT)
+
+#define SPI_STA_RX_UDF_SHIFT (9)
+#define SPI_STA_RX_UDF_MASK (0x1U << SPI_STA_RX_UDF_SHIFT)
+
+#define SPI_STA_RX_OVF_SHIFT (8)
+#define SPI_STA_RX_OVF_MASK (0x1U << SPI_STA_RX_OVF_SHIFT)
+
+#define SPI_STA_TX_FULL_SHIFT (6)
+#define SPI_STA_TX_FULL_MASK (0x1U << SPI_STA_TX_FULL_SHIFT)
+
+#define SPI_STA_TX_EMP_SHIFT (5)
+#define SPI_STA_TX_EMP_MASK (0x1U << SPI_STA_TX_EMP_SHIFT)
+
+#define SPI_STA_TX_READY_SHIFT (4)
+#define SPI_STA_TX_READY_MASK (0x1U << SPI_STA_TX_READY_SHIFT)
+
+#define SPI_STA_RX_FULL_SHIFT (2)
+#define SPI_STA_RX_FULL_MASK (0x1U << SPI_STA_RX_FULL_SHIFT)
+
+#define SPI_STA_RX_EMP_SHIFT (1)
+#define SPI_STA_RX_EMP_MASK (0x1U << SPI_STA_RX_EMP_SHIFT)
+
+#define SPI_STA_RX_RDY_SHIFT (0)
+#define SPI_STA_RX_RDY_MASK (0x1U << SPI_STA_RX_RDY_SHIFT)
+
+/*
+ * @brief SPI FIFO Control Register
+ */
+#define SPI_FCTL_TF_RST_SHIFT (31)
+#define SPI_FCTL_TF_RST_MASK (0x1U << SPI_FCTL_TF_RST_SHIFT)
+
+#define SPI_FCTL_TF_TEST_EN_SHIFT (30)
+#define SPI_FCTL_TF_TEST_EN_MASK (0x1U << SPI_FCTL_TF_TEST_EN_SHIFT)
+
+#define SPI_FCTL_TF_DRQ_EN_SHIFT (24)
+#define SPI_FCTL_TF_DRQ_EN_MASK (0x1U << SPI_FCTL_TF_DRQ_EN_SHIFT)
+#define SPI_FCTL_TF_DRQ_EN_BIT HAL_BIT(24)
+
+#define SPI_FCTL_TX_TRIG_LEVEL_SHIFT (16)
+#define SPI_FCTL_TX_TRIG_LEVEL_MASK (0xFFU << SPI_FCTL_TX_TRIG_LEVEL_SHIFT)
+
+#define SPI_FCTL_RF_RST_SHIFT (15)
+#define SPI_FCTL_RF_RST_MASK (0x1U << SPI_FCTL_RF_RST_SHIFT)
+
+#define SPI_FCTL_RF_TEST_SHIFT (14)
+#define SPI_FCTL_RF_TEST_MASK (0x1U << SPI_FCTL_RF_TEST_SHIFT)
+
+#define SPI_FCTL_RF_DRQ_EN_SHIFT (8)
+#define SPI_FCTL_RF_DRQ_EN_MASK (0x1U << SPI_FCTL_RF_DRQ_EN_SHIFT)
+
+#define SPI_FCTL_RX_TRIG_LEVEL_SHIFT (0)
+#define SPI_FCTL_RX_TRIG_LEVEL_MASK (0xFFU << SPI_FCTL_RX_TRIG_LEVEL_SHIFT)
+
+/*
+ * @brief SPI FIFO Status Registe
+ */
+#define SPI_FST_TB_WR_SHIFT (31)
+#define SPI_FST_TB_WR_MASK (0x1U << SPI_FST_TB_WR_SHIFT)
+
+#define SPI_FST_TB_CNT_SHIFT (28)
+#define SPI_FST_TB_CNT_MASK (0x7U << SPI_FST_TB_CNT_SHIFT)
+
+#define SPI_FST_TF_CNT_SHIFT (16)
+#define SPI_FST_TF_CNT_MASK (0xFFU << SPI_FST_TF_CNT_SHIFT)
+
+#define SPI_FST_RB_WR_SHIFT (15)
+#define SPI_FST_RB_WR_MASK (0x1U << SPI_FST_RB_WR_SHIFT)
+
+#define SPI_FST_RB_CNT_SHIFT (12)
+#define SPI_FST_RB_CNT_MASK (0x7U << SPI_FST_RB_CNT_SHIFT)
+
+#define SPI_FST_RF_CNT_SHIFT (0)
+#define SPI_FST_RF_CNT_MASK (0xFFU << SPI_FST_RF_CNT_SHIFT)
+
+/*
+ * @brief SPI Wait Clock Counter Register
+ */
+#define SPI_WAIT_SWC_SHIFT (16)
+#define SPI_WAIT_SWC_MASK (0xFU << SPI_WAIT_SWC_SHIFT)
+
+#define SPI_WAIT_WCC_SHIFT (0)
+#define SPI_WAIT_WCC_MASK (0xFFFFU << SPI_WAIT_WCC_SHIFT)
+
+/*
+ * @brief SPI Clock Rate Control Register
+ */
+#define SPI_CCTR_DRS_SHIFT (12)
+#define SPI_CCTR_DRS_MASK (0x1U << SPI_CCTR_DRS_SHIFT)
+typedef enum
+{
+ SPI_CCTR_DRS_type_divRate1 = 0 << SPI_CCTR_DRS_SHIFT,
+ SPI_CCTR_DRS_type_divRate2 = 1 << SPI_CCTR_DRS_SHIFT
+} SPI_CCTR_DRS_type;
+
+#define SPI_CCTR_CDR1_SHIFT (8)
+#define SPI_CCTR_CDR1_MASK (0xFU << SPI_CCTR_CDR1_SHIFT)
+
+#define SPI_CCTR_CDR2_SHIFT (0)
+#define SPI_CCTR_CDR2_MASK (0xFFU << SPI_CCTR_CDR2_SHIFT)
+
+/*
+ * @brief SPI Master mode Burst Control Register
+ */
+#define SPI_BC_MBC_SHIFT (0)
+#define SPI_BC_MBC_MASK (0xFFFFFFU << SPI_BC_MBC_SHIFT)
+
+/*
+ * @brief SPI Master mode Transmit Counter Register
+ */
+#define SPI_TC_MWTC_SHIFT (0)
+#define SPI_TC_MWTC_MASK (0xFFFFFFU << SPI_TC_MWTC_SHIFT)
+
+/*
+ * @brief SPI Burst Control Register
+ */
+#define SPI_BCC_DRM_SHIFT (28)
+#define SPI_BCC_DRM_MASK (0x1U << SPI_BCC_DRM_SHIFT)
+
+#define SPI_BCC_DBC_SHIFT (24)
+#define SPI_BCC_DBC_MASK (0xFU << SPI_BCC_DBC_SHIFT)
+
+#define SPI_BCC_STC_SHIFT (0)
+#define SPI_BCC_STC_MASK (0xFFFFFFU << SPI_BCC_STC_SHIFT)
+
+/*
+ * @brief SPI TX Date Register
+ */
+#define SPI_TXD_SHIFT (0)
+#define SPI_TXD_MASK (0xFFFFFFFFU << SPI_TXD_SHIFT)
+
+/*
+ * @brief SPI RX Date Register
+ */
+#define SPI_RXD_SHIFT (0)
+#define SPI_RXD_MASK (0xFFFFFFFFU << SPI_RXD_SHIFT)
+
+/* other */
+#define SPI_FIFO_SIZE (64)
+#define SPI_MAX_WAIT_MS (2000)
+#define SPI_SOURCE_CLK (24 * 1000 * 1000)
+
+/* io ops */
+#define HAL_BIT(pos) (1U << (pos))
+
+#define HAL_SET_BIT(reg, mask) ((reg) |= (mask))
+#define HAL_CLR_BIT(reg, mask) ((reg) &= ~(mask))
+#define HAL_GET_BIT(reg, mask) ((reg) & (mask))
+#define HAL_GET_BIT_VAL(reg, shift, vmask) (((reg) >> (shift)) & (vmask))
+
+#define HAL_MODIFY_REG(reg, clr_mask, set_mask) \
+ ((reg) = (((reg) & (~(clr_mask))) | (set_mask)))
+
+/* access LSBs of a 32-bit register (little endian only) */
+#define HAL_REG_32BIT(reg_addr) (*((volatile uint32_t *)(reg_addr)))
+#define HAL_REG_16BIT(reg_addr) (*((volatile uint16_t *)(reg_addr)))
+#define HAL_REG_8BIT(reg_addr) (*((volatile uint8_t *)(reg_addr)))
+
+#define HAL_WAIT_FOREVER OS_WAIT_FOREVER
+
+#define HAL_ARRAY_SIZE(a) (sizeof((a)) / sizeof((a)[0]))
+
+struct aw_spi_cs
+{
+ SPI_TCTRL_SS_Sel cs;
+ int cs_port;
+ int cs_pin;
+ int cs_io_func;
+};
+
+struct aw_spi_init
+{
+ uintptr_t clk;
+ uintptr_t base_addr;
+ uintptr_t irq_num;
+ int mosi_port;
+ int mosi_pin;
+ int mosi_io_func;
+ int miso_port;
+ int miso_pin;
+ int miso_io_func;
+ int ck_port;
+ int ck_pin;
+ int ck_io_func;
+ int wp_port;
+ int wp_pin;
+ int wp_io_func;
+ int hold_port;
+ int hold_pin;
+ int hold_io_func;
+};
+
+/* ------------------------------------------------------------------------------ */
+#define pio_base_addr (0x0300B000)
+#define readl(addr) (*(volatile unsigned int *)(addr))
+#define writel(value,addr) (*(volatile unsigned int *)(addr) = (value))
+
+#define GPIOn_CFG_ADDR(base, n) (base + (n) * 0x24 + 0x00)
+#define GPIOn_DATA_ADDR(base, n) (base + (n) * 0x24 + 0x10)
+#define GPIOn_DRV_ADDR(base, n) (base + (n) * 0x24 + 0x14)
+#define GPIOn_PUL_ADDR(base, n) (base + (n) * 0x24 + 0x1C)
+#define GPIOn_INT_CFG_ADDR(base, n) (base + 0x200 + (n) * 0x20 + 0x00)
+#define GPIOn_INT_CTRL_ADDR(base, n) (base + 0x200 + (n) * 0x20 + 0x10)
+#define GPIOn_INT_STA_ADDR(base, n) (base + 0x200 + (n) * 0x20 + 0x14)
+#define GPIOn_INT_DEB_ADDR(base, n) (base + 0x200 + (n) * 0x20 + 0x18)
+
+/* IO port */
+enum gpio_port
+{
+ GPIO_PORT_A = 0,
+ GPIO_PORT_B,
+ GPIO_PORT_C,
+ GPIO_PORT_D,
+ GPIO_PORT_E,
+ GPIO_PORT_F,
+ GPIO_PORT_G,
+ GPIO_PORT_H,
+ GPIO_PORT_I,
+ GPIO_PORT_NUM,
+};
+
+/* IO pin */
+enum gpio_pin
+{
+ GPIO_PIN_0 = 0,
+ GPIO_PIN_1,
+ GPIO_PIN_2,
+ GPIO_PIN_3,
+ GPIO_PIN_4,
+ GPIO_PIN_5,
+ GPIO_PIN_6,
+ GPIO_PIN_7,
+ GPIO_PIN_8,
+ GPIO_PIN_9,
+ GPIO_PIN_10,
+ GPIO_PIN_11,
+ GPIO_PIN_12,
+ GPIO_PIN_13,
+ GPIO_PIN_14,
+ GPIO_PIN_15,
+ GPIO_PIN_16,
+ GPIO_PIN_17,
+ GPIO_PIN_18,
+ GPIO_PIN_19,
+ GPIO_PIN_20,
+ GPIO_PIN_21,
+ GPIO_PIN_22,
+ GPIO_PIN_23,
+ GPIO_PIN_NUM,
+};
+
+#define IO_INPUT (0x00)
+#define IO_OUTPUT (0x01)
+#define IO_DISABLE (0x07)
+#define IO_FUN_2 (0x02)
+#define IO_FUN_3 (0x03)
+#define IO_FUN_4 (0x04)
+#define IO_FUN_5 (0x05)
+#define IO_FUN_6 (0x06)
+
+#define clk_port GPIO_PORT_C
+#define hld_port GPIO_PORT_C
+#define wp_port GPIO_PORT_C
+#define mosi_port GPIO_PORT_C
+#define miso_port GPIO_PORT_C
+#define cs_port GPIO_PORT_C
+
+#define clk_pin GPIO_PIN_0
+#define mosi_pin GPIO_PIN_2
+#define miso_pin GPIO_PIN_4
+#define wp_pin GPIO_PIN_15
+#define hld_pin GPIO_PIN_16
+#define cs_pin GPIO_PIN_3
+#define cs_sel SPI_TCTRL_SS_SEL_SS0
+
+#define ck_io_func IO_FUN_4
+#define hold_io_func IO_FUN_4
+#define wp_io_func IO_FUN_4
+#define mosi_io_func IO_FUN_4
+#define miso_io_func IO_FUN_4
+#define cs_io_func IO_FUN_4
+
+static inline __attribute((always_inline)) void gpio_set_func(enum gpio_port port, enum gpio_pin pin, uint8_t func)
+{
+ uintptr_t addr;
+ uint32_t offset;
+ uint32_t data;
+
+ addr = GPIOn_CFG_ADDR(pio_base_addr, port) + (pin / 8) * 4;
+ offset = (pin % 8) * 4;
+ data = readl(addr);
+ data &= ~(0x7 << offset);
+ data |= func << offset;
+ writel(data, addr);
+}
+static inline __attribute((always_inline)) int gpio_set_value(enum gpio_port port, enum gpio_pin pin, uint8_t value)
+{
+ uint32_t addr;
+ uint32_t offset;
+ uint32_t data;
+
+ addr = GPIOn_DATA_ADDR(pio_base_addr, port);
+ offset = pin;
+
+ data = readl(addr);
+ data &= ~(0x1 << offset);
+ data |= value << offset;
+ writel(data, addr);
+}
+
+static inline __attribute((always_inline)) void gpio_direction_output(enum gpio_port port, enum gpio_pin pin, int value)
+{
+ volatile uint32_t addr;
+ uint32_t offset;
+ uint32_t data;
+
+ gpio_set_value(port, pin, value);
+ addr = GPIOn_CFG_ADDR(pio_base_addr, port) + (pin / 8) * 4;
+ offset = (pin % 8) * 4;
+
+ data = readl(addr);
+ data &= ~(0x7 << offset);
+ data |= IO_OUTPUT << offset;
+ writel(data, addr);
+}
+
+/* ------------------------------------------------------------------------------ */
+#define SPI_BUS_MAX_CLK (100 * 1000 * 1000)
+#define SPI_CTR_ADDRESS (SPI_T *)0x05010000;
+
+static inline __attribute((always_inline)) void SPI_Reset(SPI_T *spi)
+{
+ HAL_SET_BIT(spi->GCR, SPI_CTRL_RST_MASK);
+}
+
+static inline __attribute((always_inline)) void SPI_SetMode(SPI_T *spi, SPI_CTRL_Mode mode)
+{
+ HAL_MODIFY_REG(spi->GCR, SPI_CTRL_MODE_MASK, mode);
+}
+
+static inline __attribute((always_inline)) void SPI_Enable(SPI_T *spi)
+{
+ HAL_SET_BIT(spi->GCR, SPI_CTRL_EN_MASK);
+}
+
+static inline __attribute((always_inline)) void SPI_Disable(SPI_T *spi)
+{
+ HAL_CLR_BIT(spi->GCR, SPI_CTRL_EN_MASK);
+}
+
+/*
+ * @brief
+ */
+static inline __attribute((always_inline)) void SPI_StartTransmit(SPI_T *spi)
+{
+ HAL_SET_BIT(spi->TCR, SPI_TCTRL_XCH_MASK);
+}
+
+/*
+ * @brief
+ */
+static inline __attribute((always_inline)) void SPI_SetFirstTransmitBit(SPI_T *spi, SPI_TCTRL_Fbs bit)
+{
+ HAL_MODIFY_REG(spi->TCR, SPI_TCTRL_FBS_MASK, bit);
+}
+
+/*
+ * @brief
+ */
+static inline __attribute((always_inline)) void SPI_EnableRapidsMode(SPI_T *spi, int delay_sample)
+{
+ HAL_SET_BIT(spi->TCR, SPI_TCTRL_RPSM_MASK);
+ HAL_MODIFY_REG(spi->TCR, SPI_TCTRL_SDC_MASK, delay_sample << SPI_TCTRL_SDC_SHIFT);
+}
+
+/*
+ * @brief
+ */
+static inline __attribute((always_inline)) void SPI_DisableRapidsMode(SPI_T *spi)
+{
+ HAL_CLR_BIT(spi->TCR, SPI_TCTRL_RPSM_MASK);
+}
+
+static inline __attribute((always_inline)) void SPI_SetDuplex(SPI_T *spi, SPI_TCTRL_DHB_Duplex duplex)
+{
+ HAL_MODIFY_REG(spi->TCR, SPI_TCTRL_DHB_MASK, duplex);
+}
+
+/*
+ * @brief
+ */
+static inline __attribute((always_inline)) void SPI_SetCsLevel(SPI_T *spi, int level)
+{
+ HAL_MODIFY_REG(spi->TCR, SPI_TCTRL_SS_LEVEL_MASK, level << SPI_TCTRL_SS_LEVEL_SHIFT);
+}
+
+/*
+ * @brief
+ */
+static inline __attribute((always_inline)) void SPI_ManualChipSelect(SPI_T *spi, SPI_TCTRL_SS_Sel cs)
+{
+ HAL_SET_BIT(spi->TCR, SPI_TCTRL_SS_OWNER_MASK);
+ HAL_MODIFY_REG(spi->TCR, SPI_TCTRL_SS_SEL_MASK, cs);
+}
+
+/*
+ * @brief
+ */
+static inline __attribute((always_inline)) void SPI_AutoChipSelect(SPI_T *spi, SPI_TCTRL_SS_Sel cs, int cs_remain)
+{
+ HAL_MODIFY_REG(spi->TCR, SPI_TCTRL_SS_SEL_MASK, cs);
+ HAL_CLR_BIT(spi->TCR, SPI_TCTRL_SS_OWNER_MASK);
+ HAL_MODIFY_REG(spi->TCR, SPI_TCTRL_SS_CTL_MASK, (!cs_remain) << SPI_TCTRL_SS_CTL_SHIFT);
+}
+
+/*
+ * @brief
+ */
+static inline __attribute((always_inline)) void SPI_SetCsIdle(SPI_T *spi, int idle)
+{
+ HAL_MODIFY_REG(spi->TCR, SPI_TCTRL_SPOL_MASK, (!!idle) << SPI_TCTRL_SPOL_SHIFT);
+}
+
+/*
+ * @brief
+ */
+static inline __attribute((always_inline)) void SPI_SetSclkMode(SPI_T *spi, SPI_SCLK_Mode mode)
+{
+ HAL_MODIFY_REG(spi->TCR, SPI_TCTRL_CPOL_MASK | SPI_TCTRL_CPHA_MASK, mode);
+}
+
+typedef enum
+{
+ SPI_INT_CS_DESELECT = SPI_IER_SS_INT_EN_MASK,
+ SPI_INT_TRANSFER_COMPLETE = SPI_IER_TC_INT_EN_MASK,
+ SPI_INT_TXFIFO_UNDER_RUN = SPI_IER_TF_UDR_INT_EN_MASK,
+ SPI_INT_TXFIFO_OVERFLOW = SPI_IER_TF_OVF_INT_EN_MASK,
+ SPI_INT_RXFIFO_UNDER_RUN = SPI_IER_RF_UDR_INT_EN_MASK,
+ SPI_INT_RXFIFO_OVERFLOW = SPI_IER_RF_OVF_INT_EN_MASK,
+ SPI_INT_TXFIFO_FULL = SPI_IER_TF_FUL_INT_EN_MASK,
+ SPI_INT_TXFIFO_EMPTY = SPI_IER_TX_EMP_INT_EN_MASK,
+ SPI_INT_TXFIFO_READY = SPI_IER_TX_ERQ_INT_EN_MASK,
+ SPI_INT_RXFIFO_FULL = SPI_IER_RF_FUL_INT_EN_MASK,
+ SPI_INT_RXFIFO_EMPTY = SPI_IER_RX_EMP_INT_EN_MASK,
+ SPI_INT_RXFIFO_READY = SPI_IER_RF_RDY_INT_EN_MASK
+} SPI_Int_Type;
+
+/*
+ * @brief
+ */
+static inline __attribute((always_inline)) void SPI_EnableInt(SPI_T *spi, SPI_Int_Type type)
+{
+ HAL_SET_BIT(spi->IER, type);
+}
+
+/*
+ * @brief
+ */
+static inline __attribute((always_inline)) void SPI_DisableInt(SPI_T *spi, SPI_Int_Type type)
+{
+ HAL_CLR_BIT(spi->IER, type);
+}
+
+/*
+ * @brief
+ */
+static inline __attribute((always_inline)) int SPI_IntState(SPI_T *spi, SPI_Int_Type type)
+{
+ return !!HAL_GET_BIT(spi->ISR, type);
+}
+
+static inline __attribute((always_inline)) int SPI_ClearInt(SPI_T *spi, SPI_Int_Type type)
+{
+ HAL_SET_BIT(spi->ISR, type);
+ return HAL_GET_BIT(spi->ISR, type);
+}
+
+/*
+ * @brief
+ */
+static inline __attribute((always_inline)) void SPI_DebugReadTx(SPI_T *spi, uint32_t *data)
+{
+ // tbc...
+}
+
+/*
+ * @brief
+ */
+static inline __attribute((always_inline)) void SPI_DebugWriteRx(SPI_T *spi, uint32_t *data)
+{
+ // tbc...
+}
+
+/*
+ * @brief
+ */
+static inline __attribute((always_inline)) void SPI_ResetTxFifo(SPI_T *spi)
+{
+ HAL_SET_BIT(spi->FCR, SPI_FCTL_TF_RST_MASK);
+ while (HAL_GET_BIT(spi->FCR, SPI_FCTL_TF_RST_MASK) != 0);
+}
+
+/*
+ * @brief
+ */
+static inline __attribute((always_inline)) void SPI_ResetRxFifo(SPI_T *spi)
+{
+ HAL_SET_BIT(spi->FCR, SPI_FCTL_RF_RST_MASK);
+ while (HAL_GET_BIT(spi->FCR, SPI_FCTL_RF_RST_MASK) != 0);
+}
+
+/*
+ * @brief
+ */
+static inline __attribute((always_inline)) void SPI_DMA(SPI_T *spi, int txEn, int rxEn)
+{
+ HAL_MODIFY_REG(spi->FCR,
+ SPI_FCTL_TF_DRQ_EN_MASK | SPI_FCTL_RF_DRQ_EN_MASK,
+ ((!!txEn) << SPI_FCTL_TF_DRQ_EN_SHIFT) | ((!!rxEn) << SPI_FCTL_RF_DRQ_EN_SHIFT));
+}
+
+/*
+ * @brief
+ */
+static inline __attribute((always_inline)) void SPI_SetTxFifoThreshold(SPI_T *spi, uint8_t threshold)
+{
+ HAL_MODIFY_REG(spi->FCR, SPI_FCTL_TX_TRIG_LEVEL_MASK, threshold << SPI_FCTL_TX_TRIG_LEVEL_SHIFT);
+}
+
+/*
+ * @brief
+ */
+static inline __attribute((always_inline)) void SPI_SetRxFifoThreshold(SPI_T *spi, uint8_t threshold)
+{
+ HAL_MODIFY_REG(spi->FCR, SPI_FCTL_RX_TRIG_LEVEL_MASK, threshold << SPI_FCTL_RX_TRIG_LEVEL_SHIFT);
+}
+
+/*
+ * @brief
+ */
+static inline __attribute((always_inline)) uint8_t SPI_GetTxFifoCounter(SPI_T *spi)
+{
+ return (uint8_t)((spi->FSR & SPI_FST_TF_CNT_MASK) >> SPI_FST_TF_CNT_SHIFT);
+}
+
+/*
+ * @brief
+ */
+static inline __attribute((always_inline)) uint8_t SPI_GetRxFifoCounter(SPI_T *spi)
+{
+ return (uint8_t)((spi->FSR & SPI_FST_RF_CNT_MASK) >> SPI_FST_RF_CNT_SHIFT);
+}
+
+/*
+ * @brief
+ */
+static inline __attribute((always_inline)) void SPI_EnableDualMode(SPI_T *spi)
+{
+ HAL_SET_BIT(spi->BCC, SPI_BCC_DRM_MASK);
+}
+
+/*
+ * @brief
+ */
+static inline __attribute((always_inline)) void SPI_DisableDualMode(SPI_T *spi)
+{
+ HAL_CLR_BIT(spi->BCC, SPI_BCC_DRM_MASK);
+}
+
+/*
+ * @brief
+ */
+static inline __attribute((always_inline)) void SPI_SetInterval(SPI_T *spi, uint16_t nSCLK)
+{
+ HAL_MODIFY_REG(spi->WCR, SPI_WAIT_WCC_MASK, nSCLK << SPI_WAIT_WCC_SHIFT);
+}
+
+/*
+ * @brief
+ */
+
+static inline __attribute((always_inline)) void SPI_SetClkDiv(SPI_T *spi, uint16_t div)
+{
+ uint8_t n = 0;
+ if (div < 1)
+ {
+ return;
+ }
+
+ if (div > 2 * (0xFF + 1))
+ {
+ HAL_CLR_BIT(spi->CCR, SPI_CCTR_DRS_MASK);
+ do
+ {
+ div = (div == 1) ? 0 : ((div + 1) / 2);
+ n++;
+ }
+ while (div);
+
+ HAL_MODIFY_REG(spi->CCR, SPI_CCTR_CDR1_MASK, (n & 0x0F) << SPI_CCTR_CDR1_SHIFT);
+ }
+ else
+ {
+ HAL_SET_BIT(spi->CCR, SPI_CCTR_DRS_MASK);
+ n = ((div + 1) / 2) - 1;
+ HAL_MODIFY_REG(spi->CCR, SPI_CCTR_CDR2_MASK, (n & 0xFF) << SPI_CCTR_CDR2_SHIFT);
+ }
+}
+
+/*
+ * @brief
+ */
+static inline __attribute((always_inline)) void SPI_SetDataSize(SPI_T *spi, uint32_t data_size, uint32_t dummy_size)
+{
+ HAL_MODIFY_REG(spi->MBC, SPI_BC_MBC_MASK, data_size + dummy_size);
+ HAL_MODIFY_REG(spi->MTC, SPI_TC_MWTC_MASK, data_size);
+ HAL_MODIFY_REG(spi->BCC, SPI_BCC_STC_MASK, data_size);
+}
+
+/*
+ * @brief
+ */
+static inline __attribute((always_inline)) void SPI_Write(SPI_T *spi, uint8_t *data)
+{
+ HAL_REG_8BIT(&spi->TXD) = *data;
+}
+
+/*
+ * @brief
+ */
+static inline __attribute((always_inline)) void SPI_Read(SPI_T *spi, uint8_t *data)
+{
+ *data = HAL_REG_8BIT(&spi->RXD);
+}
+
+/*
+ * @brief
+ */
+static inline __attribute((always_inline)) uint8_t *SPI_TxAddress(SPI_T *spi)
+{
+ return (uint8_t *)&spi->TXD;
+}
+
+/*
+ * @brief
+ */
+static inline __attribute((always_inline)) uint8_t *SPI_RxAddress(SPI_T *spi)
+{
+ return (uint8_t *)&spi->RXD;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/fel-remotefunc-compiler.rb b/fel-remotefunc-compiler.rb
old mode 100644
new mode 100755
index 50ea9ea..4824d51
--- a/fel-remotefunc-compiler.rb
+++ b/fel-remotefunc-compiler.rb
@@ -33,8 +33,8 @@ if ARGV.size < 2
printf("Using this example code inside of sunxi-fel:\n")
printf("\n")
printf(" uint32_t a = 1, b = 2, c;\n")
- printf(" aw_fel_remotefunc_prepare_sum(usb, a, b);\n")
- printf(" aw_fel_remotefunc_execute(usb, &c);\n")
+ printf(" aw_fel_remotefunc_prepare_sum(dev, a, b);\n")
+ printf(" aw_fel_remotefunc_execute(dev, &c);\n")
printf(" printf(\"%%d + %%d = %%d\\n\", a, b, c);\n\n")
printf("If the returned result is not needed (a void function), then the second\n")
@@ -122,7 +122,7 @@ out = File.open(ARGV[1], "w")
out.printf("/* Automatically generated, do not edit! */\n\n")
out.printf("static void\n")
-funcdecl = sprintf("aw_fel_remotefunc_prepare_#{function_name}(libusb_device_handle *usb,")
+funcdecl = sprintf("aw_fel_remotefunc_prepare_#{function_name}(feldev_handle *dev,")
out.printf("%s\n", funcdecl)
out.printf("%s", function_args.map {|a|
" " * funcdecl.index("(") + " uint32_t " + a }.join(",\n"))
@@ -143,7 +143,7 @@ out.printf("\t};\n")
out.printf("\tuint32_t args[] = {\n\t\t")
out.printf("%s\n\t};\n", function_args.join(",\n\t\t"))
-out.printf("\taw_fel_remotefunc_prepare(usb, %d, arm_code, sizeof(arm_code), %d, args);\n",
+out.printf("\taw_fel_remotefunc_prepare(dev, %d, arm_code, sizeof(arm_code), %d, args);\n",
stack_usage[0][:stack_usage], function_args.size)
out.printf("}\n")
diff --git a/fel-remotefunc-spi-data-transfer.h b/fel-remotefunc-spi-data-transfer.h
index c1a64cb..233ef70 100644
--- a/fel-remotefunc-spi-data-transfer.h
+++ b/fel-remotefunc-spi-data-transfer.h
@@ -4,147 +4,147 @@ static void
aw_fel_remotefunc_prepare_spi_batch_data_transfer(feldev_handle *dev,
uint32_t buf,
uint32_t spi_ctl_reg,
- uint32_t spi_ctl_xch_bitmask,
- uint32_t spi_fifo_reg,
- uint32_t spi_tx_reg,
- uint32_t spi_rx_reg,
- uint32_t spi_bc_reg,
- uint32_t spi_tc_reg,
- uint32_t spi_bcc_reg)
+ uint32_t unused1,
+ uint32_t unused2,
+ uint32_t unused3,
+ uint32_t unused4,
+ uint32_t unused5,
+ uint32_t unused6,
+ uint32_t unused7)
{
static uint8_t arm_code[] = {
0xf0, 0x0f, 0x2d, 0xe9, /* 0: push {r4, r5, r6, r7, r8, r9, sl, fp} */
- 0x18, 0xd0, 0x4d, 0xe2, /* 4: sub sp, sp, #24 */
- 0x38, 0x50, 0x9d, 0xe5, /* 8: ldr r5, [sp, #56] */
- 0x3c, 0x60, 0x9d, 0xe5, /* c: ldr r6, [sp, #60] */
- 0x06, 0x00, 0x8d, 0xe9, /* 10: stmib sp, {r1, r2} */
- 0x00, 0xa0, 0xd0, 0xe5, /* 14: ldrb sl, [r0] */
- 0x01, 0x20, 0xd0, 0xe5, /* 18: ldrb r2, [r0, #1] */
- 0x0a, 0xa4, 0x92, 0xe1, /* 1c: orrs sl, r2, sl, lsl #8 */
- 0x6a, 0x00, 0x00, 0x0a, /* 20: beq 1d0 <spi_batch_data_transfer+0x1d0> */
- 0xff, 0x2f, 0x0f, 0xe3, /* 24: movw r2, #65535 */
- 0x02, 0x00, 0x5a, 0xe1, /* 28: cmp sl, r2 */
- 0x18, 0x80, 0x8d, 0x02, /* 2c: addeq r8, sp, #24 */
- 0x02, 0x80, 0x80, 0x12, /* 30: addne r8, r0, #2 */
- 0x05, 0xb0, 0xa0, 0x03, /* 34: moveq fp, #5 */
- 0x48, 0xc0, 0x9d, 0xe5, /* 38: ldr ip, [sp, #72] */
- 0x08, 0xb0, 0x68, 0x05, /* 3c: strbeq fp, [r8, #-8]! */
- 0x00, 0x10, 0x68, 0xe2, /* 40: rsb r1, r8, #0 */
- 0x40, 0x20, 0x9d, 0xe5, /* 44: ldr r2, [sp, #64] */
- 0x03, 0x10, 0x01, 0xe2, /* 48: and r1, r1, #3 */
- 0x44, 0xb0, 0x9d, 0xe5, /* 4c: ldr fp, [sp, #68] */
- 0x0a, 0x70, 0xa0, 0x11, /* 50: movne r7, sl */
- 0x0c, 0x00, 0x8d, 0x05, /* 54: streq r0, [sp, #12] */
- 0x3c, 0x00, 0x81, 0xe2, /* 58: add r0, r1, #60 */
- 0x02, 0x70, 0xa0, 0x03, /* 5c: moveq r7, #2 */
- 0x00, 0x00, 0x5c, 0xe3, /* 60: cmp ip, #0 */
- 0x00, 0x70, 0x82, 0xe5, /* 64: str r7, [r2] */
- 0x08, 0x20, 0xa0, 0xe1, /* 68: mov r2, r8 */
- 0x00, 0x70, 0x8b, 0xe5, /* 6c: str r7, [fp] */
- 0x00, 0x70, 0x8c, 0x15, /* 70: strne r7, [ip] */
- 0x07, 0x00, 0x50, 0xe1, /* 74: cmp r0, r7 */
- 0x07, 0x00, 0xa0, 0x21, /* 78: movcs r0, r7 */
- 0x00, 0x40, 0x88, 0xe0, /* 7c: add r4, r8, r0 */
- 0x01, 0xc0, 0xd2, 0xe4, /* 80: ldrb ip, [r2], #1 */
- 0x04, 0x00, 0x52, 0xe1, /* 84: cmp r2, r4 */
- 0x00, 0xc0, 0xc5, 0xe5, /* 88: strb ip, [r5] */
- 0xfb, 0xff, 0xff, 0x1a, /* 8c: bne 80 <spi_batch_data_transfer+0x80> */
- 0x07, 0x00, 0x60, 0xe0, /* 90: rsb r0, r0, r7 */
- 0x00, 0x90, 0x0f, 0xe1, /* 94: mrs r9, CPSR */
- 0xc0, 0xc0, 0x89, 0xe3, /* 98: orr ip, r9, #192 */
- 0x0c, 0xf0, 0x21, 0xe1, /* 9c: msr CPSR_c, ip */
- 0x04, 0xc0, 0x9d, 0xe5, /* a0: ldr ip, [sp, #4] */
- 0x07, 0x00, 0x51, 0xe1, /* a4: cmp r1, r7 */
- 0x07, 0x10, 0xa0, 0x21, /* a8: movcs r1, r7 */
- 0x08, 0xb0, 0x9d, 0xe5, /* ac: ldr fp, [sp, #8] */
- 0x00, 0x40, 0x9c, 0xe5, /* b0: ldr r4, [ip] */
- 0x01, 0xc0, 0x88, 0xe0, /* b4: add ip, r8, r1 */
- 0x00, 0xc0, 0x8d, 0xe5, /* b8: str ip, [sp] */
- 0x08, 0xc0, 0xa0, 0xe1, /* bc: mov ip, r8 */
- 0x0b, 0x40, 0x84, 0xe1, /* c0: orr r4, r4, fp */
- 0x04, 0xb0, 0x9d, 0xe5, /* c4: ldr fp, [sp, #4] */
- 0x00, 0x40, 0x8b, 0xe5, /* c8: str r4, [fp] */
- 0x00, 0xb0, 0x9d, 0xe5, /* cc: ldr fp, [sp] */
- 0x0b, 0x00, 0x5c, 0xe1, /* d0: cmp ip, fp */
- 0x06, 0x00, 0x00, 0x0a, /* d4: beq f4 <spi_batch_data_transfer+0xf4> */
- 0x00, 0x40, 0x93, 0xe5, /* d8: ldr r4, [r3] */
- 0x7f, 0x00, 0x14, 0xe3, /* dc: tst r4, #127 */
- 0xfc, 0xff, 0xff, 0x0a, /* e0: beq d8 <spi_batch_data_transfer+0xd8> */
- 0x00, 0x40, 0xd6, 0xe5, /* e4: ldrb r4, [r6] */
- 0x01, 0x40, 0xcc, 0xe4, /* e8: strb r4, [ip], #1 */
- 0x0b, 0x00, 0x5c, 0xe1, /* ec: cmp ip, fp */
- 0xf8, 0xff, 0xff, 0x1a, /* f0: bne d8 <spi_batch_data_transfer+0xd8> */
- 0x07, 0x10, 0x61, 0xe0, /* f4: rsb r1, r1, r7 */
- 0x03, 0x00, 0x51, 0xe3, /* f8: cmp r1, #3 */
- 0x12, 0x00, 0x00, 0x9a, /* fc: bls 14c <spi_batch_data_transfer+0x14c> */
- 0x00, 0x40, 0x93, 0xe5, /* 100: ldr r4, [r3] */
- 0x7f, 0xb0, 0x04, 0xe2, /* 104: and fp, r4, #127 */
- 0x54, 0x48, 0xe6, 0xe7, /* 108: ubfx r4, r4, #16, #7 */
- 0x03, 0x00, 0x5b, 0xe3, /* 10c: cmp fp, #3 */
- 0x04, 0x10, 0x41, 0xc2, /* 110: subgt r1, r1, #4 */
- 0x00, 0xb0, 0x96, 0xc5, /* 114: ldrgt fp, [r6] */
- 0x04, 0xb0, 0x8c, 0xc4, /* 118: strgt fp, [ip], #4 */
- 0x03, 0x00, 0x50, 0xe3, /* 11c: cmp r0, #3 */
- 0x00, 0xb0, 0xa0, 0x93, /* 120: movls fp, #0 */
- 0x01, 0xb0, 0xa0, 0x83, /* 124: movhi fp, #1 */
- 0x3b, 0x00, 0x54, 0xe3, /* 128: cmp r4, #59 */
- 0x00, 0xb0, 0xa0, 0xc3, /* 12c: movgt fp, #0 */
- 0x00, 0x00, 0x5b, 0xe3, /* 130: cmp fp, #0 */
- 0xef, 0xff, 0xff, 0x0a, /* 134: beq f8 <spi_batch_data_transfer+0xf8> */
- 0x04, 0x40, 0x92, 0xe4, /* 138: ldr r4, [r2], #4 */
- 0x03, 0x00, 0x51, 0xe3, /* 13c: cmp r1, #3 */
- 0x04, 0x00, 0x40, 0xe2, /* 140: sub r0, r0, #4 */
- 0x00, 0x40, 0x85, 0xe5, /* 144: str r4, [r5] */
- 0xec, 0xff, 0xff, 0x8a, /* 148: bhi 100 <spi_batch_data_transfer+0x100> */
- 0x00, 0x00, 0x51, 0xe3, /* 14c: cmp r1, #0 */
- 0x10, 0x00, 0x00, 0x0a, /* 150: beq 198 <spi_batch_data_transfer+0x198> */
- 0x00, 0x40, 0x93, 0xe5, /* 154: ldr r4, [r3] */
- 0x7f, 0x00, 0x14, 0xe3, /* 158: tst r4, #127 */
- 0x54, 0x48, 0xe6, 0xe7, /* 15c: ubfx r4, r4, #16, #7 */
- 0x01, 0x10, 0x41, 0x12, /* 160: subne r1, r1, #1 */
- 0x00, 0xb0, 0xd6, 0x15, /* 164: ldrbne fp, [r6] */
- 0x01, 0xb0, 0xcc, 0x14, /* 168: strbne fp, [ip], #1 */
- 0x00, 0xb0, 0x90, 0xe2, /* 16c: adds fp, r0, #0 */
- 0x01, 0xb0, 0xa0, 0x13, /* 170: movne fp, #1 */
- 0x3b, 0x00, 0x54, 0xe3, /* 174: cmp r4, #59 */
- 0x00, 0xb0, 0xa0, 0xc3, /* 178: movgt fp, #0 */
- 0x00, 0x00, 0x5b, 0xe3, /* 17c: cmp fp, #0 */
- 0xf1, 0xff, 0xff, 0x0a, /* 180: beq 14c <spi_batch_data_transfer+0x14c> */
- 0x01, 0x40, 0xd2, 0xe4, /* 184: ldrb r4, [r2], #1 */
- 0x00, 0x00, 0x51, 0xe3, /* 188: cmp r1, #0 */
- 0x01, 0x00, 0x40, 0xe2, /* 18c: sub r0, r0, #1 */
- 0x00, 0x40, 0xc5, 0xe5, /* 190: strb r4, [r5] */
- 0xee, 0xff, 0xff, 0x1a, /* 194: bne 154 <spi_batch_data_transfer+0x154> */
- 0x09, 0xf0, 0x21, 0xe1, /* 198: msr CPSR_c, r9 */
- 0xff, 0xcf, 0x0f, 0xe3, /* 19c: movw ip, #65535 */
- 0x0c, 0x00, 0x5a, 0xe1, /* 1a0: cmp sl, ip */
- 0x07, 0x00, 0x88, 0x10, /* 1a4: addne r0, r8, r7 */
- 0x99, 0xff, 0xff, 0x1a, /* 1a8: bne 14 <spi_batch_data_transfer+0x14> */
- 0x11, 0x20, 0xdd, 0xe5, /* 1ac: ldrb r2, [sp, #17] */
- 0x01, 0x00, 0x12, 0xe3, /* 1b0: tst r2, #1 */
- 0x08, 0x00, 0x00, 0x1a, /* 1b4: bne 1dc <spi_batch_data_transfer+0x1dc> */
- 0x0c, 0xb0, 0x9d, 0xe5, /* 1b8: ldr fp, [sp, #12] */
- 0x02, 0x00, 0x8b, 0xe2, /* 1bc: add r0, fp, #2 */
- 0x00, 0xa0, 0xd0, 0xe5, /* 1c0: ldrb sl, [r0] */
- 0x01, 0x20, 0xd0, 0xe5, /* 1c4: ldrb r2, [r0, #1] */
- 0x0a, 0xa4, 0x92, 0xe1, /* 1c8: orrs sl, r2, sl, lsl #8 */
- 0x94, 0xff, 0xff, 0x1a, /* 1cc: bne 24 <spi_batch_data_transfer+0x24> */
- 0x18, 0xd0, 0x8d, 0xe2, /* 1d0: add sp, sp, #24 */
- 0xf0, 0x0f, 0xbd, 0xe8, /* 1d4: pop {r4, r5, r6, r7, r8, r9, sl, fp} */
- 0x1e, 0xff, 0x2f, 0xe1, /* 1d8: bx lr */
- 0x0c, 0x00, 0x9d, 0xe5, /* 1dc: ldr r0, [sp, #12] */
- 0x8b, 0xff, 0xff, 0xea, /* 1e0: b 14 <spi_batch_data_transfer+0x14> */
+ 0x08, 0xd0, 0x4d, 0xe2, /* 4: sub sp, sp, #8 */
+ 0xff, 0xbf, 0x0f, 0xe3, /* 8: movw fp, #65535 */
+ 0x00, 0x30, 0xa0, 0xe3, /* c: mov r3, #0 */
+ 0xb0, 0x30, 0xcd, 0xe1, /* 10: strh r3, [sp] */
+ 0x00, 0x70, 0xd0, 0xe5, /* 14: ldrb r7, [r0] */
+ 0x01, 0x30, 0xd0, 0xe5, /* 18: ldrb r3, [r0, #1] */
+ 0x07, 0x74, 0x93, 0xe1, /* 1c: orrs r7, r3, r7, lsl #8 */
+ 0x6c, 0x00, 0x00, 0x0a, /* 20: beq 1d8 <spi_batch_data_transfer+0x1d8> */
+ 0x0b, 0x00, 0x57, 0xe1, /* 24: cmp r7, fp */
+ 0x08, 0x60, 0x8d, 0x02, /* 28: addeq r6, sp, #8 */
+ 0x02, 0x60, 0x80, 0x12, /* 2c: addne r6, r0, #2 */
+ 0x05, 0x30, 0xa0, 0x03, /* 30: moveq r3, #5 */
+ 0x00, 0x90, 0xa0, 0x01, /* 34: moveq r9, r0 */
+ 0x08, 0x30, 0x66, 0x05, /* 38: strbeq r3, [r6, #-8]! */
+ 0x02, 0x50, 0xa0, 0x03, /* 3c: moveq r5, #2 */
+ 0x07, 0x50, 0xa0, 0x11, /* 40: movne r5, r7 */
+ 0x00, 0x80, 0x0f, 0xe1, /* 44: mrs r8, CPSR */
+ 0xc0, 0x30, 0x88, 0xe3, /* 48: orr r3, r8, #192 */
+ 0x03, 0xf0, 0x21, 0xe1, /* 4c: msr CPSR_c, r3 */
+ 0x08, 0x30, 0x91, 0xe5, /* 50: ldr r3, [r1, #8] */
+ 0x40, 0x30, 0x83, 0xe3, /* 54: orr r3, r3, #64 */
+ 0x08, 0x30, 0x81, 0xe5, /* 58: str r3, [r1, #8] */
+ 0x08, 0x30, 0x91, 0xe5, /* 5c: ldr r3, [r1, #8] */
+ 0x30, 0x30, 0xc3, 0xe3, /* 60: bic r3, r3, #48 */
+ 0x08, 0x30, 0x81, 0xe5, /* 64: str r3, [r1, #8] */
+ 0x08, 0x30, 0x91, 0xe5, /* 68: ldr r3, [r1, #8] */
+ 0x80, 0x30, 0xc3, 0xe3, /* 6c: bic r3, r3, #128 */
+ 0x08, 0x30, 0x81, 0xe5, /* 70: str r3, [r1, #8] */
+ 0x18, 0x30, 0x91, 0xe5, /* 74: ldr r3, [r1, #24] */
+ 0x02, 0x31, 0x83, 0xe3, /* 78: orr r3, r3, #-2147483648 */
+ 0x18, 0x30, 0x81, 0xe5, /* 7c: str r3, [r1, #24] */
+ 0x18, 0x30, 0x91, 0xe5, /* 80: ldr r3, [r1, #24] */
+ 0x00, 0x00, 0x53, 0xe3, /* 84: cmp r3, #0 */
+ 0xfc, 0xff, 0xff, 0xba, /* 88: blt 80 <spi_batch_data_transfer+0x80> */
+ 0x18, 0x30, 0x91, 0xe5, /* 8c: ldr r3, [r1, #24] */
+ 0x02, 0x39, 0x83, 0xe3, /* 90: orr r3, r3, #32768 */
+ 0x18, 0x30, 0x81, 0xe5, /* 94: str r3, [r1, #24] */
+ 0x18, 0x30, 0x91, 0xe5, /* 98: ldr r3, [r1, #24] */
+ 0x02, 0x09, 0x13, 0xe3, /* 9c: tst r3, #32768 */
+ 0xfc, 0xff, 0xff, 0x1a, /* a0: bne 98 <spi_batch_data_transfer+0x98> */
+ 0x30, 0xc0, 0x91, 0xe5, /* a4: ldr ip, [r1, #48] */
+ 0x05, 0x40, 0xa0, 0xe1, /* a8: mov r4, r5 */
+ 0x05, 0x00, 0xa0, 0xe1, /* ac: mov r0, r5 */
+ 0x06, 0x20, 0xa0, 0xe1, /* b0: mov r2, r6 */
+ 0xff, 0xc4, 0x0c, 0xe2, /* b4: and ip, ip, #-16777216 */
+ 0x06, 0x30, 0xa0, 0xe1, /* b8: mov r3, r6 */
+ 0x0c, 0xc0, 0x85, 0xe1, /* bc: orr ip, r5, ip */
+ 0x30, 0xc0, 0x81, 0xe5, /* c0: str ip, [r1, #48] */
+ 0x34, 0xc0, 0x91, 0xe5, /* c4: ldr ip, [r1, #52] */
+ 0xff, 0xc4, 0x0c, 0xe2, /* c8: and ip, ip, #-16777216 */
+ 0x0c, 0xc0, 0x85, 0xe1, /* cc: orr ip, r5, ip */
+ 0x34, 0xc0, 0x81, 0xe5, /* d0: str ip, [r1, #52] */
+ 0x38, 0xc0, 0x91, 0xe5, /* d4: ldr ip, [r1, #56] */
+ 0xff, 0xc4, 0x0c, 0xe2, /* d8: and ip, ip, #-16777216 */
+ 0x0c, 0xc0, 0x85, 0xe1, /* dc: orr ip, r5, ip */
+ 0x38, 0xc0, 0x81, 0xe5, /* e0: str ip, [r1, #56] */
+ 0x08, 0xc0, 0x91, 0xe5, /* e4: ldr ip, [r1, #8] */
+ 0x02, 0xc1, 0x8c, 0xe3, /* e8: orr ip, ip, #-2147483648 */
+ 0x08, 0xc0, 0x81, 0xe5, /* ec: str ip, [r1, #8] */
+ 0x00, 0xc0, 0x94, 0xe1, /* f0: orrs ip, r4, r0 */
+ 0x20, 0x00, 0x00, 0x0a, /* f4: beq 17c <spi_batch_data_transfer+0x17c> */
+ 0x1c, 0xc0, 0x91, 0xe5, /* f8: ldr ip, [r1, #28] */
+ 0x5c, 0xc8, 0xe7, 0xe7, /* fc: ubfx ip, ip, #16, #8 */
+ 0x3f, 0x00, 0x5c, 0xe3, /* 100: cmp ip, #63 */
+ 0x17, 0x00, 0x00, 0x8a, /* 104: bhi 168 <spi_batch_data_transfer+0x168> */
+ 0x00, 0x00, 0x50, 0xe3, /* 108: cmp r0, #0 */
+ 0x15, 0x00, 0x00, 0x0a, /* 10c: beq 168 <spi_batch_data_transfer+0x168> */
+ 0xff, 0xa0, 0xa0, 0xe3, /* 110: mov sl, #255 */
+ 0x01, 0x00, 0x00, 0xea, /* 114: b 120 <spi_batch_data_transfer+0x120> */
+ 0x00, 0x00, 0x50, 0xe3, /* 118: cmp r0, #0 */
+ 0x11, 0x00, 0x00, 0x0a, /* 11c: beq 168 <spi_batch_data_transfer+0x168> */
+ 0x00, 0x00, 0x53, 0xe3, /* 120: cmp r3, #0 */
+ 0x01, 0x00, 0x40, 0xe2, /* 124: sub r0, r0, #1 */
+ 0x00, 0xa0, 0xd3, 0x15, /* 128: ldrbne sl, [r3] */
+ 0x01, 0x30, 0x83, 0x12, /* 12c: addne r3, r3, #1 */
+ 0x00, 0xa2, 0xc1, 0xe5, /* 130: strb sl, [r1, #512] */
+ 0x1c, 0xc0, 0x91, 0xe5, /* 134: ldr ip, [r1, #28] */
+ 0x5c, 0xc8, 0xe7, 0xe7, /* 138: ubfx ip, ip, #16, #8 */
+ 0x3f, 0x00, 0x5c, 0xe3, /* 13c: cmp ip, #63 */
+ 0xf4, 0xff, 0xff, 0x9a, /* 140: bls 118 <spi_batch_data_transfer+0x118> */
+ 0x1c, 0xc0, 0x91, 0xe5, /* 144: ldr ip, [r1, #28] */
+ 0xff, 0x00, 0x1c, 0xe3, /* 148: tst ip, #255 */
+ 0xe7, 0xff, 0xff, 0x0a, /* 14c: beq f0 <spi_batch_data_transfer+0xf0> */
+ 0x00, 0xc3, 0xd1, 0xe5, /* 150: ldrb ip, [r1, #768] */
+ 0x00, 0x00, 0x52, 0xe3, /* 154: cmp r2, #0 */
+ 0x01, 0x40, 0x44, 0xe2, /* 158: sub r4, r4, #1 */
+ 0x7c, 0xc0, 0xef, 0xe6, /* 15c: uxtb ip, ip */
+ 0x00, 0xc0, 0xc2, 0x15, /* 160: strbne ip, [r2] */
+ 0x01, 0x20, 0x82, 0x12, /* 164: addne r2, r2, #1 */
+ 0x1c, 0xc0, 0x91, 0xe5, /* 168: ldr ip, [r1, #28] */
+ 0xff, 0x00, 0x1c, 0xe3, /* 16c: tst ip, #255 */
+ 0xf6, 0xff, 0xff, 0x1a, /* 170: bne 150 <spi_batch_data_transfer+0x150> */
+ 0x00, 0xc0, 0x94, 0xe1, /* 174: orrs ip, r4, r0 */
+ 0xde, 0xff, 0xff, 0x1a, /* 178: bne f8 <spi_batch_data_transfer+0xf8> */
+ 0x14, 0x30, 0x91, 0xe5, /* 17c: ldr r3, [r1, #20] */
+ 0x01, 0x0a, 0x13, 0xe3, /* 180: tst r3, #4096 */
+ 0xfc, 0xff, 0xff, 0x0a, /* 184: beq 17c <spi_batch_data_transfer+0x17c> */
+ 0x14, 0x30, 0x91, 0xe5, /* 188: ldr r3, [r1, #20] */
+ 0x01, 0x3a, 0x83, 0xe3, /* 18c: orr r3, r3, #4096 */
+ 0x14, 0x30, 0x81, 0xe5, /* 190: str r3, [r1, #20] */
+ 0x14, 0x30, 0x91, 0xe5, /* 194: ldr r3, [r1, #20] */
+ 0x08, 0x30, 0x91, 0xe5, /* 198: ldr r3, [r1, #8] */
+ 0x80, 0x30, 0x83, 0xe3, /* 19c: orr r3, r3, #128 */
+ 0x08, 0x30, 0x81, 0xe5, /* 1a0: str r3, [r1, #8] */
+ 0x08, 0xf0, 0x21, 0xe1, /* 1a4: msr CPSR_c, r8 */
+ 0x0b, 0x00, 0x57, 0xe1, /* 1a8: cmp r7, fp */
+ 0x05, 0x00, 0x86, 0x10, /* 1ac: addne r0, r6, r5 */
+ 0x97, 0xff, 0xff, 0x1a, /* 1b0: bne 14 <spi_batch_data_transfer+0x14> */
+ 0x01, 0x30, 0xdd, 0xe5, /* 1b4: ldrb r3, [sp, #1] */
+ 0x01, 0x00, 0x13, 0xe3, /* 1b8: tst r3, #1 */
+ 0x02, 0x00, 0x89, 0x02, /* 1bc: addeq r0, r9, #2 */
+ 0x93, 0xff, 0xff, 0x0a, /* 1c0: beq 14 <spi_batch_data_transfer+0x14> */
+ 0x09, 0x00, 0xa0, 0xe1, /* 1c4: mov r0, r9 */
+ 0x00, 0x70, 0xd0, 0xe5, /* 1c8: ldrb r7, [r0] */
+ 0x01, 0x30, 0xd0, 0xe5, /* 1cc: ldrb r3, [r0, #1] */
+ 0x07, 0x74, 0x93, 0xe1, /* 1d0: orrs r7, r3, r7, lsl #8 */
+ 0x92, 0xff, 0xff, 0x1a, /* 1d4: bne 24 <spi_batch_data_transfer+0x24> */
+ 0x08, 0xd0, 0x8d, 0xe2, /* 1d8: add sp, sp, #8 */
+ 0xf0, 0x0f, 0xbd, 0xe8, /* 1dc: pop {r4, r5, r6, r7, r8, r9, sl, fp} */
+ 0x1e, 0xff, 0x2f, 0xe1, /* 1e0: bx lr */
};
uint32_t args[] = {
buf,
spi_ctl_reg,
- spi_ctl_xch_bitmask,
- spi_fifo_reg,
- spi_tx_reg,
- spi_rx_reg,
- spi_bc_reg,
- spi_tc_reg,
- spi_bcc_reg
+ unused1,
+ unused2,
+ unused3,
+ unused4,
+ unused5,
+ unused6,
+ unused7
};
- aw_fel_remotefunc_prepare(dev, 56, arm_code, sizeof(arm_code), 9, args);
+ aw_fel_remotefunc_prepare(dev, 40, arm_code, sizeof(arm_code), 9, args);
}
diff --git a/fel-spiflash.c b/fel-spiflash.c
index 114affb..5bf362d 100644
--- a/fel-spiflash.c
+++ b/fel-spiflash.c
@@ -81,15 +81,15 @@ spi_flash_info_t default_spi_flash_info = {
#define SUN4I_SPI0_BC (0x01C05000 + 0x20)
#define SUN4I_SPI0_TC (0x01C05000 + 0x24)
-#define SUN6I_SPI0_CCTL (0x01C68000 + 0x24)
-#define SUN6I_SPI0_GCR (0x01C68000 + 0x04)
-#define SUN6I_SPI0_TCR (0x01C68000 + 0x08)
-#define SUN6I_SPI0_FIFO_STA (0x01C68000 + 0x1C)
-#define SUN6I_SPI0_MBC (0x01C68000 + 0x30)
-#define SUN6I_SPI0_MTC (0x01C68000 + 0x34)
-#define SUN6I_SPI0_BCC (0x01C68000 + 0x38)
-#define SUN6I_SPI0_TXD (0x01C68000 + 0x200)
-#define SUN6I_SPI0_RXD (0x01C68000 + 0x300)
+#define SUN6I_SPI0_CCTL (0x05010000 + 0x24)
+#define SUN6I_SPI0_GCR (0x05010000 + 0x04)
+#define SUN6I_SPI0_TCR (0x05010000 + 0x08)
+#define SUN6I_SPI0_FIFO_STA (0x05010000 + 0x1C)
+#define SUN6I_SPI0_MBC (0x05010000 + 0x30)
+#define SUN6I_SPI0_MTC (0x05010000 + 0x34)
+#define SUN6I_SPI0_BCC (0x05010000 + 0x38)
+#define SUN6I_SPI0_TXD (0x05010000 + 0x200)
+#define SUN6I_SPI0_RXD (0x05010000 + 0x300)
#define CCM_SPI0_CLK_DIV_BY_2 (0x1000)
#define CCM_SPI0_CLK_DIV_BY_4 (0x1001)
@@ -144,21 +144,70 @@ static bool spi0_init(feldev_handle *dev)
gpio_set_cfgpin(dev, PC, 2, SUN50I_GPC_SPI0);
gpio_set_cfgpin(dev, PC, 3, SUN50I_GPC_SPI0);
break;
+ case 0x1817:
+ {
+ uint32_t spi0ctl[9] = { 0x77444444, 0x00007777, 0x00000000, 0x00000000,\
+ 0x00000000, 0x00555555, 0x00000000, 0x00001054,\
+ 0x00000000 };
+ uint32_t spi0pin_base = 0x0300b048;
+ int i = 0;
+ for(i = 0; i < 9; i ++)
+ {
+ writel(spi0ctl[i], spi0pin_base + 4*i);
+ }
+ }
+ break;
+ case 0x1821:
+ {
+ uint32_t spi0ctl[9] = { 0x47744474, 0x17777777, 0x00000001, 0x00000000,\
+ 0x00018000, 0x55555555, 0x00000001, 0x00005140,\
+ 0x00000000 };
+ uint32_t spi0pin_base = 0x0300b048;
+ int i = 0;
+ for(i = 0; i < 9; i ++)
+ {
+ writel(spi0ctl[i], spi0pin_base + 4*i);
+ }
+ }
+ break;
default: /* Unknown/Unsupported SoC */
return false;
}
- reg_val = readl(CCM_AHB_GATING0);
- reg_val |= CCM_AHB_GATE_SPI0;
- writel(reg_val, CCM_AHB_GATING0);
-
- /* 24MHz from OSC24M */
- writel((1 << 31), CCM_SPI0_CLK);
- /* divide by 4 */
- writel(CCM_SPI0_CLK_DIV_BY_4, spi_is_sun6i(dev) ? SUN6I_SPI0_CCTL :
- SUN4I_SPI0_CCTL);
-
- if (spi_is_sun6i(dev)) {
+ //printf("%s line %d.\n", __func__, __LINE__);
+ uint32_t ccmu_base = 0x03001000;
+ //uint32_t cpu_ccm = ccmu_base + 0x400;
+ //uint32_t ccmu_axi = ccmu_base + 0x500;
+ //uint32_t CCMU_PSI_AHB1_AHB2_CFG_REG = ccmu_base + 0x510;
+ //uint32_t CCMU_PLL_PERI0_CTRL_REG = ccmu_base + 0x20;
+ //uint32_t CCMU_AHB3_CFG_GREG = ccmu_base + 0x51c;
+ //uint32_t CCMU_APB1_CFG_GREG = ccmu_base + 0x520;
+ uint32_t ccmu_spi0_clk_reg = ccmu_base + 0x940;
+ uint32_t ccmu_spi0_gate_rst = ccmu_base + 0x96c;
+
+ writel(0x8100000b, ccmu_spi0_clk_reg);
+ //writel(0x8000000b, ccmu_spi0_clk_reg);
+ //writel(0x8200000b, ccmu_spi0_clk_reg);
+ //writel(0x8300000b, ccmu_spi0_clk_reg);
+ //writel(0x8400000b, ccmu_spi0_clk_reg);
+ uint32_t rst_val = readl(ccmu_spi0_gate_rst);
+ rst_val &= ~(1 << 16);
+ writel(rst_val, ccmu_spi0_gate_rst);
+
+ rst_val = readl(ccmu_spi0_gate_rst);
+ rst_val |= (1 << 16);
+ writel(rst_val, ccmu_spi0_gate_rst);
+
+ rst_val = readl(ccmu_spi0_gate_rst);
+ rst_val |= (1 << 0);
+ writel(rst_val, ccmu_spi0_gate_rst);
+
+ //uint32_t clk_reg = readl(ccmu_spi0_clk_reg);
+ //rst_val = readl(ccmu_spi0_gate_rst);
+ //printf("clk_ret = 0x%08x.\n", clk_reg);
+ //printf("rst_val = 0x%08x.\n", rst_val);
+
+ if (0) {
/* Deassert SPI0 reset */
reg_val = readl(SUN6I_BUS_SOFT_RST_REG0);
reg_val |= SUN6I_SPI0_RST;
@@ -169,7 +218,70 @@ static bool spi0_init(feldev_handle *dev)
writel(reg_val, SUN6I_SPI0_GCR);
/* Wait for completion */
while (readl(SUN6I_SPI0_GCR) & (1 << 31)) {}
- } else {
+ }
+ else if((dev->soc_info->soc_id == 0x1821) || (dev->soc_info->soc_id == 0x1817))
+ {
+ uint32_t spi0_ctrl = 0x05010000;
+ uint32_t spi0_ctrl_gcr = spi0_ctrl + 0x4;
+ uint32_t spi0_ctrl_tcr = spi0_ctrl + 0x8;
+ uint32_t spi0_ctrl_clk = spi0_ctrl + 0x24;
+ uint32_t spi0_ctrl_clk_ = spi0_ctrl + 0x20;
+ uint32_t spi0_ctrl_fifo = spi0_ctrl + 0x18;
+
+ //soft reset.
+ uint32_t val = readl(spi0_ctrl_gcr);
+ val |= (1 << 31);
+ writel(val, spi0_ctrl_gcr);
+
+ //enable the bus.
+ val = readl(spi0_ctrl_gcr);
+ val |= (1 << 0);
+ writel(val, spi0_ctrl_gcr);
+
+ //transer control.
+ val = readl(spi0_ctrl_tcr);
+ val &= ~(0x3 << 4);
+ val |= 0 << 4;
+ writel(val, spi0_ctrl_tcr);
+
+ //set master.
+ val = readl(spi0_ctrl_gcr);
+ val |= (1 << 1);
+ writel(val, spi0_ctrl_gcr);
+
+ //set clk ctl
+ writel(0x2, spi0_ctrl_clk);
+ writel(0x0, spi0_ctrl_clk_);
+
+ //transer control.
+ val = readl(spi0_ctrl_tcr);
+ val = (0x1 << 6)|(0x1 << 7)|(0x1 << 2);
+ writel(val, spi0_ctrl_tcr);
+
+ // ss level.
+ val = readl(spi0_ctrl_tcr);
+ val |= (0x1 << 7);
+ writel(val, spi0_ctrl_tcr);
+
+ //enable the tp.
+ val = readl(spi0_ctrl_gcr);
+ val |= (0x1 << 7);
+ writel(val, spi0_ctrl_gcr);
+
+ //transer control owner.
+ /*val = readl(spi0_ctrl_tcr);*/
+ /*val &= ~(0x1 << 6);*/
+ /*writel(val, spi0_ctrl_tcr);*/
+
+ //fifo reset.
+ val = readl(spi0_ctrl_fifo);
+ val |= (0x1 << 15)|(0x1 << 31);
+ val &= ~((0xFF << 0)|(0xFF << 16));
+ val |= (0x40<<16) | 0x01;
+ writel(val, spi0_ctrl_fifo);
+ }
+ else
+ {
reg_val = readl(SUN4I_SPI0_CTL);
reg_val |= SUN4I_CTL_MASTER;
reg_val |= SUN4I_CTL_ENABLE | SUN4I_CTL_TF_RST | SUN4I_CTL_RF_RST;
@@ -203,15 +315,16 @@ static void prepare_spi_batch_data_transfer(feldev_handle *dev, uint32_t buf)
if (spi_is_sun6i(dev)) {
aw_fel_remotefunc_prepare_spi_batch_data_transfer(dev,
buf,
- SUN6I_SPI0_TCR,
- SUN6I_TCR_XCH,
- SUN6I_SPI0_FIFO_STA,
- SUN6I_SPI0_TXD,
- SUN6I_SPI0_RXD,
- SUN6I_SPI0_MBC,
- SUN6I_SPI0_MTC,
- SUN6I_SPI0_BCC);
+ 0x05010000,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0);
} else {
+ while(1);
aw_fel_remotefunc_prepare_spi_batch_data_transfer(dev,
buf,
SUN4I_SPI0_CTL,
@@ -416,7 +529,6 @@ void aw_fel_spiflash_info(feldev_handle *dev)
aw_fel_read(dev, dev->soc_info->spl_addr, buf, sizeof(buf));
restore_sram(dev, backup);
-
/* Assume that the MISO pin is either pulled up or down */
if (buf[5] == 0x00 || buf[5] == 0xFF) {
printf("No SPI flash detected.\n");
@@ -427,6 +539,9 @@ void aw_fel_spiflash_info(feldev_handle *dev)
case 0xEF:
manufacturer = "Winbond";
break;
+ case 0xC2:
+ manufacturer = "Macronix";
+ break;
default:
manufacturer = "Unknown";
break;
diff --git a/fel_spi.c b/fel_spi.c
new file mode 100644
index 0000000..d2441c2
--- /dev/null
+++ b/fel_spi.c
@@ -0,0 +1,81 @@
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include "aw_spi.h"
+/*-----------------------------------------------------------------------*/
+void pinctrl_init(void)
+{
+ gpio_direction_output(wp_port, wp_pin, 1);
+ gpio_direction_output(hld_port, hld_pin, 1);
+ gpio_set_func(clk_port, clk_pin, ck_io_func);
+ gpio_set_func(mosi_port, mosi_pin, mosi_io_func);
+ gpio_set_func(miso_port, miso_pin, miso_io_func);
+ gpio_set_func(cs_port, cs_pin, cs_io_func);
+}
+
+void clock_init(void)
+{
+ uint32_t ccmu_base = 0x03001000;
+ //uint32_t cpu_ccm = ccmu_base + 0x400;
+ //uint32_t ccmu_axi = ccmu_base + 0x500;
+ //uint32_t CCMU_PSI_AHB1_AHB2_CFG_REG = ccmu_base + 0x510;
+ //uint32_t CCMU_PLL_PERI0_CTRL_REG = ccmu_base + 0x20;
+ //uint32_t CCMU_AHB3_CFG_GREG = ccmu_base + 0x51c;
+ //uint32_t CCMU_APB1_CFG_GREG = ccmu_base + 0x520;
+ uint32_t ccmu_spi0_clk_reg = ccmu_base + 0x940;
+ uint32_t ccmu_spi0_gate_rst = ccmu_base + 0x96c;
+
+ writel(0x8100000b, ccmu_spi0_clk_reg);
+ //writel(0x8000000b, ccmu_spi0_clk_reg);
+ //writel(0x8200000b, ccmu_spi0_clk_reg);
+ //writel(0x8300000b, ccmu_spi0_clk_reg);
+ //writel(0x8400000b, ccmu_spi0_clk_reg);
+ uint32_t rst_val = readl(ccmu_spi0_gate_rst);
+ rst_val &= ~(1 << 16);
+ writel(rst_val, ccmu_spi0_gate_rst);
+
+ rst_val = readl(ccmu_spi0_gate_rst);
+ rst_val |= (1 << 16);
+ writel(rst_val, ccmu_spi0_gate_rst);
+
+ rst_val = readl(ccmu_spi0_gate_rst);
+ rst_val |= (1 << 0);
+ writel(rst_val, ccmu_spi0_gate_rst);
+
+ uint32_t clk_reg = readl(ccmu_spi0_clk_reg);
+ rst_val = readl(ccmu_spi0_gate_rst);
+}
+
+void spi_hw_init(void)
+{
+ //uint32_t spi0_ctrl = 0x05010000;
+ //uint32_t spi0_ctrl_clk = spi0_ctrl + 0x24;
+ //int data_width = 8;
+
+ SPI_T *spi_instance = SPI_CTR_ADDRESS;
+
+ SPI_Disable(spi_instance);
+ SPI_Reset(spi_instance);
+ SPI_ResetRxFifo(spi_instance);
+ SPI_ResetTxFifo(spi_instance);
+
+ SPI_SetDuplex(spi_instance, SPI_TCTRL_DHB_FULL_DUPLEX);
+ SPI_SetMode(spi_instance, SPI_CTRL_MODE_MASTER);
+
+ SPI_SetFirstTransmitBit(spi_instance, SPI_TCTRL_FBS_MSB);
+ SPI_SetSclkMode(spi_instance, SPI_SCLK_Mode0);
+
+ //TODO: set clk div.
+ //writel(0x0002, spi0_ctrl_clk);
+ spi_instance->CCR = 0x02;
+ SPI_ManualChipSelect(spi_instance, cs_sel);
+ SPI_SetDataSize(spi_instance, 0, 0);
+ SPI_Enable(spi_instance);
+}
+
+void spi_configure(void)
+{
+ pinctrl_init();
+ clock_init();
+ spi_hw_init();
+}
diff --git a/soc_info.c b/soc_info.c
index 7728422..dd2493e 100644
--- a/soc_info.c
+++ b/soc_info.c
@@ -34,6 +34,7 @@
* important too (overwriting them kills FEL). On A10/A13/A20 we can use
* the SRAM sections A3/A4 (0x8000-0xBFFF) for this purpose.
*/
+
sram_swap_buffers a10_a13_a20_sram_swap_buffers[] = {
/* 0x1C00-0x1FFF (IRQ stack) */
{ .buf1 = 0x1C00, .buf2 = 0xA400, .size = 0x0400 },
@@ -44,6 +45,16 @@ sram_swap_buffers a10_a13_a20_sram_swap_buffers[] = {
{ .size = 0 } /* End of the table */
};
+sram_swap_buffers v459_r328_sram_swap_buffers[] = {
+ /* 0x1C00-0x1FFF (IRQ stack) */
+ { .buf1 = 0x32C00, .buf2 = 0x3A400, .size = 0x0400 },
+ /* 0x5C00-0x6FFF (Stack) */
+ { .buf1 = 0x35C00, .buf2 = 0x3A800, .size = 0x1400 },
+ /* 0x7C00-0x7FFF (Something important) */
+ { .buf1 = 0x37C00, .buf2 = 0x3BC00, .size = 0x0400 },
+ { .size = 0 } /* End of the table */
+};
+
/*
* A31 is very similar to A10/A13/A20, except that it has no SRAM at 0x8000.
* So we use the SRAM section B at 0x20000-0x2FFFF instead. In the FEL mode,
@@ -94,6 +105,7 @@ sram_swap_buffers a80_sram_swap_buffers[] = {
{ .size = 0 } /* End of the table */
};
+extern sram_swap_buffers generic_sram_swap_buffers[];
soc_info_t soc_info_table[] = {
{
.soc_id = 0x1623, /* Allwinner A10 */
@@ -207,6 +219,20 @@ soc_info_t soc_info_table[] = {
.swap_buffers = a10_a13_a20_sram_swap_buffers,
.sid_base = 0x01C1B000,
.sid_offset = 0x200,
+ },{
+ .soc_id = 0x1821, /* Allwinner R328 */
+ .name = "R328",
+ .spl_addr = 0x20000,
+ .scratch_addr = 0x21000,
+ .thunk_addr = 0x2a200, .thunk_size = 0x200,
+ .swap_buffers = v459_r328_sram_swap_buffers,
+ },{
+ .soc_id = 0x1817, /* Allwinner V459 */
+ .name = "V459",
+ .spl_addr = 0x20000,
+ .scratch_addr = 0x21000,
+ .thunk_addr = 0x2a200, .thunk_size = 0x200,
+ .swap_buffers = v459_r328_sram_swap_buffers,
},{
.swap_buffers = NULL /* End of the table */
}
diff --git a/xfer.c b/xfer.c
new file mode 100644
index 0000000..cce8fbe
--- /dev/null
+++ b/xfer.c
@@ -0,0 +1,139 @@
+/*
+ * ===========================================================================================
+ *
+ * Filename: xfer.c
+ *
+ * Description: mini driver for nor flash on R328.
+ *
+ * Version: Melis3.0
+ * Create: 2019-11-08 14:00:23
+ * Revision: none
+ * Compiler: GCC:version 7.2.1 20170904 (release),ARM/embedded-7-branch revision 255204
+ *
+ * Author: caozilong@allwinnertech.com
+ * Organization: BU1-PSW
+ * Last Modified: 2019-11-08 14:07:53
+ *
+ * ===========================================================================================
+ */
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include "aw_spi.h"
+
+static void inline __attribute((always_inline)) xfer(void *buf, uint32_t bufsize, uint32_t spi_reg_base,
+ uint32_t __unused1,
+ uint32_t __unused2,
+ uint32_t __unused3,
+ uint32_t __unused4,
+ uint32_t __unused5,
+ uint32_t __unused6,
+ uint32_t __unused7)
+{
+ const uint8_t *send_ptr = buf;
+ uint8_t *recv_ptr = buf;
+ uint32_t tx_size = bufsize;
+ uint32_t rx_size = bufsize;
+ uint32_t cpsr;
+
+ asm volatile("mrs %0, cpsr" : "=r" (cpsr));
+ asm volatile("msr cpsr_c, %0" :: "r" (cpsr | 0xC0));
+
+ SPI_T *spi_instance = (SPI_T*)spi_reg_base;
+
+ SPI_ManualChipSelect(spi_instance, cs_sel);
+ SPI_SetCsLevel(spi_instance, 0);
+
+ SPI_ResetTxFifo(spi_instance);
+ SPI_ResetRxFifo(spi_instance);
+ SPI_SetDataSize(spi_instance, tx_size, 0);
+
+ SPI_StartTransmit(spi_instance);
+
+ while (tx_size > 0 || rx_size > 0)
+ {
+ uint8_t tx_data = 0xFF;
+ uint8_t rx_data = 0xFF;
+
+ while ((SPI_GetTxFifoCounter(spi_instance) < SPI_FIFO_SIZE) && (tx_size > 0))
+ {
+ if (send_ptr != NULL)
+ {
+ tx_data = *send_ptr++;
+ }
+ SPI_Write(spi_instance, &tx_data);
+ tx_size--;
+ }
+
+ while (SPI_GetRxFifoCounter(spi_instance) > 0)
+ {
+ rx_size--;
+ SPI_Read(spi_instance, &rx_data);
+
+ if (recv_ptr != NULL)
+ {
+ *recv_ptr++ = rx_data;
+ }
+ }
+ }
+
+ if ((tx_size != 0) || (rx_size != 0)) while(1);
+
+ while (SPI_IntState(spi_instance, SPI_INT_TRANSFER_COMPLETE) == 0);
+ SPI_ClearInt(spi_instance, SPI_INT_TRANSFER_COMPLETE);
+ SPI_SetCsLevel(spi_instance, 1);
+ /* Restore CPSR */
+ asm volatile("msr cpsr_c, %0" :: "r" (cpsr));
+}
+
+void spi_batch_data_transfer(uint8_t *buf,uint32_t spi_ctl_reg, uint32_t unused1,
+ uint32_t unused2,
+ uint32_t unused3,
+ uint32_t unused4,
+ uint32_t unused5,
+ uint32_t unused6,
+ uint32_t unused7)
+{
+ uint8_t wait_for_completion_cmd[2] = {0};
+ uint8_t *backup_buf;
+ uint32_t bufsize;
+
+ while (1) {
+ uint32_t code = (buf[0] << 8) | buf[1];
+
+ /* End of data */
+ if (code == 0)
+ return;
+
+ if (code == 0xFFFF) {
+ /* Wait for completion, part 1 */
+ backup_buf = buf;
+ buf = wait_for_completion_cmd;
+ wait_for_completion_cmd[0] = 0x05;
+ bufsize = 2;
+ } else {
+ /* Normal buffer */
+ buf += 2;
+ bufsize = code;
+ }
+
+ xfer(buf, bufsize, spi_ctl_reg, unused1,
+ unused2, unused3, unused4,
+ unused5, unused6, unused7);
+ if (code == 0xFFFF) {
+ /* Wait for completion, part 2 */
+ if (wait_for_completion_cmd[1] & 1) {
+ buf = backup_buf;
+ /* Still busy */
+ continue;
+ }
+ else {
+ /* Advance to the next code */
+ buf = backup_buf + 2;
+ }
+ }
+ else {
+ buf += bufsize;
+ }
+ }
+}
结束
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)