Files
stair56e_uart/component/boot2/bsp/bsp_spi1_slave.c
T
2026-08-05 19:07:52 +08:00

333 lines
9.4 KiB
C

#include "Includes.h"
#if 1
#define RCV_LEN 1024
#define SND_LEN 1024
#define CH_TX 3
#define CH_RX 11
#define CH11_BLK (1 << 11) //通道 11 块传输结束
#define CH3_BLK_EN (1 << 3) //通道3 块传输结束使能
static uint8_t __attribute__((aligned(4))) spi1_rcv_data[RCV_LEN];
volatile uint16_t spi1_rcv_len = 0;
static uint8_t __attribute__((aligned(4))) spi1_send_data[SND_LEN];
volatile uint16_t spi1_send_len = 0;
/* ---------------------------------------------------------------------------------------------------
- 函数名称: dma_ssi1_send
- 函数功能: spi slave 发送接口函数
- 输入参数:
- 创建日期:
----------------------------------------------------------------------------------------------------*/
void dma_ssi1_send(uint32_t snd_len)
{
__write_hw_reg32(DMAS_CHx_CTL0((CH_TX)) ,snd_len); //set trans byte len
__write_hw_reg32(DMAS_CLR ,CH_TX); //disable DMA TX channel
__write_hw_reg32(DMAS_EN ,CH_TX); //enable DMA TX channel
}
/* ---------------------------------------------------------------------------------------------------
- 函数名称: Init_spi_selve
- 函数功能: spi slave 初始化函数接口
- 输入参数:
- 创建日期:
----------------------------------------------------------------------------------------------------*/
void Init_spi_selve(uint32_t ch)
{
uint32_t val;
__write_hw_reg32(CPR_SPIx_MCLK_CTL(ch), 0x110010);//1分频 //- spi(x)_mclk = 32Mhz(When TXCO=32Mhz).
__write_hw_reg32(CPR_CTLAPBCLKEN_GRCTL , (0x1000100<<ch)); //- 打开spi(x) pclk.
__read_hw_reg32(CPR_SSI_CTRL, val);
val |= (ch==0)? 0x01: 0x10;
__write_hw_reg32(CPR_SSI_CTRL, val); //spi1 set slave
__write_hw_reg32(SSIx_EN(ch), 0x00);
__write_hw_reg32(SSIx_IE(ch), 0x10); /*接收满中断使能 接收FIFO上溢出 下溢出中断使能 */
__write_hw_reg32(SSIx_CTRL0(ch) , 0x07); /* 8bit SPI data */
__write_hw_reg32(SSIx_BAUD(ch), 2); /*- spix_mclk 分频 selve 在32M时钟下只能忍受4M (内部八分频)*/
//Init_dma_ssi1();
__write_hw_reg32(SSI1_DMAS , 0x02);
__write_hw_reg32(SSI1_DMATDL, 0x04);
//- TX Channel CH_TX
__write_hw_reg32(DMAS_CHx_SAR(CH_TX) , (uint32_t)spi1_send_data);
__write_hw_reg32(DMAS_CHx_DAR(CH_TX) , (uint32_t)SSI1_DATA);
__write_hw_reg32(DMAS_CHx_CTL1(CH_TX) ,((2 << 8)));
//__write_hw_reg32(DMAS_CHx_CTL0(CH_TX) ,0);//set trans byte len
//__write_hw_reg32(DMAS_EN , CH_TX); //enable DMA TX channel
//__write_hw_reg32(DMAS_INT_EN0,(CH3_BLK_EN));
//NVIC_EnableIRQ(DMAS_IRQn);
__write_hw_reg32(SSIx_EN(ch) , 0x01); //开启SPI传输
NVIC_EnableIRQ(SPI0_IRQn+ch);
}
//uint8_t rev_num=0;
extern void SPI1_Handler(void)
{
uint32_t spi1_data=0;
__read_hw_reg32(SSI1_RXFL,spi1_data);
while(spi1_data>0)
{
spi1_rcv_data[spi1_rcv_len++]=*SSIx_DATA(1);
if(spi1_rcv_len==1024)spi1_rcv_len=0;
//*SSIx_DATA(1)=rev_num++;
__read_hw_reg32(SSI1_RXFL,spi1_data);
}
__read_hw_reg32(SSI1_IC,spi1_data);
}
extern void test_spi1_selve(void)
{
gpio_mux_ctl(0,0);gpio_fun_inter(0,0);gpio_fun_sel(0,SSI1_SSN);
gpio_mux_ctl(1,0);gpio_fun_inter(1,0);gpio_fun_sel(1,SSI1_CLK);
gpio_mux_ctl(2,0);gpio_fun_inter(2,0);gpio_fun_sel(2,SSI1_TX);
gpio_mux_ctl(3,0);gpio_fun_inter(3,0);gpio_fun_sel(3,SSI1_RX);
Init_spi_selve(1);
while(1)
{
switch(spi1_rcv_data[0])
{
case 'A':
spi1_rcv_data[0]=0;spi1_rcv_len=0;
for(int i=0;i<SND_LEN;i++) spi1_send_data[i]=i;
spi1_send_data[0]=0x11;
dma_ssi1_send(SND_LEN);
break;
case 'B':
spi1_rcv_data[0]=0;spi1_rcv_len=0;
for(int i=0;i<SND_LEN;i++) spi1_send_data[i]=i;
spi1_send_data[0]=0x22;
dma_ssi1_send(SND_LEN);
break;
case 'C':
spi1_rcv_data[0]=0;spi1_rcv_len=0;
for(int i=0;i<SND_LEN;i++) spi1_send_data[i]=i;
spi1_send_data[0]=0x33;
dma_ssi1_send(SND_LEN);
break;
case 'D':
spi1_rcv_data[0]=0;spi1_rcv_len=0;
for(int i=0;i<SND_LEN;i++) spi1_send_data[i]=i;
spi1_send_data[0]=0x44;
dma_ssi1_send(SND_LEN);
break;
default:spi1_rcv_len=0; break;
}
}
}
static uint8_t __attribute__((aligned(4))) rxbuff[256];
static uint8_t __attribute__((aligned(4))) txbuff[256];
void Init_spi1_master(uint32_t ch, uint32_t freq)
{
uint32_t val;
__write_hw_reg32(CPR_SPIx_MCLK_CTL(ch), 0x110010);//1分频 //- spi(x)_mclk = 32Mhz(When TXCO=32Mhz).
__write_hw_reg32(CPR_CTLAPBCLKEN_GRCTL , (0x1000100<<ch)); //- 打开spi(x) pclk.
__read_hw_reg32(CPR_SSI_CTRL, val);
val |= (ch==0)? 0x01: 0x30;
__write_hw_reg32(CPR_SSI_CTRL, val);
__write_hw_reg32(SSIx_EN(ch), 0x00);
__write_hw_reg32(SSIx_IE(ch), 0x00);
__write_hw_reg32(SSIx_CTRL0(ch) , 0x07); /* 8bit SPI data */
__write_hw_reg32(SSIx_SE(ch), 0x01);
__write_hw_reg32(SSIx_BAUD(ch), freq); //- spix_mclk 分频.
__write_hw_reg32(SSIx_RXFTL(ch), 0x00);
__write_hw_reg32(SSIx_TXFTL(ch), 0x00);
//__write_hw_reg32(SSIx_EN(ch) , 0x01);
}
void spi1_read_write(uint16_t len)
{
uint32_t iWK = 0;
__write_hw_reg32(SSI1_EN , 0x00);
__write_hw_reg32(SSI1_DMAS , 0x03);
__write_hw_reg32(SSI1_DMATDL, 0x4); //-
__write_hw_reg32(SSI1_DMARDL, 0x4); //- 1/4 FIFO
__write_hw_reg32(SSI1_EN , 0x01);
//- RX Channel
__write_hw_reg32(DMAS_CHx_SAR(11) , 0x40014060);
__write_hw_reg32(DMAS_CHx_DAR(11) , (uint32_t)rxbuff);
__write_hw_reg32(DMAS_CHx_CTL1(11) ,((2 << 8)));//8bits
__write_hw_reg32(DMAS_CHx_CTL0(11) ,(len));
__write_hw_reg32(DMAS_EN , 11);
//- TX Channel
__write_hw_reg32(DMAS_CHx_SAR(3) , (uint32_t)txbuff);
__write_hw_reg32(DMAS_CHx_DAR(3) , 0x40014060);
__write_hw_reg32(DMAS_CHx_CTL1(3) ,((2 << 8)));//8bits
__write_hw_reg32(DMAS_CHx_CTL0(3) ,(len));
__write_hw_reg32(DMAS_EN , 3);
do {
__read_hw_reg32(DMAS_INT_RAW , iWK);
}while((iWK&0x808) != 0x808);
__write_hw_reg32(DMAS_INT_RAW, 0x808);
__write_hw_reg32(DMAS_CLR , 11);
__write_hw_reg32(DMAS_CLR , 3);
__write_hw_reg32(SSI1_EN , 0x00);
}
void test_spi1_master(void)
{
gpio_mux_ctl(0,0);gpio_fun_inter(0,0);gpio_fun_sel(0,SSI1_SSN);
gpio_mux_ctl(1,0);gpio_fun_inter(1,0);gpio_fun_sel(1,SSI1_CLK);
gpio_mux_ctl(2,0);gpio_fun_inter(2,0);gpio_fun_sel(2,SSI1_RX);
gpio_mux_ctl(3,0);gpio_fun_inter(3,0);gpio_fun_sel(3,SSI1_TX);
for(int i=0;i<256;i++)
{
rxbuff[i]=i;
txbuff[i]=i;
}
Init_spi1_master(1,SPIM_CLK_4MHZ);
while(1){
spi1_read_write(256);//此函数执行时间1.12ms
for(int i=0;i<0x455000;i++);
}
}
#endif
#if 0
static void wbit16(uint16_t reg_addr,int end,int start,char* bit_str)
{
uint16_t reg_val = 0;
char ch = 0;
int i = 0;
if(strlen(bit_str) != (end-start+1))
{
while(1); //error
}
reg_val = *(uint16_t *)(0X4002F000+reg_addr);
for(i=start;i<=end;i++)
{
int bit_idx = i-start; //index of bit string
ch = bit_str[(end-start)-bit_idx] - '0';
if(ch==1)
{
setbit(reg_val,i);
}
else if(ch==0)
{
clrbit(reg_val,i);
}
}
*(uint16_t *)(0X4002F000+reg_addr)=reg_val;
}
void osc32M_to_pll64M(void)
{
//???????
//for(uint32_t i=0;i<0x1200000;i++);
uint32_t val;
//??APB??
__read_hw_reg32(((volatile unsigned *)(0x40000000+ 0x130)), val);
__write_hw_reg32(((volatile unsigned *)(0x40000000+ 0x130)), (val&0xFFFFFFFE));
//??PLLM 48M??
wbit16(0x03D8,15,15,"1"); // bbpll ldo en
//wbit16(0x03D8,4,3,"11"); // bbpll fref div4
wbit16(0x001C,15,15,"1"); //debug BBPLL reset ,low reset
wbit16(0x001C,14,14,"1"); //Enable for BBPLL1,high enable,also control ref clock
wbit16(0x001C,13,13,"1"); // debug_DA_BBPLL1_EN
wbit16(0x001C,8,8,"1"); // Enable for 104M clk output to digital module
wbit16(0x0020,15,15,"1"); // reg BBPLL reset ,low reset
wbit16(0x0020,14,14,"1"); // Enable for BBPLL1,high enable,also control ref clock
wbit16(0x0020,13,13,"1"); // debug_DA_BBPLL1_EN
wbit16(0x0020,8,8,"1"); // Enable for 104M clk output to digital module
///wbit16(0x0024,9,4,"000110");// default 001100, div12,32m 000110,div
wbit16(0x0024,9,4,"001000"); //64M
wbit16(0x03D4,13,11,"011"); // vdd64m res
//xc_delay(1);//Delay 10ms
//??????PLL48M ??bbpll??????
*((volatile unsigned *)(CPR_AO_BASE + 0x20)) =0x2E;
__read_hw_reg32(((volatile unsigned *)(0x40000000+ 0x134)), val);
__write_hw_reg32(((volatile unsigned *)(0x40000000+ 0x134)), (val&0xFFFFFFE0)|0x11);//bbpll_clk_en ?? bbpll_clk_div ???
__read_hw_reg32(((volatile unsigned *)(0x40000000+ 0x130)), val);
__write_hw_reg32(((volatile unsigned *)(0x40000000+ 0x130)), (val&0xFFFFFFF9)|0x04);//0x2??RC16M???,0x00??32M osc,0x04 PLL96M 48M?????
}
void Set_PLL64M(void)
{
CPR_CTL();SYS_Main_Initialise();
osc32M_to_pll64M();
uart_64M_source_115200(0);
printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
// for(int i=0;i<800;i++);
// pll48M_to_osc32M();
// Init_uart(0,BAUD_115200);
// printf("\nTEST PLL48M\n");
}
#endif