ATxMega128 i TWI - problemy... cd - SP2GNB - 11-12-2016 22:53
Witam,
Naprawdę myślałem, że sobie poradzę z przesiadką ze zwykłej Atmegi, ale nie wyszło...Chcę pisać i czytać 24c256 na początku na pierwszej stronie. Program zwisa podczas czytania na zakomentowanych liniach:
Kod:
int8_t TWI_read_data(uint8_t readAddr)
{
// while ((TWIC_MASTER_STATUS & TWI_MASTER_BUSSTATE_gm) != TWI_MASTER_BUSSTATE_IDLE_gc)
{
}
uint8_t adres = MEM_SLAVE_ADDRESS + 1;
TWIC_MASTER_ADDR = adres;
while(!(TWIC_MASTER_STATUS & TWI_MASTER_WIF_bm));
TWIC_MASTER_DATA = 0x00;
TWIC_MASTER_ADDR = readAddr;
// while(!(TWIC_MASTER_STATUS & TWI_MASTER_RIF_bm));
return TWIC_MASTER_DATA;
}
Nie wiem co jest źle, nie wiem jak to powinno wyglądać - pomóżcie...pse...
RE: ATxMega128 i TWI - problemy... cd - SQ5KVS - 12-12-2016 1:23
A twi nie trzeba podciągać do zasilania? Podciągnąłeś?
RE: ATxMega128 i TWI - problemy... cd - SP2GNB - 12-12-2016 12:35
Witam,
Oczywiście - płytka jest od sterownika HUSARKA i z oprogramowaniem Adama SP5FCS działa bez problemów. Wykorzystuję płytkę do innych celów (Master) i działające procedury TWI są NIEZBĘDNE...(init, start, stop, write, read)...
Fajnie by było dostać jakieś fajne biblioteki. Ciekawe jakich używa Adam SP5FCS, bo jego program chodzi jak burza...
RE: ATxMega128 i TWI - problemy... cd - SQ5KVS - 12-12-2016 13:05
Ok, nie znam się na ATxMegach więc się wypowiem W tym while'u ewidentnie czeka na zmianę
stanu TWIC_MASTER_STATUS & TWI_MASTER_BUSSTATE_gm które muszą być równe TWI_MASTER_BUSSTATE_IDLE_gc żeby dalej poszedł. Dlatego było moje pytanie czy podciągnąłeś. Albo stany tych rejestrów linii nie są odpowiednio czytane (może nie odblokowałeś jakiegoś rejestru albo właśnie wymusiłeś) albo są czytane, ale nie ma nigdy TWI_MASTER_BUSSTATE_IDLE_gc bo nie podciągnąłeś, coś obciąża a może któryś układ jest upalony i wymusza? Sam to kiedyś przerabiałem i problemem okazał się rezystor który powinien mieć kilka kilo a miał pewnie gigaomy (tzn po prostu był przerwany).
Sprawdź miernikiem stany czy są wysokie. Ew sprawdź czy w manualu do ATxmegi nie ma przypadkiem jakiegoś obostrzenia na te linie (jak jest włączone coś to TWI nie działa) itp..
RE: ATxMega128 i TWI - problemy... cd - SP2GNB - 12-12-2016 15:41
Hardware jest ok, bo jak wczytuję Husarka to melduje 24C512 OK. Szukam w sofcie..
Edit:
Uparłem się zrobić na rejestrach, bez bibliotek - może błąd...
RE: ATxMega128 i TWI - problemy... cd - SP9RQA - 12-12-2016 15:59
Może jakiś przykład z sieci zadziała?
https://github.com/vlantaca/ATxmega128a4u-TWI
RE: ATxMega128 i TWI - problemy... cd - SP5FCS - 12-12-2016 18:46
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;
}
RE: ATxMega128 i TWI - problemy... cd - SP2GNB - 12-12-2016 19:50
No to mam prezent na Gwiazdkę!
DZIĘKUJĘ.
Zabieram się do implementacji...
Dam znać jak poszło...
Edit:
Jedyna różnica pomiędzy CodeVision a AS6 jaką zauważyłem to deklaracja u8 w CV a uint8_t w AS6.
Właściwie na bazie tego programu powinienem umieć napisać procedurę twic_write_reg(), ale gdybyś ją podesłał....
Dzięki z góry...
RE: ATxMega128 i TWI - problemy... cd - SP5FCS - 12-12-2016 20:02
W celu uproszczenia zapisu zdefiniowałem nowy typ u8, zawsze to mniej pisania niż uint8_t lub niejednoznaczny uint.
Kod:
///////////////////////////////////////////////////////////////////////////////////////////////////
// TWI write buffor
// addr - adres ukladu, *buffer - wskaznik do bufora danych, length - ilosc bajtow
void twic_write_buf(u8 addr, u8 *buffer, u8 length)
{
u8 i;
//nadaj adres slave
TWIC.MASTER.ADDR = addr; //adres ukladu + WR,
//generuje START
while(!(TWIC.MASTER.STATUS&TWI_MASTER_WIF_bm)); //wait for WIF
//petla wysylania bajtow do slave
for (i=0;i<length;i++)
{
twic_result=twic_test_result(); //wez status operacji
if (twic_result!=TWI_ACK) return; //ACK idz dalej,
TWIC.MASTER.DATA = *buffer++; //wskaznik do bufora danych
while(!(TWIC.MASTER.STATUS&TWI_MASTER_WIF_bm)); //wait for WIF
};
//zakonczenie wysylania danych do slave
TWIC.MASTER.CTRLC=TWI_MASTER_CMD_STOP_gc; //rozkaz STOP dla TWI
twic_result=TWI_OK; //poprawna operacja
}
Na bazie tych trzech funkcji możemy napisać obsługę dowolnego układu z innterfejsem I2C /PCF8574, 24c512, Si570, itd. /.
RE: ATxMega128 i TWI - problemy... cd - SP2GNB - 12-12-2016 20:56
Widzę adres układu, bufor z danymi, jego długość a nie widzę adresu rejestru od którego zacznę pisać...Jak to działa?
|