Hallo Matthias,
softwaretechnisch sieht das ganze so aus, dass ich ein Array habe, in dem sequentiell die Subadressen und Parameter hinterlegt sieht. Der =E4u=DFere Aufbau sieht dann so aus:
for (i=3D0; i < sizeof(videoinput_params); i +=3D 2) { do { i2c_error =3D 0; i2c_error =3D i2c_start(I2C_VIDEOINPUT_ADDR | I2C_WRITE); // Send slave address if( i2c_error =3D=3D 0) { i2c_error =3D i2c_write(videoinput_params[i]); // Send sub address
if( i2c_error =3D=3D 0) { i2c_error =3D i2c_write(videoinput_params[i+1]); // Send value
if( i2c_error =3D=3D 0) { i2c_error =3D i2c_stop(); } } } i2c_error_sum +=3D i2c_error; // DEBUG__ } while(i2c_error !=3D 0); }
Jede einzelne Subadressen/Parameter-Kombination wird also solange wiederholt bis sie fehlerfrei war.
Die Kommunikation =FCbernimmt der im =B5C eingebaute Hardware-Controller. Die Routinen sehen wie folgt aus:
####### INIT void i2c_init(void) { PFR22_D4 =3D 1; // Set port function register for I2C SDA0 PFR22_D5 =3D 1; // Set port function register for I2C SCL0
ICCR0_EN =3D 0; // Disable I2C, clears all flags but BER and BEIE in IBCR0 and IBSR0
#if (I2C_BAUDRATE =3D=3D 400) ICCR0_CS4 =3D 0; // CS4..0 : Set prescaler (~400kbit/s) ICCR0_CS3 =3D 0; ICCR0_CS2 =3D 0; ICCR0_CS1 =3D 1; ICCR0_CS0 =3D 0; ICCR0_NSF =3D 1; // Enable noise filter (should be enabled for
400kbit/s) #elif (I2C_BAUDRATE !=3D 400) ICCR0_CS4 =3D 0; // CS4..0 : Set prescaler (~98kbit/s) ICCR0_CS3 =3D 1; ICCR0_CS2 =3D 1; ICCR0_CS1 =3D 0; ICCR0_CS0 =3D 0; ICCR0_NSF =3D 0; // Disable noise filter (should be enabled for
400kbit/s) #endif // I2C_BAUDRATE
IDAR0 =3D 0; // Clear data register
IBCR0_BER =3D 0; // Clear bus error interrupt flag IBCR0_BEIE =3D 0; // Bus error interrupt disabled IBCR0_ACK =3D 0; // No acknowledge generated IBCR0_GCAA =3D 0; // No general call acknowledge is generated IBCR0_INTE =3D 0; // Disable interrupt IBCR0_INT =3D 0; // Clear transfer interrupt request flag
ICCR0_EN =3D 1; // Enable I2C }
######## Start
UINT8 i2c_start(UINT8 slave_address) { ICCR0_EN =3D 0; // Disable I2C, clears all flags but BER and BEIE in IBCR0 and IBSR0 IBCR0_BER =3D 0; // Clear bus error flag IDAR0 =3D slave_address; // Set slave_address to data register ICCR0_EN =3D 1; // Enable I2C IBCR0_MSS =3D 1; // Sets master mode, generates start condition and begins transfer return i2c_check(); // Check for errors and timeouts }
####### WRITE
UINT8 i2c_write(UINT8 value) { IDAR0 =3D value; // Load data into register
if(IBCR0_MSS !=3D 1) // Check if still master return I2C_ERROR;
IBCR0_INT =3D 0; // Starts next transfer (without start condition) return i2c_check(); // Check for errors and timeouts }
###### STOP
UINT8 i2c_stop(void) {
UINT16 timeout =3D 0;
while (IBCR0_INT =3D=3D 0) // Wait for last transfer finished { CLEAR_WD(); timeout++; if (timeout >=3D I2C_TIMEOUT_VALUE) return I2C_ERROR; }
IBCR0_MSS =3D 0; // Changes to slave mode and generates stop condition
timeout =3D 0; while (IBSR2_BB =3D=3D 1) // Wait until bus is idle (or timeout detected) { CLEAR_WD(); timeout++; if (timeout >=3D I2C_TIMEOUT_VALUE) return I2C_ERROR; }
ICCR0_EN =3D 0; // Disable I2C return I2C_OKAY;
}
######## CHECK
UINT8 i2c_check() { UINT16 timeout =3D 0;
while(IBCR0_INT =3D=3D 0) { // Waiting for answer from slave CLEAR_WD(); timeout++; // Timeout mechanism if (timeout >=3D I2C_TIMEOUT_VALUE) return I2C_ERROR; // Returns error }
if((IBCR0_BER !=3D 0) || (IBSR0_AL !=3D 0) || (IBSR0_LRB !=3D 0)) return I2C_ERROR;
return I2C_OKAY; }
###########################
Was allerdings f=FCr einen Softwarefehler sprechen w=FCrde, w=E4re dass das ganze im Einzelschrittbetrieb funktionst=FCchtig ist. Aber es kann doch nicht sein, dass irgendwer die Datenleitung dauerhaft auf Masse h=E4lt.
Achja der Slave ist ein SAA7113 von Philipps (Datenblatt: http://www.ortodoxism.ro/datasheets/philips/SAA7113H_1.pdf )
Danke schonmal, sollte ich derweil was neues herausfinden, schreib ich hier den aktuellen Stand hin
Achja hier ist noch ein Screenshot von einem funktionierenden Sendezyklus von Adresse/Subadresse/Parameter (wegen deiner 9/10 Taktfrage?!):
formatting link