Fixing MAX11802 driver (by user steved)
This commit is contained in:
parent
6bc091035a
commit
4f8b30ef36
3 changed files with 32 additions and 20 deletions
|
@ -18,18 +18,21 @@
|
||||||
// Get the hardware interface
|
// Get the hardware interface
|
||||||
#include "gmouse_lld_MAX11802_board.h"
|
#include "gmouse_lld_MAX11802_board.h"
|
||||||
|
|
||||||
// Register values to set
|
/* Register values to set */
|
||||||
#define MAX11802_MODE 0x0E // Direct conversion with averaging
|
#define MAX11802_MODE 0x0E /* Direct conversion with averaging */
|
||||||
#define MAX11802_AVG 0x55
|
#define MAX11802_AVG 0x55
|
||||||
#define MAX11802_TIMING 0x77
|
#define MAX11802_TIMING 0x77
|
||||||
#define MAX11802_DELAY 0x55
|
#define MAX11802_DELAY 0x55
|
||||||
|
|
||||||
#define Z_MIN 0
|
#define Z_MIN 0
|
||||||
#define Z_MAX 1
|
#define Z_MAX 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static bool_t MouseInit(GMouse* m, unsigned driverinstance)
|
static bool_t MouseInit(GMouse* m, unsigned driverinstance)
|
||||||
{
|
{
|
||||||
uint8_t *p;
|
const uint8_t *p;
|
||||||
|
|
||||||
static const uint8_t commandList[] = {
|
static const uint8_t commandList[] = {
|
||||||
MAX11802_CMD_GEN_WR, 0xf0, // General config - leave TIRQ enabled, even though we ignore it ATM
|
MAX11802_CMD_GEN_WR, 0xf0, // General config - leave TIRQ enabled, even though we ignore it ATM
|
||||||
|
@ -49,11 +52,15 @@ static bool_t MouseInit(GMouse* m, unsigned driverinstance)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
aquire_bus(m);
|
aquire_bus(m);
|
||||||
|
|
||||||
for (p = commandList; p < commandList+sizeof(commandList); p += 2)
|
for (p = commandList; p < commandList+sizeof(commandList); p += 2)
|
||||||
write_command(m, p[0], p[1]);
|
write_command(m, p[0], p[1]);
|
||||||
|
release_bus(m); // Need to release bus after each access to reset interface in chip
|
||||||
|
// (and in some cases, to allow sharing of SPI bus if board logic/OS manages it)
|
||||||
|
// Setup complete here
|
||||||
|
|
||||||
|
|
||||||
// Read something as a test
|
// Read something as a test
|
||||||
|
aquire_bus(m);
|
||||||
if (write_command(m, MAX11802_CMD_MODE_RD, 0) != MAX11802_MODE) {
|
if (write_command(m, MAX11802_CMD_MODE_RD, 0) != MAX11802_MODE) {
|
||||||
release_bus(m);
|
release_bus(m);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -64,6 +71,9 @@ static bool_t MouseInit(GMouse* m, unsigned driverinstance)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static bool_t read_xyz(GMouse* m, GMouseReading* pdr)
|
static bool_t read_xyz(GMouse* m, GMouseReading* pdr)
|
||||||
{
|
{
|
||||||
uint8_t readyCount;
|
uint8_t readyCount;
|
||||||
|
@ -77,10 +87,11 @@ static bool_t read_xyz(GMouse* m, GMouseReading* pdr)
|
||||||
|
|
||||||
// Start the conversion
|
// Start the conversion
|
||||||
gfintWriteCommand(m, MAX11802_CMD_MEASUREXY); // just write command
|
gfintWriteCommand(m, MAX11802_CMD_MEASUREXY); // just write command
|
||||||
|
release_bus(m);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* put a delay in here, since conversion will take a finite time - longer if reading Z as well
|
* put a delay in here, since conversion will take a finite time - longer if we were reading Z as well
|
||||||
* Potentially 1msec for 3 axes with 8us conversion time per sample, 8 samples per average
|
* Potentially at least 1msec for 3 axes with 8us conversion time per sample, 8 samples per average
|
||||||
* Note Maxim AN5435-software to do calculation (www.maximintegrated.com/design/tools/appnotes/5435/AN5435-software.zip)
|
* Note Maxim AN5435-software to do calculation (www.maximintegrated.com/design/tools/appnotes/5435/AN5435-software.zip)
|
||||||
*
|
*
|
||||||
* We'll just use a fixed delay to avoid too much polling/bus activity
|
* We'll just use a fixed delay to avoid too much polling/bus activity
|
||||||
|
@ -95,7 +106,7 @@ static bool_t read_xyz(GMouse* m, GMouseReading* pdr)
|
||||||
* We work around this by reading the registers once more after the tags indicate they are ready.
|
* We work around this by reading the registers once more after the tags indicate they are ready.
|
||||||
* There's also a separate counter to guard against never getting valid readings.
|
* There's also a separate counter to guard against never getting valid readings.
|
||||||
*
|
*
|
||||||
* Read the two or three readings required in a single burst, swapping x and y order if necessary
|
* Read the two readings required in a single burst, swapping x and y order if necessary
|
||||||
*
|
*
|
||||||
* Reading Z is possible but complicated requiring two z readings, multiplication and division, various constant ratio's,
|
* Reading Z is possible but complicated requiring two z readings, multiplication and division, various constant ratio's,
|
||||||
* and interpolation in relation to the X and Y readings. It is not a simple pressure reading.
|
* and interpolation in relation to the X and Y readings. It is not a simple pressure reading.
|
||||||
|
@ -105,21 +116,22 @@ static bool_t read_xyz(GMouse* m, GMouseReading* pdr)
|
||||||
readyCount = notReadyCount = 0;
|
readyCount = notReadyCount = 0;
|
||||||
do {
|
do {
|
||||||
// Get a set of readings
|
// Get a set of readings
|
||||||
|
aquire_bus(m);
|
||||||
gfintWriteCommand(m, MAX11802_CMD_XPOSITION);
|
gfintWriteCommand(m, MAX11802_CMD_XPOSITION);
|
||||||
#if defined(GINPUT_MOUSE_YX_INVERTED) && GINPUT_MOUSE_YX_INVERTED
|
#if defined(GINPUT_MOUSE_YX_INVERTED) && GINPUT_MOUSE_YX_INVERTED
|
||||||
pdr->y = read_value(m);
|
pdr->y = read_value(m);
|
||||||
pdr->x = read_value(m);
|
pdr->x = read_value(m);
|
||||||
#else
|
#else
|
||||||
pdr->x = read_value(m);
|
pdr->x = read_value(m);
|
||||||
pdr->y = read_value(m);
|
pdr->y = read_value(m);
|
||||||
#endif
|
#endif
|
||||||
|
release_bus(m);
|
||||||
|
|
||||||
// Test the result validity
|
// Test the result validity
|
||||||
if (((pdr->x | pdr->y) & 0x03) == 0x03) {
|
if (((pdr->x | pdr->y) & 0x03) == 0x03) {
|
||||||
|
|
||||||
// Has it been too long? If so give up
|
// Has it been too long? If so give up
|
||||||
if (++notReadyCount >= 5) {
|
if (++notReadyCount >= 5) {
|
||||||
release_bus(m);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,8 +144,6 @@ static bool_t read_xyz(GMouse* m, GMouseReading* pdr)
|
||||||
readyCount++;
|
readyCount++;
|
||||||
|
|
||||||
} while (readyCount < 2);
|
} while (readyCount < 2);
|
||||||
|
|
||||||
release_bus(m);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* format of each value returned by MAX11802:
|
* format of each value returned by MAX11802:
|
||||||
|
@ -143,19 +153,21 @@ static bool_t read_xyz(GMouse* m, GMouseReading* pdr)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Was there a valid touch?
|
// Was there a valid touch?
|
||||||
if ((pt->x & 0x03) == 0x02) {
|
if (((pdr->x | pdr->y) & 0x03) != 0x0) {
|
||||||
pdr->z = Z_MIN;
|
pdr->z = Z_MIN;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Strip the tags
|
// Strip the tags (we need to take care because coord_t is signed - and sign bit gets extended on shift!)
|
||||||
pt->x >>= 4;
|
pdr->x = (uint16_t)(pdr->x) >> 4;
|
||||||
pt->y >>= 4;
|
pdr->y = (uint16_t)(pdr->y) >> 4;
|
||||||
pdr->z = Z_MAX;
|
pdr->z = Z_MAX;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const GMouseVMT const GMOUSE_DRIVER_VMT[1] = {{
|
const GMouseVMT const GMOUSE_DRIVER_VMT[1] = {{
|
||||||
{
|
{
|
||||||
GDRIVER_TYPE_TOUCH,
|
GDRIVER_TYPE_TOUCH,
|
||||||
|
@ -167,8 +179,8 @@ const GMouseVMT const GMOUSE_DRIVER_VMT[1] = {{
|
||||||
},
|
},
|
||||||
Z_MAX, // z_max
|
Z_MAX, // z_max
|
||||||
Z_MIN, // z_min
|
Z_MIN, // z_min
|
||||||
|
Z_MAX, // z_touchon
|
||||||
Z_MIN, // z_touchoff
|
Z_MIN, // z_touchoff
|
||||||
Z_MAX, // z_touchon
|
|
||||||
{ // pen_jitter
|
{ // pen_jitter
|
||||||
GMOUSE_MAX11802_PEN_CALIBRATE_ERROR, // calibrate
|
GMOUSE_MAX11802_PEN_CALIBRATE_ERROR, // calibrate
|
||||||
GMOUSE_MAX11802_PEN_CLICK_ERROR, // click
|
GMOUSE_MAX11802_PEN_CLICK_ERROR, // click
|
||||||
|
|
|
@ -61,7 +61,7 @@ static inline uint8_t gfintWriteCommand(GMouse* m, uint8_t command) {
|
||||||
/*
|
/*
|
||||||
* Read 2 bytes as 16-bit value (command to read must have been sent previously)
|
* Read 2 bytes as 16-bit value (command to read must have been sent previously)
|
||||||
* Note: Analog value is in bits 15..4, tags (reading status) in bits 3..0
|
* Note: Analog value is in bits 15..4, tags (reading status) in bits 3..0
|
||||||
*/
|
*/
|
||||||
static inline uint16_t read_value(GMouse* m) {
|
static inline uint16_t read_value(GMouse* m) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
// LSB of register addresses specifies read (1) or write (0)
|
// LSB of register addresses specifies read (1) or write (0)
|
||||||
#define MAX11802_CMD_MEASUREXY (0x70 << 1)
|
#define MAX11802_CMD_MEASUREXY (0x70 << 1)
|
||||||
#define MAX11802_CMD_MEASUREXYZ (0x72 << 1)
|
#define MAX11802_CMD_MEASUREXYZ (0x72 << 1)
|
||||||
#define MAX11802_CMD_GEN_WR (0x01 << 1) // General config register
|
#define MAX11802_CMD_GEN_WR (0x01 << 1) // General config register
|
||||||
#define MAX11802_CMD_RES_WR (0x02 << 1)
|
#define MAX11802_CMD_RES_WR (0x02 << 1)
|
||||||
#define MAX11802_CMD_AVG_WR (0x03 << 1)
|
#define MAX11802_CMD_AVG_WR (0x03 << 1)
|
||||||
#define MAX11802_CMD_SAMPLE_WR (0x04 << 1)
|
#define MAX11802_CMD_SAMPLE_WR (0x04 << 1)
|
||||||
|
|
Loading…
Add table
Reference in a new issue