I have configured K65 controller in slave mode. When master sends a read request, i am responding with a set of 'n' number of bytes as a response, but interestingly i always see the first byte received on the master (I am using a PC based I2C tool) side is the slave ID. Per my understanding when master sends a read request, it sends slave ID, then i respond with set of bytes, not sure why i am seeing this extra byte on the master side?
Since the last byte i received is the slave ID, i am not sure if that byte within the data register is transmitted out first before the intended number of bytes transfer. I am using DMA to send the response.
Hi Kishore,
I have a demo code witch use EDMA in slave and master. It is not base on KSDK. It set register directly. Hope this can give you some help.
void dma_i2c0_send_i2c1_receive()
{
uint8 address = 0xA0;
//The data that will be sent
static uint32 dataTObeSent = 0x12345678;
//The data that will store data
static uint32 dataRead = 0;
SIM_SCGC6 |= SIM_SCGC6_DMAMUX_MASK;//enable DMA_CHAMAX
//EDMA_ERQL = 0xFFFF;
DMA_ERQ = 0xFFFF;
printf("Config DMA Mux for IIC0!\n");
// Enables the DMA channel and select the DMA Channel Source
DMAMUX_CHCFG0 = DMAMUX_CHCFG_ENBL_MASK | I2C0_DMA_CHANNEL_SOURCE;
printf("Config DMA for IIC0!\n");
// TCD Source Address
DMA_TCD0_SADDR = (uint32)&dataTObeSent;
//tcd1.saddr = 0x1FFF004c;
// Source/Destination data transfer size(8bit)
//EDMA_TCD7_ATTR = 0x0000;
DMA_TCD0_ATTR = 0x0000;
// TCD Signed Source Address Offset
//EDMA_TCD7_SOFF = 0x0001
DMA_TCD0_SOFF = 0x001;
// TCD Minor Byte Count
//EDMA_TCD7_NBYTES = 0x00000001
DMA_TCD0_NBYTES_MLOFFYES = 1;
// TCD Last Source Address Adjustment
//EDMA_TCD7_SLAST = 0x00000000
DMA_TCD0_SLAST = 0;
// Ponit to I2C0_D
//EDMA_TCD7_DADDR = 0x40066004
DMA_TCD0_DADDR = 0x40066004;
//EDMA_TCD7_CITER = 0x0004
DMA_TCD0_CITER_ELINKYES = 0x0004;
//EDMA_TCD7_DOFF = 0x0000
DMA_TCD0_DOFF = 0x0000;
//EDMA_TCD7_DLAST_SGA = 0x00000000
DMA_TCD0_DLASTSGA = 0x00000000;
//EDMA_TCD7_BITER = 0x0004
DMA_TCD0_BITER_ELINKYES = 0x0004;
//EDMA_TCD7_CSR = 0x0008
DMA_TCD0_CSR = 0x0008;
// Set Enable Request Register
DMA_SERQ = 0x00;
printf("Config DMA Mux for IIC1!\n");
// Enables the DMA channel and select the DMA Channel Source
DMAMUX_CHCFG1 = DMAMUX_CHCFG_ENBL_MASK | I2C1_DMA_CHANNEL_SOURCE;
printf("Config DMA for IIC1!\n");
printf("Config DMA for IIC1!\n");
// TCD Source Address
//EDMA_TCD8_SADDR = 0x40067004;
DMA_TCD1_SADDR = 0x40067004;
// Source/Destination data transfer size(8bit)
//EDMA_TCD8_ATTR = 0x0000
DMA_TCD1_ATTR = 0x0000;
// TCD Signed Source Address Offset
//EDMA_TCD8_SOFF = 0x0000
DMA_TCD1_SOFF = 0x0000;
// TCD Minor Byte Count
//EDMA_TCD8_NBYTES = 0x00000001
DMA_TCD1_NBYTES_MLOFFYES = 1;
// TCD Last Source Address Adjustment
//EDMA_TCD8_SLAST = 0x00000000
DMA_TCD1_SLAST = 0;
// Ponit to I2C0_D
//EDMA_TCD8_DADDR = 0x1FFF005c
DMA_TCD1_DADDR = (uint32)&dataRead;
//EDMA_TCD8_CITER = 0x0005
DMA_TCD1_CITER_ELINKYES = 0x0005;
//EDMA_TCD8_DOFF = 0x0001
DMA_TCD1_DOFF = 0x0001;
//EDMA_TCD8_DLAST_SGA = 0x00000000;
DMA_TCD1_DLASTSGA = 0x00000000;
//EDMA_TCD8_BITER = 0x0005
DMA_TCD1_BITER_ELINKYES = 0x0005;
//EDMA_TCD8_CSR = 0x0008;
DMA_TCD1_CSR = 0x0008;
// Set Enable Request Register
//EDMA_SERQ = 0x08;
DMA_SERQ = 0x00;
printf("print any key to start test\n");
in_char();
printf("Config I2C1 as Receiver!\n");
I2C1_A1 = address;
//bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
//IICEN IICIE MST TX TXAK RSTA WUEN DMAEN
//1 1 0 0 0 0 0 1
I2C1_C1 = I2C_C1_IICEN_MASK | I2C_C1_IICIE_MASK | I2C_C1_DMAEN_MASK;
printf("Config SCI0 as Transmitter!\n");
I2C0_F = 0x80;
//bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
//IICEN IICIE MST TX TXAK RSTA WUEN DMAEN
//1 1 1 1 0 0 0 1
I2C0_C1 = I2C_C1_IICEN_MASK | I2C_C1_IICIE_MASK | I2C_C1_MST_MASK | I2C_C1_TX_MASK | I2C_C1_DMAEN_MASK;
I2C0_D = address | I2C_MASTER_SEND_DATA;
//printf("Check DMA done flag!\n");
printf("check the result of slave, input any key to continue\n");
in_char();
//Little endian, and address will be sent first, so will compareed to this value
if(dataRead == ((dataTObeSent << 8) | (address & 0xFF)))
{
printf("test succeed\n");
}
else
{
printf("test fail\n");
in_char();
}
I2C0_C1 = 0x80;
I2C0_C1 = 0x00;
I2C0_C1 = 0x80;
I2C0_C1 = 0x00;
}
Regards,
Jing