From a72e0c20bb28d382fc7377f270b4d9944baeaf97 Mon Sep 17 00:00:00 2001 From: henryk Date: Mon, 11 Feb 2008 12:25:41 +0000 Subject: Framework to support run-time hardware selection. Future hardware releases should be changed to be boot-time detectable (e.g. using the yet unused AD inputs) so that one image can be used for all releases git-svn-id: https://svn.openpcd.org:2342/trunk@411 6dc7ffe9-61d6-0310-9af1-9938baff3ed1 --- openpicc/application/cmd.c | 35 ++++++++++++++++-------- openpicc/application/main.c | 8 +++++- openpicc/application/pll.c | 9 ++++--- openpicc/application/ssc_picc.c | 17 ++++++------ openpicc/application/ssc_picc.h | 2 -- openpicc/application/tc_cdiv.c | 54 ++++++++++++++++++++----------------- openpicc/application/tc_cdiv_sync.c | 12 +++++---- openpicc/application/tc_cdiv_sync.h | 3 +++ 8 files changed, 83 insertions(+), 57 deletions(-) (limited to 'openpicc/application') diff --git a/openpicc/application/cmd.c b/openpicc/application/cmd.c index 7995947..a96a68d 100644 --- a/openpicc/application/cmd.c +++ b/openpicc/application/cmd.c @@ -138,8 +138,9 @@ static const struct {ssc_metric metric; char *description;} SSC_METRICS[] = { {FREE_BUFFERS, "free rx buffers"}, {LATE_FRAMES, "late frames"}, }; -static const struct { int pin; char * description; } PIO_PINS[] = { - {OPENPICC_PIO_PLL_LOCK, "pll lock "}, +#define DYNAMIC_PIN_PLL_LOCK -1 +static struct { int pin; char * description; } PIO_PINS[] = { + {DYNAMIC_PIN_PLL_LOCK, "pll lock "}, {OPENPICC_PIO_FRAME, "frame start"}, }; void print_pio(void) @@ -152,6 +153,7 @@ void print_pio(void) " *****************************************************\n\r" " *\n\r"); for(i=0; ifeatures.data_gating) { + DumpStringToUSB("This hardware does not have data gating capability\n\r"); + break; + } i=atoiEx(args, &args); ssc_set_data_gate(i); if(i==0) { - DumpStringToUSB("SSC_DATA disabled \n\r"); + DumpStringToUSB("SSC_DATA disabled \n\r"); } else { - DumpStringToUSB("SSC_DATA enabled \n\r"); + DumpStringToUSB("SSC_DATA enabled \n\r"); } break; -#endif case 'D': i=atoiEx(args, &args); tc_cdiv_set_divider(i); @@ -241,7 +245,9 @@ void prvExecCommand(u_int32_t cmd, portCHAR *args) { " *****************************************************\n\r" " * Version " COMPILE_SVNREV "\n\r" " * compiled " COMPILE_DATE " by " COMPILE_BY "\n\r" - " *\n\r"); + " * running on "); + DumpStringToUSB(OPENPICC->release_name); + DumpStringToUSB("\n\r *\n\r"); DumpStringToUSB(" * Uptime is "); ms=xTaskGetTickCount(); DumpTimeToUSB(ms); @@ -392,7 +398,9 @@ void prvExecCommand(u_int32_t cmd, portCHAR *args) { " *****************************************************\n\r" " * Version " COMPILE_SVNREV "\n\r" " * compiled " COMPILE_DATE " by " COMPILE_BY "\n\r" - " *\n\r" + " * running on "); + DumpStringToUSB(OPENPICC->release_name); + DumpStringToUSB("\n\r *\n\r" " * test - test critical sections\n\r" #if ( configUSE_TRACE_FACILITY == 1 ) " * t - print task list and stack usage\n\r" @@ -409,9 +417,7 @@ void prvExecCommand(u_int32_t cmd, portCHAR *args) { " * d div- set tc_cdiv divider value 16, 32, 64, ...\n\r" " * j,k - increase, decrease fdt_offset\n\r" " * a - change load modulation level\n\r" -#ifdef OPENPICC_MODIFIED_BOARD " * g 0/1- disable or enable SSC_DATA through gate\n\r" -#endif " * 9 - reset CPU\n\r" " * ?,h - display this help screen\n\r" " *\n\r" @@ -542,7 +548,14 @@ void startstop_field_meter(void) { } } -portBASE_TYPE vCmdInit(void) { +portBASE_TYPE vCmdInit() { + unsigned int i; + for(i=0; iPLL_LOCK; + } + } + /* FIXME Maybe modify to use pointers? */ xCmdQueue = xQueueCreate( 10, sizeof(cmd_type) ); if(xCmdQueue == 0) { diff --git a/openpicc/application/main.c b/openpicc/application/main.c index 1125153..e1749de 100644 --- a/openpicc/application/main.c +++ b/openpicc/application/main.c @@ -42,7 +42,6 @@ #include "adc.h" #include "pll.h" #include "pio_irq.h" -#include "ssc_picc.h" #include "tc_cdiv.h" #include "tc_cdiv_sync.h" #include "tc_fdt.h" @@ -54,6 +53,13 @@ /**********************************************************************/ static inline void prvSetupHardware (void) { + /* The very, very first thing we do is setup the global OPENPICC variable to point to + * the correct hardware information. + * FIXME: Detect dynamically in the future + */ + OPENPICC = &OPENPICC_HARDWARE[OPENPICC_v0_4_p1]; + + /* When using the JTAG debugger the hardware is not always initialised to the correct default state. This line just ensures that this does not cause all interrupts to be masked at the start. */ diff --git a/openpicc/application/pll.c b/openpicc/application/pll.c index c40718a..aca95b1 100644 --- a/openpicc/application/pll.c +++ b/openpicc/application/pll.c @@ -20,6 +20,7 @@ #include #include +#include "pll.h" #include "pio_irq.h" #include "dbgu.h" #include "led.h" @@ -40,7 +41,7 @@ int pll_is_inhibited(void) int pll_is_locked(void) { - return AT91F_PIO_IsInputSet(AT91C_BASE_PIOA, OPENPICC_PIO_PLL_LOCK); + return AT91F_PIO_IsInputSet(AT91C_BASE_PIOA, OPENPICC->PLL_LOCK); } static void pll_lock_change_cb(u_int32_t pio) @@ -55,9 +56,9 @@ static void pll_lock_change_cb(u_int32_t pio) void pll_init(void) { AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, OPENPICC_PIO_PLL_INHIBIT); - AT91F_PIO_CfgInput(AT91C_BASE_PIOA, OPENPICC_PIO_PLL_LOCK); + AT91F_PIO_CfgInput(AT91C_BASE_PIOA, OPENPICC->PLL_LOCK); pll_inhibit(0); - pio_irq_register(OPENPICC_PIO_PLL_LOCK, &pll_lock_change_cb); - pio_irq_enable(OPENPICC_PIO_PLL_LOCK); + pio_irq_register(OPENPICC->PLL_LOCK, &pll_lock_change_cb); + pio_irq_enable(OPENPICC->PLL_LOCK); } diff --git a/openpicc/application/ssc_picc.c b/openpicc/application/ssc_picc.c index 1eabeb2..df6d7fa 100644 --- a/openpicc/application/ssc_picc.c +++ b/openpicc/application/ssc_picc.c @@ -649,17 +649,16 @@ void ssc_tx_init(void) tx_pdc = (AT91PS_PDC) &(ssc->SSC_RPR); } -#ifdef OPENPICC_MODIFIED_BOARD void ssc_set_data_gate(int enable) { + if(! OPENPICC->features.clock_gating) return; if(enable) - AT91F_PIO_SetOutput(AT91C_BASE_PIOA, OPENPICC_PIO_SSC_DATA_GATE); + AT91F_PIO_SetOutput(AT91C_BASE_PIOA, OPENPICC->DATA_GATE); else - AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, OPENPICC_PIO_SSC_DATA_GATE); + AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, OPENPICC->DATA_GATE); } -#endif -void ssc_rx_init(void) +void ssc_rx_init() { tc_cdiv_sync_init(); tc_cdiv_sync_enable(); @@ -679,10 +678,10 @@ void ssc_rx_init(void) AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, OPENPICC_PIO_SSC_DATA_CONTROL); AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, OPENPICC_PIO_SSC_DATA_CONTROL); -#ifdef OPENPICC_MODIFIED_BOARD - AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, OPENPICC_PIO_SSC_DATA_GATE); - AT91F_PIO_SetOutput(AT91C_BASE_PIOA, OPENPICC_PIO_SSC_DATA_GATE); -#endif + if(OPENPICC->features.clock_gating) { + AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, OPENPICC->DATA_GATE); + AT91F_PIO_SetOutput(AT91C_BASE_PIOA, OPENPICC->DATA_GATE); + } AT91F_AIC_ConfigureIt(AT91C_ID_SSC, OPENPICC_IRQ_PRIO_SSC, diff --git a/openpicc/application/ssc_picc.h b/openpicc/application/ssc_picc.h index 650a09e..3b6182a 100644 --- a/openpicc/application/ssc_picc.h +++ b/openpicc/application/ssc_picc.h @@ -100,8 +100,6 @@ extern void ssc_tx_start(ssc_dma_tx_buffer_t *buf); extern volatile u_int32_t ssc_tx_fiq_fdt_cdiv; extern volatile u_int32_t ssc_tx_fiq_fdt_ssc; -#ifdef OPENPICC_MODIFIED_BOARD extern void ssc_set_data_gate(int enable); -#endif #endif diff --git a/openpicc/application/tc_cdiv.c b/openpicc/application/tc_cdiv.c index fb7db91..c3aa60c 100644 --- a/openpicc/application/tc_cdiv.c +++ b/openpicc/application/tc_cdiv.c @@ -34,13 +34,17 @@ AT91PS_TCB tcb = AT91C_BASE_TCB; /* set carrier divider to a specific */ void __ramfunc tc_cdiv_set_divider(u_int16_t div) { - if(tcb->TCB_TC0.TC_CV > div -#ifdef OPENPICC_USE_CLOCK_GATING - /* Don't spin if FRAME_BURST is clear, the clock is stopped in this case */ - && !(!AT91F_PIO_IsInputSet(AT91C_BASE_PIOA, OPENPICC_PIO_FRAME_BURST)) -#endif - ) { - while(tcb->TCB_TC0.TC_CV > 3); /* Three carrier cycles are about 10 clock cycles, should be enough for the loop */ + if(OPENPICC->features.clock_gating) { + if(tcb->TCB_TC0.TC_CV > div + /* Don't spin if FRAME_BURST is clear, the clock is stopped in this case */ + && !(!AT91F_PIO_IsInputSet(AT91C_BASE_PIOA, OPENPICC->CLOCK_GATE)) + ) { + while(tcb->TCB_TC0.TC_CV > 3); /* Three carrier cycles are about 10 clock cycles, should be enough for the loop */ + } + } else { + if(tcb->TCB_TC0.TC_CV > div) { + while(tcb->TCB_TC0.TC_CV > 3); /* Three carrier cycles are about 10 clock cycles, should be enough for the loop */ + } } tcb->TCB_TC0.TC_RC = div; @@ -51,15 +55,19 @@ void __ramfunc tc_cdiv_set_divider(u_int16_t div) /* We must reset CV to zero when it was greater than RC. * In order to not lose phase information when doing that we'll busy wait till CV is * zero modulo the new RC.*/ - /*tc_cdiv_phase_add(tcb->TCB_TC0.TC_RC-(tcb->TCB_TC0.TC_CV%tcb->TCB_TC0.TC_RC));*/ - if(tcb->TCB_TC0.TC_CV > div -#ifdef OPENPICC_USE_CLOCK_GATING - /* Don't spin if FRAME_BURST is clear, the clock is stopped in this case */ - && !(!AT91F_PIO_IsInputSet(AT91C_BASE_PIOA, OPENPICC_PIO_FRAME_BURST)) -#endif - ) { - while(tcb->TCB_TC0.TC_CV % div != 0); - tcb->TCB_TC0.TC_CCR = AT91C_TC_SWTRG; + if(OPENPICC->features.clock_gating) { + if(tcb->TCB_TC0.TC_CV > div + /* Don't spin if FRAME_BURST is clear, the clock is stopped in this case */ + && !(!AT91F_PIO_IsInputSet(AT91C_BASE_PIOA, OPENPICC->CLOCK_GATE)) + ) { + while(tcb->TCB_TC0.TC_CV % div != 0); + tcb->TCB_TC0.TC_CCR = AT91C_TC_SWTRG; + } + } else { + if(tcb->TCB_TC0.TC_CV > div) { + while(tcb->TCB_TC0.TC_CV % div != 0); + tcb->TCB_TC0.TC_CCR = AT91C_TC_SWTRG; + } } } @@ -88,11 +96,9 @@ void tc_cdiv_init(void) OPENPICC_PIO_CARRIER_IN | OPENPICC_PIO_CARRIER_DIV_OUT | OPENPICC_PIO_CDIV_HELP_OUT | - OPENPICC_PIO_CDIV_HELP_IN -#ifdef OPENPICC_USE_CLOCK_GATING - | OPENPICC_PIO_FRAME_BURST -#endif - ); + OPENPICC_PIO_CDIV_HELP_IN); + if(OPENPICC->features.clock_gating) + AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA, 0, OPENPICC->CLOCK_GATE); AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC, ((unsigned int) 1 << AT91C_ID_TC0)); @@ -113,16 +119,14 @@ void tc_cdiv_init(void) * TIOA0 on RA comp = set, * TIOA0 on RC comp = clear, * TIOB0 on EEVT = set, TIOB0 on RB comp = clear, * EEVT = XC2 (TIOA0) - * if OPENPICC_MODIFIED_BOARD: BURST on XC0 */ + * if features.clock_gating: BURST on XC0 */ tcb->TCB_TC0.TC_CMR = AT91C_TC_CLKS_XC1 | AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO | AT91C_TC_ACPA_SET | AT91C_TC_ACPC_CLEAR | AT91C_TC_BEEVT_SET | AT91C_TC_BCPB_CLEAR | AT91C_TC_EEVT_XC2 | AT91C_TC_ETRGEDG_RISING | AT91C_TC_BSWTRG_CLEAR | AT91C_TC_ASWTRG_CLEAR -#ifdef OPENPICC_USE_CLOCK_GATING - | AT91C_TC_BURST_XC0 -#endif + | (OPENPICC->features.clock_gating ? AT91C_TC_BURST_XC0 : 0) ; tc_cdiv_set_divider(128); diff --git a/openpicc/application/tc_cdiv_sync.c b/openpicc/application/tc_cdiv_sync.c index dbaf3f7..695095d 100644 --- a/openpicc/application/tc_cdiv_sync.c +++ b/openpicc/application/tc_cdiv_sync.c @@ -2,6 +2,7 @@ #include #include +#include "tc_cdiv_sync.h" #include "dbgu.h" #include "pio_irq.h" #include "openpicc.h" @@ -46,10 +47,11 @@ void tc_cdiv_sync_reset(void) for (i = 0; i < 0xff; i++) ; AT91F_PIO_SetOutput(AT91C_BASE_PIOA, OPENPICC_PIO_SSC_DATA_CONTROL); -#ifdef OPENPICC_USE_CLOCK_GATING - /* reset tc_cdiv counter, the cleared frame signal stopped the tc_cdiv clock */ - tc_cdiv_reset(); -#endif + + if(OPENPICC->features.clock_gating) { + /* reset tc_cdiv counter, the cleared frame signal stopped the tc_cdiv clock */ + tc_cdiv_reset(); + } } } @@ -68,7 +70,7 @@ void tc_cdiv_sync_enable(void) *AT91C_PIOA_IER = OPENPICC_PIO_FRAME; } -void tc_cdiv_sync_init(void) +void tc_cdiv_sync_init() { pio_irq_init_once(); DEBUGPCRF("initializing"); diff --git a/openpicc/application/tc_cdiv_sync.h b/openpicc/application/tc_cdiv_sync.h index 0c7bd37..c834e3e 100644 --- a/openpicc/application/tc_cdiv_sync.h +++ b/openpicc/application/tc_cdiv_sync.h @@ -1,5 +1,8 @@ #ifndef _TC_CDIV_SYNC_H #define _TC_CDIV_SYNC_H + +#include "board.h" + extern void tc_cdiv_sync_disable(void); extern void tc_cdiv_sync_enable(void); extern void tc_cdiv_sync_init(void); -- cgit v1.2.3