Fixing MAX11802 driver (by user steved)

This commit is contained in:
Joel Bodenmann 2014-11-14 16:38:40 +01:00
parent 6bc091035a
commit 4f8b30ef36
3 changed files with 32 additions and 20 deletions

View file

@ -18,8 +18,8 @@
// 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
@ -27,9 +27,12 @@
#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,6 +116,7 @@ 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);
@ -113,13 +125,13 @@ static bool_t read_xyz(GMouse* m, GMouseReading* pdr)
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;
} }
@ -133,8 +145,6 @@ static bool_t read_xyz(GMouse* m, GMouseReading* pdr)
} while (readyCount < 2); } while (readyCount < 2);
release_bus(m);
/** /**
* format of each value returned by MAX11802: * format of each value returned by MAX11802:
* Bits 15..4 - analog value * Bits 15..4 - analog value
@ -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_MIN, // z_touchoff
Z_MAX, // z_touchon Z_MAX, // z_touchon
Z_MIN, // z_touchoff
{ // 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