页次: 1
F1C100S裸機:SPI1從模式無法正常工作。
嗨,大家好,
我對F1C100S的SPI1有問題。
當我將SPI1與SLAVE模式一起使用時。
當我向SPI1_TXD_REG寫1個字(4字節)並從寄存器SPI1_FSR_REG中讀回TX_FIFO中的數字字節時。
SPI1_FSR_REG的返回值:0x20000(僅2個字節).// TX_FIFO中期望有4個字節
但是,當我切換到MASTER模式時,SPI1_FSR_REG的返回值是正確的:0x40000(4個字節)。
您能告訴我程序中的錯誤嗎?
非常感謝你。
main.c
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#define CCU_BASE (0x01C20000)
#define PIO_BASE (0x01C20800)
#define SPI1_BASE (0x01C06000)
#define DMA_BASE (0x01C02000)
#define TIMER_BASE (0x01C20C00)
/* PIO: PA(0), PB(1), PC(2), PD(3), PE(4), PF(5) */
#define Pn_CFG0(n) (*(volatile uint32_t *)(PIO_BASE + n*0x24 + 0x00)) // Port n Configure Register 0 (n=0~5)
#define Pn_CFG1(n) (*(volatile uint32_t *)(PIO_BASE + n*0x24 + 0x04)) // Port n Configure Register 1 (n=0~5)
#define Pn_CFG2(n) (*(volatile uint32_t *)(PIO_BASE + n*0x24 + 0x08)) // Port n Configure Register 2 (n=0~5)
#define Pn_CFG3(n) (*(volatile uint32_t *)(PIO_BASE + n*0x24 + 0x0C)) // Port n Configure Register 3 (n=0~5)
#define Pn_DATA(n) (*(volatile uint32_t *)(PIO_BASE + n*0x24 + 0x10)) // Port n Data Register (n=0~5)
#define Pn_DRV0(n) (*(volatile uint32_t *)(PIO_BASE + n*0x24 + 0x14)) // Port n Multi-Driving Register 0 (n=0~5)
#define Pn_DRV1(n) (*(volatile uint32_t *)(PIO_BASE + n*0x24 + 0x18)) // Port n Multi-Driving Register 1 (n=0~5)
#define Pn_PUL0(n) (*(volatile uint32_t *)(PIO_BASE + n*0x24 + 0x1C)) // Port n Pull Register 0 (n=0~5)
#define Pn_PUL1(n) (*(volatile uint32_t *)(PIO_BASE + n*0x24 + 0x20)) // Port n Pull Register 1
#define Pn_INT_CFG0(n) (*(volatile uint32_t *)(PIO_BASE + 0x200 + n*0x20 + 0x0)) // PIO Interrupt Configure Register 0 (n=0~2) PD(0), PE(1), PF(2)
#define Pn_INT_CFG1(n) (*(volatile uint32_t *)(PIO_BASE + 0x200 + n*0x20 + 0x4)) // PIO Interrupt Configure Register 1 (n=0~2) PD(0), PE(1), PF(2)
#define Pn_INT_CFG2(n) (*(volatile uint32_t *)(PIO_BASE + 0x200 + n*0x20 + 0x8)) // PIO Interrupt Configure Register 2 (n=0~2) PD(0), PE(1), PF(2)
#define Pn_INT_CFG3(n) (*(volatile uint32_t *)(PIO_BASE + 0x200 + n*0x20 + 0xC)) // PIO Interrupt Configure Register 3 (n=0~2) PD(0), PE(1), PF(2)
#define Pn_INT_CTRL(n) (*(volatile uint32_t *)(PIO_BASE + 0x200 + n*0x20 + 0x10)) // PIO Interrupt Control Register (n=0~2) PD(0), PE(1), PF(2)
#define Pn_INT_STA(n) (*(volatile uint32_t *)(PIO_BASE + 0x200 + n*0x20 + 0x14)) // PIO Interrupt Status Register (n=0~2) PD(0), PE(1), PF(2)
#define Pn_INT_DEB(n) (*(volatile uint32_t *)(PIO_BASE + 0x200 + n*0x20 + 0x18)) // PIO Interrupt Debounce Register (n=0~2) PD(0), PE(1), PF(2)
/* CCU */
#define BUS_CLK_GATING_REG0 (*(volatile uint32_t *)(CCU_BASE + 0x0060))
#define BUS_CLK_GATING_REG1 (*(volatile uint32_t *)(CCU_BASE + 0x0064))
#define BUS_CLK_GATING_REG2 (*(volatile uint32_t *)(CCU_BASE + 0x0068))
#define BUS_SOFT_RST_REG0 (*(volatile uint32_t *)(CCU_BASE + 0x02C0))
#define BUS_SOFT_RST_REG1 (*(volatile uint32_t *)(CCU_BASE + 0x02C4))
#define BUS_SOFT_RST_REG2 (*(volatile uint32_t *)(CCU_BASE + 0x02D0))
/* SPI1 */
#define SPI1_GCR_REG (*(volatile uint32_t *)(SPI1_BASE + 0x0004))
#define SPI1_TCR_REG (*(volatile uint32_t *)(SPI1_BASE + 0x0008))
#define SPI1_IER_REG (*(volatile uint32_t *)(SPI1_BASE + 0x0010))
#define SPI1_ISR_REG (*(volatile uint32_t *)(SPI1_BASE + 0x0014))
#define SPI1_FCR_REG (*(volatile uint32_t *)(SPI1_BASE + 0x0018))
#define SPI1_FSR_REG (*(volatile uint32_t *)(SPI1_BASE + 0x001C))
#define SPI1_WCR_REG (*(volatile uint32_t *)(SPI1_BASE + 0x0020))
#define SPI1_CCR_REG (*(volatile uint32_t *)(SPI1_BASE + 0x0024))
#define SPI1_MBC_REG (*(volatile uint32_t *)(SPI1_BASE + 0x0030))
#define SPI1_MTC_REG (*(volatile uint32_t *)(SPI1_BASE + 0x0034))
#define SPI1_BCC_REG (*(volatile uint32_t *)(SPI1_BASE + 0x0038))
#define SPI1_TXD_REG (*(volatile uint32_t *)(SPI1_BASE + 0x0200))
#define SPI1_RXD_REG (*(volatile uint32_t *)(SPI1_BASE + 0x0300))
/* WDOG */
#define WDOG_IRQ_EN_REG (*(volatile uint32_t *)(TIMER_BASE + 0x00A0))
#define WDOG_IRQ_STA_REG (*(volatile uint32_t *)(TIMER_BASE + 0x00A4))
#define WDOG_CTRL_REG (*(volatile uint32_t *)(TIMER_BASE + 0x00B0))
#define WDOG_CFG_REG (*(volatile uint32_t *)(TIMER_BASE + 0x00B4))
#define WDOG_MODE_REG (*(volatile uint32_t *)(TIMER_BASE + 0x00B8))
extern void sys_uart_putc(char c);
int boot_main(int argc, char **argv) {
/* Do initial mem pool */
do_init_mem_pool();
do_init_dma_pool();
printf("Start main while!\n\r");
//usb_device_init(USB_TYPE_USB_COM);
volatile int i;
for(i = 0;i <1000;i++)
{
;;;
}
usb_reg_debugdump();//0x53555741
//////////////////////////////////////////////////////
// Config SPI1 Interface Pin
Pn_CFG0(0) = 0x6666;
// Config SPI1 reset rule
BUS_SOFT_RST_REG0 |= (1 << 21);
// Config SPI1 CLK gate
BUS_CLK_GATING_REG0 |= (1 << 21);
// Reset SPI1, SPI1 Slave Mode, Enable SPI1
SPI1_GCR_REG = (1 << 31) | (0 << 1) | (1 << 0);
// Wait SPI1 reset complete
while(SPI1_GCR_REG & (1<<31));
// SS_LEVEL no active level: high, SS active level: low, CPOL=0, CPHA=1
SPI1_TCR_REG = (1<<7)|(1<<2)|(0<<1)|(1<<0);
// TX FIFO reset, RX FIFO reset
SPI1_FCR_REG = (1<<31) | (1<<15);
// Wait TX FIFO reset complete
while(SPI1_FCR_REG & (1<<31)) asm("nop");
// Wait RX FIFO reset complete
while(SPI1_FCR_REG & (1<<15)) asm("nop");
printf("SPI1_FSR_REG:0x%X\n", SPI1_FSR_REG);
SPI1_TXD_REG = 0x01;
printf("SPI1_FSR_REG:0x%X\n", SPI1_FSR_REG);
// Output: 0x20000 with SPI1_GCR_REG = (1 << 31) | (0 << 1) | (1 << 0): Slave Mode
// Output: 0x40000 with SPI1_GCR_REG = (1 << 31) | (1 << 1) | (1 << 0): Master Mode
//SPI1_FSR_REG[23:16]
//TX FIFO Counter
//These bits indicate the number of words in TX FIFO
//0: 0 byte in TX FIFO
//1: 1 byte in TX FIFO
//…
//64: 64 bytes in TX FIFO
//Other: /
/////////////////////////////////////////////////
printf("WDOG reset system\n");
WDOG_CFG_REG = 0x01; // Reset whole sytem
WDOG_MODE_REG = 0x01; // Start WDOG
while(1)
{
}
return 0;
}
void __fatal_error(const char *msg) {
while (1);
}
#ifndef NDEBUG
void __assert_func(const char *file, int line, const char *func, const char *expr) {
//printf("Assertion '%s' failed, at file %s:%d\n", expr, file, line);
__fatal_error("Assertion failed");
}
#endif
嗨,大家好,
我對F1C100S的SPI1有問題。
當我將SPI1與SLAVE模式一起使用時。
當我向SPI1_TXD_REG寫1個字(4字節)並從寄存器SPI1_FSR_REG中讀回TX_FIFO中的數字字節時。
SPI1_FSR_REG的返回值:0x20000(僅2個字節).// TX_FIFO中期望有4個字節
但是,當我切換到MASTER模式時,SPI1_FSR_REG的返回值是正確的:0x40000(4個字節)。
您能告訴我程序中的錯誤嗎?
非常感謝你。
main.c
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#define CCU_BASE (0x01C20000)
#define PIO_BASE (0x01C20800)
#define SPI1_BASE (0x01C06000)
#define DMA_BASE (0x01C02000)
#define TIMER_BASE (0x01C20C00)
/* PIO: PA(0), PB(1), PC(2), PD(3), PE(4), PF(5) */
#define Pn_CFG0(n) (*(volatile uint32_t *)(PIO_BASE + n*0x24 + 0x00)) // Port n Configure Register 0 (n=0~5)
#define Pn_CFG1(n) (*(volatile uint32_t *)(PIO_BASE + n*0x24 + 0x04)) // Port n Configure Register 1 (n=0~5)
#define Pn_CFG2(n) (*(volatile uint32_t *)(PIO_BASE + n*0x24 + 0x08)) // Port n Configure Register 2 (n=0~5)
#define Pn_CFG3(n) (*(volatile uint32_t *)(PIO_BASE + n*0x24 + 0x0C)) // Port n Configure Register 3 (n=0~5)
#define Pn_DATA(n) (*(volatile uint32_t *)(PIO_BASE + n*0x24 + 0x10)) // Port n Data Register (n=0~5)
#define Pn_DRV0(n) (*(volatile uint32_t *)(PIO_BASE + n*0x24 + 0x14)) // Port n Multi-Driving Register 0 (n=0~5)
#define Pn_DRV1(n) (*(volatile uint32_t *)(PIO_BASE + n*0x24 + 0x18)) // Port n Multi-Driving Register 1 (n=0~5)
#define Pn_PUL0(n) (*(volatile uint32_t *)(PIO_BASE + n*0x24 + 0x1C)) // Port n Pull Register 0 (n=0~5)
#define Pn_PUL1(n) (*(volatile uint32_t *)(PIO_BASE + n*0x24 + 0x20)) // Port n Pull Register 1
#define Pn_INT_CFG0(n) (*(volatile uint32_t *)(PIO_BASE + 0x200 + n*0x20 + 0x0)) // PIO Interrupt Configure Register 0 (n=0~2) PD(0), PE(1), PF(2)
#define Pn_INT_CFG1(n) (*(volatile uint32_t *)(PIO_BASE + 0x200 + n*0x20 + 0x4)) // PIO Interrupt Configure Register 1 (n=0~2) PD(0), PE(1), PF(2)
#define Pn_INT_CFG2(n) (*(volatile uint32_t *)(PIO_BASE + 0x200 + n*0x20 + 0x8)) // PIO Interrupt Configure Register 2 (n=0~2) PD(0), PE(1), PF(2)
#define Pn_INT_CFG3(n) (*(volatile uint32_t *)(PIO_BASE + 0x200 + n*0x20 + 0xC)) // PIO Interrupt Configure Register 3 (n=0~2) PD(0), PE(1), PF(2)
#define Pn_INT_CTRL(n) (*(volatile uint32_t *)(PIO_BASE + 0x200 + n*0x20 + 0x10)) // PIO Interrupt Control Register (n=0~2) PD(0), PE(1), PF(2)
#define Pn_INT_STA(n) (*(volatile uint32_t *)(PIO_BASE + 0x200 + n*0x20 + 0x14)) // PIO Interrupt Status Register (n=0~2) PD(0), PE(1), PF(2)
#define Pn_INT_DEB(n) (*(volatile uint32_t *)(PIO_BASE + 0x200 + n*0x20 + 0x18)) // PIO Interrupt Debounce Register (n=0~2) PD(0), PE(1), PF(2)
/* CCU */
#define BUS_CLK_GATING_REG0 (*(volatile uint32_t *)(CCU_BASE + 0x0060))
#define BUS_CLK_GATING_REG1 (*(volatile uint32_t *)(CCU_BASE + 0x0064))
#define BUS_CLK_GATING_REG2 (*(volatile uint32_t *)(CCU_BASE + 0x0068))
#define BUS_SOFT_RST_REG0 (*(volatile uint32_t *)(CCU_BASE + 0x02C0))
#define BUS_SOFT_RST_REG1 (*(volatile uint32_t *)(CCU_BASE + 0x02C4))
#define BUS_SOFT_RST_REG2 (*(volatile uint32_t *)(CCU_BASE + 0x02D0))
/* SPI1 */
#define SPI1_GCR_REG (*(volatile uint32_t *)(SPI1_BASE + 0x0004))
#define SPI1_TCR_REG (*(volatile uint32_t *)(SPI1_BASE + 0x0008))
#define SPI1_IER_REG (*(volatile uint32_t *)(SPI1_BASE + 0x0010))
#define SPI1_ISR_REG (*(volatile uint32_t *)(SPI1_BASE + 0x0014))
#define SPI1_FCR_REG (*(volatile uint32_t *)(SPI1_BASE + 0x0018))
#define SPI1_FSR_REG (*(volatile uint32_t *)(SPI1_BASE + 0x001C))
#define SPI1_WCR_REG (*(volatile uint32_t *)(SPI1_BASE + 0x0020))
#define SPI1_CCR_REG (*(volatile uint32_t *)(SPI1_BASE + 0x0024))
#define SPI1_MBC_REG (*(volatile uint32_t *)(SPI1_BASE + 0x0030))
#define SPI1_MTC_REG (*(volatile uint32_t *)(SPI1_BASE + 0x0034))
#define SPI1_BCC_REG (*(volatile uint32_t *)(SPI1_BASE + 0x0038))
#define SPI1_TXD_REG (*(volatile uint32_t *)(SPI1_BASE + 0x0200))
#define SPI1_RXD_REG (*(volatile uint32_t *)(SPI1_BASE + 0x0300))
/* WDOG */
#define WDOG_IRQ_EN_REG (*(volatile uint32_t *)(TIMER_BASE + 0x00A0))
#define WDOG_IRQ_STA_REG (*(volatile uint32_t *)(TIMER_BASE + 0x00A4))
#define WDOG_CTRL_REG (*(volatile uint32_t *)(TIMER_BASE + 0x00B0))
#define WDOG_CFG_REG (*(volatile uint32_t *)(TIMER_BASE + 0x00B4))
#define WDOG_MODE_REG (*(volatile uint32_t *)(TIMER_BASE + 0x00B8))
extern void sys_uart_putc(char c);
int boot_main(int argc, char **argv) {
/* Do initial mem pool */
do_init_mem_pool();
do_init_dma_pool();
printf("Start main while!\n\r");
//usb_device_init(USB_TYPE_USB_COM);
volatile int i;
for(i = 0;i <1000;i++)
{
;;;
}
usb_reg_debugdump();//0x53555741
//////////////////////////////////////////////////////
// Config SPI1 Interface Pin
Pn_CFG0(0) = 0x6666;
// Config SPI1 reset rule
BUS_SOFT_RST_REG0 |= (1 << 21);
// Config SPI1 CLK gate
BUS_CLK_GATING_REG0 |= (1 << 21);
// Reset SPI1, SPI1 Slave Mode, Enable SPI1
SPI1_GCR_REG = (1 << 31) | (0 << 1) | (1 << 0);
// Wait SPI1 reset complete
while(SPI1_GCR_REG & (1<<31));
// SS_LEVEL no active level: high, SS active level: low, CPOL=0, CPHA=1
SPI1_TCR_REG = (1<<7)|(1<<2)|(0<<1)|(1<<0);
// TX FIFO reset, RX FIFO reset
SPI1_FCR_REG = (1<<31) | (1<<15);
// Wait TX FIFO reset complete
while(SPI1_FCR_REG & (1<<31)) asm("nop");
// Wait RX FIFO reset complete
while(SPI1_FCR_REG & (1<<15)) asm("nop");
printf("SPI1_FSR_REG:0x%X\n", SPI1_FSR_REG);
SPI1_TXD_REG = 0x01;
printf("SPI1_FSR_REG:0x%X\n", SPI1_FSR_REG);
// Output: 0x20000 with SPI1_GCR_REG = (1 << 31) | (0 << 1) | (1 << 0): Slave Mode
// Output: 0x40000 with SPI1_GCR_REG = (1 << 31) | (1 << 1) | (1 << 0): Master Mode
//SPI1_FSR_REG[23:16]
//TX FIFO Counter
//These bits indicate the number of words in TX FIFO
//0: 0 byte in TX FIFO
//1: 1 byte in TX FIFO
//…
//64: 64 bytes in TX FIFO
//Other: /
/////////////////////////////////////////////////
printf("WDOG reset system\n");
WDOG_CFG_REG = 0x01; // Reset whole sytem
WDOG_MODE_REG = 0x01; // Start WDOG
while(1)
{
}
return 0;
}
void __fatal_error(const char *msg) {
while (1);
}
#ifndef NDEBUG
void __assert_func(const char *file, int line, const char *func, const char *expr) {
//printf("Assertion '%s' failed, at file %s:%d\n", expr, file, line);
__fatal_error("Assertion failed");
}
#endif
页次: 1