From: Pavel Pisa Date: Sun, 4 Jan 2015 09:20:50 +0000 (+0100) Subject: Optimize PXMCC firmware to use only 32-bit types and change mode selection back. X-Git-Url: http://rtime.felk.cvut.cz/gitweb/fpga/lx-cpu1/lx-rocon.git/commitdiff_plain/3fc92d46ab6381eaa3cc936d066eae73f8c5a7b7 Optimize PXMCC firmware to use only 32-bit types and change mode selection back. Gain 5% time reduction by integration of multiplication of array indexes by element size into index computation expressions. Signed-off-by: Pavel Pisa --- diff --git a/hw/lx-rocon_firmware/firmware.c b/hw/lx-rocon_firmware/firmware.c index 82de626..2e1822d 100644 --- a/hw/lx-rocon_firmware/firmware.c +++ b/hw/lx-rocon_firmware/firmware.c @@ -33,6 +33,9 @@ /* 1 / (2 * k3) * 65536 */ #define RECI16_2_K3 37837 +#define offsbychar(_ptr, _offs) \ + ((typeof(&(_ptr)[0]))((char*)(_ptr) + (_offs))) + pxmcc_data_t pxmcc_data; void init_defvals(void) @@ -79,20 +82,24 @@ void main(void) uint32_t last_rx_done_sqn = 0; pxmcc_axis_data_t *pxmcc; - pxmcc_data.common.fwversion = PXMCC_FWVERSION; pxmcc_data.common.pwm_cycle = 2500; pxmcc_data.common.min_idle = 0x7fff; - pxmcc = pxmcc_data.axis; - pxmcc->ccflg = 0; - pxmcc->ptindx = 0; - /*pxmcc->ptofs = *FPGA_IRC0;*/ - pxmcc->ptirc = 1000; - pxmcc->ptreci = 4294967; /* (1LL<<32)*ptper/ptirc */ - pxmcc->pwm_dq = 0; pxmcc_data.curadc[0].siroladc_offs = 0x0c17; pxmcc_data.curadc[1].siroladc_offs = 0x0c66; pxmcc_data.curadc[2].siroladc_offs = 0x0c66; + pxmcc = pxmcc_data.axis; + do { + pxmcc->ccflg = 0; + pxmcc->mode = 1; + pxmcc->ptirc = 1000; + pxmcc->ptreci = 4294967; /* (1LL<<32)*ptper/ptirc */ + pxmcc->pwm_dq = 0; + pxmcc++; + } while(pxmcc != pxmcc_data.axis + PXMCC_AXIS_COUNT); + + asm volatile("": : : "memory"); + pxmcc_data.common.fwversion = PXMCC_FWVERSION; asm volatile("": : : "memory"); #if 0 @@ -155,7 +162,7 @@ void main(void) pwm_alp = pwm_d * pxmcc->ptcos - pwm_q * pxmcc->ptsin; pwm_bet = pwm_d * pxmcc->ptsin + pwm_q * pxmcc->ptcos; - if (pxmcc->mode) { + if (!pxmcc->mode) { pwm_bet_div_2_k3 = RECI16_2_K3 * (pwm_bet >> 16); #ifndef SUPPRESS_CONDITIONALS @@ -296,7 +303,7 @@ void main(void) *uptr = pwm4 | 0x4000; } } else { - if (pxmcc->mode) { + if (!pxmcc->mode) { pwmtx_info = pxmcc->pwmtx_info; uptr = FPGA_LX_MASTER_TX + ((pwmtx_info >> 0) & 0xff); pxmcc->pwm_prew[1] = *uptr & 0x3fff; @@ -343,13 +350,13 @@ void main(void) int i; pxmcc_curadc_data_t *curadc = pxmcc_data.curadc; volatile uint32_t *siroladc = FPGA_LX_MASTER_RX_ADC0; - uint16_t val; + uint32_t val; for (i = 0; i < PXMCC_CURADC_CHANNELS; ) { val = *siroladc; - curadc->cur_val = (int16_t)(val - curadc->siroladc_last - - curadc->siroladc_offs); + curadc->cur_val = (uint16_t)(val - curadc->siroladc_last) - + curadc->siroladc_offs; curadc->siroladc_last = val; i++; @@ -385,7 +392,7 @@ void main(void) #endif /*COMPUTE_PHASE_SECTOR*/ out_info = pxmcc->out_info; - if (pxmcc->mode) { + if (!pxmcc->mode) { pwm1 = pxmcc->pwm_prew[0]; pwm2 = pxmcc->pwm_prew[1]; @@ -457,10 +464,18 @@ void main(void) uint32_t u2gtu3 = (int32_t)(pwm3 - pwm2) >> 31; uint32_t state50_msk = u1gtu2 & u1gtu3; uint32_t pwm_reci_bits; + uint32_t sz4idx = sizeof(*pxmcc->pwm_prew); + uint32_t sz4cur = sizeof(*pxmcc_data.curadc); + uint32_t curmult_idx2curadc; + #if 0 curmult_idx = (((u1gtu3 ^ u1gtu2) | 1) ^ u2gtu3 ^ u1gtu2) & 3; - pwm_reci = pxmcc_data.common.pwm_cycle - pxmcc->pwm_prew[curmult_idx]; + #else + /* Variant where curmult_idx is directly computed as byte offset to uint32_t array */ + curmult_idx = (((u1gtu3 ^ u1gtu2) | (1 * sz4idx)) ^ u2gtu3 ^ u1gtu2) & (3 * sz4idx); + pwm_reci = pxmcc_data.common.pwm_cycle - *offsbychar(pxmcc->pwm_prew, curmult_idx); + #endif #if 0 pwm_reci_bits = __builtin_clzl(pwm_reci); @@ -485,8 +500,17 @@ void main(void) * so it is destructive and has not to be applied twice, * but it is much better optimized */ + #if 0 curmult_idx = (0x102 >> (curmult_idx * 4)) & 3; pcurmult = &pxmcc_data.curadc[out_info + curmult_idx].cur_val; + #else + curmult_idx2curadc = ((2 * sz4cur) << (0 * sz4idx)) | + ((0 * sz4cur) << (1 * sz4idx)) | + ((1 * sz4cur) << (2 * sz4idx)); + curmult_idx = (curmult_idx2curadc >> curmult_idx) & (sz4cur | (sz4cur << 1)); + pcurmult = &pxmcc_data.curadc[out_info].cur_val; + pcurmult = offsbychar(pcurmult, curmult_idx); + #endif *pcurmult = (int32_t)(pwm_reci * (*pcurmult)) >> 16; cur2 = pxmcc_data.curadc[out_info + 0].cur_val; diff --git a/hw/lx-rocon_firmware/pxmcc_types.h b/hw/lx-rocon_firmware/pxmcc_types.h index 33be168..284e8da 100644 --- a/hw/lx-rocon_firmware/pxmcc_types.h +++ b/hw/lx-rocon_firmware/pxmcc_types.h @@ -47,13 +47,13 @@ typedef struct pxmcc_axis_data_t { uint32_t inp_info; /* which irc to use */ uint32_t out_info; /* output index */ uint32_t pwmtx_info; /* offsets of pwm1 .. pwm4 from FPGA_LX_MASTER_TX */ - uint16_t pwm_prew[4]; + uint32_t pwm_prew[4]; } pxmcc_axis_data_t; typedef struct pxmcc_curadc_data_t { int32_t cur_val; - uint16_t siroladc_offs; - uint16_t siroladc_last; + int32_t siroladc_offs; + uint32_t siroladc_last; } pxmcc_curadc_data_t; typedef struct pxmcc_data_t { diff --git a/sw/app/rocon/appl_tests.c b/sw/app/rocon/appl_tests.c index 71af788..b7686d8 100644 --- a/sw/app/rocon/appl_tests.c +++ b/sw/app/rocon/appl_tests.c @@ -433,7 +433,7 @@ int cmd_do_testtumblefw(cmd_io_t *cmd_io, const struct cmd_des *des, char *param pwmtx_info = (9 << 0) | (10 << 8) | (11 << 16); - mcc_axis->mode = 1; + mcc_axis->mode = 0; mcc_axis->inp_info = mcs->pxms_inp_info; mcc_axis->out_info = mcs->pxms_out_info; @@ -454,17 +454,17 @@ int cmd_do_testtumblefw(cmd_io_t *cmd_io, const struct cmd_des *des, char *param mcc_data->axis[1].inp_info = 1; mcc_data->axis[1].out_info = 3; mcc_data->axis[1].pwmtx_info = (12 << 0) | (13 << 8) | (14 << 16); - mcc_data->axis[1].mode = 1; + mcc_data->axis[1].mode = 0; mcc_data->axis[1].ccflg = 1; mcc_data->axis[2].inp_info = 2; mcc_data->axis[2].out_info = 6; mcc_data->axis[2].pwmtx_info = (15 << 0) | (16 << 8) | (18 << 16); - mcc_data->axis[2].mode = 1; + mcc_data->axis[2].mode = 0; mcc_data->axis[2].ccflg = 1; mcc_data->axis[3].inp_info = 3; mcc_data->axis[3].out_info = 9; mcc_data->axis[3].pwmtx_info = (19 << 0) | (20 << 8) | (21 << 16); - mcc_data->axis[3].mode = 1; + mcc_data->axis[3].mode = 0; mcc_data->axis[3].ccflg = 1; }