I'm having trouble using the I2C interface with the ROM boot loader active. I don't get the reponses I expect.
Code from my I2C master:
#define TIVA_DEVICEADDRESS (0x42<<1) uint8 status_cmd = COMMAND_GET_STATUS; uint8 ping_cmd = COMMAND_PING; void EeSetStart(void) { volatile uint16 x; // Start condition ACCESS2_CTRL_REG &= ~(EN_ACCESS_BUS); x++; // 624 ns ACCESS2_CTRL_REG |= (SCL_VAL | SDA_VAL); BusyWait1(); ACCESS2_CTRL_REG &= ~(SDA_VAL); BusyWait1(); ACCESS2_CTRL_REG &= ~(SCL_VAL); BusyWait1(); } void EeSetStop(void) { // stop condition ACCESS2_CTRL_REG &= ~(EN_ACCESS_BUS); ACCESS2_CTRL_REG &= ~(SCL_VAL | SDA_VAL); BusyWait1(); ACCESS2_CTRL_REG |= SCL_VAL; BusyWait1(); ACCESS2_CTRL_REG |= SDA_VAL; BusyWait1(); } void EeSendByte(BYTE a) { volatile WORD n; ACCESS2_CTRL_REG |= EN_ACCESS_BUS; // automatic control SDA/SCL-VAL n++; // this is neccesssary to delay following events ACCESS2_CLEAR_INT_REG = 0; ACCESS2_IN_OUT_REG=a; // Wait until transmission is done while (!(ACCESS2_CTRL_REG & ACCESSx_INT)) ; ACCESS2_CLEAR_INT_REG = 0; } BYTE ReadByte_Ack(UByte nextNoAck) { volatile uint16 Read = 0; ACCESS2_CTRL_REG &= ~ACKn; while (!(ACCESS2_CTRL_REG & ACCESSx_INT)); Read=ACCESS2_IN_OUT_REG; // Read received byte ACCESS2_CLEAR_INT_REG = 0; if (nextNoAck) { ACCESS2_CTRL_REG |= ACKn; // don't transmit Acknowledge } return(Read); } BYTE ReadByte_NoAck(void) { volatile uint16 Read = 0; ACCESS2_CTRL_REG |= ACKn; // don't transmit Acknowledge while (!(ACCESS2_CTRL_REG & ACCESSx_INT)); Read=ACCESS2_IN_OUT_REG; // Read received byte ACCESS2_CLEAR_INT_REG = 0; return(Read); } uint8 send_packet(uint8* data, uint8 size) { uint8 i, ack, checksum = 0; for (i = 0; i < size; i++) { checksum += data[i]; } do { EeSetStop(); EeSetStart(); EeSendByte(TIVA_DEVICEADDRESS); } while (ACCESS2_CTRL_REG & ACKn); EeSetStop(); EeSetStart(); EeSendByte(size +2); EeSendByte(checksum); for (i = 0; i < size; i++) { EeSendByte(data[i]); } EeSetStart(); // Set Device address for read EeSendByte(TIVA_DEVICEADDRESS|0x01); ack = ReadByte_NoAck(); debugf("-%02X-\n", ack); EeSetStop(); return ack; } uint8 get_packet(uint8* data, uint8* size) { uint8 i, psize, pchecksum, checksum = 0; do { EeSetStop(); EeSetStart(); EeSendByte(TIVA_DEVICEADDRESS); } while (ACCESS2_CTRL_REG & ACKn); EeSetStart(); EeSendByte(TIVA_DEVICEADDRESS|0x01); psize = ReadByte_Ack(0); debugf("psize = %02X\n", psize); if (psize < *size) *size = psize; pchecksum = ReadByte_Ack(0); debugf("pchecksum = %02X\n", pchecksum); for (i = 0; i < *size; i++) { if (i == (*size-1)) { data[i] = ReadByte_NoAck(); } else if (i == (*size-2)) { ReadByte_Ack(1); } else { data[i] = ReadByte_Ack(0); } } for (i = 0; i < *size; i++) { checksum = data[i]; } EeSetStart(); // Set Device address for write EeSendByte(TIVA_DEVICEADDRESS); if (checksum == pchecksum) { EeSendByte(COMMAND_ACK); EeSetStop(); return COMMAND_ACK; } else { EeSendByte(COMMAND_NAK); EeSetStop(); return COMMAND_NAK; } } uint8 send_command(uint8* cmd, uint8 size) { uint8 ret; uint8 status, ssize; ret = send_packet(cmd, size); ret = send_packet(&status_cmd, 1); ssize = sizeof(status); ret = get_packet(&status, &ssize); debugf("status: %02X\n", status); return ret; }
void tiva_main()
{
send_commnad(&ping_cmd, 1);
}
Output from my debug interface:
-c2- <-- expected 0xCC = COMMAND_ACK -c2- <-- expected 0xCC = COMMAND_ACK psize = c2 <-- expected 1 pchecksum = f0 <-- expected 0x40 status: fc <-- expected 0x40 = COMMAND_RET_SUCCESS
Any ideas?