diff options
author | Harald Welte <laforge@osmocom.org> | 2019-12-23 20:11:00 +0100 |
---|---|---|
committer | Harald Welte <laforge@osmocom.org> | 2019-12-23 20:43:23 +0100 |
commit | 82b522bcda19bc9e3ec6920bb05d0386fac51184 (patch) | |
tree | 337ef4969ee9ce3ef9aa2b91a425d18116b3d607 | |
parent | f3734e752fe7de4ddef371ca6c81b7f8e5e426dd (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.c | 83 | ||||
-rw-r--r-- | sam/applications/sam_e1/main.c | 7 |
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(); |