00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <stdint.h>
00004 #include <fcntl.h>
00005 #include <unistd.h>
00006 #include <string.h>
00007
00008 #include "hicap.h"
00009 #include "hlog.h"
00010
00011
00012 static int clbcol_to_abscol_(int col);
00013 static int realrow_to_bitstreamrow_(int row);
00014 static int write_header_(int device, uint32_t row, uint32_t column, uint32_t frame, int frames);
00015 static int write_frames_(int device, uint32_t frames, char* filename,uint32_t frameOffset);
00016 static int write_postconfig_(int device);
00017
00019 static int* clbcol_to_abscol_current = NULL;
00025 static int* realrow_to_bitstreamrow_current = NULL;
00027 static int clbrows_current = -1;
00029 static int clbcols_current = -1;
00030
00031
00032 static int clbcol_to_abscol_(int col)
00033 {
00034 if (clbcol_to_abscol_current == NULL || clbcols_current == -1)
00035 return -1;
00036 else if (col > -1 && col < clbcols_current)
00037 return clbcol_to_abscol_current[col];
00038 else
00039 return -1;
00040 }
00041
00042
00043 static int realrow_to_bitstreamrow_(int row)
00044 {
00045 if (realrow_to_bitstreamrow_current == NULL || clbrows_current == -1)
00046 return -1;
00047 else if (row > -1 && row < clbrows_current)
00048 return realrow_to_bitstreamrow_current[row];
00049 else
00050 return -1;
00051 }
00052
00053
00054
00055
00056 static int write_header_(int device, uint32_t row, uint32_t column, uint32_t frame, int frames)
00057 {
00058 uint32_t data[19];
00059 int ret=0;
00060 uint32_t address;
00061 uint32_t packet;
00062 uint32_t headerWords;
00063 uint32_t totalWords;
00064
00065
00066 data[0] = DUMMY_PACKET;
00067 data[1] = SYNC_PACKET;
00068 data[2] = NOP_PACKET;
00069 data[3] = NOP_PACKET;
00070
00071
00072 data[4] = CMD_PACKET;
00073 data[5] = RCRC_CMD;
00074 data[6] = NOP_PACKET;
00075 data[7] = NOP_PACKET;
00076
00077
00078 data[8] = IDCODE_PACKET;
00079 data[9] = V4FX12ID;
00080
00081
00082 address = (0<<22) | (0<<19) | (row<<14) | (column<<6) | frame;
00083
00084
00085 data[10] = FAR_PACKET;
00086 data[11] = address;
00087
00088
00089 data[12] = CMD_PACKET;
00090 data[13] = WCFG_CMD;
00091 data[14] = NOP_PACKET;
00092
00093 totalWords = ((frames+1)*WORDS_PR_FRAME);
00094
00095 if(totalWords < XHI_TYPE_1_PACKET_MAX_WORDS){
00096
00097 packet = (1<<TYPE1) | (1<<OP_WRITE) | (FDRI<<REG_ADDR) | totalWords;
00098 data[15] = packet;
00099
00100 headerWords = 16;
00101 }else{
00102
00103 packet = (1<<TYPE1) | (1<<OP_WRITE) | (FDRI<<REG_ADDR);
00104 data[15] = packet;
00105
00106 packet = (1<<TYPE2) | (1<<OP_WRITE) | totalWords;
00107 data[16] = packet;
00108
00109 headerWords = 17;
00110 }
00111
00112
00113 ret = write(device, data, sizeof(uint32_t)*headerWords);
00114
00115 return ret;
00116 }
00117
00118
00119 static int write_frames_(int device, uint32_t frames, char* filename, uint32_t frameOffset)
00120 {
00121 int ret=0;
00122 void *frameBuffer;
00123 FILE *inFile;
00124
00125
00126 frameBuffer = malloc(sizeof(uint32_t)*WORDS_PR_FRAME*(frames+1));
00127 if(frameBuffer == NULL){
00128 hlog_write(HLOG_ERROR, "write_frames_: (hicap) allocating frame buffer\n");
00129 return -1;
00130 }
00131
00132
00133 inFile = fopen(filename, "r");
00134 if(inFile == NULL){
00135 hlog_write(HLOG_ERROR, "write_frames_: (hicap) opening file\n");
00136 free(frameBuffer);
00137 return -1;
00138 }
00139
00140
00141 if(fseek(inFile, frameOffset*WORDS_PR_FRAME*sizeof(uint32_t), SEEK_SET) < 0){
00142 hlog_write(HLOG_ERROR, "write_frames_: (hicap) setting filepointer offset\n");
00143 free(frameBuffer);
00144 fclose(inFile);
00145 return -1;
00146 }
00147
00148
00149 if(fread(frameBuffer, WORDS_PR_FRAME*sizeof(uint32_t), (frames) , inFile) < 0){
00150 hlog_write(HLOG_ERROR, "write_frames_: (hicap) reading from file\n");
00151 ret = -1;
00152 }else{
00153
00154
00155
00156 if(write(device, frameBuffer, sizeof(uint32_t)*WORDS_PR_FRAME*(frames+1)) < 0){
00157 hlog_write(HLOG_ERROR, "write_frames_: (hicap) writing frames to device\n");
00158 ret = -1;
00159 }
00160 }
00161
00162
00163 free(frameBuffer);
00164 fclose(inFile);
00165
00166 return ret;
00167 }
00168
00169
00170 static int write_postconfig_(int device)
00171 {
00172 uint32_t data[5];
00173 int ret=0;
00174
00175
00176 data[0] = CMD_PACKET;
00177 data[1] = XHI_DISABLED_AUTO_CRC;
00178
00179
00180 data[2] = DESYNC_CMD;
00181 data[3] = NOP_PACKET;
00182 data[4] = NOP_PACKET;
00183
00184 ret = write(device, data, 4*5);
00185
00186 return ret;
00187 }
00188
00189
00190 int hicap_get_status(int icap_handle)
00191 {
00192 uint32_t data[7];
00193 uint32_t status;
00194
00195
00196 data[0] = DUMMY_PACKET;
00197 data[1] = SYNC_PACKET;
00198 data[2] = NOP_PACKET;
00199 data[3] = NOP_PACKET;
00200
00201
00202 data[4] = (1<<TYPE1) | (1<<OP_READ) | (STAT<<REG_ADDR) | 1;
00203 data[5] = NOP_PACKET;
00204 data[6] = NOP_PACKET;
00205
00206 if(write(icap_handle, data, sizeof(uint32_t)*7) == 0){
00207 hlog_write(HLOG_ERROR, "hicap_get_status: writing get status\n");
00208 return 0;
00209 }
00210
00211
00212 if(read(icap_handle, &status, sizeof(uint32_t)) == 0){
00213 hlog_write(HLOG_ERROR, "hicap_get_status: reading status\n");
00214 return 0;
00215 }
00216
00217
00218 data[0] = DESYNC_CMD;
00219 data[1] = NOP_PACKET;
00220 data[2] = NOP_PACKET;
00221
00222 if(write(icap_handle, data, sizeof(uint32_t)*3) == 0){
00223 hlog_write(HLOG_ERROR, "hicap_get_status: desyncing get status\n");
00224 return 0;
00225 }
00226
00227 return status;
00228 }
00229
00230
00231 int hicap_open(char* icap_device, char* device_type)
00232 {
00233 clbcol_to_abscol_current = NULL;
00234 clbcols_current = -1;
00235 realrow_to_bitstreamrow_current = NULL;
00236 clbrows_current = -1;
00237
00238 if (strcmp((const char*)device_type, "XC4VFX12") == 0) {
00239 clbcol_to_abscol_current = calloc(1, HC_CLBCOLS_XC4VFX12);
00240 clbcols_current = HC_CLBCOLS_XC4VFX12;
00241 clbrows_current = HC_CLBMINORROWS_XC4VFX12 / 16;
00242 realrow_to_bitstreamrow_current = calloc(1, clbrows_current);
00243
00244
00245 int colmapping[HC_CLBCOLS_XC4VFX12] = {1,2,3,4,5,6,7,8,9,10,11,12,15,16,17,18,20,21,22,23,24,25,26,27};
00246
00247 int rowmapping[HC_CLBMINORROWS_XC4VFX12 / 16] = {1, 0, 2, 3};
00248 int i;
00249 for (i = 0; i<HC_CLBCOLS_XC4VFX12; i++)
00250 clbcol_to_abscol_current[i] = colmapping[i];
00251 for (i = 0; i<clbrows_current; i++)
00252 realrow_to_bitstreamrow_current[i] = rowmapping[i];
00253 }
00254
00255 return open(icap_device, O_RDWR);
00256 }
00257
00258
00259 int hicap_close(int icap_handle)
00260 {
00261 clbcols_current = -1;
00262 clbrows_current = -1;
00263 if (clbcol_to_abscol_current != NULL)
00264 free(clbcol_to_abscol_current);
00265
00266 if (realrow_to_bitstreamrow_current != NULL)
00267 free(realrow_to_bitstreamrow_current);
00268
00269 if (close(icap_handle) != 0) {
00270 hlog_write(HLOG_ERROR, "hicap_close: closing driver\n");
00271 return -1;
00272 } else
00273 return 0;
00274 }
00275
00276
00277 int hicap_write(int icap_handle, char* infilename, int real_row, int clb_column, int frames_offset, int frames)
00278 {
00279 if (write_header_(icap_handle, realrow_to_bitstreamrow_(real_row), clbcol_to_abscol_(clb_column), frames_offset, frames) < 0) {
00280 hlog_write(HLOG_ERROR, "hicap_write: Writing header\n");
00281 return -1;
00282 }
00283
00284 if (write_frames_(icap_handle, frames, infilename, frames_offset) < 0) {
00285 hlog_write(HLOG_ERROR, "hicap_write: Writing frames\n");
00286 return -2;
00287 }
00288
00289 if (write_postconfig_(icap_handle) < 0) {
00290 hlog_write(HLOG_ERROR, "hicap_write: Writing postconfig\n");
00291 return -3;
00292 }
00293
00294 return 0;
00295 }
00296