#include #include #include #include #include #include #include #include #include "adc.h" #include "hinf.h" #define RAND_MAX 2147483647 // stdlib.h を include するとエラーになるので,RAND_MAX をここで定義する pthread_t mytask; volatile float * time_resp; volatile double * cont_real; volatile struct my_msg_struct * msg; void *thread_code(void *arg) { volatile double * p; hrtime_t s_time; float t, t0; int count_record, flag = 0; int i, j; // double u, y[2], w; double u, y[CH+1], w; double x[ORDER_MAX]; // 補償器の状態 double x_tmp[ORDER_MAX]; while(1){ int ret; int err; ret = pthread_wait_np(); if (msg->command == START_TASK) { msg->command = STOP_TASK; flag = 1; count_record = 0; u = 0.; w = 0.; for(i = 0; i < msg->order; i++){ x[i] = 0.; } s_time = gethrtime(); pthread_make_periodic_np(pthread_self(), s_time, msg->sampling_period * 1.0e9); } if(flag == 1){ t = (gethrtime() - s_time)*1.0e-9; w = AMP * (2. * rand() / (RAND_MAX + 1.) - 1.); // 白色雑音用データを乱数で発生 da_conv(V_OFFSET + w, 0); // 一次音源スピーカに出力 ad_conv(&y); y[0] -= REFMIC_OFFSET; y[1] -= ERRMIC_OFFSET; if(count_record > BUF_LEN * WAITING_SAMPLES){ /* u = C x + D y */ u = 0.; p = &cont_real[msg->order * (msg->order + 1)]; for(i = 0; i < msg->order; i++){ u += *p * x[i]; p++; } u += *p * y[0]; if(u > U_MAX) u = U_MAX; if(u < -U_MAX) u = -U_MAX; #ifdef NO_CONTROL u = 0; #endif da_conv(V_OFFSET + u, 1); // 2次スピーカに出力 /* x[k+1] = A x[k] + B y */ p = cont_real; for(i = 0; i < msg->order; i++){ x_tmp[i] = 0.; for(j = 0; j < msg->order; j++){ x_tmp[i] += *p * x[j]; p++; } x_tmp[i] += *p * y[0]; p++; } memcpy(x, x_tmp, sizeof(x)); } if(count_record < BUF_LEN * RECORDING_SAMPLES){ time_resp[count_record++] = t; time_resp[count_record++] = y[1]; // err. mic. output z time_resp[count_record++] = y[0]; // ref. mic. output y time_resp[count_record++] = u; // control input u time_resp[count_record++] = w; // noise source input w }else{ flag = 0; pthread_make_periodic_np(pthread_self(), gethrtime(), 0.1 * 1e9); } } } return 0; } int init_module(void) { pthread_attr_t attr; struct sched_param sched_param; int ret; if((time_resp = (volatile float *) mbuff_alloc("time_resp", BUF_LEN * RECORDING_SAMPLES * sizeof(float))) == NULL){ rtl_printf("mbuff_alloc failed for time_resp\n"); return -1; } if((cont_real = (volatile double *) mbuff_alloc("cont_real", (ORDER_MAX + 1) * (ORDER_MAX + 1) * sizeof(double))) == NULL){ rtl_printf("mbuff_alloc failed for cont_real\n"); return -1; } if((msg = (volatile struct my_msg_struct *) mbuff_alloc("msg", sizeof(struct my_msg_struct))) == NULL){ rtl_printf("mbuff_alloc failed\n"); return -1; } msg->command = STOP_TASK; pthread_attr_init (&attr); /* 属性の初期化 */ pthread_attr_setfp_np(&attr, 1); /* FPU の使用を許可 */ sched_param.sched_priority = 1; /* 優先順位 */ pthread_attr_setschedparam (&attr, &sched_param); init_adc(); init_dac(); da_conv(V_OFFSET, 0); da_conv(V_OFFSET, 1); ret = pthread_create (&mytask, &attr, thread_code, (void *)0); pthread_make_periodic_np(mytask, gethrtime(), 0.1 * 1e9); rtl_printf("hinf_module: init\n"); return 0; } void cleanup_module(void) { mbuff_free("time_resp",(void*)time_resp); mbuff_free("cont_real",(void*)cont_real); mbuff_free("msg",(void*)msg); pthread_cancel(mytask); pthread_join(mytask, NULL); cleanup_adc(); cleanup_dac(); da_conv(V_OFFSET, 0); da_conv(V_OFFSET, 1); rtl_printf("hinf_module: cleanup\n"); }