/** * \brief Application entry point for adcife example. * * \return Unused (ANSI-C compatibility). */ int main(void) { uint32_t uc_key = 0; /* Initialize the SAM system */ sysclk_init(); board_init(); /* Initialize the UART console */ configure_console(); /* Output example information */ puts(STRING_HEADER); /* Set default ADCIFE test mode. */ g_adc_test_mode.uc_trigger_mode = TRIGGER_MODE_SOFTWARE; g_adc_test_mode.uc_pdc_en = 1; g_adc_test_mode.uc_gain_en = 0; display_menu(); start_dac(); start_adc(); while (1) { /* ADCIFE software trigger per 1s */ if (g_adc_test_mode.uc_trigger_mode == TRIGGER_MODE_SOFTWARE) { adc_start_software_conversion(&g_adc_inst); } if (!usart_read(CONF_UART, &uc_key)) { adc_disable_interrupt(&g_adc_inst, ADC_SEQ_SEOC); display_menu(); set_adc_test_mode(); start_adc(); puts("Press any key to display configuration menu.\r"); } delay_ms(1000); if (g_uc_condone_flag == 1) { if(g_adc_test_mode.uc_pdc_en == 0) { printf("Internal DAC Voltage = %4d mv \r\n", (int)(g_adc_sample_data[0] * VOLT_REF / MAX_DIGITAL)); } else { printf("Internal DAC Voltage = %4d mv \r\n", (int)(g_adc_sample_data[0] * VOLT_REF / MAX_DIGITAL)); printf("Scaled VCC Voltage = %4d mv \r\n", (int)(g_adc_sample_data[1] * VOLT_REF / MAX_DIGITAL)); } g_uc_condone_flag = 0; } } }
/** * \brief Test ADCIFE in Differential mode. * * \param test Current test case. */ static void run_adcife_diff_test(const struct test_case *test) { uint32_t timeout = ADC_NUM_OF_ATTEMPTS; bool conversion_timeout = false; struct adc_seq_config adc_seq_cfg = { /* Select Vref for shift cycle */ .zoomrange = ADC_ZOOMRANGE_0, /* Pad Ground */ .muxneg = ADC_MUXNEG_1, /* Scaled Vcc, Vcc/10 */ .muxpos = ADC_MUXPOS_2, /* Enables the internal voltage sources */ .internal = ADC_INTERNAL_3, /* Disables the ADC gain error reduction */ .gcomp = ADC_GCOMP_DIS, /* Disables the HWLA mode */ .hwla = ADC_HWLA_DIS, /* 12-bits resolution */ .res = ADC_RES_12_BIT, /* Enables the differential mode */ .bipolar = ADC_BIPOLAR_DIFFERENTIAL }; struct adc_ch_config adc_ch_cfg = { .seq_cfg = &adc_seq_cfg, /* Internal Timer Max Counter */ .internal_timer_max_count = 60, /* Window monitor mode is off */ .window_mode = 0, .low_threshold = 0, .high_threshold = 0, }; adc_ch_set_config(&g_adc_inst, &adc_ch_cfg); adc_configure_trigger(&g_adc_inst, ADC_TRIG_CON); adc_configure_gain(&g_adc_inst, ADC_GAIN_1X); while (!((adc_get_status(&g_adc_inst) & ADCIFE_SR_SEOC) == ADCIFE_SR_SEOC)) { if (!timeout--) { conversion_timeout = true; } } test_assert_true(test, conversion_timeout == false, "ADCIFE Differential conversion timeout"); /* Because selected channel is positive input, then in differential mode * the output conversion result will = 2047 + (Vin/Vref)*2047. */ test_assert_true(test, adc_get_last_conv_value(&g_adc_inst) > 2047, "ADCIFE Differential test failed"); } /** * \brief Test ADCIFE in internal timer trigger mode, * which also tests interrupt driven conversions. * * \param test Current test case. */ static void run_adcife_itimer_trig_test(const struct test_case *test) { struct adc_seq_config adc_seq_cfg = { /* Select Vref for shift cycle */ .zoomrange = ADC_ZOOMRANGE_0, /* Pad Ground */ .muxneg = ADC_MUXNEG_1, /* Scaled Vcc, Vcc/10 */ .muxpos = ADC_MUXPOS_2, /* Enables the internal voltage sources */ .internal = ADC_INTERNAL_3, /* Disables the ADC gain error reduction */ .gcomp = ADC_GCOMP_DIS, /* Disables the HWLA mode */ .hwla = ADC_HWLA_DIS, /* 12-bits resolution */ .res = ADC_RES_12_BIT, /* Enables the single-ended mode */ .bipolar = ADC_BIPOLAR_SINGLEENDED }; struct adc_ch_config adc_ch_cfg = { .seq_cfg = &adc_seq_cfg, /* Internal Timer Max Counter */ .internal_timer_max_count = 60, /* Window monitor mode is off */ .window_mode = 0, .low_threshold = 0, .high_threshold = 0, }; adc_ch_set_config(&g_adc_inst, &adc_ch_cfg); adc_set_callback(&g_adc_inst, ADC_SEQ_SEOC, adcife_set_conv_flag, ADCIFE_IRQn, 1); adc_configure_trigger(&g_adc_inst, ADC_TRIG_INTL_TIMER); adc_configure_gain(&g_adc_inst, ADC_GAIN_1X); adc_configure_itimer_period(&g_adc_inst, adc_ch_cfg.internal_timer_max_count); adc_start_itimer(&g_adc_inst); delay_ms(100); test_assert_true(test, g_uc_condone_flag == 1, "ADCIFE Internal Timer trigger test failed"); } /* When VDDANA is in MIN value = 2.4V, the equivalent voltage value is * (2400 * 255) / ((1 << 10) - 1) = 598mv. The relative digital value is * 598 * 4095 / 1000 = 2449. */ #define DAC_INTERNAL_MIN_VALUE 2449 /* When VDDANA is in MAX value = 3.6V the equivalent voltage value is * (3600 * 255) / ((1 << 10) - 1) = 897mv. The relative digital value is * 897 * 4095 / 1000 = 3673. */ #define DAC_INTERNAL_MAX_VALUE 3673 /* When VCC is in MIN value = 1.6V, the equivalent voltage value is * 1600 / 10 = 160mv. The relative digital value is * 160 * 4095 / 1000 = 434. */ #define VCC_SCALED_MIN_VALUE 434 /* When VCC is in MAX value = 3.6V, the equivalent voltage value is * 3600 / 10 = 360mv. The relative digital value is * 360 * 4095 / 1000 = 1474. */ #define VCC_SCALED_MAX_VALUE 1474 /** * \brief Test ADCIFE in multiple channel mode. * * \param test Current test case. */ static void run_adcife_multichannel_test(const struct test_case *test) { start_dac(); adc_pdca_set_config(&g_adc_pdca_cfg); pdca_channel_set_callback(CONFIG_ADC_PDCA_RX_CHANNEL, pdca_transfer_done, PDCA_0_IRQn, 1, PDCA_IER_TRC); adc_configure_trigger(&g_adc_inst, ADC_TRIG_CON); adc_configure_gain(&g_adc_inst, ADC_GAIN_1X); delay_ms(100); /* The DAC output voltage value is 823mv, so the equivalent ADC value should be * 4095 * 823 / 1000 = 3370. The scaled VCC output voltage is 330mv, so the * equivalent ADC value should be 4095 * 330 / 1000 = 1351. */ test_assert_true(test, ((DAC_INTERNAL_MIN_VALUE < g_adc_sample_data[0] < DAC_INTERNAL_MAX_VALUE) && (VCC_SCALED_MIN_VALUE < g_adc_sample_data[1] < VCC_SCALED_MAX_VALUE)), "ADCIFE Multichannel test failed"); } /** * \brief Test ADCIFE in window monitor mode. * * \param test Current test case. */ static void run_adcife_wm_test(const struct test_case *test) { struct adc_seq_config adc_seq_cfg = { /* Select Vref for shift cycle */ .zoomrange = ADC_ZOOMRANGE_0, /* Pad Ground */ .muxneg = ADC_MUXNEG_1, /* Scaled Vcc, Vcc/10 */ .muxpos = ADC_MUXPOS_2, /* Enables the internal voltage sources */ .internal = ADC_INTERNAL_3, /* Disables the ADC gain error reduction */ .gcomp = ADC_GCOMP_DIS, /* Disables the HWLA mode */ .hwla = ADC_HWLA_DIS, /* 12-bits resolution */ .res = ADC_RES_12_BIT, /* Enables the single-ended mode */ .bipolar = ADC_BIPOLAR_SINGLEENDED }; struct adc_ch_config adc_ch_cfg = { .seq_cfg = &adc_seq_cfg, /* Internal Timer Max Counter */ .internal_timer_max_count = 60, /* Window monitor mode is off */ .window_mode = ADC_WM_MODE_3, /* The equivalent voltage value is 205 * 1000 / 4095 = 50mv. */ .low_threshold = 205, /* The equivalent voltage value is 2050 * 1000 / 4095 = 500mv. */ .high_threshold = 2050, }; adc_ch_set_config(&g_adc_inst, &adc_ch_cfg); adc_configure_trigger(&g_adc_inst, ADC_TRIG_CON); adc_configure_gain(&g_adc_inst, ADC_GAIN_1X); adc_set_callback(&g_adc_inst, ADC_WINDOW_MONITOR, adcife_set_wm_flag, ADCIFE_IRQn, 1); delay_ms(100); test_assert_true(test, g_uc_enter_win_flag == 1, "ADCIFE Inside Window Mode test failed"); /* The teseted channel voltage is outside window */ adc_disable(&g_adc_inst); g_uc_enter_win_flag = 0; adc_seq_cfg.muxpos = ADC_MUXPOS_3; adc_ch_set_config(&g_adc_inst, &adc_ch_cfg); adc_configure_trigger(&g_adc_inst, ADC_TRIG_CON); adc_configure_gain(&g_adc_inst, ADC_GAIN_1X); adc_enable_interrupt(&g_adc_inst, ADC_WINDOW_MONITOR); delay_ms(100); test_assert_true(test, g_uc_enter_win_flag == 0, "ADCIFE Outside Window Mode test failed"); } /** * \brief Run ADCIFE driver unit tests. */ int main(void) { const usart_serial_options_t usart_serial_options = { .baudrate = CONF_TEST_BAUDRATE, .charlength = CONF_TEST_CHARLENGTH, .paritytype = CONF_TEST_PARITY, .stopbits = CONF_TEST_STOPBITS }; /* Initialize the system clock and board */ sysclk_init(); board_init(); /* Enable the debug uart */ stdio_serial_init(CONF_TEST_USART, &usart_serial_options); #if defined(__GNUC__) setbuf(stdout, NULL); #endif /* Define all the test cases */ DEFINE_TEST_CASE(adcife_init_test, NULL, run_adcife_init_test, NULL, "ADCIFE Initialize test"); DEFINE_TEST_CASE(adcife_diff_test, NULL, run_adcife_diff_test, NULL, "ADCIFE Differential test"); DEFINE_TEST_CASE(adcife_itmer_trig_test, NULL, run_adcife_itimer_trig_test, NULL, "ADCIFE Internal Timer trigger test"); DEFINE_TEST_CASE(adcife_multichannel_test, NULL, run_adcife_multichannel_test, NULL, "ADCIFE Multichannel test"); DEFINE_TEST_CASE(adcife_wm_test, NULL, run_adcife_wm_test, NULL, "ADCIFE Window Monitor Mode test"); /* Put test case addresses in an array */ DEFINE_TEST_ARRAY(adcife_tests) = { &adcife_init_test, &adcife_diff_test, &adcife_itmer_trig_test, &adcife_multichannel_test, &adcife_wm_test, }; /* Define the test suite */ DEFINE_TEST_SUITE(adcife_suite, adcife_tests, "SAM ADCIFE driver test suite"); /* Run all tests in the test suite */ test_suite_run(&adcife_suite); while (1) { /* Busy-wait forever. */ } }
int probe1() { unsigned int pciBusNo, pciDevNo, pciFuncNo; unsigned char byte; /* int i,j;*/ UINT32 s_pBA0, s_pBA1; /* To ensure that taskDelay(1) is 1ms delay */ sysClkRateSet(1000); if (pciConfigLibInit (PCI_MECHANISM_1, 0xCF8, 0xCFC, 0) != OK) { printf("PCI lib config error\n"); return 1; } /**************************** * Find SoundCard * Set BaseAddr0, BaseAddr1 ****************************/ if(!(pciFindDevice(PCI_VENDOR_ID_CIRRUS,PCI_DEVICE_ID_CRYSTAL_CS4281, 0, &pciBusNo, &pciDevNo, &pciFuncNo)==OK)) { printf("\n CS4281 sound card NOT FOUND!!! \n"); return 1; } printf("\n FOUND CS4281 sound card, configuring BA0,BA1... \n"); pciConfigOutLong( pciBusNo, pciDevNo, pciFuncNo, PCI_CFG_BASE_ADDRESS_0, CS4281_pBA0); /* pciConfigOutLong( pciBusNo, pciDevNo, pciFuncNo, PCI_CFG_BASE_ADDRESS_1, CS4281_pBA1); */ pciConfigInLong( pciBusNo, pciDevNo, pciFuncNo, PCI_CFG_BASE_ADDRESS_0, &s_pBA0); pciConfigInLong( pciBusNo, pciDevNo, pciFuncNo, PCI_CFG_BASE_ADDRESS_1, &s_pBA1 ); printf ("\npBusNo pDeviceNo pFuncNo pBA0 pBA1\n\n"); printf ("%.8x %.8x %.8x %.8x %.8x \n", pciBusNo, pciDevNo, pciFuncNo, s_pBA0,s_pBA1); /******************************** * Config PCI Device Capability * DMA Master * MEM mapped ********************************/ /* Set the INTA vector */ pciConfigInByte(pciBusNo, pciDevNo, pciFuncNo, PCI_CFG_DEV_INT_LINE, &cs4281_irq); printf("\nFound CS4281 configured for IRQ %d\n", cs4281_irq); pciConfigInByte(pciBusNo, pciDevNo, pciFuncNo, PCI_CFG_DEV_INT_PIN, &byte); printf("\tINT_PIN=%.8x\n", byte); /* Enable the device's capabilities as specified * Bus Master Enable/ Mem Space Enable */ pciConfigOutWord(pciBusNo, pciDevNo, pciFuncNo, PCI_CFG_COMMAND, (unsigned short)0x0006); /*************************** * BringUp Hardware ***************************/ /*Include Init Function Here*/ cs4281_hw_init(); /**************************** * Allocate ADC_BUFFER * Allocate DAC_BUFFER * * Hook cs4281_interrupt * * Program CoDec ****************************/ if((DAC_BUFFER=valloc(DAC_BUFFER_SIZE))==NULL) { printf("\n DAC_BUFFER valloc failed!\n"); return 1; } memset( DAC_BUFFER, 0, DAC_BUFFER_SIZE ); printf("\ndac=%x",DAC_BUFFER); /*for( i=0 ; i < DAC_BUFFER_SIZE ; i++ ) ((char *)DAC_BUFFER)[i]=0x7f;*/ writel((UINT32)DAC_BUFFER+8,CS4281_pBA0 + BA0_DBA0); writel(DAC_BUFFER_SIZE-16, CS4281_pBA0 + BA0_DBC0); printf("\nbao=%x",readl(CS4281_pBA0 + BA0_DBA0)); printf("\nbco=%x",readl(CS4281_pBA0 + BA0_DBC0)); printf("\ncco=%x",readl(CS4281_pBA0 + BA0_DCC0)); if((ADC_BUFFER=valloc(ADC_BUFFER_SIZE))==NULL) { printf("\n ADC_BUFFER valloc failed!\n"); return 1; } printf("\nadc=%x",ADC_BUFFER); /*for( i=0 ; i < ADC_BUFFER_SIZE ; i++ ) ((char *)ADC_BUFFER)[i]=0x7f;*/ writel((UINT32)ADC_BUFFER+8,CS4281_pBA0 + BA0_DBA1); writel(ADC_BUFFER_SIZE-16, CS4281_pBA0 + BA0_DBC1); /* connect interrupt */ printf("\n Hook cs4281_interrupt to vector %d\n", (INUM_TO_IVEC (cs4281_irq+INT_NUM_IRQ0))); pciIntConnect((INUM_TO_IVEC (cs4281_irq+INT_NUM_IRQ0)), (VOIDFUNCPTR)cs4281_interrupt, 0); sysIntEnablePIC(cs4281_irq); SEM_DMA_Playback = semBCreate(SEM_Q_FIFO,SEM_EMPTY); SEM_MY_Playback = semBCreate(SEM_Q_FIFO,SEM_EMPTY); SEM_DMA_Record = semBCreate(SEM_Q_FIFO,SEM_EMPTY); SEM_Sample = semBCreate(SEM_Q_FIFO,SEM_EMPTY); CNT_DMA_Playback = CNT_DMA_Record = 0; /* program coDec */ printf("\n Program CoDec (sample rate, DMA...)\n"); prog_codec(); /********************************************* * start dac/adc, interrupt is comming... *********************************************/ start_dac(); return 0; }
/** * \brief Example entry point. * * \return Unused (ANSI-C compatibility). */ int main(void) { uint8_t c_choice; int16_t s_adc_value; int16_t s_dac_value; int16_t s_threshold = 0; float f_dac_data; uint32_t ul_dac_data; /* Initialize the SAM system. */ sysclk_init(); board_init(); configure_console(); /* Output example information. */ puts(STRING_HEADER); /* Initialize threshold. */ gs_us_low_threshold = 500; gs_us_high_threshold = 2000; struct adc_config adc_cfg = { /* System clock division factor is 16 */ .prescal = ADC_PRESCAL_DIV16, /* The APB clock is used */ .clksel = ADC_CLKSEL_APBCLK, /* Max speed is 150K */ .speed = ADC_SPEED_150K, /* ADC Reference voltage is 0.625*VCC */ .refsel = ADC_REFSEL_1, /* Enables the Startup time */ .start_up = CONFIG_ADC_STARTUP }; struct adc_seq_config adc_seq_cfg = { /* Select Vref for shift cycle */ .zoomrange = ADC_ZOOMRANGE_0, /* Pad Ground */ .muxneg = ADC_MUXNEG_1, /* DAC Internal */ .muxpos = ADC_MUXPOS_3, /* Enables the internal voltage sources */ .internal = ADC_INTERNAL_3, /* Disables the ADC gain error reduction */ .gcomp = ADC_GCOMP_DIS, /* Disables the HWLA mode */ .hwla = ADC_HWLA_DIS, /* 12-bits resolution */ .res = ADC_RES_12_BIT, /* Enables the single-ended mode */ .bipolar = ADC_BIPOLAR_SINGLEENDED }; struct adc_ch_config adc_ch_cfg = { .seq_cfg = &adc_seq_cfg, /* Internal Timer Max Counter */ .internal_timer_max_count = 60, /* Window monitor mode is off */ .window_mode = ADC_WM_MODE_3, /* The equivalent voltage value is 500 * VOLT_REF / 4095 = 251mv. */ .low_threshold = gs_us_low_threshold, /* The equivalent voltage value is 2000 * VOLT_REF / 4095 = 1002mv. */ .high_threshold = gs_us_high_threshold, }; start_dac(); if(adc_init(&g_adc_inst, ADCIFE, &adc_cfg) != STATUS_OK) { puts("-F- ADC Init Fail!\n\r"); while(1); } if(adc_enable(&g_adc_inst) != STATUS_OK) { puts("-F- ADC Enable Fail!\n\r"); while(1); } adc_ch_set_config(&g_adc_inst, &adc_ch_cfg); adc_configure_trigger(&g_adc_inst, ADC_TRIG_CON); adc_configure_gain(&g_adc_inst, ADC_GAIN_1X); adc_set_callback(&g_adc_inst, ADC_WINDOW_MONITOR, adcife_wm_handler, ADCIFE_IRQn, 1); /* Display main menu. */ display_menu(); while (1) { scanf("%c", (char *)&c_choice); printf("%c\r\n", c_choice); switch (c_choice) { case '0': adc_disable_interrupt(&g_adc_inst, ADC_WINDOW_MONITOR); printf("DAC output is set to(mv) from 0mv to %dmv: ", (int32_t)VOLT_REF); s_dac_value = get_voltage(); puts("\r"); f_dac_data = (float)s_dac_value * DACC_MAX_DATA / VDDANA; ul_dac_data = f_to_int(f_dac_data); if (s_dac_value >= 0) { dacc_write_conversion_data(DACC, ul_dac_data); } delay_ms(100); adc_clear_status(&g_adc_inst, ADCIFE_SCR_WM); adc_enable_interrupt(&g_adc_inst, ADC_WINDOW_MONITOR); break; case '1': adc_disable_interrupt(&g_adc_inst, ADC_WINDOW_MONITOR); printf("Low threshold is set to(mv) from 0mv to %dmv: ", (int32_t)VOLT_REF); s_threshold = get_voltage(); puts("\r"); if (s_threshold >= 0) { s_adc_value = s_threshold * MAX_DIGITAL / VOLT_REF; adc_configure_wm_threshold(&g_adc_inst, s_adc_value, gs_us_high_threshold); /* Renew low threshold. */ gs_us_low_threshold = s_adc_value; float f_low_threshold = (float)gs_us_low_threshold * VOLT_REF / MAX_DIGITAL; uint32_t ul_low_threshold = f_to_int(f_low_threshold); printf("Setting low threshold to %u mv (reg value to 0x%x ~%d%%)\n\r", ul_low_threshold, gs_us_low_threshold, gs_us_low_threshold * 100 / MAX_DIGITAL); } adc_clear_status(&g_adc_inst, ADCIFE_SCR_WM); adc_enable_interrupt(&g_adc_inst, ADC_WINDOW_MONITOR); break; case '2': adc_disable_interrupt(&g_adc_inst, ADC_WINDOW_MONITOR); printf("High threshold is set to(mv)from 0mv to %dmv:", (int32_t)VOLT_REF); s_threshold = get_voltage(); puts("\r"); if (s_threshold >= 0) { s_adc_value = s_threshold * MAX_DIGITAL / VOLT_REF; adc_configure_wm_threshold(&g_adc_inst, gs_us_low_threshold, s_adc_value); /* Renew high threshold. */ gs_us_high_threshold = s_adc_value; float f_high_threshold = (float)gs_us_high_threshold * VOLT_REF / MAX_DIGITAL; uint32_t ul_high_threshold = f_to_int(f_high_threshold); printf("Setting high threshold to %u mv (reg value to 0x%x ~%d%%)\n\r", ul_high_threshold, gs_us_high_threshold, gs_us_high_threshold * 100 / MAX_DIGITAL); } adc_clear_status(&g_adc_inst, ADCIFE_SCR_WM); adc_enable_interrupt(&g_adc_inst, ADC_WINDOW_MONITOR); break; case '3': adc_disable_interrupt(&g_adc_inst, ADC_WINDOW_MONITOR); puts("-a. Above low threshold.\n\r" "-b. Below high threshold.\n\r" "-c. In the comparison window.\n\r" "-d. Out of the comparison window.\n\r" "-q. Quit the setting.\r"); c_choice = get_wm_mode(); adc_configure_wm_mode(&g_adc_inst, c_choice); printf("Comparison mode is %c.\n\r", 'a' + c_choice - 1); adc_clear_status(&g_adc_inst, ADCIFE_SCR_WM); adc_enable_interrupt(&g_adc_inst, ADC_WINDOW_MONITOR); break; case 'm': display_menu(); break; case 'i': display_info(); adc_clear_status(&g_adc_inst, ADCIFE_SCR_WM); adc_enable_interrupt(&g_adc_inst, ADC_WINDOW_MONITOR); break; } puts("Press \'m\' or \'M\' to display the main menu again!\r"); } }