0
votes

Welcome. For a few days I'm trying to get the correct answer from the PS2 PAD on the STM32F411RE nucleo. I use SPI and USART to receive messages. The clock frequency is set to 8MHz, in SPI prescaler 64 configuration which gives me 125KHz (or KBits / s). The first bit is taken from LSB, CPOL param at 1, and CPHA on 2. NSS software controlled, set to GPIO output (PA4-CS pin). I use PA5 pins as SCK (clock) PA6-MISO, PA7-MOSI. SPI is set to Full-Duplex Master mode. (USART asynchronous and 9600Bits / s but it's just for receiving messages on a PC). I would add that the microcontroller operates at HAL library. In the main.c file:

#define CS_LOW HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET)
#define CS_HIGH HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET)

CS LOW - sets the line "attetion" to state 0 and CS_HIGH to state 1. Functinon sending command and return data(MISO-MOSI):

uint8_t PS2_RWByte(uint8_t komenda, uint8_t tablica, int wielkosc)
   {
     HAL_SPI_Transmit(&hspi1, &komenda, sizeof(komenda), 1);
     HAL_SPI_Receive(&hspi1, &tablica, sizeof(tablica), 1);
    return(tablica);
   }

Function sending a byte string:

uint8_t Get_PS2Dat(uint8_t buf[])
{
   CS_LOW;
   HAL_Delay(15/1000);
   buf[0]=PS2_RWByte(0x01, buf[0], 8);HAL_Delay(15/1000);
   buf[1]=PS2_RWByte(0x42, buf[1], 8);HAL_Delay(15/1000);
   buf[2]=PS2_RWByte(0x00, buf[2], 8);HAL_Delay(15/1000);
   buf[3]=PS2_RWByte(0x00, buf[3], 8);HAL_Delay(15/1000);
   buf[4]=PS2_RWByte(0x00, buf[4], 8);HAL_Delay(15/1000);
   buf[5]=PS2_RWByte(0x00, buf[5], 8);HAL_Delay(15/1000);
   buf[6]=PS2_RWByte(0x00, buf[6], 8);HAL_Delay(15/1000);
   buf[7]=PS2_RWByte(0x00, buf[7], 8);HAL_Delay(15/1000);
   buf[8]=PS2_RWByte(0x00, buf[8], 8);HAL_Delay(15/1000);
   CS_HIGH;
   if((buf[0]==0xff)&&(buf[1]==0x41)&&(buf[2]==0x5a))
   return 1;
   if((buf[0]==0xff)&&(buf[1]==0x73)&&(buf[2]==0x5a))
   return 2;
   return 0;
   }

In main function:

int main(void){
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_SPI1_Init();
HAL_SPI_MspInit(&hspi1);
uint8_t PS2buf[10]={0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
uint8_t wyswietl[30]={0};
while (1)
{Get_PS2Dat(PS2buf);
     for(int i=0;i<9;i++)
     {
     sprintf(wyswietl,"%u ,",PS2buf[i]);
     HAL_UART_Transmit(&huart2,wyswietl,30,250);
     }
 sprintf(wyswietl,"\n\r");
 HAL_UART_Transmit(&huart2,wyswietl,30,250);
 HAL_Delay(300);
 }
 }

After sending the information: 0x01 0x42 0x00 0x00 0x00 I should get 0xFF 0x41 0x5A 0xFF 0xFF if no button is pressed. At 3 and 4 bytes should appear information about the pressed keys while I get such values: 65, 255, 255, 255, 255 ie 0xFF 0xFF 0xFF 0xFF 0xFF. It is strange how the second sent byte corresponds to the first received. The additional point is that if you press the "mode" key the value 65 changes to 115 (0x73), while others still remain unchanged. I provide link to support page:

PlayStation 2 Controller Interface

I will also add that is exactly this PAD:

Link to page

Maybe someone comes up with some idea. Please help me. :)

2

2 Answers

2
votes

You should use HAL_SPI_TransmitReceive instead of a combination of HAL_SPI_Transmit and HAL_SPI_Receive.

  • The function HAL_SPI_Transmit only sends data and omit incoming bytes.
  • The function HAL_SPI_Receive sends dummy data and fetches incoming bytes.

So basicly what you receiving is every second character. 65 = 0x42 is the second character. Because you send a dummy byte when you receive data the remaining message is not understood by the ps2 controller so you get 0xFF.

Change your PS2_RWByte function like that and it should work:

uint8_t PS2_RWByte(uint8_t komenda, uint8_t tablica, int wielkosc)
{
  HAL_SPI_TransmitReceive(&hspi1, &komenda, &tablica, sizeof(uint8_t), 1);
  return(tablica);
}
0
votes

Ian not familiar with ps2 pad , but I believe you have to set the NSS pin back to high after your spi-receive . ( So you need also set to low before every single writing ...)