diff options
author | Wael El-Essawy <welessa@us.ibm.com> | 2015-10-28 09:58:33 -0500 |
---|---|---|
committer | Wael Elessawy <welessa@us.ibm.com> | 2015-11-02 10:27:44 -0600 |
commit | b780668c24b267b1831b411a8f30fa3ae98ba10a (patch) | |
tree | 7a96f430587868c3dd5e12af13169fd85b3a52b8 | |
parent | ccc93c5fdd656234785249a0662a8e8c485963a6 (diff) | |
download | talos-occ-b780668c24b267b1831b411a8f30fa3ae98ba10a.tar.gz talos-occ-b780668c24b267b1831b411a8f30fa3ae98ba10a.zip |
busy_wait based on decrementer values inside interrupts.
Change-Id: Iceba2e502420cd03e173edfa7740c6539e120264
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/21562
Reviewed-by: Wael Elessawy <welessa@us.ibm.com>
Tested-by: Wael Elessawy <welessa@us.ibm.com>
-rw-r--r-- | src/occ_gpe0/apss_util.c | 34 | ||||
-rw-r--r-- | src/occ_gpe0/apss_util.h | 8 |
2 files changed, 36 insertions, 6 deletions
diff --git a/src/occ_gpe0/apss_util.c b/src/occ_gpe0/apss_util.c index 2a78561..04e9879 100644 --- a/src/occ_gpe0/apss_util.c +++ b/src/occ_gpe0/apss_util.c @@ -115,17 +115,39 @@ int wait_spi_completion(GpeErrorStruct *error, uint32_t reg, uint8_t timeout) * End Function Specification */ -// result based on busy_wait(1) calibration against pk_sleep(1) -#define BUSY_LOOP_CONSTANT 71 void busy_wait(uint32_t t_microseconds) { int j; volatile uint32_t i; -// ppe42_mullw macro works fine, but compiler parameter settings seems broken, use nested loop instead -// int loop = t * 100; // Assuming loop iteration takes 6 ppe cycles = 0.01 microseconds - for(j = 0; j < BUSY_LOOP_CONSTANT; j++) - for(i = 0; i < t_microseconds; i++); + uint32_t start_decrementer_value; // The decrementer register value at the beginning + uint32_t end_decrementer_value; // The decrementer register value at the end + uint32_t current_decrementer_value; // The current decrementer register value + uint32_t duration; + MFDEC(start_decrementer_value); // get the decrementer register value at the beginning + current_decrementer_value = start_decrementer_value; + + // multiply the delay time by the 37.5 MHz external clock frequency. + // I believe that the ppe42_mullw macro works fine, but the + // compiler parameter settings seems broken. + // @todo: This is a temporary fix, use external frequency directive. + duration = (t_microseconds << 5) + + (t_microseconds << 2) + + (t_microseconds) + + (t_microseconds >> 1); + + // Calculate the decrementer register value at the end of the busy wait period + end_decrementer_value = start_decrementer_value - duration; + + if(start_decrementer_value < end_decrementer_value); // decrementer overflows during the busy wait? + { + MFDEC(current_decrementer_value); + while(current_decrementer_value < end_decrementer_value) // Wait until Decrementer overflows + MFDEC(current_decrementer_value); + } + + while (current_decrementer_value > end_decrementer_value) // Wait until end_decrementer_value is reached + MFDEC(current_decrementer_value); } diff --git a/src/occ_gpe0/apss_util.h b/src/occ_gpe0/apss_util.h index 1f7a76c..1c53cde 100644 --- a/src/occ_gpe0/apss_util.h +++ b/src/occ_gpe0/apss_util.h @@ -8,4 +8,12 @@ void apss_set_ffdc(GpeErrorStruct *o_error, uint32_t i_addr, uint32_t i_rc, uint int wait_spi_completion(GpeErrorStruct *error, uint32_t reg, uint8_t timeout); +// Read decrementer register +#define MFDEC(reg_var) \ +asm volatile \ + ( \ + " mfdec %[dec_var] \n" \ + : [dec_var]"=r"(reg_var) \ + ); + #endif //_APSS_UTIL_H |