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/Makefile | 1 + 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 +++ openpicc/config/board.c | 40 +++++++++++++++++++++++++++ openpicc/config/board.h | 41 +++++++++++++++++----------- 11 files changed, 149 insertions(+), 73 deletions(-) create mode 100644 openpicc/config/board.c diff --git a/openpicc/Makefile b/openpicc/Makefile index f88afb8..73c1c72 100644 --- a/openpicc/Makefile +++ b/openpicc/Makefile @@ -75,6 +75,7 @@ LINKER_FLAGS=-Xlinker -oopenpicc.elf -Xlinker -M -Xlinker -Map=openpicc.map # Source files that must be built to ARM mode. # ARM_SRC= \ + config/board.c \ application/main.c \ application/led.c \ application/cmd.c \ 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); diff --git a/openpicc/config/board.c b/openpicc/config/board.c new file mode 100644 index 0000000..aaa1163 --- /dev/null +++ b/openpicc/config/board.c @@ -0,0 +1,40 @@ +/* OpenPICC pin assignment array for dynamic run-time configuration for different board layouts + * (C) 2008 Henryk Plötz + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "board.h" +#include "lib_AT91SAM7.h" + +const struct openpicc_hardware OPENPICC_HARDWARE[] = { + [OPENPICC_v0_4] = {OPENPICC_v0_4, + "OpenPICC v0.4", // release name + {0, 0,}, // features: data_gating, clock_gating + AT91C_PIO_PA4, // PLL_LOCK + -1, // CLOCK_GATE + -1, // DATA_GATE + }, + [OPENPICC_v0_4_p1] = {OPENPICC_v0_4_p1, + "OpenPICC v0.4 patchlevel 1", + {1, 1,}, + AT91C_PIO_PA5, + AT91C_PIO_PA4, + AT91C_PIO_PA31, + }, +}; + +const struct openpicc_hardware *OPENPICC; diff --git a/openpicc/config/board.h b/openpicc/config/board.h index 0cfc9a5..428acd4 100644 --- a/openpicc/config/board.h +++ b/openpicc/config/board.h @@ -52,13 +52,30 @@ /*-----------------*/ /* Board version */ /*-----------------*/ -/* Modified board, routing PLL_LOCK to PA5 and a copy of FRAME to PA4, enabling the use of the T/C BURST feature. */ -#define OPENPICC_MODIFIED_BOARD - -#ifdef OPENPICC_MODIFIED_BOARD -#define OPENPICC_USE_SSC_DATA_GATING -#define OPENPICC_USE_CLOCK_GATING -#endif +enum openpicc_release { + OPENPICC_v0_4, /* Schematics v0.4, as sold in the shop */ + + OPENPICC_v0_4_p1, /* based on schematics v0.4; Modifications: + * + PLL_LOCK relocated from PA4 to PA5 + * + Copy of FRAME routed to PA4 + * + Connection between R18 and 3V3 removed, instead R18 is now connected to PA31*/ +}; +struct openpicc_hardware { + enum openpicc_release release; + char *release_name; + struct { + int data_gating:1; + int clock_gating:1; + } features; + + int PLL_LOCK; + + int CLOCK_GATE; + int DATA_GATE; +}; + +extern const struct openpicc_hardware OPENPICC_HARDWARE[]; +extern const struct openpicc_hardware *OPENPICC; /*-----------------*/ /* Pins */ @@ -70,11 +87,6 @@ #define OPENPICC_PIO_SS2_DT_THRESH AT91C_PIO_PA8 #define OPENPICC_PIO_PLL_INHIBIT AT91C_PIO_PA24 -#ifdef OPENPICC_MODIFIED_BOARD -#define OPENPICC_PIO_PLL_LOCK AT91C_PIO_PA5 -#else -#define OPENPICC_PIO_PLL_LOCK AT91C_PIO_PA4 -#endif #define OPENPICC_MOD_PWM AT91C_PA23_PWM0 #define OPENPICC_MOD_SSC AT91C_PA17_TD @@ -83,10 +95,7 @@ #define OPENPICC_SSC_TF AT91C_PIO_PA15 #define OPENPICC_PIO_FRAME AT91C_PIO_PA20 -#ifdef OPENPICC_MODIFIED_BOARD -#define OPENPICC_PIO_FRAME_BURST AT91C_PIO_PA4 -#define OPENPICC_PIO_SSC_DATA_GATE AT91C_PIO_PA31 -#endif + #define OPENPICC_PIO_SSC_DATA_CONTROL AT91C_PIO_PA21 #define OPENPICC_PIO_AB_DETECT AT91C_PIO_PA22 #define OPENPICC_PIO_PLL_INHIBIT AT91C_PIO_PA24 -- cgit v1.2.3