⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 endpoint.c.svn-base

📁 lwip协议在arm7+uCos系统上的移植
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
#include "endpoint.h"
#include "os_cpu.h"
#include "44b.h"
#include "uCOS_II.h"
#include "Hpi.h"
#include "Dsp2arm.h"

#include "os_tasks.h"
OS_STK Task6Stack[TASK6_STACKSIZE];

struct raw_data_frame frame_rd[4];
struct erd_tcb tcb_rd[4];
struct raw_data_pointer p_rdata_A;
struct raw_data_pointer p_rdata_B;

struct band_value_frame frame_bv[4];
struct ebv_tcb tcb_bv[4];
struct band_value_pointer p_bvalue_A;
struct band_value_pointer p_bvalue_B;

struct response_frame rframe_A;
struct response_frame rframe_B;

struct hardware_parameter_frame hframe_A;
struct hardware_parameter_frame hframe_B;

struct station_information info_A;
struct station_information info_B;


void rtc_init(void){

	rRTCCON = 1;
	
	rRTCALM = 0;
	rRTCRST = 3;
	rTICINT = 0;

	rRTCCON = 0;

}


void rtc_set(unsigned long long time){

	unsigned char* p;

	p = (unsigned char*)&time;

	rRTCCON |= 0x01;

	rBCDYEAR = p[5];
	rBCDMON = p[4];
	rBCDDAY = p[3];
	rBCDHOUR = p[2];
	rBCDMIN = p[1];

	if(rBCDSEC != 0){
		
		rBCDSEC = p[0];
		
	} else {

		rBCDYEAR = p[5];
		rBCDMON = p[4];
		rBCDDAY = p[3];
		rBCDHOUR = p[2];
		rBCDMIN = p[1];
		rBCDSEC = p[0];
		
	}

	rRTCCON &= 0xfe;

}


unsigned long long rtc_get(void){

	unsigned long long time;
	unsigned char* p;

	time = 0;
	p = (unsigned char*)&time;

	rRTCCON |= 0x01;

	p[5] = rBCDYEAR;
	p[4] = rBCDMON;
	p[3] = rBCDDAY;
	p[2] = rBCDHOUR;
	p[1] = rBCDMIN;

	if(rBCDSEC != 0){
		
		p[0] = rBCDSEC;
		
	} else {

		p[5] = rBCDYEAR;
		p[4] = rBCDMON;
		p[3] = rBCDDAY;
		p[2] = rBCDHOUR;
		p[1] = rBCDMIN;
		p[0] = rBCDSEC;
		
	}
	
	rRTCCON &= 0xfe;

	return time;

}


void endpoint_init(void){

	int i;

	for(i=0;i<4;i++){
		
		frame_rd[i].r_frame.func_code = func_fetch_raw;
		frame_rd[i].raw_data.count = 0;

		tcb_rd[i].rd_frame = &frame_rd[i];
		tcb_rd[i].counter = 0;
		tcb_rd[i].sending= 0;

		frame_bv[i].r_frame.func_code = func_inquiry_endpoint;
		
		tcb_bv[i].bv_frame = &frame_bv[i];
		tcb_bv[i].sending = 0;
		tcb_bv[i].writen =0;
	}
	
	tcb_rd[0].next = &tcb_rd[1];
	tcb_rd[1].next = &tcb_rd[0];
	tcb_rd[2].next = &tcb_rd[3];
	tcb_rd[3].next = &tcb_rd[2];
	
	tcb_bv[0].next = &tcb_bv[1];
	tcb_bv[1].next = &tcb_bv[0];
	tcb_bv[2].next = &tcb_bv[3];
	tcb_bv[3].next = &tcb_bv[2];
	
	p_rdata_A.erd_sender = p_rdata_A.erd_writer = &tcb_rd[0];
	p_rdata_B.erd_sender = p_rdata_B.erd_writer = &tcb_rd[2];

	p_bvalue_A.ebv_sender = p_bvalue_A.ebv_writer = &tcb_bv[0];
	p_bvalue_B.ebv_sender = p_bvalue_B.ebv_writer = &tcb_bv[2];
	
	hframe_A.r_frame.func_code = func_inquiry_hardware_parameter;
	hframe_B.r_frame.func_code = func_inquiry_hardware_parameter;

	info_A.p_rdata = &p_rdata_A;
	info_A.p_bvalue = &p_bvalue_A;
	info_A.hframe = &hframe_A;
	info_A.rframe = &rframe_A;

	info_B.p_rdata = &p_rdata_B;
	info_B.p_bvalue = &p_bvalue_B;
	info_B.hframe = &hframe_B;
	info_B.rframe = &rframe_B;

	info_A.dsp_sem = OSSemCreate(0);
	info_B.dsp_sem = OSSemCreate(0);

	info_A.other = &info_B;
	info_B.other = &info_A;
	

}


void send_raw_data(struct station_information* info){

	#if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
 	OS_CPU_SR  cpu_sr;
	#endif

	int len;

	OS_ENTER_CRITICAL();
	info->p_rdata->erd_writer = info->p_rdata->erd_sender->next;
	info->p_rdata->erd_sender->sending = 1;
	OS_EXIT_CRITICAL();

	if (info->p_rdata->erd_sender->counter != 0){

		info->p_rdata->erd_sender->rd_frame->r_frame.err = err_ok;
		info->p_rdata->erd_sender->rd_frame->raw_data.count = info->p_rdata->erd_sender->counter;
		len = rframe_len + 2 + info->p_rdata->erd_sender->counter * sizeof(info->p_rdata->erd_sender->rd_frame->raw_data.data[0]);
		netconn_write(info->conn, (void*)info->p_rdata->erd_sender->rd_frame, len,NETCONN_NOCOPY);
		info->p_rdata->erd_sender->counter = 0;

	} else {

		info->p_rdata->erd_sender->rd_frame->r_frame.err = err_nodata;
		netconn_write(info->conn, (void*)info->p_rdata->erd_sender->rd_frame, rframe_len, NETCONN_NOCOPY);

	}
	
	OS_ENTER_CRITICAL();
	info->p_rdata->erd_sender->sending = 0;
	info->p_rdata->erd_sender = info->p_rdata->erd_sender->next;
	OS_EXIT_CRITICAL();

}


void send_harware_parameter(struct station_information* info){

	netconn_write(info->conn, (void*)info->hframe, hframe_len, NETCONN_NOCOPY);

}


void send_band_value(struct station_information* info){

	#if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
 	OS_CPU_SR  cpu_sr;
	#endif


	OS_ENTER_CRITICAL();
	info->p_bvalue->ebv_writer = info->p_bvalue->ebv_sender->next;
	info->p_bvalue->ebv_sender->sending = 1;
	OS_EXIT_CRITICAL();

	if(info->p_bvalue->ebv_sender->writen == 1){

		info->p_bvalue->ebv_sender->bv_frame->r_frame.err = err_ok;
		netconn_write(info->conn, (void*)info->p_bvalue->ebv_sender->bv_frame, bframe_len, NETCONN_NOCOPY);
		info->p_bvalue->ebv_sender->writen = 0;
	
	} else {

		info->p_bvalue->ebv_sender->bv_frame->r_frame.err = err_nodata;
		netconn_write(info->conn, (void*)info->p_bvalue->ebv_sender->bv_frame, rframe_len, NETCONN_NOCOPY);

	}
	
	OS_ENTER_CRITICAL();
	info->p_bvalue->ebv_sender->sending = 0;
	info->p_bvalue->ebv_sender = info->p_bvalue->ebv_sender->next;
	OS_EXIT_CRITICAL();


}


void send_pre_data(struct station_information* info){

	INT8U err;

	info->p_rdata->erd_sender = info->p_rdata->erd_writer;
	info->p_rdata->erd_writer->counter = 0;

	info->pre_need = 1;
	if(info->other->pre_geting == 0){

		info->pre_geting = 1;

		do{
			HWriteS(DSP_GDATA_NUM, info->pre_list.numbers[info->pre_list.send_counter]);
			HWriteS(DSP_INT_TYPEF, SHK_PRE_DATA);
			Hint();

			OSSemPend(info->dsp_sem, (INT16U)0, &err);

			send_raw_data(info);


		} while(info->pre_list.numbers[++info->pre_list.send_counter] != 0);

		info->pre_geting = 0;
		info->pre_need = 0;

		if (info->other->pre_need == 1){

			OSSemPost(info->other->dsp_sem);
		}
	} else {

		OSSemPend(info->dsp_sem, (INT16U)0, &err);

		info->pre_geting = 1;

		do{
		HWriteS(DSP_GDATA_NUM, info->pre_list.numbers[info->pre_list.send_counter]);
		HWriteS(DSP_INT_TYPEF, SHK_PRE_DATA);
		Hint();

		OSSemPend(info->dsp_sem, (INT16U)0, &err);

		send_raw_data(info);


		} while(info->pre_list.numbers[++info->pre_list.send_counter] != 0);

		info->pre_geting = 0;
		info->pre_need = 0;

		if (info->other->pre_need == 1){

			OSSemPost(info->other->dsp_sem);
		}
	}
}



void set_sample_para(struct station_information* info){

	int i;
	unsigned short band_para[2*MAX_BAND_COUNT];

	for(i=0; i<MAX_BAND_COUNT; i++){

		band_para[2*i] = info->step_info[info->cur_step].step_parameter.b_wlength[i];
		band_para[2*i+1] = info->step_info[info->cur_step].step_parameter.b_binning[i];

	}

	HWriteS(DSP_INT_TIME, info->step_info[info->cur_step].step_parameter.exposure_time);
	HWriteC(DSP_BAND_PARA1, band_para, 2*MAX_BAND_COUNT);
	HWriteC(DSP_BAND_PARA2, band_para, 2*MAX_BAND_COUNT);

	HWriteS(DSP_INT_TYPEF, SHK_CCD_PARA);
	Hint();

}


void do_response(struct commad_frame* cframe, unsigned short len, struct station_information* info){


	struct endpoint_sampling_parameter* s_parameter;
	struct endpoint_step_sampling_parameter* ss_parameter;
	struct endpoint_hardware_parameter* h_parameter;


	switch(cframe->func_code){

		case func_inquiry_endpoint:
			send_band_value(info);
			break;
		case func_fetch_raw:
			send_raw_data(info);
			break;
		case func_inquiry_hardware_parameter:
			send_harware_parameter(info);
			break;
		case func_set_hardware_parameter:
			info->rframe->func_code = func_set_hardware_parameter;
			if(len == hardframe_len){

				h_parameter = (struct endpoint_hardware_parameter*)&cframe->data;

			} else {

				info->rframe->err = err_baddata;
				netconn_write(info->conn, (void*)info->rframe, rframe_len, NETCONN_NOCOPY);

			}
			break;
		case func_step_start:
			info->rframe->func_code = func_step_start;
			if(len == stepframe_len){

				ss_parameter = (struct endpoint_step_sampling_parameter*)&cframe->data;
				
				info->step_starting = 1;
				info->cur_step = ss_parameter->step_num;
				info->step_info[ss_parameter->step_num].step_parameter = ss_parameter->s_parameter;
				
				HWriteS(DSP_INT_TIME, ss_parameter->s_parameter.exposure_time);
				HWriteS(DSP_INT_TYPEF, SHK_CCD_PARA);
				Hint();

			} else {

				info->rframe->err = err_baddata;
				netconn_write(info->conn, (void*)info->rframe, rframe_len, NETCONN_NOCOPY);

			}
			break;
		case func_step_end:
			info->rframe->func_code = func_step_end;
			info->rframe->err = err_ok;
			break;
		case func_recipe_start:
			info->rframe->func_code = func_recipe_start;
			info->rframe->err = err_ok;
			break;
		case func_recipe_end:
			info->rframe->func_code = func_recipe_end;
			info->rframe->err = err_ok;
			break;
		case func_sys_start:
			info->rframe->func_code = func_sys_start;
			if(len == sysframe_len){

				s_parameter = (struct endpoint_sampling_parameter*)&cframe->data;

				info->cur_step = 0;
				info->step_info[0].start_num = 0;
				info->step_info[0].step_parameter = *s_parameter;

				HWriteS(DSP_INT_TIME, s_parameter->exposure_time);
				HWriteS(DSP_INT_TYPEF, SHK_CCD_RESTAR);
				Hint();
				
				
			} else {

				info->rframe->err = err_baddata;
				netconn_write(info->conn, (void*)info->rframe, rframe_len, NETCONN_NOCOPY);

			}
			
			break;
		case func_sys_end:
			info->rframe->func_code = func_sys_end;
			info->rframe->err = err_ok;
			break;
		default:
			info->rframe->func_code = cframe->func_code;
			info->rframe->err = err_badfunc;
			netconn_write(info->conn, (void*)info->rframe, rframe_len, NETCONN_NOCOPY);
			break;

	}

}



/***************************************************************************

关于原始数据的操作规则:

真正用于发送的数据结构为raw_data_frame。
这个结构和协议要求一样,1 byte对齐。

erd_tcb结构用于控制:

struct erd_tcb{
	struct erd_tcb *next;
	volatile struct raw_data_frame* rd_frame;
	int full;
	int sending;
};

每一个通道由两个erd_tcb构成,它们指向不同的raw_data_frame。
同时,它们的next指针分别指向对方。

每一个通道有两个指向erd_tcb的指针,分别是erd_sender和erd_writer。
他们用于控制读和写。

读写操作相互独立,之间并没有通信。

write操作:
	erd_writer所指是否full,不是就写入数据。
	是就判断next是否sending。是就放弃这一次操作。
	不是则:erd_sender = erd_writer;erd_writer = erd_writer->next;
	清空erd_writer所指的数据,写入新数据。
    
send操作:
	判断erd_sender所指是否为空,是就发送错误信息。
	不是则标记sending,erd_writer = erd_sender->next;
	发送数据,发送后清空erd_sender所指数据,erd_sender = erd_sender->next;
	清除原来sending标志。

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -