blob: e3a9339572e7c584697850543b876e0d9ac283dc [file] [log] [blame]
/******************************************************************************
* 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
}