custom97.cpp
Use a periodic interrupt from the controller. Requires RTOS and Custom97 firmware.
#include "rsi.h"
using namespace RSI::RapidCode::SynqNet;
#define SYNC_PERIOD (1) // interrupt every SynqNet/MotionController sample
#define FIRMWARE_WAIT_TIME (12000) // 25 nanosecond cycles to delay the firmware foreground -- "tune" this value using VM3 and HostProcessTime
#define DATA_READ_COUNT (3) // how many Rincon values to read
#define DATA_WRITE_COUNT (3) // how many values to write to the Rincon buffer
#define ENCODER_X_ADDR (0x1000180)
#define ENCODER_Y_ADDR (0x1000220)
#define ENCODER_Z_ADDR (0x1000260)
#define TORQUE_X_ADDR (0x1000184)
#define TORQUE_Y_ADDR (0x1000224)
#define TORQUE_Z_ADDR (0x1000264)
#define MS_PER_SECOND (1000.0)
MotionController *controller;
long currentCounter = 0;
long previousCounter = 0;
long deltaSamples = 0;
long iterations = 0;
unsigned long cpuFreq = 0;
double deltaTime = 0.0;
double minTime = 1000000.0;
double maxTime = 0.0;
typedef struct {
long encoderX;
long encoderY;
long encoderZ;
} ReadData;
typedef struct {
long torqueX;
long torqueY;
long torqueZ;
} WriteData;
long readSize;
long writeSize;
ReadData *readData;
WriteData *writeData;
void CheckHostProcessTimeStatus()
{
if(controller->SyncInterruptHostProcessStatusBitGet() == true)
{
printf("\n\n Oops, we took too long processing the last interrupt. \n");
controller->SyncInterruptHostProcessStatusClear();
}
}
void PrintTimingInfo()
{
currentCounter = controller->OS->PerformanceTimerCountGet();
deltaSamples = currentCounter - previousCounter;
previousCounter = currentCounter;
deltaTime = (double)( deltaSamples * (double)(1/(double)cpuFreq)) * MS_PER_SECOND;
if(iterations > 1)
{
if(deltaTime > maxTime)
{
maxTime = deltaTime;
}
if(deltaTime < minTime)
{
minTime = deltaTime;
}
printf("IRQ %ld: %3.3lf ms Min: %3.3lf Max: %3.3lf \r", iterations, deltaTime, minTime, maxTime );
}
}
void SetupCustom97()
{
printf("Custom97 version is: %ld\n ", controller->Custom97VersionGet());
controller->Custom97WaitTimeSet(FIRMWARE_WAIT_TIME);
controller->OS->Sleep(1);
controller->Custom97ReadPtrSet(0, ENCODER_X_ADDR);
controller->Custom97ReadPtrSet(1, ENCODER_Y_ADDR);
controller->Custom97ReadPtrSet(2, ENCODER_Z_ADDR);
controller->Custom97ReadCountSet(DATA_READ_COUNT);
controller->Custom97WritePtrSet(0, TORQUE_X_ADDR);
controller->Custom97WritePtrSet(1, TORQUE_Y_ADDR);
controller->Custom97WritePtrSet(2, TORQUE_Z_ADDR);
printf("Setting Write count");
controller->Custom97WriteCountSet(DATA_WRITE_COUNT);
readData = new ReadData;
writeData = new WriteData;
readSize = sizeof(ReadData);
writeSize = sizeof(WriteData);
}
void DisableCustom97()
{
controller->Custom97ReadCountSet(0);
controller->Custom97WriteCountSet(0);
delete readData;
delete writeData;
}
void custom97Main()
{
try
{
controller = MotionController::CreateFromBoard(0);
controller->ServiceThreadEnableSet(false);
SetupCustom97();
cpuFreq = controller->OS->PerformanceTimerFrequencyGet();
printf("CPU Frequency is: %u Hz\n", cpuFreq);
printf("Host will have %ld microseconds to process data.\n", controller->SyncInterruptHostProcessTimeGet() );
controller->SyncInterruptPeriodSet(SYNC_PERIOD);
controller->SyncInterruptEnableSet(true);
printf("Press a key to exit the Sync Interrupt processing loop...\n");
while( controller->OS->KeyGet(RSIWaitPOLL) < 0)
{
controller->SyncInterruptWait();
CheckHostProcessTimeStatus();
PrintTimingInfo();
controller->SyncInterruptHostProcessFlagSet(true);
controller->Custom97ReadDataGet(readData, readSize);
writeData->torqueX = 0;
writeData->torqueY = 1;
writeData->torqueZ = 2;
controller->Custom97WriteDataSet(writeData, writeSize);
controller->SyncInterruptHostProcessFlagSet(false);
iterations++;
}
DisableCustom97();
controller->SyncInterruptEnableSet(false);
}
catch (RsiError *err)
{
printf("%s\n", err->text);
}
printf("Press a key to exit.\n");
while( controller->OS->KeyGet(RSIWaitPOLL) < 0)
{
controller->OS->Sleep(100);
}
}