Simulated Microcontroller Digital Inputs/Digital Outputs
The MxV uC library simulates a generic DIO sub-system of a typical microcontroller. The library provides an interface to the simulated DIO used for:
•Configuring up to 256 ports (ports range from 0 to 255; each port contains 8 I/O pins)
•Configuring individual pins as inputs or outputs
•Reading the state of input pins
•Setting the state of an output pins
•Generating an interrupt request when the state of an input pin changes
Harnessing the DIO capabilities of the simulated MxV µC is very easy and straight forward. As with all MxV µC sub-systems, the DIO sub-system must be initialized before it is used. To initialize the DIO sub-system, add a call to: void MxVuC_DIO_Initialize(void) in your application initialization code or add it to the following function in the 'AppIF.c' file: void SUT_Init(void) |
There are two ways of configuring I/O pins as inputs or outputs. Both ways accomplish the same goal, but one of them might prove more useful in one situation over another. To configure individual pins as inputs or outputs without affecting the configuration of other pins on the same port, use the following for inputs: void MxVuC_DIO_ConfigInput( mxvU8 port, mxvU8 input_mask) For outputs, use: void MxVuC_DIO_ConfigOutput( mxvU8 port, mxvU8 input_mask) 'port' is the port which contains pins of interest (valid ports range from 0 to 255). 'input_mask' contains 8 bits for each of the 8 pins on the 'port'. Bit 0 corresponds to pin 1, bit 1 corresponds to pin 2, and so on. A pin is configured as an input or an output (depending on which function is called) if its corresponding bit is 1. If a bit is 0, the configuration for its corresponding pin is not touched. For example, to configure pins 3 and 4 on port 2 as outputs: #define PIN3_MASK 0x08 #define PIN4_MASK 0x10 MxVuC_DIO_ConfigOutput(2, PIN3_MASK | PIN4_MASK); In other cases, it might be easier to configure an entire port at once. Calling: void MxVuC_DIO_SetConfig( mxvU8 port, mxvU8 cfg_mask) allows for configuring every pin on 'port' in a single function call. 'cfg_mask' contains 8 bits for each of the 8 pins on 'port'. Bit 0 corresponds to pin 1, bit 1 corresponds to pin 2, and so on. A pin is configured as an input if its corresponding bit is 0. A pin is configured as an output if its corresponding bit is 1. Note that calling this function does affect the configuration of every pin on 'port'. To find the current configuration of an entire port, call: mxvU8 MxVuC_DIO_GetConfig( mxvU8 port) This function returns the current configuration of an entire port. The DIO sub-system allows for reconfiguring all ports and pins at any point in the program. |
Output pins can be set (setting its state to HIGH), cleared (setting its state to LOW), and toggled (HIGH to LOW, LOW to HIGH). To set the state of one or more output pins to HIGH, call: void MxVuC_DIO_Set( mxvU8 port, mxvU8 mask) To set the state of one or more output pins to LOW, call: void MxVuC_DIO_Clear( mxvU8 port, mxvU8 mask) To toggle the state of one or more output pins, call: void MxVuC_DIO_Toggle( mxvU8 port, mxvU8 mask) 'port' is the port which contains the pins of interest. 'mask' contains 8 bits for each of the 8 pins on 'port'. Calling these functions updates the state of output pins whose corresponding bits are set to 1. For example, to toggle output pin 1 on port 5: #define PIN1_MASK 0x02 MxVuC_DIO_Toggle(5, PIN1_MASK) An entire port can be updated with a single function call: void MxVuC_DIO_Write( mxvU8 port, mxvU8 state) This function updates all output pins on 'port' (if 'port' contains input pins, their state is not affected or changed). An output pin state is set to HIGH if its corresponding bit is set to 1, otherwise the output pin state will be cleared (set to LOW). It is highly recommended that output pins states be set or cleared before being configured as outputs (this applies to microcontroller code more than MxV code). This ensures that the output state is latched internally before enabling that latched state (which could be different from what is desired on power-up) to appear on the output pin. |
The state of input and output pins can be read by calling: mxvBool MxVuC_DIO_Get( mxvU8 port, mxvU8 mask) The returned value is 'mxvTrue (1)' if all of the pins in the mask are set (mxvFalse (0) otherwise). An entire port can be read with a single function call: mxvU8 MxVuC_DIO_Read( mxvU8 port) This function returns the state of all pins on 'port'. An input or an output pin is HIGH if its corresponding bit is set to 1, otherwise the pin is LOW. |
The following macros, defined in 'uC_dio.h' (this header file is automatically included when 'mxv_uC.h' is included), are provided to assist in harnessing DIO signals: MXVUC_DIO_INPUT(sig_name, port, pin) MXVUC_DIO_OUTPUT(sig_name, port, pin) where 'MXVUC_DIO_INPUT' is used to harness digital input signals to the SUT (the application code) and 'MXVUC_DIO_OUTPUT' is used to harness digital output signals to the SUT. 'sig_name' is the name that will be used and displayed by MxV. 'port' is the port the pin is on. 'pin' is the pin number. Note: The pin required here is NOT the mask. For pin 0, enter 0, for pin 7 enter 7, For example: //Configure the Low Power Detect to use pin 0 on port 2 MXVUC_DIO_INPUT("Low Power Detect", 0x02, 0x00) //Configure the Charging output to use pin 1 on port 2 MXVUC_DIO_OUTPUT("Charging", 0x02, 0x01) These two macros should be used when defining input and output signals in 'PortDefs[]' in AppIF.c |
The DIO sub-system can be configured to generate an interrupt request when the state of a digital input changes. The generated interrupt request is serviced when the application code is not being executed (MxV µC interrupts never interrupt the application code). There are several steps needed to configure the DIO sub-system to generate the above interrupt request: 1.The digital input that needs to generate an interrupt request must be harnessed in the 'AppIF.c' file using the macro 'MXVUS_DIO_INPUT'. The macro definition of 'MXVUC_DIO_INPUT' provides a callback function 'MxVuC_DIO_DIL_Handler' that is executed when any digital input changes. 2.The address of the interrupt service routine must be located at offset 'MxVuC_Vector_DIO' in the SUT interrupt vector table 'MxVuC_VectorTableSUT'. 3.The digital input must be configured to enable the interrupt request. This can be accomplished by calling: void MxVuC_DIO_SetIrq( mxvU8 port, mxvU8 output_mask) where 'port' is the port which contains pins of interest. All pins that need to generate an interrupt request must have 1 in their corresponding bit in 'output_mask'. By default, no input pins generate an interrupt request; they must be configured first. After calling the above function, the input pin can generate an interrupt request when its state changes. When the interrupt request is serviced, the interrupt service routine whose address is at 'MxVuC_VectorTableSUT[MxVuC_Vector_DIO]' is executed. MxVuC_DIO_irqPort and MxVuC_DIO_irqMask must be used by the interrupt service routine to figure out which pin on which port caused the interrupt request. When the interrupt service routine is serviced, MxVuC_DIO_irqPort will have the port number that contains the pin whose state has changed. MxVuC_DIO_irqMask contains a 1 in bit corresponding to the input pin whose state has changed. Note that if the state of multiple input pins on the same port or on different ports change at the same time, the interrupt service routine is serviced and executed for every input pin that has changed (if the state of 5 input pins is changed, the interrupt service routine is executed 5 times). The generation of an interrupt request can be disabled on pins which allowed for it by calling: void MxVuC_DIO_ClearIrq( mxvU8 port, mxvU8 output_mask) where 'port' is the port which contains pins of interest. All pins that do not need to generate an interrupt request must have 1 in their corresponding bit in 'output_mask'. Calling: mxvU8 MxVuC_DIO_GetIrq( mxvU8 port) returns the state of all pins for 'port'. All pins that can generate an interrupt request will have a 1 in their corresponding bits. Note that output pins cannot generate an interrupt request even if they are configured to do so. |
For the DIO sub-system to function correctly, MxV needs to inject the state of digital inputs in 'MxVuC_DIO_DIL' and needs to read the state of the digital outputs from 'MxVuC_DIO_Pin'. This is already taken care of when the 'MXVUC_DIO_INPUT' and 'MXVUC_DIO_OUTPUT' macros are used in the 'AppIF.c' file to harness digital inputs and outputs. It is possible to reconfigure a digital input pin to be a digital output or vice versa several times during the application execution. However, if a pin is harnessed by MxV as an output and the application code reconfigures that pin as an input in the middle of executing the program, MxV will report that the output of that pin is high-impedance (since the pin doesn't drive or control the line anymore to HIGH or LOW). |
#define LED_PORT 0x0A
#define LED_PIN 4
#define LED_MASK (1<<LED_PIN)
#define SWITCH_PORT 0x0A
#define SWITCH_PIN 5
#define SWITCH_MASK (1<<SWITCH_PIN)
//In AppIF.c portdef table
//Note the portdef table uses the PIN not the MASK
MXVUC_DIO_OUTPUT("LED", LED_PORT, LED_PIN)
MXVUC_DIO_INPUT("Switch", SWITCH_PORT, SWITCH_PIN)
//Somewhere in the target code
//Note the API calls uses the MASK not the PIN
MxVuC_DIO_Clear(LED_PORT, LED_MASK);
MxVuC_DIO_ConfigOutput(LED_PORT, LED_MASK);
MxVuC_DIO_ConfigInput(SWITCH_PORT, SWITCH_MASK);
Linking your code with the MxVMC