Exemplo n.º 1
0
static Eterm do_chksum(ChksumFun sumfun, Process *p, Eterm ioterm, int left, 
		       void *sum, int *res, int *err)
{
    Eterm *objp;
    Eterm obj;
    int c;
    DECLARE_ESTACK(stack);
    unsigned char *bytes = NULL;
    int numbytes = 0;

    *err = 0;
    if (left <= 0 || is_nil(ioterm)) {
	DESTROY_ESTACK(stack);
	*res = 0;
	return ioterm;
    }
    if(is_binary(ioterm)) {
	Uint bitoffs;
	Uint bitsize;
	Uint size;
	Eterm res_term = NIL;
	unsigned char *bytes;
	byte *temp_alloc = NULL;
	
	ERTS_GET_BINARY_BYTES(ioterm, bytes, bitoffs, bitsize);
	if (bitsize != 0) {
	    *res = 0;
	    *err = 1;
	    DESTROY_ESTACK(stack);
	    return NIL;
	}
	if (bitoffs != 0) {
	    bytes = erts_get_aligned_binary_bytes(ioterm, &temp_alloc);
	    /* The call to erts_get_aligned_binary_bytes cannot fail as 
	       we'we already checked bitsize and that this is a binary */
	}

	size = binary_size(ioterm);


	if (size > left) {
	    Eterm *hp;
	    ErlSubBin *sb;
	    Eterm orig;
	    Uint offset;
	    /* Split the binary in two parts, of which we 
	       only process the first */
	    hp = HAlloc(p, ERL_SUB_BIN_SIZE);
	    sb = (ErlSubBin *) hp;
	    ERTS_GET_REAL_BIN(ioterm, orig, offset, bitoffs, bitsize);
	    sb->thing_word = HEADER_SUB_BIN;
	    sb->size = size - left;
	    sb->offs = offset + left;
	    sb->orig = orig;
	    sb->bitoffs = bitoffs;
	    sb->bitsize = bitsize;
	    sb->is_writable = 0;
	    res_term = make_binary(sb);
	    size = left;
	}
	(*sumfun)(sum, bytes, size);
	*res = size;
	DESTROY_ESTACK(stack);
	erts_free_aligned_binary_bytes(temp_alloc);
	return res_term;
    }
	
    if (!is_list(ioterm)) {
	*res = 0;
	*err = 1;
	DESTROY_ESTACK(stack);
	return NIL;
    }

    /* OK a list, needs to be processed in order, handling each flat list-level
       as they occur, just like io_list_to_binary would */
    *res = 0;
    ESTACK_PUSH(stack,ioterm);
    while (!ESTACK_ISEMPTY(stack) && left) {
	ioterm = ESTACK_POP(stack);
	if (is_nil(ioterm)) {
	    /* ignore empty lists */
	    continue;
	}
	if(is_list(ioterm)) {
L_Again:   /* Restart with sublist, old listend was pushed on stack */
	    objp = list_val(ioterm);
	    obj = CAR(objp);
	    for(;;) { /* loop over one flat list of bytes and binaries
		         until sublist or list end is encountered */
		if (is_byte(obj)) {
		    int bsize = 0;
		    for(;;) {
			if (bsize >= numbytes) {
			    if (!bytes) {
				bytes = erts_alloc(ERTS_ALC_T_TMP, 
						   numbytes = 500);
			    } else {
				if (numbytes > left) {
				    numbytes += left;
				} else {
				    numbytes *= 2;
				}
				bytes = erts_realloc(ERTS_ALC_T_TMP, bytes,
						     numbytes);
			    }
			}  
			bytes[bsize++] = (unsigned char) unsigned_val(obj);
			--left;
			ioterm = CDR(objp);
			if (!is_list(ioterm)) {
			    break;
			}
			objp = list_val(ioterm);
			obj = CAR(objp);
			if (!is_byte(obj))
			    break;
			if (!left) {
			    break;
			}
		    }
		    (*sumfun)(sum, bytes, bsize);
		    *res += bsize;
		} else if (is_nil(obj)) {
		    ioterm = CDR(objp);
		    if (!is_list(ioterm)) {
			break;
		    }
		    objp = list_val(ioterm);
		    obj = CAR(objp);
		} else if (is_list(obj)) {
		    /* push rest of list for later processing, start 
		       again with sublist */
		    ESTACK_PUSH(stack,CDR(objp));
		    ioterm = obj;
		    goto L_Again;
		} else if (is_binary(obj)) {
		    int sres, serr;
		    Eterm rest_term;
		    rest_term = do_chksum(sumfun, p, obj, left, sum, &sres,
					  &serr);
		    *res += sres;
		    if (serr != 0) {
			*err = 1;
			DESTROY_ESTACK(stack);
			if (bytes != NULL)
			    erts_free(ERTS_ALC_T_TMP, bytes);
			return NIL;
		    }
		    left -= sres;
		    if (rest_term != NIL) {
			Eterm *hp;
			hp = HAlloc(p, 2);
			obj = CDR(objp);
			ioterm = CONS(hp, rest_term, obj);
			left = 0;
			break;
		    }
		    ioterm = CDR(objp);
		    if (is_list(ioterm)) {
			/* objp and obj need to be updated if 
			   loop is to continue */
			objp = list_val(ioterm);
			obj = CAR(objp);
		    }
		} else {
		    *err = 1;
		    DESTROY_ESTACK(stack);
		    if (bytes != NULL)
			erts_free(ERTS_ALC_T_TMP, bytes);
		    return NIL;
		} 
		if (!left || is_nil(ioterm) || !is_list(ioterm)) {
		    break;
		}
	    } /* for(;;) */
	} /* is_list(ioterm) */

	if (!left) {
#ifdef ALLOW_BYTE_TAIL
	    if (is_byte(ioterm)) {
		/* inproper list with byte tail*/
		Eterm *hp;
		hp = HAlloc(p, 2);
		ioterm = CONS(hp, ioterm, NIL);
	    }
#else
	    ;
#endif
	} else if (!is_list(ioterm) && !is_nil(ioterm)) {
	    /* inproper list end */
#ifdef ALLOW_BYTE_TAIL
	    if (is_byte(ioterm)) {
		unsigned char b[1];
		b[0] = (unsigned char) unsigned_val(ioterm);
		(*sumfun)(sum, b, 1);
		++(*res);
		--left;
		ioterm = NIL;
	    } else
#endif 
	    if is_binary(ioterm) {
		int sres, serr;
		ioterm = do_chksum(sumfun, p, ioterm, left, sum, &sres, &serr);
		*res +=sres;
		if (serr != 0) {
		    *err = 1;
		    DESTROY_ESTACK(stack);
		    if (bytes != NULL)
			erts_free(ERTS_ALC_T_TMP, bytes);
		    return NIL;
		}
		left -= sres;
	    } else {
		*err = 1;
		DESTROY_ESTACK(stack);
		if (bytes != NULL)
		    erts_free(ERTS_ALC_T_TMP, bytes);
		return NIL;
	    }
	}
    } /* while left and not estack empty */
Exemplo n.º 2
0
void send_telemetry(struct sensordata *sensorData_ptr, struct nav *navData_ptr, struct control *controlData_ptr, struct mission *missionData_ptr, uint16_t cpuLoad)
{
	int bytes=0;
	unsigned short flags=0;
	unsigned long tmp;
	uint16_t tele_data[23], output_CKSUM=0;
	static byte sendpacket[TELE_PACKET_SIZE]={'U','U','T',};

	// Build send_telemetry data packet
	tmp = (unsigned long)( sensorData_ptr->imuData_ptr->time*1e04 );		// time buffer will now overflow after 59.6 hrs (thats what 4 bytes' worth!)
	memcpy(&tele_data[0],&tmp,4);

	tele_data[2] = (uint16_t)(0);
	tele_data[3] = (uint16_t)(0);

	tele_data[4] = (uint16_t)( sensorData_ptr->imuData_ptr->p*R2D / 200.0 * 0x7FFF );	//rate = 200 deg/s max saturation
	tele_data[5] = (uint16_t)( sensorData_ptr->imuData_ptr->q*R2D / 200.0 * 0x7FFF );
	tele_data[6] = (uint16_t)( sensorData_ptr->imuData_ptr->r*R2D / 200.0 * 0x7FFF );
	
	tele_data[7] = (uint16_t)( (sensorData_ptr->adData_ptr->h) / 10000.0 * 0x7FFF );			// max AGL Alt.(m) = 10000 m
	tele_data[8] = (uint16_t)( (sensorData_ptr->adData_ptr->ias) / 80.0 * 0x7FFF );				// max Indicated Airspeed(IAS) = 80 m/s	

	tele_data[9] = (uint16_t)( navData_ptr->psi*R2D / 180.0 * 0x7FFF );		// Euler angles [psi,theta,phi] (deg)
	tele_data[10]= (uint16_t)( navData_ptr->the*R2D / 90.0 * 0x7FFF );
	tele_data[11]= (uint16_t)( navData_ptr->phi*R2D / 180.0 * 0x7FFF );

	tele_data[12]= (uint16_t)( (controlData_ptr->da_r-controlData_ptr->da_l)/2 / R_AILERON_MAX * 0x7FFF );		// control surface commands (normalized 0-1)
	tele_data[13]= (uint16_t)( controlData_ptr->de / ELEVATOR_MAX * 0x7FFF );
	tele_data[14]= (uint16_t)( controlData_ptr->dthr * 0x7FFF );
	tele_data[15]= (uint16_t)( controlData_ptr->dr / RUDDER_MAX * 0x7FFF );


	tele_data[16] = cpuLoad;		/* cpuload */

	tmp = (unsigned long)( sensorData_ptr->gpsData_ptr->lon *1e07 );
	memcpy(&tele_data[17],&tmp,4);
	tmp = (unsigned long)( sensorData_ptr->gpsData_ptr->lat *1e07 );
	memcpy(&tele_data[19],&tmp,4);

	//if (ofpMode == standby) flags = flags | 0x01;
	if (missionData_ptr->mode == 2) flags = flags | 0x01<<1;	// Autopilot mode
	if (missionData_ptr->mode == 1) flags = flags | 0x01<<4;  // Manual mode
	if ( (sensorData_ptr->imuData_ptr->err_type != checksum_err) && (sensorData_ptr->imuData_ptr->err_type != got_invalid) ) flags = flags | 0x01<<6;
	if (sensorData_ptr->gpsData_ptr->err_type == data_valid || sensorData_ptr->gpsData_ptr->err_type == incompletePacket) flags = flags | 0x01<<7;
	if (sensorData_ptr->gpsData_ptr->navValid == 0) flags = flags | 0x01<<8;
	
	tele_data[21] = flags;
	tele_data[22] = (uint16_t)sensorData_ptr->gpsData_ptr->satVisible;
	
	
	memcpy(&sendpacket[3],&tele_data,46);
	// compute 16-bit checksum of output data (excluding the header)
	output_CKSUM = do_chksum (sendpacket, 2,TELE_PACKET_SIZE-2);
	*(uint16_t *)&sendpacket[49] = output_CKSUM;

	// send send_telemetry data packet to serial port
	while(bytes != TELE_PACKET_SIZE) bytes += write(port, &sendpacket[bytes], TELE_PACKET_SIZE-bytes); bytes=0;
	
	// Send status message if present
	if (statusMsg[0] != 0){
		while(bytes != 103) bytes += write(port, &statusMsg[bytes], 103-bytes); bytes=0;
		statusMsg[0] =0;
	}
}
Exemplo n.º 3
0
int read_gps(struct gps *gpsData_ptr)
{
	// serial port buffer handle
	cyg_io_handle_t port_handle;
	cyg_serial_buf_info_t buff_info;
	unsigned int len = sizeof (buff_info);

	// get serial port handle
	cyg_io_lookup( gpsData_ptr->portName, &port_handle );	
	
	cyg_io_get_config (port_handle, CYG_IO_GET_CONFIG_SERIAL_BUFFER_INFO,\
			&buff_info, &len);
	unsigned int bytesInBuffer = buff_info.rx_count;
	unsigned int bytesReadThisCall =0;;
	unsigned short msgPayloadSize = 0, bytesToRead = 0, bytesRead = 0;
	int status = 0;
	
	// Initialization of persistent local buffer
	if (gpsData_ptr->localBuffer == NULL)
	{
		gpsData_ptr->localBuffer = (unsigned char*) malloc (1024 * sizeof (unsigned char));
	}

	// First check if there are any bytes in the serial buffer, return if none
	if( bytesInBuffer == 0 )
		return -1;

	// Get localBuffer stored in gps packet. This is to keep the following code readable
	localBuffer = gpsData_ptr->localBuffer;
	bytesInLocalBuffer= gpsData_ptr->bytesInLocalBuffer;
	readState = gpsData_ptr->readState;
	
	// Keep reading until we've processed all of the bytes in the buffer
	while (bytesReadThisCall < bytesInBuffer){
		
		switch (readState){
			case 0: //Look for packet header bytes
				// Read in up to 2 bytes to the first open location in the local buffer
				bytesRead = read(gpsData_ptr->port,&localBuffer[bytesInLocalBuffer],2-bytesInLocalBuffer);
				bytesReadThisCall += bytesRead; // keep track of bytes read during this call
					
				if (localBuffer[0] == 0xA0){ // Check for first header byte
					bytesInLocalBuffer = 1;
					if (localBuffer[1] == 0xA2){ // Check for second header byte
						bytesInLocalBuffer = 2;
						readState++; // header complete, move to next stage
					}
				}
				else {
					gpsData_ptr->err_type = noPacketHeader;
				}
			break;	// end case 0
			
			case 1: //Look for message size bytes
				// Find how many bytes need to be read for data length (2) - bytes already read (includes 2 byte header)
				bytesToRead = 4 - bytesInLocalBuffer;	
		
				// Read in up to 2 bytes to the first open location in the local buffer
				bytesRead = read(gpsData_ptr->port,&localBuffer[bytesInLocalBuffer],bytesToRead);
				bytesReadThisCall += bytesRead; // keep track of bytes read during this call
				bytesInLocalBuffer += bytesRead; // keep track of bytes in local buffer
				
				if (bytesRead == bytesToRead){
					readState++; // size bytes complete, move to next stage
				}
				else{
					//printf ("\n<GPS>: Failed to get size bytes");
					gpsData_ptr->err_type = incompletePacket;				
				}
			break;	// end case 1
		
			case 2: //Read payload, checksum, and stop bytes
				// Find message payload size
				msgPayloadSize = getbeuw(localBuffer,2)&0x7FFF; // packet size is 15 bits. bitwise AND ensures only 15 bits are used.
				
				//printf("<GPS>: msgPayloadSize: %d\n",msgPayloadSize);
				
				// Error checking on payload size. If size is bigger than expected, dump packet
				if(msgPayloadSize > GPS_MAX_MSG_SIZE){			
					gpsData_ptr->err_type = incompletePacket;
					reset_localBuffer();
				}
				
				// Find how many bytes need to be read for the total message (Header (2) + Size (2) + Payload + checksum (2) + stop (2) - bytes already read )
				bytesToRead = msgPayloadSize + 8 - bytesInLocalBuffer;
				
				// Read in the remainder of the message to the local buffer, starting at the first empty location
				bytesRead = read (gpsData_ptr->port, &localBuffer[bytesInLocalBuffer], bytesToRead);
				bytesInLocalBuffer += bytesRead; // keep track of bytes in local buffer
				bytesReadThisCall += bytesRead; // keep track of bytes read during this call
				
				if (bytesRead == bytesToRead){
					//printf ("\n<GPS>: Got complete message! Tried for %d, got %d",bytesToRead,bytesRead);
					//printf("<GPS>: Packet ID %d \n", localBuffer[4]);
					//printf("<GPS>: msgPayloadSize: %d\n",msgPayloadSize);
					//printf("<GPS>: My checksum: %d  Recv: %d\n",do_chksum(localBuffer, 4, msgPayloadSize+4),getbeuw(localBuffer,4+msgPayloadSize));

					// Checksum verification (15-bit, big endian)
					if ( (do_chksum(localBuffer, 4, msgPayloadSize+4)&0x7FFF) == (getbeuw(localBuffer,4+msgPayloadSize)&0x7FFF) ){
						// If it's OK, extract data
						parse_gps( gpsData_ptr );
						gpsData_ptr->err_type = data_valid;
						//printf ("\n<GPS>: Success!");
						status = 1;
					}
					else{
						//printf ("\n<GPS>: Checksum mismatch!");
						gpsData_ptr->err_type = checksum_err;
					}
					reset_localBuffer(); // Clear the local buffer regardless
				}
				else{
					//printf ("<GPS>: Didn't get complete message. Tried for %d, got %d. %d\n",bytesToRead,bytesRead,msgPayloadSize);
					gpsData_ptr->err_type= incompletePacket;
					
					status = 0;
				}
			break;	// end case 2
				
			default:
				reset_localBuffer();
				printf ("\n<GPS>: Why are you here?");
				status = 0;
			break;	// end default
		
		} // end switch (readState)

	} // end while (bytesReadThisCall < bytesInBuffer)
	
	// Store local buffer in gps packet
	gpsData_ptr->localBuffer = localBuffer;
	gpsData_ptr->bytesInLocalBuffer = bytesInLocalBuffer;
	gpsData_ptr->readState = readState;
	
	return status;
}
Exemplo n.º 4
0
// How to handle static variables with multiple sensors?  objects? add to gpspacket?
int read_gps(struct gps *gpsData_ptr)
{
	cyg_io_handle_t port_handle;
	cyg_serial_buf_info_t buff_info;
	unsigned int len = sizeof (buff_info);

	// get serial port handle
	cyg_io_lookup( gpsData_ptr->portName, &port_handle );
	
	cyg_io_get_config (port_handle, CYG_IO_GET_CONFIG_SERIAL_BUFFER_INFO,\
			&buff_info, &len);
	unsigned int bytesInBuffer = buff_info.rx_count;
	unsigned int bytesReadThisCall =0;;
	unsigned short msgPayloadSize = 0, bytesToRead = 0, bytesRead = 0;
	int status =0;
	
	// Initialization of persistent local buffer
	if (gpsData_ptr->localBuffer == NULL)
	{
		gpsData_ptr->localBuffer = (unsigned char*) malloc (1024 * sizeof (unsigned char));
	}

	// First check if there are any bytes in the serial buffer, return if none
	if( bytesInBuffer == 0 )
		return -1;

	// Get localBuffer stored in gps packet. This is to keep the following code readable
	localBuffer = gpsData_ptr->localBuffer;
	bytesInLocalBuffer= gpsData_ptr->bytesInLocalBuffer;
	readState = gpsData_ptr->readState;

	//fprintf(stderr, "read state is %d (before while)\n", readState);

	// Keep reading until we've processed all of the bytes in the buffer
	while (bytesReadThisCall < bytesInBuffer){
		
		//fprintf(stderr, "read state is %d (after while)\n", readState);

		switch (readState){
			case 0: //Look for packet header bytes
				// Read in up to 4 bytes to the first open location in the local buffer
				bytesRead = read(gpsData_ptr->port,&localBuffer[bytesInLocalBuffer],4-bytesInLocalBuffer);
				bytesReadThisCall += bytesRead; // keep track of bytes read during this call
					
				if (localBuffer[0] == '$'){ // Check for first header byte
					bytesInLocalBuffer = 1;

					//fprintf(stderr, "case 0, $ header type \n");

					if (localBuffer[1] == 'B'){ // Check for second header byte
						bytesInLocalBuffer = 2;
						if (localBuffer[2] == 'I'){ // Check for third header byte
							bytesInLocalBuffer = 3;
							if (localBuffer[3] == 'N'){ // Check for fourth header byte
								bytesInLocalBuffer = 4;
								readState++; // header complete, move to next stage
							}
						}
					}
				}
				else {
					gpsData_ptr->err_type = noPacketHeader;
				}
				break;	// end case 0
				
			case 1: // Look for block ID and data length
				// Find how many bytes need to be read for block ID (2) + data length (2) - bytes already read (includes 4 byte header)
				bytesToRead = 8 - bytesInLocalBuffer;
			
				// Read in bytes to the last location in the local buffer
				bytesRead = read(gpsData_ptr->port,&localBuffer[bytesInLocalBuffer],bytesToRead);
				bytesInLocalBuffer += bytesRead; // keep track of bytes in local buffer
				bytesReadThisCall += bytesRead; // keep track of bytes read during this call
				
				if (bytesRead == bytesToRead){
					readState++;
					//printf ("\n<GPS>: Got msgID: %d and Data Length: %d", localBuffer[5]*256 + localBuffer[4], localBuffer[7]*256 + localBuffer[6]);
				}
				else{
					gpsData_ptr->err_type = incompletePacket;
				}
				break;	// end case 1
		
			case 2: //Read payload, checksum, and stop bytes
				// Find message payload size
				msgPayloadSize = localBuffer[7]*256 + localBuffer[6]; // data is in little endian format
				
				// Error checking on payload size. If size is bigger than expected, dump packet
				if(msgPayloadSize > GPS_MAX_MSG_SIZE){			
					gpsData_ptr->err_type = incompletePacket;
					reset_localBuffer();
				}
				
				// Find how many bytes need to be read for the total message (Header (4)  + ID (2) + Size (2) + Payload + checksum (2) + stop (2) - bytes already read )
				bytesToRead = msgPayloadSize + 12 - bytesInLocalBuffer;
				
				// Read in the remainder of the message to the local buffer, starting at the first empty location
				bytesRead = read (gpsData_ptr->port, &localBuffer[bytesInLocalBuffer], bytesToRead);
				bytesInLocalBuffer += bytesRead; // keep track of bytes in local buffer
				bytesReadThisCall += bytesRead; // keep track of bytes read during this call
				
				if (bytesRead == bytesToRead){
					//printf ("\n<GPS>: Got complete message! Tried for %d, got %d",bytesToRead,bytesRead);
					//printf ("\n<GPS>: My checksum: %d  Recv: %d",do_chksum(localBuffer, 8, msgPayloadSize+8),(localBuffer[8+msgPayloadSize+1]*256 + localBuffer[8+msgPayloadSize]));
					// Checksum verification
					if ( do_chksum(localBuffer, 8, msgPayloadSize+8) == (localBuffer[8+msgPayloadSize+1]*256 + localBuffer[8+msgPayloadSize]) ){
						// If it's OK, extract data
						parse_gps( gpsData_ptr );
						gpsData_ptr->err_type = data_valid;
						//printf ("\n<GPS>: Success!");
						status = 1;
					}										
					else{ 
						//printf ("\n<GPS>: Checksum mismatch!");
						gpsData_ptr->err_type = checksum_err;
					}
					reset_localBuffer();
				}
				else{
					//printf ("\n<GPS>: Didn't get complete message. Tried for %d, got %d",bytesToRead,bytesRead);
					gpsData_ptr->err_type= incompletePacket;
					
					status = 0;									
				}
				break;	// end case 2
				
				default:
					reset_localBuffer();
					printf ("\n<GPS>: Why are you here?");
					status = 0;
				break; // end default
		
		} // end switch (readState)

	} // end while (bytesReadThisCall < bytesInBuffer)	

	// Store local buffer in gps packet
	gpsData_ptr->localBuffer = localBuffer;
	gpsData_ptr->bytesInLocalBuffer = bytesInLocalBuffer;
	gpsData_ptr->readState = readState;
	
	return status;
}