📄 endpoint.c.svn-base
字号:
#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 + -