omap3530/beagle_drivers/byd_touch/common/controller.cpp
branchBeagle_BSP_dev
changeset 95 450a8cf0c020
parent 85 d93b485c1325
equal deleted inserted replaced
85:d93b485c1325 95:450a8cf0c020
    41 	SET_BUS_TYPE(iSpiBusId, DIicBusChannel::ESpi);
    41 	SET_BUS_TYPE(iSpiBusId, DIicBusChannel::ESpi);
    42 	SET_CHAN_NUM(iSpiBusId, KSpiModule);
    42 	SET_CHAN_NUM(iSpiBusId, KSpiModule);
    43 	SET_SLAVE_ADDR(iSpiBusId, KSpiSlaveAddr);
    43 	SET_SLAVE_ADDR(iSpiBusId, KSpiSlaveAddr);
    44 	}
    44 	}
    45 
    45 
       
    46 
       
    47 // Writes number of bytes stored in the write buffer - to the controller.
       
    48 // aNumOfBytes specifies number of bytes including first byte of address.
       
    49 // The write buffer should contain the data from index=1 and it's length should be set
       
    50 // to number of registers to update + 1 (one byte for the address / command)
       
    51 TInt TTouchControllerInterface::WriteMultiple(TUint8 aStartAddress, TInt aNumBytes)
       
    52 	{
       
    53 	LOG_FUNCTION_CALL;
       
    54 	if(aNumBytes != iSpiWriteBuffer.Length())
       
    55 		{
       
    56 #ifdef VERBOSE_DEBUG
       
    57 		Kern::Printf("Transfer buffers are not properly set, line: %d", __LINE__);
       
    58 #endif
       
    59 		return KErrArgument;
       
    60 		}
       
    61 	iSpiReadBuffer.SetLength(aNumBytes);
       
    62 	iSpiWriteBuffer[0] = KWriteCommand | (aStartAddress << 1);
       
    63 	return IicBus::QueueTransaction(iSpiBusId, &iSpiTransaction);
       
    64 	}
       
    65 
       
    66 
       
    67 // Reads number of bytes and stores them into the read buffer
       
    68 // aNumOfBytes specifies number of bytes (excluding first byte of address)
       
    69 // The read buffer will contain the received data starting from index=1 (TODO: consider MidTPtr)
       
    70 TInt TTouchControllerInterface::ReadMultiple(TUint8 aStartAddress, TInt aNumBytes)
       
    71 	{
       
    72 	LOG_FUNCTION_CALL;
       
    73 	TInt r = KErrNone;
       
    74 
       
    75 	// if trying to read from address different that currently stored - first update the read register..
       
    76 	if(iCurrentReadStart != aStartAddress)
       
    77 		{
       
    78 		r = Write(KMasterReadStartAddr, aStartAddress);
       
    79 		if(r != KErrNone)
       
    80 			{
       
    81 			return r;
       
    82 			}
       
    83 		iCurrentReadStart = aStartAddress;
       
    84 		}
       
    85 
       
    86 	// make sure buffers are set to the requested size
       
    87 	iSpiReadBuffer.SetLength(aNumBytes + 1);
       
    88 	iSpiWriteBuffer.SetLength(aNumBytes + 1);
       
    89 	iSpiWriteBuffer[0] = KReadCommand;
       
    90 
       
    91 	return IicBus::QueueTransaction(iSpiBusId, &iSpiTransaction);
       
    92 	}
       
    93 
       
    94 TInt TTouchControllerInterface::Write(TUint8 aRegAddress, TUint8 aValue)
       
    95 	{
       
    96 	LOG_FUNCTION_CALL;
       
    97 	iSpiWriteBuffer.SetLength(2);
       
    98 	iSpiReadBuffer.SetLength(2);
       
    99 	iSpiWriteBuffer[0] = KWriteCommand | (aRegAddress << 1);
       
   100 	iSpiWriteBuffer[1] = aValue;
       
   101 
       
   102 
       
   103 #ifdef VERBOSE_DEBUG
       
   104 	for (int i = 0; i < iSpiWriteBuffer.Length(); i++)
       
   105 		Kern::Printf("WR0[i]: %d", iSpiWriteBuffer[i]);
       
   106 
       
   107 	for (int i = 0; i < iSpiReadBuffer.Length(); i++)
       
   108 		Kern::Printf("W0[i]: %d", iSpiReadBuffer[i]);
       
   109 #endif
       
   110 	TInt r = IicBus::QueueTransaction(iSpiBusId, &iSpiTransaction);
       
   111 
       
   112 #ifdef VERBOSE_DEBUG
       
   113 	for (int i = 0; i < iSpiReadBuffer.Length(); i++)
       
   114 		Kern::Printf("W1[i]: %d", iSpiReadBuffer[i]);
       
   115 #endif
       
   116 	return r;
       
   117 	}
       
   118 
       
   119 
    46 TInt TTouchControllerInterface::Read(TUint8 aRegAddress, TUint8& aValue)
   120 TInt TTouchControllerInterface::Read(TUint8 aRegAddress, TUint8& aValue)
    47 	{
   121 	{
    48 	LOG_FUNCTION_CALL;
   122 	LOG_FUNCTION_CALL;
    49 	iSpiWriteBuffer[0] = KReadCommand;
   123 	TInt r = ReadMultiple(aRegAddress, 2);
    50 	iSpiWriteBuffer[1] = aRegAddress;
   124 
    51 	iSpiWriteBuffer[2] = 0; // TODO - might not be needed..
       
    52 #ifdef VERBOSE_DEBUG
       
    53 	for (int i = 0; i <KSpiPacketLength; i++)
       
    54 		Kern::Printf("R0[i]: %d", iSpiReadBuffer[1]);
       
    55 #endif
       
    56 	TInt r = IicBus::QueueTransaction(iSpiBusId, &iSpiTransaction);
       
    57 	if(r == KErrNone)
   125 	if(r == KErrNone)
    58 		{
   126 		{
    59 		aValue = iSpiReadBuffer[2];
   127 		aValue = iSpiReadBuffer[1];
    60 		}
   128 		}
    61 #ifdef VERBOSE_DEBUG
   129 	return r;
    62 	for (int i = 0; i <KSpiPacketLength; i++)
   130 	}
    63 		Kern::Printf("R1[i]: %d", iSpiReadBuffer[1]);
   131 
    64 #endif
   132 
    65 	return r;
   133 //(TODO: consider MidTPtr)
    66 	}
   134 inline TDes& TTouchControllerInterface::ReadBuff()
    67 
   135 	{
    68 TInt TTouchControllerInterface::Write(TUint8 aRegAddress, TUint8 aValue)
   136 	return iSpiReadBuffer;
    69 	{
   137 	}
    70 	LOG_FUNCTION_CALL;
   138 
    71 	iSpiWriteBuffer[0] = KWriteCommand;
   139 //(TODO: consider MidTPtr)
    72 	iSpiWriteBuffer[1] = aRegAddress;
   140 inline TDes& TTouchControllerInterface::WriteBuff()
    73 	iSpiWriteBuffer[2] = aValue;
   141 	{
    74 
   142 	return iSpiWriteBuffer;
    75 #ifdef VERBOSE_DEBUG
   143 	}
    76 	for (int i = 0; i < 3; i++)
   144 
    77 		Kern::Printf("WR0[i]: %d", iSpiWriteBuffer[i]);
   145 
    78 
   146 // Touch controller implementation
    79 	for (int i = 0; i <KSpiPacketLength; i++)
       
    80 		Kern::Printf("W0[i]: %d", iSpiReadBuffer[1]);
       
    81 #endif
       
    82 	TInt r = IicBus::QueueTransaction(iSpiBusId, &iSpiTransaction);
       
    83 
       
    84 #ifdef VERBOSE_DEBUG
       
    85 	for (int i = 0; i <KSpiPacketLength; i++)
       
    86 		Kern::Printf("W1[i]: %d", iSpiReadBuffer[1]);
       
    87 #endif
       
    88 	return r;
       
    89 	}
       
    90 
       
    91 // Touch controller
       
    92 TouchController::TouchController() :
   147 TouchController::TouchController() :
    93 	iCallback(NULL)
   148 	iCallback(NULL)
    94 	{
   149 	{
    95 	}
   150 	}
    96 
   151 
   106 	if(r == KErrNone)
   161 	if(r == KErrNone)
   107 		{
   162 		{
   108 		r = GPIO::SetPinDirection(KResetPin, GPIO::EOutput);
   163 		r = GPIO::SetPinDirection(KResetPin, GPIO::EOutput);
   109 		if(r == KErrNone)
   164 		if(r == KErrNone)
   110 			{
   165 			{
   111 //			GPIO::SetOutputState(KResetPin, GPIO::ELow);
   166 #ifdef RESET_LOW
       
   167 			GPIO::SetOutputState(KResetPin, GPIO::ELow);
       
   168 #else
   112 			GPIO::SetOutputState(KResetPin, GPIO::EHigh);
   169 			GPIO::SetOutputState(KResetPin, GPIO::EHigh);
   113 //			GPIO::SetOutputState(KResetPin, GPIO::ELow);
   170 #endif
   114 
       
   115 			Kern::NanoWait(25000); // should be > 10us
   171 			Kern::NanoWait(25000); // should be > 10us
   116 //			GPIO::SetOutputState(KResetPin, GPIO::EHigh);
   172 #ifdef RESET_LOW
       
   173 
       
   174 			GPIO::SetOutputState(KResetPin, GPIO::EHigh);
       
   175 #else
   117 			GPIO::SetOutputState(KResetPin, GPIO::ELow);
   176 			GPIO::SetOutputState(KResetPin, GPIO::ELow);
   118 
   177 #endif
   119 			}
   178 			}
   120 		}
   179 		}
   121 //	Kern::NanoWait(1000000);
       
   122 //	SoftReset();
       
   123 //	Kern::NanoWait(1000000);
       
   124 
       
   125 	iInterface.Write(KMasterReadStartAddr, X1_H);
       
   126 	return r;
   180 	return r;
   127 	}
   181 	}
   128 TInt TouchController::SoftReset()
   182 TInt TouchController::SoftReset()
   129 	{
   183 	{
   130 	LOG_FUNCTION_CALL;
       
   131 	for(TInt i = 0; i<4; i++)
       
   132 		{
       
   133 		iCtrlRegsCache[i] = 0;
       
   134 		}
       
   135 	return iInterface.Write(KControl_0, KControl_0_SWRST);
   184 	return iInterface.Write(KControl_0, KControl_0_SWRST);
       
   185 	}
       
   186 
       
   187 TInt TouchController::Configure(TTouchMode aMode)
       
   188 	{
       
   189 	LOG_FUNCTION_CALL;
       
   190 	TDes& writeBuffer = iInterface.WriteBuff();
       
   191 	writeBuffer.SetLength(14);
       
   192 
       
   193 	// value for KControl_0 register in writeBuffer[1]
       
   194 	switch(aMode)
       
   195 		{
       
   196 		case EModeSingle:
       
   197 			writeBuffer[1] = KControl_0_MODE_SINGLE;
       
   198 			break;
       
   199 		case EModeMulti:
       
   200 			writeBuffer[1] = KControl_0_MODE_MULTI;
       
   201 			break;
       
   202 		case EModeGesture:
       
   203 			writeBuffer[1] = KControl_0_MODE_GESTURE;
       
   204 			break;
       
   205 		}
       
   206 
       
   207 //	const TUint8 KWindowXStart_Msb = 0x4; // R/W
       
   208 //	const TUint8 KWindowXStart_Lsb = 0x5; // R/W
       
   209 //	const TUint8 KWindowXStop_Msb  = 0x6; // R/W
       
   210 //	const TUint8 KWindowXStop_Lsb  = 0x7; // R/W
       
   211 //	const TUint8 KWindowYStart_Msb = 0x8; // R/W
       
   212 //	const TUint8 KWindowYStart_Lsb = 0x9; // R/W
       
   213 //	const TUint8 KWindowYStop_Msb  = 0xa; // R/W
       
   214 //	const TUint8 KWindowYStop_Lsb  = 0xb; // R/W
       
   215 //	const TUint8 KMasterReadStartAddr = 0xc; // R/W
       
   216 
       
   217 	writeBuffer[2] = (TInt8)(KControl_1_PAT_100 | KControl_1_PVT_200); // KControl_1 // TODO: update these values..
       
   218 	writeBuffer[3] = (TInt8)(KNumColumns << KControl_2_C_SHIFT);       // KControl_2 // TODO: update these values..
       
   219 	writeBuffer[4] = (TInt8)(KNumRows    << KControl_3_R_SHIFT);       // KControl_3 // TODO: update these values..
       
   220 
       
   221 	writeBuffer[5] = 0; // KWindowXStart_Msb // TODO: update these values..
       
   222 	writeBuffer[6] = 0; // KWindowXStart_Lsb // TODO: update these values..
       
   223 	writeBuffer[7] = 0; // KWindowXStop_Msb // TODO: update these values..
       
   224 	writeBuffer[8] = 0; // KWindowXStop_Lsb // TODO: update these values..
       
   225 
       
   226 	writeBuffer[9] = 0; // KWindowYStart_Msb // TODO: update these values..
       
   227 	writeBuffer[10] = 0; // KWindowYStart_Lsb // TODO: update these values..
       
   228 	writeBuffer[11] = 0; // KWindowYStop_Msb // TODO: update these values..
       
   229 	writeBuffer[12] = 0; // KWindowYStop_Lsb // TODO: update these values..
       
   230 	writeBuffer[13] = 0; // KMasterReadStartAddr // TODO: update these values..
       
   231 
       
   232 	return iInterface.WriteMultiple(KControl_0, 14);
   136 	}
   233 	}
   137 
   234 
   138 TInt TouchController::SetTouchMode(TTouchMode aMode)
   235 TInt TouchController::SetTouchMode(TTouchMode aMode)
   139 	{
   236 	{
   140 	LOG_FUNCTION_CALL;
   237 	LOG_FUNCTION_CALL;
   141 	iCtrlRegsCache[0] &= ~KControl_0_MODE_MASK; // clear all mode bits
   238 	iCtrlRegsCache[0] &= ~KControl_0_MODE_MASK; // clear all mode bits
   142 	switch(aMode)
   239 	switch(aMode)
   143 		{
   240 		{
   144 		case ESingle:
   241 		case EModeSingle:
   145 			iCtrlRegsCache[0] |= KControl_0_MODE_SINGLE;
   242 			iCtrlRegsCache[0] |= KControl_0_MODE_SINGLE;
   146 			break;
   243 			break;
   147 		case EMulti:
   244 		case EModeMulti:
   148 			iCtrlRegsCache[0] |= KControl_0_MODE_MULTI;
   245 			iCtrlRegsCache[0] |= KControl_0_MODE_MULTI;
   149 			break;
   246 			break;
   150 		case EGesture:
   247 		case EModeGesture:
   151 			iCtrlRegsCache[0] |= KControl_0_MODE_GESTURE;
   248 			iCtrlRegsCache[0] |= KControl_0_MODE_GESTURE;
   152 			break;
   249 			break;
   153 		}
   250 		}
   154 
   251 
   155 	return iInterface.Write(KControl_0, iCtrlRegsCache[0]);
   252 	return iInterface.Write(KControl_0, iCtrlRegsCache[0]);
   201 	iCtrlRegsCache[2] &= ~KControl_2_C_MASK; // clear bits..
   298 	iCtrlRegsCache[2] &= ~KControl_2_C_MASK; // clear bits..
   202 	iCtrlRegsCache[2] |= (aNumberOfColumns << KControl_2_C_SHIFT) & KControl_2_C_MASK;
   299 	iCtrlRegsCache[2] |= (aNumberOfColumns << KControl_2_C_SHIFT) & KControl_2_C_MASK;
   203 	return iInterface.Write(KControl_2, iCtrlRegsCache[2]);
   300 	return iInterface.Write(KControl_2, iCtrlRegsCache[2]);
   204 	}
   301 	}
   205 
   302 
       
   303 
   206 TInt TouchController::SetNumberOfRows(TUint aNumberOfRows)
   304 TInt TouchController::SetNumberOfRows(TUint aNumberOfRows)
   207 	{
   305 	{
   208 	LOG_FUNCTION_CALL;
   306 	LOG_FUNCTION_CALL;
   209 	iCtrlRegsCache[3] &= ~KControl_3_R_SHIFT; // clear bits..
   307 	iCtrlRegsCache[3] &= ~KControl_3_R_SHIFT; // clear bits..
   210 	iCtrlRegsCache[3] |= (aNumberOfRows << KControl_3_R_SHIFT) & KControl_3_R_MASK; // set new value..
   308 	iCtrlRegsCache[3] |= (aNumberOfRows << KControl_3_R_SHIFT) & KControl_3_R_MASK; // set new value..
   211 	return iInterface.Write(KControl_3, iCtrlRegsCache[3]);
   309 	return iInterface.Write(KControl_3, iCtrlRegsCache[3]);
   212 	}
   310 	}
   213 
   311 
       
   312 
   214 TInt TouchController::EnableWindowMode(TPoint aStart, TPoint aStop)
   313 TInt TouchController::EnableWindowMode(TPoint aStart, TPoint aStop)
   215 	{
   314 	{
   216 	LOG_FUNCTION_CALL;
   315 	LOG_FUNCTION_CALL;
   217 
   316 	TDes& writeBuffer = iInterface.WriteBuff();
   218 	TBool error_occured = EFalse;
   317 	writeBuffer.SetLength(9);
       
   318 
   219 	// setup window points
   319 	// setup window points
   220 	TInt r = iInterface.Write(KWindowXStart_Msb, (TUint8)(aStart.iX >> 8));
   320 	writeBuffer[0] = KWriteCommand | (KWindowXStart_Msb << 1); // address of first register to write..
   221 	if(r != KErrNone)
   321 	writeBuffer[1] = (TUint8)(aStart.iX >> 8); // KWindowXStart_Msb
   222 		error_occured = ETrue;
   322 	writeBuffer[2] = (TUint8)(aStart.iX);      // KWindowXStart_Lsb
   223 
   323 	writeBuffer[3] = (TUint8)(aStop.iX >> 8);  // KWindowXStop_Msb
   224 	r = iInterface.Write(KWindowXStart_Lsb, (TUint8)(aStart.iX));
   324 	writeBuffer[4] = (TUint8)(aStop.iX);       // KWindowXStop_Lsb
   225 	if(r != KErrNone)
   325 	writeBuffer[5] = (TUint8)(aStart.iY >> 8); // KWindowYStart_Msb
   226 		error_occured = ETrue;
   326 	writeBuffer[6] = (TUint8)(aStart.iY);      // KWindowYStart_Lsb
   227 
   327 	writeBuffer[7] = (TUint8)(aStop.iY >> 8);  // KWindowYStop_Msb
   228 	r = iInterface.Write(KWindowYStart_Msb, (TUint8)(aStart.iY >> 8));
   328 	writeBuffer[8] = (TUint8)(aStop.iY);       // KWindowYStop_Lsb
   229 	if(r != KErrNone)
   329 
   230 		error_occured = ETrue;
   330 	return iInterface.WriteMultiple(KWindowXStart_Msb, 9);
   231 
       
   232 	r = iInterface.Write(KWindowYStart_Lsb, (TUint8)(aStart.iY));
       
   233 	if(r != KErrNone)
       
   234 		error_occured = ETrue;
       
   235 
       
   236 	r = iInterface.Write(KWindowXStop_Msb, (TUint8)(aStop.iX >> 8));
       
   237 	if(r != KErrNone)
       
   238 		error_occured = ETrue;
       
   239 
       
   240 	r = iInterface.Write(KWindowXStop_Lsb, (TUint8)(aStop.iX));
       
   241 	if(r != KErrNone)
       
   242 		error_occured = ETrue;
       
   243 
       
   244 	r = iInterface.Write(KWindowYStop_Msb, (TUint8)(aStop.iY >> 8));
       
   245 	if(r != KErrNone)
       
   246 		error_occured = ETrue;
       
   247 
       
   248 	r = iInterface.Write(KWindowYStop_Lsb, (TUint8)(aStop.iY));
       
   249 	if(r != KErrNone)
       
   250 		error_occured = ETrue;
       
   251 
       
   252 	// enable mode
       
   253 	if(!error_occured)
       
   254 		{
       
   255 		iCtrlRegsCache[1] |= ~KControl_1_WS; // set enable bit..
       
   256 		r = iInterface.Write(KControl_1, iCtrlRegsCache[1]);
       
   257 		}
       
   258 	else
       
   259 		{
       
   260 		r = KErrGeneral;
       
   261 		}
       
   262 	return r;
       
   263 	}
   331 	}
   264 
   332 
   265 TInt TouchController::DisableWindowMode()
   333 TInt TouchController::DisableWindowMode()
   266 	{
   334 	{
   267 	LOG_FUNCTION_CALL;
   335 	LOG_FUNCTION_CALL;
   270 	}
   338 	}
   271 
   339 
   272 TInt TouchController::NumOfTouches()
   340 TInt TouchController::NumOfTouches()
   273 	{
   341 	{
   274 	TUint8 val = 0;
   342 	TUint8 val = 0;
   275 	return iInterface.Read(KTouchNumberAndType, val);
   343 	TInt r = iInterface.Read(KTouchNumberAndType, val);
       
   344 	if (r == KErrNone)
       
   345 		{
       
   346 		r = val;
       
   347 		}
       
   348 	return r;
   276 	}
   349 	}
   277 
   350 
   278 TInt TouchController::GetMeasurements(TPoint* aPoints, TInt& aNumPoints)
   351 TInt TouchController::GetMeasurements(TPoint* aPoints, TInt& aNumPoints)
   279 	{
   352 	{
   280 	LOG_FUNCTION_CALL;
   353 	LOG_FUNCTION_CALL;
   281 	TInt r = KErrArgument;
   354 	TInt r = KErrArgument;
   282 	TInt num_points = 0;
   355 	TInt num_points = 0;
       
   356 
   283 	if(aPoints)
   357 	if(aPoints)
   284 		{
   358 		{
   285 		// check how many points is there to read..
   359 		r = iInterface.ReadMultiple(KTouchNumberAndType, 14);
   286 		TUint8 val = 0;
   360 
   287 		r = iInterface.Read(KTouchNumberAndType, val);
   361 		if(r == KErrNone)
   288 
       
   289 		//Kern::Printf("KTouchNumberAndType %x", val);
       
   290 		// if in multi mode - read all received, but only up to one otherwise..
       
   291 		num_points = val & (val & KTouchNumberAndType_MULTI ? KTouchNumberAndType_TouchNMask : 1);
       
   292 
       
   293 		// setup the transaction:
       
   294 		for (TInt i = 0; i < num_points; i++) // if anything was touched at all..
       
   295 			{
   362 			{
   296 			// get X coordinate
   363 			TDes& readBuffer = iInterface.ReadBuff();
   297 			r = iInterface.Read(X1_H + (i << 2), val);
   364 
   298 			if (r != KErrNone)
   365 			// check how many points is there to read..
   299 				break;
   366 			TUint8 val = readBuffer[1]; // TODO: update this if MidTPtr could be used..
   300 
   367 	//		Kern::Printf("KTouchNumberAndType %x", val);
   301 			aPoints[i].iX = TInt(val << 8);
   368 
   302 
   369 			// if in multi mode - read all received, but only up to one otherwise..
   303 			r = iInterface.Read(X1_L + (i << 2) , val);
   370 			num_points = val & (val & KTouchNumberAndType_MULTI ? KTouchNumberAndType_TouchNMask : 1);
   304 			if (r != KErrNone)
   371 
   305 				break;
   372 			// read the coordinates..
   306 
   373 			for (TInt i = 0; i < num_points; i++) // if anything was touched at all..
   307 			aPoints[i].iX |= TInt(val);
   374 				{
   308 
   375 				// get X coordinate
   309 			// get Y coordinate
   376 				aPoints[i].iX |= TInt(readBuffer[(i << 2) + 1] << 8); // X_H
   310 			r = iInterface.Read(Y1_H + (i << 2), val);
   377 				aPoints[i].iX =  TInt(readBuffer[(i << 2) + 2]);      // X_L
   311 			if (r != KErrNone)
   378 
   312 				break;
   379 				// get Y coordinate
   313 
   380 				aPoints[i].iY |= TInt(readBuffer[(i << 2) + 3] << 8); // Yx_H
   314 			aPoints[i].iY = TInt(val << 8);
   381 				aPoints[i].iY =  TInt(readBuffer[(i << 2) + 4]);      // Y_L
   315 
   382 				}
   316 			r = iInterface.Read(Y1_L + (i << 2) , val);
   383 
   317 			if (r != KErrNone)
   384 			aNumPoints = num_points;
   318 				break;
       
   319 
       
   320 			aPoints[i].iY |= TInt(val);
       
   321 			}
   385 			}
   322 		}
   386 		}
   323 
   387 	return r;
   324 	// update number of points
   388 	}
   325 	if (r != KErrNone)
   389 
   326 		{
       
   327 		aNumPoints = 0;
       
   328 		}
       
   329 	else
       
   330 		{
       
   331 		aNumPoints = num_points;
       
   332 		}
       
   333 	return r;
       
   334 	}
       
   335