I'm writing an I2C driver for the XMC4700 and am having problems getting it to actually do anything on the I2C bus. I'm not using DAVE, or any libraries--I'm writing to the peripheral registers directly.
The hardware configuration is the XMC4700 Relax board. I'm configuring my I2C driver to use USIC channel U1C1, with the pins configured as follows: SDA (P3.15 DX0A/DOUT0), SCL (P0.13 DX1B/SCLKOUT). I have the pins themselves configured as outputs, ALT Function 2, open drain.
I have taken USIC1 and PORTS out of reset.
Here's how I have U1C1 configured:
KSCFG = USIC_CH_KSCFG_MODEN_Msk | USIC_CH_KSCFG_BPMODEN_Msk
CCR = 4
PCR = USIC_CH_PCR_IICMode_SCRIEN_Msk | USIC_CH_PCR_IICMode_RSCRIEN_Msk | USIC_CH_PCR_IICMode_PCRIEN_Msk |
USIC_CH_PCR_IICMode_NACKIEN_Msk | USIC_CH_PCR_IICMode_ARLIEN_Msk | USIC_CH_PCR_IICMode_ERRIEN_Msk |
USIC_CH_PCR_IICMode_ACKIEN_Msk | (0xa << USIC_CH_PCR_IICMode_HDEL_Pos)
DX0CR = USIC_CH_DX0CR_DSEN_Msk | 0b000
DX1CR = USIC_CH_DX1CR_DSEN_Msk | 0b001
SCTR = USIC_CH_SCTR_SDIR_Msk | (1 << USIC_CH_SCTR_PDL_Pos) | (0b11 << USIC_CH_SCTR_TRM_Pos) | (0x3f << USIC_CH_SCTR_FLE_Pos) | (7 << USIC_CH_SCTR_WLE_Pos)
TCSR = (0b01 << USIC_CH_TCSR_TDEN_Pos) | USIC_CH_TCSR_TDSSM_Msk
BRG = (9 << USIC_CH_BRG_DCTQ_Pos) | ((pdiv - 1) << USIC_CH_BRG_PDIV_Pos);
FDR = (step << USIC_CH_FDR_STEP_Pos) | (2 << USIC_CH_FDR_DM_Pos);
After setting everything up as above, I'm attempting to do an I2C write operation to an MCP9808 temperature sensor connected to the I2C bus attached to P0.13 and P3.15. Both SCL and SDA have 10K pull-ups to Vcc. There are no other I2C devices on the bus. To start the transfer, I'm writing the following to U1C1's TBUF[0] register:
TBUF[]0] = (0b100 << 8) | (slaveaddr << 1)
That should cause the USIC to initiate an I2C start condition on the bus and send the slave address on the bus. I've got a logic analyzer connected to both SCL and SDA and see no transitions on either line. When I write to TBUF[0], the only U1C1 register changes I see are these:
TCSR.TDV changes from 0 to 1
TCSR.TE changes from 0 to 1
In particular, I do not see PSR.SCR go to 1, which would indicate the START condition has been initiated. I do see that DX0CR.DXS = 1 and DX1CR.DXS = 1, which, if I'm reading the reference manual correctly, should be the current values of the bus lines. They should be high in idle state, which they are, but they should transition during a start sequence, which they don't.
Since I'm not seeing any I2C bus activity, I checked that the two ports (P0.13/P3.15) work as normal GPIO ports, and they do, both as push-pull outputs and open-drain outputs.
What am I missing here? I'm sure that I have a minor configuration error preventing things from working, but I've been over the code many times and just don't see it.