How to activate CS on SPI2 Kinetis

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

How to activate CS on SPI2 Kinetis

Jump to solution
1,501 Views
OldNick
Contributor IV

OK,

stupid question time again folks. :robotsad:

 

Running the SPI master example code from the tower, and ported to my target (K20)

 

I have attached my SPI memory device to SPI2 (pins 144-141 on QFP), and configured the IO init to alt 2 for those pins.

(Cannot use SPI2_PCS0 because the flexbus wants that pin, so expect to use SPI2_PCS1 as a negated CS)

 

user config enables spi2:

fopen works, and pushes pin 144 high.

 

bus accesses drive clock cycles, but CS stays high forever.

 

RM says you con't need a callback for DSPI in Kinetis.  Polled driver seems loop from 1 to 8 looking for an appropriate CS but then skips assertion becasue callback is NULL.

 

Tried setting CS to 1 using IOCTL call

param = 1;

ioctl (spifd, IO_IOCTL_SPI_SET_CS, &param)

 

Any ideas? Documentation is as helpful as ever.

0 Kudos
1 Solution
525 Views
PetrM
Senior Contributor I

Hello,

 

sorry for confusion, the CS settings have their history...

Anyway, ioctls SET_CS and GET_CS operate with the same alignment as used in spi_init structure, so:

 

const DSPI_INIT_STRUCT _bsp_dspi2_init = {
   2,                                                     /* SPI channel                     */
   SPI_PUSHR_PCS(1 << 2),        /* Chip Select 2                   */
   ...

}

 

param = SPI_PUSHR_PCS(1 << 2);

ioctl (spi_fd, IO_IOCTL_SPI_SET_CS, &param);

 

ioctl (spi_fd, IO_IOCTL_SPI_GET_CS, &param);

if (param == SPI_PUSHR_PCS(1 << 2)) ...

 

io_info_ptr->CS holds the bits aligned starting with bit 0, the driver is aware of that.

 

PetrM

 

View solution in original post

0 Kudos
3 Replies
525 Views
MarkP_
Contributor V

Hi OldNick,

there are BSP-dependant initialization files in directory ..\Freescale MQX 3.7\mqx\source\bsp\twrk60n512.

Check files:

1) init_spi.c: Change to CS1:

SPI_PUSHR_PCS(1 << 0),        /* Chip Select 0                   */

 

2) init_gpio.c, function _bsp_dspi_io_init()

need DSPI0.PCS0/PCS1 changes

 

(Noticed these files when changing uart ports: the function _bsp_serial_io_init() need changes)

 

BR,

Mark

 

 

0 Kudos
525 Views
OldNick
Contributor IV

Thanks Mark you're a star

,

Had already done the gpio_init which sets the pin multiplexer

 

Then, after posting I stepped through the init and found the reference to the _bsp_init_spi2 but could not find where that was defined. (IAR cannot find the definition or reference cos its in the library, so had to use explorer "find" on the mqx directories, ugh!)

 

About an hour later, made a guess and changed the appropriate line to

SPI_PUSHR_PCS(2 << 0),        /* Chip Select 1?                  */

and the hardware started working.

 

As ever, there is no information on any of this in MQXIOUG.pdf:robotmad:

 

Now, if you look in the DSPI IOCTRL function (buried 4 layers deep in the call stack) there is a get CS and a set CS function.  These are mentioned in the documentation but with no clue about what the valid parameter values should be.

 

Get CS with my new init now returns 1million or so.

Set CS during runtime did not work. At all.

 

fragment from spi_pol_dspi.c

        case IO_IOCTL_SPI_GET_CS:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                *param_ptr = SPI_PUSHR_PCS(io_info_ptr->CS);
            }
            break;
        case IO_IOCTL_SPI_SET_CS:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                io_info_ptr->CS = SPI_PUSHR_PCS_GET(*param_ptr);
            }
            break;

and the two macros are

1.

#define SPI_PUSHR_PCS(x)                         (((uint32_t)(((uint32_t)(x))<<SPI_PUSHR_PCS_SHIFT))&SPI_PUSHR_PCS_MASK)
//from MK40X256VMD100.h

2.

#define SPI_PUSHR_PCS_GET(x)    (((x) & SPI_PUSHR_PCS_MASK) >> SPI_PUSHR_PCS_SHIFT) //from spi_dspi_prv.h

Unless I am mistaken, these two IOctrl calls are wrong. SET_CS does not affect the control register, and GET_CS hits the control register, and thinks it is getting a return value from the SET macro.

 

Will hope for clarification from Freescale/EA, but not holding my breath.

0 Kudos
526 Views
PetrM
Senior Contributor I

Hello,

 

sorry for confusion, the CS settings have their history...

Anyway, ioctls SET_CS and GET_CS operate with the same alignment as used in spi_init structure, so:

 

const DSPI_INIT_STRUCT _bsp_dspi2_init = {
   2,                                                     /* SPI channel                     */
   SPI_PUSHR_PCS(1 << 2),        /* Chip Select 2                   */
   ...

}

 

param = SPI_PUSHR_PCS(1 << 2);

ioctl (spi_fd, IO_IOCTL_SPI_SET_CS, &param);

 

ioctl (spi_fd, IO_IOCTL_SPI_GET_CS, &param);

if (param == SPI_PUSHR_PCS(1 << 2)) ...

 

io_info_ptr->CS holds the bits aligned starting with bit 0, the driver is aware of that.

 

PetrM

 

0 Kudos