| /****************************************************************************** |
| * Copyright (c) 2015-2016 by Silicon Laboratories |
| * |
| * $Id: platform.c 6174 2016-12-08 01:13:17Z elgeorge $ |
| * |
| * This file contains proprietary information. |
| * No dissemination allowed without prior written permission from |
| * Silicon Laboratories, Inc. |
| * |
| * File Description: |
| * |
| * This file implements common VMB/VMB2 functions needed for the various demos. |
| * |
| */ |
| |
| #ifndef PROSLIC_LINUX_KERNEL |
| #include <ctype.h> |
| #include <stdio.h> |
| #include "proslic_timer.h" |
| #include "user_intf.h" |
| #else |
| #include "proslic_sys.h" |
| #endif |
| |
| #include "proslic.h" |
| #include "spi_main.h" |
| |
| /***********************************/ |
| |
| static void vmbReset(SiVoiceControlInterfaceType *ctrlInterface) |
| { |
| /* Setup code keeps part in reset at prompt.... */ |
| |
| ctrlInterface->Reset_fptr(ctrlInterface->hCtrl,0); |
| |
| /* For ISI, we needed to extend the delay to access the part - |
| somewhere between 1 - 2 seconds is needed. |
| Normally this delay can be shorter. */ |
| ctrlInterface->Delay_fptr(ctrlInterface->hTimer,1500); |
| } |
| |
| |
| /************************************/ |
| #ifdef VMB2 |
| void vmbSetup(SiVoiceControlInterfaceType *ProHWIntf) |
| { |
| #ifndef SILABS_NO_PROMPTS |
| uInt8 m; |
| char resp[4]; |
| int sclk_freq; |
| int pcm_src; |
| int pclk_freq; |
| uInt16 firmware_version; |
| int isISI=0; |
| #else |
| SILABS_UNREFERENCED_PARAMETER(ProHWIntf); |
| #endif |
| |
| #ifndef SILABS_NO_PROMPTS |
| printf("Demo: VMB2 VCP Connected via %s\n", SPI_GetPortNum(ProHWIntf->hCtrl)); |
| firmware_version = GetFirmwareID(); |
| printf("Demo: VMB2 Firmware Version %d.%d\n", ((firmware_version >> 8)&0x00FF), |
| (firmware_version & 0x00FF)); |
| #endif |
| /* Set some defaults */ |
| SPI_setSCLKFreq(VMB2_SCLK_1000); |
| PCM_setPCLKFreq(VMB2_PCLK_2048); |
| |
| #ifndef SILABS_NO_PROMPTS |
| printf("\nChange Default VMB2 Settings (y/n) ?? ->"); |
| FLUSH_STDOUT; |
| fgets(resp, 3, stdin); |
| |
| if(toupper((int)*resp) == 'Y') |
| { |
| /* Releases prior to firmware rev 1.3 did not support ISI */ |
| if( firmware_version >= 0x0103) |
| { |
| printf("\nDo you want to use SPI or ISI (s/i) ?? ->"); |
| FLUSH_STDOUT; |
| fgets(resp, 3, stdin); |
| printf("\n\n"); |
| fflush(stdout); |
| } |
| else |
| { |
| *resp = 'S'; |
| } |
| |
| if(toupper((int)*resp) == 'S') |
| { |
| printf("\n\n"); |
| printf("-----------------\n"); |
| printf("Select SCLK Freq\n"); |
| printf("-----------------\n"); |
| printf("0. Default \n"); |
| printf("1. 1MHz\n"); |
| printf("2. 2MHz\n"); |
| printf("3. 4MHz\n"); |
| printf("4. 8MHz\n"); |
| printf("5. 12MHz\n"); |
| printf("-----------------\n"); |
| printf("Selection -> "); |
| FLUSH_STDOUT; |
| |
| fgets(resp, 3, stdin); |
| printf("\n\n"); |
| fflush(stdout); |
| |
| switch(*resp) |
| { |
| case '0': |
| sclk_freq = VMB2_SCLK_1000; |
| break; |
| case '1': |
| sclk_freq = VMB2_SCLK_1000; |
| break; |
| case '2': |
| sclk_freq = VMB2_SCLK_2000; |
| break; |
| case '3': |
| sclk_freq = VMB2_SCLK_4000; |
| break; |
| case '4': |
| sclk_freq = VMB2_SCLK_8000; |
| break; |
| case '5': |
| sclk_freq = VMB2_SCLK_12000; |
| break; |
| default: |
| sclk_freq = VMB2_SCLK_1000; |
| } |
| |
| SPI_setSCLKFreq(sclk_freq); |
| } |
| else |
| { |
| SPI_SelectFormat(2); |
| printf("VMB2 now set for ISI.\n"); |
| isISI = 1; |
| } |
| |
| printf("-----------------\n"); |
| printf("Select PCM Source\n"); |
| printf("-----------------\n"); |
| printf("0. Internal \n"); |
| printf("1. External\n"); |
| printf("-----------------\n"); |
| printf("Selection -> "); |
| |
| FLUSH_STDOUT; |
| fgets(resp, 3, stdin); |
| printf("\n\n"); |
| |
| switch(*resp) |
| { |
| case '1': |
| pcm_src = 0; |
| if(isISI == 1) |
| { |
| printf("NOTE: ISI needs to have a 2.048 MHz PCLK\n"); |
| } |
| break; |
| |
| default: |
| pcm_src = 1; /* internal */ |
| break; |
| } |
| |
| /* Setup hardware */ |
| PCM_setSource(pcm_src); |
| |
| if( (pcm_src == 1) && (isISI == 0)) |
| { |
| printf("\n\n"); |
| printf("-----------------\n"); |
| printf("Select PCLK Freq\n"); |
| printf("-----------------\n"); |
| printf("0. Default \n"); |
| printf("1. 8192kHz\n"); |
| printf("2. 4096kHz\n"); |
| printf("3. 2048kHz\n"); |
| printf("4. 1024kHz\n"); |
| printf("5. 512kHz\n"); |
| printf("6. 1536kHz\n"); |
| printf("7. 768kHz\n"); |
| printf("8. 1544kHz\n"); |
| printf("-----------------\n"); |
| printf("Selection -> "); |
| |
| FLUSH_STDOUT; |
| |
| fgets(resp, 3, stdin); |
| m = atoi(resp); |
| printf("\n\n"); |
| fflush(stdout); |
| |
| if((m < 1)||(m > 8)) |
| { |
| pclk_freq = 3; |
| } |
| else |
| { |
| pclk_freq = m-1; |
| } |
| |
| printf("-----------------\n"); |
| printf("Select Framesync type\n"); |
| printf("-----------------\n"); |
| printf ("0. FSYNC Short\n"); |
| printf ("1. FSYNC Long\n"); |
| printf("-----------------\n"); |
| printf("Selection -> "); |
| |
| FLUSH_STDOUT; |
| |
| fgets(resp, 3, stdin); |
| m = atoi(resp); |
| printf("\n\n"); |
| fflush(stdout); |
| |
| if(m == 1) |
| { |
| PCM_setFsyncType(VMB2_FSYNC_LONG); |
| } |
| else |
| { |
| PCM_setFsyncType(VMB2_FSYNC_SHORT); |
| } |
| PCM_setPCLKFreq(pclk_freq); |
| |
| |
| /* PCM Cross-connect (loopback), requires firmware version 1.7 or higher */ |
| /* Allowed for Single channel devices, but will appear to do nothing */ |
| if( firmware_version >= 0x0107) |
| { |
| printf("-----------------\n"); |
| printf("Select PCM Cross-connect configuration\n"); |
| printf("-----------------\n"); |
| printf ("0. Loopback Enabled\n"); |
| printf ("1. Loopback Disabled\n"); |
| printf("-----------------\n"); |
| printf("Selection -> "); |
| FLUSH_STDOUT; |
| fgets(resp, 3, stdin); |
| m = atoi(resp); |
| printf("\n\n"); |
| fflush(stdout); |
| |
| if(m == 0) |
| { |
| PCM_enableXConnect(0x01); |
| } |
| else |
| { |
| PCM_enableXConnect(0x00); |
| } |
| } |
| } |
| } /* end of if change = 'Y' */ |
| #endif |
| } |
| |
| #elif defined(VMB1) |
| #include "DLLWrapper.h" |
| void vmbSetup(SiVoiceControlInterfaceType *ProHWIntf) |
| { |
| char resp[4]; |
| int pcm_src, m; |
| int pcm_enums[] = {128,64,32,16,8,4,512,12,24}; |
| |
| SILABS_UNREFERENCED_PARAMETER(ProHWIntf); |
| |
| #ifdef SILABS_NO_PROMPTS |
| return; |
| #endif |
| printf("Demo: VMB Connected\n"); |
| |
| printf("\nChange Default VMB Settings (y/n) ?? ->"); |
| FLUSH_STDOUT; |
| fgets(resp, 3, stdin); |
| |
| if(toupper(*resp) == 'Y') |
| { |
| printf("\n\n"); |
| printf("-----------------\n"); |
| printf("Select PCM Source\n"); |
| printf("-----------------\n"); |
| printf("0. Internal \n"); |
| printf("1. External\n"); |
| printf("-----------------\n"); |
| printf("Selection -> "); |
| |
| FLUSH_STDOUT; |
| |
| fgets(resp, 3, stdin); |
| printf("\n\n"); |
| fflush(stdout); |
| |
| switch(*resp) |
| { |
| case '0': |
| pcm_src = 1; |
| break; |
| case '1': |
| pcm_src = 0; |
| m = 3; |
| break; |
| default: |
| pcm_src = 1; /* internal */ |
| break; |
| } |
| |
| if(pcm_src == 1) |
| { |
| |
| printf("\n\n"); |
| printf("-----------------\n"); |
| printf("Select PCLK Freq\n"); |
| printf("-----------------\n"); |
| printf("0. Default \n"); |
| printf("1. 8192kHz\n"); |
| printf("2. 4096kHz\n"); |
| printf("3. 2048kHz\n"); |
| printf("4. 1024kHz\n"); |
| printf("5. 512kHz\n"); |
| printf("6. 256kHz\n"); |
| printf("7. 32768kHz\n"); |
| printf("8. 768kHz\n"); |
| printf("9. 1536kHz\n"); |
| |
| printf("-----------------\n"); |
| printf("Selection -> "); |
| |
| FLUSH_STDOUT; |
| |
| fgets(resp, 3, stdin); |
| m = atoi(resp); |
| printf("\n\n"); |
| fflush(stdout); |
| |
| if(m == 0) |
| { |
| m = 3;/* 2.048 MHz */ |
| } |
| |
| |
| if((m <0) || (m>9)) |
| { |
| printf("Invalid choice, defaulting to 2.048 Mhz\n"); |
| m = 3; |
| } |
| } |
| printf("pcm_src = %d m = %d\n", pcm_src, m); |
| setPcmSourceExp(pcm_src, pcm_enums[m-1], 0); |
| } |
| } |
| #elif defined(LINUX_SPIDEV) |
| extern uint32_t get_max_spi_speed(); |
| extern void set_spi_speed(uint32_t speed); |
| |
| void vmbSetup(SiVoiceControlInterfaceType *ProHWIntf) |
| { |
| char resp[10] = {0}; |
| uint32_t spi_speed = 2000000; //Hz... |
| |
| SILABS_UNREFERENCED_PARAMETER(ProHWIntf); |
| |
| #ifndef SILABS_NO_PROMPTS |
| printf("\nChange Default Settings (y/n) ?? ->"); |
| |
| FLUSH_STDOUT; |
| |
| fgets(resp, 9, stdin); |
| |
| #else |
| *resp = 'N'; |
| #endif |
| |
| if(toupper(resp[0]) == 'Y') |
| { |
| uint32_t max_spi_speed; |
| |
| max_spi_speed = get_max_spi_speed(); |
| printf("Enter SPI clock rate: (1000-%u) -> ", max_spi_speed); |
| |
| FLUSH_STDOUT; |
| |
| fgets(resp, 9, stdin); |
| spi_speed = strtoul(resp,NULL, 0); |
| } |
| |
| set_spi_speed(spi_speed); |
| } |
| #else |
| void vmbSetup(SiVoiceControlInterfaceType *ProHWIntf) |
| { |
| SILABS_UNREFERENCED_PARAMETER(ProHWIntf); |
| } |
| #endif /* vmbSetup() calls */ |
| |
| /************************************/ |
| void initControlInterfaces(SiVoiceControlInterfaceType *ProHWIntf, void *spiIf, |
| void *timerObj) |
| { |
| |
| SiVoice_setControlInterfaceCtrlObj (ProHWIntf, spiIf); |
| SiVoice_setControlInterfaceTimerObj (ProHWIntf, timerObj); |
| SiVoice_setControlInterfaceSemaphore (ProHWIntf, NULL); |
| |
| #ifndef PROSLIC_LINUX_KERNEL |
| SiVoice_setControlInterfaceReset (ProHWIntf, ctrl_ResetWrapper); |
| |
| SiVoice_setControlInterfaceWriteRegister (ProHWIntf, ctrl_WriteRegisterWrapper); |
| SiVoice_setControlInterfaceReadRegister (ProHWIntf, ctrl_ReadRegisterWrapper); |
| SiVoice_setControlInterfaceWriteRAM (ProHWIntf, ctrl_WriteRAMWrapper); |
| SiVoice_setControlInterfaceReadRAM (ProHWIntf, ctrl_ReadRAMWrapper); |
| |
| SiVoice_setControlInterfaceDelay (ProHWIntf, time_DelayWrapper); |
| SiVoice_setControlInterfaceTimeElapsed (ProHWIntf, time_TimeElapsedWrapper); |
| SiVoice_setControlInterfaceGetTime (ProHWIntf, time_GetTimeWrapper); |
| #else |
| /* The kernel code uses an array of functions that are exported to the global symbol table, |
| * therefore, we'll access them this way to initialize the control interface. |
| */ |
| SiVoice_setControlInterfaceReset (ProHWIntf, proslic_spi_if.reset); |
| |
| SiVoice_setControlInterfaceWriteRegister (ProHWIntf, proslic_spi_if.write_reg); |
| SiVoice_setControlInterfaceReadRegister (ProHWIntf, proslic_spi_if.read_reg); |
| SiVoice_setControlInterfaceWriteRAM (ProHWIntf, proslic_spi_if.write_ram); |
| SiVoice_setControlInterfaceReadRAM (ProHWIntf, proslic_spi_if.read_ram); |
| |
| SiVoice_setControlInterfaceDelay (ProHWIntf, proslic_timer_if.slic_delay); |
| SiVoice_setControlInterfaceTimeElapsed (ProHWIntf, |
| proslic_timer_if.elapsed_time); |
| SiVoice_setControlInterfaceGetTime (ProHWIntf, proslic_timer_if.get_time); |
| |
| #endif |
| |
| #ifndef PROSLIC_LINUX_KERNEL |
| ctrl_ResetWrapper(spiIf, |
| 1); /* Since we may be changing clocks in vmbSetup() , keep the part in reset */ |
| |
| /* |
| ** Configuration of SPI and PCM internal/external |
| */ |
| vmbSetup(ProHWIntf); |
| |
| /* |
| ** Call host/system reset function (omit if ProSLIC tied to global reset) |
| */ |
| #ifndef SILABS_NO_PROMPTS |
| printf("Demo: Resetting device...\n"); |
| #endif |
| #endif |
| vmbReset(ProHWIntf); |
| } |
| |
| /************************************/ |
| void destroyControlInterfaces(SiVoiceControlInterfaceType *ProHWIntf) |
| { |
| #if defined(VMB2) || defined(LINUX_SPIDEV) |
| SPI_Close(ProHWIntf->hCtrl); |
| #else |
| SILABS_UNREFERENCED_PARAMETER(ProHWIntf); |
| #endif |
| |
| } |
| |