Use Spi : 20bits with PCS5 use as PCSS

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

Use Spi : 20bits with PCS5 use as PCSS

Jump to solution
1,229 Views
arnogir
Senior Contributor II

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?

0 Kudos
Reply
1 Solution
949 Views
RadekS
NXP Employee
NXP Employee

Hi Arnaud,

This 8bits clock pulse at beginning is dummy transfer just for switch clock to requested polarity.

Unfortunately current SPI driver is not compatible with your direct access to the registers.

I would like to propose better and simpler solution for you without such invasive modification of SPI driver.

Please use option for registering CS callback.

In this callback, you can manage your entire 8 CS signals trough GPIO pins and you don’t need any demultiplexer.

SPI example code shows how to use CS callback for one CS signal, you can extend this callback for support more signals. See code defined by BSP_SPI_MEMORY_GPIO_CS macro.

Value of cs_mask will told you which CS pin should by moved to active state. It directly fits to parameter when you open SPI driver. These values don’t need fits to any number sequence. So, if you open spi by command spifd = fopen (spi2:129, NULL);, cs_mask will be 129 at begin of correspond channel data transfer.

This allows implement your own logic and handle number SPI channels as much you need (limited by number of GPIO pins).

Note: When cs_mask=NULL, all CS signal should be set into inactive state.

I hope it helps you.

Have a great day,
RadekS

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

View solution in original post

0 Kudos
Reply
2 Replies
950 Views
RadekS
NXP Employee
NXP Employee

Hi Arnaud,

This 8bits clock pulse at beginning is dummy transfer just for switch clock to requested polarity.

Unfortunately current SPI driver is not compatible with your direct access to the registers.

I would like to propose better and simpler solution for you without such invasive modification of SPI driver.

Please use option for registering CS callback.

In this callback, you can manage your entire 8 CS signals trough GPIO pins and you don’t need any demultiplexer.

SPI example code shows how to use CS callback for one CS signal, you can extend this callback for support more signals. See code defined by BSP_SPI_MEMORY_GPIO_CS macro.

Value of cs_mask will told you which CS pin should by moved to active state. It directly fits to parameter when you open SPI driver. These values don’t need fits to any number sequence. So, if you open spi by command spifd = fopen (spi2:129, NULL);, cs_mask will be 129 at begin of correspond channel data transfer.

This allows implement your own logic and handle number SPI channels as much you need (limited by number of GPIO pins).

Note: When cs_mask=NULL, all CS signal should be set into inactive state.

I hope it helps you.

Have a great day,
RadekS

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

0 Kudos
Reply
949 Views
arnogir
Senior Contributor II

Hi

For the dummy spi transfer, to resolve it I use Mode 0 and add a NOT operator on SPI CLK.

For the CS, I seen this possibility to manage himself by GPIO.

I tested another possibility by modifying MQX SPI driver:

I Added IOCTL services.

1- Fist to have the possibility to use PCS5 as Strobe.

2- To set bit CONT on PUSHR register if configured and if not last byte.

By this way, Strobe signal stay low during spi transfer.

Thank for your help

0 Kudos
Reply