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;
}
}