Odpowiedz 
 
Ocena wątku:
  • 0 Głosów - 0 Średnio
  • 1
  • 2
  • 3
  • 4
  • 5
ATxMega128 i TWI - problemy... cd
SP5FCS Offline
Adam
*****

Liczba postów: 1,072
Dołączył: 02-02-2009
Post: #7
RE: ATxMega128 i TWI - problemy... cd
Działający kod pod Xmegi:

Kod:
///////////////////////////////////////////////////////////////////////////////////////////////////
// procedury do obslugi komunikacji poprzez TWI
///////////////////////////////////////////////////////////////////////////////////////////////////

#define CLK_XMEGA           32000000        //zegar procesora
#define CLK_TWI               100000        //zegar dla TWI

volatile    u8  twic_result;                //wynik ostatniego dzialania na TWI


///////////////////////////////////////////////////////////////////////////////////////////////////
// TWI - MASTER
///////////////////////////////////////////////////////////////////////////////////////////////////
// TWI_MASTER_cat_RLA_offset      = 0x00        // Control Register A
// TWI_MASTER_cat_RLB_offset      = 0x01        // Control Register B
// TWI_MASTER_cat_RLC_offset      = 0x02        // Control Register C
// TWI_MASTER_STATUS_offset     = 0x03        // Status Register
// TWI_MASTER_BAUD_offset       = 0x04        // Baurd Rate Control Register
// TWI_MASTER_ADDR_offset       = 0x05        // Address Register
// TWI_MASTER_DATA_offset       = 0x06        // Data Register
// TWI_SLAVE_cat_RLA_offset       = 0x00        // Control Register A
// TWI_SLAVE_cat_RLB_offset       = 0x01        // Control Register B
// TWI_SLAVE_STATUS_offset      = 0x02        // Status Register
// TWI_SLAVE_ADDR_offset        = 0x03        // Address Register
// TWI_SLAVE_DATA_offset        = 0x04        // Data Register
// TWI_SLAVE_ADDRMASK_offset    = 0x05          // Address Mask Register
// TWI_cat_RL_offset              = 0x00          // TWI Common Control Register
// TWI_MASTER_offset            = 0x0001      // TWI master module
// TWI_SLAVE_offset             = 0x0008      // TWI slave module
///////////////////////////////////////////////////////////////////////////////////////////////////

#define TWI_BAUD(F_SYS, F_TWI) ((F_SYS / (2 * F_TWI)) - 5)  //macro dla twi baud
#define TWI_OK          0                   //all OK
#define TWI_ACK         1                   //ACK
#define TWI_NACK        3                   //no ACK
#define TWI_RIF         4                   //flag RIF
#define TWI_BUSERR      5                   //bus error
#define TWI_ARBLOST     6                   //bus arbitration is lost

///////////////////////////////////////////////////////////////////////////////////////////////////
// Inicjowanie interfejsu TWIC, I2C na C0-SDA, C1-SCL
void twic_master_init( void )
{
//konfiguracja pinow dla TWI_C
PORTC.OUTSET=0b00000011;                            // ustaw stan pinow na wysoki
PORTC.DIRSET=0b00000011;                            // SDA, SCL as outputs
PORTC.PIN0CTRL=PORT_SRLEN_bm | PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
PORTC.PIN1CTRL=PORT_SRLEN_bm | PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;

TWIC.MASTER.BAUD  = TWI_BAUD(CLK_XMEGA,CLK_TWI);    //(32M/(2*100k)-5)    częstotliwość twi 100 kHz
TWIC.CTRL         = 0;                              //SDHOLD, EDIEN - clear common register
TWIC.MASTER.CTRLB = TWI_MASTER_SMEN_bm;             //TIMEOUT=0,QCEN=0,SMEN=1 Smart Mode Enable
TWIC.MASTER.CTRLA = TWI_MASTER_ENABLE_bm;             //INTLVL=0,RIEN=0,WIEN=0, ENABLE=1
TWIC.MASTER.STATUS= TWI_MASTER_BUSSTATE_IDLE_gc;    //force initial bus state to idle
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// TWI test result
u8 twic_test_result(void)
{
u8 status=TWIC.MASTER.STATUS;                           //wez status TWIC
if (status&TWI_MASTER_ARBLOST_bm)                       //if arbitration lost
    {
    TWIC.MASTER.STATUS=status | TWI_MASTER_ARBLOST_bm;  //wpisz 1, kasuje flage
    return TWI_ARBLOST;                                 //rezultat funkcji
    };    
if (status&TWI_MASTER_BUSERR_bm)                        //if bus error
    {
    TWIC.MASTER.STATUS=status | TWI_MASTER_BUSERR_bm;   //wpisz 1, kasuje flage
    return TWI_BUSERR;                                  //rezultat funkcji
    };
if (status&TWI_MASTER_WIF_bm)                           //if WIF, zapis do slave
    {
    //odwrotnie bit dla ACK !!!
    if (status&TWI_MASTER_RXACK_bm)                     //if 1, no ACK od slave
        {
        TWIC.MASTER.CTRLC=TWI_MASTER_CMD_STOP_gc;       //rozkaz STOP dla TWI
        return TWI_NACK;                                // no ACK
        }
        else                                            //if 0, ACK
        {
        return TWI_ACK;                                 // ACK
        }      
    };
if (status&TWI_MASTER_RIF_bm)                           // if RIF, odczyt ze slave
        return TWI_RIF;                                 // odebrano bajt od slave        
}


///////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char twic_read_reg(unsigned char addr, unsigned char reg)
{
u8 data;
//nadaj adres slave + nr rejstru
TWIC.MASTER.ADDR = addr;                               //adres ukladu + WR, generuje START                                                                
while(!(TWIC.MASTER.STATUS&TWI_MASTER_WIF_bm));        //wait for WIF
twic_result=twic_test_result();                        //wez status operacji
if (twic_result!=TWI_ACK) return 0;                    //ACK idz dalej, inny zwracaj kod bledu

TWIC.MASTER.DATA = reg;                                   //adres rejestru
while(!(TWIC.MASTER.STATUS&TWI_MASTER_WIF_bm));        //wait for WIF
twic_result=twic_test_result();                        //wez status operacji
if (twic_result!=TWI_ACK) return 0;                    //ACK idz dalej, inny zwracaj kod bledu

//nadaj adres do odczytu  
TWIC.MASTER.ADDR = addr|0x01;                            //adres ukladu I2C + RD    
while(!(TWIC.MASTER.STATUS&TWI_MASTER_RIF_bm));        //czekaj na zakonczenie odbioru        
data = TWIC.MASTER.DATA;                               //odczytany bajt

// send NACK and STOP
TWIC.MASTER.CTRLC=TWI_MASTER_ACKACT_bm|TWI_MASTER_​CMD_STOP_gc;
twic_result=TWI_OK;                                    //poprawna operacja
return data;
}

73 Adam
12-12-2016 18:46
Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
Odpowiedz 


Wiadomości w tym wątku
RE: ATxMega128 i TWI - problemy... cd - SP5FCS - 12-12-2016 18:46

Skocz do:


Użytkownicy przeglądający ten wątek: 10 gości