mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-07-04 03:11:43 +00:00
Move PWM allocation to HAL to allow for checking against DIO allocation
Re-number MXP DIO to match pinout (include SPI and I2C pins) (fixes artf2664) Change PWM MXP mapping to accommodate DIO re-mapping This re-implementation also fixes artf2668 for C++ and Java Change the test bench to reflect this change also Change-Id: If30bd6a85a9f1f619fbde06a4ecd595a15fd28f7
This commit is contained in:
committed by
Thomas Clark
parent
deb335d96d
commit
59473ab7a7
@@ -21,6 +21,8 @@ extern "C"
|
||||
bool checkRelayChannel(void* digital_port_pointer);
|
||||
|
||||
void setPWM(void* digital_port_pointer, unsigned short value, int32_t *status);
|
||||
bool allocatePWMChannel(void* digital_port_pointer, int32_t *status);
|
||||
void freePWMChannel(void* digital_port_pointer, int32_t *status);
|
||||
unsigned short getPWM(void* digital_port_pointer, int32_t *status);
|
||||
void setPWMPeriodScale(void* digital_port_pointer, uint32_t squelchMask, int32_t *status);
|
||||
void* allocatePWM(int32_t *status);
|
||||
|
||||
@@ -62,6 +62,7 @@ tRelay* relaySystem = NULL;
|
||||
tPWM* pwmSystem = NULL;
|
||||
Resource *DIOChannels = NULL;
|
||||
Resource *DO_PWMGenerators = NULL;
|
||||
Resource *PWMChannels = NULL;
|
||||
|
||||
bool digitalSystemsInitialized = false;
|
||||
|
||||
@@ -99,6 +100,7 @@ void initializeDigital(int32_t *status) {
|
||||
|
||||
Resource::CreateResourceObject(&DIOChannels, tDIO::kNumSystems * kDigitalPins);
|
||||
Resource::CreateResourceObject(&DO_PWMGenerators, tDIO::kNumPWMDutyCycleAElements + tDIO::kNumPWMDutyCycleBElements);
|
||||
Resource::CreateResourceObject(&PWMChannels, tPWM::kNumSystems * kPwmPins);
|
||||
digitalSystem = tDIO::create(status);
|
||||
|
||||
// Relay Setup
|
||||
@@ -165,15 +167,19 @@ bool checkRelayChannel(void* digital_port_pointer) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Map DIO pin numbers from their physical number (10 to 19) to their position
|
||||
* Map DIO pin numbers from their physical number (10 to 26) to their position
|
||||
* in the bit field.
|
||||
*/
|
||||
uint32_t remapMXPChannel(uint32_t pin) {
|
||||
if(pin < 14) {
|
||||
return pin - 10; // First four digital headers
|
||||
} else {
|
||||
return pin - 6; // Last 8 digital headers, not counting the SPI pins
|
||||
}
|
||||
return pin - 10;
|
||||
}
|
||||
|
||||
uint32_t remapMXPPWMChannel(uint32_t pin) {
|
||||
if(pin < 14) {
|
||||
return pin - 10; //first block of 4 pwms (MXP 0-3)
|
||||
} else {
|
||||
return pin - 6; //block of PWMs after SPI
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -191,11 +197,6 @@ void setPWM(void* digital_port_pointer, unsigned short value, int32_t *status) {
|
||||
pwmSystem->writeHdr(port->port.pin, value, status);
|
||||
} else {
|
||||
pwmSystem->writeMXP(port->port.pin - tPWM::kNumHdrRegisters, value, status);
|
||||
|
||||
// Enable special functions on this pin
|
||||
uint32_t bitToSet = 1 << remapMXPChannel(port->port.pin);
|
||||
short specialFunctions = digitalSystem->readEnableMXPSpecialFunction(status);
|
||||
digitalSystem->writeEnableMXPSpecialFunction(specialFunctions | bitToSet, status);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -426,6 +427,32 @@ bool allocateDIO(void* digital_port_pointer, bool input, int32_t *status) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool allocatePWMChannel(void* digital_port_pointer, int32_t *status) {
|
||||
DigitalPort* port = (DigitalPort*) digital_port_pointer;
|
||||
char buf[64];
|
||||
snprintf(buf, 64, "PWM %d", port->port.pin);
|
||||
if (PWMChannels->Allocate(port->port.pin, buf) == ~0ul) return false;
|
||||
if (port->port.pin > tPWM::kNumHdrRegisters-1) {
|
||||
snprintf(buf, 64, "PWM %d and DIO %d", port->port.pin, remapMXPPWMChannel(port->port.pin) + 10);
|
||||
if (DIOChannels->Allocate(remapMXPPWMChannel(port->port.pin) + 10, buf) == ~0ul) return false;
|
||||
uint32_t bitToSet = 1 << remapMXPPWMChannel(port->port.pin);
|
||||
short specialFunctions = digitalSystem->readEnableMXPSpecialFunction(status);
|
||||
digitalSystem->writeEnableMXPSpecialFunction(specialFunctions | bitToSet, status);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void freePWMChannel(void* digital_port_pointer, int32_t *status) {
|
||||
DigitalPort* port = (DigitalPort*) digital_port_pointer;
|
||||
PWMChannels->Free(port->port.pin);
|
||||
if(port->port.pin > tPWM::kNumHdrRegisters-1) {
|
||||
DIOChannels->Free(remapMXPPWMChannel(port->port.pin) + 10);
|
||||
uint32_t bitToUnset = 1 << remapMXPPWMChannel(port->port.pin);
|
||||
short specialFunctions = digitalSystem->readEnableMXPSpecialFunction(status);
|
||||
digitalSystem->writeEnableMXPSpecialFunction(specialFunctions & ~bitToUnset, status);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Free the resource associated with a digital I/O channel.
|
||||
*
|
||||
|
||||
@@ -15,7 +15,6 @@ constexpr float PWM::kDefaultPwmPeriod;
|
||||
constexpr float PWM::kDefaultPwmCenter;
|
||||
const int32_t PWM::kDefaultPwmStepsDown;
|
||||
const int32_t PWM::kPwmDisabled;
|
||||
static Resource *allocated = NULL;
|
||||
|
||||
/**
|
||||
* Initialize PWMs given a channel.
|
||||
@@ -28,7 +27,6 @@ void PWM::InitPWM(uint32_t channel)
|
||||
{
|
||||
m_table = NULL;
|
||||
char buf[64];
|
||||
Resource::CreateResourceObject(&allocated, kPwmChannels);
|
||||
|
||||
if (!CheckPWMChannel(channel))
|
||||
{
|
||||
@@ -37,16 +35,12 @@ void PWM::InitPWM(uint32_t channel)
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(buf, 64, "PWM %d", channel);
|
||||
if (allocated->Allocate(channel, buf) == ~0ul)
|
||||
{
|
||||
CloneError(allocated);
|
||||
return;
|
||||
}
|
||||
int32_t status = 0;
|
||||
allocatePWMChannel(m_pwm_ports[channel], &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
|
||||
m_channel = channel;
|
||||
|
||||
int32_t status = 0;
|
||||
setPWM(m_pwm_ports[m_channel], kPwmDisabled, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
|
||||
@@ -73,10 +67,12 @@ PWM::PWM(uint32_t channel)
|
||||
PWM::~PWM()
|
||||
{
|
||||
int32_t status = 0;
|
||||
|
||||
setPWM(m_pwm_ports[m_channel], kPwmDisabled, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
|
||||
allocated->Free(m_channel);
|
||||
freePWMChannel(m_pwm_ports[m_channel], &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -43,10 +43,10 @@ public:
|
||||
static const uint32_t kFakePressureSwitchChannel = 11;
|
||||
static const uint32_t kFakeSolenoid1Channel = 12;
|
||||
static const uint32_t kFakeSolenoid2Channel = 13;
|
||||
static const uint32_t kFakeRelayForward = 14;
|
||||
static const uint32_t kFakeRelayReverse = 15;
|
||||
static const uint32_t kFakeJaguarForwardLimit = 16;
|
||||
static const uint32_t kFakeJaguarReverseLimit = 17;
|
||||
static const uint32_t kFakeRelayForward = 18;
|
||||
static const uint32_t kFakeRelayReverse = 19;
|
||||
static const uint32_t kFakeJaguarForwardLimit = 20;
|
||||
static const uint32_t kFakeJaguarReverseLimit = 21;
|
||||
|
||||
/* Relay channels */
|
||||
static const uint32_t kRelayChannel = 0;
|
||||
|
||||
@@ -37,8 +37,6 @@ import edu.wpi.first.wpilibj.hal.HALUtil;
|
||||
* 0 = disabled (i.e. PWM output is held low)
|
||||
*/
|
||||
public class PWM extends SensorBase implements LiveWindowSendable {
|
||||
private static Resource allocated = new Resource( kPwmChannels);
|
||||
|
||||
/**
|
||||
* Represents the amount to multiply the minimum servo-pulse pwm period by.
|
||||
*/
|
||||
@@ -113,12 +111,6 @@ public class PWM extends SensorBase implements LiveWindowSendable {
|
||||
*/
|
||||
private void initPWM(final int channel) {
|
||||
checkPWMChannel(channel);
|
||||
try {
|
||||
allocated.allocate(channel);
|
||||
} catch (CheckedAllocationException e) {
|
||||
throw new AllocationException(
|
||||
"PWM channel " + channel + " is already allocated");
|
||||
}
|
||||
m_channel = channel;
|
||||
|
||||
ByteBuffer status = ByteBuffer.allocateDirect(4);
|
||||
@@ -127,6 +119,13 @@ public class PWM extends SensorBase implements LiveWindowSendable {
|
||||
m_port = DIOJNI.initializeDigitalPort(DIOJNI.getPort((byte) m_channel), status.asIntBuffer());
|
||||
HALUtil.checkStatus(status.asIntBuffer());
|
||||
|
||||
if (!PWMJNI.allocatePWMChannel(m_port, status.asIntBuffer()))
|
||||
{
|
||||
throw new AllocationException(
|
||||
"PWM channel " + channel + " is already allocated");
|
||||
}
|
||||
HALUtil.checkStatus(status.asIntBuffer());
|
||||
|
||||
PWMJNI.setPWM(m_port, (short) 0, status.asIntBuffer());
|
||||
HALUtil.checkStatus(status.asIntBuffer());
|
||||
|
||||
@@ -156,10 +155,11 @@ public class PWM extends SensorBase implements LiveWindowSendable {
|
||||
PWMJNI.setPWM(m_port, (short) 0, status.asIntBuffer());
|
||||
HALUtil.checkStatus(status.asIntBuffer());
|
||||
|
||||
PWMJNI.freeDIO(m_port, status.asIntBuffer());
|
||||
PWMJNI.freePWMChannel(m_port, status.asIntBuffer());
|
||||
HALUtil.checkStatus(status.asIntBuffer());
|
||||
|
||||
allocated.free(m_channel);
|
||||
PWMJNI.freeDIO(m_port, status.asIntBuffer());
|
||||
HALUtil.checkStatus(status.asIntBuffer());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,6 +7,8 @@ import edu.wpi.first.wpilibj.SensorBase;
|
||||
|
||||
|
||||
public class PWMJNI extends DIOJNI {
|
||||
public static native boolean allocatePWMChannel(ByteBuffer digital_port_pointer, IntBuffer status);
|
||||
public static native void freePWMChannel(ByteBuffer digital_port_pointer, IntBuffer status);
|
||||
public static native void setPWM(ByteBuffer digital_port_pointer, short value, IntBuffer status);
|
||||
public static native short getPWM(ByteBuffer digital_port_pointer, IntBuffer status);
|
||||
public static native void setPWMPeriodScale(ByteBuffer digital_port_pointer, int squelchMask, IntBuffer status);
|
||||
|
||||
@@ -54,8 +54,8 @@ public class PCMTest extends AbstractComsSetup {
|
||||
fakePressureSwitch = new DigitalOutput(11);
|
||||
fakeCompressor = new AnalogInput(1);
|
||||
|
||||
solenoid1 = new Solenoid(0);
|
||||
solenoid2 = new Solenoid(1);
|
||||
solenoid1 = new Solenoid(7);
|
||||
solenoid2 = new Solenoid(6);
|
||||
|
||||
fakeSolenoid1 = new DigitalInput(12);
|
||||
fakeSolenoid2 = new DigitalInput(13);
|
||||
|
||||
@@ -68,8 +68,8 @@ public final class TestBench {
|
||||
/* CAN ASSOICATED CHANNELS */
|
||||
public static final int kCANRelayPowerCycler = 1;
|
||||
public static final int kFakeJaguarPotentiometer = 1;
|
||||
public static final int kFakeJaguarForwardLimit = 16;
|
||||
public static final int kFakeJaguarReverseLimit = 17;
|
||||
public static final int kFakeJaguarForwardLimit = 20;
|
||||
public static final int kFakeJaguarReverseLimit = 21;
|
||||
public static final int kCANJaguarID = 2;
|
||||
|
||||
//THESE MUST BE IN INCREMENTING ORDER
|
||||
@@ -310,12 +310,12 @@ public final class TestBench {
|
||||
|
||||
@Override
|
||||
protected DigitalInput giveInputTwo() {
|
||||
return new DigitalInput(14);
|
||||
return new DigitalInput(18);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DigitalInput giveInputOne() {
|
||||
return new DigitalInput(15);
|
||||
return new DigitalInput(19);
|
||||
}
|
||||
};
|
||||
return relay;
|
||||
|
||||
@@ -14,6 +14,43 @@ TLogLevel pwmJNILogLevel = logWARNING;
|
||||
else Log().Get(level)
|
||||
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_wpilibj_hal_PWMJNI
|
||||
* Method: allocatePWMChannel
|
||||
* Signature: (Ljava/nio/ByteBuffer;Ljava/nio/IntBuffer;)Z
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL Java_edu_wpi_first_wpilibj_hal_PWMJNI_allocatePWMChannel
|
||||
(JNIEnv * env, jclass, jobject id, jobject status)
|
||||
{
|
||||
PWMJNI_LOG(logDEBUG) << "Calling DIOJNI allocatePWMChannel";
|
||||
void ** javaId = (void**)env->GetDirectBufferAddress(id);
|
||||
PWMJNI_LOG(logDEBUG) << "Port Ptr = " << *javaId;
|
||||
jint * statusPtr = (jint*)env->GetDirectBufferAddress(status);
|
||||
PWMJNI_LOG(logDEBUG) << "Status Ptr = " << statusPtr;
|
||||
jbyte returnValue = allocatePWMChannel(*javaId, statusPtr);
|
||||
PWMJNI_LOG(logDEBUG) << "Status = " << *statusPtr;
|
||||
PWMJNI_LOG(logDEBUG) << "allocatePWMChannelResult = " << (jint)returnValue;
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_wpilibj_hal_PWMJNI
|
||||
* Method: freePWMChannel
|
||||
* Signature: (Ljava/nio/ByteBuffer;Ljava/nio/IntBuffer;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_PWMJNI_freePWMChannel
|
||||
(JNIEnv * env, jclass, jobject id, jobject status)
|
||||
{
|
||||
PWMJNI_LOG(logDEBUG) << "Calling DIOJNI freePWMChannel";
|
||||
void ** javaId = (void**)env->GetDirectBufferAddress(id);
|
||||
PWMJNI_LOG(logDEBUG) << "Port Ptr = " << *javaId;
|
||||
jint * statusPtr = (jint*)env->GetDirectBufferAddress(status);
|
||||
PWMJNI_LOG(logDEBUG) << "Status Ptr = " << statusPtr;
|
||||
freePWMChannel(*javaId, statusPtr);
|
||||
PWMJNI_LOG(logDEBUG) << "Status = " << *statusPtr;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_wpilibj_hal_PWMJNI
|
||||
* Method: setPWM
|
||||
|
||||
Reference in New Issue
Block a user