Hi kfranz,
Good question.
Let me try to answer.
I'm using the TWR-K70F120M tower kit with the TWR-MEM Rev B card to allow accessing serial flash using the SPI2 in polled mode to allow me to use IOCTL commands to change the chip select used by the SPI module.
Also using MQX3.8.1 and the C:\Freescale\Freescale MQX 3.8\mqx\examples\spi project. "spi.c" source attached.
Doing this I think I uncovered errata that I will pass along to our MQX Development team to review.
The init_spi.c in the BSP has the following:
const DSPI_INIT_STRUCT _bsp_dspi2_init = {
2, /* SPI channel */
SPI_PUSHR_PCS(1 << 0), /* Chip Select 0 */ //DES 32-bit value is 0x00010000 (big endian format)
The SPI_PUSHR_PCS is stored to a 32-bit value in the structure.
The spi_pol_dspi.c _dspi_polled_init() function does the following:
Io_info_ptr->CS = DSPI_PUSHR_PCS_GET(dspi_init_ptr->CS);
The macro will basically returns 32-bit result of 0x00000001 (big endian format) so rather than having the variable in the register format, it is now just a chip select value but note that the real chip select value is io_info_ptr->CS - 1 (i.e. value of 1 equals CS 0, value 2 equals CS 1, etc..)
The rest of the SPI driver uses the io_info_ptr->CS value/mask.
I changed the IOCTL calls GET/SET to work with value/mask rather than register format.
My example code is modifying this to allow the example to use the SPI2 CS0 or CS1 and therefore you can just change the TWR-MEM Rev B jumper J14 to test. J14 pin 1-2 is CS0 and J14 pin 2-3 is CS1.
Now that I have played with this code I think the initialization code and driver code are out of sync and will leave it to the developers to correct.
But the change I did make to the spi_pol_dspi.c is as follows:
case IO_IOCTL_SPI_GET_CS:
if (NULL == param_ptr)
{
result = SPI_ERROR_INVALID_PARAMETER;
}
else
{
*param_ptr = (io_info_ptr->CS) - 1; //DES <-updated
//DES bad format *param_ptr = DSPI_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 = (*param_ptr) + 1; //DES <-updated
//DES bad format io_info_ptr->CS = DSPI_PUSHR_PCS_GET(*param_ptr);
}
break;
In summary: You can use one fopen() call per SPI module and then use the IOCTL call to change which SPI chip select you want to use for that module.
Regards,
David