AnsweredAssumed Answered

Use Spi : 20bits with PCS5 use as PCSS

Question asked by arnogir on May 6, 2015
Latest reply on May 7, 2015 by arnogir

Hello

 

I'm using the K60 with MQX 4.1.1

I need to communicate with a Stepper Motor driver (TMC262).

 

The need of this component is following:

CLK Idle at High State.

Take Rising edge of CLK

 

SPI with 20 bits of data. Buffer is taken on ChipSelect Rising edge.

 

Then I have the following code ( Initialize SPI and then send 5 sequences of 24bits (20 bits used) ):

    DV_Tmc262_SpiComponent = fopen("spi0:1", NULL);
    if (NULL == DV_Tmc262_SpiComponent[MotorID])
    {
      printf("\n DV_Tmc262_Init failed!!!\n");
      return;
    }
    /* Set channel BaudRate */
    Param =DV_TMC262_SPI_CHANNEL_BAUD_RATE;
    ioctl(DV_Tmc262_SpiComponent, IO_IOCTL_SPI_SET_BAUD, &Param);
    /* Set channel as MasterMode */
    Param  = SPI_DEVICE_MASTER_MODE;
    ioctl(DV_Tmc262_SpiComponent,IO_IOCTL_SPI_SET_TRANSFER_MODE , &Param);
    /* Set channel Transmission mode: Clock signal inactive high and bit sampled on rising edge. */
    Param  = SPI_CLK_POL_PHA_MODE3;
    ioctl(DV_Tmc262_SpiComponent, IO_IOCTL_SPI_SET_MODE, &Param);
  
    /* Set Frame size Transmission mode */
    Param  = 8;
    ioctl(DV_Tmc262_SpiComponent, IO_IOCTL_SPI_SET_FRAMESIZE, &Param);
  
    /* Set Full-Duplex mode (In Read, send data en Read received data in the same buffer */
    Param  = SPI_FLAG_FULL_DUPLEX;
    ioctl(DV_Tmc262_SpiComponent, IO_IOCTL_SPI_SET_FLAGS, &Param);

    ioctl(DV_Tmc262_SpiComponent, IO_IOCTL_SPI_GET_MODE, &Param);
    ioctl(DV_Tmc262_SpiComponent, IO_IOCTL_SPI_GET_CS, &Param);

    /* send initial configuration */
//debug
Debug_Toggle_Pin1();    
    DV_Tmc262_SendBuffer(DV_TMC262_InitCfg_DrvCtrl, MotorID);  
    DV_Tmc262_SendBuffer(DV_TMC262_InitCfg_ChopConf, MotorID);
    DV_Tmc262_SendBuffer(DV_TMC262_InitCfg_SmartEn, MotorID);
    DV_Tmc262_SendBuffer(DV_TMC262_InitCfg_SgsConf, MotorID);
    DV_Tmc262_SendBuffer(DV_TMC262_InitCfg_DrvConf, MotorID);

**********
uint8_t DV_Tmc262_SendBuffer(
 uint8_t*  Buffer,
 tDV_Tmc262_MotorID MotorID  
 )
 {  
 uint8_t ReturnValue;
 
 /* Send 1 word of 3 Bytes : 24bits */  
 ReturnValue = fread(Buffer, 3, 1, DV_Tmc262_SpiComponent[MotorID]);
 
 /* Wait till transfer end (and deactivate CS) */
 fflush(DV_Tmc262_SpiComponent[MotorID]);
 
 /* Return the number of read word */
 return(ReturnValue);
 
 }
 

 

 

With this code, this work correctly. 24 Bits are sent with sequence of 3x 8bits. A small time is inserted between each 8 bits but this not important for the TMC262.

We can see before the first 24bits transmission a 8bits clock pulse. But this is ok for us because Chip select stay High during these clock pulses. Then Not taken by the TMC262:

 

TEK00003.jpg

 

TEK00004.jpg

 

 

But now,, I need to drive 8 TMC262.

Like there is no CS pin on one SPI, I want use the SS signal (replace CS5) and the with CS0, CS1 and CS4 drive a 3 to 8 Demultiplexer to drive 8 TMC262.

Like MQX has no option to use the SS mode, I add this code before start SPI fopen...:

 

SPI0_MCR |= SPI_MCR_PCSSE_MASK;

 

But with this, I have many problem!

 

First, the 8 wast bits clock before first real transmission is a problem because during this time, PCS5/SS goes low. Then one of the 8 TMC will receive a CS goes low and will taken into account these 8 wast clk edge!

We can see on the same screenshoot, that for the first call of fread, Clock goes low.

TEK00000.jpg

 

The second problem is that PCS5/SS return High between each 8 bits transmission. Then, I can't transmit at least 20 bits without CS return High!

I tried to change with IOCtl IO_IOCTL_SPI_SET_FRAMSIZE to 20, but the maximum is 16!

Then how drive with PCS5 in SS mode a component which need 20bits?

 

TEK00001.jpg

 

Anybody has Idea to solve my  two problems?

Attachments

Outcomes