|  | @@ -46,27 +46,26 @@ uint8_t pat9125_s = 0;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  // Init sequence, address & value.
 | 
	
		
			
				|  |  | -const PROGMEM uint8_t pat9125_init_seq1[] = {
 | 
	
		
			
				|  |  | +const PROGMEM uint8_t pat9125_init_bank0[] = {
 | 
	
		
			
				|  |  |  	// Disable write protect.
 | 
	
		
			
				|  |  |  	PAT9125_WP, 0x5a,
 | 
	
		
			
				|  |  |  	// Set the X resolution to zero to let the sensor know that it could safely ignore movement in the X axis.
 | 
	
		
			
				|  |  | -    PAT9125_RES_X, PAT9125_XRES,
 | 
	
		
			
				|  |  | -    // Set the Y resolution to a maximum (or nearly a maximum).
 | 
	
		
			
				|  |  | -    PAT9125_RES_Y, PAT9125_YRES,
 | 
	
		
			
				|  |  | -    // Set 12-bit X/Y data format.
 | 
	
		
			
				|  |  | -    PAT9125_ORIENTATION, 0x04,
 | 
	
		
			
				|  |  | -//	PAT9125_ORIENTATION, 0x04 | (xinv?0x08:0) | (yinv?0x10:0), //!? direction switching does not work
 | 
	
		
			
				|  |  | -    // Now continues the magic sequence from the PAT912EL Application Note: Firmware Guides for Tracking Optimization.
 | 
	
		
			
				|  |  | -    0x5e, 0x08,
 | 
	
		
			
				|  |  | -    0x20, 0x64,
 | 
	
		
			
				|  |  | -    0x2b, 0x6d,
 | 
	
		
			
				|  |  | -    0x32, 0x2f,
 | 
	
		
			
				|  |  | -    // stopper
 | 
	
		
			
				|  |  | -    0x0ff
 | 
	
		
			
				|  |  | +	PAT9125_RES_X, PAT9125_XRES,
 | 
	
		
			
				|  |  | +	// Set the Y resolution to a maximum (or nearly a maximum).
 | 
	
		
			
				|  |  | +	PAT9125_RES_Y, PAT9125_YRES,
 | 
	
		
			
				|  |  | +	// Set data format and sensor orientation.
 | 
	
		
			
				|  |  | +	PAT9125_ORIENTATION, ((PAT9125_12B_RES?0x04:0) | (PAT9125_INVERT_X?0x08:0) | (PAT9125_INVERT_Y?0x10:0) | (PAT9125_SWAP_XY?0x20:0)),
 | 
	
		
			
				|  |  | +	
 | 
	
		
			
				|  |  | +	// Now continues the magic sequence from the PAT912EL Application Note: Firmware Guides for Tracking Optimization.
 | 
	
		
			
				|  |  | +	0x5e, 0x08,
 | 
	
		
			
				|  |  | +	0x20, 0x64,
 | 
	
		
			
				|  |  | +	0x2b, 0x6d,
 | 
	
		
			
				|  |  | +	0x32, 0x2f,
 | 
	
		
			
				|  |  | +	0xff //end of sequence
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  // Init sequence, address & value.
 | 
	
		
			
				|  |  | -const PROGMEM uint8_t pat9125_init_seq2[] = {
 | 
	
		
			
				|  |  | +const PROGMEM uint8_t pat9125_init_bank1[] = {
 | 
	
		
			
				|  |  |  	// Magic sequence to enforce full frame rate of the sensor.
 | 
	
		
			
				|  |  |  	0x06, 0x028,
 | 
	
		
			
				|  |  |  	0x33, 0x0d0,
 | 
	
	
		
			
				|  | @@ -93,14 +92,14 @@ const PROGMEM uint8_t pat9125_init_seq2[] = {
 | 
	
		
			
				|  |  |  	0x6e, 0x022,
 | 
	
		
			
				|  |  |  	0x71, 0x007,
 | 
	
		
			
				|  |  |  	0x72, 0x008,
 | 
	
		
			
				|  |  | -	// stopper
 | 
	
		
			
				|  |  | -    0x0ff
 | 
	
		
			
				|  |  | +	0xff //end of sequence
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -uint8_t pat9125_rd_reg(uint8_t addr);
 | 
	
		
			
				|  |  | -void pat9125_wr_reg(uint8_t addr, uint8_t data);
 | 
	
		
			
				|  |  | -uint8_t pat9125_wr_reg_verify(uint8_t addr, uint8_t data);
 | 
	
		
			
				|  |  | +static uint8_t pat9125_rd_reg(uint8_t addr);
 | 
	
		
			
				|  |  | +static void pat9125_wr_reg(uint8_t addr, uint8_t data);
 | 
	
		
			
				|  |  | +static uint8_t pat9125_wr_reg_verify(uint8_t addr, uint8_t data);
 | 
	
		
			
				|  |  | +static uint8_t pat9125_wr_seq(const uint8_t* seq);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  extern FILE _uartout;
 | 
	
		
			
				|  |  |  #define uartout (&_uartout)
 | 
	
	
		
			
				|  | @@ -128,11 +127,14 @@ uint8_t pat9125_probe()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  uint8_t pat9125_init(void)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -    if (!pat9125_probe())
 | 
	
		
			
				|  |  | -        return 0;
 | 
	
		
			
				|  |  | +	if (!pat9125_probe())
 | 
	
		
			
				|  |  | +		return 0;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    // Verify that the sensor responds with its correct product ID.
 | 
	
		
			
				|  |  | -    pat9125_PID1 = pat9125_rd_reg(PAT9125_PID1);
 | 
	
		
			
				|  |  | +// Switch to bank0, not allowed to perform pat9125_wr_reg_verify on this register.
 | 
	
		
			
				|  |  | +	pat9125_wr_reg(PAT9125_BANK_SELECTION, 0);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	// Verify that the sensor responds with its correct product ID.
 | 
	
		
			
				|  |  | +	pat9125_PID1 = pat9125_rd_reg(PAT9125_PID1);
 | 
	
		
			
				|  |  |  	pat9125_PID2 = pat9125_rd_reg(PAT9125_PID2);
 | 
	
		
			
				|  |  |  	if ((pat9125_PID1 != 0x31) || (pat9125_PID2 != 0x91))
 | 
	
		
			
				|  |  |  	{
 | 
	
	
		
			
				|  | @@ -142,54 +144,41 @@ uint8_t pat9125_init(void)
 | 
	
		
			
				|  |  |  			return 0;
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -#ifdef PAT9125_NEW_INIT
 | 
	
		
			
				|  |  | -	// Switch to bank0, not allowed to perform OTS_RegWriteRead.
 | 
	
		
			
				|  |  | -	pat9125_wr_reg(PAT9125_BANK_SELECTION, 0);
 | 
	
		
			
				|  |  | +#if PAT9125_NEW_INIT
 | 
	
		
			
				|  |  |  	// Software reset (i.e. set bit7 to 1). It will reset to 0 automatically.
 | 
	
		
			
				|  |  | -	// After the reset, OTS_RegWriteRead is not allowed.
 | 
	
		
			
				|  |  | +	// pat9125_wr_reg_verify is not allowed because the register contents will change as soon as they are written. No point in verifying those.
 | 
	
		
			
				|  |  |  	pat9125_wr_reg(PAT9125_CONFIG, 0x97);
 | 
	
		
			
				|  |  |  	// Wait until the sensor reboots.
 | 
	
		
			
				|  |  | -	// Delay 1ms.
 | 
	
		
			
				|  |  | -	_delay_us(1000);
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -		const uint8_t *ptr = pat9125_init_seq1;
 | 
	
		
			
				|  |  | -		for (;;) {
 | 
	
		
			
				|  |  | -			const uint8_t addr = pgm_read_byte_near(ptr ++);
 | 
	
		
			
				|  |  | -			if (addr == 0x0ff)
 | 
	
		
			
				|  |  | -				break;
 | 
	
		
			
				|  |  | -			if (! pat9125_wr_reg_verify(addr, pgm_read_byte_near(ptr ++)))
 | 
	
		
			
				|  |  | -				// Verification of the register write failed.
 | 
	
		
			
				|  |  | -				return 0;
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	// Delay 10ms.
 | 
	
		
			
				|  |  | -	_delay_ms(10);
 | 
	
		
			
				|  |  | -	// Switch to bank1, not allowed to perform OTS_RegWrite.
 | 
	
		
			
				|  |  | +	_delay_ms(1);
 | 
	
		
			
				|  |  | +	
 | 
	
		
			
				|  |  | +	//Write init sequence in bank0. MUST ALREADY BE IN bank0.
 | 
	
		
			
				|  |  | +	if (!pat9125_wr_seq(pat9125_init_bank0))
 | 
	
		
			
				|  |  | +		return 0;
 | 
	
		
			
				|  |  | +	
 | 
	
		
			
				|  |  | +	_delay_ms(10); // not sure why this is here. But I'll allow it.
 | 
	
		
			
				|  |  | +	
 | 
	
		
			
				|  |  | +	// Switch to bank1, not allowed to perform pat9125_wr_reg_verify on this register.
 | 
	
		
			
				|  |  |  	pat9125_wr_reg(PAT9125_BANK_SELECTION, 0x01);
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -		const uint8_t *ptr = pat9125_init_seq2;
 | 
	
		
			
				|  |  | -		for (;;) {
 | 
	
		
			
				|  |  | -			const uint8_t addr = pgm_read_byte_near(ptr ++);
 | 
	
		
			
				|  |  | -			if (addr == 0x0ff)
 | 
	
		
			
				|  |  | -				break;
 | 
	
		
			
				|  |  | -			if (! pat9125_wr_reg_verify(addr, pgm_read_byte_near(ptr ++)))
 | 
	
		
			
				|  |  | -				// Verification of the register write failed.
 | 
	
		
			
				|  |  | -				return 0;
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	// Switch to bank0, not allowed to perform OTS_RegWriteRead.
 | 
	
		
			
				|  |  | +	//Write init sequence in bank1. MUST ALREADY BE IN bank1.
 | 
	
		
			
				|  |  | +	if (!pat9125_wr_seq(pat9125_init_bank1))
 | 
	
		
			
				|  |  | +		return 0;
 | 
	
		
			
				|  |  | +	
 | 
	
		
			
				|  |  | +	// Switch to bank0, not allowed to perform pat9125_wr_reg_verify on this register.
 | 
	
		
			
				|  |  |  	pat9125_wr_reg(PAT9125_BANK_SELECTION, 0x00);
 | 
	
		
			
				|  |  | +	
 | 
	
		
			
				|  |  |  	// Enable write protect.
 | 
	
		
			
				|  |  | -	pat9125_wr_reg(PAT9125_WP, 0x00);
 | 
	
		
			
				|  |  | +	pat9125_wr_reg(PAT9125_WP, 0x00); //prevents writing to registers over 0x09
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	pat9125_PID1 = pat9125_rd_reg(PAT9125_PID1);
 | 
	
		
			
				|  |  |  	pat9125_PID2 = pat9125_rd_reg(PAT9125_PID2);
 | 
	
		
			
				|  |  | -#endif //PAT9125_NEW_INIT
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +#else //PAT9125_NEW_INIT
 | 
	
		
			
				|  |  |  	pat9125_wr_reg(PAT9125_RES_X, PAT9125_XRES);
 | 
	
		
			
				|  |  |  	pat9125_wr_reg(PAT9125_RES_Y, PAT9125_YRES);
 | 
	
		
			
				|  |  | -	fprintf_P(uartout, PSTR("PAT9125_RES_X=%u\n"), pat9125_rd_reg(PAT9125_RES_X));
 | 
	
		
			
				|  |  | -	fprintf_P(uartout, PSTR("PAT9125_RES_Y=%u\n"), pat9125_rd_reg(PAT9125_RES_Y));
 | 
	
		
			
				|  |  | +	printf_P(PSTR("PAT9125_RES_X=%u\n"), pat9125_rd_reg(PAT9125_RES_X));
 | 
	
		
			
				|  |  | +	printf_P(PSTR("PAT9125_RES_Y=%u\n"), pat9125_rd_reg(PAT9125_RES_Y));
 | 
	
		
			
				|  |  | +#endif //PAT9125_NEW_INIT
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  	return 1;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -251,7 +240,7 @@ uint8_t pat9125_update_bs(void)
 | 
	
		
			
				|  |  |  	return 0;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -uint8_t pat9125_rd_reg(uint8_t addr)
 | 
	
		
			
				|  |  | +static uint8_t pat9125_rd_reg(uint8_t addr)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |  	uint8_t data = 0;
 | 
	
		
			
				|  |  |  #if defined(PAT9125_SWSPI)
 | 
	
	
		
			
				|  | @@ -274,7 +263,7 @@ uint8_t pat9125_rd_reg(uint8_t addr)
 | 
	
		
			
				|  |  |      return 0;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -void pat9125_wr_reg(uint8_t addr, uint8_t data)
 | 
	
		
			
				|  |  | +static void pat9125_wr_reg(uint8_t addr, uint8_t data)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |  #if defined(PAT9125_SWSPI)
 | 
	
		
			
				|  |  |  	swspi_start();
 | 
	
	
		
			
				|  | @@ -296,8 +285,21 @@ void pat9125_wr_reg(uint8_t addr, uint8_t data)
 | 
	
		
			
				|  |  |      return;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -uint8_t pat9125_wr_reg_verify(uint8_t addr, uint8_t data)
 | 
	
		
			
				|  |  | +static uint8_t pat9125_wr_reg_verify(uint8_t addr, uint8_t data)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |  	pat9125_wr_reg(addr, data);
 | 
	
		
			
				|  |  |  	return pat9125_rd_reg(addr) == data;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static uint8_t pat9125_wr_seq(const uint8_t* seq)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	for (;;) {
 | 
	
		
			
				|  |  | +		const uint8_t addr = pgm_read_byte(seq++);
 | 
	
		
			
				|  |  | +		if (addr == 0xff)
 | 
	
		
			
				|  |  | +			break;
 | 
	
		
			
				|  |  | +		if (!pat9125_wr_reg_verify(addr, pgm_read_byte(seq++)))
 | 
	
		
			
				|  |  | +			// Verification of the register write failed.
 | 
	
		
			
				|  |  | +			return 0;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	return 1;
 | 
	
		
			
				|  |  | +}
 |