Contributed by bzhou830, organized by Ai-Thinker
[Peripheral Porting] Ai-WB2+Dual-Axis Joystick Module
Peripheral introduction
The dual-axis joystick module uses the metal-button joystick potentiometer from PS2 game controllers. The module provides two analog output interfaces and one digital output interface. The output values correspond to the x- and y-axis offsets, which are analog values. The button indicates whether the user has pressed down on the z-axis, and its output is a digital switch value.

The module interfaces are as follows: 
Porting process
Based on the analysis above, we need:
- Two ADC channels to sample the analog values of the x-axis and y-axis respectively;
- One GPIO input to detect the digital output on the z-axis;
In summary, we need to use the ADC and GPIO input functions.
Note that the ADC usage mentioned above only uses one channel, but here we need to use two channels simultaneously, so we need to check the documentation for the corresponding API calls. Looking through the documentation, we can find:
Click to expand full code
int hosal_adc_add_channel(hosal_adc_dev_t *adc,uint32_t channel)Add an ADC channel to the ADC device. The parameters are as follows:
- adc: the ADC port device
- channel: the ADC channel to add
- Return value: returns 0 on success, otherwise EIO or another value
With this, we can add multiple ADC sampling channels.
Hardware wiring
For the hardware connection, the left side is the WB2 and the right side is the dual-axis joystick.
IO11 ---> VRX
IO5 ---> VRY
IO3 ---> SW
3V3 ---> 5V
GND ---> GND

Code analysis
Click to expand full code
#include <stdio.h>
#include <string.h>
#include <FreeRTOS.h>
#include <task.h>
#include <hosal_adc.h>
#include <hosal_gpio.h>
#include <bl_adc.h>
#include <bl_gpio.h>
#include <blog.h>
/********** BL602 ADC ************
* channel0 -----> gpio12
* channel1 -----> gpio4
* channel2 -----> gpio14
* channel3 -----> gpio13
* channel4 -----> gpio5
* channel5 -----> gpio6
* channel7 -----> gpio9
* channel9 -----> gpio10
* channel10 -----> gpio11
* channel11 -----> gpio15
*/
#define ADC_X_PIN 11
#define ADC_Y_PIN 5
#define KEY_PIN 3
void main(void)
{
static uint8_t key_state = 0;
static hosal_gpio_dev_t key;
key.port = KEY_PIN;
key.config = INPUT_PULL_UP;
hosal_gpio_init(&key);
static hosal_adc_dev_t adc0 = {
.cb = NULL,
.config = {
.mode = HOSAL_ADC_ONE_SHOT,
.pin = ADC_X_PIN,
.sampling_freq = 340,
},
.dma_chan = 0,
.p_arg = NULL,
.port = 0,
};
hosal_adc_init(&adc0);
hosal_adc_add_channel(&adc0, bl_adc_get_channel_by_gpio(ADC_X_PIN));
hosal_adc_add_channel(&adc0, bl_adc_get_channel_by_gpio(ADC_Y_PIN));
for (;;)
{
int v_y = hosal_adc_value_get(&adc0, bl_adc_get_channel_by_gpio(ADC_Y_PIN), 100);
int v_x = hosal_adc_value_get(&adc0, bl_adc_get_channel_by_gpio(ADC_X_PIN), 100);
hosal_gpio_input_get(&key, &key_state);
blog_info("x = %ld mV, y = %ld mV, btn = %d\r\n", v_y, v_x, key_state);
vTaskDelay(pdMS_TO_TICKS(1000));
}
}Result verification


