/** * Initialize hardware SPI * */ void SdSpi::init(uint8_t sckDivisor) { uint32_t ctar, ctar0, ctar1; if (sckDivisor <= 2) { // 1/2 speed ctar = SPI_CTAR_DBR | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0); } else if (sckDivisor <= 4) { // 1/4 speed ctar = SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0); } else if (sckDivisor <= 8) { // 1/8 speed ctar = SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1); } else if (sckDivisor <= 12) { // 1/12 speed ctar = SPI_CTAR_BR(2) | SPI_CTAR_CSSCK(2); } else if (sckDivisor <= 16) { // 1/16 speed ctar = SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(3); } else if (sckDivisor <= 32) { // 1/32 speed ctar = SPI_CTAR_PBR(1) | SPI_CTAR_BR(4) | SPI_CTAR_CSSCK(4); } else if (sckDivisor <= 64) { // 1/64 speed ctar = SPI_CTAR_PBR(1) | SPI_CTAR_BR(5) | SPI_CTAR_CSSCK(5); } else { // 1/128 speed ctar = SPI_CTAR_PBR(1) | SPI_CTAR_BR(6) | SPI_CTAR_CSSCK(6); } // CTAR0 - 8 bit transfer ctar0 = ctar | SPI_CTAR_FMSZ(7); // CTAR1 - 16 bit transfer ctar1 = ctar | SPI_CTAR_FMSZ(15); if (SPI0_CTAR0 != ctar0 || SPI0_CTAR1 != ctar1) { SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F); SPI0_CTAR0 = ctar0; SPI0_CTAR1 = ctar1; } SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_PCSIS(0x1F); CORE_PIN11_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); CORE_PIN12_CONFIG = PORT_PCR_MUX(2); CORE_PIN13_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); }
/********************************************************* * Name: SPI_High_rate * Desc: Change SPI baud rate to high speed * Parameter: None * Return: None **********************************************************/ void SPI_High_rate(void) { /*Body*/ /* DSPI clock 6 MHz */ /* The system clock fsys = 68 MHz */ /* Value to be passed in SPI_Send_byte() function to DPI_CTAR0 register */ #ifdef MCU_MKL25Z4 SPI1_BR = SPI_BR_SPPR(1) | SPI_BR_SPR(1); #else gSPI_BaudRate = (SPI_CTAR_PBR(1) | SPI_CTAR_BR(0x01)); /* Configure the rest of the delays */ gSPI_BeforeTransfDelay = (SPI_CTAR_CSSCK(1) | SPI_CTAR_CSSCK(0x02)); gSPI_AfterTransfDelay = (SPI_CTAR_PASC(1) | SPI_CTAR_ASC(0x02)); gSPI_InterTransfDelay = (SPI_CTAR_PDT(1) | SPI_CTAR_DT(0x01)); #endif }/*EndBody*/
static int dspi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) { struct chip_data *chip; struct fsl_dspi *dspi = spi_master_get_devdata(spi->master); unsigned char br = 0, pbr = 0, fmsz = 0; /* Only alloc on first setup */ chip = spi_get_ctldata(spi); if (chip == NULL) { chip = kcalloc(1, sizeof(struct chip_data), GFP_KERNEL); if (!chip) return -ENOMEM; } chip->mcr_val = SPI_MCR_MASTER | SPI_MCR_PCSIS | SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF; if ((spi->bits_per_word >= 4) && (spi->bits_per_word <= 16)) { fmsz = spi->bits_per_word - 1; } else { pr_err("Invalid wordsize\n"); kfree(chip); return -ENODEV; } chip->void_write_data = 0; hz_to_spi_baud(&pbr, &br, spi->max_speed_hz, clk_get_rate(dspi->clk)); chip->ctar_val = SPI_CTAR_FMSZ(fmsz) | SPI_CTAR_CPOL(spi->mode & SPI_CPOL ? 1 : 0) | SPI_CTAR_CPHA(spi->mode & SPI_CPHA ? 1 : 0) | SPI_CTAR_LSBFE(spi->mode & SPI_LSB_FIRST ? 1 : 0) | SPI_CTAR_PBR(pbr) | SPI_CTAR_BR(br); spi_set_ctldata(spi, chip); return 0; }
//----------------------------------------------------------------------------- // FUNCTION: D4DLCDHW_Init_Kinetis_Spi // SCOPE: Low Level Driver API function // DESCRIPTION: The function is used for initialization of this low level driver // // PARAMETERS: none // // RETURNS: result: 1 - Success // 0 - Failed //----------------------------------------------------------------------------- static unsigned char D4DLCDHW_Init_Kinetis_Spi(void) { // defined in spi_cfg.h #ifdef D4DLCD_DISPLAY_MCU_USER_INIT D4DLCD_DISPLAY_MCU_USER_INIT #endif D4DLCD_SPI_PORT_INIT; D4DLCD_ASSERT_DC; D4DLCD_INIT_DC; // Enable and clear SPI D4DLCD_SPI_MCR &= (~ SPI_MCR_MDIS_MASK); D4DLCD_SPI_MCR = SPI_MCR_HALT_MASK | SPI_MCR_CLR_TXF_MASK | SPI_MCR_CLR_RXF_MASK; // 15+1 = 16-bit transfers, Fclk = Fsys/4 D4DLCD_SPI_CTAR0 = SPI_CTAR_FMSZ(15) | SPI_CTAR_BR(0); #ifdef D4DLCD_SPI_DBL_BRATE D4DLCD_SPI_CTAR0 |= SPI_CTAR_DBR_MASK; // Dual Baudrate enable in config file #endif // Set CS0-7 inactive high D4DLCD_SPI_MCR |= (SPI_MCR_PCSIS(1 << (D4DLCD_SPI_PCS_ID))|SPI_MCR_MSTR_MASK); // Disable all IRQs D4DLCD_SPI_RSER = 0; // clear Flag D4DLCD_SPI_SR = SPI_SR_TFFF_MASK; D4DLCD_SPI_SR = SPI_SR_TCF_MASK; // Enable SPI D4DLCD_SPI_MCR &= (~ SPI_MCR_HALT_MASK); return 1; }
/** * Initialization with cpol and cpha 0, speed is configurable. * * @param SPI speed [0-7] */ void init(uint8_t speed) { init(); // Default 1/2 speed uint32_t ctar = SPI_CTAR_DBR; switch(speed) { case 1: // 1/4 ctar = 0; break; case 2: // 1/8 ctar = SPI_CTAR_BR(1); break; case 3: // 1/12 ctar = SPI_CTAR_BR(2); break; case 4: // 1/16 ctar = SPI_CTAR_BR(3); break; case 5: // 1/32 ctar = SPI_CTAR_PBR(1) | SPI_CTAR_BR(4); break; case 6: // 1/64 ctar = SPI_CTAR_PBR(1) | SPI_CTAR_BR(5); break; case 7: //1/128 ctar = SPI_CTAR_PBR(1) | SPI_CTAR_BR(6); // fall thru default: // default 1/2 speed, this is the maximum. break; } ctar0 = ctar | SPI_CTAR_FMSZ(7); ctar1 = ctar | SPI_CTAR_FMSZ(15); updatectars(); }
/* ===================================================================*/ LDD_TDeviceData* SM1_Init(LDD_TUserData *UserDataPtr) { /* Allocate LDD device structure */ SM1_TDeviceDataPtr DeviceDataPrv; /* {Default RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; DeviceDataPrv->UserData = UserDataPtr; /* Store the RTOS device structure */ /* Interrupt vector(s) allocation */ /* {Default RTOS Adapter} Set interrupt vector: IVT is static, ISR parameter is passed by the global variable */ INT_SPI0__DEFAULT_RTOS_ISRPARAM = DeviceDataPrv; DeviceDataPrv->TxCommand = 0x80040000U; /* Initialization of current Tx command */ DeviceDataPrv->ErrFlag = 0x00U; /* Clear error flags */ /* Clear the receive counters and pointer */ DeviceDataPrv->InpRecvDataNum = 0x00U; /* Clear the counter of received characters */ DeviceDataPrv->InpDataNumReq = 0x00U; /* Clear the counter of characters to receive by ReceiveBlock() */ DeviceDataPrv->InpDataPtr = NULL; /* Clear the buffer pointer for received characters */ /* Clear the transmit counters and pointer */ DeviceDataPrv->OutSentDataNum = 0x00U; /* Clear the counter of sent characters */ DeviceDataPrv->OutDataNumReq = 0x00U; /* Clear the counter of characters to be send by SendBlock() */ DeviceDataPrv->OutDataPtr = NULL; /* Clear the buffer pointer for data to be transmitted */ /* SIM_SCGC6: SPI0=1 */ SIM_SCGC6 |= SIM_SCGC6_SPI0_MASK; /* Interrupt vector(s) priority setting */ /* NVIC_IPR2: PRI_10=1 */ NVIC_IPR2 = (uint32_t)((NVIC_IPR2 & (uint32_t)~(uint32_t)( NVIC_IP_PRI_10(0x02) )) | (uint32_t)( NVIC_IP_PRI_10(0x01) )); /* NVIC_ISER: SETENA31=0,SETENA30=0,SETENA29=0,SETENA28=0,SETENA27=0,SETENA26=0,SETENA25=0,SETENA24=0,SETENA23=0,SETENA22=0,SETENA21=0,SETENA20=0,SETENA19=0,SETENA18=0,SETENA17=0,SETENA16=0,SETENA15=0,SETENA14=0,SETENA13=0,SETENA12=0,SETENA11=0,SETENA10=1,SETENA9=0,SETENA8=0,SETENA7=0,SETENA6=0,SETENA5=0,SETENA4=0,SETENA3=0,SETENA2=0,SETENA1=0,SETENA0=0 */ NVIC_ISER = NVIC_ISER_SETENA10_MASK; /* NVIC_ICER: CLRENA31=0,CLRENA30=0,CLRENA29=0,CLRENA28=0,CLRENA27=0,CLRENA26=0,CLRENA25=0,CLRENA24=0,CLRENA23=0,CLRENA22=0,CLRENA21=0,CLRENA20=0,CLRENA19=0,CLRENA18=0,CLRENA17=0,CLRENA16=0,CLRENA15=0,CLRENA14=0,CLRENA13=0,CLRENA12=0,CLRENA11=0,CLRENA10=0,CLRENA9=0,CLRENA8=0,CLRENA7=0,CLRENA6=0,CLRENA5=0,CLRENA4=0,CLRENA3=0,CLRENA2=0,CLRENA1=0,CLRENA0=0 */ NVIC_ICER = 0x00U; /* SIM_SCGC5: PORTE=1,PORTC=1 */ SIM_SCGC5 |= (SIM_SCGC5_PORTE_MASK | SIM_SCGC5_PORTC_MASK); /* PORTE_PCR18: ISF=0,MUX=6 */ PORTE_PCR18 = (uint32_t)((PORTE_PCR18 & (uint32_t)~(uint32_t)( PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x01) )) | (uint32_t)( PORT_PCR_MUX(0x06) )); /* PORTE_PCR19: ISF=0,MUX=6 */ PORTE_PCR19 = (uint32_t)((PORTE_PCR19 & (uint32_t)~(uint32_t)( PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x01) )) | (uint32_t)( PORT_PCR_MUX(0x06) )); /* PORTC_PCR5: ISF=0,MUX=2 */ PORTC_PCR5 = (uint32_t)((PORTC_PCR5 & (uint32_t)~(uint32_t)( PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x05) )) | (uint32_t)( PORT_PCR_MUX(0x02) )); /* PORTC_PCR2: ISF=0,MUX=2 */ PORTC_PCR2 = (uint32_t)((PORTC_PCR2 & (uint32_t)~(uint32_t)( PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x05) )) | (uint32_t)( PORT_PCR_MUX(0x02) )); /* SPI0_MCR: MSTR=0,CONT_SCKE=0,DCONF=0,FRZ=0,MTFE=0,??=0,ROOE=1,??=0,??=0,??=0,PCSIS=4,DOZE=0,MDIS=0,DIS_TXF=0,DIS_RXF=0,CLR_TXF=0,CLR_RXF=0,SMPL_PT=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,HALT=1 */ SPI0_MCR = SPI_MCR_DCONF(0x00) | SPI_MCR_ROOE_MASK | SPI_MCR_PCSIS(0x04) | SPI_MCR_SMPL_PT(0x00) | SPI_MCR_HALT_MASK; /* Set Configuration register */ /* SPI0_MCR: MSTR=1,CONT_SCKE=0,DCONF=0,FRZ=0,MTFE=0,??=0,ROOE=1,??=0,??=0,??=0,PCSIS=4,DOZE=0,MDIS=0,DIS_TXF=1,DIS_RXF=1,CLR_TXF=1,CLR_RXF=1,SMPL_PT=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,HALT=1 */ SPI0_MCR = SPI_MCR_MSTR_MASK | SPI_MCR_DCONF(0x00) | SPI_MCR_ROOE_MASK | SPI_MCR_PCSIS(0x04) | SPI_MCR_DIS_TXF_MASK | SPI_MCR_DIS_RXF_MASK | SPI_MCR_CLR_TXF_MASK | SPI_MCR_CLR_RXF_MASK | SPI_MCR_SMPL_PT(0x00) | SPI_MCR_HALT_MASK; /* Set Configuration register */ /* SPI0_CTAR0: DBR=1,FMSZ=7,CPOL=0,CPHA=0,LSBFE=0,PCSSCK=0,PASC=0,PDT=0,PBR=2,CSSCK=0,ASC=0,DT=0,BR=1 */ SPI0_CTAR0 = SPI_CTAR_DBR_MASK | SPI_CTAR_FMSZ(0x07) | SPI_CTAR_PCSSCK(0x00) | SPI_CTAR_PASC(0x00) | SPI_CTAR_PDT(0x00) | SPI_CTAR_PBR(0x02) | SPI_CTAR_CSSCK(0x00) | SPI_CTAR_ASC(0x00) | SPI_CTAR_DT(0x00) | SPI_CTAR_BR(0x01); /* Set Clock and Transfer Attributes register */ /* SPI0_SR: TCF=1,TXRXS=0,??=0,EOQF=1,TFUF=1,??=0,TFFF=1,??=0,??=0,??=0,??=1,??=0,RFOF=1,??=0,RFDF=1,??=0,TXCTR=0,TXNXTPTR=0,RXCTR=0,POPNXTPTR=0 */ SPI0_SR = SPI_SR_TCF_MASK | SPI_SR_EOQF_MASK | SPI_SR_TFUF_MASK | SPI_SR_TFFF_MASK | SPI_SR_RFOF_MASK | SPI_SR_RFDF_MASK | SPI_SR_TXCTR(0x00) | SPI_SR_TXNXTPTR(0x00) | SPI_SR_RXCTR(0x00) | SPI_SR_POPNXTPTR(0x00) | 0x00200000U; /* Clear flags */ /* SPI0_RSER: TCF_RE=0,??=0,??=0,EOQF_RE=0,TFUF_RE=0,??=0,TFFF_RE=0,TFFF_DIRS=0,??=0,??=0,??=0,??=0,RFOF_RE=0,??=0,RFDF_RE=1,RFDF_DIRS=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ SPI0_RSER = SPI_RSER_RFDF_RE_MASK; /* Set DMA Interrupt Request Select and Enable register */ /* SPI0_MCR: HALT=0 */ SPI0_MCR &= (uint32_t)~(uint32_t)(SPI_MCR_HALT_MASK); /* Registration of the device structure */ PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_SM1_ID,DeviceDataPrv); return ((LDD_TDeviceData *)DeviceDataPrv); /* Return pointer to the data data structure */ }
OSStatus spi_init( spi_driver_t* spi_driver, SPI_MemMapPtr spi_peripheral, uint32_t baud_rate_bps, uint8_t chip_select, bool polarity, bool phase, bool use_dma ) { uint8_t br = get_baud_rate_scaler_register_value( baud_rate_bps ); spi_driver->spi_peripheral = spi_peripheral; spi_driver->baud_rate_bps = baud_rate_bps; spi_driver->chip_select = chip_select; spi_driver->polarity = polarity; spi_driver->phase = phase; spi_driver->use_dma = use_dma; /* Enable SPI peripheral clock */ set_spi_peripheral_clock( spi_peripheral, true ); /* Enable SPI peripheral and clean up (stop) any previous transfer * MDIS = 0 to enable * HALT = 1 to stop transfer * MSTR = 1 for master mode * DCONF = 0 for SPI * PCSIS[x] = 1 for CS active low */ SPI_MCR_REG( spi_peripheral ) &= ~(uint32_t) ( SPI_MCR_MDIS_MASK | SPI_MCR_DCONF(0) ); SPI_MCR_REG( spi_peripheral ) |= (uint32_t) ( (0x1<<24)|SPI_MCR_HALT_MASK | SPI_MCR_MSTR_MASK | SPI_MCR_PCSIS( 1 << chip_select ) ); /* Select Clock and Transfer Attributes Register (CTAR). Always use CTAR0 */ SPI_PUSHR_REG( spi_peripheral ) &= ~(uint32_t) SPI_PUSHR_CTAS(CTAR_REG_USED); /* Reset Clock and Transfer Attributes (CTAR) register */ SPI_CTAR_REG( spi_peripheral, CTAR_REG_USED ) = 0; /* Set SPI configuration * FMSZ = 7. Set frame size to 8-bit. frame size = FMSZ + 1 * CPOL = phase * CPHA = polarity * DBR = 00 * PBR = 2 * BR = calculate based on baud_rate_Mbps * PCSSCK = 0 * PASC = 0 * PDT = 0 * CSSCK = BR - 1 * ASC = BR - 1 * DT = 0 */ SPI_CTAR_REG( spi_peripheral, CTAR_REG_USED ) |= (uint32_t) ( SPI_CTAR_CPOL_MASK & (uint32_t)( polarity << SPI_CTAR_CPOL_SHIFT ) ) | (uint32_t) ( SPI_CTAR_CPHA_MASK & (uint32_t)( phase << SPI_CTAR_CPHA_SHIFT ) ) | (uint32_t) ( SPI_CTAR_FMSZ( 8 - 1 ) ) | (uint32_t) ( SPI_CTAR_DBR_MASK & ( DOUBLE_BAUD_RATE << SPI_CTAR_DBR_SHIFT ) ) | (uint32_t) ( SPI_CTAR_PBR( CTAR_PBR ) ) | (uint32_t) ( SPI_CTAR_BR( br ) ) | (uint32_t) ( SPI_CTAR_CSSCK( br - 1 ) ) | (uint32_t) ( SPI_CTAR_ASC( br - 1 ) ); clear_spi_fifos( spi_peripheral ); /* Enable the start transfer bit */ SPI_MCR_REG( spi_peripheral ) &= ~(uint32_t) ( SPI_MCR_HALT_MASK ); if(use_dma) { SPI_RSER_REG( spi_peripheral ) |= (0x3<<24)|(0x3<<16); DMA_init(); } spi_status_print(spi_peripheral); return kNoErr; }
//========================================================================= //函数名称:spi_init //函数参数:spin:SPI通道号。 // Master:是否是主机。 //函数返回:无 //功能概要:SPI初始化。 //========================================================================= void spi_init(SPIn spin,SPI_CFG master) { //使能SPI模块时钟,配置SPI引脚功能 if(spin == 0) { SIM_SCGC6 |= SIM_SCGC6_DSPI0_MASK; //PORTA_PCR14 = 0 | PORT_PCR_MUX(0x2) | PORT_PCR_DSE_MASK;//PCS0 //DSE=1:输出时高驱动能力 PORTA_PCR15 = 0 | PORT_PCR_MUX(0x2) | PORT_PCR_DSE_MASK;//SCK PORTA_PCR16 = 0 | PORT_PCR_MUX(0x2) | PORT_PCR_DSE_MASK;//SOUT PORTA_PCR17 = 0 | PORT_PCR_MUX(0x2);//SIN } else if(spin == 1) { SIM_SCGC6 |= SIM_SCGC6_SPI1_MASK; PORTE_PCR1 = 0 | PORT_PCR_MUX(0x2) | PORT_PCR_DSE_MASK; //SOUT PORTE_PCR2 = 0 | PORT_PCR_MUX(0x2) | PORT_PCR_DSE_MASK; //SCK PORTE_PCR3 = 0 | PORT_PCR_MUX(0x2); //SIN PORTE_PCR4 = 0 | PORT_PCR_MUX(0x2) | PORT_PCR_DSE_MASK; //PCS0 } else { SIM_SCGC3 |= SIM_SCGC3_SPI2_MASK; PORTD_PCR13 = 0 | PORT_PCR_MUX(0x2) | PORT_PCR_DSE_MASK; //SOUT PORTD_PCR12 = 0 | PORT_PCR_MUX(0x2) | PORT_PCR_DSE_MASK; //SCK PORTD_PCR14 = 0 | PORT_PCR_MUX(0x2)/* | PORT_PCR_DSE_MASK*/; //SIN //PORTD_PCR15 = 0 | PORT_PCR_MUX(0x2)/* | PORT_PCR_DSE_MASK*/; //PCS1 } SPI_MCR_REG(SPIN[spin]) = 0 | SPI_MCR_CLR_TXF_MASK //Clear the Tx FIFO counter. | SPI_MCR_CLR_RXF_MASK //Clear the Rx FIFO counter. //| SPI_MCR_PCSIS_MASK | SPI_MCR_HALT_MASK; //根据主从机模式设置工作模式。MCU提供最大主机频率是1/2主频,最大从机频率是1/4主频 if(master == MASTER) { SPI_MCR_REG(SPIN[spin]) = (0 | SPI_MCR_MSTR_MASK //Master,主机模式 // | SPI_MCR_PCSIS(2) //PCS1 ); SPI_CTAR_REG(SPIN[spin],0) = (0 //| SPI_CTAR_DBR_MASK //双波特率 ,这里设 DBR=1,CPHA=1,PBR=00,得SCK Duty Cycle 为 50/50 //| SPI_CTAR_CPHA_MASK //数据在SCK上升沿改变(输出),在下降沿被捕捉(输入读取)。如果是0,则反之。 w25x16在上升沿读取数据;NRF24L01在上升沿读取数据 | SPI_CTAR_PBR(1) //波特率分频器 ,0~3 对应的分频值Prescaler为 2、3、5、7 | SPI_CTAR_PDT(0x00) //延时因子为 PDT*2+1 ,这里PDT为3,即延时因子为7。PDT为2bit | SPI_CTAR_BR(0) //波特率计数器值 ,当BR<=3,分频Scaler 为 2*(BR+1) ,当BR>=3,分频Scaler 为 2^BR 。BR为4bit //SCK 波特率 = (fSYS/Prescaler) x [(1+DBR)/Scaler ] fSYS 为 Bus clock // 100M 2 1 2 = 50M 这里以最大的来算 // 100M 5 1 2 =20M //| SPI_CTAR_CPOL_MASK //时钟极性,1表示 SCK 不活跃状态为高电平, NRF24L01 不活跃为低电平 | SPI_CTAR_FMSZ(0x07) //每帧传输 7bit+1 ,即8bit (FMSZ默认就是8) // | SPI_CTAR_LSBFE_MASK //1为低位在前。 //| SPI_CTAR_CSSCK(1) // //|SPI_CTAR_PCSSCK(2) //设置片选信号有效到时钟第一个边沿出现的延时的预分频值。tcsc延时预分频 2*x+1; ); //LSBFE 为 0 ,数据在前 } else { //默认从机模式 SPI_CTAR_SLAVE_REG(SPIN[spin],0) = 0 | SPI_CTAR_SLAVE_FMSZ(0x07) | SPI_CTAR_SLAVE_CPOL_MASK | SPI_CTAR_SLAVE_CPHA_MASK; } //DELAY_MS(100); /************* 清标志位 ***************/ SPI_SR_REG(SPIN[spin]) = (SPI_SR_EOQF_MASK //End of Queue Flag,发送队列空了,发送完毕 | SPI_SR_TFUF_MASK //Transmit FIFO Underflow Flag,传输FIFO下溢标志位,SPI为从机模式,Tx FIFO为空,而外部SPI主机模式启动传输,标志位就会置1,写1清0 | SPI_SR_TFFF_MASK //Transmit FIFO Fill Flag,传输FIFO满标志位。 写1或者DMA控制器发现传输FIFO满了就会清0。 0表示Tx FIFO满了 | SPI_SR_RFOF_MASK //Receive FIFO Overflow Flag,接收FIFO溢出标志位。 | SPI_SR_RFDF_MASK); //Receive FIFO Drain Flag,接收FIFO损耗标志位,写1或者DMA控制器发现传输FIFO空了就会清0。0表示Rx FIFO空 SPI_MCR_REG(SPIN[spin]) &= ~SPI_MCR_HALT_MASK; //启动SPI传输。1为暂停,0为启动 DELAY_MS(1); }
/********************************************************* * Name: SPI_Init * Desc: Initialize SPI2 Module * Parameter: None * Return: None **********************************************************/ void SPI_Init(void) { /*Body*/ /* set PORTE pin 1 to DSPI1.SOUT*/ #ifdef MCU_MK70F12 /* set PORTE pin 1 to DSPI1.SOUT*/ PORTE_PCR1 = PORT_PCR_MUX(7); /* set PORTE pin 2 to DSPI1.SCK*/ PORTE_PCR2 = PORT_PCR_MUX(2); /* set PORTE pin 3 to DSPI1.SIN*/ PORTE_PCR3 = PORT_PCR_MUX(7); /* set PORTE pin 4 to DSPI1.CS0*/ PORTE_PCR4 = PORT_PCR_MUX(2); SIM_SCGC5 |= SIM_SCGC5_PORTE_MASK; /* Enable clock gate to DSPI1 module */ SIM_SCGC6 |= SIM_SCGC6_DSPI1_MASK; #elif defined MCU_MK20D5 /* set PORTD pin 1 to SPI0.SOUT*/ PORTD_PCR2 = PORT_PCR_MUX(2); /* set PORTD pin 1 to SPI0.SCK*/ PORTD_PCR1 = PORT_PCR_MUX(2); /* set PORTD pin 3 to SPI0.SIN*/ PORTD_PCR3 = PORT_PCR_MUX(2); /* set PORTD pin 0 to SPI0.CS0*/ PORTD_PCR0 = PORT_PCR_MUX(2); SIM_SCGC5 |= SIM_SCGC5_PORTE_MASK; /* Enable clock gate to DSPI1 module */ SIM_SCGC6 |= SIM_SCGC6_SPI0_MASK; #elif defined MCU_MK20D7 /* set PORTE pin 1 to DSPI1.SOUT*/ PORTE_PCR1 = PORT_PCR_MUX(2); /* set PORTE pin 2 to DSPI1.SCK*/ PORTE_PCR2 = PORT_PCR_MUX(2); /* set PORTE pin 3 to DSPI1.SIN*/ PORTE_PCR3 = PORT_PCR_MUX(2); /* set PORTE pin 4 to DSPI1.CS0*/ PORTE_PCR4 = PORT_PCR_MUX(2); SIM_SCGC5 |= SIM_SCGC5_PORTE_MASK; /* Enable clock gate to DSPI1 module */ SIM_SCGC6 |= SIM_SCGC6_SPI1_MASK; #elif defined MCU_MK40D7 /* set PORTE pin 1 to DSPI1.SOUT*/ PORTE_PCR1 = PORT_PCR_MUX(2); /* set PORTE pin 2 to DSPI1.SCK*/ PORTE_PCR2 = PORT_PCR_MUX(2); /* set PORTE pin 3 to DSPI1.SIN*/ PORTE_PCR3 = PORT_PCR_MUX(2); /* set PORTE pin 4 to DSPI1.CS0*/ PORTE_PCR4 = PORT_PCR_MUX(2); SIM_SCGC5 |= SIM_SCGC5_PORTE_MASK; /* Enable clock gate to DSPI1 module */ SIM_SCGC6 |= SIM_SCGC6_SPI1_MASK; #elif defined MCU_MK40N512VMD100 /* set PORTE pin 1 to DSPI1.SOUT*/ PORTE_PCR1 = PORT_PCR_MUX(2); /* set PORTE pin 2 to DSPI1.SCK*/ PORTE_PCR2 = PORT_PCR_MUX(2); /* set PORTE pin 3 to DSPI1.SIN*/ PORTE_PCR3 = PORT_PCR_MUX(2); /* set PORTE pin 4 to DSPI1.CS0*/ PORTE_PCR4 = PORT_PCR_MUX(2); SIM_SCGC5 |= SIM_SCGC5_PORTE_MASK; /* Enable clock gate to DSPI1 module */ SIM_SCGC6 |= SIM_SCGC6_SPI1_MASK; #elif defined MCU_MK53N512CMD100 /* set PORTE pin 1 to DSPI1.SOUT*/ PORTE_PCR1 = PORT_PCR_MUX(2); /* set PORTE pin 2 to DSPI1.SCK*/ PORTE_PCR2 = PORT_PCR_MUX(2); /* set PORTE pin 3 to DSPI1.SIN*/ PORTE_PCR3 = PORT_PCR_MUX(2); /* set PORTE pin 4 to DSPI1.CS0*/ PORTE_PCR4 = PORT_PCR_MUX(2); SIM_SCGC5 |= SIM_SCGC5_PORTE_MASK; /* Enable clock gate to DSPI1 module */ SIM_SCGC6 |= SIM_SCGC6_SPI1_MASK; #elif defined MCU_MK60N512VMD100 /* set PORTE pin 1 to DSPI1.SOUT*/ PORTE_PCR1 = PORT_PCR_MUX(2); /* set PORTE pin 2 to DSPI1.SCK*/ PORTE_PCR2 = PORT_PCR_MUX(2); /* set PORTE pin 3 to DSPI1.SIN*/ PORTE_PCR3 = PORT_PCR_MUX(2); /* set PORTE pin 4 to DSPI1.CS0*/ PORTE_PCR4 = PORT_PCR_MUX(2); SIM_SCGC5 |= SIM_SCGC5_PORTE_MASK; /* Enable clock gate to DSPI1 module */ SIM_SCGC6 |= SIM_SCGC6_SPI1_MASK; #elif defined MCU_MK21D5 SIM_SCGC5 |= SIM_SCGC5_PORTB_MASK; /* set PORTB pin 16 to DSPI1.SOUT*/ PORTB_PCR16 = PORT_PCR_MUX(2); /* set PORTB pin 11 to DSPI1.SCK*/ PORTB_PCR11 = PORT_PCR_MUX(2); /* set PORTB pin 17 to DSPI1.SIN*/ PORTB_PCR17 = PORT_PCR_MUX(2); /* set PORTB pin 10 to DSPI1.CS0*/ PORTB_PCR10 = PORT_PCR_MUX(2); SIM_SCGC5 |= SIM_SCGC5_PORTB_MASK; /* Enable clock gate to DSPI1 module */ SIM_SCGC6 |= SIM_SCGC6_SPI1_MASK | SIM_SCGC6_DMAMUX_MASK; #elif defined MCU_MKL25Z4 /* set PORTE pin 1 to DSPI1.SOUT*/ PORTE_PCR1 = PORT_PCR_MUX(2); /* set PORTE pin 2 to DSPI1.SCK*/ PORTE_PCR2 = PORT_PCR_MUX(2); /* set PORTE pin 3 to DSPI1.SIN*/ PORTE_PCR3 = PORT_PCR_MUX(2); /* set PORTE pin 4 to DSPI1.CS0*/ PORTE_PCR4 = PORT_PCR_MUX(2); SIM_SCGC5 |= SIM_SCGC5_PORTE_MASK; /* Enable clock gate to DSPI1 module */ SIM_SCGC4 |= SIM_SCGC4_SPI1_MASK; SIM_SCGC6 |= SIM_SCGC6_DMAMUX_MASK; #else /* set PORTE pin 1 to DSPI1.SOUT*/ PORTE_PCR1 = PORT_PCR_MUX(2); /* set PORTE pin 2 to DSPI1.SCK*/ PORTE_PCR2 = PORT_PCR_MUX(2); /* set PORTE pin 3 to DSPI1.SIN*/ PORTE_PCR3 = PORT_PCR_MUX(2); /* set PORTE pin 4 to DSPI1.CS0*/ PORTE_PCR4 = PORT_PCR_MUX(2); SIM_SCGC5 |= SIM_SCGC5_PORTE_MASK; /* Enable clock gate to DSPI1 module */ SIM_SCGC6 |= SIM_SCGC6_DMAMUX_SPI1_MASK; #endif /* Enable master mode, disable both transmit and receive FIFO buffers, set the inactive state for PCS2 high, enable the module (MDIS = 0), delay the sample point from the leading edge of the clock and halt any transfer */ #ifdef MCU_MK20D5 SPI0_MCR = (SPI_MCR_MSTR_MASK | SPI_MCR_PCSIS(1) | SPI_MCR_SMPL_PT(2) | SPI_MCR_HALT_MASK); SPI0_MCR |= (SPI_MCR_CLR_RXF_MASK | SPI_MCR_CLR_TXF_MASK); #elif defined MCU_MKL25Z4 PORTE_PCR4 = PORT_PCR_MUX(1); GPIOE_PDDR |= (1<<4); SPI_clr_SS(); SPI1_C2 = SPI_C2_SPISWAI_MASK; SPI1_C1 = SPI_C1_SPE_MASK | SPI_C1_MSTR_MASK | SPI_C1_SSOE_MASK; #else SPI1_MCR = (SPI_MCR_MSTR_MASK | SPI_MCR_PCSIS(1) | SPI_MCR_SMPL_PT(2) | SPI_MCR_HALT_MASK); SPI1_MCR |= (SPI_MCR_CLR_RXF_MASK | SPI_MCR_CLR_TXF_MASK); #endif /* DSPI clock 375 KHz */ /* The system clock fsys = 68 MHz */ // K60: bus clock: 48MHz, DSPI clock: ~107 KHz // K70: bus clock: 60MHz, DSPI clock: ~156 KHz /* Value to be passed in SPI_Send_byte() function to DPI_CTAR0 register */ #ifdef MCU_MKL25Z4 /* 375KHz SPI clock */ SPI1_BR = SPI_BR_SPPR(7) | SPI_BR_SPR(5); /* SCK = 10us */ #else #ifdef MCU_MK70F12 gSPI_BaudRate = (SPI_CTAR_PBR(1) | SPI_CTAR_BR(0x07)); #else gSPI_BaudRate = (SPI_CTAR_PBR(3) | SPI_CTAR_BR(0x06)); #endif /* Configure the rest of the delays */ gSPI_BeforeTransfDelay = (SPI_CTAR_CSSCK(1) | SPI_CTAR_CSSCK(0x04)); gSPI_AfterTransfDelay = (SPI_CTAR_PASC(3) | SPI_CTAR_ASC(0x04)); gSPI_InterTransfDelay = (SPI_CTAR_PDT(3) | SPI_CTAR_DT(0x05)); #endif }/*EndBody*/
/** * \brief dspi_hal_set_baud,Internal function * \details Set the DSPI baud rate in bits per second. * This function will take in the desired bitsPerSec (baud rate) and will calculate the nearest * possible baud rate without exceeding the desired baud rate, and will return the calculated * baud rate in bits-per-second. It requires that the caller also provide the frequency of the * module source clock (in Hz). */ static uint32_t dspi_hal_set_baud(uint32_t instance, uint8_t whichCtar, uint32_t bitsPerSec, uint32_t sourceClockInHz) { uint32_t prescaler, bestPrescaler; uint32_t scaler, bestScaler; uint32_t dbr, bestDbr; uint32_t realBaudrate, bestBaudrate; uint32_t diff, min_diff; uint32_t baudrate = bitsPerSec; /* for master mode configuration, if slave mode detected, return 0*/ if(!(SPI_InstanceTable[instance]->MCR & SPI_MCR_MSTR_MASK)) { return 0; } /* find combination of prescaler and scaler resulting in baudrate closest to the */ /* requested value */ min_diff = 0xFFFFFFFFU; bestPrescaler = 0; bestScaler = 0; bestDbr = 1; bestBaudrate = 0; /* required to avoid compilation warning */ /* In all for loops, if min_diff = 0, the exit for loop*/ for (prescaler = 0; (prescaler < 4) && min_diff; prescaler++) { for (scaler = 0; (scaler < 16) && min_diff; scaler++) { for (dbr = 1; (dbr < 3) && min_diff; dbr++) { realBaudrate = ((sourceClockInHz * dbr) / (s_baudratePrescaler[prescaler] * (s_baudrateScaler[scaler]))); /* calculate the baud rate difference based on the conditional statement*/ /* that states that the calculated baud rate must not exceed the desired baud rate*/ if (baudrate >= realBaudrate) { diff = baudrate-realBaudrate; if (min_diff > diff) { /* a better match found */ min_diff = diff; bestPrescaler = prescaler; bestScaler = scaler; bestBaudrate = realBaudrate; bestDbr = dbr; } } } } } uint32_t temp; /* write the best dbr, prescalar, and baud rate scalar to the CTAR*/ temp = SPI_InstanceTable[instance]->CTAR[whichCtar]; temp &= ~(SPI_CTAR_DBR_MASK| SPI_CTAR_PBR_MASK | SPI_CTAR_BR_MASK); if((bestDbr-1)) { temp |= SPI_CTAR_DBR_MASK|SPI_CTAR_PBR(bestPrescaler)|SPI_CTAR_BR(bestScaler); } else { temp |= SPI_CTAR_PBR(bestPrescaler)|SPI_CTAR_BR(bestScaler); } SPI_InstanceTable[instance]->CTAR[whichCtar] = temp; /* return the actual calculated baud rate*/ LIB_TRACE("bestBaudrate:%d\r\n", bestBaudrate); return bestBaudrate; }
static SPI_slave volatile test_slave = SPI_slave( Platform::spi0, {PTD, 0}, GPIOPin::MUX_ALT2, ( SPI_CTAR_FMSZ(7) | // 8-bit frames SPI_CTAR_CPOL_MASK | // Clock idle high SPI_CTAR_CPHA_MASK | // Sample following edge SPI_CTAR_PCSSCK(2) | // PCS to SCK prescaler = 5 SPI_CTAR_PASC(2) | // Same delay before end of PCS SPI_CTAR_PDT(3) | // Same delay after end of PCS SPI_CTAR_PBR(0) | // Use sysclk / 2 SPI_CTAR_CSSCK(6) | // Base delay is 128*Tsys SPI_CTAR_ASC(3) | // Unit delay before end of PCS SPI_CTAR_DT(3) | // Same after end of PCS SPI_CTAR_BR(8) // Scale by 256 ), 0 ); /*! * @brief Application entry point */ int main(){ struct pt pt_dsp, pt_controller, pt_wavegen; PT_INIT(&pt_dsp); PT_INIT(&pt_controller); PT_INIT(&pt_wavegen); // Perform late initializations
void SPI_Configuration (void) { SPI_Type *SPIx = NULL; PORT_Type *SPI_PORT = NULL; SPI_InitTypeDef SPI_InitStruct; SPI_DataMapTypeDef *pSPI_DataMap; SPI_CSMapTypeDef *pSPI_CSMap; SPI_InitStruct.SPIxDataMap = SPILCD_PORT_DATA; SPI_InitStruct.SPIxPCSMap = SPILCD_PORT_CS; SPI_InitStruct.SPI_DataSize = 16; SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; SPI_InitStruct.SPI_Mode = SPI_Mode_Master; SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge; SPI_InitStruct.SPI_CPOL = SPI_CPOL_High; SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB; //SPI_Init(&SPI_InitStruct); pSPI_CSMap = (SPI_CSMapTypeDef*)&(SPI_InitStruct.SPIxPCSMap); pSPI_DataMap = (SPI_DataMapTypeDef*)&(SPI_InitStruct.SPIxDataMap); SIM->SCGC6 |= SIM_SCGC6_SPI0_MASK; SPIx = SPI0; SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK; SPI_PORT = PORTA; SPI_PORT->PCR[pSPI_DataMap->SPI_SCK_Pin_Index] &= ~PORT_PCR_MUX_MASK; SPI_PORT->PCR[pSPI_DataMap->SPI_SIN_Pin_Index] &= ~PORT_PCR_MUX_MASK; SPI_PORT->PCR[pSPI_DataMap->SPI_SOUT_Pin_Index] &= ~PORT_PCR_MUX_MASK; SPI_PORT->PCR[pSPI_DataMap->SPI_SCK_Pin_Index] |= PORT_PCR_MUX(pSPI_DataMap->SPI_Alt_Index); SPI_PORT->PCR[pSPI_DataMap->SPI_SIN_Pin_Index] |= PORT_PCR_MUX(pSPI_DataMap->SPI_Alt_Index); SPI_PORT->PCR[pSPI_DataMap->SPI_SOUT_Pin_Index] |= PORT_PCR_MUX(pSPI_DataMap->SPI_Alt_Index); /*SCK配置开漏*/ SPI_PORT->PCR[pSPI_DataMap->SPI_SCK_Pin_Index]|= PORT_PCR_ODE_MASK; SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK; /* SPI_PORT = PORTA; SPI_PORT->PCR[pSPI_CSMap->SPI_PCS_Pin_Index] &= ~PORT_PCR_MUX_MASK; SPI_PORT->PCR[pSPI_CSMap->SPI_PCS_Pin_Index] |= PORT_PCR_MUX(pSPI_CSMap->SPI_Alt_Index);*/ //设置主从模式 (SPI_InitStruct.SPI_Mode == SPI_Mode_Master)?(SPIx->MCR |= SPI_MCR_MSTR_MASK):(SPIx->MCR &= ~SPI_MCR_MSTR_MASK); SPIx->MCR = 0 & (~SPI_MCR_MDIS_MASK) |SPI_MCR_HALT_MASK //让SPI进入停止模式 |SPI_MCR_MSTR_MASK //配置SPI为主机模式 |SPI_MCR_PCSIS_MASK //PCS为高电平当在SPI不工作的时候 |SPI_MCR_CLR_TXF_MASK //首先要清除MDIS,清除TXF_MASK和RXF_MASK |SPI_MCR_CLR_RXF_MASK |SPI_MCR_DIS_TXF_MASK //然后再禁止TXD和RXD FIFO 模式 ,将SPI配置成正常模式 |SPI_MCR_DIS_RXF_MASK |SPI_MCR_SMPL_PT(2); SPIx->CTAR[1] = 0| SPI_CTAR_DBR_MASK //设置通信的 | SPI_CTAR_PCSSCK(0) | SPI_CTAR_PASC(0) | SPI_CTAR_ASC(0) | SPI_CTAR_PBR(0) | SPI_CTAR_CSSCK(0) | SPI_CTAR_FMSZ(SPI_InitStruct.SPI_DataSize -1)//设置数据传输的位数 | SPI_CTAR_PDT(0);//设置片选信号在数据完成后的延时值 //分频设置 SPIx->CTAR[1] |=SPI_CTAR_BR(SPI_InitStruct.SPI_BaudRatePrescaler); //时钟相位设置 (SPI_InitStruct.SPI_CPHA == SPI_CPHA_1Edge)?(SPIx->CTAR[1] &= ~SPI_CTAR_CPHA_MASK):(SPIx->CTAR[1] |= SPI_CTAR_CPHA_MASK); //时钟极性 (SPI_InitStruct.SPI_CPOL == SPI_CPOL_Low)?(SPIx->CTAR[1] &= ~SPI_CTAR_CPOL_MASK):(SPIx->CTAR[1] |= SPI_CTAR_CPOL_MASK); //配置MSB或者LSD (SPI_InitStruct.SPI_FirstBit == SPI_FirstBit_MSB)?(SPIx->CTAR[1] &= ~SPI_CTAR_LSBFE_MASK):(SPIx->CTAR[1] |= SPI_CTAR_LSBFE_MASK); //清空状态 SPIx->SR = SPI_SR_EOQF_MASK //队列结束标志 w1c (write 1 to clear) | SPI_SR_TFUF_MASK //TX FIFO underflow flag w1c | SPI_SR_TFFF_MASK //TX FIFO fill flag w1c | SPI_SR_RFOF_MASK //RX FIFO overflow flag w1c | SPI_SR_RFDF_MASK //RX FIFO fill flasg w1c (0时为空) | SPI_SR_TCF_MASK; //开始传输 SPIx->MCR &= ~SPI_MCR_HALT_MASK; //开始传输,见参考手册1129页 AD7687_ReceiveWord (); NVIC_DisableIRQ (AD7687_SIN_IRQ); AD7687_SIN_PORT->PCR[AD7687_SIN_Pin]&=~PORT_PCR_IRQC_MASK; AD7687_SIN_PORT->PCR[AD7687_SIN_Pin]|=PORT_PCR_IRQC(GPIO_IT_RISING); }
/** * @brief SPI初始化 * * @param spino SPI通道号 * @param master 是否是主机 * * @return E_ID 输入序号错误 * @return E_OK 初始化正常 */ ER spi_init(uint8_t spino, uint8_t master) { if((spino < 0) || (spino > SPI_NO_GET(SPI2))) { return (E_ID); } SPI_MemMapPtr base_addr = spi_get_base_address(spino); /* 使能SPI模块时钟,配置SPI引脚功能 */ if(SPI_MOD_SET(spino) == SPI0) { SIM_SCGC6 |= SIM_SCGC6_DSPI0_MASK; /* PORT_PCR_MUX(0x2) : SPI功能 * PORT_PCR_DSE_MASK : Drive Strength Enable */ gpio_init(PORT_NO_GET(SD_CS), PIN_NO_GET(SD_CS), OUT_PUT, HIGH_POWER); /* PCS0 */ PORTA_PCR15 = 0 | PORT_PCR_MUX(0x2) | PORT_PCR_DSE_MASK; /* SCK */ PORTA_PCR16 = 0 | PORT_PCR_MUX(0x2) | PORT_PCR_DSE_MASK; /* SOUT */ PORTA_PCR17 = 0 | PORT_PCR_MUX(0x2); /* SIN */ } else if(SPI_MOD_SET(spino) == SPI1) { SIM_SCGC6 |= SIM_SCGC6_SPI1_MASK; PORTE_PCR4 = 0 | PORT_PCR_MUX(0x2) | PORT_PCR_DSE_MASK; /* PCS0 */ PORTE_PCR2 = 0 | PORT_PCR_MUX(0x2) | PORT_PCR_DSE_MASK; /* SCK */ PORTE_PCR1 = 0 | PORT_PCR_MUX(0x2) | PORT_PCR_DSE_MASK; /* SOUT */ PORTE_PCR3 = 0 | PORT_PCR_MUX(0x2); /* SIN */ } else { SIM_SCGC3 |= SIM_SCGC3_SPI2_MASK; } SPI_MCR_REG(base_addr) = 0 | SPI_MCR_CLR_TXF_MASK /* Clear the Tx FIFO counter. */ | SPI_MCR_CLR_RXF_MASK /* Clear the Rx FIFO counter. */ | SPI_MCR_HALT_MASK; /* Starts and stops DSPI transfers */ /* 根据主从机模式设置工作模式 */ if(master == MASTER) { SPI_MCR_REG(base_addr) |= SPI_MCR_MSTR_MASK; /* Master/Slave Mode Select */ SPI_CTAR_REG(base_addr,0) = 0 | SPI_CTAR_DBR_MASK /* Double Baud Rate */ | SPI_CTAR_FMSZ(0x07) /* Frame Size: 8bit */ | SPI_CTAR_PDT_MASK /* 延时因子为7 */ | SPI_CTAR_BR(0x8); /* Selects the scaler value for the baud rate. */ //| SPI_CTAR_CPOL_MASK; /* Clock Polarity */ //| SPI_CTAR_CPHA_MASK; /* Clock Phase */ } else { SPI_CTAR_SLAVE_REG(base_addr,0) = 0 | SPI_CTAR_SLAVE_FMSZ(0x07) | SPI_CTAR_SLAVE_CPOL_MASK | SPI_CTAR_SLAVE_CPHA_MASK; } SPI_SR_REG(base_addr) = SPI_SR_EOQF_MASK /* End of Queue Flag */ | SPI_SR_TFUF_MASK /* Transmit FIFO Underflow Flag */ | SPI_SR_TFFF_MASK /* Transmit FIFO Fill Flag */ | SPI_SR_RFOF_MASK /* Receive FIFO Overflow Flag */ | SPI_SR_RFDF_MASK; /* Receive FIFO Drain Flag */ SPI_MCR_REG(base_addr) &= ~SPI_MCR_HALT_MASK; /* start */ return (E_OK); }
/*FUNCTION**************************************************************** * * Function Name : _dspi_polled_ioctl * Returned Value : MQX error code * Comments : * This function performs miscellaneous services for * the SPI I/O device. * *END*********************************************************************/ uint_32 _dspi_polled_ioctl ( /* [IN] The address of the device specific information */ DSPI_INFO_STRUCT_PTR io_info_ptr, /* [IN] The command to perform */ uint_32 cmd, /* [IN] Parameters for the command */ uint_32_ptr param_ptr, /* [IN] Opening flags */ uint_32 flags ) { SPI_MemMapPtr dspi_ptr; SPI_CS_CALLBACK_STRUCT_PTR callbacks; uint_32 val, num, size, command; uint_32 result = SPI_OK; SPI_READ_WRITE_STRUCT_PTR rw_ptr; uchar_ptr input, output; dspi_ptr = io_info_ptr->DSPI_PTR; switch (cmd) { case IO_IOCTL_SPI_GET_BAUD: if (NULL == param_ptr) { result = SPI_ERROR_INVALID_PARAMETER; } else { val = dspi_ptr->CTAR[0]; val = BAUDRATE_PRESCALER[SPI_CTAR_PBR_GET(val)] * BAUDRATE_SCALER[SPI_CTAR_BR_GET(val)]; *param_ptr = (uint_32)((io_info_ptr->INIT.CLOCK_SPEED) / val); } break; case IO_IOCTL_SPI_SET_BAUD: if (NULL == param_ptr) { result = SPI_ERROR_INVALID_PARAMETER; } else if (0 == (*param_ptr)) { result = SPI_ERROR_BAUD_RATE_INVALID; } else { val = _dspi_find_baudrate (io_info_ptr->INIT.CLOCK_SPEED, *param_ptr); /* Disable SPI module */ dspi_ptr->MCR |= SPI_MCR_HALT_MASK; /* Set the frequency divider */ dspi_ptr->CTAR[0] &= (~ (SPI_CTAR_PBR(0x0F) | SPI_CTAR_BR(0x0F))); dspi_ptr->CTAR[0] |= val; /* Enable SPI module */ dspi_ptr->MCR &= (~ SPI_MCR_HALT_MASK); } break; case IO_IOCTL_SPI_DEVICE_DISABLE: dspi_ptr->MCR |= SPI_MCR_HALT_MASK; break; case IO_IOCTL_SPI_DEVICE_ENABLE: dspi_ptr->MCR &= (~ SPI_MCR_HALT_MASK); break; case IO_IOCTL_SPI_GET_MODE: if (NULL == param_ptr) { result = SPI_ERROR_INVALID_PARAMETER; } else { if (dspi_ptr->CTAR[0] & SPI_CTAR_CPOL_MASK) { if (dspi_ptr->CTAR[0] & SPI_CTAR_CPHA_MASK) { *param_ptr = SPI_CLK_POL_PHA_MODE3; } else { *param_ptr = SPI_CLK_POL_PHA_MODE2; } } else { if (dspi_ptr->CTAR[0] & SPI_CTAR_CPHA_MASK) { *param_ptr = SPI_CLK_POL_PHA_MODE1; } else { *param_ptr = SPI_CLK_POL_PHA_MODE0; } } } break; case IO_IOCTL_SPI_SET_MODE: if (NULL == param_ptr) { result = SPI_ERROR_INVALID_PARAMETER; } else { /* Disable SPI module */ dspi_ptr->MCR |= SPI_MCR_HALT_MASK; switch (*param_ptr) { case (SPI_CLK_POL_PHA_MODE0): /* Inactive state of SPI_CLK = logic 0 */ dspi_ptr->CTAR[0] &= (~ SPI_CTAR_CPOL_MASK); /* SPI_CLK transitions middle of bit timing */ dspi_ptr->CTAR[0] &= (~ SPI_CTAR_CPHA_MASK); break; case (SPI_CLK_POL_PHA_MODE1): /* Inactive state of SPI_CLK = logic 0 */ dspi_ptr->CTAR[0] &= (~ SPI_CTAR_CPOL_MASK); /* SPI_CLK transitions begining of bit timing */ dspi_ptr->CTAR[0] |= SPI_CTAR_CPHA_MASK; break; case (SPI_CLK_POL_PHA_MODE2): /* Inactive state of SPI_CLK = logic 1 */ dspi_ptr->CTAR[0] |= SPI_CTAR_CPOL_MASK; /* SPI_CLK transitions middle of bit timing */ dspi_ptr->CTAR[0] &= (~ SPI_CTAR_CPHA_MASK); break; case (SPI_CLK_POL_PHA_MODE3): /* Inactive state of SPI_CLK = logic 1 */ dspi_ptr->CTAR[0] |= SPI_CTAR_CPOL_MASK; /* SPI_CLK transitions begining of bit timing */ dspi_ptr->CTAR[0] |= SPI_CTAR_CPHA_MASK; break; default: result = SPI_ERROR_MODE_INVALID; break; } /* Enable SPI module */ dspi_ptr->MCR &= (~ SPI_MCR_HALT_MASK); } break; case IO_IOCTL_SPI_GET_TRANSFER_MODE: if (NULL == param_ptr) { result = SPI_ERROR_INVALID_PARAMETER; } else { if (dspi_ptr->MCR & SPI_MCR_MSTR_MASK) { *param_ptr = SPI_DEVICE_MASTER_MODE; } else { *param_ptr = SPI_DEVICE_SLAVE_MODE; } } break; case IO_IOCTL_SPI_SET_TRANSFER_MODE: if (NULL == param_ptr) { result = SPI_ERROR_INVALID_PARAMETER; } else { /* Disable SPI module */ dspi_ptr->MCR |= SPI_MCR_HALT_MASK; /* Set transfer mode */ if (*param_ptr == SPI_DEVICE_SLAVE_MODE) { dspi_ptr->MCR &= (~ SPI_MCR_MSTR_MASK); } else if (*param_ptr == SPI_DEVICE_MASTER_MODE) { dspi_ptr->MCR |= SPI_MCR_MSTR_MASK; } else { result = SPI_ERROR_TRANSFER_MODE_INVALID; } /* Enable SPI module */ dspi_ptr->MCR &= (~ SPI_MCR_HALT_MASK); } break; case IO_IOCTL_SPI_GET_ENDIAN: if (NULL == param_ptr) { result = SPI_ERROR_INVALID_PARAMETER; } else if (dspi_ptr->CTAR[0] & SPI_CTAR_LSBFE_MASK) { *param_ptr = SPI_DEVICE_LITTLE_ENDIAN; } else { *param_ptr = SPI_DEVICE_BIG_ENDIAN; } break; case IO_IOCTL_SPI_SET_ENDIAN: if (NULL == param_ptr) { result = SPI_ERROR_INVALID_PARAMETER; } else if (! (dspi_ptr->MCR & SPI_MCR_MSTR_MASK)) { result = SPI_ERROR_ENDIAN_INVALID; } else if (*param_ptr == SPI_DEVICE_LITTLE_ENDIAN) { dspi_ptr->CTAR[0] |= SPI_CTAR_LSBFE_MASK; } else if (*param_ptr == SPI_DEVICE_BIG_ENDIAN) { dspi_ptr->CTAR[0] &= (~ SPI_CTAR_LSBFE_MASK); } else { result = SPI_ERROR_ENDIAN_INVALID; } break; case IO_IOCTL_SPI_GET_STATS: if (NULL == param_ptr) { result = SPI_ERROR_INVALID_PARAMETER; } else { *((SPI_STATISTICS_STRUCT_PTR)param_ptr) = io_info_ptr->STATS; } break; case IO_IOCTL_SPI_CLEAR_STATS: io_info_ptr->STATS.INTERRUPTS = 0; io_info_ptr->STATS.RX_PACKETS = 0; io_info_ptr->STATS.RX_OVERFLOWS = 0; io_info_ptr->STATS.TX_PACKETS = 0; io_info_ptr->STATS.TX_ABORTS = 0; io_info_ptr->STATS.TX_UNDERFLOWS= 0; break; case IO_IOCTL_FLUSH_OUTPUT: case IO_IOCTL_SPI_FLUSH_DEASSERT_CS: while ((0 != io_info_ptr->RECEIVING) || (0 != io_info_ptr->ONTHEWAY) || (dspi_ptr->RSER & SPI_RSER_TFFF_RE_MASK)) {}; // waiting for completion if ((0 == (flags & SPI_FLAG_NO_DEASSERT_ON_FLUSH)) || (IO_IOCTL_SPI_FLUSH_DEASSERT_CS == cmd)) { /* Deassert all chip selects */ if (dspi_ptr->MCR & SPI_MCR_MSTR_MASK) { for (num = 0; num < DSPI_CS_COUNT; num++) { if ((NULL != io_info_ptr->CS_CALLBACK[num]) && (0 != (io_info_ptr->CS_ACTIVE & (1 << num)))) { io_info_ptr->CS_CALLBACK[num] (SPI_PUSHR_PCS(1 << num), 1, io_info_ptr->CS_USERDATA[num]); } } io_info_ptr->CS_ACTIVE = 0; dspi_ptr->RSER &= (~ SPI_RSER_RFDF_RE_MASK); val = (uint_32)-1; _dspi_polled_tx_rx (io_info_ptr, (uchar_ptr)&val, TRUE, 0); dspi_ptr->RSER |= SPI_RSER_RFDF_RE_MASK; } } break; case IO_IOCTL_SPI_GET_FRAMESIZE: if (NULL == param_ptr) { result = SPI_ERROR_INVALID_PARAMETER; } else { *param_ptr = SPI_CTAR_FMSZ_GET(dspi_ptr->CTAR[0]) + 1; } break; case IO_IOCTL_SPI_SET_FRAMESIZE: if (NULL == param_ptr) { result = SPI_ERROR_INVALID_PARAMETER; } else { /* Disable SPI module */ dspi_ptr->MCR |= SPI_MCR_HALT_MASK; dspi_ptr->CTAR[0] &= (~ (SPI_CTAR_FMSZ(0x0F))); dspi_ptr->CTAR[0] |= SPI_CTAR_FMSZ(*param_ptr - 1); /* Enable SPI module */ dspi_ptr->MCR &= (~ SPI_MCR_HALT_MASK); } break; case IO_IOCTL_SPI_GET_CS: if (NULL == param_ptr) { result = SPI_ERROR_INVALID_PARAMETER; } else { *param_ptr = SPI_PUSHR_PCS(io_info_ptr->CS); } break; case IO_IOCTL_SPI_SET_CS: if (NULL == param_ptr) { result = SPI_ERROR_INVALID_PARAMETER; } else { io_info_ptr->CS = SPI_PUSHR_PCS_GET(*param_ptr); } break; case IO_IOCTL_SPI_ENABLE_MODF: result = MQX_IO_OPERATION_NOT_AVAILABLE; break; case IO_IOCTL_SPI_DISABLE_MODF: break; case IO_IOCTL_SPI_SET_CS_CALLBACK: if (NULL == param_ptr) { result = SPI_ERROR_INVALID_PARAMETER; } else { callbacks = (SPI_CS_CALLBACK_STRUCT_PTR)(param_ptr); for (num = 0; num < DSPI_CS_COUNT; num++) { if (0 != (callbacks->MASK & (SPI_PUSHR_PCS(1 << num)))) { io_info_ptr->CS_CALLBACK[num] = callbacks->CALLBACK; io_info_ptr->CS_USERDATA[num] = callbacks->USERDATA; } } } break; case IO_IOCTL_SPI_READ_WRITE: if (NULL == param_ptr) { result = SPI_ERROR_INVALID_PARAMETER; } else { rw_ptr = (SPI_READ_WRITE_STRUCT_PTR)param_ptr; command = SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS(io_info_ptr->CS); size = rw_ptr->BUFFER_LENGTH; input = (uchar_ptr)rw_ptr->WRITE_BUFFER; output = (uchar_ptr)rw_ptr->READ_BUFFER; for (num = 0; num < size; num++) { val = _dspi_polled_tx_rx (io_info_ptr, input, TRUE, command); if (SPI_CTAR_FMSZ_GET(dspi_ptr->CTAR[0]) > 7) { output[0] = (uint_8)(val >> 8); output++; input++; } output[0] = (uint_8)val; output++; input++; io_info_ptr->STATS.RX_PACKETS++; io_info_ptr->STATS.TX_PACKETS++; } } break; case IO_IOCTL_SPI_KEEP_QSPI_CS_ACTIVE: result = MQX_IO_OPERATION_NOT_AVAILABLE; break; default: result = IO_ERROR_INVALID_IOCTL_CMD; break; }
void Spi::set_baudrate (Division d) { s_ctar [ctar_]->br = (uint8_t) d; SPI0_CTAR(ctar_) &= ~ SPI_CTAR_BR(0x0F); SPI0_CTAR(ctar_) |= SPI_CTAR_BR (d); }
int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed) { SPI_Type *spi_dev; uint8_t br_prescaler = 0xff; uint8_t br_scaler = 0xff; uint8_t prescaler_tmp = 0xff; uint8_t scaler_tmp = 0xff; uint32_t ctas = 0; uint32_t ctar = 0; uint32_t br_desired; uint32_t module_clock; uint32_t tcsc_freq; uint32_t tasc_freq; uint32_t tdt_freq; switch (speed) { case SPI_SPEED_100KHZ: br_desired = 100000; break; case SPI_SPEED_400KHZ: br_desired = 400000; break; case SPI_SPEED_1MHZ: br_desired = 1000000; break; case SPI_SPEED_5MHZ: br_desired = 5000000; break; case SPI_SPEED_10MHZ: br_desired = 10000000; break; default: return -2; } switch (dev) { #if SPI_0_EN case SPI_0: KINETIS_CFG_SPI_IO(0); break; #endif /* SPI_0_EN */ #if SPI_1_EN case SPI_1: KINETIS_CFG_SPI_IO(1); break; #endif /* SPI_1_EN */ #if SPI_2_EN case SPI_2: KINETIS_CFG_SPI_IO(2); break; #endif /* SPI_2_EN */ #if SPI_3_EN case SPI_3: KINETIS_CFG_SPI_IO(3); break; #endif /* SPI_3_EN */ #if SPI_4_EN case SPI_4: KINETIS_CFG_SPI_IO(4); break; #endif /* SPI_4_EN */ #if SPI_5_EN case SPI_5: KINETIS_CFG_SPI_IO(5); break; #endif /* SPI_5_EN */ #if SPI_6_EN case SPI_6: KINETIS_CFG_SPI_IO(6); break; #endif /* SPI_6_EN */ #if SPI_7_EN case SPI_7: KINETIS_CFG_SPI_IO(7); break; #endif /* SPI_7_EN */ default: return -1; } /* Find baud rate scaler and prescaler settings */ if (find_closest_baudrate_scalers(module_clock, br_desired, &br_prescaler, &br_scaler) < 0) { /* Desired baud rate is too low to be reachable at current module clock frequency. */ return -2; } ctar |= SPI_CTAR_PBR(br_prescaler) | SPI_CTAR_BR(br_scaler); /* Find the other delay divisors */ /* tCSC */ if (tcsc_freq == 0) { /* Default to same as baud rate if set to zero. */ tcsc_freq = br_desired; } if (find_closest_delay_scalers(module_clock, tcsc_freq, &prescaler_tmp, &scaler_tmp) < 0) { /* failed to find a solution */ return -2; } ctar |= SPI_CTAR_PCSSCK(prescaler_tmp) | SPI_CTAR_CSSCK(scaler_tmp); /* tASC */ if (tasc_freq == 0) { /* Default to same as baud rate if set to zero. */ tasc_freq = br_desired; } if (find_closest_delay_scalers(module_clock, tasc_freq, &prescaler_tmp, &scaler_tmp) < 0) { /* failed to find a solution */ return -2; } ctar |= SPI_CTAR_PASC(prescaler_tmp) | SPI_CTAR_ASC(scaler_tmp); /* tDT */ if (tdt_freq == 0) { /* Default to same as baud rate if set to zero. */ tdt_freq = br_desired; } if (find_closest_delay_scalers(module_clock, tdt_freq, &prescaler_tmp, &scaler_tmp) < 0) { /* failed to find a solution */ return -2; } ctar |= SPI_CTAR_PDT(prescaler_tmp) | SPI_CTAR_DT(scaler_tmp); /* Set clock polarity and phase. */ switch (conf) { case SPI_CONF_FIRST_RISING: break; case SPI_CONF_SECOND_RISING: ctar |= SPI_CTAR_CPHA_MASK; break; case SPI_CONF_FIRST_FALLING: ctar |= SPI_CTAR_CPOL_MASK; break; case SPI_CONF_SECOND_FALLING: ctar |= SPI_CTAR_CPHA_MASK | SPI_CTAR_CPOL_MASK; break; default: return -2; } /* Update CTAR register with new timing settings, 8-bit frame size. */ spi_dev->CTAR[ctas] = SPI_CTAR_FMSZ(7) | ctar; /* enable SPI */ spi_dev->MCR = SPI_MCR_MSTR_MASK | SPI_MCR_DOZE_MASK | SPI_MCR_CLR_TXF_MASK | SPI_MCR_CLR_RXF_MASK; if (KINETIS_SPI_USE_HW_CS) { spi_dev->MCR |= SPI_MCR_PCSIS(1); } spi_dev->RSER = (uint32_t)0; return 0; }
ctar0Value = ctar0; ctar1Value = ctar1; // Configure SPI (void)spi_setSpeed(0); SPI0->MCR = SPI_MCR_CLR_RXF_MASK|SPI_MCR_ROOE_MASK|SPI_MCR_CLR_TXF_MASK|SPI_MCR_PCSIS((1<<0)|(1<<1))| SPI_MCR_MSTR_MASK|SPI_MCR_FRZ_MASK|SPI_MCR_DCONF(0)|SPI_MCR_SMPL_PT(0); } typedef struct { uint32_t freq; uint32_t ctarBaud; } Scidata; static const Scidata spiBaudTable[] = { // freq(kHz) ctarBaud /* 0 */ {12000, SPI_CTAR_PBR(0)|SPI_CTAR_BR(0)|SPI_CTAR_PCSSCK(0)|SPI_CTAR_CSSCK(0)}, /* 1 */ { 8000, SPI_CTAR_PBR(1)|SPI_CTAR_BR(0)|SPI_CTAR_PCSSCK(0)|SPI_CTAR_CSSCK(1)}, /* 2 */ { 6000, SPI_CTAR_PBR(0)|SPI_CTAR_BR(1)|SPI_CTAR_PCSSCK(0)|SPI_CTAR_CSSCK(1)}, /* 3 */ { 4800, SPI_CTAR_PBR(2)|SPI_CTAR_BR(0)|SPI_CTAR_PCSSCK(1)|SPI_CTAR_CSSCK(0)}, /* 4 */ { 4000, SPI_CTAR_PBR(1)|SPI_CTAR_BR(1)|SPI_CTAR_PCSSCK(1)|SPI_CTAR_CSSCK(0)}, /* 5 */ { 3000, SPI_CTAR_PBR(0)|SPI_CTAR_BR(3)|SPI_CTAR_PCSSCK(0)|SPI_CTAR_CSSCK(2)}, /* 6 */ { 2667, SPI_CTAR_PBR(1)|SPI_CTAR_BR(2)|SPI_CTAR_PCSSCK(2)|SPI_CTAR_CSSCK(0)}, /* 7 */ { 2400, SPI_CTAR_PBR(2)|SPI_CTAR_BR(1)|SPI_CTAR_PCSSCK(2)|SPI_CTAR_CSSCK(0)}, /* 8 */ { 2000, SPI_CTAR_PBR(1)|SPI_CTAR_BR(3)|SPI_CTAR_PCSSCK(1)|SPI_CTAR_CSSCK(1)}, /* 9 */ { 1500, SPI_CTAR_PBR(0)|SPI_CTAR_BR(4)|SPI_CTAR_PCSSCK(0)|SPI_CTAR_CSSCK(3)}, /* 10 */ { 1200, SPI_CTAR_PBR(2)|SPI_CTAR_BR(3)|SPI_CTAR_PCSSCK(2)|SPI_CTAR_CSSCK(1)}, /* 11 */ { 1000, SPI_CTAR_PBR(1)|SPI_CTAR_BR(4)|SPI_CTAR_PCSSCK(1)|SPI_CTAR_CSSCK(2)}, /* 12 */ { 857, SPI_CTAR_PBR(3)|SPI_CTAR_BR(3)|SPI_CTAR_PCSSCK(1)|SPI_CTAR_CSSCK(2)}, /* 13 */ { 750, SPI_CTAR_PBR(0)|SPI_CTAR_BR(5)|SPI_CTAR_PCSSCK(2)|SPI_CTAR_CSSCK(2)}, /* 14 */ { 600, SPI_CTAR_PBR(2)|SPI_CTAR_BR(4)|SPI_CTAR_PCSSCK(2)|SPI_CTAR_CSSCK(2)}, /* 15 */ { 500, SPI_CTAR_PBR(1)|SPI_CTAR_BR(5)|SPI_CTAR_PCSSCK(1)|SPI_CTAR_CSSCK(3)},
/* ===================================================================*/ LDD_TDeviceData* SPI_SD_Init(LDD_TUserData *UserDataPtr) { /* Allocate LDD device structure */ SPI_SD_TDeviceDataPtr DeviceDataPrv; /* {Default RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; DeviceDataPrv->UserData = UserDataPtr; /* Store the RTOS device structure */ /* Interrupt vector(s) allocation */ /* {Default RTOS Adapter} Set interrupt vector: IVT is static, ISR parameter is passed by the global variable */ INT_SPI1__DEFAULT_RTOS_ISRPARAM = DeviceDataPrv; DeviceDataPrv->TxCommand = 0x80000000U; /* Initialization of current Tx command */ DeviceDataPrv->ErrFlag = 0x00U; /* Clear error flags */ /* Clear the receive counters and pointer */ DeviceDataPrv->InpRecvDataNum = 0x00U; /* Clear the counter of received characters */ DeviceDataPrv->InpDataNumReq = 0x00U; /* Clear the counter of characters to receive by ReceiveBlock() */ DeviceDataPrv->InpDataPtr = NULL; /* Clear the buffer pointer for received characters */ /* Clear the transmit counters and pointer */ DeviceDataPrv->OutSentDataNum = 0x00U; /* Clear the counter of sent characters */ DeviceDataPrv->OutDataNumReq = 0x00U; /* Clear the counter of characters to be send by SendBlock() */ DeviceDataPrv->OutDataPtr = NULL; /* Clear the buffer pointer for data to be transmitted */ DeviceDataPrv->CurrentAttributeSet = 0U; /* Init current attribute set */ DeviceDataPrv->SerFlag = 0x00U; /* Reset flags */ /* SIM_SCGC6: SPI1=1 */ SIM_SCGC6 |= SIM_SCGC6_SPI1_MASK; /* Interrupt vector(s) priority setting */ /* NVICIP27: PRI27=0x70 */ NVICIP27 = NVIC_IP_PRI27(0x70); /* NVICISER0: SETENA|=0x08000000 */ NVICISER0 |= NVIC_ISER_SETENA(0x08000000); /* SIM_SCGC5: PORTD=1 */ SIM_SCGC5 |= SIM_SCGC5_PORTD_MASK; /* PORTD_PCR7: ISF=0,MUX=7 */ PORTD_PCR7 = (uint32_t)((PORTD_PCR7 & (uint32_t)~(uint32_t)( PORT_PCR_ISF_MASK )) | (uint32_t)( PORT_PCR_MUX(0x07) )); /* PORTD_PCR6: ISF=0,MUX=7 */ PORTD_PCR6 = (uint32_t)((PORTD_PCR6 & (uint32_t)~(uint32_t)( PORT_PCR_ISF_MASK )) | (uint32_t)( PORT_PCR_MUX(0x07) )); /* PORTD_PCR5: ISF=0,MUX=7 */ PORTD_PCR5 = (uint32_t)((PORTD_PCR5 & (uint32_t)~(uint32_t)( PORT_PCR_ISF_MASK )) | (uint32_t)( PORT_PCR_MUX(0x07) )); /* SPI1_MCR: MSTR=0,CONT_SCKE=0,DCONF=0,FRZ=0,MTFE=0,PCSSE=0,ROOE=1,??=0,??=0,PCSIS=0,DOZE=0,MDIS=0,DIS_TXF=0,DIS_RXF=0,CLR_TXF=0,CLR_RXF=0,SMPL_PT=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,HALT=1 */ SPI1_MCR = SPI_MCR_DCONF(0x00) | SPI_MCR_ROOE_MASK | SPI_MCR_PCSIS(0x00) | SPI_MCR_SMPL_PT(0x00) | SPI_MCR_HALT_MASK; /* Set Configuration register */ /* SPI1_MCR: MSTR=1,CONT_SCKE=0,DCONF=0,FRZ=0,MTFE=0,PCSSE=0,ROOE=1,??=0,??=0,PCSIS=0,DOZE=0,MDIS=0,DIS_TXF=1,DIS_RXF=1,CLR_TXF=1,CLR_RXF=1,SMPL_PT=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,HALT=1 */ SPI1_MCR = SPI_MCR_MSTR_MASK | SPI_MCR_DCONF(0x00) | SPI_MCR_ROOE_MASK | SPI_MCR_PCSIS(0x00) | SPI_MCR_DIS_TXF_MASK | SPI_MCR_DIS_RXF_MASK | SPI_MCR_CLR_TXF_MASK | SPI_MCR_CLR_RXF_MASK | SPI_MCR_SMPL_PT(0x00) | SPI_MCR_HALT_MASK; /* Set Configuration register */ /* SPI1_CTAR0: DBR=1,FMSZ=7,CPOL=0,CPHA=0,LSBFE=0,PCSSCK=0,PASC=0,PDT=0,PBR=0,CSSCK=0,ASC=0,DT=0,BR=0 */ SPI1_CTAR0 = SPI_CTAR_DBR_MASK | SPI_CTAR_FMSZ(0x07) | SPI_CTAR_PCSSCK(0x00) | SPI_CTAR_PASC(0x00) | SPI_CTAR_PDT(0x00) | SPI_CTAR_PBR(0x00) | SPI_CTAR_CSSCK(0x00) | SPI_CTAR_ASC(0x00) | SPI_CTAR_DT(0x00) | SPI_CTAR_BR(0x00); /* Set Clock and Transfer Attributes register */ /* SPI1_SR: TCF=1,TXRXS=0,??=0,EOQF=1,TFUF=1,??=0,TFFF=1,??=0,??=0,??=0,??=1,??=0,RFOF=1,??=0,RFDF=1,??=0,TXCTR=0,TXNXTPTR=0,RXCTR=0,POPNXTPTR=0 */ SPI1_SR = SPI_SR_TCF_MASK | SPI_SR_EOQF_MASK | SPI_SR_TFUF_MASK | SPI_SR_TFFF_MASK | SPI_SR_RFOF_MASK | SPI_SR_RFDF_MASK | SPI_SR_TXCTR(0x00) | SPI_SR_TXNXTPTR(0x00) | SPI_SR_RXCTR(0x00) | SPI_SR_POPNXTPTR(0x00) | 0x00200000U; /* Clear flags */ /* SPI1_RSER: TCF_RE=0,??=0,??=0,EOQF_RE=0,TFUF_RE=0,??=0,TFFF_RE=0,TFFF_DIRS=0,??=0,??=0,??=0,??=0,RFOF_RE=0,??=0,RFDF_RE=1,RFDF_DIRS=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ SPI1_RSER = SPI_RSER_RFDF_RE_MASK; /* Set DMA Interrupt Request Select and Enable register */ SPI_SD_SetClockConfiguration(DeviceDataPrv, Cpu_GetClockConfiguration()); /* Set Initial according speed CPU mode */ /* Registration of the device structure */ PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_SPI_SD_ID,DeviceDataPrv); return ((LDD_TDeviceData *)DeviceDataPrv); /* Return pointer to the data data structure */ }
/*********************************************************************************************** 功能:SPI 初始化 形参:SPI_InitStruct SPI 初始化结构 返回:0 详解:0 ************************************************************************************************/ void SPI_Init(SPI_InitTypeDef* SPI_InitStruct) { SPI_Type *SPIx = NULL; PORT_Type *SPI_PORT = NULL; SPI_DataMapTypeDef *pSPI_DataMap = (SPI_DataMapTypeDef*)&(SPI_InitStruct->SPIxDataMap); SPI_CSMapTypeDef *pSPI_CSMap = (SPI_CSMapTypeDef*)&(SPI_InitStruct->SPIxPCSMap); //参数检测 assert_param(IS_SPI_DATA_CHL(SPI_InitStruct->SPIxDataMap)); assert_param(IS_SPI_PCS_CHL(SPI_InitStruct->SPIxPCSMap)); assert_param(IS_SPI_BAUDRATE(SPI_InitStruct->SPI_BaudRatePrescaler)); assert_param(IS_SPI_MODE(SPI_InitStruct->SPI_Mode)); assert_param(IS_SPI_CPHA(SPI_InitStruct->SPI_CPHA)); assert_param(IS_SPI_CPOL(SPI_InitStruct->SPI_CPOL)); assert_param(IS_SPI_FIRSTBIT(SPI_InitStruct->SPI_FirstBit)); //找出SPI模块 开SPI模块时钟 switch(pSPI_DataMap->SPI_Index) { case 0: SIM->SCGC6 |= SIM_SCGC6_SPI0_MASK; SPIx = SPI0; break; case 1: SIM->SCGC6 |= SIM_SCGC6_SPI1_MASK; SPIx = SPI1; break; case 2: SIM->SCGC3 |= SIM_SCGC3_SPI2_MASK; SPIx = SPI2; break; default:break; } //找出对应的PORT switch(pSPI_DataMap->SPI_GPIO_Index) { case 0: SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK; SPI_PORT = PORTA; break; case 1: SIM->SCGC5 |= SIM_SCGC5_PORTB_MASK; SPI_PORT = PORTB; break; case 2: SIM->SCGC5 |= SIM_SCGC5_PORTC_MASK; SPI_PORT = PORTC; break; case 3: SIM->SCGC5 |= SIM_SCGC5_PORTD_MASK; SPI_PORT = PORTD; break; case 4: SIM->SCGC5 |= SIM_SCGC5_PORTE_MASK; SPI_PORT = PORTE; break; default:break; } //开启对应的引脚 SCK SOUT SIN SPI_PORT->PCR[pSPI_DataMap->SPI_SCK_Pin_Index] &= ~PORT_PCR_MUX_MASK; SPI_PORT->PCR[pSPI_DataMap->SPI_SIN_Pin_Index] &= ~PORT_PCR_MUX_MASK; SPI_PORT->PCR[pSPI_DataMap->SPI_SOUT_Pin_Index] &= ~PORT_PCR_MUX_MASK; SPI_PORT->PCR[pSPI_DataMap->SPI_SCK_Pin_Index] |= PORT_PCR_MUX(pSPI_DataMap->SPI_Alt_Index); SPI_PORT->PCR[pSPI_DataMap->SPI_SIN_Pin_Index] |= PORT_PCR_MUX(pSPI_DataMap->SPI_Alt_Index); SPI_PORT->PCR[pSPI_DataMap->SPI_SOUT_Pin_Index] |= PORT_PCR_MUX(pSPI_DataMap->SPI_Alt_Index); /*SCK配置开漏*/ SPI_PORT->PCR[pSPI_DataMap->SPI_SCK_Pin_Index]|= PORT_PCR_ODE_MASK; //配置PCS //找出对应的PORT switch(pSPI_CSMap->SPI_GPIO_Index) { case 0: SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK; SPI_PORT = PORTA; break; case 1: SIM->SCGC5 |= SIM_SCGC5_PORTB_MASK; SPI_PORT = PORTB; break; case 2: SIM->SCGC5 |= SIM_SCGC5_PORTC_MASK; SPI_PORT = PORTC; break; case 3: SIM->SCGC5 |= SIM_SCGC5_PORTD_MASK; SPI_PORT = PORTD; break; case 4: SIM->SCGC5 |= SIM_SCGC5_PORTE_MASK; SPI_PORT = PORTE; break; default:break; } SPI_PORT->PCR[pSPI_CSMap->SPI_PCS_Pin_Index] &= ~PORT_PCR_MUX_MASK; SPI_PORT->PCR[pSPI_CSMap->SPI_PCS_Pin_Index] |= PORT_PCR_MUX(pSPI_CSMap->SPI_Alt_Index); //设置主从模式 (SPI_InitStruct->SPI_Mode == SPI_Mode_Master)?(SPIx->MCR |= SPI_MCR_MSTR_MASK):(SPIx->MCR &= ~SPI_MCR_MSTR_MASK); //配置SPI主模式寄存器 SPIx->MCR = 0 & (~SPI_MCR_MDIS_MASK) |SPI_MCR_HALT_MASK //让SPI进入停止模式 |SPI_MCR_MSTR_MASK //配置SPI为主机模式 |SPI_MCR_PCSIS_MASK //PCS为高电平当在SPI不工作的时候 |SPI_MCR_CLR_TXF_MASK //首先要清除MDIS,清除TXF_MASK和RXF_MASK |SPI_MCR_CLR_RXF_MASK |SPI_MCR_DIS_TXF_MASK //然后再禁止TXD和RXD FIFO 模式 ,将SPI配置成正常模式 |SPI_MCR_DIS_RXF_MASK |SPI_MCR_SMPL_PT(2); //配置分频及波特率 SPIx->CTAR[1] = 0| SPI_CTAR_DBR_MASK //设置通信的 | SPI_CTAR_PCSSCK(0) | SPI_CTAR_PASC(0) | SPI_CTAR_PBR(0) | SPI_CTAR_CSSCK(0) | SPI_CTAR_FMSZ(SPI_InitStruct->SPI_DataSize -1) //设置数据传输的位数 | SPI_CTAR_PDT(0); //设置片选信号在数据完成后的延时值 //分频设置 SPIx->CTAR[1] |=SPI_CTAR_BR(SPI_InitStruct->SPI_BaudRatePrescaler); //时钟相位设置 (SPI_InitStruct->SPI_CPHA == SPI_CPHA_1Edge)?(SPIx->CTAR[1] &= ~SPI_CTAR_CPHA_MASK):(SPIx->CTAR[1] |= SPI_CTAR_CPHA_MASK); //时钟极性 (SPI_InitStruct->SPI_CPOL == SPI_CPOL_Low)?(SPIx->CTAR[1] &= ~SPI_CTAR_CPOL_MASK):(SPIx->CTAR[1] |= SPI_CTAR_CPOL_MASK); //配置MSB或者LSD (SPI_InitStruct->SPI_FirstBit == SPI_FirstBit_MSB)?(SPIx->CTAR[1] &= ~SPI_CTAR_LSBFE_MASK):(SPIx->CTAR[1] |= SPI_CTAR_LSBFE_MASK); //清空状态 SPIx->SR = SPI_SR_EOQF_MASK //队列结束标志 w1c (write 1 to clear) | SPI_SR_TFUF_MASK //TX FIFO underflow flag w1c | SPI_SR_TFFF_MASK //TX FIFO fill flag w1c | SPI_SR_RFOF_MASK //RX FIFO overflow flag w1c | SPI_SR_RFDF_MASK //RX FIFO fill flasg w1c (0时为空) | SPI_SR_TCF_MASK; //开始传输 SPIx->MCR &= ~SPI_MCR_HALT_MASK; //开始传输,见参考手册1129页 }
void spi_set_params(const spi_bus_t spi_num, const uint8_t ctas, const spi_config_t* config) { uint32_t ctar = 0; uint8_t br_prescaler = 0xff; uint8_t br_scaler = 0xff; uint8_t prescaler_tmp = 0xff; uint8_t scaler_tmp = 0xff; /* All of the SPI modules run on the Bus clock, see K60 Ref Manual. 3.9.4.2 SPI clocking */ /* Find the baud rate divisors */ find_closest_baudrate_scalers(SystemBusClock, config->sck_freq, &br_prescaler, &br_scaler); ctar |= SPI_CTAR_PBR(br_prescaler) | SPI_CTAR_BR(br_scaler); /* Find the other delay divisors */ /* tCSC */ if (config->tcsc_freq > 0) { if (find_closest_delay_scalers(SystemBusClock, config->tcsc_freq, &prescaler_tmp, &scaler_tmp) == 0) { ctar |= SPI_CTAR_PCSSCK(prescaler_tmp) | SPI_CTAR_CSSCK(scaler_tmp); } else { /* failed to find a solution */ DEBUGGER_BREAK(BREAK_INVALID_PARAM); } } else { /* default: copy BR scaler */ ctar |= SPI_CTAR_PCSSCK(br_prescaler) | SPI_CTAR_CSSCK(br_scaler); } /* tASC */ if (config->tasc_freq > 0) { if (find_closest_delay_scalers(SystemBusClock, config->tasc_freq, &prescaler_tmp, &scaler_tmp) == 0) { ctar |= SPI_CTAR_PASC(prescaler_tmp) | SPI_CTAR_ASC(scaler_tmp); } else { /* failed to find a solution */ DEBUGGER_BREAK(BREAK_INVALID_PARAM); } } else { /* default: copy BR scaler */ ctar |= SPI_CTAR_PASC(br_prescaler) | SPI_CTAR_ASC(br_scaler); } /* tDT */ if (config->tdt_freq > 0) { if (find_closest_delay_scalers(SystemBusClock, config->tdt_freq, &prescaler_tmp, &scaler_tmp) == 0) { ctar |= SPI_CTAR_PDT(prescaler_tmp) | SPI_CTAR_DT(scaler_tmp); } else { /* failed to find a solution */ DEBUGGER_BREAK(BREAK_INVALID_PARAM); } } else { /* default: copy BR scaler */ ctar |= SPI_CTAR_PDT(br_prescaler) | SPI_CTAR_DT(br_scaler); } /* FMSZ+1 equals the frame size */ ctar |= SPI_CTAR_FMSZ(config->frame_size - 1); if (config->cpol != 0) { ctar |= SPI_CTAR_CPOL_MASK; } if (config->cpha != 0) { ctar |= SPI_CTAR_CPHA_MASK; } SPI[spi_num]->CTAR[ctas] = ctar; spi_conf[spi_num][ctas] = config; }
uint8 LPLD_SPI_Init(SPI_InitTypeDef spi_init_structure) { SPI_MemMapPtr spix = spi_init_structure.SPI_SPIx; uint8 spi_mode = spi_init_structure.SPI_ModeSelect; uint8 sck_div = spi_init_structure.SPI_SckDivider; boolean txFIFO_enable = spi_init_structure.SPI_EnableTxFIFO; boolean rxFIFO_enable = spi_init_structure.SPI_EnableRxFIFO; //定义SPI外设中断变量 boolean tx_complete_int = spi_init_structure.SPI_TxCompleteIntEnable; boolean QueueEnd_Request_int = spi_init_structure.SPI_QueueEndIntEnable; boolean txFIFO_underflow_int = spi_init_structure.SPI_TxFIFO_UnderflowIntEnable; boolean rxFIFO_overflow_int = spi_init_structure.SPI_RxFIFO_OverflowIntEnable; boolean txFIFO_Fill_int = spi_init_structure.SPI_TxFIFO_FillIntEnable; boolean rxFIFO_Drain_int = spi_init_structure.SPI_RxFIFO_DrainIntEnable; boolean txFIFO_req = spi_init_structure.SPI_TxFIFO_RequestSelect; boolean rxFIFO_req = spi_init_structure.SPI_RxFIFO_RequestSelect; //选择SPI引脚 PortPinsEnum_Type miso_pin = spi_init_structure.SPI_MisoPin;//MISO PortPinsEnum_Type mosi_pin = spi_init_structure.SPI_MosiPin;//MOSI PortPinsEnum_Type sck_pin = spi_init_structure.SPI_SckPin; //SCK PortPinsEnum_Type pcs0_pin = spi_init_structure.SPI_Pcs0Pin;//PCS0 PortPinsEnum_Type pcs1_pin = spi_init_structure.SPI_Pcs1Pin;//PCS1 PortPinsEnum_Type pcs2_pin = spi_init_structure.SPI_Pcs2Pin;//PCS2 PortPinsEnum_Type pcs3_pin = spi_init_structure.SPI_Pcs3Pin;//PCS3 PortPinsEnum_Type pcs4_pin = spi_init_structure.SPI_Pcs4Pin;//PCS4 PortPinsEnum_Type pcs5_pin = spi_init_structure.SPI_Pcs5Pin;//PCS5 //定义中断回掉函数 SPI_ISR_CALLBACK TxComplete_isr = spi_init_structure.SPI_TxCompleteIntIsr; SPI_ISR_CALLBACK QueueEndReq_isr = spi_init_structure.SPI_QueueEndIntIsr; SPI_ISR_CALLBACK UnderflowInt_isr = spi_init_structure.SPI_TxFIFO_UnderflowIntIsr; SPI_ISR_CALLBACK OverflowInt_isr = spi_init_structure.SPI_RxFIFO_OverflowIntIsr; SPI_ISR_CALLBACK FillInt_isr = spi_init_structure.SPI_TxFIFO_FillIntIsr; SPI_ISR_CALLBACK DrainInt_isr = spi_init_structure.SPI_RxFIFO_DrainIntIsr; if (spi_mode < SPI_MODE_MASTER || spi_mode > SPI_MODE_SLAVE || sck_div > SPI_SCK_DIV_32768) return 0; //检测参数 if(spix == SPI0) { //enable DSPI0 clock SIM_SCGC6 |= SIM_SCGC6_DSPI0_MASK; //选择pcs0 //NRF24L01 pcs0_pin = PTA14 switch(pcs0_pin) { case PTA14: PORTA->PCR[14] = 0 | PORT_PCR_MUX(2) | PORT_PCR_DSE_MASK; break; case PTC4: PORTA->PCR[4] = 0 | PORT_PCR_MUX(2) | PORT_PCR_DSE_MASK; break; default: return 0; } //选择PCS1 if(pcs1_pin == PTC3) { PORTC->PCR[3] = 0 | PORT_PCR_MUX(2) | PORT_PCR_DSE_MASK; } else if (pcs1_pin == PTD4)//pcs1_pin == PTD4 { PORTD->PCR[4] = 0 | PORT_PCR_MUX(2) | PORT_PCR_DSE_MASK; } //选择PCS2 if(pcs2_pin == PTC2) { PORTC->PCR[2] = 0 | PORT_PCR_MUX(2) | PORT_PCR_DSE_MASK; } else if (pcs2_pin == PTD5)//pcs2_pin == PTD5 { PORTD->PCR[5] = 0 | PORT_PCR_MUX(2) | PORT_PCR_DSE_MASK; } //选择PCS3 if(pcs3_pin == PTC1) { PORTC->PCR[1] = 0 | PORT_PCR_MUX(2) | PORT_PCR_DSE_MASK; } else if (pcs3_pin == PTD6)//pcs3_pin == PTD6 { PORTD->PCR[6] = 0 | PORT_PCR_MUX(2) | PORT_PCR_DSE_MASK; } //选择PCS4 if(pcs4_pin == PTC0) { PORTC->PCR[0] = 0 | PORT_PCR_MUX(2) | PORT_PCR_DSE_MASK; } //选择PCS5 if(pcs5_pin == PTB23) { PORTB->PCR[23] = 0 | PORT_PCR_MUX(3) | PORT_PCR_DSE_MASK; } //选择SCK //sck_pin = PTA15 if(sck_pin == PTA15) { PORTA->PCR[15] = 0 | PORT_PCR_MUX(2) | PORT_PCR_DSE_MASK;//SCK } else if (sck_pin == PTA15)//sck_pin == PTC5 { PORTC->PCR[5] = 0 | PORT_PCR_MUX(2) | PORT_PCR_DSE_MASK;//SCK } //选择mosi //mosi_pin = PTA16 if(mosi_pin == PTA16) { PORTA->PCR[16] = 0 | PORT_PCR_MUX(2) | PORT_PCR_DSE_MASK;//SOUT } else if (mosi_pin == PTC6)//mosi_pin == PTC6 { PORTC->PCR[6] = 0 | PORT_PCR_MUX(2) | PORT_PCR_DSE_MASK;//SOUT } //选择MISO //miso_pin = PTA17 if(miso_pin == PTA17) { PORTA->PCR[17] = 0 | PORT_PCR_MUX(2); //SIN } else if (miso_pin == PTC7)//miso_pin == PTC7 { PORTC->PCR[7] = 0 | PORT_PCR_MUX(2); //SIN } } else if(spix == SPI1) { SIM_SCGC6 |= SIM_SCGC6_DSPI1_MASK; //选择PCS0 if(pcs0_pin == PTB10) { PORTB->PCR[10] = 0 | PORT_PCR_MUX(2) | PORT_PCR_DSE_MASK; } else if (pcs0_pin == PTE4)//pcs0_pin == PTE4 { PORTE->PCR[4] = 0 | PORT_PCR_MUX(2) | PORT_PCR_DSE_MASK; } //选择PCS1 if(pcs1_pin == PTB9) { PORTB->PCR[9] = 0 | PORT_PCR_MUX(2) | PORT_PCR_DSE_MASK; } else if (pcs1_pin == PTE0)//pcs1_pin == PTE0 { PORTE->PCR[0] = 0 | PORT_PCR_MUX(2) | PORT_PCR_DSE_MASK; } //选择PCS2 if(pcs2_pin == PTE5) { PORTE->PCR[5] = 0 | PORT_PCR_MUX(2) | PORT_PCR_DSE_MASK; } //选择PCS3 if(pcs3_pin == PTE6) { PORTE->PCR[6] = 0 | PORT_PCR_MUX(2) | PORT_PCR_DSE_MASK; } //选择SCK if(sck_pin == PTB11) { PORTB->PCR[11] = 0 | PORT_PCR_MUX(2) | PORT_PCR_DSE_MASK; } else if (sck_pin == PTE2)//sck_pin == PTE2 { PORTE->PCR[2] = 0 | PORT_PCR_MUX(2) | PORT_PCR_DSE_MASK;//SCK } //选择MOSI if(mosi_pin == PTB16) { PORTB->PCR[16] = 0 | PORT_PCR_MUX(2) | PORT_PCR_DSE_MASK;//SOUT } else if (mosi_pin == PTE1)//mosi_pin == PTE1 { PORTE->PCR[1] = 0 | PORT_PCR_MUX(2) | PORT_PCR_DSE_MASK;//SOUT } //选择MISO if(miso_pin == PTB17) { PORTB->PCR[17] = 0 | PORT_PCR_MUX(2); //SIN } else if (miso_pin == PTE3)//miso_pin == PTE3 { PORTE->PCR[3] = 0 | PORT_PCR_MUX(2); //SIN } } else if(spix == SPI2) { SIM_SCGC3 |= SIM_SCGC3_DSPI2_MASK; //选择PCS0 if(pcs0_pin == PTD11) { PORTD->PCR[11] = 0 | PORT_PCR_MUX(2) | PORT_PCR_DSE_MASK; } else if (pcs0_pin == PTB20)//pcs0_pin == PTB20 { PORTB->PCR[20] = 0 | PORT_PCR_MUX(2) | PORT_PCR_DSE_MASK; } //选择PCS1 if(pcs1_pin == PTD15) { PORTD->PCR[15] = 0 | PORT_PCR_MUX(2) | PORT_PCR_DSE_MASK; } //选择SCK if(sck_pin == PTD12) { PORTD->PCR[12] = 0 | PORT_PCR_MUX(2) | PORT_PCR_DSE_MASK; } else if (sck_pin == PTB21)//sck_pin == PTB21 { PORTB->PCR[21] = 0 | PORT_PCR_MUX(2) | PORT_PCR_DSE_MASK;//SCK } //选择MOSI if(mosi_pin == PTD13) { PORTD->PCR[13] = 0 | PORT_PCR_MUX(2) | PORT_PCR_DSE_MASK;//SOUT } else if (mosi_pin == PTB22)//mosi_pin == PTB22 { PORTB->PCR[22] = 0 | PORT_PCR_MUX(2) | PORT_PCR_DSE_MASK;//SOUT } //选择MISO if(miso_pin == PTD14) { PORTD->PCR[14] = 0 | PORT_PCR_MUX(2); //SIN } else if (miso_pin == PTB23)//miso_pin == PTB23 { PORTB->PCR[23] = 0 | PORT_PCR_MUX(2); //SIN } } //allow external logic to disable dspi clocks spix->MCR &= ~(SPI_MCR_MDIS_MASK); spix->MCR |= (SPI_MCR_HALT_MASK //stop transfers //PCS[5] / PCSS is used as active-low PCS strobe signal |SPI_MCR_PCSIS_MASK //clear the tx fifo count |SPI_MCR_CLR_TXF_MASK //clear the rx fifo count |SPI_MCR_CLR_RXF_MASK); //选择SPI工作模式 switch (spi_mode) { case SPI_MODE_SLAVE: spix->MCR &= ~SPI_MCR_MSTR_MASK; break; case SPI_MODE_MASTER: spix->MCR |= SPI_MCR_MSTR_MASK; break; default: return 0; } //选择使能tx FIFO if(txFIFO_enable == TRUE) { //tx fifo is enable spix->MCR &= ~SPI_MCR_DIS_TXF_MASK; } else { //tx fifo is disable spix->MCR |= SPI_MCR_DIS_TXF_MASK;//选择传统方式 } //选择使能Rx FIFO if(rxFIFO_enable == TRUE) { //rx fifo is enable spix->MCR &= ~SPI_MCR_DIS_RXF_MASK; } else { //rx fifo is disable spix->MCR |= SPI_MCR_DIS_RXF_MASK; //选择传统方式 } //选择使能发送完成中断 if(tx_complete_int == TRUE) { spix->RSER |= SPI_RSER_TCF_RE_MASK; } else { spix->RSER &= ~SPI_RSER_TCF_RE_MASK; } //选择使能发送队列结束中断 if(QueueEnd_Request_int == TRUE) { spix->RSER |=SPI_RSER_EOQF_RE_MASK; } else spix->RSER &= ~SPI_RSER_EOQF_RE_MASK; //选择使能txFIFO为空中断 if(txFIFO_underflow_int== TRUE) { spix->RSER |=SPI_RSER_TFUF_RE_MASK; } else spix->RSER &= ~SPI_RSER_TFUF_RE_MASK; //选择使能rxFIFO溢出中断 if(rxFIFO_overflow_int== TRUE) { spix->RSER |=SPI_RSER_RFOF_RE_MASK; } else { spix->RSER &= ~SPI_RSER_RFOF_RE_MASK; } //选择使能txFIFO有数据进入队列中断或者DMA请求 if(txFIFO_Fill_int== TRUE) { spix->RSER |=SPI_RSER_TFFF_RE_MASK; } else { spix->RSER &= ~SPI_RSER_TFFF_RE_MASK; } //选择使能rxFIFO非空中断或者DMA请求 if(rxFIFO_Drain_int== TRUE) { spix->RSER |=SPI_RSER_RFDF_RE_MASK; } else { spix->RSER &= ~SPI_RSER_RFDF_RE_MASK; } //选择使能txFIFO中断或者DMA请求 if(txFIFO_req == SPI_FIFO_DMAREQUEST) { spix->RSER |=SPI_RSER_TFFF_DIRS_MASK; } else { spix->RSER &= ~SPI_RSER_TFFF_DIRS_MASK; } //选择使能rxFIFO中断或者DMA请求 if(rxFIFO_req == SPI_FIFO_DMAREQUEST) { spix->RSER |= SPI_RSER_RFDF_DIRS_MASK; } else { spix->RSER &= ~SPI_RSER_RFDF_DIRS_MASK; } //添加中断回调函数 if(spix == SPI0) { if(tx_complete_int == TRUE) { SPI0_ISR[SPI_TxComplete_Int] = TxComplete_isr; } if(QueueEnd_Request_int == TRUE) { SPI0_ISR[SPI_QueueEndReq_Int] = QueueEndReq_isr; } if(txFIFO_underflow_int == TRUE) { SPI0_ISR[SPI_TxFIFO_UnderflowInt] = UnderflowInt_isr; } if(rxFIFO_overflow_int == TRUE) { SPI0_ISR[SPI_RxFIFO_OverflowInt] = OverflowInt_isr; } if(txFIFO_Fill_int == TRUE && txFIFO_req == SPI_FIFO_INTREQUEST) { SPI0_ISR[SPI_TxFIFO_FillInt] = FillInt_isr; } if(rxFIFO_Drain_int == TRUE && rxFIFO_req == SPI_FIFO_INTREQUEST) { SPI0_ISR[SPI_RxFIFO_DrainInt] = DrainInt_isr; } } else if (spix == SPI1) { if(tx_complete_int == TRUE) { SPI1_ISR[SPI_TxComplete_Int] = TxComplete_isr; } if(QueueEnd_Request_int == TRUE) { SPI1_ISR[SPI_QueueEndReq_Int] = QueueEndReq_isr; } if(txFIFO_underflow_int == TRUE) { SPI1_ISR[SPI_TxFIFO_UnderflowInt] = UnderflowInt_isr; } if(rxFIFO_overflow_int == TRUE) { SPI1_ISR[SPI_RxFIFO_OverflowInt] = OverflowInt_isr; } if(txFIFO_Fill_int == TRUE && txFIFO_req == SPI_FIFO_INTREQUEST) { SPI1_ISR[SPI_TxFIFO_FillInt] = FillInt_isr; } if(rxFIFO_Drain_int == TRUE && rxFIFO_req == SPI_FIFO_INTREQUEST) { SPI1_ISR[SPI_RxFIFO_DrainInt] = DrainInt_isr; } } else if (spix == SPI2) { if(tx_complete_int == TRUE) { SPI2_ISR[SPI_TxComplete_Int] = TxComplete_isr; } if(QueueEnd_Request_int == TRUE) { SPI2_ISR[SPI_QueueEndReq_Int] = QueueEndReq_isr; } if(txFIFO_underflow_int == TRUE) { SPI2_ISR[SPI_TxFIFO_UnderflowInt] = UnderflowInt_isr; } if(rxFIFO_overflow_int == TRUE) { SPI2_ISR[SPI_RxFIFO_OverflowInt] = OverflowInt_isr; } if(txFIFO_Fill_int == TRUE && txFIFO_req == SPI_FIFO_INTREQUEST) { SPI2_ISR[SPI_TxFIFO_FillInt] = FillInt_isr; } if(rxFIFO_Drain_int == TRUE && rxFIFO_req == SPI_FIFO_INTREQUEST) { SPI2_ISR[SPI_RxFIFO_DrainInt] = DrainInt_isr; } } /* //配置SPI CTAR寄存器,设置SPI的总线时序 //MSB first spix->CTAR[0] &= (~SPI_CTAR_LSBFE_MASK); //DBR sck double spix->CTAR[0] |= (SPI_CTAR_DBR_MASK //baud rate div = 1 |SPI_CTAR_PBR() //set date frame length = 7+1 |SPI_CTAR_FMSZ(7)); //设置SPI总线频率 //SCK总线频率 = g_bus_clock/ SCK_DIV_x spix->CTAR[0] |=SPI_CTAR_BR(sck_div); //tCSC = (1/g_bus_clock) x PCSSCK x CSSCK //tCSC = 1/50,000,000 x PCSSCK x CSSCK spix->CTAR[0] |=SPI_CTAR_PCSSCK(1); spix->CTAR[0] |=SPI_CTAR_CSSCK(1); //tDT = (1/g_bus_clock) x PDT x DT spix->CTAR[0] |=SPI_CTAR_DT(1); spix->CTAR[0] |=SPI_CTAR_PDT(1); //Config the Delay of the last edge of SCK and the negation of PCS //tASC = (1/g_bus_clock) x PASC x ASC spix->CTAR[0] |=SPI_CTAR_PASC(1); spix->CTAR[0] |=SPI_CTAR_ASC(1); */ //清除标志位 spix->SR |= (SPI_SR_RFDF_MASK |SPI_SR_RFOF_MASK |SPI_SR_TFFF_MASK |SPI_SR_TFUF_MASK |SPI_SR_TCF_MASK |SPI_SR_EOQF_MASK); spix->CTAR[0] = (0 |SPI_CTAR_PBR(0) |SPI_CTAR_PDT(0) |SPI_CTAR_BR(0) |SPI_CTAR_FMSZ(0x07)); //使能spix //enable transfers spix->MCR &=~SPI_MCR_HALT_MASK; return 1; }