problem med i2c och picar
Postat: 8 september 2009, 16:20:07
Tjo, nån som har erfarenhet av i2c och picar? Min i2c hänger sig nämnligen då och då, har inte exakt lyckats lista ut vart det är den hänger sig, då jag inte har möjlighet till debug-mode på programmeraren.
Om nu ingen orkar felsöka, finns det någe sätt att "starta om"/resetta i2c-modulen utan att behöva starta om hela Mastern?
Jag tror att det är i smI2C_Read_WaitIFAdr (se source) som den fastnar
ps. slavarna krashar inte, och de går på egen matning. reset av mastern brukar räcka
//Mvh, mig
i2c-nätverket ser ut lite löst som följande:
sladd avser vanlig telefonledning med RJ44-kontakter.
i2c-bussen är kopplad med pullup vid mastern och i övrigt går den bara rakt in på i2c-benen på picarna.
alla picar är 18F2550
Hub-schematics: http://roze.ridorana.se/old/bilder/help/hub.png
och för den som tror att det e mjukvarurelaterat, kod för master:
Om nu ingen orkar felsöka, finns det någe sätt att "starta om"/resetta i2c-modulen utan att behöva starta om hela Mastern?
Jag tror att det är i smI2C_Read_WaitIFAdr (se source) som den fastnar
ps. slavarna krashar inte, och de går på egen matning. reset av mastern brukar räcka
//Mvh, mig
i2c-nätverket ser ut lite löst som följande:
Kod: Markera allt
Master ---> (10m sladd) ---> "hub" (se bild nedan) ---> (2m sladd) ---> Slave 102
|-> (2m sladd) ---> Slave 110
i2c-bussen är kopplad med pullup vid mastern och i övrigt går den bara rakt in på i2c-benen på picarna.
alla picar är 18F2550
Hub-schematics: http://roze.ridorana.se/old/bilder/help/hub.png
och för den som tror att det e mjukvarurelaterat, kod för master:
Kod: Markera allt
typedef enum {
smI2C_off = 0,
smI2C_Free = 1,
smI2C_Write_WaitSEN = 2,
smI2C_Write_Adr = 3,
smI2C_Write_WaitBF = 4,
smI2C_Write_WaitIF = 5,
smI2C_Write_Data = 6,
smI2C_Write_WaitPEN = 7,
smI2C_Read_WaitSEN = 8,
smI2C_Read_Adr = 9,
smI2C_Read_WaitBFAdr = 10,
smI2C_Read_WaitIFAdr = 11,
smI2C_Read_Data = 12,
smI2C_Read_WaitIF = 13,
smI2C_Read_WaitACKEN = 14,
smI2C_Read_WaitPEN = 15,
smI2C_Read_Finished = 16
} enumI2C;
typedef struct{
ubyte ubAdr;
ubyte ubSize;
ubyte ubCnt;
ubyte *aubData;
enumI2C State;
} smI2CData;
smI2CData smI2C;
ubyte smI2C_Write(ubyte ubAdr, void *aubData, ubyte ubCount){
ubyte i, *from, *to;
if(smI2C.State == smI2C_Free){
smI2C.ubCnt = ubCount;
smI2C.ubAdr = ubAdr;
smI2C.aubData = TempBuff;
from = aubData;
to = TempBuff;
for(i=ubCount; i ; i--){
*to++ = *from++;
}
SEN = 1; // Send Start
smI2C.State = smI2C_Write_WaitSEN;
return 1;
}else{
return 0;
}
}
ubyte smI2C_Read(ubyte ubAdr, ubyte ubCount )
{
if(smI2C.State == smI2C_Free){
smI2C.ubCnt = ubCount;
smI2C.ubSize = ubCount;
smI2C.ubAdr = ubAdr + 1;
smI2C.aubData = TempBuff;
TempBuff[0]=255; // extra försäkring om läsning misslyckades
SEN = 1; // Send Start
smI2C.State = smI2C_Read_WaitSEN;
return 1;
}else{
return 0;
}
}
void smI2C_Execute(void){
switch(smI2C.State){
case smI2C_off: break;
case smI2C_Free: break;
/////////////
// Write //
/////////////
case smI2C_Write_WaitSEN:
if(!SEN){
smI2C.State = smI2C_Write_Adr;
}
break;
case smI2C_Write_Adr:
SSPIF = 0;
SSPBUF = smI2C.ubAdr ;
smI2C.State = smI2C_Write_WaitBF;
break;
case smI2C_Write_WaitBF:
if(!BF){
smI2C.State = smI2C_Write_WaitIF;
}
break;
case smI2C_Write_WaitIF:
if(SSPIF){
if(smI2C.ubCnt > 0){
smI2C.State = smI2C_Write_Data;
}else{
PEN = 1; // Generate Stop Condition
smI2C.State = smI2C_Write_WaitPEN;
}
}
break;
case smI2C_Write_Data: SSPIF = 0;
SSPBUF = *(smI2C.aubData);
smI2C.aubData++;
smI2C.ubCnt--;
smI2C.State = smI2C_Write_WaitBF;
break;
case smI2C_Write_WaitPEN: if( ! PEN )
smI2C.State = smI2C_Free;
break;
////////////
// Read //
////////////
case smI2C_Read_WaitSEN:
if(!SEN){
smI2C.State = smI2C_Read_Adr;
}
break;
case smI2C_Read_Adr:
SSPIF = 0;
SSPBUF = smI2C.ubAdr;
smI2C.State = smI2C_Read_WaitBFAdr;
break;
case smI2C_Read_WaitBFAdr:
if(!BF){
smI2C.State = smI2C_Read_WaitIFAdr;
}
break;
case smI2C_Read_WaitIFAdr:
if(SSPIF){
if(smI2C.ubCnt > 0){
smI2C.State = smI2C_Read_Data;
}else{
PEN = 1; // Generate Stop Condition
smI2C.State = smI2C_Read_WaitPEN;
}
}
break;
case smI2C_Read_Data:
SSPIF = 0; // Clear SPP Interrupt Flag
RCEN = 1; // Enable Receive Mode
smI2C.State = smI2C_Read_WaitIF;
break;
case smI2C_Read_WaitIF:
if(SSPIF){
*(smI2C.aubData) = SSPBUF;
if(smI2C.ubCnt != 1){
ACKDT=0;
}else{
ACKDT=1;
}
ACKEN=1;
smI2C.ubCnt--;
smI2C.aubData++;
smI2C.State = smI2C_Read_WaitACKEN;
}
break;
case smI2C_Read_WaitACKEN:
if(!ACKEN){
if(smI2C.ubCnt > 0){
smI2C.State = smI2C_Read_Data;
}else{
PEN = 1; // Generate Stop Condition
smI2C.State = smI2C_Read_WaitPEN;
}
}
break;
case smI2C_Read_WaitPEN:
if(!PEN){
smI2C.State = smI2C_Read_Finished;
}
break;
case smI2C_Read_Finished:
break;
}
}