'How to use STM32 to read signal from the PS2 hand controller through SPI protocol?
I have a project where I need to connect a PS2 hand controller to my microcontroller (STM32F4 series) to control a robot. I want to use the controller to read the signals from the buttons and joystick on that hand controller via SPI communication using DMA to avoid missing events from PS2. Then, I can control my robot's direction, speed, and switch between several operating modes.
Currently, I am first building a small program to test the signal transmission between the microcontroller and the ps2 controller. I created variables for each button on the handler, and then each time I press a button, the corresponding variable should increase by one. However, it seems that my MCU cannot receive the signal from the ps2 yet because when I connect and press the buttons, the program still cannot run as expected. I have also attached my main code below.
#include "main.h"
/* Private variables ---------------------------------------------------------*/
#define spi_enable HAL_GPIO_WritePin(NSS_GPIO_Port, NSS_Pin, GPIO_PIN_RESET)
#define spi_disable HAL_GPIO_WritePin(NSS_GPIO_Port, NSS_Pin, GPIO_PIN_SET)
SPI_HandleTypeDef hspi1;
DMA_HandleTypeDef hdma_spi1_rx;
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_SPI1_Init(void);
uint8_t HC_PS2_RX[8];
uint8_t HC_PS2_TX[8]={0x01, 0x42};
uint8_t anl_btn=0, start=0, up=0, right=0, down=0, left=0; //buttons in uint8_t HC_PS2_RX[3]
uint8_t l2=0, r2=0, l1=0, r1=0, triag=0, o_btn=0, x_btn=0, sqr=0; //buttons in uint8_t HC_PS2_RX[4]
int main(void)
{
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_SPI1_Init();
while (1)
{
spi_enable;
HAL_SPI_TransmitReceive_DMA(&hspi1, HC_PS2_TX, HC_PS2_RX, 8);
spi_disable;
}
}
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi){
if (HC_PS2_RX[3] == 0xF7) //press start button
start++;
else if (HC_PS2_RX[3] == 0xFE) //press ANALOG button
up++;
else if (HC_PS2_RX[3] == 0xEF) //press up button
up++;
else if (HC_PS2_RX[3] == 0xDF) //press right button
right++;
else if (HC_PS2_RX[3] == 0xBF) //press down button
down++;
else if (HC_PS2_RX[3] == 0x7F) //press left button
left++;
else if (HC_PS2_RX[4] == 0x7F) //press square button
sqr++;
else if (HC_PS2_RX[4] == 0xBF) //press X button
x_btn++;
else if (HC_PS2_RX[4] == 0xDF) //press circle button
o_btn++;
else if (HC_PS2_RX[4] == 0xEF) //press triangle button
triag++;
else if (HC_PS2_RX[4] == 0xF7) //press R1 button
r1++;
else if (HC_PS2_RX[4] == 0xFB) //press L1 button
l1++;
else if (HC_PS2_RX[4] == 0xFD) //press R2 button
r2++;
else if (HC_PS2_RX[4] == 0xFE) //press L2 button
l2++;
}
I also attached the ps2's message format that i found for anyone who wants to refer.

I'm still fairly new to embedded programming so can someone help me with suggestions on where maybe I'm going wrong, please? If you have any questions about my SPI configuration, just comment and I will clarify. Thank you so much!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
