⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 samspi.c

📁 S64和VS1003的MP3播放实现的源代码/
💻 C
字号:
#ifdef AT91SAM7S32
#include "AT91SAM7S32.h"
#include "lib_AT91SAM7S32.h"
#endif

#ifdef AT91SAM7S64
#include "AT91SAM7S64.h"
#include "lib_AT91SAM7S64.h"
#endif

#include "SAMspi.h"

void SAMspiSetSCBR(unsigned char ch, unsigned char baudrate)
{
	unsigned int reg = 0;
	AT91PS_SPI pSPI   = AT91C_BASE_SPI;

    ch &= 0x03; /* 0 ~ 3 */

	if ( baudrate < SPI_SCBR_MIN ) baudrate = SPI_SCBR_MIN;
	if ( baudrate > 1 ) baudrate &= 0xFE;

	reg = pSPI->SPI_CSR[ch];
	reg = ( reg & ~(AT91C_SPI_SCBR) ) | ( (unsigned long)baudrate << 8 );
	pSPI->SPI_CSR[ch] = reg;
}

void SAMspiCfgCH(unsigned char ch, unsigned int mode)
{
    unsigned int reg = 0;
	AT91PS_SPI pSPI   = AT91C_BASE_SPI;

    ch &= 0x03; /* 0 ~ 3 */
    
    reg = pSPI->SPI_CSR[ch];
    /* keep SCBR value, since it can be set in another API */
    reg &= AT91C_SPI_SCBR; /* mask all other value */

    reg |= mode;

    pSPI->SPI_CSR[ch] = reg;
}

unsigned short SAMspiSend(unsigned char ch, unsigned short data)
{
    unsigned int spib = 0;
	AT91PS_SPI pSPI   = AT91C_BASE_SPI;

    ch &= 0x0F;

    while((pSPI->SPI_SR & AT91C_SPI_TDRE) == 0);      // Wait for the transfer to complete
    pSPI->SPI_TDR = (ch << 16) | (data & 0xFFFF);                  // Send the data

    //pSPI->SPI_TDR = (data & 0xFFFF);                  // Send the data

    while((pSPI->SPI_SR & AT91C_SPI_RDRF) == 0);      // Wait until the character can be sent
    spib = ((pSPI->SPI_RDR) & 0xFFFF);                // Get the data received

    return spib;
}

/* 
  NOTE :
        ALL the /CS will be controlled by PIO, NOT SPI.
*/
void SAMspiInit(void)
{
	unsigned char i = 0;

	AT91PS_SPI pSPI      = AT91C_BASE_SPI;
	AT91PS_PIO pPIOA     = AT91C_BASE_PIOA;
	AT91PS_PMC pPMC      = AT91C_BASE_PMC;
	// AT91PS_PDC pPDC_SPI  = AT91C_BASE_PDC_SPI;

	// disable PIO from controlling MOSI, MISO, SCK (=hand over to SPI)
	// keep CS untouched - used as GPIO pin during init
	pPIOA->PIO_PDR = AT91C_PA12_MISO | AT91C_PA13_MOSI | AT91C_PA14_SPCK; //  | NCPS_PDR_BIT;
	// set pin-functions in PIO Controller
	pPIOA->PIO_ASR = AT91C_PA12_MISO | AT91C_PA13_MOSI | AT91C_PA14_SPCK; /// not here: | NCPS_ASR_BIT;
	/// not here: pPIOA->PIO_BSR = NPCS_BSR_BIT;

	// set chip-select as output high (unselect card)
	pPIOA->PIO_PER  = NPCS_ASR_BIT; // enable PIO of CS-pin
	pPIOA->PIO_SODR = NPCS_ASR_BIT; // set
	pPIOA->PIO_OER  = NPCS_ASR_BIT; // output

	pPIOA->PIO_PER  = NPCS_BSR_BIT; // enable PIO of CS-pin
	pPIOA->PIO_SODR = NPCS_BSR_BIT; // set
	pPIOA->PIO_OER  = NPCS_BSR_BIT; // output

	// enable peripheral clock for SPI ( PID Bit 5 )
	pPMC->PMC_PCER = ( (unsigned int) 1 << AT91C_ID_SPI ); // n.b. IDs are just bit-numbers

	// SPI enable and reset
	pSPI->SPI_CR = AT91C_SPI_SPIEN | AT91C_SPI_SWRST;

	// SPI mode: master, fixed periph. sel., FDIV=0, fault detection disabled
	pSPI->SPI_MR  = AT91C_SPI_MSTR | AT91C_SPI_PS_FIXED | AT91C_SPI_MODFDIS;

    // SPI mode: master, variable periph. sel., FDIV=0, fault detection disabled
    //pSPI->SPI_MR  = AT91C_SPI_MSTR | AT91C_SPI_PS_VARIABLE | AT91C_SPI_MODFDIS;

	// set PCS for fixed select
	pSPI->SPI_MR &= 0xFFF0FFFF; // lib: AT91F_SPI_CfgPCS() 
	pSPI->SPI_MR |= ((SPI_MR_PCS << 16) & AT91C_SPI_PCS ); // set PCS

	// set chip-select-register
	// 8 bits per transfer, CPOL=0, ClockPhase=0, DLYBCT = 0
	// pSPI->SPI_CSR[SPI_CSR_NUM] = AT91C_SPI_CPOL | AT91C_SPI_BITS_8;
	pSPI->SPI_CSR[SPI_CSR_NUM] = AT91C_SPI_NCPHA | AT91C_SPI_BITS_8; // ok

	// slow during init
	SAMspiSetSCBR(0, 0xFE); // ch 0
	SAMspiSetSCBR(1, 0xFE); // ch 1
	SAMspiSetSCBR(2, 0xFE); // ch 2
	SAMspiSetSCBR(3, 0xFE); // ch 3

	// enable SPI
	pSPI->SPI_CR = AT91C_SPI_SPIEN;

	/* Send 20 spi commands with card not selected */
    /* enbale PCS */
	for(i = 0; i < 21; i++)
		SAMspiSend(SPI_CSR_NUM, 0xFF);

	/* enable automatic chip-select */
	//pPIOA->PIO_ODR  = NPCS_BSR_BIT; // input
	//pPIOA->PIO_CODR = NPCS_BSR_BIT; // clear

    /* do not need SPI to control NPCS */
#if 0
	// disable PIO from controlling the CS pin (=hand over to SPI)
	pPIOA->PIO_PDR  = NPCS_PDR_BIT;

	// set pin-functions in PIO Controller
	pPIOA->PIO_ASR  = NPCS_ASR_BIT;      
	pPIOA->PIO_BSR  = NPCS_BSR_BIT;  
#endif    
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -