NXC direct IO pin access
-
- Posts: 1818
- Joined: 02 Oct 2010, 02:19
- Location: Michigan USA
- Contact:
NXC direct IO pin access
John, is there a way to write the IO pins (5 and 6) high and low with NXC?
Matt
http://mattallen37.wordpress.com/
I'm all for gun control... that's why I use both hands when shooting
http://mattallen37.wordpress.com/
I'm all for gun control... that's why I use both hands when shooting
Re: NXC direct IO pin access
I can say at least that the functions exist to do so. If you look at the NXC API documentation http://bricxcc.sourceforge.net/nbc/nxcd ... index.html under Input Module Functions, the following functions are listed:
and also the following to read the current state:
Code: Select all
void SetSensorDigiPinsDirection(const byte port,const byte & direction)
void SetSensorDigiPinsOutputLevel(const byte port,const byte & outputLevel)
void SetSensorDigiPinsStatus(const byte port, const byte & status)
Code: Select all
byte SensorDigiPinsDirection(const byte port)
byte SensorDigiPinsOutputLevel(const byte port)
byte SensorDigiPinsStatus(const byte port)
Re: NXC direct IO pin access
These functions are all implemented by the IOMapWrite or IOMapRead system call functions and either read from or modify the input module IOMap fields corresponding to the function names. The firmware does not use these fields if you do not set the sensor type to Custom. Here's the relevant code from the input module:
The "DigiPinsStatus" status field in the IOMap is really read only since it is always overwritten by the firmware with the value read from hardware and never used to pass information to the device on the specified port. The pin status will contain the status (0 or 1) of both pin 0 and pin 1 OR-ed together. E.G., the value might be 0, 1, 2, or 3 depending on the set or cleared state of the 2 digital pins.
As you can see from the code, you pick which pin to control via the "DigiPinsDirection" field (setting bit 1 for pin 0 and bit 2 for pin 1 and both bits for both pins). You set or clear the pin via the "DigiPinsOutputLevel" field. The same bits in "outputLevel" are used in the above function to decide whether to set or clear the pin. The way this function is written with the "else" clause after the check for DigiPinsDir & 0x02 looks like a bug to me. I'm not sure what was intended here, but it looks like if you don't set or clear pin 1 then a function is called for pin 1 that its equivalent for pin 0 does not get called via an else clause on the first if statement. Calling either dInputClearDigi* or dInputSetDigi* sets the direction of the pin to Out but - as written - nothing ever changes the direction of pin 0 to In while the else clause does give you a way to set the direction of pin 1 to In (by leaving the second bit clear in the DigiPinsDir field). I shall probably add the else clause to the first if statement so that it calls dInputSetDirInDigi0 when the pin 0 bit is not set in the DigiPinsDirection field.
John Hansen
Code: Select all
void cInputSetupCustomSensor(UBYTE Port)
{
if ((IOMapInput.Inputs[Port].DigiPinsDir) & 0x01)
{
if ((IOMapInput.Inputs[Port].DigiPinsOut) & 0x01)
{
dInputSetDigi0(Port);
}
else
{
dInputClearDigi0(Port);
}
}
if ((IOMapInput.Inputs[Port].DigiPinsDir) & 0x02)
{
if ((IOMapInput.Inputs[Port].DigiPinsOut) & 0x02)
{
dInputSetDigi1(Port);
}
else
{
dInputClearDigi1(Port);
}
}
else
{
dInputSetDirInDigi1(Port);
}
if (CUSTOMACTIVE == (IOMapInput.Inputs[Port].CustomActiveStatus))
{
dInputSetActive(Port);
}
else
{
if (CUSTOM9V == (IOMapInput.Inputs[Port].CustomActiveStatus))
{
dInputSet9v(Port);
}
else
{
dInputSetInactive(Port);
}
}
}
As you can see from the code, you pick which pin to control via the "DigiPinsDirection" field (setting bit 1 for pin 0 and bit 2 for pin 1 and both bits for both pins). You set or clear the pin via the "DigiPinsOutputLevel" field. The same bits in "outputLevel" are used in the above function to decide whether to set or clear the pin. The way this function is written with the "else" clause after the check for DigiPinsDir & 0x02 looks like a bug to me. I'm not sure what was intended here, but it looks like if you don't set or clear pin 1 then a function is called for pin 1 that its equivalent for pin 0 does not get called via an else clause on the first if statement. Calling either dInputClearDigi* or dInputSetDigi* sets the direction of the pin to Out but - as written - nothing ever changes the direction of pin 0 to In while the else clause does give you a way to set the direction of pin 1 to In (by leaving the second bit clear in the DigiPinsDir field). I shall probably add the else clause to the first if statement so that it calls dInputSetDirInDigi0 when the pin 0 bit is not set in the DigiPinsDirection field.
John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
http://bricxcc.sourceforge.net/
Who is online
Users browsing this forum: No registered users and 7 guests