void twl3025_uplink(int on, int16_t at) { int16_t bul_ena = at - TSP_DELAY - 6; if (bul_ena < 0) printf("BULENA time negative (%d)\n", bul_ena); if (on) { /* calibration should be done just before BULENA */ tpu_enq_at(bul_ena - UPLINK_DELAY); /* bdl_ena - 35 - TSP_DELAY - BULCAL_DURATION - TSP_DELAY - BULON_TO_BULCAL - TSP_DELAY */ twl3025_tsp_write(BULON); /* bdl_ena - 35 - TSP_DELAY - BULCAL_DURATION - TSP_DELAY - BULON_TO_BULCAL */ tpu_enq_wait(BULON_TO_BULCAL - TSP_DELAY); /* bdl_ena - 35 - TSP_DELAY - BULCAL_DURATION - TSP_DELAY */ twl3025_tsp_write(BULON | BULCAL); /* bdl_ena - 35 - TSP_DELAY - BULCAL_DURATION */ tpu_enq_wait(BULCAL_DURATION - TSP_DELAY); /* bdl_ena - 35 - TSP_DELAY */ twl3025_tsp_write(BULON); /* bdl_ena - 35 */ tpu_enq_wait(35); /* minimum time required to bring the ramp up (really needed?) */ tpu_enq_at(bul_ena); twl3025_tsp_write(BULON | BULENA); } else { tpu_enq_at(bul_ena); twl3025_tsp_write(BULON); tpu_enq_wait(35); /* minimum time required to bring the ramp down (needed!) */ twl3025_tsp_write(0); } }
/* Enqueue a series of TSP commands in the TPU to (de)activate the downlink path */ void twl3025_downlink(int on, int16_t at) { int16_t bdl_ena = at - TSP_DELAY - 6; if (on) { if (bdl_ena < 0) printf("BDLENA time negative (%d)\n", bdl_ena); /* calibration should be done just before BDLENA */ tpu_enq_at(bdl_ena - DOWNLINK_DELAY); /* bdl_ena - TSP_DELAY - BDLCAL_DURATION - TSP_DELAY - BDLON_TO_BDLCAL - TSP_DELAY */ twl3025_tsp_write(BDLON); /* bdl_ena - TSP_DELAY - BDLCAL_DURATION - TSP_DELAY - BDLON_TO_BDLCAL */ tpu_enq_wait(BDLON_TO_BDLCAL - TSP_DELAY); /* bdl_ena - TSP_DELAY - BDLCAL_DURATION - TSP_DELAY */ twl3025_tsp_write(BDLON | BDLCAL); /* bdl_ena - TSP_DELAY - BDLCAL_DURATION */ tpu_enq_wait(BDLCAL_DURATION - TSP_DELAY); /* bdl_ena - TSP_DELAY */ twl3025_tsp_write(BDLON); //tpu_enq_wait(BDLCAL_TO_BDLENA) this is only 3.7us == 4 qbits, i.e. less than the TSP_DELAY tpu_enq_at(bdl_ena); twl3025_tsp_write(BDLON | BDLENA); } else { tpu_enq_at(bdl_ena); twl3025_tsp_write(BDLON); //tpu_enq_wait(nBDLENA_TO_nBDLON) this is only 3.7us == 4 qbits, i.e. less than the TSP_DELAY twl3025_tsp_write(0); } }
/* synchronize the L1S to a new timebase (typically a new cell */ void synchronize_tdma(struct l1_cell_info *cinfo) { int32_t fn_offset; uint32_t tpu_shift = cinfo->time_alignment; /* NB detection only works if the TOA of the SB * is within 0...8. We have to add 75 to get an SB TOA of 4. */ tpu_shift += 75; tpu_shift = (l1s.tpu_offset + tpu_shift) % QBITS_PER_TDMA; fn_offset = cinfo->fn_offset - 1; /* if we're already very close to the end of the TPU frame, the * next interrupt will basically occur now and we need to * compensate */ if (tpu_shift < SWITCH_TIME) fn_offset++; #if 0 /* probably wrong as we already added "offset" and "shift" above */ /* increment the TPU quarter-bit offset */ l1s.tpu_offset = (l1s.tpu_offset + tpu_shift) % TPU_RANGE; #else l1s.tpu_offset = tpu_shift; #endif puts("Synchronize_TDMA\n"); /* request the TPU to adjust the SYNCHRO and OFFSET registers */ tpu_enq_at(SWITCH_TIME); tpu_enq_sync(l1s.tpu_offset); #if 0 /* FIXME: properly end the TPU window at the emd of l1_sync() */ tpu_end_scenario(); #endif /* Change the current time to reflect the new value */ l1s_time_inc(&l1s.current_time, fn_offset); l1s.next_time = l1s.current_time; l1s_time_inc(&l1s.next_time, 1); /* The serving cell now no longer has a frame or bit offset */ cinfo->fn_offset = 0; cinfo->time_alignment = 0; }