/* * ddr.c * * Created on: 26-05-2014 * Author: KJ */ #include "tdefs.h" #include "misc.h" #include #include #include "ddr.h" #include "ddr_drv.h" #include "rec_an.h" #include "rec_bin.h" #include "comm.h" #include "misc.h" #include "config.h" #pragma LOCATION(ddr_bank0,0xc4000000) // @ non-cached memory above 128MB volatile u8 ddr_bank0[DDR_REG_BANK_SIZE]; #pragma LOCATION(ddr_bank1,0xc4100000) // @ non-cached memory above 128MB volatile u8 ddr_bank1[DDR_REG_BANK_SIZE]; #pragma LOCATION(ddr_bank2,0xc4200000) // @ non-cached memory above 128MB volatile u8 ddr_bank2[DDR_REG_BANK_SIZE]; #pragma LOCATION(ddr_bank3,0xc4300000) // @ non-cached memory above 128MB volatile u8 ddr_bank3[DDR_REG_BANK_SIZE]; volatile struct ddr_reg_inf ddr_regs = { .cur_reg_bank = 0, .bank[0].data = (void*) ddr_bank0, .bank[0].state = BANK_BUFFERING, .bank[0].addr_offset = 0, .bank[0].pre_trigger_cnt = 0, .bank[0].post_trigger_cnt = 0, .bank[0].total_cnt = 0, .bank[1].data = (void*) ddr_bank1, .bank[2].data = (void*) ddr_bank2, .bank[3].data = (void*) ddr_bank3, }; int ddr_initlog(void *arguments, void *logic) { struct ddr_args *args = (struct ddr_args *)arguments; struct ddr_logic *log = (struct ddr_logic *)logic; log->trigger_ptr = log_manager.nets_data + (args->io.trigger_in >> 3); log->trigger_bit_no = args->io.trigger_in & 0x07; if(log->trigger_ptr >= (log_manager.nets_data+sizeof(log_manager.nets_data))) return -1; switch((enum ddr_fs)args->params.f_sampling) { case Fs_100Hz: log->decimation=10/LOOP_CYCLE_MS; break; case Fs_50Hz: log->decimation=20/LOOP_CYCLE_MS; break; case Fs_10Hz: log->decimation=100/LOOP_CYCLE_MS; break; case Fs_5Hz: log->decimation=200/LOOP_CYCLE_MS; break; case Fs_1Hz: log->decimation=1000/LOOP_CYCLE_MS; break; case Fs_0_5Hz: log->decimation=2000/LOOP_CYCLE_MS; break; case Fs_0_1Hz: log->decimation=10000/LOOP_CYCLE_MS; break; default: log->decimation=10/LOOP_CYCLE_MS; break; } log->pre_trigger_samples = args->params.pre_trigger_time / log->decimation; if(args->params.pre_trigger_time) log->pre_trigger_samples++; log->post_trigger_samples = args->params.post_trigger_time / log->decimation; if(args->params.post_trigger_time) log->post_trigger_samples++; log->max_reg_samples = args->params.max_reg_time / log->decimation; if(args->params.max_reg_time) log->max_reg_samples++; return 0; } void ddr(void *arguments, void *logic) { struct ddr_logic *log = (struct ddr_logic *)logic; //struct ddr_args *args = (struct ddr_args *)arguments; struct rec_an_logic *an_log; struct rec_bin_logic *bin_log; u16 sample_buf[(MAX_SAMPLE_SIZE/sizeof(u16)) + 8]; int i,bit_cnt=0,pos=0; u8 new_sample=0; if(ddr_drv_log_ptr == NULL) // ddr driver not initialized? return; if(!log->decimation_cnt--) { log->decimation_cnt=log->decimation; new_sample=1; } switch(ddr_regs.bank[ddr_regs.cur_reg_bank].state) { case BANK_BUFFERING: if(*log->trigger_ptr & (1<trigger_bit_no)) { ddr_regs.bank[ddr_regs.cur_reg_bank].state=BANK_TRIGGERED; ddr_regs.bank[ddr_regs.cur_reg_bank].tr_time=(timesync_bits & CFG_TSYNC_USE_SWCLK)?cur_time_sw.tv_sec:cur_time.tv_sec; ddr_regs.bank[ddr_regs.cur_reg_bank].tr_time_ms=(timesync_bits & CFG_TSYNC_USE_SWCLK)?cur_time_sw.tv_usec:cur_time.tv_usec; ddr_regs.bank[ddr_regs.cur_reg_bank].sample_size=ddr_drv_log_ptr->sample_size; ddr_regs.bank[ddr_regs.cur_reg_bank].an_count=ddr_drv_log_ptr->an_count; ddr_regs.bank[ddr_regs.cur_reg_bank].bin_count=ddr_drv_log_ptr->bin_count; ddr_regs.bank[ddr_regs.cur_reg_bank].post_trigger_cnt=0; ddr_regs.bank[ddr_regs.cur_reg_bank].trigger_offset=ddr_regs.bank[ddr_regs.cur_reg_bank].addr_offset; ddr_regs.bank[ddr_regs.cur_reg_bank].total_cnt=ddr_regs.bank[ddr_regs.cur_reg_bank].pre_trigger_cnt; } else { if(new_sample && ddr_regs.bank[ddr_regs.cur_reg_bank].pre_trigger_cntpre_trigger_samples) ddr_regs.bank[ddr_regs.cur_reg_bank].pre_trigger_cnt++; } break; case BANK_TRIGGERED: if(new_sample) { if(ddr_regs.bank[ddr_regs.cur_reg_bank].total_cnt++>=log->max_reg_samples || ddr_regs.bank[ddr_regs.cur_reg_bank].post_trigger_cnt>=log->post_trigger_samples) { // send notify to ARM ddr_regs.bank[ddr_regs.cur_reg_bank].state=BANK_FILLED; ddr_regs.bank[ddr_regs.cur_reg_bank].decimation=log->decimation; ddr_regs.cur_reg_bank++; ddr_regs.cur_reg_bank%=DDR_MAX_REG_BANKS; ddr_regs.bank[ddr_regs.cur_reg_bank].state=BANK_BUFFERING; ddr_regs.bank[ddr_regs.cur_reg_bank].addr_offset=0; ddr_regs.bank[ddr_regs.cur_reg_bank].post_trigger_cnt=0; ddr_regs.bank[ddr_regs.cur_reg_bank].pre_trigger_cnt=0; ddr_regs.bank[ddr_regs.cur_reg_bank].trigger_offset=0; ddr_regs.bank[ddr_regs.cur_reg_bank].total_cnt=0; logman_notify|=LOGMAN_NOTIFY_NEW_DDR; // Notify_sendEvent(notify.remoteProcId,notify.lineId,notify.eventId, NOTIFY_NEW_DDR_REG, TRUE); } else { if(*log->trigger_ptr & (1<trigger_bit_no)) ddr_regs.bank[ddr_regs.cur_reg_bank].post_trigger_cnt=0; else ddr_regs.bank[ddr_regs.cur_reg_bank].post_trigger_cnt++; } } break; case BANK_EMPTY: case BANK_FILLED: default: ddr_regs.bank[ddr_regs.cur_reg_bank].state=BANK_BUFFERING; ddr_regs.bank[ddr_regs.cur_reg_bank].addr_offset=0; ddr_regs.bank[ddr_regs.cur_reg_bank].post_trigger_cnt=0; ddr_regs.bank[ddr_regs.cur_reg_bank].pre_trigger_cnt=0; ddr_regs.bank[ddr_regs.cur_reg_bank].trigger_offset=0; ddr_regs.bank[ddr_regs.cur_reg_bank].total_cnt=0; break; } // // will be overwritten by ARM // *((u32 *)&sample_buf[0]) = 0; // sample number 1..n // *((u32 *)&sample_buf[2]) = 0; // time stamp 0..n*1ms @ 1 kHz // if(new_sample) { pos = 4; for(i=0;ian_count;i++) { an_log = (struct rec_an_logic *)log_manager.log_element[ddr_drv_log_ptr->element_num[i] & 0x3FFF].fun_log_ptr; sample_buf[pos]=*an_log->in_ptr; pos++; } sample_buf[pos]=0; for(;i<(ddr_drv_log_ptr->an_count+ddr_drv_log_ptr->bin_count);i++) { bin_log = (struct rec_bin_logic *)log_manager.log_element[ddr_drv_log_ptr->element_num[i] & 0x3FFF].fun_log_ptr; if(*bin_log->in_ptr & bin_log->in_bit_mask) sample_buf[pos]|=(1<<(bit_cnt%16)); if(!(++bit_cnt%16) && bit_cnt) { pos++; sample_buf[pos]=0; } } if(ddr_regs.bank[ddr_regs.cur_reg_bank].addr_offset + ddr_drv_log_ptr->sample_size > DDR_REG_BANK_SIZE) ddr_regs.bank[ddr_regs.cur_reg_bank].addr_offset=0; memcpy((u8*)ddr_regs.bank[ddr_regs.cur_reg_bank].data+ddr_regs.bank[ddr_regs.cur_reg_bank].addr_offset,(void *)sample_buf,ddr_drv_log_ptr->sample_size); ddr_regs.bank[ddr_regs.cur_reg_bank].addr_offset+=ddr_drv_log_ptr->sample_size; } }