diff --git a/FEE/smile_fee.h b/FEE/smile_fee.h index 416901ca5775970f0f6017c91c69135b211e17ec..9d0ffc05f8d0b68b80dfe46d1715f1e7301299ca 100644 --- a/FEE/smile_fee.h +++ b/FEE/smile_fee.h @@ -132,9 +132,23 @@ struct fee_event_dection { } __attribute__((packed)); +__extension__ +struct fee_data_pkt { + struct fee_data_hdr hdr; + uint8_t *data; +} __attribute__((packed)); +__extension__ +struct fee_pattern { + union { + uint16_t ccd:1; + uint16_t side:1; + uint16_t row:7; + uint16_t col:7; + uint16_t pat; + }; - +} __attribute__((packed)); diff --git a/FEE/smile_fee_cmd.c b/FEE/smile_fee_cmd.c index e710447f092ee94c6633e62475422bc743d480fb..92a4466f6c19d9bc1f7dbcf08ec4909999ebdb32 100644 --- a/FEE/smile_fee_cmd.c +++ b/FEE/smile_fee_cmd.c @@ -77,8 +77,8 @@ static int fee_read_cmd_register_internal(uint16_t trans_id, uint8_t *cmd, static int fee_write_cmd_register_internal(uint16_t trans_id, uint8_t *cmd, uint32_t addr) { - return smile_fee_gen_cmd(trans_id, cmd, RMAP_WRITE_ADDR_INC_VERIFY_REPLY, - addr, 4); + return smile_fee_gen_cmd(trans_id, cmd, RMAP_WRITE_ADDR_INC_REPLY, + addr, 4); } diff --git a/FEE/smile_fee_demo.c b/FEE/smile_fee_demo.c index 2041e0784cf01898bc834a843dabcd7d729ea857..a869a489ef4b7a680808296fa9b978988c3a6369 100644 --- a/FEE/smile_fee_demo.c +++ b/FEE/smile_fee_demo.c @@ -28,11 +28,11 @@ #include <gresb.h> +#include <smile_fee.h> #include <smile_fee_cfg.h> #include <smile_fee_ctrl.h> #include <smile_fee_rmap.h> - #include <rmap.h> /* for FEE simulation */ /* whatever for now ... */ @@ -391,6 +391,70 @@ static int32_t rmap_tx(const void *hdr, uint32_t hdr_size, } +/** + * dirty hack for packet reception, more or less a copy of rmap_rx() + */ + +static uint32_t pkt_rx(uint8_t *pkt) +{ + int recv_bytes; + static uint32_t pkt_size; /* keep last packet size */ + + /* XXX: gresb-to-host header is just 4 bytes, but we need 2 extra in + * order to be able to distinguish between rmap and non-rmap packets + * + * + * NOTE THAT THIS IS A DIRTY HACK FOR THE DEMONSTRATOR ONLY, DO NOT DO + * THIS IN PRODUCTION CODE! EVER! + */ + + uint8_t gresb_hdr[4+2]; + + uint8_t *recv_buffer; + + if (!pkt) { /* next packet size requested */ + + /* try to grab a header */ + recv_bytes = recv(bridge_fd, gresb_hdr, 6, MSG_PEEK | MSG_DONTWAIT); + + /* we won't bother, this is a stupid demo, not production code */ + if (recv_bytes <= 0) + return 0; + + /* header is 4 bytes, but we need 6 */ + if (recv_bytes < (4 + 2)) + return 0; + + pkt_size = gresb_get_spw_data_size(gresb_hdr); + + /* XXX the protocol id is (or should be) in byte 6 */ + if (gresb_hdr[5] != FEE_DATA_PROTOCOL) + return 0; + + /* tell caller about next packet */ + return pkt_size; + } + + /* we packet space, now start receiving + * note the lack of basic sanity checks... + */ + + /* buffer is payload + header */ + recv_buffer = malloc(pkt_size + 4); + + recv_bytes = recv(bridge_fd, recv_buffer, pkt_size + 4, 0); + + + /* the caller supplied their own buffer */ + memcpy(pkt, gresb_get_spw_data(recv_buffer), pkt_size); + free(recv_buffer); + + return pkt_size; + +} + + + /** * rx function for smile_fee_ctrl * @@ -409,27 +473,37 @@ static uint32_t rmap_rx(uint8_t *pkt) int recv_bytes; static uint32_t pkt_size; /* keep last packet size */ - uint8_t gresb_hdr[4]; /* gresb-to-host header is 4 bytes */ + /* XXX: gresb-to-host header is just 4 bytes, but we need 2 extra in + * order to be able to distinguish between rmap and non-rmap packets + * + * + * NOTE THAT THIS IS A DIRTY HACK FOR THE DEMONSTRATOR ONLY, DO NOT DO + * THIS IN PRODUCTION CODE! EVER! + */ + + uint8_t gresb_hdr[4+2]; uint8_t *recv_buffer; if (!pkt) { /* next packet size requested */ /* try to grab a header */ - - //recv_bytes = recv(bridge_fd, gresb_hdr, 4, MSG_PEEK); - recv_bytes = recv(bridge_fd, gresb_hdr, 4, MSG_PEEK | MSG_DONTWAIT); + recv_bytes = recv(bridge_fd, gresb_hdr, 6, MSG_PEEK | MSG_DONTWAIT); /* we won't bother, this is a stupid demo, not production code */ if (recv_bytes <= 0) return 0; - /* header is 4 bytes... */ - if (recv_bytes < 4) + /* header is 4 bytes, but we need 6 */ + if (recv_bytes < (4 + 2)) return 0; pkt_size = gresb_get_spw_data_size(gresb_hdr); + /* XXX the protocol id is (or should be) in byte 6 */ + if (gresb_hdr[5] != RMAP_PROTOCOL_ID) + return 0; + /* tell caller about next packet */ return pkt_size; } @@ -530,33 +604,50 @@ static void sync_rmap(void) printf("synced\n\n"); } - - /** - * SMILE FEE commanding demonstrator, this would run on the DPU - * note: all values are random + * procedure Test 1: read a basic FEE register + * */ -static void smile_fee_demo(void) +static void smile_fee_test1(void) { - printf("sync vstart from FEE\n"); + printf("Test1: read a basic FEE register\n"); + + printf("sync vstart/vend from FEE\n"); smile_fee_sync_vstart(FEE2DPU); + sync_rmap(); + printf("vstart: %x, vend %x\n", smile_fee_get_vstart(), smile_fee_get_vend()); + + printf("Test1 complete\n\n"); +} + + +/** + * procedure Test 2: read, write & read a basic FEE register + * + */ + +static void smile_fee_test2(void) +{ + printf("Test 2: read, write & read a basic FEE register\n"); printf("sync ccd2 e/f single pixel threshold from FEE\n"); smile_fee_sync_ccd2_e_pix_treshold(FEE2DPU); sync_rmap(); - printf("ccd2 e value now: %x\n", smile_fee_get_ccd2_e_pix_treshold()); - printf("ccd2 f value now: %x\n", smile_fee_get_ccd2_f_pix_treshold()); - - + printf("ccd2 e value currently: %x\n", smile_fee_get_ccd2_e_pix_treshold()); + printf("ccd2 f value currently: %x\n", smile_fee_get_ccd2_f_pix_treshold()); printf("setting2 ccd e/f local values\n"); + smile_fee_set_ccd2_e_pix_treshold(0x7b); smile_fee_set_ccd2_f_pix_treshold(0x7c); - printf("syncing ccd2 e/f single pixel thresold to FEE\n"); + printf("ccd2 e local value now: %x\n", smile_fee_get_ccd2_e_pix_treshold()); + printf("ccd2 f local value now: %x\n", smile_fee_get_ccd2_f_pix_treshold()); + + printf("syncing ccd2 e/f single pixel threshold to FEE\n"); smile_fee_sync_ccd2_e_pix_treshold(DPU2FEE); sync_rmap(); @@ -565,7 +656,7 @@ static void smile_fee_demo(void) smile_fee_set_ccd2_e_pix_treshold(0x0); smile_fee_set_ccd2_f_pix_treshold(0x0); - printf("syncing back ccd2 e/f single pixel thresold from FEE\n"); + printf("syncing back ccd2 e/f single pixel threshold from FEE\n"); smile_fee_sync_ccd2_e_pix_treshold(FEE2DPU); sync_rmap(); @@ -573,80 +664,127 @@ static void smile_fee_demo(void) printf("ccd1 value now: %x\n", smile_fee_get_ccd2_e_pix_treshold()); printf("ccd2 value now: %x\n", smile_fee_get_ccd2_f_pix_treshold()); + printf("Test2 complete\n\n"); +} - printf("standing by\n"); - while(1) usleep(1000000); /* stop here for now */ +/** + * procedure Test 3: Get 6x6 binned pattern images from "Frame Transfer Pattern + * Mode." + * + */ - printf("Configuring start of vertical row shared with charge injection\n"); - smile_fee_set_vstart(35); - printf("Configuring duration of a parallel overlap period (TOI)\n"); - smile_fee_set_parallel_toi_period(5); +static void smile_fee_test3(void) +{ + printf("Test 3: 6x6 binned pattern from frame transfer pattern mode\n"); - printf("Syncing configured values to FEE via RMAP\n"); - smile_fee_sync_vstart(DPU2FEE); - smile_fee_sync_parallel_toi_period(DPU2FEE); + smile_fee_set_packet_size(0x30c); + smile_fee_set_int_period(0x0fa0); - printf("Waiting for sync to complete\n"); - sync_rmap(); + /* all above are reg4, this will suffice */ + smile_fee_sync_packet_size(DPU2FEE); - printf("Verifying configured values in FEE\n"); + smile_fee_set_correction_bypass(1); + smile_fee_set_digitise(1); + smile_fee_set_readout_nodes(3); - printf("Clearing local values\n"); - smile_fee_set_vstart(0); - smile_fee_set_parallel_toi_period(0); + /* all above are reg5, this will suffice */ + smile_fee_sync_correction_bypass(DPU2FEE); - printf("Syncing configured values from FEE to DPU via RMAP\n"); - smile_fee_sync_vstart(FEE2DPU); - smile_fee_sync_parallel_toi_period(FEE2DPU); + smile_fee_set_ccd_mode_config(0x1); + smile_fee_set_ccd_mode2_config(0x2); + + /* all above are reg32, this will suffice */ + smile_fee_sync_ccd_mode_config(DPU2FEE); + + sync_rmap(); /* make sure all parameters are set */ + + /* trigger packet transmission */ + smile_fee_set_execute_op(0x1); + smile_fee_sync_execute_op(DPU2FEE); - printf("Waiting for sync to complete\n"); sync_rmap(); + while (1) + { + static int ps = 1; /* times to print everything... */ + static int pp = 1; /* times to print everything... */ + int n, i; + struct fee_data_pkt *pkt; + struct fee_pattern *pat; - printf("Checking values: vertical row shared with charge injection: "); + usleep(1000); - if (smile_fee_get_vstart() == 35) - printf("SUCCESS\n"); - else - printf("FAILURE\n"); + n = pkt_rx(NULL); + if (n) + pkt = (struct fee_data_pkt *) malloc(n); + else + continue; - printf("Checking values: duration of a parallel overlap period (TOI): "); + n = pkt_rx((uint8_t *) pkt); - if (smile_fee_get_parallel_toi_period() == 5) - printf("SUCCESS\n"); - else - printf("FAILURE\n"); + if (n <= 0) + printf("Error in pkt_rx()\n"); - printf("Setting execute op flag to expedite operational parameters\n"); - smile_fee_set_execute_op(1); + pkt->hdr.data_len = __be16_to_cpu(pkt->hdr.data_len); + pkt->hdr.frame_cntr = __be16_to_cpu(pkt->hdr.frame_cntr); + pkt->hdr.seq_cntr = __be16_to_cpu(pkt->hdr.seq_cntr); - printf("Syncing execute op flag to FEE via RMAP\n"); - smile_fee_sync_execute_op(DPU2FEE); - printf("Waiting for sync to complete\n"); - sync_rmap(); + if (ps) { + ps--; + printf("data type %d len %d frame %d seq %d\n", + pkt->hdr.type.pkt_type, + pkt->hdr.data_len, + pkt->hdr.frame_cntr, + pkt->hdr.seq_cntr); + } - printf("Waiting for FEE to complete operation\n"); + pat = (struct fee_pattern *) &pkt->data; + n = pkt->hdr.data_len / sizeof(struct fee_pattern); - while (1) { - printf("Syncing execute op flag from FEE to DPU via RMAP\n"); - smile_fee_sync_execute_op(FEE2DPU); - printf("Waiting for sync to complete\n"); - sync_rmap(); + if (pp) { + pp--; + printf("n %d\n", n); + for (i = 0; i < n; i++) { + pat[i].pat = __be16_to_cpu(pat[i].pat); + printf("%d %d %d %d\n", pat[i].ccd, pat[i].side, pat[i].row, pat[i].col); - if (!smile_fee_get_execute_op()) - break; + } + } + + /* setup abort ... */ + if (pkt->hdr.seq_cntr == 2555) /* gen stops about there? */ + ps = -1; - printf("FEE hast not yet completed operation\n"); + free(pkt); + + /* abort ... */ + if (ps < 0) + break; } + printf("Test3 complete\n\n"); +} + + +/** + * SMILE FEE commanding demonstrator, this would run on the DPU + */ + +static void smile_fee_demo(void) +{ + smile_fee_test1(); + smile_fee_test2(); + smile_fee_test3(); - printf("FEE operation completed\n"); + + printf("standing by\n"); + while(1) usleep(1000000); /* stop here for now */ } diff --git a/FEE/smile_fee_rmap.c b/FEE/smile_fee_rmap.c index 13b56399199c4a2ac05c545602d8e2cf071d4801..20cbabcd2f9e0ad2c6193639a68671b9deacf143 100644 --- a/FEE/smile_fee_rmap.c +++ b/FEE/smile_fee_rmap.c @@ -558,6 +558,7 @@ int smile_fee_package(uint8_t *blob, case RMAP_WRITE_ADDR_INC_VERIFY: case RMAP_WRITE_ADDR_SINGLE_VERIFY_REPLY: case RMAP_WRITE_ADDR_INC_VERIFY_REPLY: + case RMAP_WRITE_ADDR_INC_REPLY: has_data_crc = 1; n += 1; break; @@ -596,8 +597,8 @@ int smile_fee_package(uint8_t *blob, } #endif /* __BYTE_ORDER__ */ + blob[cmd_size + 1 + data_size] = rmap_crc8(&blob[cmd_size + 1], data_size); - blob[cmd_size + 1 + data_size] = rmap_crc8(data, data_size); } else { /* if no data is present, data crc is 0x0 */ if (has_data_crc)