📄 ssitest.c
字号:
/*
* Copyright (c) 1995-1999 by TriMedia Technologies.
*
* +------------------------------------------------------------------+
* | This software is furnished under a license and may only be used |
* | and copied in accordance with the terms and conditions of such |
* | a license and with the inclusion of this copyright notice. This |
* | software or any other copies of this software may not be provided|
* | or otherwise made available to any other person. The ownership |
* | and title of this software is not transferred. |
* | |
* | The information in this software is subject to change without |
* | any prior notice and should not be construed as a commitment by |
* | TriMedia Technologies. |
* | |
* | this code and information is provided "as is" without any |
* | warranty of any kind, either expressed or implied, including but |
* | not limited to the implied warranties of merchantability and/or |
* | fitness for any particular purpose. |
* +------------------------------------------------------------------+
*
* Module name : ssitest.c 1.31
*
* Last update : 17:32:34 - 00/11/09
*
* Description:
*
* The SSI test demonstrates the use of the TM SSI to control
* the Thomson ST7545 analog front end. The SSI itself is fairly basic,
* but the 7545 is rather complex. This demo glosses over the complexities
* of the 7545: A canned initialization sequence is used.
* The more complete control required for a real modem would use a higher
* level interface with more details.
* We have, for instance, written a pSOS ST7545 device driver for this.
*/
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <tmlib/dprintf.h>
#include <tmlib/AppModel.h>
#include <tmlib/tmtypes.h>
#include <tm1/tmInterrupts.h>
#include <tm1/tmBoard.h>
#include <ops/custom_defs.h>
#include <tm1/tmSSI.h>
#include <tm1/tmHelp.h>
#define MAX_TX_BUF_SIZE 1024
#define DEFAULT_TX_DATA 0x3DFF
#define CONFIG_ARRAY_SIZE 256
/* ST7545 AFE config array: FSS is 5 */
static UInt16 st7545ConfigArray[] = {
0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x39A1, 0xFFFF, 0xFFFF, 0xFFFF,
0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x3BD0, 0xFFFF, 0xFFFF, 0xFFFF,
0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x3872, 0xFFFF, 0xFFFF, 0x39A1,
0x3A82, 0xFFFF, 0xFFFF, 0x3872,
0x3FFF, 0xFFFF, 0xFFFF, 0x3BC0,
0xE7FF, 0xFFFF, 0x0000, 0x0000,
0xA7FF, 0x3AD0, 0x0000, 0x0000,
0xA7FF, 0x0000, 0x0000, 0x3998,
0xA7FF, 0x0000, 0x0000, 0x0000,
0xA7FF, 0x0000, 0x3998, 0x0000,
0xA7FF, 0x0000, 0xB510, 0x4DB8,
0xA7FF, 0x0460, 0xCBF8, 0xA000,
0xA7FF, 0xB638, 0x4690, 0x1248,
0xA7FF, 0xCE80, 0xA000, 0xB738,
0xA7FF, 0x41E0, 0x05E8, 0xD8A8,
0xA7FF, 0xA000, 0xB390, 0x5580,
0xA7FF, 0x0268, 0x2078, 0xA000,
0xA7FF, 0x0000, 0x0000, 0x0050,
0xEFFF, 0xFFFF, 0x0000, 0x0000,
0xAFFF, 0x38B0, 0x0000, 0x0000,
0xAFFF, 0x0000, 0x0000, 0x3998,
0xAFFF, 0x0000, 0x0000, 0xB5A8,
0xAFFF, 0x4780, 0x0290, 0xC000,
0xAFFF, 0xA000, 0xBF18, 0x41C0,
0xAFFF, 0x18B0, 0x2078, 0xA000,
0xAFFF, 0xB348, 0x5610, 0x0430,
0xAFFF, 0xD8A8, 0xA000, 0xB460,
0xAFFF, 0x4F08, 0x0980, 0xCE80,
0xAFFF, 0xA000, 0xB6F8, 0x4228,
0xAFFF, 0x1DA0, 0xCBF8, 0xA000,
0xAFFF, 0x0000, 0x0000, 0x0048,
0xF7FF, 0xFFFF, 0x0000, 0x0000,
0xB7FF, 0x3AD0, 0x0000, 0x0000,
0xB7FF, 0x0000, 0x0000, 0x3998,
0xB7FF, 0x0000, 0x0000, 0x0000,
0xB7FF, 0x0000, 0x3998, 0x0000,
0xB7FF, 0x0000, 0xB510, 0x4DB8,
0xB7FF, 0x0460, 0xCBF8, 0xA000,
0xB7FF, 0xB638, 0x4690, 0x1248,
0xB7FF, 0xCE80, 0xA000, 0xB738,
0xB7FF, 0x41E0, 0x05E8, 0xD8A8,
0xB7FF, 0xA000, 0xB390, 0x5580,
0xB7FF, 0x0268, 0x2078, 0xA000,
0xB7FF, 0x0000, 0x0000, 0x0050,
0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x3FFF, 0x0000, 0xFFFF, 0xFFFF, /* repeating waveform starts here */
0x3FFF, 0x0000, 0xFFFF, 0xFFFF,
0x3FFF, 0x2000, 0xFFFF, 0xFFFF,
0x3FFF, 0x4000, 0xFFFF, 0xFFFF,
0x3FFF, 0x6000, 0xFFFF, 0xFFFF,
0x3FFF, 0x8000, 0xFFFF, 0xFFFF,
0x3FFF, 0xA000, 0xFFFF, 0xFFFF,
0x3FFF, 0xC000, 0xFFFF, 0xFFFF,
0x3FFF, 0xF000, 0xFFFF, 0xFFFF,
};
static void ssiTestISR(void);
static void st7545ConfigFunc(void);
static UInt16 *TxBuffer, *RxBuffer;
static UInt TxPtr, RxPtr;
static UInt TxBufSize, RxBufSize;
static void (*initFunc) (void); /* Used in the ISR */
volatile static Bool InitFlag = True;
int
main(int argc, char **argv)
{
tmLibdevErr_t retval;
Int ssiInstance;
float gain;
int i, freq, sRate;
FILE *fp;
char ins[80];
pssiCapabilities_t pssiCap;
ssiInstanceSetup_t ssiSetup;
ssiFrameSetup_t ssiFrame;
Bool offHook = False;
DPsize(1024 * 1024);
DP(("Entering SSI device library test program, V2.03\n\n"));
printf("\nTrimedia SSI device library test program, V2.03 \n");
ssiGetCapabilities(&pssiCap);
printf("SSI library version %d.%d.%d\n",
pssiCap->version.majorVersion,
pssiCap->version.minorVersion,
pssiCap->version.buildVersion);
printf("SSI using %s AFE and support is enabled for ", pssiCap->afeName);
if (pssiCap->connectionFlags & sacConnectToPOTS)
printf("Plain Old Telepone Service");
if (pssiCap->connectionFlags & sacConnectToISDN)
printf("ISDN Service");
if (pssiCap->connectionFlags & sacConnectToOTHER)
printf("Other Service");
printf("\n\n");
DP(("Running on ")); tmHelpReportSystem(Null);
printf("Running on "); tmHelpReportSystem(stdout);
printf("\nThis program tests the TM SSI library with the ST7545 AFE.\n");
printf("The telecom connection should be plugged into a phone line "
"for these tests.\n");
/* Setup the Tx buffer */
TxBuffer = (UInt16 *) malloc(MAX_TX_BUF_SIZE * sizeof (UInt16));
if (!TxBuffer) {
printf("failed to malloc Tx Buffer\n");
return (1);
}
/* Initialize the TxBuffer with a sine wave */
freq = 800;
gain = 0.707;
sRate = 9600;
TxBufSize = sRate / freq; /* number of 16 bit words */
for (i = 0; i < TxBufSize; i++) {
float val, arg;
Int16 ival;
arg = 2.0 * 3.1415927 * (float) i / (float) TxBufSize;
val = gain * 32000.0 * sin(arg);
ival = (Int16) val;
TxBuffer[i] = (UInt16) ival;
}
for (; i < MAX_TX_BUF_SIZE; i++)
TxBuffer[i] = 0;
/* Setup the Rx buffer */
RxBufSize = 20 * 9600; /* 20 seconds at 9600hz */
RxBuffer = (UInt16 *) malloc(RxBufSize * sizeof (UInt16));
if (!RxBuffer) {
printf("failed to malloc Rx Buffer\n");
return (2);
}
RxPtr = 0;
for (i = 0; i < RxBufSize; i++)
RxBuffer[i] = 0;
/* open the interface */
retval = ssiOpen(&ssiInstance);
if (retval)
printf("ssiOpen failed with %x\n", retval);
/* setup the SSI Control Block, and call open */
ssiSetup.configBuffer = Null; /* not used */
ssiSetup.configBufferLength = 0; /* not used */
ssiSetup.interruptPriority = intPRIO_6; /* SSI needs high priority */
ssiSetup.isr = ssiTestISR;
ssiSetup.interruptLevelSelect = 12; /* ils */
ssiSetup.txInterruptEnable = True;
ssiSetup.rxInterruptEnable = False;
ssiSetup.changeDetectorInterruptEnable = False;
retval = ssiInstanceSetup(ssiInstance, &ssiSetup);
if (retval) {
printf("SSI Test: Initial ssiSetup failed with "
"error code 0x%x\n", retval);
return (retval);
}
ssiFrame.validSlotsPerFrame = 4; /* vss: must be even! */
ssiFrame.slotsPerFrame = 5; /* fss */
ssiSetFraming(ssiInstance, &ssiFrame);
/*
* We use a canned array to intitialize the 7545. A 7545 library is
* available...
*/
TxPtr = 0;
initFunc = st7545ConfigFunc;
InitFlag = True;
initFunc(); /* primes the pipeline */
ssiStart(ssiInstance);
for (i = 0; InitFlag; i++) { /* the ISR sets initFunc to NULL when
* init is completed
*/
microsleep(5);
if (i > 10000 / 5) { /* 10 ms */
printf("SSI Init timeout error\n");
return (1);
}
}
printf("ST7545 init completed after %d microseconds. \n", i * 5);
/* take the phone off hook */
ssiOffHook(ssiInstance);
offHook = True;
printf("\nA sine wave at %d Hz, %2.1f db is being generated. \n",
freq, 20 * log10(gain));
while (1) {
char ic;
int count;
if (offHook)
printf("h to hangup. s for sine, a for silence, q to exit:\n");
else
printf("h to take phone off hook. s for sine, a "
"for silence, q to exit:\n");
gets(ins);
switch (*ins) {
case 'h':
if (offHook) {
ssiOnHook(ssiInstance);
offHook = False;
break;
}
ssiOffHook(ssiInstance);
offHook = True;
break;
case 's':
count = sscanf(ins, "%c %d %f", &ic, &freq, &gain);
if (count == 1) {
printf("Enter the sinewave frequency in Hertz:\n");
freq = 800;
gets(ins);
sscanf(ins, "%d", &freq);
gain = 0.707;
printf("Enter the amplitude of the sinewave "
"(1.0 is full scale)\n");
gets(ins);
sscanf(ins, "%f", &gain);
}
printf("A sine wave at %d Hz, %2.1f db down (%f) is "
"being generated. \n", freq, 20.0 * log10(gain), gain);
TxBufSize = sRate / freq; /* number of 16 bit
* words */
if (TxBufSize > MAX_TX_BUF_SIZE)
TxBufSize = MAX_TX_BUF_SIZE;
/*
* create a buffer full of sine waves to test output.
* The default Tx Data was filled in by the ssiOpen()
*/
for (i = 0; i < TxBufSize; i++) {
float val, arg;
Int16 ival;
arg = 2.0 * 3.1415927 * (float) i / (float) TxBufSize;
val = gain * 32000.0 * sin(arg);
ival = (Int16) val;
TxBuffer[i] = (UInt16) ival;
}
break;
case 'a':
for (i = 0; i < TxBufSize; i++)
TxBuffer[i] = 0;
printf("SSI Test paused\n");
break;
case 'q':
ssiOnHook(ssiInstance);
ssiClose(ssiInstance);
printf("Writing 16 bit data captured from SSI to ssiin.bin:\n");
fp = fopen("ssiin.bin", "wb");
if (!fp) {
printf("failed to open ssiin.bin for writing\n");
return (1);
}
fwrite(RxBuffer, RxBufSize, sizeof (UInt16), fp);
fclose(fp);
printf("Recorded 16 bit data from input written to file. \n");
free(RxBuffer);
free(TxBuffer);
return 0;
}
}
}
static Int lastCalled = 0;
static UInt isrCount = 0;
static void
_ssiTestISR(void)
{
int now, diff;
UInt32 csr;
++isrCount;
now = cycles();
diff = now - lastCalled;
if ((lastCalled != 0) && (diff > 83333))
DP(("\nssiTestISR %d: WARNING: Possible latency overrun. "
"Cycle count %d \n", isrCount, diff));
/* 83333 = 32/4 * 100MHz/9600Hz */
lastCalled = now;
csr = MMIO(SSI_CSR); /* only need to read once */
if (ssiFES(csr)) { /* Framing error. */
ssiAckCFES();
DP(("FE "));
}
if (ssiCDS(csr)) { /* Change Dectect (Ring). */
ssiAckCCDS();
DP(("CD "));
}
if (ssiTUE(csr)) { /* Transmit Underrun Error */
ssiAckCTUE(); /* Clear the interrupt. */
DP(("TU "));
}
if (ssiROE(csr)) { /* Receive overrun Error */
ssiAckCROE(); /* Clear the interrupt. */
DP(("RO "));
}
if (InitFlag)
initFunc();
else {
while (ssiGetWAW() > 1) {
MMIO(SSI_TXDR) = SSI_WordSwap(DEFAULT_TX_DATA, TxBuffer[TxPtr]);
TxPtr = (TxPtr + 1) % TxBufSize;
MMIO(SSI_TXDR) = SSI_WordSwap(DEFAULT_TX_DATA, DEFAULT_TX_DATA);
}
}
while (ssiGetWAR() > 1) {
int a;
/* it is the access to SSI_RXACK which actually increments the FIFO pointer.
* This is done so that a speculative load from SSI_RXDR will not lose
* data. Here, I need the first 32 bits (read in a), but not the second.
* So I read RXDR once, and ack twice.
*/
a = MMIO(SSI_RXDR);
MMIO(SSI_RXACK) = 1; /* Signal the read. */
MMIO(SSI_RXACK) = 1; /* Signal the read. */
/* store the low word in capture buffer */
RxBuffer[RxPtr++] = 0xFFFF & a;
RxPtr %= RxBufSize;
}
}
static void
ssiTestISR(void)
{
#pragma TCS_handler
AppModel_suspend_scheduling();
AppModel_run_on_sstack((AppModel_Fun)_ssiTestISR, Null);
AppModel_resume_scheduling();
}
static void
st7545ConfigFunc(void)
{
while (ssiGetWAW() > 1) {
MMIO(SSI_TXDR) = SSI_WordSwap(st7545ConfigArray[TxPtr++],
st7545ConfigArray[TxPtr++]);
MMIO(SSI_TXDR) = SSI_WordSwap(st7545ConfigArray[TxPtr++],
st7545ConfigArray[TxPtr++]);
if (TxPtr > CONFIG_ARRAY_SIZE) {
InitFlag = False;
TxPtr = 0;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -