| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- /*
- * Copyright (c) 2019, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2019-08-26 sogwms The first version
- */
- #include "ps2.h"
- #include "ps2_table.h"
- #define DBG_SECTION_NAME "ps2"
- #define DBG_LEVEL DBG_LOG
- #include <rtdbg.h>
- #define THREAD_DELAY_TIME 30
- #define THREAD_PRIORITY ((RT_THREAD_PRIORITY_MAX / 3) + 3)
- #define THREAD_STACK_SIZE 1024
- #define THREAD_TIMESLICE 10
- #define KEEP_TIME() _delay_us(16);
- static uint8_t light_mode = PS2_NO_MODE;
- static rt_thread_t tid_ps2 = RT_NULL;
- static struct ps2_table table[PS2_TABLE_SIZE] = PS2_DEFAULT_TABLE;
- static rt_base_t ps2_cs_pin;
- static rt_base_t ps2_clk_pin;
- static rt_base_t ps2_do_pin;
- static rt_base_t ps2_di_pin;
- static void hal_cs_high(void)
- {
- rt_pin_write(ps2_cs_pin, PIN_HIGH);
- }
- static void hal_cs_low(void)
- {
- rt_pin_write(ps2_cs_pin, PIN_LOW);
- }
- static void hal_clk_high(void)
- {
- rt_pin_write(ps2_clk_pin, PIN_HIGH);
- }
- static void hal_clk_low(void)
- {
- rt_pin_write(ps2_clk_pin, PIN_LOW);
- }
- static void hal_do_high(void)
- {
- rt_pin_write(ps2_do_pin, PIN_HIGH);
- }
- static void hal_do_low(void)
- {
- rt_pin_write(ps2_do_pin, PIN_LOW);
- }
- static int hal_read_di(void)
- {
- return rt_pin_read(ps2_di_pin);
- }
- static void _delay_us(uint16_t us)
- {
- for (int i = 0; i < us; i++)
- {
- for (int j = 0; j < 0x1F;)
- j++;
- }
- }
- static uint8_t _transfer(uint8_t data)
- {
- uint8_t temp = 0;
- for (uint16_t i = 0x01; i < 0x0100; i <<= 1)
- {
- if (i & data)
- hal_do_high();
- else
- hal_do_low();
- hal_clk_high();
- KEEP_TIME();
- hal_clk_low();
- if (hal_read_di())
- temp = i | temp;
- KEEP_TIME();
- hal_clk_high();
- }
-
- return temp;
- }
- static void transfer(const uint8_t *pb_send, uint8_t *pb_recv, uint8_t len)
- {
- hal_cs_low();
- _delay_us(16);
- for (uint8_t i = 0; i < len; i++)
- {
- pb_recv[i] = _transfer(pb_send[i]);
- }
- hal_cs_high();
- _delay_us(16);
- }
- int ps2_scan(ps2_ctrl_data_t pt)
- {
- uint8_t temp[9] = {0};
- temp[0] = 0x01;
- temp[1] = 0x42;
- temp[3] = 0;
- temp[4] = 0;
- transfer(temp, temp, 9);
- pt->button = temp[3] | (temp[4] << 8);
- pt->right_stick_x = temp[5];
- pt->right_stick_y = temp[6];
- pt->left_stick_x = temp[7];
- pt->left_stick_y = temp[8];
- if (temp[2] == 0x5A)
- {
- light_mode = temp[1];
- return 1;
- }
- else
- {
- light_mode = PS2_NO_MODE;
- }
- return 0;
- }
- /**
- * @return PS2_GREEN_MDOE or PS2_RED_MDOE or other(no connect)
- */
- int ps2_read_light(void)
- {
- return light_mode;
- }
- static rt_err_t ps2_sender_send(rt_uint16_t cmd, void *param, rt_uint16_t size)
- {
- // TODO
- if (cmd == COMMAND_RC_VIBRATE)
- {
- }
- else
- {
- return RT_ERROR;
- }
- return RT_EOK;
- }
- static struct command_sender ps2_sender = {
- .name = "ano",
- .send = ps2_sender_send
- };
- command_sender_t ps2_get_sender(void)
- {
- return &ps2_sender;
- }
- static void ps2_thread_entry(void *param)
- {
- struct ps2_ctrl_data ctrl_data;
- struct cmd_velocity target_velocity;
- while (1)
- {
- rt_thread_mdelay(THREAD_DELAY_TIME);
- ps2_scan(&ctrl_data);
- // look-up table and send standard command
- for (int i = 0; i < PS2_TABLE_SIZE; i++)
- {
- if (!(ctrl_data.button & table[i].ps2_cmd))
- {
- if (table[i].standard_cmd != COMMAND_NONE)
- {
- command_handle(table[i].standard_cmd, RT_NULL, 0);
- }
- }
- }
- // rocker
- if (ps2_read_light() == PS2_RED_MODE)
- {
- uint8_t value[4] = {
- ctrl_data.left_stick_x,
- ctrl_data.right_stick_x,
- ctrl_data.left_stick_y,
- ctrl_data.right_stick_y};
- rt_int16_t cmd[4] = {
- table[PS2_ROCKER_LX].standard_cmd,
- table[PS2_ROCKER_LY].standard_cmd,
- table[PS2_ROCKER_RX].standard_cmd,
- table[PS2_ROCKER_RY].standard_cmd};
- for (int i = 0; i < 4; i++)
- {
- if (cmd[i] != COMMAND_NONE)
- {
- float tmp = CHASSIS_VELOCITY_LINEAR_MAXIMUM;
- if (cmd[i] == COMMAND_SET_CHASSIS_VELOCITY_ANGULAR_Z)
- {
- tmp = CHASSIS_VELOCITY_ANGULAR_MAXIMUM;
- }
-
- target_velocity.data.common = tmp * ((0x80 - (int)(i/2)) - value[i]) / 128;
- command_handle(cmd[i], &target_velocity, sizeof(struct cmd_velocity));
- }
- }
- }
- }
- }
- void ps2_init(rt_base_t cs_pin, rt_base_t clk_pin, rt_base_t do_pin, rt_base_t di_pin)
- {
- ps2_cs_pin = cs_pin;
- ps2_clk_pin = clk_pin;
- ps2_do_pin = do_pin;
- ps2_di_pin = di_pin;
- rt_pin_mode(ps2_cs_pin, PIN_MODE_OUTPUT);
- rt_pin_mode(ps2_clk_pin, PIN_MODE_OUTPUT);
- rt_pin_mode(ps2_do_pin, PIN_MODE_OUTPUT);
- rt_pin_mode(ps2_di_pin, PIN_MODE_INPUT);
-
- hal_cs_high();
- hal_clk_high();
- // cmd_info.target = target;
- tid_ps2 = rt_thread_create("ps2",
- ps2_thread_entry, RT_NULL,
- THREAD_STACK_SIZE,
- THREAD_PRIORITY, THREAD_TIMESLICE);
- if (tid_ps2 != RT_NULL)
- {
- rt_thread_startup(tid_ps2);
- }
- else
- {
- LOG_E("Can't create thread for ps2");
- }
- }
|