summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Markgraf <steve@steve-m.de>2021-10-23 20:31:12 +0200
committerSteve Markgraf <steve@steve-m.de>2021-10-23 22:28:25 +0200
commit6c6c880a66b9c08b81b540971563cde7986cd60e (patch)
tree5fdba303513eb6883d4f2ba7c541ac1d503feffe
parentc731c86b9b595c0bf2f48d1b4ee471ce71d61a0e (diff)
fw: use proper delay routines, adapt all delayssteve-m/trx_rebased
Because the Pirelli DP-L10 display initialization has very strict timing requirements, implement compiler version agnostic delay functions using inline assembly. As it turned out, our delay routines always were way off: delay_ms(1000) with GCC 4.8.2 was actually 400ms, and with GCC 11.2.0 480ms were measured, the latter resulting in the DP-L10 display not working anymore. As the new routines now actually wait the time they should, scale all existing delay times by 0.4 to get the same behavior as previously with the old GCC version.
-rw-r--r--src/target/firmware/abb/twl3025.c4
-rw-r--r--src/target/firmware/apps/loader/main.c2
-rw-r--r--src/target/firmware/apps/loader_mtk/main.c4
-rw-r--r--src/target/firmware/apps/menu/main.c4
-rwxr-xr-xsrc/target/firmware/apps/simtest/main.c2
-rw-r--r--src/target/firmware/apps/snake_game/main.c4
-rw-r--r--src/target/firmware/board/mt62xx/init.c10
-rw-r--r--src/target/firmware/calypso/dsp.c6
-rw-r--r--src/target/firmware/calypso/sim.c2
-rw-r--r--src/target/firmware/calypso/spi.c2
-rw-r--r--src/target/firmware/calypso/tpu.c2
-rw-r--r--src/target/firmware/fb/fb_s6b33b1x.c10
-rw-r--r--src/target/firmware/fb/fb_ssd1783.c4
-rw-r--r--src/target/firmware/fb/fb_ssd1963.c4
-rw-r--r--src/target/firmware/fb/fb_td014.c4
-rwxr-xr-xsrc/target/firmware/include/calypso/sim.h2
-rw-r--r--src/target/firmware/lib/delay.c37
17 files changed, 64 insertions, 39 deletions
diff --git a/src/target/firmware/abb/twl3025.c b/src/target/firmware/abb/twl3025.c
index 5b792d68..3e7fabb4 100644
--- a/src/target/firmware/abb/twl3025.c
+++ b/src/target/firmware/abb/twl3025.c
@@ -178,7 +178,7 @@ uint16_t twl3025_reg_read(uint8_t reg)
/* A read cycle contains two SPI transfers */
spi_xfer(TWL3025_DEV_IDX, 16, &tx, &rx);
- delay_ms(1);
+ delay_us(400);
spi_xfer(TWL3025_DEV_IDX, 16, &tx, &rx);
rx >>= 6;
@@ -192,7 +192,7 @@ uint16_t twl3025_reg_read(uint8_t reg)
static void twl3025_wait_ibic_access(void)
{
/* Wait 6 * 32kHz clock cycles for first IBIC access (187us + 10% = 210us) */
- delay_ms(1);
+ delay_us(400);
}
int twl3025_get_pwon(void)
diff --git a/src/target/firmware/apps/loader/main.c b/src/target/firmware/apps/loader/main.c
index 9b7a1b59..6fffa4a7 100644
--- a/src/target/firmware/apps/loader/main.c
+++ b/src/target/firmware/apps/loader/main.c
@@ -69,7 +69,7 @@ static void flush_uart(void)
unsigned i;
for (i = 0; i < 500; i++) {
uart_poll(sercomm_uart);
- delay_ms(1);
+ delay_us(400);
}
}
diff --git a/src/target/firmware/apps/loader_mtk/main.c b/src/target/firmware/apps/loader_mtk/main.c
index f2ebbea1..4373ba43 100644
--- a/src/target/firmware/apps/loader_mtk/main.c
+++ b/src/target/firmware/apps/loader_mtk/main.c
@@ -63,7 +63,7 @@ static void flush_uart(void)
unsigned i;
for (i = 0; i < 500; i++) {
uart_poll(sercomm_uart);
- delay_ms(1);
+ delay_us(400);
}
}
@@ -83,7 +83,7 @@ static void device_reset(void)
static void device_enter_loader(__unused unsigned char bootrom)
{
flush_uart();
- delay_ms(2000);
+ delay_ms(800);
void (*entry)( void ) = (void (*)(void))0;
entry();
}
diff --git a/src/target/firmware/apps/menu/main.c b/src/target/firmware/apps/menu/main.c
index fa369681..78af4030 100644
--- a/src/target/firmware/apps/menu/main.c
+++ b/src/target/firmware/apps/menu/main.c
@@ -108,7 +108,7 @@ static void wait_key_release(void)
{
/* wait for key release */
while (key_state == PRESSED) {
- delay_ms(10);
+ delay_ms(4);
keypad_poll();
}
}
@@ -323,7 +323,7 @@ int main(void)
while (1) {
for (i = 0; i < 50; i++) {
keypad_poll();
- delay_ms(10);
+ delay_ms(4);
osmo_timers_update();
handle_key_code();
}
diff --git a/src/target/firmware/apps/simtest/main.c b/src/target/firmware/apps/simtest/main.c
index e20c52a1..e9994f24 100755
--- a/src/target/firmware/apps/simtest/main.c
+++ b/src/target/firmware/apps/simtest/main.c
@@ -285,7 +285,7 @@ void do_sim_test(void)
printf(" Result: ");
myHexdump(buffer,12);
- delay_ms(5000);
+ delay_ms(2000);
calypso_sim_powerdown();
diff --git a/src/target/firmware/apps/snake_game/main.c b/src/target/firmware/apps/snake_game/main.c
index 44dda9af..3012b68f 100644
--- a/src/target/firmware/apps/snake_game/main.c
+++ b/src/target/firmware/apps/snake_game/main.c
@@ -409,8 +409,8 @@ int main(void)
osmo_timers_update();
intro();
- delay_ms(5000);
- fb_clear_fancy(20);
+ delay_ms(2000);
+ fb_clear_fancy(8);
fb_setfg(FB_COLOR_BLACK);
fb_setbg(FB_COLOR_WHITE);
diff --git a/src/target/firmware/board/mt62xx/init.c b/src/target/firmware/board/mt62xx/init.c
index dae38cf4..86b5c27c 100644
--- a/src/target/firmware/board/mt62xx/init.c
+++ b/src/target/firmware/board/mt62xx/init.c
@@ -49,7 +49,7 @@ void pll_init(void)
writew(PLL_RST, MTK_PLL_PLL);
writew(0, MTK_PLL_PLL);
- delay_ms(1);
+ delay_us(400);
/* Turn on PLL for MCU, DSP and USB */
writew(PLL_MPLLSEL_PLL | PLL_DPLLSEL | PLL_UPLLSEL, MTK_PLL_PLL);
@@ -87,9 +87,9 @@ void memory_init(void)
for (i = 0; i < 5; ++i) {
/* Setup five single bits, one by one for DRAM init */
writel((1 << (24 + i)) | (0x400013), MTK_EMI_CONN);
- delay_ms(1);
+ delay_us(400);
writel(0x400013, MTK_EMI_CONN);
- delay_ms(1);
+ delay_us(400);
}
#if 0
@@ -109,9 +109,9 @@ void memory_init(void)
for (i = 0; i < 5; ++i) {
/* Setup five single bits, one by one for DRAM init */
writel((1 << (24 + i)) | (0x500013), MTK_EMI_CONN);
- delay_ms(1);
+ delay_us(400);
writel(0x500013, MTK_EMI_CONN);
- delay_ms(1);
+ delay_us(400);
}
#endif
diff --git a/src/target/firmware/calypso/dsp.c b/src/target/firmware/calypso/dsp.c
index a1d8db54..46057686 100644
--- a/src/target/firmware/calypso/dsp.c
+++ b/src/target/firmware/calypso/dsp.c
@@ -186,13 +186,13 @@ static void dsp_pre_boot(const struct dsp_section *bootcode)
writew(BL_STATUS_NA, BL_CMD_STATUS);
} else
- delay_ms(10);
+ delay_ms(4);
dputs("Releasing DSP from Reset\n");
calypso_reset_set(RESET_DSP, 0);
/* Wait 10 us */
- delay_ms(100);
+ delay_ms(40);
dsp_bl_wait_ready();
}
@@ -650,7 +650,7 @@ static void _dsp_dump_range(uint32_t addr, uint32_t size, int mode)
while (bs--) {
/* FIXME workaround: small delay to prevent overflowing
* the sercomm buffer */
- delay_ms(2);
+ delay_us(800);
if ((addr&15)==0)
printf("%05lx : ", addr);
printf("%04hx%c", *api++, ((addr&15)==15)?'\n':' ');
diff --git a/src/target/firmware/calypso/sim.c b/src/target/firmware/calypso/sim.c
index dc5885c4..cab12c2d 100644
--- a/src/target/firmware/calypso/sim.c
+++ b/src/target/firmware/calypso/sim.c
@@ -86,7 +86,7 @@ void calypso_sim_regdump(void)
#ifdef DEBUG
unsigned int regVal;
-#define SIM_DEBUG_OUTPUTDELAY 200
+#define SIM_DEBUG_OUTPUTDELAY 80
puts("\n\n\n");
puts("====================== CALYPSO SIM REGISTER DUMP =====================\n");
diff --git a/src/target/firmware/calypso/spi.c b/src/target/firmware/calypso/spi.c
index 049ac080..dcaed73f 100644
--- a/src/target/firmware/calypso/spi.c
+++ b/src/target/firmware/calypso/spi.c
@@ -121,7 +121,7 @@ int spi_xfer(uint8_t dev_idx, uint8_t bitlen, const void *dout, void *din)
break;
}
/* FIXME: calibrate how much delay we really need (seven 13MHz cycles) */
- delay_ms(1);
+ delay_us(400);
if (din) {
tmp = readw(SPI_REG(REG_RX_MSB)) << 16;
diff --git a/src/target/firmware/calypso/tpu.c b/src/target/firmware/calypso/tpu.c
index cbeef843..7e53a2e5 100644
--- a/src/target/firmware/calypso/tpu.c
+++ b/src/target/firmware/calypso/tpu.c
@@ -291,7 +291,7 @@ void tpu_wait_idle(void)
{
dputs("Waiting for TPU Idle ");
/* Wait until TPU is doing something */
- delay_us(3);
+ delay_us(1);
/* Wait until TPU is idle */
while (readw(TPU_REG(TPU_CTRL)) & TPU_CTRL_IDLE)
dputchar('.');
diff --git a/src/target/firmware/fb/fb_s6b33b1x.c b/src/target/firmware/fb/fb_s6b33b1x.c
index e36c5471..38af6e86 100644
--- a/src/target/firmware/fb/fb_s6b33b1x.c
+++ b/src/target/firmware/fb/fb_s6b33b1x.c
@@ -99,7 +99,7 @@ static void fb_s6b33b1x_send_cmdlist(const struct s6b33b1x_cmdlist *p)
static void fb_spca_write(uint16_t addr, uint16_t val)
{
writew(addr, nCS4_ADDR);
- delay_ms(1);
+ delay_us(100);
writew(val , nCS4_ADDR | 2);
}
@@ -109,15 +109,15 @@ static void fb_spca_init(void)
/* Initialize Sunplus SPCA552E Media Controller for bypass mode */
fb_spca_write(0x7e, 0x00); /* internal register access */
- delay_ms(10);
+ delay_ms(4);
fb_spca_write(0x7a, 0x00); /* keep CPU in reset state */
- delay_ms(10);
+ delay_ms(4);
fb_spca_write(0x7f, 0x00); /* select main page */
- delay_ms(5);
+ delay_ms(2);
fb_spca_write(0x72, 0x07); /* don't reshape timing, 16 bit mode */
fb_spca_write(0x14, 0x03);
fb_spca_write(0x7f, 0x00); /* select main page */
- delay_ms(5);
+ delay_ms(2);
fb_spca_write(0x06, 0xff);
fb_spca_write(0x7f, 0x09);
fb_spca_write(0x19, 0x08); /* backlight: 0x08 is on, 0x0c is off */
diff --git a/src/target/firmware/fb/fb_ssd1783.c b/src/target/firmware/fb/fb_ssd1783.c
index cacdce03..d05cbf72 100644
--- a/src/target/firmware/fb/fb_ssd1783.c
+++ b/src/target/firmware/fb/fb_ssd1783.c
@@ -128,9 +128,9 @@ static void
fb_ssd1783_init(void){
printf("%s: initializing LCD.\n",__FUNCTION__);
calypso_reset_set(RESET_EXT, 0);
- delay_ms(5);
+ delay_ms(2);
uwire_init();
- delay_ms(5);
+ delay_ms(2);
fb_ssd1783_send_cmdlist(ssd1783_initdata);
}
diff --git a/src/target/firmware/fb/fb_ssd1963.c b/src/target/firmware/fb/fb_ssd1963.c
index 361434e4..9b6ddf28 100644
--- a/src/target/firmware/fb/fb_ssd1963.c
+++ b/src/target/firmware/fb/fb_ssd1963.c
@@ -126,9 +126,9 @@ static void
fb_ssd1963_init(void){
printf("%s: initializing LCD.\n",__FUNCTION__);
calypso_reset_set(RESET_EXT, 0);
- delay_ms(5);
+ delay_ms(2);
uwire_init();
- delay_ms(5);
+ delay_ms(2);
fb_ssd1963_send_cmdlist(ssd1963_initdata);
}
diff --git a/src/target/firmware/fb/fb_td014.c b/src/target/firmware/fb/fb_td014.c
index c7bde0ca..c4deb1df 100644
--- a/src/target/firmware/fb/fb_td014.c
+++ b/src/target/firmware/fb/fb_td014.c
@@ -73,9 +73,9 @@ static void
fb_td014_init(void) {
printf("%s: initializing LCD.\n",__FUNCTION__);
calypso_reset_set(RESET_EXT, 0);
- delay_ms(5);
+ delay_ms(2);
uwire_init();
- delay_ms(5);
+ delay_ms(2);
fb_td014_send_cmdlist(td014_initdata);
}
diff --git a/src/target/firmware/include/calypso/sim.h b/src/target/firmware/include/calypso/sim.h
index 8f627b18..97977a68 100755
--- a/src/target/firmware/include/calypso/sim.h
+++ b/src/target/firmware/include/calypso/sim.h
@@ -147,7 +147,7 @@
/* 1 = SIM card insertion/extraction */
-#define SIM_OPERATION_DELAY 100 /* Time between operations like reset, vcc apply ect... */
+#define SIM_OPERATION_DELAY 40 /* Time between operations like reset, vcc apply etc... */
void calypso_sim_regdump(void); /* Display Register dump */
diff --git a/src/target/firmware/lib/delay.c b/src/target/firmware/lib/delay.c
index 443ca827..112e956a 100644
--- a/src/target/firmware/lib/delay.c
+++ b/src/target/firmware/lib/delay.c
@@ -1,16 +1,41 @@
#include <delay.h>
-/* FIXME: We need properly calibrated delay loops at some point! */
+#define CALYPSO_CLK 52000000
+#define CYCLES_PER_LOOP 4
+#define COUNTS_PER_MS (CALYPSO_CLK / CYCLES_PER_LOOP) / 1000
+#define COUNTS_PER_US COUNTS_PER_MS/1000
+
void delay_us(unsigned int us)
{
- volatile unsigned int i;
+ unsigned int counts = COUNTS_PER_US * us;
- for (i= 0; i < us*4; i++) { i; }
+ asm volatile
+ (
+ "mov r3, %[counts]\n\t"
+ "usloop:\n\t"
+ "subs r3, #1\n\t"
+ "bne usloop\n\t"
+ : /* we have no output, list empty */
+ : [counts] "r" (counts)
+ /* r3 and flags are clobbered */
+ : "r3", "cc"
+ );
}
void delay_ms(unsigned int ms)
{
- volatile unsigned int i;
-
- for (i= 0; i < ms*1300; i++) { i; }
+ unsigned int counts = COUNTS_PER_MS;
+ while (ms--) {
+ asm volatile
+ (
+ "mov r3, %[counts]\n\t"
+ "msloop:\n\t"
+ "subs r3, #1\n\t"
+ "bne msloop\n\t"
+ : /* we have no output, list empty */
+ : [counts] "r" (counts)
+ /* r3 and flags are clobbered */
+ : "r3", "cc"
+ );
+ }
}