K65 I2C DMA Slave operation

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

K65 I2C DMA Slave operation

624 Views
kishorebolisett
Contributor I

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.

Labels (1)
0 Kudos
1 Reply

469 Views
jingpan
NXP TechSupport
NXP TechSupport

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

0 Kudos