AnsweredAssumed Answered

I²C Problems with BF537

Question asked by Michl on Apr 12, 2010
Latest reply on May 3, 2010 by PrasanthR

Hey guys, i have trouble with my I²C-EEPROM ST24c04.

 

I'M using the HW_TWI interface of the BF537.

When I'mwriting the full 4KBit of the EEPROM, the written data is correct. Ichecked this with an external EEPROM-Reader.

 

When I'm reading data, just the first 256Byte are correct. The upper 256Byte are wrong, but I don't know why. The only difference is the bit before the R/W-Bit. For the first 256Byte it is 0 for the upper 1.

I use the RESTART condition for random address reading.

 

Perhaps there is some errors in my code?

 

CODE:

 

 

void Init_TWI (void)
{
    u8 clk_hi, clk_low;
   
    *pTWI_CONTROL = (SCLK / 10) | TWI_ENA;            // Setup Prescaler, 10MHz Time Reference; Enable TWI
           
   
    clk_hi  = (10000 / TWI_CLK) * 0.5;     // (10000kHz (Time Reference) / TWI_CLK) * Duty_Cycle
    clk_low = (10000 / TWI_CLK) * 0.5;    // (10000kHz (Time Reference) / TWI_CLK) * Duty_Cycle
    *pTWI_CLKDIV = CLKLOW(clk_low) | CLKHI(clk_hi);
   
    EEPROM_Select (EEPROM_1, Block_0);
   
    *pTWI_FIFO_CTL = 0x0000;    // Rx & Tx Interrupt at 1Byte, No Buffer Flush
   
    *pTWI_INT_MASK = RCVSERV |    // Receive FIFO Service
                     XMTSERV |    // Transmit FIFO Service
                     MERR |        // Master Transmit Error
                     MCOMP;        // Master Transfer Complete   
   
    Restart_Flag = 0;
}

 

 

 

 

 

void TWI_Write (u8 bytes_to_write)
{
    *pTWI_MASTER_CTL = MEN |                    // Master Enable
                       (bytes_to_write << 6);    // Bytes to write                      
}

 

 

 


void TWI_Read (u8 bytes_to_read)
{
    *pTWI_MASTER_CTL = MEN |                    // Master Enable
                       MDIR|                    // Receive Direction
                       (bytes_to_read << 6);    // Bytes to read           
}

 

 

 

 

 

void EEPROM_Select (u8 eeprom, u8 block)
{
    *pTWI_MASTER_ADDR =  0x50;            // I²C Standard 0b1010
    *pTWI_MASTER_ADDR += (eeprom << 1);
    *pTWI_MASTER_ADDR += (block & 0x0F);
}

 

 

 


void EEPROM_Write (u8 eeprom, u8 block, u8 address, u8 datasize, u8 *data)
{
//    do
//    {
//        if (*pTWI_MASTER_STAT & ANAK)
//            *pTWI_MASTER_STAT |= ANAK;        // Adress-NAK-Bit zurücksetzen
        xmt   = 0;
        mcomp = 0;
   
        TWI_TxPtr = data;                    // Pointer auf Daten
        *pTWI_XMT_DATA8 = address;            // Adresse in FIFO laden
        EEPROM_Select (eeprom, block);        // EEPROM auswählen, hierzu müssen Daten im FIFO sein, ansonsten Fehler (siehe HW_Ref)

 

        TWI_Write (datasize + 1);            // Tx beginnen
        TWI_Next_Cycle = 0;       
        while(!TWI_Next_Cycle);                // 10ms warten -> EEPROM Write Time!
        while((*pTWI_MASTER_STAT & BUSBUSY) || (*pTWI_MASTER_STAT & MPROG));    // Auf Tx_Ende warten

 

//    }while(*pTWI_MASTER_STAT & ANAK);        // Bei Adress-NAK nochmals versuchen
   
}

 

 

 

unsigned char EEPROM_Read (u8 eeprom, u8 block, u8 address, u8 datasize)
{
    unsigned char Rx_Data;
   
    Restart_bytes_to_read = datasize;
    Restart_Flag = 1;
   
    TWI_RxPtr = (u8*)&Rx_Data;

 

    *pTWI_XMT_DATA8 = address;            // Adresse in FIFO laden
    EEPROM_Select (eeprom, block);        // EEPROM auswählen, hierzu müssen Daten im FIFO sein, ansonsten Fehler (siehe HW_Ref)

 


    TWI_Write (1);                        // Tx beginnen       
    TWI_Next_Cycle = 0;
    while(!TWI_Next_Cycle);
    while((*pTWI_MASTER_STAT & BUSBUSY) || (*pTWI_MASTER_STAT & MPROG));    // Auf Tx_Ende warten

 

    return Rx_Data;
}

 

**************************** Interrupt CODE **********************************

*********************************************************************************

 

if (*pSIC_ISR & IRQ_TWI)
    {

 

        if (*pTWI_INT_STAT & MCOMP)                    // Transfer Complete
        {
            *pTWI_INT_STAT |= MCOMP;                // Clear Interrupt
           
            if (*pTWI_MASTER_CTL & RSTART)
            {
                *pTWI_MASTER_CTL &= ~RSTART;
                Restart_Flag = 0;
                *pTWI_MASTER_CTL |= ((Restart_bytes_to_read) << 6);
            }
           
            mcomp++;
        }
       
        if (*pTWI_INT_STAT & XMTSERV)                // Transfer IRQ
        {
            if ((*pTWI_MASTER_CTL & DCNT) > 0)        // Load next data if DCNT is > 1
                *pTWI_XMT_DATA8 = *TWI_TxPtr++;    // Otherwise data transfer will be completed in next cycle
               
               
            if (((*pTWI_MASTER_CTL & DCNT) == 0) && (Restart_Flag == 1))
            {
                *pTWI_MASTER_CTL = (RSTART | MDIR | MEN);
            }
            *pTWI_INT_STAT |= XMTSERV;                // Clear Interrupt
            xmt++;
           
        }
       
        if (*pTWI_INT_STAT & MERR)
        {
            *pTWI_INT_STAT |= MERR;        // Clear Interrupt
            merr = *pTWI_MASTER_STAT;    // Save Master Status
        }
       
       
        if (*pTWI_INT_STAT & RCVSERV)            // Read IRQ
        {
            *pTWI_INT_STAT |= RCVSERV;            // Clear Interrupt
            *TWI_RxPtr++ = *pTWI_RCV_DATA8;        // Save received Byte
            rcv++;
        }
       
       

 

        ssync();
    }

 

 

I hope someone can help me. Thanks a lot!

Attachments

Outcomes