|  | 
 
 发表于 2023-5-19 15:51:21
|
显示全部楼层 
|  
 作为分割线,在迁移F28035的时候,遇到了一些困难,现在将迁移好的工程,迁移到F28034上面。
 (F28034CDD)因为在迁移的时候,会注释掉昊芯提供的驱动库中一些模块的初始化,沿用MD500E中的函数,因此在034的工程中,也需要进行处理。
 同时,由于F28034和F28035的IIC模块有些调整,需要修改f_eeprom.c中的处理函数,包括InitSetI2ca,RwEeprom,I2cIntDeal,RwI2cBus。
 为了避免混淆,F28034和F28035后面将分享不同的工程,而非通过宏来区分。
 
 修改后,可以在数码管上面显示-H-C-,闪烁一段时间后,则会报ERR07的故障。说明已经完成了功能码的初始化操作。
 
 ERR07是恒速过压故障。这可能是因为未接驱动板导致的。
 根据手册说明,ERR07有两种原因,过压抑制设定不合适或者是运行过程中存在外力拖动电机运行。
 
 
 
 复制代码//=====================================================================
//
// 读写I2C数据
//
//=====================================================================
Uint16 RwI2cBus(Uint16 mode)
{
    int16 i;
   // Wait until the STP bit is cleared from any previous master communication.
   // Clearing of this bit by the module is delayed until after the SCD bit is
   // set. If this bit is not checked prior to initiating a new message, the
   // I2C could get confused.
    if (I2caRegs.I2CMDR.bit.STP == 1)
    {
        return I2C_STP_NOT_READY_ERROR;
    }
    
// Check if bus busy
    if ((I2caRegs.I2CSTR.bit.BB == 1) && (I2cMsg.status != I2C_MSG_STATUS_RESTART))
    {
        return I2C_BUS_BUSY_ERROR;
    }
// Setup slave address
#if (EEPROM_TYPE == EEPROM_24LC32)
    I2caRegs.I2CSAR = I2C_SLAVE_ADDR;
#elif 1
    I2caRegs.I2CSAR = (I2C_SLAVE_ADDR | (I2cMsg.highAddr >> 8)) & 0xff;
#endif    
    if (mode == RW_I2C_BUS_WRITE)
    {
        // Setup number of bytes to send
        // buffer + Address
#if (EEPROM_TYPE == EEPROM_24LC32)
        I2caRegs.I2CCNT = I2cMsg.bytes + 2;
#elif 1
        I2caRegs.I2CCNT = I2cMsg.bytes + 1;
#endif
        I2caRegs.I2CDXR = I2cMsg.highAddr; // Setup data to send
#if (EEPROM_TYPE == EEPROM_24LC32)
        I2caRegs.I2CDXR = I2cMsg.lowAddr;
#endif
        for (i = 0; i < I2cMsg.bytes; i++)
        {
            I2caRegs.I2CDXR = I2cMsg.buffer[i];
        }
#ifdef  DSC28034_CDD
       //20211221 H
           I2caRegs.I2CMDR.bit.MST = 1;
           I2caRegs.I2CMDR.bit.TRX = 1;
           I2caRegs.I2CMDR.bit.STT = 1;
           asm volatile (" NOP ");
           I2caRegs.I2CMDR.all = 0x4E20;
#else
        // Send start as master transmitter
        I2caRegs.I2CMDR.all = 0x6E20;   // S.A.D.P
#endif
    }
    else if ((mode == RW_I2C_BUS_READ) && (I2C_MSG_STATUS_RESTART == I2cMsg.status) )
    {
        I2caRegs.I2CCNT = I2cMsg.bytes; // Setup how many bytes to expect
#ifdef  DSC28034_CDD
        //20211221 H
                I2caRegs.I2CMDR.bit.MST = 1;
                I2caRegs.I2CMDR.bit.TRX = 0;
                I2caRegs.I2CMDR.bit.STT = 1;
                asm volatile (" NOP ");
                I2caRegs.I2CMDR.all = 0x4C20;                // Send restart as master receiver
#else
        I2caRegs.I2CMDR.all = 0x6C20;   // Send restart as master receiver
#endif
                                        // S.A.D.P
    }
    else                                        // ACK, or start read
    {
#if (EEPROM_TYPE == EEPROM_24LC32)
        I2caRegs.I2CCNT = 2;
        I2caRegs.I2CDXR = I2cMsg.highAddr;
        I2caRegs.I2CDXR = I2cMsg.lowAddr;
#elif 1
        I2caRegs.I2CCNT = 1;
        I2caRegs.I2CDXR = I2cMsg.highAddr;
#endif
        
        I2caRegs.I2CMDR.all = 0x6620;   // Send data to setup EEPROM address
                                        // S.A.D
    }
    return I2C_SUCCESS;
}
//=====================================================================
//
// I2C总线状态处理
//
//=====================================================================
LOCALF void I2cIntDeal(void)
{
    Uint16 IntSource;
        Uint16 IntNack = 0;
// Read interrupt source
#ifdef  DSC28034_CDD
    while(1)
    {
    IntSource = I2caRegs.I2CISRC.all;
            if (IntSource == I2C_NO_ISRC) break;
            else if(IntSource == I2C_NACK_ISRC)
            {
                    IntNack = 1;
            }
            else if (IntSource == I2C_ARDY_ISRC) break;
            else if (IntSource == I2C_SCD_ISRC) break;
    }
    if ( (IntSource == I2C_NO_ISRC) && (IntNack == 0) )    // 没有中断标志,返回
        return;
#else
     IntSource = I2caRegs.I2CISRC.all;
    if (IntSource == I2C_NO_ISRC)   // 没有中断标志,返回
        return;
#endif
    if (IntSource == I2C_SCD_ISRC)   // Interrupt source = stop condition detected
    {
            I2caRegs.I2CSTR.all = I2C_CLR_SCD_BIT;
        if (I2cMsg.status == I2C_MSG_STATUS_WRITE_BUSY)                //写状态完成后,EEPROM会将数据写入内存中,此时进行ADK查询
        {
            Uint16 tmp = 0;
            while (RwI2cBus(RW_I2C_BUS_ACK) != I2C_SUCCESS) // 如果还没有完成,继续查询I2C总线状态
            {
                // The EEPROM will send back a NACK while it is performing
                // a write operation. Even though the write communique is
                // complete at this point, the EEPROM could still be busy
                // programming the data. Therefore, multiple attempts are
                // necessary.
                if (++tmp >= 100)
                    break;
            }
        }
        // If a message receives a NACK during the address setup portion of the
        // EEPROM read, the code further below included in the register access ready
        // interrupt source code will generate a stop condition. After the stop
        // condition is received (here), set the message status to try again.
        // User may want to limit the number of retries before generating an error.
      #ifdef  DSC28034_CDD
      #else
        else if (I2cMsg.status == I2C_MSG_STATUS_SEND_NOSTOP_BUSY) //ACK查询数据发送完成
        {
            I2cMsg.status = I2C_MSG_STATUS_IDLE;
        }
      #endif
        // If completed message was reading EEPROM data, reset msg to inactive state
        // and read data from FIFO.
        else if (I2cMsg.status == I2C_MSG_STATUS_READ_BUSY)                        //数据读取完成
        {
            int16 i;
//            DELAY_US(1);
            asm volatile (" NOP ");
            for (i = 0; i < I2cMsg.bytes; i++)
            {
                I2cMsg.buffer[i] = I2caRegs.I2CDRR;
            }
            asm volatile (" NOP ");
            I2cMsg.status = I2C_MSG_STATUS_RW_OK;
        }
    }  // end of stop condition detected
    // Interrupt source = Register Access Ready
    // This interrupt is used to determine when the EEPROM address setup portion of the
    // read data communication is complete. Since no stop bit is commanded, this flag
    // tells us when the message has been sent instead of the SCD flag. If a NACK is
    // received, clear the NACK bit and command a stop. Otherwise, move on to the read
    // data portion of the communication.
#ifdef  DSC28034_CDD
    else if (IntSource == I2C_ARDY_ISRC)    // ARDY中断的发生条件参考I2CSTR说明!   在STP=0时,内部计数器减到0时置位
    {
                I2caRegs.I2CSTR.all = I2C_CLR_ARDY_BIT;
                if (I2cMsg.status == I2C_MSG_STATUS_SEND_NOSTOP_BUSY)//ACK结束后进行读操作
        {
                    DELAY_US(30);                 //20211209
                I2cMsg.status = I2C_MSG_STATUS_RESTART;
        }
                else if (I2cMsg.status == I2C_MSG_STATUS_WRITE_BUSY)        //写完成,查询EEPROM在线
        {
            I2cMsg.status = I2C_MSG_STATUS_RW_OK;
                        I2caRegs.I2CMDR.bit.STP = 1;
                        //InitSetI2ca();                                                                                //复位I2C
            //I2caRegs.I2CMDR.all = 0x0000;    // reset I2C
            //I2caRegs.I2CMDR.all = 0x0020;
        }
    }
    //2021.12.24        H
        if(IntNack == 1)
        {
                I2caRegs.I2CMDR.bit.STP = 1;    // 之后SCD=1,进入SCDINT
                I2caRegs.I2CSTR.all = I2C_CLR_NACK_BIT;
                I2caRegs.I2CFFTX.bit.TXFFRST = 0;
                asm volatile ("NOP");
                I2caRegs.I2CFFTX.bit.TXFFRST = 1;
        }
#else
    else if (IntSource == I2C_ARDY_ISRC)    // ARDY中断的发生条件参考I2CSTR说明!
    {
        if (I2caRegs.I2CSTR.bit.NACK == 1)
        {
            I2caRegs.I2CMDR.bit.STP = 1;    // 之后SCD=1,进入SCDINT
            I2caRegs.I2CSTR.all = I2C_CLR_NACK_BIT;
        }
        else if (I2cMsg.status == I2C_MSG_STATUS_SEND_NOSTOP_BUSY)
        {
            I2cMsg.status = I2C_MSG_STATUS_RESTART;
        }
        else if (I2cMsg.status == I2C_MSG_STATUS_WRITE_BUSY)
        {
            I2cMsg.status = I2C_MSG_STATUS_RW_OK;
            InitSetI2ca();
            //I2caRegs.I2CMDR.all = 0x0000;    // reset I2C
            //I2caRegs.I2CMDR.all = 0x0020;
        }
    }
#endif
}
 复制代码void InitSetI2ca(void)
{
    // Initialize I2C
    I2caRegs.I2CMDR.all = 0x4000;    // reset I2C
    I2caRegs.I2CSAR = 0x50;        // Slave address - EEPROM control code
#if (DSP_CLOCK == 140)      // DSP运行频率140MHz
    I2caRegs.I2CPSC.all = 20;        // Prescaler - need 7-12 Mhz on module clk, I2C module clock = 10MHz
    I2caRegs.I2CCLKL = 55;          // clk低电平设置为 (25+5)*0.1us = 3us
    I2caRegs.I2CCLKH = 55;
#endif
#if (DSP_CLOCK == 120)      // DSP运行频率120MHz
    I2caRegs.I2CPSC.all = 11;        // Prescaler - need 7-12 Mhz on module clk, I2C module clock = 10MHz
    I2caRegs.I2CCLKL = 55;          // clk低电平设置为 (25+5)*0.1us = 3us
    I2caRegs.I2CCLKH = 55;
#endif
#if (DSP_CLOCK == 100)      // DSP运行频率100MHz
    I2caRegs.I2CPSC.all = 9;        // Prescaler - need 7-12 Mhz on module clk, I2C module clock = 10MHz
    I2caRegs.I2CCLKL = 55;          // clk低电平设置为 (25+5)*0.1us = 3us
    I2caRegs.I2CCLKH = 55;
#endif
#if (DSP_CLOCK == 80)      // DSP运行频率60MHz
    I2caRegs.I2CPSC.all = 7;        // Prescaler - need 7-12 Mhz on module clk, I2C module clock = 10MHz
    I2caRegs.I2CCLKL = 55;          // NOTE: must be non zero, clk低电平设置为 (55+5)*0.1us = 6us
    I2caRegs.I2CCLKH = 55;          // NOTE: must be non zero, clk高电平设置为 (55+5)*0.1us = 6us
#endif
#if (DSP_CLOCK == 60)      // DSP运行频率60MHz
    I2caRegs.I2CPSC.all = 5;        // Prescaler - need 7-12 Mhz on module clk, I2C module clock = 10MHz
    I2caRegs.I2CCLKL = 25;          // NOTE: must be non zero, clk低电平设置为 (55+5)*0.1us = 6us
    I2caRegs.I2CCLKH = 25;          // NOTE: must be non zero, clk高电平设置为 (55+5)*0.1us = 6us
#endif
#if 0
    I2caRegs.I2CCLKL = 55;          // NOTE: must be non zero, clk低电平设置为 (55+5)*0.1us = 6us
    I2caRegs.I2CCLKH = 55;          // NOTE: must be non zero, clk高电平设置为 (55+5)*0.1us = 6us
#elif 1
//    I2caRegs.I2CCLKL = 55;          // clk低电平设置为 (25+5)*0.1us = 3us
//    I2caRegs.I2CCLKH = 55;
#elif 1     // 200KHz
    I2caRegs.I2CCLKL = 20;          // clk低电平设置为 (20+5)*0.1us = 2.5us
    I2caRegs.I2CCLKH = 20;
#elif 1
    I2caRegs.I2CCLKL = 10;           // 试验ok
    I2caRegs.I2CCLKH = 10;
#elif 1
    I2caRegs.I2CCLKL = 4;           // 试验ok
    I2caRegs.I2CCLKH = 9;
#endif
    I2caRegs.I2CIER.all = 0x0024;   // SCD & ARDY interrupts
    I2caRegs.I2CMDR.all = 0x4020;   // Take I2C out of reset
                                    // Stop I2C when suspended
    I2caRegs.I2CFFTX.all = 0x6040;  // Enable FIFO mode and TXFIFO
    I2caRegs.I2CFFRX.all = 0x2040;  // Enable RXFIFO, clear RXFFINT,
   // I2caRegs.I2CFFRX.all = 0x2040;  // Enable RXFIFO, clear RXFFINT,
}
 
 
 
 
 
 | 
 |