Go to Post A Guru teaching batteries at Exide: "Do not draw your power from up here, by your terminals. You must reach down deep into your plates and pull the energy from your entire being! You must prove yourself worthy to be FIRST power cells!" - KenWittlief [more]
Home
Go Back   Chief Delphi > Technical > Programming > Java
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Reply
Thread Tools Rate Thread Display Modes
  #1   Spotlight this post!  
Unread 18-10-2011, 02:36
AllenGregoryIV's Avatar
AllenGregoryIV AllenGregoryIV is online now
Engineering Coach
AKA: Allen "JAG" Gregory
FRC #3847 (Spectrum)
Team Role: Coach
 
Join Date: Jul 2008
Rookie Year: 2003
Location: Texas
Posts: 2,560
AllenGregoryIV has a reputation beyond reputeAllenGregoryIV has a reputation beyond reputeAllenGregoryIV has a reputation beyond reputeAllenGregoryIV has a reputation beyond reputeAllenGregoryIV has a reputation beyond reputeAllenGregoryIV has a reputation beyond reputeAllenGregoryIV has a reputation beyond reputeAllenGregoryIV has a reputation beyond reputeAllenGregoryIV has a reputation beyond reputeAllenGregoryIV has a reputation beyond reputeAllenGregoryIV has a reputation beyond repute
Send a message via AIM to AllenGregoryIV
Programming an SPI sensor in Java

Has any one successfully used the SPI bus in Java. I'm about to start a project and looking for sample code. I know about the tSPI class but I haven't looked in to it in depth yet.

Thanks,
Allen Gregory
__________________

Team 647 | Cyber Wolf Corps | Alumni | 2003-2006 | Shoemaker HS
Team 2587 | DiscoBots | Mentor | 2008-2011 | Rice University / Houston Food Bank
Team 3847 | Spectrum | Coach | 2012-20... | St Agnes Academy
LRI | Alamo Regional | 2014-20...
"Competition has been shown to be useful up to a certain point and no further, but cooperation, which is the thing we must strive for today, begins where competition leaves off." - Franklin D. Roosevelt
Reply With Quote
  #2   Spotlight this post!  
Unread 19-10-2011, 10:44
charrisTTI charrisTTI is offline
Ramblin' Wreck
AKA: Charles Harris
FRC #0623
Team Role: Mentor
 
Join Date: Jan 2005
Rookie Year: 2003
Location: Vienna, VA
Posts: 106
charrisTTI has a spectacular aura aboutcharrisTTI has a spectacular aura about
Send a message via AIM to charrisTTI
Re: Programming an SPI sensor in Java

We tried SPI a couple of years ago using java. A lot of trial and error with the API if I remember correctly. Also needed some "glue hardware" since pins are either output or input on cRIO, but devices had single pin used for both.

First block is used to interface with optical mouse chip.
Second block shows how first was called.
Third block is used to interface with magnetic rotary encoder.

Hope this helps.


Code:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package edu.wpi.first.frc623;

import edu.wpi.first.wpilibj.DigitalModule;
import edu.wpi.first.wpilibj.SensorBase;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.fpga.tSPI;

/**
 *
 * @author charris
 */
public class PAN3101OpticalMouse extends SensorBase {

    // register map from datasheet
    private static final char OPERATION_MODE_1 = 0x00;
    private static final char PRODUCT_ID1 = 0x01;
    private static final char DELTA_Y_1 = 0x02;
    private static final char DELTA_X_1 = 0x03;
    private static final char IMAGE_QUALITY_1 = 0x04;

    private static final char PRODUCT_ID2_A = 0x14;
    private static final char PRODUCT_ID2_B = 0x15;
    private static final char MOTION_STATUS = 0x16;
    private static final char DELTA_X_2 = 0x17;
    private static final char DELTA_Y_2 = 0x18;
    private static final char IMAGE_QUALITY_2 = 0x19;
    private static final char OPERATION_MODE_2 = 0x1A;
    private static final char CONFIGURATION = 0x1B;

    private static final char OPERATION_MODE_3 = 0x40;
    private static final char PRODUCT_ID3 = 0x41;
    private static final char DELTA_Y_3 = 0x42;
    private static final char DELTA_X_3 = 0x43;
    private static final char IMAGE_QUALITY_3 = 0x44;

    private static final char WRITE_REGISTER = 0x80;

    private static final char RES_400_CPI = 0x80;
    private static final char FULL_RESET = 0x80;
    private static final char SLEEP_DISABLE = 0x01;
    private static final char DEFAULT_MODE = 0x00;

    tSPI spi;
    DigitalModule module;
    int slot;
    int clockPin;
    int dataOutPin;
    int dataInPin;
    int inhibitPin;

    public PAN3101OpticalMouse( int slotParam, int clockPinParam, int dataOutPinParam, int dataInPinParam, int inhibitPinParam )
    {
        slot = slotParam;
        clockPin = clockPinParam;
        dataOutPin = dataOutPinParam;
        dataInPin = dataInPinParam;
        inhibitPin = inhibitPinParam;

        // get our module
        module = DigitalModule.getInstance(slot);

        // create SPI instance
        //spi = new tSPI();

        // allocate our pins
        module.allocateDIO(clockPin, false);
        module.allocateDIO(dataOutPin, false);
        module.allocateDIO(dataInPin, true);
        module.allocateDIO(inhibitPin, false);

    }

    public void intialize()
    {
        // reset the chip
        module.setDIO(clockPin, false);
        Timer.delay(0.01);
        module.setDIO(clockPin, true);
        Timer.delay(0.001);
        module.setDIO(clockPin, false);
        Timer.delay(0.01);

        // setup for SPI
        tSPI.writeChannels_SCLK_Module(DigitalModule.slotToIndex(slot));
        tSPI.writeChannels_SCLK_Channel(DigitalModule.remapDigitalChannel(clockPin-1));

        tSPI.writeChannels_MOSI_Module(DigitalModule.slotToIndex(slot));
        tSPI.writeChannels_MOSI_Channel(DigitalModule.remapDigitalChannel(dataOutPin-1));

        tSPI.writeChannels_MISO_Module(DigitalModule.slotToIndex(slot));
        tSPI.writeChannels_MISO_Channel(DigitalModule.remapDigitalChannel(dataInPin-1));

        // set clock
        tSPI.writeConfig_ClockPolarity(true);

        //tSPI.writeConfig_FramePolarity(true);
        tSPI.writeConfig_LatchLast(false);
        tSPI.writeConfig_LatchFirst(false);

        // set the width to 8
        tSPI.writeConfig_BusBitWidth(8);

        // data is valid on rising edge of clock
        tSPI.writeConfig_DataOnFalling(false);

        // set the bit order
        tSPI.writeConfig_MSBfirst(true);

        tSPI.strobeReset();
        tSPI.strobeClearReceivedData();

        // call for reset
        putRegister( OPERATION_MODE_1, FULL_RESET );
        Timer.delay(2.0);
        // disable sleep
        putRegister( OPERATION_MODE_1, SLEEP_DISABLE );
        //Timer.delay(2.0);

        // set resolution to 400 cpi
        char configTemp = getRegister(CONFIGURATION);
        //Timer.delay(2.0);
        putRegister(CONFIGURATION, (char)(RES_400_CPI | configTemp ));
        //Timer.delay(2.0);
    }

    public byte getDeltaX()
    {
        return (byte)getRegister(DELTA_X_1);
    }

    public byte getDeltaY()
    {
        return (byte)getRegister(DELTA_Y_1);
    }

    protected char getRegister( char addressParam )
    {
        // select for write
        tSPI.writeChannels_SS_Module(DigitalModule.slotToIndex(slot));
        tSPI.writeChannels_SS_Channel(0);

        // write the data to load
        tSPI.writeDataToLoad(addressParam);

        // strobe out the data
        tSPI.strobeLoad();

        // wait for completion
        while( tSPI.readReceivedElements() == 0 )
        {
            java.lang.Thread.yield();
        }

        // set inhibit
        //module.setDIO(inhibitPin, false);
        tSPI.writeChannels_SS_Module(DigitalModule.slotToIndex(slot));
        tSPI.writeChannels_SS_Channel(DigitalModule.remapDigitalChannel(inhibitPin-1));

        // clear the data to load
        tSPI.writeDataToLoad(0x0);

        // clear received data
        tSPI.strobeClearReceivedData();

        // strobe in the data
        tSPI.strobeLoad();


        // wait for completion
        //while( !tSPI.readStatus_Idle() )
        while( tSPI.readReceivedElements() == 0 )
        {
            java.lang.Thread.yield();
        }

        // strobe in the received data
        tSPI.strobeReadReceivedData();

        // read the data
        long rawData = tSPI.readReceivedData();

        return (char)(rawData & 0xFF);
    }

    protected void putRegister( char addressParam, char dataParam )
    {
        // clear select
        tSPI.writeChannels_SS_Module(DigitalModule.slotToIndex(slot));
        tSPI.writeChannels_SS_Channel(0);

        // get deltax

        // write the adddrss to load
        tSPI.writeDataToLoad(addressParam | WRITE_REGISTER);

        // strobe out the data
        tSPI.strobeLoad();

        // wait for completion
        while( tSPI.readReceivedElements() == 0 )
        {
            java.lang.Thread.yield();
        }

        tSPI.writeChannels_SS_Module(DigitalModule.slotToIndex(slot));
        tSPI.writeChannels_SS_Channel(0);

        // write the data to load
        tSPI.writeDataToLoad(dataParam);

        // clear received data
        tSPI.strobeClearReceivedData();

        // strobe in the data
        tSPI.strobeLoad();

        // wait for completion
        while( tSPI.readReceivedElements() == 0 )
        {
            java.lang.Thread.yield();
        }
        // strobe in the received data
        tSPI.strobeReadReceivedData();

        // read the data
        long rawData = tSPI.readReceivedData();
    }
}
Here is how it was used. Run called by timer thread at frequency sufficient to make sure we did not lose any counts. Optical mouse chip had maximum limit for movement speed. Had problems getting good mechanical mount close enough to the floor. We really needed a different lens to allow mounting further from the floor.


Code:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package edu.wpi.first.frc623;

/**
 *
 * @author charris
 */
public class OpticalMouseEncoder extends Thread {
    private PAN3101OpticalMouse mouse;
    private long totalX;
    private long totalY;

    public OpticalMouseEncoder()
    {
        mouse = new PAN3101OpticalMouse( 4, 1, 2, 3, 4 );
        totalX = 0;
        totalY = 0;
    }

    public void run()
    {
        // initialize the sensor
        mouse.intialize();

        while( true )
        {
            byte deltaX = mouse.getDeltaX();
            byte deltaY = mouse.getDeltaY();

            synchronized( this )
            {
                totalX += deltaX;
                totalY += deltaY;
            }

            try
            {
                this.sleep(10);
            }
            catch( InterruptedException e )
            {
                
            }
        }

    }

    synchronized public void reset()
    {
        totalX = 0;
        totalY = 0;
    }

    synchronized public void resetX()
    {
        totalX = 0;
    }

    synchronized public void resetY()
    {
        totalY = 0;
    }

    synchronized public long getXCounts()
    {
        return totalX;
    }

    synchronized public long getYCounts()
    {
        return totalY;
    }

    public double getXInches()
    {
        return ( (double) getXCounts() ) / 400.0;
    }

    public double getYInches()
    {
        return ( (double) getYCounts() ) / 400.0;
    }
}
Here is class for the magnetic rotary encoder (we ultimately used two analog channels for this sensor to get best performance):

Code:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package edu.wpi.first.frc623;

import edu.wpi.first.wpilibj.DigitalModule;
import edu.wpi.first.wpilibj.SensorBase;
import edu.wpi.first.wpilibj.fpga.tSPI;

/**
 *
 * @author charris
 */
public class AS5030FourWireSPI extends SensorBase {

    public class AS5030Result
    {
        public double angle;
        public int agc;
    }


    tSPI spi;
    DigitalModule module;
    int slot;
    int clockPin;
    int dataOutPin;
    int dataInPin;
    int chipSelectPin;


    public AS5030FourWireSPI( int slotParam, int clockPinParam, int dataOutPinParam, int dataInPinParam, int chipSelectPinParam )
    {
        slot = slotParam;
        clockPin = clockPinParam;
        dataOutPin = dataOutPinParam;
        dataInPin = dataInPinParam;
        chipSelectPin = chipSelectPinParam;
        
        // get our module
        module = DigitalModule.getInstance(slot);

        // create SPI instance
        //spi = new tSPI();

        // allocate our pins
        module.allocateDIO(clockPin, false);
        module.allocateDIO(dataOutPin, false);
        module.allocateDIO(dataInPin, true);
        module.allocateDIO(chipSelectPin, false);

        // setup for SPI
        tSPI.writeChannels_SCLK_Module(DigitalModule.slotToIndex(slot));
        tSPI.writeChannels_SCLK_Channel(DigitalModule.remapDigitalChannel(clockPin-1));

        tSPI.writeChannels_MOSI_Module(DigitalModule.slotToIndex(slot));
        tSPI.writeChannels_MOSI_Channel(DigitalModule.remapDigitalChannel(dataOutPin-1));

        tSPI.writeChannels_MISO_Module(DigitalModule.slotToIndex(slot));
        tSPI.writeChannels_MISO_Channel(DigitalModule.remapDigitalChannel(dataInPin-1));
    }

    public void initialize()
    {
        // set chip select low to start
        module.setDIO(chipSelectPin, true);

        // data is valid on rising edge of clock
        tSPI.writeConfig_DataOnFalling(false);

        // set the bit order
        tSPI.writeConfig_MSBfirst(true);

        tSPI.strobeReset();
        tSPI.strobeClearReceivedData();
    }

    public AS5030Result getData( )
    {
        // select the chip
        module.setDIO(chipSelectPin, false);

        // write the 5 bit command
        // set the width
        tSPI.writeConfig_BusBitWidth(5);

        // write the data to load
        tSPI.writeDataToLoad(0x1F);

        // strobe out the data
        tSPI.strobeLoad();

        // wait for completion
        while( !tSPI.readStatus_Idle() )
        {
            java.lang.Thread.yield();
        }

        // change back to 16 bits
        tSPI.writeConfig_BusBitWidth(16);
        // clear the data to load
        tSPI.writeDataToLoad(0x0);

        // clear received data
        tSPI.strobeClearReceivedData();

        // strobe in the data
        tSPI.strobeLoad();


        // wait for completion
        //while( !tSPI.readStatus_Idle() )
        while( tSPI.readReceivedElements() == 0 )
        {
            java.lang.Thread.yield();
        }

        // strobe in the received data
        tSPI.strobeReadReceivedData();

        // read the data
        long rawData = tSPI.readReceivedData();

        // deselect the chip
        module.setDIO(chipSelectPin, true);

        AS5030Result result = new AS5030Result();

        long rawAngle = rawData & 0xFF;

        int agc = (int)((rawData >> 8) & 0x3F);

        result.angle = (double)rawAngle * 360.0 / 256.0;
        result.agc = agc;
        
        return result;
    }
}
__________________
FRC 623 2003,2004,2005,2006,2007,2008, 2009, 2010, 2011
FRC 1900 2007
FVC 60 and 193 2006
FVC 3271 2007
FTC 226 and 369 2008, 2009, 2010, 2011
FTC 3806 2010
Reply With Quote
  #3   Spotlight this post!  
Unread 19-10-2011, 13:14
AllenGregoryIV's Avatar
AllenGregoryIV AllenGregoryIV is online now
Engineering Coach
AKA: Allen "JAG" Gregory
FRC #3847 (Spectrum)
Team Role: Coach
 
Join Date: Jul 2008
Rookie Year: 2003
Location: Texas
Posts: 2,560
AllenGregoryIV has a reputation beyond reputeAllenGregoryIV has a reputation beyond reputeAllenGregoryIV has a reputation beyond reputeAllenGregoryIV has a reputation beyond reputeAllenGregoryIV has a reputation beyond reputeAllenGregoryIV has a reputation beyond reputeAllenGregoryIV has a reputation beyond reputeAllenGregoryIV has a reputation beyond reputeAllenGregoryIV has a reputation beyond reputeAllenGregoryIV has a reputation beyond reputeAllenGregoryIV has a reputation beyond repute
Send a message via AIM to AllenGregoryIV
Re: Programming an SPI sensor in Java

Thank you charrisTTI, that looks like it should help us out a lot.
__________________

Team 647 | Cyber Wolf Corps | Alumni | 2003-2006 | Shoemaker HS
Team 2587 | DiscoBots | Mentor | 2008-2011 | Rice University / Houston Food Bank
Team 3847 | Spectrum | Coach | 2012-20... | St Agnes Academy
LRI | Alamo Regional | 2014-20...
"Competition has been shown to be useful up to a certain point and no further, but cooperation, which is the thing we must strive for today, begins where competition leaves off." - Franklin D. Roosevelt
Reply With Quote
Reply


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump


All times are GMT -5. The time now is 18:54.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi