📄 ffsport_spi.c
字号:
/***********************************************************
* MMC/SD-interface to SPI-slot of STR71x *
* *
* by Frank Goetze - www.embedded-os.de *
************************************************************
* FFSPort_MMC.c *
* MMC/SD TO SPI PORT *
************************************************************
* - code generation Frank Goetze 09/2007 *
***********************************************************/
/***********************************************************
* !!! WARNING !!! *
* on STR71x you can not use the /SS pin of BSPIx *
* for manual /SS handling, you will get an BERR *
* (Bus Error) on next read-data after setting /SS *
* manually low. *
* using an other pin you have to set the unused *
* BSPIx /SS-pin to out-wp and driven high *
***********************************************************/
#include "../../../inc/MMC/STR71x/FFSPort_SPI.h"
/****************** constant variables ********************/
#define CPU_CRISTAL_CLK 4000000UL // processor crystal-clock in Hz
/*
************************************************************
* set max possible baudrate and return this
************************************************************
*/
U32 FFSPort_MMC_SetBR(U32 maxclk)
{
U32 s_clksrc;
U08 d;
s_clksrc = CPU_CRISTAL_CLK; // set start-clk (cristal-clk)
if(STR_PRCCU_CFR & STR_PRCCU_CFR_DIV2) s_clksrc /= 2U; // is DIV2 active
if(STR_PRCCU_CFR & STR_PRCCU_CFR_CSU_CKSEL) { // if PLL enabled
while(!(STR_PRCCU_CFR & STR_PRCCU_CFR_LOCK)); // be shure PLL is locked
switch((STR_PRCCU_PLL1CR & STR_PRCCU_PLL1CR_MX_MASK) >> 4) { // mul clk with PLL-multiplier (defined at startup)
case 0: s_clksrc *= 20U; break;
case 1: s_clksrc *= 12U; break;
case 2: s_clksrc *= 24U; break;
default:
case 3: s_clksrc *= 16U; break;
}
s_clksrc /= ((STR_PRCCU_PLL1CR & STR_PRCCU_PLL1CR_DX_MASK) + 1); // div clk with PLL-dividier (defined at startup)
} else {
if(!(STR_PRCCU_CFR & STR_PRCCU_CFR_CK2_16)) { // if no PLL in use, check the CLK2/16 use
s_clksrc /= 16U;
}
}
s_clksrc /= (1U << (STR_PRCCU_PDIVR & STR_PRCCU_PDIVR_FACT1_MASK)); // PDIV for PCLK1 (APB1)
d = 3; // div must be grater 5 and alltimes even, so we use d*2
while((maxclk < (s_clksrc / (2 * d))) && (d < 0x7F)) d++; // search lowest clk-div for SPI-speed (highest possible SPI-speed)
STR_BSPI1_CLK = 2 * d; // set SPI-div and return the used SPI-speed in Hz
return(s_clksrc / (2 * d)); // !!! since STR_BSPIx_CLK must be an even-value greater 5...
} // ... and the PCLK1 can not be greater than MCLK ...
// ... you get not really the highest possible speed !!!
/*
************************************************************
* write a char and read one back
************************************************************
*/
U08 FFSPort_MMC_Send(U08 w)
{
while(!(STR_BSPI1_CSR2 & STR_BSPI1_CSR2_TFE)); // wait up to tx-empty
STR_BSPI1_TXR = (U32)(w) << 8; // write char and send
while(!(STR_BSPI1_CSR2 & STR_BSPI1_CSR2_RFNE)); // wait up to rx-not_empty (char received)
return((U08)(STR_BSPI1_RXR >> 8)); // return received char
}
/*
************************************************************
* reinitialise the SPI-port
************************************************************
*/
U08 FFSPort_MMC_ReInit(void)
{
STR_BSPI1_CLK = 0x00FE; // master-clock dividier use at startup PCLK1 / 254
STR_BSPI1_CSR2 = 0x0001; // TX-1word-FiFo & clear-FiFo
STR_BSPI1_CSR1 = 0x0301; // RX-1word-FiFo & 8-bit & CPHA=1 & CPOL=1 & enable SPI1
STR_BSPI1_CSR1 |= 0x0002; // and at last set master
FFSPort_MMC_SetBR(400000); // set SPI-clk to max 400kHz as startup (should never be > 400kHz, says MMC)
return(0); // return actual alltimes ok.
}
/*
************************************************************
* initialise the SPI-port
************************************************************
*/
U08 FFSPort_MMC_Init(void)
{
STR_IOPORT0_PC0 |= 0x01F0; // P0.5, P0.6, alternate (SPI1) & P0.7, P0.8 manual output-pu & P0.4 as alt input-wp
STR_IOPORT0_PC1 = (STR_IOPORT0_PC1 & ~0x0180) | 0x0070;
STR_IOPORT0_PC2 = (STR_IOPORT0_PC2 & ~0x0010) | 0x01E0;
STR_IOPORT0_PD |= 0x0190; // set P0.4 (MISO-wp) & P0.8 (used /SS) & P.07 (org /SS) to high
STR_IOPORT1_PC0 |= 0x8400; // P1.10, P1.15 manual input-wp (CMOS)
STR_IOPORT1_PC1 |= 0x8400;
STR_IOPORT1_PC2 &=~0x8400;
STR_IOPORT1_PD |= 0x8400; // set P1.10 (WP-wp) & P1.15 (CD-wp) to high
return(FFSPort_MMC_ReInit());
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -