rink.nu / projects / musixbox / changeset 254:9214b5cee9b6
Use the new message -> response approach as implemented in the touchscreen code, and synchronize before attempting to use the AVR.
authorRink Springer <rink@rink.nu>
Mon Dec 29 20:00:33 2008 +0100 (2008-12-29 ago)
changeset 2549214b5cee9b6
parent 253 a44cb6394527
child 255 2d0fe98e6804
Use the new message -> response approach as implemented in the touchscreen code, and synchronize before attempting to use the AVR.
     1.1 --- a/include/ui/interaction_avr.h	Sat Dec 27 13:03:55 2008 +0100
     1.2 +++ b/include/ui/interaction_avr.h	Mon Dec 29 20:00:33 2008 +0100
     1.3 @@ -6,6 +6,9 @@
     1.4  /* Commands send by the AVR to us */
     1.5  #define CMD_NONE		0x00
     1.6  #define CMD_COORDS		0x01
     1.7 +#define CMD_SYNC		0xf0
     1.8 +#define CMD_SYNCED		0xf1
     1.9 +#define CMD_DRAWN		0xf2
    1.10  
    1.11  /* Maximum argument length */
    1.12  #define CMD_MAX_DATA_LENGTH	0x10
    1.13 @@ -45,6 +48,15 @@
    1.14  	//! \brief Handle a touch coordinate request
    1.15  	void handleTouch(uint8_t* buf);
    1.16  
    1.17 +	//! \brief Synchronized the AVR device with us
    1.18 +	void sync();
    1.19 +
    1.20 +	//! \brief Called if we got a synced charachter
    1.21 +	void setSynced() { synced = true; }
    1.22 +
    1.23 +	//! \brief Called if we got a drawn command
    1.24 +	void setDrawn() { drawn = true; }
    1.25 +
    1.26  private:
    1.27  	//! \brief File descriptor used for serial access
    1.28  	int fd;
    1.29 @@ -52,6 +64,12 @@
    1.30  	//! \brief Need to update the display?
    1.31  	bool dirty;
    1.32  
    1.33 +	//! \brief Have we gotten a sync charachter?
    1.34 +	bool synced;
    1.35 +
    1.36 +	//! \brief Have we drawn the data?
    1.37 +	bool drawn;
    1.38 +
    1.39  	//! \brief Working contents of display data
    1.40  	unsigned char* displaydata;
    1.41  
     2.1 --- a/lib/ui/interaction_avr.cc	Sat Dec 27 13:03:55 2008 +0100
     2.2 +++ b/lib/ui/interaction_avr.cc	Mon Dec 29 20:00:33 2008 +0100
     2.3 @@ -24,6 +24,8 @@
     2.4  } commandmap[] = {
     2.5  	{ CMD_NONE,   0 },
     2.6  	{ CMD_COORDS, 4 },
     2.7 +	{ CMD_SYNCED, 0 },
     2.8 +	{ CMD_DRAWN,  0 },
     2.9  };
    2.10  
    2.11  void*
    2.12 @@ -77,12 +79,12 @@
    2.13  				fprintf(stderr, "InteractionAVR: received unknown command 0x%02x, ignored\n", curCmd);
    2.14  #endif
    2.15  				curCmd = CMD_NONE;
    2.16 -				break;
    2.17 +				continue;
    2.18  			}
    2.19  			curByte = 0; numBytes = commandmap[idx].len;
    2.20  			if (numBytes >= CMD_MAX_DATA_LENGTH) {
    2.21  #ifdef DEBUG
    2.22 -				fprintf(stderr, "InteractionAVR: command 0x%02x has argument length %u > maximum %u, adjusting!\n", curCmd, numBytes, CMD_MAX_DATA_LEN);
    2.23 +				fprintf(stderr, "InteractionAVR: command 0x%02x has argument length %u > maximum %u, adjusting!\n", curCmd, numBytes, CMD_MAX_DATA_LENGTH);
    2.24  #endif
    2.25  				numBytes = CMD_MAX_DATA_LENGTH;
    2.26  			}
    2.27 @@ -105,6 +107,12 @@
    2.28  			case CMD_COORDS:
    2.29  				avr->handleTouch(argBuf);
    2.30  				break;
    2.31 +			case CMD_SYNCED:
    2.32 +				avr->setSynced();
    2.33 +				break;
    2.34 +			case CMD_DRAWN:
    2.35 +				avr->setDrawn();
    2.36 +				break;
    2.37  			default:
    2.38  				/*
    2.39  				 * Length is know, but no action. Ignore the
    2.40 @@ -177,8 +185,8 @@
    2.41  	/* Finally, launch the thread to cope with incoming data */
    2.42  	pthread_create(&recvThread, NULL, avrRecvThread, this);
    2.43  
    2.44 -	/* We do not know what's on the LCD, so write whenever we can! */
    2.45 -	dirty = true;
    2.46 +	/* Ensure the AVR and us are in sync */
    2.47 +	sync();
    2.48  }
    2.49  
    2.50  InteractionAVR::~InteractionAVR()
    2.51 @@ -204,9 +212,6 @@
    2.52  void
    2.53  InteractionAVR::yield()
    2.54  {
    2.55 -	if (!dirty)
    2.56 -		return;
    2.57 -
    2.58  	/*
    2.59  	 * If we have outstanding updates, write them page by page, controller
    2.60  	 * by controller. This is actually so much faster than sending updates
    2.61 @@ -230,8 +235,6 @@
    2.62  			}
    2.63  		}
    2.64  	}
    2.65 -
    2.66 -	dirty = false;
    2.67  }
    2.68  
    2.69  void
    2.70 @@ -244,8 +247,6 @@
    2.71  		displaydata[x + (getWidth() * (y / 8))] |= 1 << (y % 8);
    2.72  	else
    2.73  		displaydata[x + (getWidth() * (y / 8))] &= ~(1 << (y % 8));
    2.74 -
    2.75 -	dirty = true;
    2.76  }
    2.77  
    2.78  void
    2.79 @@ -253,11 +254,20 @@
    2.80  {
    2.81  	unsigned char a;
    2.82  
    2.83 -	a = 0x80 | (ic ? 0x40 : 0) | page;
    2.84 +	a = (ic ? 0x40 : 0) | page;
    2.85  	if (!write(fd, &a, 1))
    2.86  		return;
    2.87  	if (!write(fd, data, 64))
    2.88  		return;
    2.89 +
    2.90 +	/* Wait until the AVR acknowledges our request */
    2.91 +	for (int tries = 0; tries < 10000; tries++) {
    2.92 +		if (drawn) {
    2.93 +			drawn = false;
    2.94 +			break;
    2.95 +		}
    2.96 +		usleep(10);
    2.97 +	}
    2.98  }
    2.99  
   2.100  void
   2.101 @@ -299,3 +309,32 @@
   2.102  	/* All is well => report the coordinate */
   2.103  	setInteraction(x, y, INTERACTION_TYPE_NORMAL);
   2.104  }
   2.105 +
   2.106 +void
   2.107 +InteractionAVR::sync()
   2.108 +{
   2.109 +	unsigned char syncmd = CMD_SYNC;
   2.110 +	int syncs = 0;
   2.111 +
   2.112 +	/*
   2.113 +	 * Establish sync with the device: the idea is that we send up to
   2.114 +	 * 65 SYNC commands. If the AVR is is still busy drawing, it'll
   2.115 +	 * place these on the display and continue. However, if it's not,
   2.116 +	 * it will return the 'synced' command which the receiver thread
   2.117 +	 * acts on by setting the synced boolean to true.
   2.118 +	 */
   2.119 +	synced = false;
   2.120 +	for (int syncs = 0; syncs < 65; syncs++) {
   2.121 +		if (!write(fd, &syncmd, 1))
   2.122 +			return;
   2.123 +		usleep(10000);
   2.124 +		if (synced)
   2.125 +			return;
   2.126 +	}
   2.127 +
   2.128 +	/*
   2.129 +	 * Give up; the device is in such a wedged state, we can't make heads
   2.130 +	 * or tails of it...
   2.131 +	 */
   2.132 +	throw InteractionException("Unable to synchronize with the device");
   2.133 +}
Powered by FreeBSD, PostgreSQL and Perl
© 2001 - 2011 Rink Springer