ggg
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hi,
I am writing UPP driver and application for C6748.
I am not getting the required event and interrupt after the control register configurations
If anyone has any inputs pls share.
Thanks
Veena
/*Control Register with Duplex Mode 1 Channel A Transmitter and Channel B Receiver*/
/* Single data rate , Datawidth = 16,DataPacking = No data Packing,Justification =3h reserved*/
#define UPP_UPCTL_VALUE 0x62630007
/* UPICR Channel A = TX, Channel B = Rx ,ClkDivA =1, ClkDivB =1, TRISA = HighImpedeance,TRISB = HighImpedeance ,ENA = 0,ENB = 1 */
/*CLKIVA =0(Not inverted),CLKINVB = 0,WAITA =1 ,WAITB =0,WAITPOLA = 0,WAITPOLA = 0,STARTA = 0,STARTB=1,STARTPOLA =0,STARTPOLB = 0.*/
#define UPP_UPICR_VALUE 0x30182020
/* UPTCR ChanA Tx size = 256bytes ReadSize =256bytes */
#define UPP_UPTCR_VALUE 0x03030303
/* UPIVR Both chan A and Chan B will be FFFFFFF when idle. */
#define UPP_UPIVR_VALUE 0xFFFFFFFF
#define UPP_UPIES_VALUE 0x00000EFF
#define UPP_UPPCR_VALUE 0x00000007
#define UPP_EVENT 94
Code:
m_pUppRegs = (CSL_UppRegsOvly)CSL_UPP_0_REGS;
m_pUppRegs ->UPCTL |= UPP_UPCTL_VALUE;
m_pUppRegs ->UPICR |= UPP_UPICR_VALUE;
m_pUppRegs ->UPIVR |= UPP_UPIVR_VALUE;
m_pUppRegs ->UPTCR |= UPP_UPTCR_VALUE;
m_pUppRegs ->UPIES |= UPP_UPIES_VALUE;
//Register the ISR
/* map Upp event to cpu int5
*/
CSL_FINS(g_pCSystemHandler->m_pIntcRegs->INTMUX1,
DSPINTC_INTMUX1_INTSEL5,
UPP_EVENT);
/* set ISTP to point to the vector table address */
//ISTP = (unsigned int)InterruptVectorTable;
/* clear all interrupts, bits 4 thru 15 */
ICR = 0xFFF0;
/* enable the bits for non maskable interrupt and */
IER = 0xF2;
/* enable interrupts, set GIE bit */
_enable_interrupts();
Veena,
Are you writing your own driver for uPP, or using one of the drivers provided by TI? There are two uPP drivers that are already available:
I recommend looking at these drivers if you haven't already done so. Even if you want to use your own driver, the first driver I linked to above includes a very simple test application that could be useful for comparing with your own code. That could help you figure out what is going wrong.
Also, I recommend reviewing section 2.6 of the uPP user guide. This section explains the step-by-step process that you should follow to initialize and configure the uPP peripheral. I see some (but not all) of those steps reflected in your current source code.
Hope this helps.
Dear Joe,
Thanks a lot. It was V helpful.
I have gone through the step by step proceesure in the user guide and had coded the same.
the BIOSPSP has application which is polling based and not interrupt based.
the BIOS_Driver is the one that can solve my purpose. I would appreciate if you could provide me something on the application for the CSL Driver( upp_bios_drv.pjt) to use the functions is the project.
regards
Veena
Dear Joe,
I have tried using BIOS Driver.
When I create task using
// create task
demo_tsk = TSK_create(LOCAL_upp_demo,
NULL, 0);
It sometiemes creates the task sometimes it fails.
Could you provide me some inputs on this?
my .tcf file is below
utils.loadPlatform("ti.platforms.evm6748"); /* The following DSP/BIOS Features are enabled. */ bios.enableRealTimeAnalysis(prog); bios.enableRtdx(prog); bios.enableTskManager(prog); bios.MEM.STACKSIZE = 0x1000; bios.MEM.ARGSSEG = prog.get("DDR"); bios.MEM.STACKSEG = prog.get("DDR"); bios.MEM.GBLINITSEG = prog.get("DDR"); bios.MEM.TRCDATASEG = prog.get("DDR"); bios.MEM.SYSDATASEG = prog.get("DDR"); bios.MEM.OBJSEG = prog.get("DDR"); bios.MEM.BIOSSEG = prog.get("DDR"); bios.MEM.SYSINITSEG = prog.get("DDR"); bios.MEM.HWISEG = prog.get("DDR"); bios.MEM.HWIVECSEG = prog.get("DDR"); bios.MEM.RTDXTEXTSEG = prog.get("DDR"); bios.MEM.TEXTSEG = prog.get("DDR"); bios.MEM.SWITCHSEG = prog.get("DDR"); bios.MEM.BSSSEG = prog.get("DDR"); bios.MEM.FARSEG = prog.get("DDR"); bios.MEM.CINITSEG = prog.get("DDR"); bios.MEM.PINITSEG = prog.get("DDR"); bios.MEM.CONSTSEG = prog.get("DDR"); bios.MEM.DATASEG = prog.get("DDR"); bios.MEM.CIOSEG = prog.get("DDR"); bios.MEM.ENABLELOADADDR = 1; bios.MEM.LOADBIOSSEG = prog.get("DDR"); bios.MEM.LOADSYSINITSEG = prog.get("DDR"); bios.MEM.LOADGBLINITSEG = prog.get("DDR"); bios.MEM.LOADTRCDATASEG = prog.get("DDR"); bios.MEM.LOADTEXTSEG = prog.get("DDR"); bios.MEM.LOADSWITCHSEG = prog.get("DDR"); bios.MEM.LOADCINITSEG = prog.get("DDR"); bios.MEM.LOADPINITSEG = prog.get("DDR"); bios.MEM.LOADCONSTSEG = prog.get("DDR"); bios.MEM.LOADHWISEG = prog.get("DDR"); bios.MEM.LOADHWIVECSEG = prog.get("DDR"); bios.MEM.LOADRTDXTEXTSEG = prog.get("DDR"); bios.MEM.NOMEMORYHEAPS = 0; bios.MEM.instance("DDR").createHeap = 1; bios.MEM.instance("DDR").heapSize = 0x00100000; bios.MEM.BIOSOBJSEG = prog.get("DDR"); bios.MEM.MALLOCSEG = prog.get("DDR"); bios.LOG.create("trace"); bios.LOG.instance("trace").bufLen = 1024; bios.TSK.STACKSEG = prog.get("DDR"); bios.UDEV.create("UPP"); bios.UDEV.instance("UPP").fxnTableType = "IOM_Fxns"; bios.UDEV.instance("UPP").comment = "uPP IOM mini driver"; bios.UDEV.instance("UPP").initFxn = prog.extern("UPP_INIT"); bios.UDEV.instance("UPP").fxnTable = prog.extern("UPP_FXN_TABLE"); bios.UDEV.instance("UPP").params = prog.extern("UPP_DEV_CONFIG"); bios.ECM.ENABLE = 1; bios.HWI.instance("HWI_INT7").interruptSelectNumber = 2; // !GRAPHICAL_CONFIG_TOOL_SCRIPT_INSERT_POINT! /* Create application task */ prog.gen();
Also I wanted to us the PSP driver.
the packag has a min with initializations only. Any application suitable could also be of help
Regards
Veena
Veena,
I don't see anything wrong with your TCF file. Let me make sure I understand what's happening. When you run your application, the call to TSK_create() sometimes fails by returning a NULL (0) value. However, this doesn't happen every time you run the application. Is this correct? Is there some pattern you can notice (i.e. TSK_create works the first time you load and run your application but not the second, or something like that)?
It's unusual for TSK_create() to be inconsistent in this way. I definitely want to help you solve this problem.
Veena,
When you attempt to re-run the program, do you reload it or merely reset the PC to the program entrypoint? It sounds to me like DSP/BIOS is not getting properly reset/re-initialized between one run and the next. If you could, please list the steps (i.e. menu commands in CCS) that you're using to restart your application.
Veena,
Take a look at the "test" application that comes with the driver; this should give you the basic idea how to setup the driver. To configure uPP in duplex 1 mode, all you need to do is configure the driver to use both channels, with channel A transmitting and channel B receiving. The driver should then take care of all the uPP register configuration.
Your code to setup the driver params struct may look something like this:
upp_UserParams upp_setup = UPP_USERPARAMS;
// common settings
upp_setup.params.channels = 2;
// settings for channel A
upp_setup.params.A.direction = upp_dir_xmit;
upp_setup.params.A.clock_div = 7;
upp_setup.params.A.idle_value = 0xAAAA;
// settings for channel B
upp_setup.params.B.direction = upp_dir_rcv;
upp_setup.params.B.clock_div = 7;
upp_setup.params.B.idle_value = 0xBBBB;
// not shown: setup callback functions for various interrupt events
Hope this helps.
Hi Joe, I have configured the driver in Duplex 1 Without loopback.
I am expecting interrupt to be genrated as soon as there is some data in buffer A.
But I do not get any interrupt.
Can u suggest any better method?
Please fine the changes in red
// application include file
#include "upp_drv_testcfg.h"
#include <upp_md.h>
#include <ti\pspiom\cslr\cslr_upp.h>
#include "cslr_gpio.h"
extern "C" {
#include "evmc6748.h"
#include "evmc6748_timer.h"
}
// PSC registers (lifted from GEL)
#define PSC1_BASE 0x01E27000
#define PSC1_MDCTL (PSC1_BASE+0xA00)
#define PSC1_MDSTAT (PSC1_BASE+0x800)
#define PSC1_PTCMD *(unsigned int*) (PSC1_BASE + 0x120)
#define PSC1_PTSTAT *(unsigned int*) (PSC1_BASE + 0x128)
// kick and pinmux registers (lifted from GEL)
#define SYS_BASE 0x01C14000
#define KICK0R *(unsigned int*)(SYS_BASE + 0x038)
#define KICK1R *(unsigned int*)(SYS_BASE + 0x03C)
#define PINMUX0 *(unsigned int*)(SYS_BASE + 0x120)
#define PINMUX1 *(unsigned int*)(SYS_BASE + 0x124)
#define PINMUX2 *(unsigned int*)(SYS_BASE + 0x128)
#define PINMUX3 *(unsigned int*)(SYS_BASE + 0x12C)
#define PINMUX4 *(unsigned int*)(SYS_BASE + 0x130)
#define PINMUX5 *(unsigned int*)(SYS_BASE + 0x134)
#define PINMUX6 *(unsigned int*)(SYS_BASE + 0x138)
#define PINMUX7 *(unsigned int*)(SYS_BASE + 0x13C)
#define PINMUX8 *(unsigned int*)(SYS_BASE + 0x140)
#define PINMUX9 *(unsigned int*)(SYS_BASE + 0x144)
#define PINMUX10 *(unsigned int*)(SYS_BASE + 0x148)
#define PINMUX11 *(unsigned int*)(SYS_BASE + 0x14C)
#define PINMUX12 *(unsigned int*)(SYS_BASE + 0x150)
#define PINMUX13 *(unsigned int*)(SYS_BASE + 0x154)
#define PINMUX14 *(unsigned int*)(SYS_BASE + 0x158)
#define PINMUX15 *(unsigned int*)(SYS_BASE + 0x15C)
#define PINMUX16 *(unsigned int*)(SYS_BASE + 0x160)
#define PINMUX17 *(unsigned int*)(SYS_BASE + 0x164)
#define PINMUX18 *(unsigned int*)(SYS_BASE + 0x168)
#define PINMUX19 *(unsigned int*)(SYS_BASE + 0x16C)
CSL_GpioRegsOvly m_pGPIORegs ;
CSL_UppRegsOvly UppRegsOvly;
// static init struct for uPP driver (use defaults)
const upp_StaticConfig UPP_DEV_CONFIG = UPP_STATICCONFIG;
// local typedef
typedef enum LOCAL_mode {
LOCAL_mode_AB_dlb,
LOCAL_mode_BA_dlb,
LOCAL_mode_A_transmit,
LOCAL_mode_A_receive,
LOCAL_mode_B_receive
} LOCAL_mode;
// configuration macros
#define upp_line_size (1024)
#define upp_line_count (2)
#define upp_line_offset (upp_line_size)
#define upp_clock_div 0//(7)
#define upp_demo_mode (LOCAL_mode_AB_dlb)
// global variables
volatile int upp_interrupt_count = 0;
volatile int upp_error_count = 0;
LOCAL_mode upp_mode = upp_demo_mode;
Uint8 upp_buffer_a[upp_line_size];// * upp_line_count];
Uint8 upp_buffer_b[upp_line_size];// * upp_line_count];
// local functions
static int LOCAL_upp_demo();
static void LOCAL_upp_config(upp_UserParams *upp_setup);
static void LOCAL_upp_config_xfers(upp_Transfer *xfer_a, upp_Transfer *xfer_b);
static void LOCAL_upp_complete_cb(upp_Transfer *xfer, Uint32 upp_isr_bit);
static void LOCAL_upp_error_cb(upp_Transfer *xfer, Uint32 upp_isr_bit);
static void LOCAL_kick_unlock();
static void LOCAL_PSC1_LPSC_enable(unsigned int PD, unsigned int LPSC_num);
static void LOCAL_apply_upp_pinmux();
Fxn CUppDriver::UppDeviceInit()
{
//return ulnStatus;
TSK_Handle demo_tsk;
// system initialization (doesn't rely on GEL)
printf("UPP Test start-----------\n");
// unlock device
KICK_Unlock();
// turn on uPP LPSC
PSC1_LPSC_enable(0, 19);
// enable uPP pinmux - enable all uPP pin functions
Apply_Upp_PINMUX();
// enable HWI7 (tied to ECM block 2; see TCF)
C64_enableIER(1 << 9);
UppTransferBegin();
}
// LOCAL_upp_demo is the primary DSP/BIOS TSK function. It is called
// after main
static int CUppDriver::UppTransferBegin()
{
upp_UserParams upp_setup;
upp_Transfer upp_xfer_a, upp_xfer_b;
GIO_Handle upph;
int i, status, target_int_count;
size_t Psize = 16;
// initialize uPP buffers
for (i = 0; i < sizeof(upp_buffer_a); i++) //sizeof(upp_buffer_a) / 4
{
// put data in transmit buffer and clear receive buffer
if (upp_mode == LOCAL_mode_BA_dlb)
{
((Uint32 *)upp_buffer_b)[i] = 0xBBBB5555;
((Uint32 *)upp_buffer_a)[i] = 0x00000000;
}
else
{
((Uint32 *)upp_buffer_a)[i] = i;//0xAAAA5555;
((Uint32 *)upp_buffer_b)[i] = 0x00000000;
}
if(upp_mode==LOCAL_mode_A_transmit)
{
((Uint32 *)upp_buffer_b)[i] = 0xAAAA;
}
if(upp_mode==LOCAL_mode_B_receive)
{
((Uint32 *)upp_buffer_b)[i] = 0xAAAA;
}
}
upp_setup.params.A.width = 16;
// specify driver parameters
LOCAL_upp_config(&upp_setup);
// create driver handle
upph = GIO_create("/UPP", IOM_INOUT, &status, &upp_setup, NULL);
if (upph == NULL)
{
LOG_printf (&trace, "GIO_create failed");
//return -1;
}
// program transfer(s)
LOCAL_upp_config_xfers(&upp_xfer_a, &upp_xfer_b);
LOG_printf (&trace, "Programming uPP transfers...");
// note: begin read first if in DLB mode
switch (upp_mode)
{
case LOCAL_mode_AB_dlb:
status = GIO_read(upph, &upp_xfer_b, NULL);
status |= GIO_write(upph, &upp_xfer_a, NULL);
break;
case LOCAL_mode_BA_dlb:
status = GIO_read(upph, &upp_xfer_a, NULL);
status |= GIO_write(upph, &upp_xfer_b, NULL);
break;
case LOCAL_mode_A_transmit:
status = GIO_write(upph, &upp_xfer_a, NULL);
break;
case LOCAL_mode_A_receive:
status = GIO_read(upph, &upp_xfer_a, NULL);
break;
case LOCAL_mode_B_receive:
status = GIO_read(upph, &upp_xfer_b, NULL);
break;
default:
// unrecognized mode (shouldn't happen)
status = -1;
break;
}
// catch GIO_submit errors)
if (status < 0)
{
LOG_printf(&trace, "Error programming uPP transfers.\n");
upp_error_count++;
}
// wait until transfer(s) complete
target_int_count = (upp_mode == LOCAL_mode_AB_dlb ||
upp_mode == LOCAL_mode_BA_dlb) ? 2 : 1;
while (upp_interrupt_count < target_int_count && upp_error_count == 0)
asm(" nop");
// check buffers (loopback modes only)
if (target_int_count == 2 && upp_error_count == 0)
for (i = 0; i < sizeof(upp_buffer_a); i++)
if (upp_buffer_a[i] != upp_buffer_b[i])
{
// LOG_printf(&trace, "Data mismatch in buffers.\n");
printf("Data mismatch in buffers.\n");
upp_error_count++;
}
// report test result
if (upp_error_count)
// LOG_printf(&trace, "uPP transfers completed with %u errors.\n", upp_error_count);
printf("uPP transfers completed with %u errors.\n", upp_error_count);
else
// LOG_printf (&trace, "uPP transfers complete!");
printf("uPP transfers complete!\n");
return 0;
}
static void LOCAL_upp_config(upp_UserParams *upp_setup)
{
start with default settings
*upp_setup = UPP_USERPARAMS;
upp_setup->params.B.clock_div = upp_clock_div;
upp_setup->params.B.fxn_eow = (upp_CbFxn)LOCAL_upp_complete_cb
upp_setup->params.B.en_enable = TRUE;
upp_setup->params.B.en_wait = FALSE;
upp_setup->params.B.en_start = FALSE;
upp_setup->params.A.clock_div =0;
upp_setup->params.B.clock_div =0;
upp_setup->params.A.width = 16;
upp_setup->params.B.width = 16;
switch (upp_mode)
{
case LOCAL_mode_AB_dlb:
// A-to-B loopback
upp_setup->params.A.direction = upp_dir_xmit;
upp_setup->params.B.direction = upp_dir_rcv;
upp_setup->params.channels = 2;
//upp_setup->params.special_mode = upp_digital_loopback;
UppRegsOvly->UPCTL =UppRegsOvly->UPCTL| 0x04;
UppRegsOvly->UPICR =UppRegsOvly->UPICR| 0x10;
break;
case LOCAL_mode_BA_dlb:
// B-to-A loopback
upp_setup->params.A.direction = upp_dir_rcv;
upp_setup->params.B.direction = upp_dir_xmit;
upp_setup->params.channels = 2;
upp_setup->params.special_mode = upp_digital_loopback;
break;
case LOCAL_mode_A_transmit:
// Single channel transmit
upp_setup->params.A.direction = upp_dir_xmit;
break;
case LOCAL_mode_A_receive:
// Single channel receive
upp_setup->params.A.direction = upp_dir_rcv;
break;
case LOCAL_mode_B_receive:
// Single channel receive
upp_setup->params.B.direction = upp_dir_rcv;
break;
default:
// unrecognized mode (shouldn't happen)
LOG_printf(&trace, "Warning: unrecognized uPP mode\n");
break;
}
}
// LOCAL_upp_config_xfers initializes uPP transfers according to parameters
// defined in local macros
static void LOCAL_upp_config_xfers(upp_Transfer *xfer_a, upp_Transfer *xfer_b)
{
// start with default settings
*xfer_a = UPP_TRANSFER;
*xfer_b = UPP_TRANSFER;
// apply common settings
xfer_a->windowAddr = upp_buffer_a;
xfer_a->lineCount = upp_line_count;
xfer_a->lineSize = upp_line_size;
xfer_a->lineOffset = upp_line_offset;
xfer_a->channel = upp_A;
xfer_b->windowAddr = upp_buffer_b;
xfer_b->lineCount = upp_line_count;
xfer_b->lineSize = upp_line_size;
xfer_b->lineOffset = upp_line_offset;
xfer_b->channel = upp_B;
// note: upp_xfer_b will only be used in DLB modes
}
// LOCAL_upp_complete_cb is a callback function used to track the
// completion of uPP transfers (i.e. EOW events)
static void LOCAL_upp_complete_cb(upp_Transfer *xfer, Uint32 upp_isr_bit)
{
// LOG_printf(&trace, "uPP interrupt: 0x%08X", upp_isr_bit);
printf("uPP interrupt: 0x%08X", upp_isr_bit);
upp_interrupt_count++;
// note: only uPP HWI is enabled, so increment should be atomic/safe
}
// LOCAL_upp_error_cb is a callback function used to track uPP error
// events (underrun/overflow, internal error, or DMA programming error)
static void LOCAL_upp_error_cb(upp_Transfer *xfer, Uint32 upp_isr_bit)
{
LOG_printf(&trace, "uPP error: 0x%08X", upp_isr_bit);
upp_error_count++;
// note: only uPP HWI is enabled, so increment should be atomic/safe
}
LOCAL_kick_unlock allows register access at run time. Based on code
taken from GEL file
static void LOCAL_kick_unlock()
{
// enables register access at run time
KICK0R = 0x83e70b13; // Kick0 register + data (unlock)
KICK1R = 0x95a4f1e0; // Kick1 register + data (unlock)
}
// LOCAL_PSC1_LPSC_enable powers on one LPSC. Based on code taken from
// GEL file
static void LOCAL_PSC1_LPSC_enable(unsigned int PD, unsigned int LPSC_num)
{
*(unsigned int*) (PSC1_MDCTL + 4 * LPSC_num) =
(*(unsigned int*) (PSC1_MDCTL + 4 * LPSC_num) & 0xFFFFFFE0) | 0x0003;
PSC1_PTCMD = 0x1 << PD;
// Wait for power state transition to finish
while( (PSC1_PTSTAT & (0x1 << PD)) != 0) asm(" nop");
while( (*(unsigned int*)(PSC1_MDSTAT + 4 * LPSC_num) & 0x1F) !=0x3) asm(" nop");
}
// LOCAL_apply_upp_pinmux enables all uPP pin functions. Based on code taken
// from GEL file
static void LOCAL_apply_upp_pinmux()
{
// all pins (channel A, channel B, DATA, and XDATA)
PINMUX13 = (PINMUX13 & 0x0000FFFF) | 0x44440000;
PINMUX14 = (PINMUX14 & 0x000000FF) | 0x44444400;
PINMUX15 = (PINMUX15 & 0x00000000) | 0x44444444;
PINMUX16 = (PINMUX16 & 0x00000000) | 0x44444444;
PINMUX17 = (PINMUX17 & 0x00000000) | 0x44444444;
PINMUX18 = (PINMUX18 & 0xFF000000) | 0x00444444;
}
//-------------
// END OF FILE
//-------------
// application include file
#include
"upp_drv_testcfg.h"
#include <upp_md.h>
#include
<ti\pspiom\cslr\cslr_upp.h>
#include
"cslr_gpio.h"
extern
"C"
{
#include
"evmc6748.h"
#include
"evmc6748_timer.h"
} // PSC registers (lifted from GEL) #define
PSC1_BASE 0x01E27000
#define
PSC1_MDCTL (PSC1_BASE+0xA00)
#define
PSC1_MDSTAT (PSC1_BASE+0x800)
#define
PSC1_PTCMD *(unsigned int
*) (PSC1_BASE + 0x120)
#define
PSC1_PTSTAT *(unsigned int
*) (PSC1_BASE + 0x128)
// kick and pinmux registers (lifted from GEL) #define
SYS_BASE 0x01C14000
#define
KICK0R *(unsigned int
*)(SYS_BASE + 0x038)
#define
KICK1R *(unsigned int
*)(SYS_BASE + 0x03C)
#define
PINMUX0 *(unsigned int
*)(SYS_BASE + 0x120)
#define
PINMUX1 *(unsigned int
*)(SYS_BASE + 0x124)
#define
PINMUX2 *(unsigned int
*)(SYS_BASE + 0x128)
#define
PINMUX3 *(unsigned int
*)(SYS_BASE + 0x12C)
#define
PINMUX4 *(unsigned int
*)(SYS_BASE + 0x130)
#define
PINMUX5 *(unsigned int
*)(SYS_BASE + 0x134)
#define
PINMUX6 *(unsigned int
*)(SYS_BASE + 0x138)
#define
PINMUX7 *(unsigned int
*)(SYS_BASE + 0x13C)
#define
PINMUX8 *(unsigned int
*)(SYS_BASE + 0x140)
#define
PINMUX9 *(unsigned int
*)(SYS_BASE + 0x144)
#define
PINMUX10 *(unsigned int
*)(SYS_BASE + 0x148)
#define
PINMUX11 *(unsigned int
*)(SYS_BASE + 0x14C)
#define
PINMUX12 *(unsigned int
*)(SYS_BASE + 0x150)
#define
PINMUX13 *(unsigned int
*)(SYS_BASE + 0x154)
#define
PINMUX14 *(unsigned int
*)(SYS_BASE + 0x158)
#define
PINMUX15 *(unsigned int
*)(SYS_BASE + 0x15C)
#define
PINMUX16 *(unsigned int
*)(SYS_BASE + 0x160)
#define
PINMUX17 *(unsigned int
*)(SYS_BASE + 0x164)
#define
PINMUX18 *(unsigned int
*)(SYS_BASE + 0x168)
#define
PINMUX19 *(unsigned int
*)(SYS_BASE + 0x16C)
CSL_GpioRegsOvly m_pGPIORegs ; CSL_UppRegsOvly UppRegsOvly;
// static init struct for uPP driver (use defaults) const
upp_StaticConfig UPP_DEV_CONFIG = UPP_STATICCONFIG;
// local typedef typedef
enum
LOCAL_mode {
LOCAL_mode_AB_dlb, LOCAL_mode_BA_dlb, LOCAL_mode_A_transmit, LOCAL_mode_A_receive, LOCAL_mode_B_receive } LOCAL_mode;
// configuration macros #define
upp_line_size (1024)
#define
upp_line_count (2)
#define
upp_line_offset (upp_line_size)
#define
upp_clock_div 0
//(7)
#define
upp_demo_mode (LOCAL_mode_AB_dlb)
// global variables volatile
int
upp_interrupt_count = 0;
volatile
int
upp_error_count = 0;
LOCAL_mode upp_mode = upp_demo_mode; Uint8 upp_buffer_a[upp_line_size];
// * upp_line_count];
Uint8 upp_buffer_b[upp_line_size];
// * upp_line_count];
// local functions
static
int
LOCAL_upp_demo();
static
void
LOCAL_upp_config(upp_UserParams *upp_setup);
static
void
LOCAL_upp_config_xfers(upp_Transfer *xfer_a, upp_Transfer *xfer_b);
static
void
LOCAL_upp_complete_cb(upp_Transfer *xfer, Uint32 upp_isr_bit);
static
void
LOCAL_upp_error_cb(upp_Transfer *xfer, Uint32 upp_isr_bit);
static
void
LOCAL_kick_unlock();
static
void LOCAL_PSC1_LPSC_enable(unsigned int PD, unsigned int
LPSC_num);
static
void
LOCAL_apply_upp_pinmux();
Fxn CUppDriver::UppDeviceInit() {
//return ulnStatus;
TSK_Handle demo_tsk;
// system initialization (doesn't rely on GEL)
printf(
"UPP Test start-----------\n"
);
// unlock device
KICK_Unlock();
// turn on uPP LPSC
PSC1_LPSC_enable(0, 19);
// enable uPP pinmux - enable all uPP pin functions
Apply_Upp_PINMUX();
// enable HWI7 (tied to ECM block 2; see TCF)
C64_enableIER(1 << 9); UppTransferBegin();
if
(demo_tsk == NULL)
LOG_printf(&trace,
"TSK_create() failed.\n"
);
}
// LOCAL_upp_demo is the primary DSP/BIOS TSK function. It is called // after main static
int
CUppDriver::UppTransferBegin()
{ upp_UserParams upp_setup; upp_Transfer upp_xfer_a, upp_xfer_b; GIO_Handle upph;
int
i, status, target_int_count;
size_t Psize = 16;
// initialize uPP buffers
for (i = 0; i < sizeof(upp_buffer_a); i++)
//sizeof(upp_buffer_a) / 4
{
// put data in transmit buffer and clear receive buffer
if
(upp_mode == LOCAL_mode_BA_dlb)
{ ((Uint32 *)upp_buffer_b)[i] = 0xBBBB5555; ((Uint32 *)upp_buffer_a)[i] = 0x00000000; }
else
{ ((Uint32 *)upp_buffer_a)[i] = i;
//0xAAAA5555;
((Uint32 *)upp_buffer_b)[i] = 0x00000000; }
if
(upp_mode==LOCAL_mode_A_transmit)
{ ((Uint32 *)upp_buffer_b)[i] = 0xAAAA; }
if
(upp_mode==LOCAL_mode_B_receive)
{ ((Uint32 *)upp_buffer_b)[i] = 0xAAAA; } } upp_setup.params.A.width = 16;
// specify driver parameters
LOCAL_upp_config(&upp_setup);
// create driver handle
upph = GIO_create(
"/UPP"
, IOM_INOUT, &status, &upp_setup, NULL);
if
(upph == NULL)
{ LOG_printf (&trace,
"GIO_create failed"
);
//return -1;
}
// program transfer(s)
LOCAL_upp_config_xfers(&upp_xfer_a, &upp_xfer_b); LOG_printf (&trace,
"Programming uPP transfers..."
);
// note: begin read first if in DLB mode
switch
(upp_mode)
{
case
LOCAL_mode_AB_dlb:
status = GIO_read(upph, &upp_xfer_b, NULL); status |= GIO_write(upph, &upp_xfer_a, NULL);
break
;
case
LOCAL_mode_BA_dlb:
status = GIO_read(upph, &upp_xfer_a, NULL); status |= GIO_write(upph, &upp_xfer_b, NULL);
break
;
case
LOCAL_mode_A_transmit:
status = GIO_write(upph, &upp_xfer_a, NULL);
break
;
case
LOCAL_mode_A_receive:
status = GIO_read(upph, &upp_xfer_a, NULL);
break
;
case
LOCAL_mode_B_receive:
status = GIO_read(upph, &upp_xfer_b, NULL);
break
;
default
:
// unrecognized mode (shouldn't happen)
status = -1;
break
;
}
// catch GIO_submit errors)
if
(status < 0)
{ LOG_printf(&trace,
"Error programming uPP transfers.\n"
);
upp_error_count++; }
// wait until transfer(s) complete
target_int_count = (upp_mode == LOCAL_mode_AB_dlb || upp_mode == LOCAL_mode_BA_dlb) ? 2 : 1;
while
(upp_interrupt_count < target_int_count && upp_error_count == 0)
asm(
" nop"
);
// check buffers (loopback modes only)
if
(target_int_count == 2 && upp_error_count == 0)
for (i = 0; i < sizeof
(upp_buffer_a); i++)
if
(upp_buffer_a[i] != upp_buffer_b[i])
{
// LOG_printf(&trace, "Data mismatch in buffers.\n");
printf(
"Data mismatch in buffers.\n"
);
upp_error_count++; }
// report test result
if
(upp_error_count)
// LOG_printf(&trace, "uPP transfers completed with %u errors.\n", upp_error_count); printf(
"uPP transfers completed with %u errors.\n"
, upp_error_count);
else
// LOG_printf (&trace, "uPP transfers complete!");
printf(
"uPP transfers complete!\n"
);
return
0;
}
static
void
LOCAL_upp_config(upp_UserParams *upp_setup)
{ start with
default
settings
*upp_setup = UPP_USERPARAMS; upp_setup->params.B.clock_div = upp_clock_div; upp_setup->params.B.fxn_eow = (upp_CbFxn)LOCAL_upp_complete_cb;
//(upp_CbFxn)Upp_Complete_CB;
upp_setup->params.B.en_enable = TRUE; upp_setup->params.B.en_wait = FALSE; upp_setup->params.B.en_start = FALSE; upp_setup->params.A.clock_div =0; upp_setup->params.B.clock_div =0; upp_setup->params.A.width = 16; upp_setup->params.B.width = 16;
switch
(upp_mode)
{
case
LOCAL_mode_AB_dlb:
// A-to-B loopback
upp_setup->params.A.direction = upp_dir_xmit; upp_setup->params.B.direction = upp_dir_rcv; upp_setup->params.channels = 2;
//upp_setup->params.special_mode = upp_digital_loopback;
UppRegsOvly->UPCTL =UppRegsOvly->UPCTL| 0x04; UppRegsOvly->UPICR =UppRegsOvly->UPICR| 0x10;
break
;
case
LOCAL_mode_BA_dlb:
// B-to-A loopback
upp_setup->params.A.direction = upp_dir_rcv; upp_setup->params.B.direction = upp_dir_xmit; upp_setup->params.channels = 2; upp_setup->params.special_mode = upp_digital_loopback;
break
;
case
LOCAL_mode_A_transmit:
// Single channel transmit
upp_setup->params.A.direction = upp_dir_xmit;
break
;
case
LOCAL_mode_A_receive:
// Single channel receive
upp_setup->params.A.direction = upp_dir_rcv;
break
;
case
LOCAL_mode_B_receive:
// Single channel receive
upp_setup->params.B.direction = upp_dir_rcv;
break
;
default
:
// unrecognized mode (shouldn't happen)
LOG_printf(&trace,
"Warning: unrecognized uPP mode\n"
);
break
;
} }
// LOCAL_upp_config_xfers initializes uPP transfers according to parameters // defined in local macros static
void
LOCAL_upp_config_xfers(upp_Transfer *xfer_a, upp_Transfer *xfer_b)
{
// start with default settings
*xfer_a = UPP_TRANSFER; *xfer_b = UPP_TRANSFER;
// apply common settings
xfer_a->windowAddr = upp_buffer_a; xfer_a->lineCount = upp_line_count; xfer_a->lineSize = upp_line_size; xfer_a->lineOffset = upp_line_offset; xfer_a->channel = upp_A; xfer_b->windowAddr = upp_buffer_b; xfer_b->lineCount = upp_line_count; xfer_b->lineSize = upp_line_size; xfer_b->lineOffset = upp_line_offset; xfer_b->channel = upp_B;
// note: upp_xfer_b will only be used in DLB modes
} // LOCAL_upp_complete_cb is a callback function used to track the // completion of uPP transfers (i.e. EOW events) static
void
LOCAL_upp_complete_cb(upp_Transfer *xfer, Uint32 upp_isr_bit)
{
// LOG_printf(&trace, "uPP interrupt: 0x%08X", upp_isr_bit); printf(
"uPP interrupt: 0x%08X"
, upp_isr_bit);
upp_interrupt_count++;
// note: only uPP HWI is enabled, so increment should be atomic/safe
} // LOCAL_upp_error_cb is a callback function used to track uPP error // events (underrun/overflow, internal error, or DMA programming error) static
void
LOCAL_upp_error_cb(upp_Transfer *xfer, Uint32 upp_isr_bit)
{ LOG_printf(&trace,
"uPP error: 0x%08X"
, upp_isr_bit);
upp_error_count++;
// note: only uPP HWI is enabled, so increment should be atomic/safe
} LOCAL_kick_unlock allows
register
access at run time. Based on code
taken from GEL file
static
void
LOCAL_kick_unlock()
{
// enables register access at run time
KICK0R = 0x83e70b13;
// Kick0 register + data (unlock)
KICK1R = 0x95a4f1e0;
// Kick1 register + data (unlock)
} // LOCAL_PSC1_LPSC_enable powers on one LPSC. Based on code taken from // GEL file static
void LOCAL_PSC1_LPSC_enable(unsigned int PD, unsigned int
LPSC_num)
{ *(
unsigned int
*) (PSC1_MDCTL + 4 * LPSC_num) =
(*(
unsigned int
*) (PSC1_MDCTL + 4 * LPSC_num) & 0xFFFFFFE0) | 0x0003;
PSC1_PTCMD = 0x1 << PD;
// Wait for power state transition to finish
while( (PSC1_PTSTAT & (0x1 << PD)) != 0) asm(" nop"
);
while( (*(unsigned int*)(PSC1_MDSTAT + 4 * LPSC_num) & 0x1F) !=0x3) asm(" nop"
);
}
// LOCAL_apply_upp_pinmux enables all uPP pin functions. Based on code taken // from GEL file static
void
LOCAL_apply_upp_pinmux()
{
// all pins (channel A, channel B, DATA, and XDATA)
PINMUX13 = (PINMUX13 & 0x0000FFFF) | 0x44440000; PINMUX14 = (PINMUX14 & 0x000000FF) | 0x44444400; PINMUX15 = (PINMUX15 & 0x00000000) | 0x44444444; PINMUX16 = (PINMUX16 & 0x00000000) | 0x44444444; PINMUX17 = (PINMUX17 & 0x00000000) | 0x44444444; PINMUX18 = (PINMUX18 & 0xFF000000) | 0x00444444; } //------------- // END OF FILE //-------------
// application include file
#include
"upp_drv_testcfg.h"
#include <upp_md.h>
#include
<ti\pspiom\cslr\cslr_upp.h>
#include "
slr_gpio.h"
extern
"C"
{
#include "evmc6748.h"
#include "evmc6748_timer.h"
} // PSC registers (lifted from GEL) #define
PSC1_BASE 0x01E27000
#define
PSC1_MDCTL (PSC1_BASE+0xA00)
#define
PSC1_MDSTAT (PSC1_BASE+0x800)
#define
PSC1_PTCMD *(unsigned int
*) (PSC1_BASE + 0x120)
#define
PSC1_PTSTAT *(unsigned int
*) (PSC1_BASE + 0x128)
// kick and pinmux registers (lifted from GEL)
#define
SYS_BASE 0x01C14000
#define
KICK0R *(unsigned int
*)(SYS_BASE + 0x038)
#define
KICK1R *(unsigned int
*)(SYS_BASE + 0x03C)
#define
PINMUX0 *(unsigned int
*)(SYS_BASE + 0x120)
#define
PINMUX1 *(unsigned int
*)(SYS_BASE + 0x124)
#define
PINMUX2 *(unsigned int
*)(SYS_BASE + 0x128)
#define
PINMUX3 *(unsigned int
*)(SYS_BASE + 0x12C)
#define
PINMUX4 *(unsigned int
*)(SYS_BASE + 0x130)
#define
PINMUX5 *(unsigned int
*)(SYS_BASE + 0x134)
#define
PINMUX6 *(unsigned int
*)(SYS_BASE + 0x138)
#define
PINMUX7 *(unsigned int
*)(SYS_BASE + 0x13C)
#define
PINMUX8 *(unsigned int
*)(SYS_BASE + 0x140)
#define
PINMUX9 *(unsigned int
*)(SYS_BASE + 0x144)
#define
PINMUX10 *(unsigned int
*)(SYS_BASE + 0x148)
#define
PINMUX11 *(unsigned int
*)(SYS_BASE + 0x14C)
#define
PINMUX12 *(unsigned int
*)(SYS_BASE + 0x150)
#define
PINMUX13 *(unsigned int
*)(SYS_BASE + 0x154)
#define
PINMUX14 *(unsigned int
*)(SYS_BASE + 0x158)
#define
PINMUX15 *(unsigned int
*)(SYS_BASE + 0x15C)
#define
PINMUX16 *(unsigned int
*)(SYS_BASE + 0x160)
#define
PINMUX17 *(unsigned int
*)(SYS_BASE + 0x164)
#define
PINMUX18 *(unsigned int
*)(SYS_BASE + 0x168)
#define
PINMUX19 *(unsigned int
*)(SYS_BASE + 0x16C)
CSL_GpioRegsOvly m_pGPIORegs ; CSL_UppRegsOvly UppRegsOvly;
// static init struct for uPP driver (use defaults)
const
upp_StaticConfig UPP_DEV_CONFIG = UPP_STATICCONFIG;
// local typedef
typedef
enum
LOCAL_mode {
LOCAL_mode_AB_dlb, LOCAL_mode_BA_dlb, LOCAL_mode_A_transmit, LOCAL_mode_A_receive, LOCAL_mode_B_receive } LOCAL_mode;
// configuration macros
#define
upp_line_size (1024)
#define
upp_line_count (2)
#define
upp_line_offset (upp_line_size)
#define
upp_clock_div 0
//(7)
#define
upp_demo_mode (LOCAL_mode_AB_dlb)
// global variables
volatile
int
upp_interrupt_count = 0;
volatile
int
upp_error_count = 0;
LOCAL_mode upp_mode = upp_demo_mode; Uint8 upp_buffer_a[upp_line_size];
// * upp_line_count];
Uint8 upp_buffer_b[upp_line_size];
// * upp_line_count];
// local functions
static
int
LOCAL_upp_demo();
static
void
LOCAL_upp_config(upp_UserParams *upp_setup);
static
void
LOCAL_upp_config_xfers(upp_Transfer *xfer_a, upp_Transfer *xfer_b);
static
void
LOCAL_upp_complete_cb(upp_Transfer *xfer, Uint32 upp_isr_bit);
static
void
LOCAL_upp_error_cb(upp_Transfer *xfer, Uint32 upp_isr_bit);
static
void
LOCAL_kick_unlock();
static
void LOCAL_PSC1_LPSC_enable(unsigned int PD, unsigned int
LPSC_num);
static
void
LOCAL_apply_upp_pinmux();
Fxn CUppDriver::UppDeviceInit() {
//return ulnStatus;
TSK_Handle demo_tsk;
// system initialization (doesn't rely on GEL)
printf(
"UPP Test start-----------\n"
);
// unlock device
KICK_Unlock();
// turn on uPP LPSC
PSC1_LPSC_enable(0, 19);
// enable uPP pinmux - enable all uPP pin functions
Apply_Upp_PINMUX();
// enable HWI7 (tied to ECM block 2; see TCF)
C64_enableIER(1 << 9); UppTransferBegin();
if
(demo_tsk == NULL)
LOG_printf(&trace,
"TSK_create() failed.\n"
);
}
// LOCAL_upp_demo is the primary DSP/BIOS TSK function. It is called // after main
static
int
CUppDriver::UppTransferBegin()
{ upp_UserParams upp_setup; upp_Transfer upp_xfer_a, upp_xfer_b; GIO_Handle upph;
int
i, status, target_int_count;
size_t Psize = 16;
// initialize uPP buffers
for (i = 0; i < sizeof(upp_buffer_a); i++)
//sizeof(upp_buffer_a) / 4
{
// put data in transmit buffer and clear receive buffer
if
(upp_mode == LOCAL_mode_BA_dlb)
{ ((Uint32 *)upp_buffer_b)[i] = 0xBBBB5555; ((Uint32 *)upp_buffer_a)[i] = 0x00000000; }
else
{ ((Uint32 *)upp_buffer_a)[i] = i;
//0xAAAA5555;
((Uint32 *)upp_buffer_b)[i] = 0x00000000; }
if
(upp_mode==LOCAL_mode_A_transmit)
{ ((Uint32 *)upp_buffer_b)[i] = 0xAAAA; }
if
(upp_mode==LOCAL_mode_B_receive)
{ ((Uint32 *)upp_buffer_b)[i] = 0xAAAA; } } upp_setup.params.A.width = 16;
// specify driver parameters
LOCAL_upp_config(&upp_setup);
// create driver handle
upph = GIO_create(
"/UPP"
, IOM_INOUT, &status, &upp_setup, NULL);
if
(upph == NULL)
{ LOG_printf (&trace,
"GIO_create failed"
);
//return -1;
}
// program transfer(s)
LOCAL_upp_config_xfers(&upp_xfer_a, &upp_xfer_b); LOG_printf (&trace,
"Programming uPP transfers..."
);
// note: begin read first if in DLB mode
switch
(upp_mode)
{
case
LOCAL_mode_AB_dlb:
status = GIO_read(upph, &upp_xfer_b, NULL); status |= GIO_write(upph, &upp_xfer_a, NULL);
break
;
case
LOCAL_mode_BA_dlb:
status = GIO_read(upph, &upp_xfer_a, NULL); status |= GIO_write(upph, &upp_xfer_b, NULL);
break
;
case
LOCAL_mode_A_transmit:
status = GIO_write(upph, &upp_xfer_a, NULL);
break
;
case
LOCAL_mode_A_receive:
status = GIO_read(upph, &upp_xfer_a, NULL);
break
;
case
LOCAL_mode_B_receive:
status = GIO_read(upph, &upp_xfer_b, NULL);
break
;
default
:
// unrecognized mode (shouldn't happen)
status = -1;
break
;
}
// catch GIO_submit errors)
if
(status < 0)
{ LOG_printf(&trace,
"Error programming uPP transfers.\n"
);
upp_error_count++; }
// wait until transfer(s) complete
target_int_count = (upp_mode == LOCAL_mode_AB_dlb || upp_mode == LOCAL_mode_BA_dlb) ? 2 : 1;
while
(upp_interrupt_count < target_int_count && upp_error_count == 0)
asm(
" nop"
);
// check buffers (loopback modes only)
if
(target_int_count == 2 && upp_error_count == 0)
for (i = 0; i < sizeof
(upp_buffer_a); i++)
if
(upp_buffer_a[i] != upp_buffer_b[i])
{
// LOG_printf(&trace, "Data mismatch in buffers.\n");
printf(
"Data mismatch in buffers.\n"
);
upp_error_count++; }
// report test result
if
(upp_error_count)
// LOG_printf(&trace, "uPP transfers completed with %u errors.\n", upp_error_count);
printf(
"uPP transfers completed with %u errors.\n"
, upp_error_count);
else
// LOG_printf (&trace, "uPP transfers complete!");
printf(
"uPP transfers complete!\n"
);
return
0;
}
static
void
LOCAL_upp_config(upp_UserParams *upp_setup)
{ start with
default
settings
*upp_setup = UPP_USERPARAMS; upp_setup->params.B.clock_div = upp_clock_div; upp_setup->params.B.fxn_eow = (upp_CbFxn)LOCAL_upp_complete_cb;
//(upp_CbFxn)Upp_Complete_CB;
upp_setup->params.B.en_enable = TRUE; upp_setup->params.B.en_wait = FALSE; upp_setup->params.B.en_start = FALSE; upp_setup->params.A.clock_div =0; upp_setup->params.B.clock_div =0; upp_setup->params.A.width = 16; upp_setup->params.B.width = 16;
switch
(upp_mode)
{
case
LOCAL_mode_AB_dlb:
// A-to-B loopback
upp_setup->params.A.direction = upp_dir_xmit; upp_setup->params.B.direction = upp_dir_rcv; upp_setup->params.channels = 2;
//upp_setup->params.special_mode = upp_digital_loopback;
UppRegsOvly->UPCTL =UppRegsOvly->UPCTL| 0x04; UppRegsOvly->UPICR =UppRegsOvly->UPICR| 0x10;
break
;
case
LOCAL_mode_BA_dlb:
// B-to-A loopback
upp_setup->params.A.direction = upp_dir_rcv; upp_setup->params.B.direction = upp_dir_xmit; upp_setup->params.channels = 2; upp_setup->params.special_mode = upp_digital_loopback;
break
;
case
LOCAL_mode_A_transmit:
// Single channel transmit
upp_setup->params.A.direction = upp_dir_xmit;
break
;
case
LOCAL_mode_A_receive:
// Single channel receive
upp_setup->params.A.direction = upp_dir_rcv;
break
;
case
LOCAL_mode_B_receive:
// Single channel receive
upp_setup->params.B.direction = upp_dir_rcv;
break
;
default
:
// unrecognized mode (shouldn't happen)
LOG_printf(&trace,
"Warning: unrecognized uPP mode\n"
);
break
;
} }
// LOCAL_upp_config_xfers initializes uPP transfers according to parameters // defined in local macros
static
void
LOCAL_upp_config_xfers(upp_Transfer *xfer_a, upp_Transfer *xfer_b)
{
// start with default settings
*xfer_a = UPP_TRANSFER; *xfer_b = UPP_TRANSFER;
// apply common settings
xfer_a->windowAddr = upp_buffer_a; xfer_a->lineCount = upp_line_count; xfer_a->lineSize = upp_line_size; xfer_a->lineOffset = upp_line_offset; xfer_a->channel = upp_A; xfer_b->windowAddr = upp_buffer_b; xfer_b->lineCount = upp_line_count; xfer_b->lineSize = upp_line_size; xfer_b->lineOffset = upp_line_offset; xfer_b->channel = upp_B;
// note: upp_xfer_b will only be used in DLB modes
}
// LOCAL_upp_complete_cb is a callback function used to track the // completion of uPP transfers (i.e. EOW events) static
void
LOCAL_upp_complete_cb(upp_Transfer *xfer, Uint32 upp_isr_bit)
{
// LOG_printf(&trace, "uPP interrupt: 0x%08X", upp_isr_bit);
printf(
"uPP interrupt: 0x%08X"
, upp_isr_bit);
upp_interrupt_count++;
// note: only uPP HWI is enabled, so increment should be atomic/safe
}
// LOCAL_upp_error_cb is a callback function used to track uPP error // events (underrun/overflow, internal error, or DMA programming error) static
void
LOCAL_upp_error_cb(upp_Transfer *xfer, Uint32 upp_isr_bit)
{ LOG_printf(&trace,
"uPP error: 0x%08X"
, upp_isr_bit);
upp_error_count++;
// note: only uPP HWI is enabled, so increment should be atomic/safe
} LOCAL_kick_unlock allows
register
access at run time. Based on code
taken from GEL file
static
void
LOCAL_kick_unlock()
{
// enables register access at run time
KICK0R = 0x83e70b13;
// Kick0 register + data (unlock)
KICK1R = 0x95a4f1e0;
// Kick1 register + data (unlock)
}
// LOCAL_PSC1_LPSC_enable powers on one LPSC. Based on code taken from // GEL file static
void LOCAL_PSC1_LPSC_enable(unsigned int PD, unsigned int
LPSC_num)
{ *(
unsigned int
*) (PSC1_MDCTL + 4 * LPSC_num) =
(*(
unsigned int
*) (PSC1_MDCTL + 4 * LPSC_num) & 0xFFFFFFE0) | 0x0003;
PSC1_PTCMD = 0x1 << PD;
// Wait for power state transition to finish
while( (PSC1_PTSTAT & (0x1 << PD)) != 0) asm(" nop"
);
while( (*(unsigned int*)(PSC1_MDSTAT + 4 * LPSC_num) & 0x1F) !=0x3) asm(" nop"
);
}
// LOCAL_apply_upp_pinmux enables all uPP pin functions. Based on code taken // from GEL file
static
void
LOCAL_apply_upp_pinmux()
{
// all pins (channel A, channel B, DATA, and XDATA)
PINMUX13 = (PINMUX13 & 0x0000FFFF) | 0x44440000; PINMUX14 = (PINMUX14 & 0x000000FF) | 0x44444400; PINMUX15 = (PINMUX15 & 0x00000000) | 0x44444444; PINMUX16 = (PINMUX16 & 0x00000000) | 0x44444444; PINMUX17 = (PINMUX17 & 0x00000000) | 0x44444444; PINMUX18 = (PINMUX18 & 0xFF000000) | 0x00444444; }
//------------- // END OF FILE //-------------
Veena,
Could you describe your hardware setup? Are you trying to run an "external" loopback test (i.e. connecting the channel A and B pins), or are you doing something else?
One thing I notice in your code is that you are attempting to set some register values manually:
UppRegsOvly->UPCTL =UppRegsOvly->UPCTL| 0x04;
UppRegsOvly->UPICR =UppRegsOvly->UPICR| 0x10;
This is not necessary since the driver will set these register values automatically. Generally speaking, any settings you apply before calling GIO_create() will be lost when the driver resets the uPP peripheral. I recommend checking the uPP registers after calling GIO_create() to make sure the settings you want have actually been applied.
Also, when sharing an entire source file on the forum, I recommend simply attaching it to your post (using the "options" tab next to "compose" above the text entry box). The forum doesn't handle big blocks of text very well; it likes to double the line breaks in copy-pasted text.
Hi Joe,
My hardware Setup is as follows:
UPP communicated with FPGA for transmit and recieve. I use Duplex 1 mode
in Transmit mode:
I have not confiured START as ENABLE is enough for transmission. on FPGA I am able to recieve the transmitted data.
In recieve mode:
I have disabled ENABLE and START, I have enabled WAIT.
my concern is that when I get data through FPGA on Data pins interrupt should be generated at every ENABLE high.
I get some junk data in between the actual data.
What am I missing?
Thanks and regards
Veena
Hi Joe,
This is V important and Urgent. I would appreciate if you cud guide me on this.
In the above UPP prgram, I get EOl and EOW interrupts only after I do a GIO_Read.
My expectation is : Once the data is ready I should get interrupt first then I do a GIO_read.
Thanks and regards
Veena
Veena,
With ENABLE and START disabled for receive mode, the uPP peripheral will read incoming data every time the clock line pulses. If you're getting spurious data, it may indicate that you have some glitch or extra pulse in your clock signal. Using ENABLE could be helpful for correcting this sort of error. (With ENABLE, data is only read when the clock pulses and ENABLE is asserted.)
Also, you should generally call GIO_read before you expect data to arrive. The sequence of events should be like this:
Hope this helps.
Hi Joe,
Thanks a lot for all the inputs it was helpful,
My UPP driver is working now in terms of transmit and recieve.
one more concern is that I get external HW interrupt on a GPIO and then the driver begins recieving.
but I cannot call GIO_read in a HWI.
Could you throw some light on how to make this driver a non-blocking driver and how to set GIO Manager properties to use non-blocking synchronization methods
Thanks and regards
Veena
Hi Joe,
Thanks a lot for all the support.
I have one more query.
I have configured EOL
I call GIO_Read every 2.5ms but call to EOL gets missed it gets called in 5ms sometimes 2.5 ms
does it cause some delay?
rgds
Veena
Veena,
Do your transfers have more than one line per window? It is possible for multiple interrupt events to be handled by a single call to the ISR function. For example, the last line in a transfer will generate an EOL event at almost the same time as the EOW event. For very small line sizes, you can also have multiple EOL events serviced by a single ISR call. In this case, one of the EOL events may be "masked" by the other, and your application may only see that a single EOL event occurred. The best way to avoid this is to increase your buffer and line sizes (or decrease the uPP clock speed) so that interrupts occur less frequently.
Please let me know if this answers your question.