|
|||
| Did you know...
|
Serial Wombat Pin Mode Software Development Kit Example 3: Initialization CommandsIn example 2, we created a simple example which toggled a pin after some preset period of time by using a counter which was stored in the persistent data area for a pin. In this example we will show how to process incoming communications packets in the initialization commands. We will allow the user of our pin mode to set the high and low times of the wave form. There are two 8 byte buffers used for communcations: rxbuffer and txbuffer. You can find them declared in globals.c. The Initialization command can act on data in the rxbuffer, and write data into the txbuffer. The 8 byte response in txbuffer is sent to the host upon exiting your init function. Before entering your function the rxbuffer array is copied to txbuffer. Therefore, if you simply wish to echo the input packet back to the host, no changes in txbuffer are necessary. rxbuffer[0] holds the high level command. If your init function is called, rxbuffer[0] will have a value between 200 and 209, inclusive. You can use this value to choose between various actions in your init function. rxbuffer[1] contains the physical pin number being configured. This value is used by the system to load and store the tp buffer to the proper location in the array of pin data. This value is seldom useful to the pin mode code. rxbuffer[2] contains the mode the pin is being configured to. This value tells the system which initialization function to call. This value is never useful to the pin mode code. rxbuffer[3] through rxbuffer[7] can be defined by the pin mode. These values can be used to configure the operation of the pin mode. By Serial Wombat convention, multi-byte values are sent most-significant byte first. This is often inconvenient for programmers, because Intel computers and the C18 compiler used in the SDK store values in little-endian mode. However, big-endian numbers are substantially easier for humans to read and compute by sight. Therefore they are used for the Wombat protocol. A macro is provided in utilities.h called ASSIGN_RXBUFFER16 which will move a 16bit value in the rxbuffer to a 16bit variable, properly reversing the byte order. For example: // Copy 16 bit value from rxbuffer[5] and rxbuffer[6] to // tp.somemode.some16bitvalue ASSIGN_RXBUFFER16(tp.somemode.some16bitvalue, 5);
Example 3 Code: Modify Example 2 code to allow the user to specify the number of high and low frames.In types.h:
typedef union _pin_register_t{
uint8 bytes[16];
struct generic_n {
uint8 bytes[8];
uint16 buffer;
uint8 mode;
uint8 hw_mode;
uint8 duty_cycle;
uint8 hw_counter;
uint8 hw_support;
} generic;
struct example2_n{
uint8 counter;
} example2;
struct example3_n{
uint16 counter;
uint16 high_to_low;
uint16 low_to_high;
} example3;
} pin_register_t;
in user_code.c:
void init_user_code (void)
{
if (rxbuffer[0] == CONFIGURE_CHANNEL_MODE_0)
{
//Do something here in response to a 200 command
// High to low point is in rxbuffer[3] and rxbuffer[4]
ASSIGN_RXBUFFER16(tp.example3.high_to_low, 3);
// low to high point is in rxbuffer[5] and rxbuffer[6]
ASSIGN_RXBUFFER16(tp.example3.low_to_high, 5);
tp.example3.counter = 0;
vpin_high();
}
}
void update_user_code()
{
//This function is called periodically, after the first time
//an init function for the pin is called
if (tp.example3.counter == 0)
{
vpin_high();
}
else if (tp.example3.counter == tp.example3.high_to_low)
{
vpin_low();
}
++tp.example3.counter;
if (tp.example3.counter == tp.example3.low_to_high)
{
tp.example3.counter = 0;
}
}
As before in example 1, build the project, then run it through sdkextract.exe. Download using Xmodem. Once you've downloaded the pin mode into the Wombat, issue the command: 200 20 0xF0 0x0100 0x0200 0x55 This will set the pulse to 256 frames high, and 256 frames low (the second number above, 0x200, indicates the shutoff time, not the duration of the pulse). Attaching an oscilloscope to pin 20 shows the following:
This shows that our sample mode is working. As expected, the pin outputs a waveform of 256 frames high, and 256 frames low. In the capture above the period of each is measured slightly greater than 256ms. This is due to the fact that the measurement by the scope is imprecise, and the fact that the internal oscillator of the Wombat's 18F4620 microcontroller can vary by up to 1%. Since each pin has its own set of variables which get copied in and out of tp as the pin is serviced, it is possible to use the same code to drive two pins with two different values. We'll set pin 20 as above, then set pin 21 to turn on for 32 cycles, then turn off and wait until a total of 512 frames have passed.
The result (channel 1 attached to pin 20 and channel 2 attached to pin 21):
Note that the two pulses are not in sync; that is, neither the rising or falling edges coincide. This is due to the fact that each pin has its own counter, so when each counter is set to 0 depends on when the configuration message for each pin was received. If only there was a way to share a counter across multiple pins, so the rise of the pulse could be synchronized...
|
||
Copyright Wombat Interface Products, 2005-2008. All Rights Reserved.