Ich bin gleich zu GNU gegangen (lieber als nach 30 tage), und bin einigermassen zufrieden, vor allen mit das preis-leistungs verhältniss.
Das monitor program is einfach genug, so das du die custom defines von metroworks relativ einfach hier austauschen kannst. Es benüzt port-H pins 0&1, und interrupt wird von das relevante edge ge-trigger’t . Es speichert dan MON_SIZE daten. Du kannst entweder zu dien Gelegenheit diesen dumpIICTrace() aufrufen, oder wenn es voll ist, wird’s von alleine gemacht.
Das output kommt als 2 reihen nuller und einser raus, und kann als primitiver logic-analiser gesehn werden. Mann kann vor allem sehen ob die start-stop und ack Sequenzen so sind wie Mann sich es vorstellt
Code:
#define PORT (*((ptPIM)0x240))
#define scl PORT.pth.byte & PTH0
#define sda PORT.pth.byte & PTH1
#define PortHIntVector (* (unsigned int *)(0x3e4c))
// records old value of portH
unsigned int porth;
#define MON_SIZE 200
tU08 trans[MON_SIZE];
unsigned int count=0;
void PORTH_ISR(void) __attribute__((interrupt));
void initIICMonitor(void)
{
// connect ISR's to ports
PortHIntVector = (unsigned int)PORTH_ISR;
// set pins 0&1 to input
PORT.ddrh.byte &= 0xFC;
// initially trigger on falling edge
PORT.ppsh.byte &= 0xFC;
// clear interrupts on pins
PORT.pifh.byte |= 0x03;
// enable interrupts on pins 0&1
PORT.pieh.byte |= 0x03;
asm("cli");
}
void dumpIICTrace(){
int i;
int c2;
volatile tU08 oscl = 0;
volatile tU08 osda = 0;
//enable interrupts
asm("sei");
DBug12FNP->printf("iic_bitslave TestPorts:count %d\n\r",count);
for (c2=0;c2<count;c2++){
DBug12FNP->printf("%d",trans[c2]&1);
}
DBug12FNP->printf("\n\r");
for (c2=0;c2<count;c2++){
DBug12FNP->printf("%d",(trans[c2]&2)>>1);
}
DBug12FNP->printf("\n\r");
count = 0;
// disable interrupts
asm("cli");
}
void PORTH_ISR(void){
volatile unsigned char lporth;
lporth = PORT.pth.byte;
//DBug12FNP->printf("iic_mon : ISR called %x pifh %x old %x\n\r",PORT.pifh.byte,lporth,porth);
if (count < MON_SIZE){
trans[count] = lporth;
if ((lporth&1)==1) {
// now triger on falling edge
PORT.ppsh.byte &= 0xFE;
}else{
// now triger on raising edge
PORT.ppsh.byte |= 0x01;
}
if ((lporth&2)==2) {
// now triger on falling edge
PORT.ppsh.byte &= 0xFD;
}else{
// now triger on raising edge
PORT.ppsh.byte |= 0x02;
}
count++;
}
else{
DBug12FNP->printf("iic_mon: buffer overflow\n\r");
dumpIICTrace();
}
// reset interrupts
// clear interrupts on pins
if ((PORT.pifh.byte&1)==1) PORT.pifh.byte |= 0x01;
if ((PORT.pifh.byte&2)==2) PORT.pifh.byte |= 0x02;
}
Lesezeichen