aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@osmocom.org>2019-12-23 20:11:00 +0100
committerHarald Welte <laforge@osmocom.org>2019-12-23 20:43:23 +0100
commit82b522bcda19bc9e3ec6920bb05d0386fac51184 (patch)
tree337ef4969ee9ce3ef9aa2b91a425d18116b3d607
parentf3734e752fe7de4ddef371ca6c81b7f8e5e426dd (diff)
e1: Add support for vogelchr's USB E1 interface board
The board from the following hardware repository https://github.com/vogelchr/e1_sam4_usb is supported now.
-rw-r--r--sam/applications/sam_e1/e1_ssc_tc.c83
-rw-r--r--sam/applications/sam_e1/main.c7
2 files changed, 80 insertions, 10 deletions
diff --git a/sam/applications/sam_e1/e1_ssc_tc.c b/sam/applications/sam_e1/e1_ssc_tc.c
index 8e024967..0acd6ebd 100644
--- a/sam/applications/sam_e1/e1_ssc_tc.c
+++ b/sam/applications/sam_e1/e1_ssc_tc.c
@@ -14,19 +14,38 @@
/* We use one timer/counter block to generate an artificial frame signal from the
* received/recovered clock, which we then feed into the SSC for bit/octet-alignment */
+/* The SAM4S contains two TC peripheral blocks (let's call them instance 0 + 1),
+ * each of which has three TC functional blocks (TC0..2, TC3..5). The naming in
+ * Atmel literature and source code is highly confusing as TC1 sometimes means
+ * instance 1, but sometimes counter '1' at instance '0'. */
+
+#if BOARD == OSMOCOM_E1_USB
+#define ID_TC_ALIGN ID_TC2 /* TC2 == TC2 on instance 0 */
+#define TC_ALIGN TC0 /* instance 0 */
+#define TC_CHANNEL_ALIGN 2 /* TC2 on instance 0 */
+#elif BOARD == SAM4S_XPLAINED_PRO
#define ID_TC_ALIGN ID_TC4 /* TC4 == TC1 on instance 1 */
#define TC_ALIGN TC1 /* instance 1 */
#define TC_CHANNEL_ALIGN 1 /* TC1 on instance 1 */
+#else
+#error "Unsupported BOARD"
+#endif
void e1_tc_align_init(void)
{
printf("%s\n\r", __func__);
sysclk_enable_peripheral_clock(ID_TC_ALIGN);
- //TC_CMR_EEVT_XC1 | /* external event is XC1 */
//TC_CMR_AEEVT_CLEAR | /* clear TIOA on ext event */
tc_init(TC_ALIGN, TC_CHANNEL_ALIGN,
+ TC_CMR_EEVT_XC1 | /* external event is XC1 to make TOIB an output */
+#if BOARD == OSMOCOM_E1_USB
+ TC_CMR_TCCLKS_XC2 | /* use XC2 as clock source */
+#elif BOARD == SAM4S_XPLAINED_PRO
TC_CMR_TCCLKS_XC0 | /* use XC0 as clock source */
+#else
+#error "Unsupported BOARD"
+#endif
TC_CMR_WAVE | /* waveform mode */
TC_CMR_WAVSEL_UP_RC | /* upward counting with trigger on RC compare */
TC_CMR_ACPA_SET | /* set TIOA on RA compare */
@@ -35,13 +54,13 @@ void e1_tc_align_init(void)
TC_CMR_BCPC_CLEAR /* clear TIOB on RC compare */
);
- /* Route TCLK0 to XC0 */
- tc_set_block_mode(TC_ALIGN, TC_BMR_TC0XC0S_TCLK0 | TC_BMR_TC1XC1S_TCLK1 | TC_BMR_TC2XC2S_TCLK2);
+ /* Route TCLK0 to XC0, TCLK2 to XC2 (on each TC instance) */
+ tc_set_block_mode(TC_ALIGN, TC_BMR_TC0XC0S_TCLK0 | TC_BMR_TC2XC2S_TCLK2);
/* one frame is 256 clock cycles */
tc_write_rc(TC_ALIGN, TC_CHANNEL_ALIGN, 256);
/* use RA to shift position of rising edge of generated frame signal */
- tc_write_ra(TC_ALIGN, TC_CHANNEL_ALIGN, 16);
+ e1_tc_align_set(16);
tc_start(TC_ALIGN, TC_CHANNEL_ALIGN);
}
@@ -53,21 +72,38 @@ uint32_t e1_tc_align_read(void)
void e1_tc_align_set(uint8_t pos)
{
+#if BOARD == OSMOCOM_E1_USB
+ tc_write_rb(TC_ALIGN, TC_CHANNEL_ALIGN, pos);
+#elif BOARD == SAM4S_XPLAINED_PRO
tc_write_ra(TC_ALIGN, TC_CHANNEL_ALIGN, pos);
+#else
+#error "Unsupported BOARD"
+#endif
+}
+
+static uint32_t e1_tc_align_get(void)
+{
+#if BOARD == OSMOCOM_E1_USB
+ return tc_read_rb(TC_ALIGN, TC_CHANNEL_ALIGN);
+#elif BOARD == SAM4S_XPLAINED_PRO
+ return tc_read_ra(TC_ALIGN, TC_CHANNEL_ALIGN);
+#else
+#error "Unsupported BOARD"
+#endif
}
static void e1_tc_align_increment(void)
{
- uint32_t ra = tc_read_ra(TC_ALIGN, TC_CHANNEL_ALIGN);
+ uint32_t ra = e1_tc_align_get();
ra++;
if (ra >= 256) {
/* we cannot set RA to 0 (no pulse generated), so restart */
- tc_write_ra(TC_ALIGN, TC_CHANNEL_ALIGN, 1);
+ e1_tc_align_set(1);
tc_start(TC_ALIGN, TC_CHANNEL_ALIGN);
} else {
/* generate frame signal one bit later */
- tc_write_ra(TC_ALIGN, TC_CHANNEL_ALIGN, ra);
+ e1_tc_align_set(ra);
}
}
@@ -213,17 +249,31 @@ void e1_init_gpio(void)
pio_configure_pin(PIO_PA17_IDX, PIO_PERIPH_A); /* TD */
/* receive frame generation via TC */
+#if BOARD == OSMOCOM_E1_USB
+ pio_configure_pin(PIO_PA29_IDX, PIO_PERIPH_B); /* TCLK2 */
+ pio_configure_pin(PIO_PA27_IDX, PIO_PERIPH_B); /* TIOB2 */
+#elif BOARD == SAM4S_XPLAINED_PRO
pio_configure_pin(PIO_PC25_IDX, PIO_PERIPH_B); /* TCKL3 */
- pio_configure_pin(PIO_PA20_IDX, PIO_PERIPH_A); /* RF */
pio_configure_pin(PIO_PC26_IDX, PIO_PERIPH_B); /* TIOA4 */
- //pio_configure_pin(PIO_PC27_IDX, PIO_PERIPH_B); /* TIOB4 */
+#else
+#error "Unsupported BOARD"
+#endif
+ pio_configure_pin(PIO_PA20_IDX, PIO_PERIPH_A); /* RF */
/* SPI to LIU */
+#if BOARD == OSMOCOM_E1_USB
+ pio_configure_pin(PIO_PA7_IDX, PIO_INPUT); /* !LIU_INT */
+ pio_configure_pin(PIO_PA31_IDX, PIO_PERIPH_A); /* NPCS1 / !LIU_CS */
+#elif BOARD == SAM4S_XPLAINED_PRO
pio_configure_pin(PIO_PC27_IDX, PIO_INPUT); /* !LIU_INT */
pio_configure_pin(PIO_PA9_IDX, PIO_PERIPH_B); /* NPCS1 / !LIU_CS */
+#else
+#error "Unsupported BOARD"
+#endif
pio_configure_pin(PIO_PA12_IDX, PIO_PERIPH_A); /* LIU_MISO */
pio_configure_pin(PIO_PA14_IDX, PIO_PERIPH_A); /* LIU_SCLK */
pio_configure_pin(PIO_PA13_IDX, PIO_PERIPH_A); /* LIU_MOSI */
+ pio_configure_pin(PIO_PA8_IDX, PIO_OUTPUT_1); /* !RST_LIU */
}
void e1_ssc_init(void)
@@ -272,8 +322,17 @@ void e1_ssc_init(void)
static const clock_opt_t tx_clk = {
.ul_ckg = SSC_TCMR_CKG_CONTINUOUS,
.ul_cki = 0, //SSC_RCMR_CKI
+#if BOARD == OSMOCOM_E1_USB
+ /* TX clock is generated by SSC peripheral, not externally */
+ .ul_cko = SSC_TCMR_CKO_CONTINUOUS,
+ .ul_cks = SSC_TCMR_CKS_MCK,
+#elif BOARD == SAM4S_XPLAINED_PRO
+ /* TX clock is generated externally by 2.048Mhz XO */
.ul_cko = SSC_TCMR_CKO_NONE,
.ul_cks = SSC_TCMR_CKS_TK,
+#else
+#error "Unsupported BOARD"
+#endif
.ul_period = 0,
.ul_start_sel = SSC_TCMR_START_CONTINUOUS,
.ul_sttdly = 0,
@@ -290,7 +349,11 @@ void e1_ssc_init(void)
printf("ssc_set_transmitter\n\r");
ssc_set_transmitter(SSC, (clock_opt_t *) &tx_clk, (data_frame_opt_t *) &tx_opt);
-#endif
+#if BOARD == OSMOCOM_E1_USB
+ /* somehow ssc_set_clock_divider(SSC, 2048000, sysclk_get_peripheral_hz()) doesn't work */
+ SSC->SSC_CMR = SSC_CMR_DIV(27);
+#endif /* BOARD */
+#endif /* TX_ENABLE */
/* set up Peripheral DMA controller */
g_pdc_ssc_cur_rx_idx = 0;
diff --git a/sam/applications/sam_e1/main.c b/sam/applications/sam_e1/main.c
index 4117b5cc..627e7cc1 100644
--- a/sam/applications/sam_e1/main.c
+++ b/sam/applications/sam_e1/main.c
@@ -273,6 +273,13 @@ void SysTick_Handler(void)
int main(void)
{
/* Initialize the SAM system */
+#if BOARD == OSMOCOM_E1_USB
+ pmc_enable_periph_clk(ID_PIOB);
+ /* disable VCTCXO before initializing clocking (PB0=ENABLE_VCTCXO) */
+ pio_configure_pin(PIO_PB0_IDX, PIO_TYPE_PIO_OUTPUT_0);
+ /* enable VCXO before initializing clocking (PB1=ENABLE_VCXO) */
+ pio_configure_pin(PIO_PB1_IDX, PIO_TYPE_PIO_OUTPUT_1);
+#endif
sysclk_init();
g_ul_current_mck = sysclk_get_cpu_hz();
board_init();