3.j. Orangutan SVP Functions

Overview

The Orangutan SVP is based on the AVR ATmega324 or ATmega1284 processor. It has an auxiliary processor that provides the USB connection, five configurable input lines, and battery voltage reading. Several parts of the Pololu AVR C/C++ Library have built-in support for using the auxiliary processor, so you will not need to worry about the details of the Serial Peripheral Interface (SPI) protocol used to talk to the auxiliary processor. If you are curious about the details of the SPI protocol, you can read the C++ source code of the library.

Complete documentation of the SVP-specific functions can be found in Section 13 of the Pololu AVR Library Command Reference.

An overview of the analog input functions, which support reading the analog inputs on the SVP’s auxiliary processor, can be found in Section 3.a. An overview of the serial port communication functions, which support sending and receiving bytes from the computer via the auxiliary processor’s USB connection, can be found in Section 3.h.

Setting the mode

One of the first things to think about when writing a program for the SVP is what mode you want the auxiliary processor to be in.

If you want to use quadrature encoders, you can use the SVP_MODE_ENCODERS mode and let the auxiliary processor handle the readings from two quadrature encoders on lines A, B, C and D/RX.

If you want to maximize the number of analog inputs available, you can use the SVP_MODE_ANALOG mode which makes A, B, C, and D/RX be analog inputs. The ADC/SS line is also available as an analog input. It is hardwired to a user trimpot, but you can cut the labeled trace between ADC/SS and POT on the bottom of the board to disconnect the pot, and then connect something else to that pin. This allows you to use a total of 13 analog inputs: eight on the AVR and five on the auxiliary processor. All 13 inputs can be read using the same functions (see Section 3.a), so you don’t need to worry too much about which processor is converting them.

If you want to receive TTL-level serial bytes on your computer, you can use the SVP_MODE_RX mode (the default) which makes A, B, and C be analog inputs and D/RX be the serial receive line. In this mode, TTL-level serial bytes received on the RX line will be sent to the computer on the Pololu Orangutan SVP TTL Serial Port. The RX line, along with the TX line (which is always the serial transmit line) make the Orangutan SVP’s auxiliary processor function as a USB-to-TTL-serial adapter for your computer, allowing you to control serial devices from your computer. Alternatively, you can control the serial devices directly from the AVR using the functions in Section 3.h and you can use the RX line to monitor and debug the bytes that are being transmitted (or received) by the AVR.

You can use the setMode() command at the beginning of your program to set the mode of the auxiliary processor. See the Pololu AVR Library Command Reference for details.

Powered by SPI

Whenever you call a function in the Pololu AVR Library that uses the auxiliary processor, the function might initiate SPI communication to the auxiliary processor. This means that the MOSI (PB5) and SCK (PB7) pins will be set to outputs, the MISO (PB6) pin will be set as an input, a pull-up resistor will be enabled on SS (PB4) if it is an input, and the AVR’s hardware SPI module will be enabled. The functions that do this include any analog input function that uses an input on the auxiliary processor, any function for reading the battery voltage or trimpot, any serial port function that uses the USB_COMM port, and any function specific to the Orangutan SVP (Section 13 of the Command Reference).

PB4 should be an output

In order for the functions that talk to the auxiliary processor to work, the SS (PB4) pin must either be an output or be an input that is always high. The AVR’s SPI module is designed so that if SS is an input and it reads low (0 V), then the SPI module will automatically go in to slave mode (the MSTR bit in SPCR will become zero), making it impossible to communicate with the auxiliary processor. Therefore, it is recommended that you make SS an output at the beginning of your program. This can be done with one of the following lines of code:

set_digital_output(IO_B4, LOW);  // Make SSbar an output (C only)
OrangutanDigital::setOutput(IO_B4, LOW);  // Make SSbar an output (C++ only)
DDRB |= 1<<DDB4;  // Make SSbar an output

Usage Examples

This library comes with an example program in libpololu-avr\examples.

1. svp1

A simple example that demonstrates some SVP-specific functions.

#include <pololu/orangutan.h>

/*
 * svp1: for the Orangutan SVP.
 *
 * This example uses the OrangutanSVP functions to set the mode of the
 * auxiliary processor, take analog readings on line D/RX, and display
 * information about the Orangutan's current USB device state on the LCD.
 *
 * http://www.pololu.com/docs/0J20
 * http://www.pololu.com
 * http://forum.pololu.com
 */

int main()
{
  // Make SSbar be an output so it does not interfere with SPI communication.
  set_digital_output(IO_B4, LOW);

  // Set the mode to SVP_MODE_ANALOG so we can get analog readings on line D/RX.
  svp_set_mode(SVP_MODE_ANALOG);

  while(1)
  {
    clear(); // Erase the LCD.

    if (usb_configured())
    {
      // Connected to USB and the computer recognizes the device.
      print("USB");
    }
    else if (usb_power_present())
    {
      // Connected to USB.
      print("usb");
    }

    if (usb_suspend())
    {
      // Connected to USB, in the Suspend state.  
      lcd_goto_xy(4,0);
      print("SUS");
    }

    if (dtr_enabled())
    {
      // The DTR virtual handshaking line is 1.
      // This often means that a terminal program is conencted to the
      // Pololu Orangutan SVP USB Communication Port.
      lcd_goto_xy(8,0);
      print("DTR");
    }

    if (rts_enabled())
    {
      // The RTS virtual handshaking line is 1.
      lcd_goto_xy(12,0);
      print("RTS");
    }

    // Display an analog reading from channel D, in millivolts.
    lcd_goto_xy(0,1);
    print("Channel D: ");
    print_long(analog_read_millivolts(CHANNEL_D));

    // Wait for 100 ms, otherwise the LCD would flicker.
    delay_ms(100);
  }
}