SPI ReadBlock doesn't work

cancel
Showing results for 
Search instead for 
Did you mean: 

SPI ReadBlock doesn't work

986 Views
jpcordovae
Contributor II

Using PE and the example found in help I'm not able to read a response of a AD7794 DAC that I have in a custom PCB.

I checked the code and SPI PE configuration several times and I'm sure to have a correct configuration, however  the driver are not able to read the block.

I suppose to reset the DAC sending 32 consecutive bits with ones (that works perfect), later I read an ID register, but the driver don't send the clock signals to read the response or even the CS lines either.

Inside of the function AD7794_Init there is a SM1_ReceiveBlock that never happen.

LDD_TError AD7794_Reset()

{

  unsigned char dataRst[5];

  dataRst[0] = 0b11111111;

  dataRst[1] = 0b11111111;

  dataRst[2] = 0b11111111;

  dataRst[3] = 0b11111111;

  if( SM1_SendBlock(SM1_DeviceData, (LDD_TData *)dataRst, (uint16_t) 4) == ERR_OK )

  {

  while (!SM1_GetBlockSentStatus(SM1_DeviceData))

  {

   SM1_Main(SM1_DeviceData);

  }

  }else{

  return ERR_OK; // to catch errors

  }

}

LDD_TError AD7794_Init()

{

  unsigned char dataInit[2] = { AD7793_COMM_READ | AD7793_COMM_ADDR(AD7793_REG_ID), 0x00 };

  if( SM1_SendBlock(SM1_DeviceData, (LDD_TData *)dataInit, (uint16_t) 1) == ERR_OK )  {

  while (!SM1_GetBlockSentStatus(SM1_DeviceData))  {

   SM1_Main(SM1_DeviceData);

  }

  }else{

  return ERR_OK; // to catch errors

  }

  unsigned char dataRX[4] = { 0x00, 0x00, 0x00, 0x00 };

  if( SM1_ReceiveBlock(SM1_DeviceData, (LDD_TData *)dataRX, (uint16_t) 1) == ERR_OK )

  {

  while(!SM1_GetBlockReceivedStatus(SM1_DeviceData))

  {

  SM1_Main(SM1_DeviceData);

  }

  }else{

  return ERR_OK; // to catch errors

  }

}

LDD_TError AD7794_GetStatus(unsigned char *_status)

{

  unsigned char data = AD7793_COMM_READ | AD7793_COMM_ADDR(AD7793_REG_STAT);

  if(SM1_SendBlock(SM1_DeviceData, (LDD_TData *)&data, (uint16_t) 1) == ERR_OK )

  {

  while (!SM1_GetBlockSenStatus(SM1_DeviceData))

  {

   SM1_Main(SM1_DeviceData);

  }

  }else{

  return ERR_OK; // to catch errors

  }

  if( SM1_ReceiveBlock(SM1_DeviceData, (LDD_TData *)_status, (uint16_t) 1) == ERR_OK )

  {

  while(!SM1_GetBlockReceivedStatus(SM1_DeviceData))

  {

  SM1_Main(SM1_DeviceData);

  }

  }else{

  return ERR_OK; // to catch errors

  }

  return ERR_OK;

}

/*lint -save  -e970 Disable MISRA rule (6.3) checking. */

int main(void)

/*lint -restore Enable MISRA rule (6.3) checking. */

{

  /* Write your local variable definition here */

  /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/

  PE_low_level_init();

  /*** End of Processor Expert internal initialization.                    ***/

  /* Write your code here */

  SM1_SelectConfiguration(SM1_DeviceData, 0U, 0U);

  AD7794_Reset();

  AD7794_Init();

  unsigned char bufferRX[4] = { 0x00, 0x00, 0x00, 0x00 };

  //AD7794_GetStatus(bufferRX);

  /*while(1){

   AD7794_GetStatus(bufferRX);

   bufferRX[0] = 0x00;

  }*/

  /*** Don't write any code pass this line, or it will be deleted during code generation. ***/

  /*** RTOS startup code. Macro PEX_RTOS_START is defined by the RTOS component. DON'T MODIFY THIS CODE!!! ***/

  #ifdef PEX_RTOS_START

    PEX_RTOS_START();                  /* Startup of the selected RTOS. Macro is defined by the RTOS component. */

  #endif

  /*** End of RTOS startup code.  ***/

  /*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/

  for(;;){}

  /*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/

} /*** End of mainroutine. DO NOT MODIFY THIS TEXT!!! ***/

the ndBlock(SM1_Devi

ndBlock(SM1_Devi

Labels (1)
0 Kudos
4 Replies

469 Views
Jorge_Gonzalez
NXP Employee
NXP Employee

Hello Juan Pablo Echeverria:

The ReceiveBlock() method prepares some buffers to receive data. However for the SPI module to send the clock you need to "send dummy bytes" by using the SendBlock() API. The block sent must have the same size as the expected number of bytes to receive.

I hope this helps. Let me know if you have doubts.

Best regards,

Jorge Gonzalez

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

469 Views
jpcordovae
Contributor II

Hi Jorge,

it was very helpful, I fixed the functions and now I'm reading without problems.

Thanks you.

JP

0 Kudos

469 Views
sruthyuk
Contributor I

hi Juan,

Could you please post the entire code of ur project?? Am also trying to  read a response of a AD5421 DAC. But the SPI transmission is not working properly in MK60FX512 while interfacing with DAC. Is ur SPI is working properly without using interrupt event??

Please reply me as soon as possible.

Regards,

Sruthy UK

0 Kudos

469 Views
jpcordovae
Contributor II

hi sruthy_uk,

here the relevant code:

/*******************************************************************************

* Definitions

******************************************************************************/

#define DSPI_MASTER_BASE (SPI0_BASE)

#define DSPI_MASTER_BASEADDR ((SPI_Type *) DSPI_MASTER_BASE)

#define DSPI_MASTER_CLK_SRC (DSPI0_CLK_SRC)

#define TRANSFER_SIZE (256)         /*! Transfer size */

#define TRANSFER_BAUDRATE (500000U) /*! Transfer baudrate - 500k */

void SetSPIConfig()

{

  dspi_master_config_t masterConfig;

  uint32_t sourceClock;

  status_t status;

  /*Master config*/

  masterConfig.whichCtar = kDSPI_Ctar0;

  masterConfig.ctarConfig.baudRate = TRANSFER_BAUDRATE;

  masterConfig.ctarConfig.bitsPerFrame = 8;

  masterConfig.ctarConfig.cpol = kDSPI_ClockPolarityActiveLow;

  masterConfig.ctarConfig.cpha = kDSPI_ClockPhaseSecondEdge;

  masterConfig.ctarConfig.direction = kDSPI_MsbFirst;

  masterConfig.ctarConfig.pcsToSckDelayInNanoSec = 2000;

  masterConfig.ctarConfig.lastSckToPcsDelayInNanoSec = 2000;

  masterConfig.ctarConfig.betweenTransferDelayInNanoSec = 1000;

  masterConfig.whichPcs = kDSPI_Pcs1;

  masterConfig.pcsActiveHighOrLow = kDSPI_PcsActiveLow;

  masterConfig.enableContinuousSCK = false;

  masterConfig.enableRxFifoOverWrite = false;

  masterConfig.enableModifiedTimingFormat = false;

  masterConfig.samplePoint = kDSPI_SckToSin0Clock;

  NVIC_SetPriority(SPI0_IRQn, 6);

  sourceClock = CLOCK_GetFreq(DSPI_MASTER_CLK_SRC);

  status = DSPI_RTOS_Init(&master_rtos_handle, DSPI_MASTER_BASEADDR, &masterConfig, sourceClock);

  if (status != kStatus_Success)

  {

  PRINTF("DSPI master: error during initialization. \r\n");

  //vTaskSuspend(NULL);

  }

}

pay attention to source clock and baudrate.

static void SPI_master_task(void *pvParameters)

{

    dspi_transfer_t masterXfer;

    status_t status;

    SetSPIConfig();

    /* AD7794 init and config*/

    AD7794_Reset();

    AD7794_Init();

    AD7794_Config();

    AD7794_GetStatus();

    /*Start master transfer*/

    masterSendBuffer[0] = 0xFF;

    masterSendBuffer[1] = 0xFF;

    masterSendBuffer[2] = 0xFF;

    masterSendBuffer[3] = 0xFF;

    masterXfer.txData = masterSendBuffer;

    masterXfer.rxData = masterReceiveBuffer;

    masterXfer.configFlags = kDSPI_MasterCtar0 | kDSPI_MasterPcs1 | kDSPI_MasterPcsContinuous;

    masterXfer.dataSize = 4;

    //RESET

    PRINTF("Reset AD7794\r\n");

    status = DSPI_RTOS_Transfer(&master_rtos_handle, &masterXfer);

    vTaskDelay( 500/portTICK_PERIOD_MS );

    // Init

    ClearSPIBuffers();

    masterSendBuffer[0] = AD7793_COMM_READ | AD7793_COMM_ADDR(AD7793_REG_ID);

    masterXfer.dataSize = 2;

    status = DSPI_RTOS_Transfer(&master_rtos_handle, &masterXfer);

    PRINTF("Init AD7794: 0x%02x\r\n",masterReceiveBuffer[1]);

    // Status

    ClearSPIBuffers();

    masterSendBuffer[0] = AD7793_COMM_READ | AD7793_COMM_ADDR(AD7793_REG_STAT);

    masterXfer.dataSize = 2;

  status = DSPI_RTOS_Transfer(&master_rtos_handle, &masterXfer);

  PRINTF("Status AD7794: 0x%02x\r\n",masterReceiveBuffer[1]);

  // get Mode register

  ClearSPIBuffers();

  masterSendBuffer[0] = AD7793_COMM_READ | AD7793_COMM_ADDR(AD7793_REG_MODE);

  masterXfer.dataSize = 3;

  status = DSPI_RTOS_Transfer(&master_rtos_handle, &masterXfer);

  PRINTF("Mode AD7794: 0x%02x%02x\r\n",masterReceiveBuffer[1],masterReceiveBuffer[2]);

  // configuration register

  ClearSPIBuffers();

  masterSendBuffer[0] = AD7793_COMM_READ | AD7793_COMM_ADDR(AD7793_REG_CONF);

  masterXfer.dataSize = 3;

  status = DSPI_RTOS_Transfer(&master_rtos_handle, &masterXfer);

  PRINTF("Conf AD7794: 0x%02x%02x\r\n",masterReceiveBuffer[1],masterReceiveBuffer[2]);

  // IO register

  ClearSPIBuffers();

  masterSendBuffer[0] = AD7793_COMM_READ | AD7793_COMM_ADDR(AD7793_REG_IO);

  masterXfer.dataSize = 2;

  status = DSPI_RTOS_Transfer(&master_rtos_handle, &masterXfer);

  PRINTF("IO  AD7794: 0x%02x\r\n",masterReceiveBuffer[1]);

  // modify configuration register

  ClearSPIBuffers();

  masterSendBuffer[0] = AD7793_COMM_WRITE | AD7793_COMM_ADDR(AD7793_REG_CONF);

  masterXfer.dataSize = 3;

  PRINTF("modifying configuration register\r\n");

  PRINTF("CON15: VBIAS1  : 0 Bias voltaje generator disabled. \r\n");

  PRINTF("CON14: VBIAS2  : 0 \r\n");

  PRINTF("CON13: BO      : 0 Burnout Current Enable Bit. \r\n");

  PRINTF("CON12: U/!B    : 0 Bipolar \r\n");

  PRINTF("CON11: BOOST   : 0 \r\n");

  PRINTF("CON10: G2      : 0  Set to G=1 / 2.5V\r\n");

  PRINTF("CON09: G1      : 0 \r\n");

  PRINTF("CON08: G0      : 0 \r\n");

  PRINTF("CON07: REFSEL1 : 0 External reference applied between REFIN1(+) and REFIN1(-).\r\n");

  PRINTF("CON06: REFSEL0 : 0 \r\n");

  PRINTF("CON05: REF_DET : 0 NOXREF bit in the status register indicates when the external reference being used by the ADC is open circuit or less than 0.5 V. \r\n");

  PRINTF("CON04: BUF     : 1 \r\n");

  PRINTF("CON03: CH3     : 0 AIN1(+)/AIN1(-) | Calibration Pair 0 .\r\n");

  PRINTF("CON03: CH2     : 0 \r\n");

  PRINTF("CON03: CH1     : 0 \r\n");

  PRINTF("CON03: CH0     : 0 \r\n");

  masterSendBuffer[1] = 0b00000000;

  masterSendBuffer[2] = 0b00010000;\

  status = DSPI_RTOS_Transfer(&master_rtos_handle, &masterXfer);

  vTaskDelay( 2000/portTICK_PERIOD_MS );

  // configuration register

  ClearSPIBuffers();

  masterSendBuffer[0] = AD7793_COMM_READ | AD7793_COMM_ADDR(AD7793_REG_CONF);

  masterXfer.dataSize = 3;

  status = DSPI_RTOS_Transfer(&master_rtos_handle, &masterXfer);

  PRINTF("Conf AD7794: 0x%02x%02x\r\n",masterReceiveBuffer[1],masterReceiveBuffer[2]);

  // set current sources at 210uA

  ClearSPIBuffers();

  masterSendBuffer[0] = AD7793_COMM_WRITE | AD7793_COMM_ADDR(AD7793_REG_IO);

  masterSendBuffer[1] = 0b00000010;

  PRINTF("Setting IO Register\r\n");

  PRINTF("IO7 :          : 0 \r\n");

  PRINTF("IO6 : IOEN     : 0 \r\n");

  PRINTF("IO5 : IO2DAT   : 0 \r\n");

  PRINTF("IO4 : IO1DAT   : 0 \r\n");

  PRINTF("IO3 : IEXCDIR1 : 0 Current Source IEXC1 connected to Pin IOUT1. Current Source IEXC2 connected to Pin IOUT2.\r\n");

  PRINTF("IO2 : IEXCDIR0 : 0 \r\n");

  PRINTF("IO1 : IEXCEN1  : 1 210 uA\r\n");

  PRINTF("IO0 : IEXCEN0  : 0 \r\n");

  masterXfer.dataSize = 2;

  status = DSPI_RTOS_Transfer(&master_rtos_handle, &masterXfer);

  vTaskDelay( 2000/portTICK_PERIOD_MS );

  //Checking IO registers

  ClearSPIBuffers();

  masterSendBuffer[0] = AD7793_COMM_READ | AD7793_COMM_ADDR(AD7793_REG_IO);

  masterXfer.dataSize = 2;

  status = DSPI_RTOS_Transfer(&master_rtos_handle, &masterXfer);

  PRINTF("IO  AD7794: 0x%02x\r\n",masterReceiveBuffer[1]);

  //TickType_t xDelay = 1000 / portTICK_PERIOD_MS;

  // set mode register

  ClearSPIBuffers();

  masterSendBuffer[0] = AD7793_COMM_WRITE | AD7793_COMM_ADDR(AD7793_REG_MODE);

  masterXfer.dataSize = 3;

  PRINTF("MR15  : MD2       : 0 Continuous Conversion Mode. \r\n");

  PRINTF("MR14  : MD1       : 0 \r\n");

  PRINTF("MR13  : MD0       : 0 \r\n");

  PRINTF("MR12  : PSW       : 1 Set by user to close the power switch PSW to GND.\r\n");

  PRINTF("MR11  :           : 0 \r\n");

  PRINTF("MR10  :           : 0 \r\n");

  PRINTF("MR09  : AMP-CM    : 1 \r\n");

  PRINTF("MR08  :           : 0 \r\n");

  PRINTF("MR07  : CLK1      : 0 Internal 64 kHz clock. Internal clock is not available at the CLK pin.\r\n");

  PRINTF("MR06  : CLK0      : 0 \r\n");

  PRINTF("MR05  :           : 0 \r\n");

  PRINTF("MR04  : CHOP-DIS  : 0 Chop disabled\r\n");

  PRINTF("MR03  : FS3       : 1 fadc 4.17, Tsettle 480ms, \r\n");

  PRINTF("MR02  : FS2       : 1 \r\n");

  PRINTF("MR01  : FS1       : 1 \r\n");

  PRINTF("MR00  : FS0       : 1 \r\n");

  /*ClearSPIBuffers();

  masterSendBuffer[0] = AD7793_COMM_WRITE | AD7793_COMM_ADDR(AD7793_REG_MODE);

  masterSendBuffer[1] = 0b11010000;

  masterSendBuffer[2] = 0b00011111;

  status = DSPI_RTOS_Transfer(&master_rtos_handle, &masterXfer);

  vTaskDelay( 4000/portTICK_PERIOD_MS );*/

  /*ClearSPIBuffers();

  masterSendBuffer[0] = AD7793_COMM_WRITE | AD7793_COMM_ADDR(AD7793_REG_MODE);

  masterSendBuffer[1] = 0b10110000;

  masterSendBuffer[2] = 0b00011111;

  status = DSPI_RTOS_Transfer(&master_rtos_handle, &masterXfer);

  vTaskDelay( 4000/portTICK_PERIOD_MS );*/

  ClearSPIBuffers();

  masterSendBuffer[0] = AD7793_COMM_WRITE | AD7793_COMM_ADDR(AD7793_REG_MODE);

  masterSendBuffer[1] = 0b00010000;

  masterSendBuffer[2] = 0b00001111;

  status = DSPI_RTOS_Transfer(&master_rtos_handle, &masterXfer);

  vTaskDelay( 1000/portTICK_PERIOD_MS );

  // get Mode register

  ClearSPIBuffers();

  masterSendBuffer[0] = AD7793_COMM_READ | AD7793_COMM_ADDR(AD7793_REG_MODE);

  masterXfer.dataSize = 3;

  status = DSPI_RTOS_Transfer(&master_rtos_handle, &masterXfer);

  PRINTF("Mode AD7794: 0x%02x%02x\r\n",masterReceiveBuffer[1],masterReceiveBuffer[2]);

  //EnableSPIDataInInterrupt();

  // write continuous read mode

  ClearSPIBuffers();

  //masterSendBuffer[0] = AD7793_COMM_READ | AD7793_COMM_ADDR(AD7793_REG_DATA) | 0b00000100;

  masterSendBuffer[0] = 0b01011100;

  masterXfer.dataSize = 1;

  status = DSPI_RTOS_Transfer(&master_rtos_handle, &masterXfer);

  vTaskDelay( 2000/portTICK_PERIOD_MS );

  uint32_t tmp2;

  while(1)

  {

  //PRINTF("ENTERING TO LOOP.\r\n");

  //xSemaphoreTake(AD7794_sem,portMAX_DELAY);

  //SetSPIConfig();

  //Read ADC channel 1

  vTaskDelay( 480/portTICK_PERIOD_MS );

  ClearSPIBuffers();

  //masterSendBuffer[0] = AD7793_COMM_READ | AD7793_COMM_ADDR(AD7793_REG_DATA) | 0b00000100;

  //masterSendBuffer[0] = 0b01011100;

  masterXfer.dataSize = 3;

  status = DSPI_RTOS_Transfer(&master_rtos_handle, &masterXfer);

  tmp2 = (((uint32_t)masterReceiveBuffer[0])<<16) + (((uint32_t)masterReceiveBuffer[1])<<8) + ((uint32_t)masterReceiveBuffer[2]);

  double dmV = ( tmp2 / pow(2.0,23) - 1.0)*1.05;

  PRINTF("ADC DATA Value: 0x%02x%02x%02x  %.3f mV\r\n",masterReceiveBuffer[0],masterReceiveBuffer[1],masterReceiveBuffer[2], dmV*1000 );

  //EnableSPIDataInInterrupt();

  }

    vTaskSuspend(NULL);

}

This is a test code working with no problem. At the end was more easy to use DSPI_RTOS_Transfer in Kinetis SDK 2.x and FreeRTOS than use PE with all the fancy and bugged stuffs.

I can´t send complete code given my contract, but I could share more config files if you need it by PM.

Regards,

JP

0 Kudos