SPI transfer LSB first

19 Apr 2011

Hello, I have an IC that needs requires 8bit data transfers that are LSB first. I do not want to swap the order of the bits in a byte before I send it(not elegant).

On page 407 of the datasheet has a bit 6 called LSBF. I need to set this bit.

I have tried to use the spi object like normal (set speed and format CPHA = 1 CPOL = 1 ) and then set the bit via LPC_SPI->SPCR But it does not work. Also my speed and format bits don't show up when I read the SPCR register.

Jeff

19 Apr 2011

I am getting by with the bit swapping code below but I would like to have control over the registers.

I found some bit swapping code here: http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith64BitsDiv

cmd = ((cmd * 0x0802LU & 0x22110LU) | (cmd * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;

BTW, love the mBed.

19 Apr 2011

Not that it helps much, but you can use the __RBIT() CMSIS intrinsic to reverse bits in a 32-bit word.

19 Apr 2011

Could you show us the code you use to set the LSBF bit?

19 Apr 2011

The mouse uses MSB first transfers and the WTV020 uses LSB first so I switch it to LSB then back to MSB.

@Igore I have seen in a post you used LPC_WDT. This is what inspired me to try LPC_SPI.

void WTV_SendCommand(unsigned char cmd)
{
    uint32_t spi_control_reg_32 = 0xaaaaaaaa;

    //cmd = ((cmd * 0x0802LU & 0x22110LU) | (cmd * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
    
    //Reset 5ms low 5ms high
    DO_WTV020_RESET_NOT = 0;
    Delay_ms(5);
    DO_WTV020_RESET_NOT = 1;

    Delay_ms(4);
    MOUSE_DisableUpdates();
    Delay_ms(1);

    SPI_SetSpeed(2500);

    spi_control_reg_32 = LPC_SPI->SPCR;
    DEBUG_PRINTF("spi_control_reg_32 = %X\r\n", spi_control_reg_32);

    spi_control_reg_32 = spi_control_reg_32 | 0x00000040; //Set LSBF bit (LSB first)
    DEBUG_PRINTF("spi_control_reg_32 s = %X\r\n", spi_control_reg_32);

    LPC_SPI->SPCR = spi_control_reg_32;

    DO_WTV020_SS = 0;
    Delay_ms(5);

    SPI_SendChar(cmd);

    spi_control_reg_32 = spi_control_reg_32 & 0xFFFFFFBF; /* Clear LSBF bit (MSB first) */
    DEBUG_PRINTF("spi_control_reg_32 c = %X\r\n", spi_control_reg_32);
    
    Delay_ms(1);
    LPC_SPI->SPCR = spi_control_reg_32;
    
    DO_WTV020_SS = 1;
        
    SPI_Init(); //set spi back to fast speed
    MOUSE_EnableUpdates();
}
19 Apr 2011

Here is my guess at what is going on.

The LPC1768 implements two SSP controllers, and one SPI controller. Controller SSP0 shares the same pins as the SPI controller. On page 401 of the User Manual, there is the following remark:

Quote:

Remark: SSP0 is intended to be used as an alternative for the SPI interface, which is included as a legacy peripheral. Only one of these peripherals can be used at the any one time.

The mbed library is no doubt using SSP0 and SSP1. You are trying to access the SPI port, and are not able to because SSP0 is already enabled. That would be why you don't see your speed and format bits show up when you read the SPI status register.

If you disable SSP0 and then remove its power and clock, then enable power and clock for the SPI controller, that may get you going. (You might find it helpful to check the code in the CMSIS driver library to see how the SPI and SSP initialization is handled.)

19 Apr 2011

Hexley / Igore,

Thank you for your help. This explains my trouble.