/** * \brief Initial the ssc interface. */ static void init_ssc(void) { clock_opt_t tx_clk_option; data_frame_opt_t tx_data_frame_option; /* Initialize clock */ pmc_enable_periph_clk(ID_SSC); /* Reset SSC */ ssc_reset(SSC); /* Configure SSC */ ssc_set_clock_divider(SSC, SAMPLE_RATE * (BITS_BY_SLOT + 1) * 2, sysclk_get_peripheral_hz()); /* Transmitter clock mode configuration. */ tx_clk_option.ul_cks = SSC_TCMR_CKS_MCK; tx_clk_option.ul_cko = SSC_TCMR_CKO_CONTINUOUS; tx_clk_option.ul_cki = 0; tx_clk_option.ul_ckg = SSC_TCMR_CKG_NONE; tx_clk_option.ul_start_sel = SSC_TCMR_START_RF_EDGE; tx_clk_option.ul_sttdly = 1; tx_clk_option.ul_period = BITS_BY_SLOT - 1; /* Transmitter frame mode configuration. */ tx_data_frame_option.ul_datlen = BITS_BY_SLOT - 1; tx_data_frame_option.ul_msbf = SSC_TFMR_MSBF; tx_data_frame_option.ul_datnb = 0; tx_data_frame_option.ul_fslen = BITS_BY_SLOT - 1; tx_data_frame_option.ul_fslen_ext = 0; tx_data_frame_option.ul_fsos = SSC_TFMR_FSOS_NEGATIVE; tx_data_frame_option.ul_fsedge = SSC_TFMR_FSEDGE_POSITIVE; /* Configure the SSC transmitter to I2S mode. */ ssc_set_transmitter(SSC, &tx_clk_option, &tx_data_frame_option); /* Disable transmitter first */ ssc_disable_tx(SSC); /* Disable All Interrupt */ ssc_disable_interrupt(SSC, 0xFFFFFFFF); }
/** * \brief Test Synchronous Serial Controller. * This test sets SSC module in the loop mode and check the receiver data * whether it's the same as the transmit data. * * \param test Current test case. */ static void run_ssc_test(const struct test_case *test) { uint32_t ul_mck; clock_opt_t tx_clk_option; clock_opt_t rx_clk_option; data_frame_opt_t rx_data_frame_option; data_frame_opt_t tx_data_frame_option; /* Initialize the local variable. */ ul_mck = 0; memset((uint8_t *)&rx_clk_option, 0, sizeof(clock_opt_t)); memset((uint8_t *)&rx_data_frame_option, 0, sizeof(data_frame_opt_t)); memset((uint8_t *)&tx_clk_option, 0, sizeof(clock_opt_t)); memset((uint8_t *)&tx_data_frame_option, 0, sizeof(data_frame_opt_t)); /* Initialize the SSC module and work in loop mode. */ pmc_enable_periph_clk(ID_SSC); ssc_reset(SSC); ul_mck = sysclk_get_cpu_hz(); ssc_set_clock_divider(SSC, SSC_BIT_RATE, ul_mck); /* Transmitter clock mode configuration. */ tx_clk_option.ul_cks = SSC_TCMR_CKS_MCK; tx_clk_option.ul_cko = SSC_TCMR_CKO_CONTINUOUS; tx_clk_option.ul_cki = 0; tx_clk_option.ul_ckg = SSC_TCMR_CKG_NONE; tx_clk_option.ul_start_sel = SSC_TCMR_START_CONTINUOUS; tx_clk_option.ul_sttdly = 0; tx_clk_option.ul_period = 0; /* Transmitter frame mode configuration. */ tx_data_frame_option.ul_datlen = BIT_LEN_PER_CHANNEL - 1; tx_data_frame_option.ul_msbf = SSC_TFMR_MSBF; tx_data_frame_option.ul_datnb = 0; tx_data_frame_option.ul_fslen = 0; tx_data_frame_option.ul_fslen_ext = 0; tx_data_frame_option.ul_fsos = SSC_TFMR_FSOS_TOGGLING; tx_data_frame_option.ul_fsedge = SSC_TFMR_FSEDGE_POSITIVE; /* Configure the SSC transmitter. */ ssc_set_transmitter(SSC, &tx_clk_option, &tx_data_frame_option); /* Receiver clock mode configuration. */ rx_clk_option.ul_cks = SSC_RCMR_CKS_TK; rx_clk_option.ul_cko = SSC_RCMR_CKO_NONE; rx_clk_option.ul_cki = 0; rx_clk_option.ul_ckg = SSC_TCMR_CKG_NONE; rx_clk_option.ul_start_sel = SSC_RCMR_START_RF_EDGE; rx_clk_option.ul_sttdly = 0; rx_clk_option.ul_period = 0; /* Receiver frame mode configuration. */ rx_data_frame_option.ul_datlen = BIT_LEN_PER_CHANNEL - 1; rx_data_frame_option.ul_msbf = SSC_TFMR_MSBF; rx_data_frame_option.ul_datnb = 0; rx_data_frame_option.ul_fslen = 0; rx_data_frame_option.ul_fslen_ext = 0; rx_data_frame_option.ul_fsos = SSC_TFMR_FSOS_NONE; rx_data_frame_option.ul_fsedge = SSC_TFMR_FSEDGE_POSITIVE; /* Configure the SSC receiver. */ ssc_set_receiver(SSC, &rx_clk_option, &rx_data_frame_option); /* Enable the loop mode. */ ssc_set_loop_mode(SSC); /* Enable the tx and rx function. */ ssc_enable_rx(SSC); ssc_enable_tx(SSC); /* Configure the RX interrupt. */ ssc_enable_interrupt(SSC, SSC_IER_RXRDY); /* Enable SSC interrupt line from the core */ NVIC_DisableIRQ(SSC_IRQn); NVIC_ClearPendingIRQ(SSC_IRQn); NVIC_SetPriority(SSC_IRQn, SSC_IRQ_PRIO); NVIC_EnableIRQ(SSC_IRQn); for (g_uc_tx_index = 0; g_uc_tx_index < BUFFER_SIZE; g_uc_tx_index++) { ssc_write(SSC, g_uc_tx_buff[g_uc_tx_index]); } while (!g_uc_rx_done) { } test_assert_true(test, (memcmp(g_uc_rx_buff, g_uc_tx_buff, BUFFER_SIZE) == 0), "Test: SSC received data is not the same as the transmit data!"); }