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

📄 spirom.c

📁 TI公司TMS320VC5509的外设驱动程序
💻 C
字号:
/*
 *  Copyright (C) 2001, Spectrum Digital, Inc.  All Rights Reserved.
 */
 
#include "5509.h"
#include "util.h"

#define SPIROM_SIZE                0x2000 // in bytes
#define SPIROM_PAGESIZE            64
#define SPIROM_PAGES               (SPIROM_SIZE / SPIROM_PAGESIZE)
#define SPIROM_CE                  GPIO_4
#define SPIROM_OP_WREN             0x06
#define SPIROM_OP_WRDI             0x04
#define SPIROM_OP_RDSR             0x05
#define SPIROM_OP_WRSR             0x01
#define SPIROM_OP_READ             0x03
#define SPIROM_OP_WRITE            0x02
#define SPIROM_STAT_BUSY           0x01

// AIC23 Control Register addresses
#define AIC23_LT_LINE_CTL         0x00  // 0
#define AIC23_RT_LINE_CTL         0x02  // 1
#define AIC23_LT_HP_CTL           0x04  // 2
#define AIC23_RT_HP_CTL           0x06  // 3
#define AIC23_ANALOG_AUDIO_CTL    0x08  // 4
#define AIC23_DIGITAL_AUDIO_CTL   0x0A  // 5
#define AIC23_POWER_DOWN_CTL      0x0C  // 6
#define AIC23_DIGITAL_IF_FORMAT   0x0E  // 7
#define AIC23_SAMPLE_RATE_CTL     0x10  // 8
#define AIC23_DIG_IF_ACTIVATE     0x12  // 9
#define AIC23_RESET_REG           0x1E  // F - Writing 0 to this reg triggers reset


unsigned char spirom_buf[SPIROM_PAGESIZE];
unsigned short spirom_cmd[3];

void SPIROM_AssertCE()
{
    PC55XX_GPIO pGPIO = (PC55XX_GPIO)C55XX_GPIO_ADDR;

    // Configure CE for output, set low
    SetMask(pGPIO -> iodir, SPIROM_CE);
    ClearMask(pGPIO -> iodata, SPIROM_CE);
}

void SPIROM_DeassertCE()
{
    PC55XX_MCSP pMCBSP0 = (PC55XX_MCSP)C55XX_MSP0_ADDR;
    PC55XX_GPIO pGPIO = (PC55XX_GPIO)C55XX_GPIO_ADDR;

    // Wait for transmission to finish
    while (!ReadMask(pMCBSP0 -> spcr2, SPCR2_XRDY));
    SWDelayUsec(2);

    // Configure CE for output, set high
    SetMask(pGPIO -> iodir, SPIROM_CE);
    SetMask(pGPIO -> iodata, SPIROM_CE);
}


void SPIROM_Cmd(unsigned short cmd, unsigned short addr, int len)
{
    PC55XX_MCSP pMCBSP0 = (PC55XX_MCSP)C55XX_MSP0_ADDR;
    unsigned long i, dummy;
    
    // Set up command
    spirom_cmd[0] = cmd;
    spirom_cmd[1] = (addr >> 8) & 0xff;
    spirom_cmd[2] = addr & 0xff;

    // Send the command
    for (i = 0; i < len; i++)
    {
        // Wait for transmitter to become free
        while (!ReadMask(pMCBSP0 -> spcr2, SPCR2_XRDY));

        // Transmit data 
        pMCBSP0 -> dxr1 = spirom_cmd[i];
  
        // Read response
        dummy = pMCBSP0 -> ddr1;
    }
}

void SPIROM_SendData(unsigned char *buf, unsigned long len)
{
    PC55XX_MCSP pMCBSP0 = (PC55XX_MCSP)C55XX_MSP0_ADDR;
    unsigned long i;
    unsigned short dummy;
    
    for (i = 0; i < len; i++)
    {
        // Wait for transmitter to become free
        while (!ReadMask(pMCBSP0 -> spcr2, SPCR2_XRDY));

        // Transmit data 
        pMCBSP0 -> dxr1 = spirom_buf[i];
          
        // Read response
        dummy = pMCBSP0 -> ddr1;
    }    
}

void SPIROM_GetData(unsigned char *buf, unsigned short len)
{
    PC55XX_MCSP pMCBSP0 = (PC55XX_MCSP)C55XX_MSP0_ADDR;
    unsigned char bytedata;
    unsigned long i, transferlength;
    
    transferlength = len + 2;
    for (i = 0; i < transferlength; i++)
    {
        // Wait for transmitter to become free
        while (!ReadMask(pMCBSP0 -> spcr2, SPCR2_XRDY));

        // Transmit dummy value to generate sclk 
        pMCBSP0 -> dxr1 = 0;
  
        // Read response
        bytedata = pMCBSP0 -> ddr1;
        if (i > 1)
            buf[i - 2] = bytedata;
    }
}

unsigned short SPIROM_ReadStatus()
{
    unsigned char status, testbuf[16];
    
    SPIROM_AssertCE();
    SPIROM_Cmd(SPIROM_OP_RDSR, 0, 1);
    SPIROM_GetData(&status, 1);
    SPIROM_DeassertCE();
    
    return status;
}

void SPIROM_WaitUntilDone()
{
    unsigned short status;
    
    while(1)
    {
       status = SPIROM_ReadStatus();
       if (!(status & SPIROM_STAT_BUSY))
           break;
    }

//    SWDelayMsec(10);
}

unsigned short SPIROM_Read(unsigned long addr, unsigned char *buf, unsigned short len)
{
    // Read data
    SPIROM_AssertCE();
    SPIROM_Cmd(SPIROM_OP_READ, addr, 3);
    SPIROM_GetData(buf, len);
    SPIROM_DeassertCE();
    
    return 0;
}

unsigned short SPIROM_Write(unsigned long addr, unsigned char *buf, unsigned short len)
{
    //Enable writes
    SPIROM_AssertCE();
    SPIROM_Cmd(SPIROM_OP_WREN, 0x0000, 1);
    SPIROM_DeassertCE();
    
    // Write data
    SPIROM_AssertCE();
    SPIROM_Cmd(SPIROM_OP_WRITE, addr, 3);
    SPIROM_SendData(buf, len);
    SPIROM_DeassertCE();
    SPIROM_WaitUntilDone();
    
    return 0;
}

void SPIROM_Init()
{
    PC55XX_MCSP pMCBSP0 = (PC55XX_MCSP)C55XX_MSP0_ADDR;
    PC55XX_EXTBUS pExtBus = (PC55XX_EXTBUS)C55XX_EXTBUS_ADDR;
    
    // Configure serial port 0 for McBSP mode 
//    WriteField(pExtBus -> exbussel, EXBUSSEL_SPMODE_MCBSP, EXBUSSEL_SP0MODE);

    // Put the MCBSP in reset
    ClearMask(pMCBSP0 -> spcr1, SPCR1_RRST | CLKSTP_NODELAY);
    ClearMask(pMCBSP0 -> spcr2, SPCR2_XRST);
    
    // Enable clock stop mode
    WriteMask(pMCBSP0 -> spcr1, CLKSTP_NODELAY, SPCR1_CLKSTP);

    // Config TX frame parameters (8 bit, single phase, delay 0, 1 word/frame)
    Write(pMCBSP0 -> xcr1, XWDLEN1_8 | XFRLEN1_1);
    Write(pMCBSP0 -> xcr2, XPHASE_SINGLE | XDATDLY_0);

    // Config RX frame parameters (8 bit, single phase, delay 0, 1 word/frame)
    Write(pMCBSP0 -> rcr1, RWDLEN1_8 | RFRLEN1_1);
    Write(pMCBSP0 -> rcr2, RPHASE_SINGLE | RDATDLY_0);

    // Config rate generator for 2MHz divided from CPU clock
    WriteField(pMCBSP0 -> srgr1, (dspclk.freq >> 1) - 1, SRGR1_CLKGDV);
    WriteField(pMCBSP0 -> srgr1, 10, SRGR1_FWID);
    Write(pMCBSP0 -> srgr2, SRGR2_CLKSM);

    // Config pins (Master, CLKX output, TX rising CLK, RX rising CLK)   
    Write(pMCBSP0 -> pcr, PCR_FSXM | PCR_CLKXM | PCR_CLKXP);

    // Bring transmitter and receiver out of reset
    SetMask(pMCBSP0 -> spcr1, SPCR1_RRST);
    SetMask(pMCBSP0 -> spcr2, SPCR2_GRST | SPCR2_XRST);
}

unsigned short SPIROM_Test()
{
    unsigned short status;
    unsigned long addr;
    int i, j;
    
    // Initialize SPI Rom
    SPIROM_Init();
    
    // Read status
    status = SPIROM_ReadStatus();
    
    // Write pattern to all pages
    addr = 0;
    for (i = 0; i < SPIROM_PAGES; i++)
    {
        for (j = 0; j < SPIROM_PAGESIZE; j++)
            spirom_buf[j] = (i + j) & 0xff;
        SPIROM_Write(addr, spirom_buf, SPIROM_PAGESIZE);

        addr += SPIROM_PAGESIZE;
    }

    // Verify all pages
    addr = 0;
    for (i = 0; i < SPIROM_PAGES; i++)
    {
        SPIROM_Read(addr, spirom_buf, SPIROM_PAGESIZE);
        for (j = 0; j < SPIROM_PAGESIZE; j++)
            if (spirom_buf[j] != ((i + j) & 0xff))
                return ERR_SPIROM_VERIFY;
        addr += SPIROM_PAGESIZE;
    }
    
    return 0;
}

⌨️ 快捷键说明

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