Page 4 of 10 FirstFirst 12345678 ... LastLast
Results 31 to 40 of 92

Thread: Open Laser Show DAC (USB)

  1. #31
    Join Date
    Feb 2009
    Location
    East Coast of Southern Virginia
    Posts
    536

    Default

    If you look in OLSD.C you will find a main() function. ... look for the comments "Load DAC A" and "Load DAC B".

    E
    // Load DAC A
    // X X X PowerMode Load Output AddrB AddrA
    // pull down chip select!
    spi_word = 0b0111000000000000 | (dy << 4) | ((dxy & 0xF0) >> 4);
    portb.bit2 = 0;
    SPDR = spi_word >> 8;
    while (!(SPSR & (1 << SPIF)));
    SPDR = spi_word & 0x00FF;
    while (!(SPSR & (1 << SPIF)));
    // pull up chip select!
    portb.bit2 = 1;
    asm("nop");
    The microchip SPI DAC communicates serially over an SPI port. Its packet or command word is 16 bits in length. The first thing we do is assemble that command word. Since there are 2 DACs in one package part of the command word addresses DAC A.

    Next we set Bit2 of PortB to 0. This is the Chip Select for the DAC. This tells the DAC that any communications on the SPI bus is meant for it. The chip select is active low (meaning a 0 selects the DAC and a 1 deselects the DAC).

    Now we write the upper Byte (8 bits) of the 16 bit DAC word. We do this by shifting it down 8 bits and setting the SPI Data Register (SPDR) to the Byte.

    Next we poll (check continuously) the SPI Status Register to see that the Byte has been written. Once it is written we can write the lower 8 bits of the DAC word. We wait for that to write also before continuing on. Once the lower byte has been written we deselect the DAC and waste 1 cpu cycle by executing a NOP instruction.

    We have to deselect the DAC before writing the next word to it and we have to wait a predetermined amount of time. It has been a while since I looked at the data sheet however I a pretty sure it has to be done like that.

    Then we do the same to load DAC B.

    Then we set the colors and pull the load DAC line low to output the values we buffered in the DAC. This insures that we update all outputs nearly instantaneously.

    You will find the same code in the Arduino Library if you look in the OLSD.cpp file at the OLSD::OutputPoint() function.

    The rest of the code is for the point output timer, the safety timer and communications.

    Replacing the XY DAC output code should be fairly straightforward. Don't forget the port initializations. Those are really important.

    I hope this helps.

  2. #32
    Join Date
    Feb 2009
    Location
    East Coast of Southern Virginia
    Posts
    536

    Default

    You should be able to put in unsigned 16 bit integers for X and Y into the OutputPoint() function. It rescales them to 12 bit unsigned numbers internally. So your range should be 0 to 65535. The circle example rescales the +-floating point numbers to unsigned 16 bit integers. There should be no magic numbers.

    - - - Updated - - -

    Magic numbers are probably a sign of communications issues with your DAC as you have guessed already.

  3. #33
    Join Date
    May 2013
    Location
    Fort Mill, SC
    Posts
    556

    Default

    Thank you cfavreau. I was able to change the code in the place you suggested and I am able to display all test patterns now. Thank you for that. I did have to change the SPI settings to match my DAC. My DAC is not capable of running at 8MHz clock so I had to lower that to 4MHz. I did notice though that the DAC you are using can take a 20MHz clock that is pretty good and it has me thinking I may just change to that style. But for now things are working the way they should.

    The code for the circle still does not want to pass the full 16 bit number, not sure why. The code makes sense to me that it should pass the 16 bit number then shift it to make a 12 bit number. But honestly I don't really care about that anymore since I am really trying to work on getting my Arduino compatible with a future purchase of LSX.

  4. #34
    Join Date
    Feb 2009
    Location
    East Coast of Southern Virginia
    Posts
    536

    Default

    I am happy that you got things straight. The Microchip DAC is a great value. It costs less than $3 in single quantities and in general is very nice. It has a 1us (1MHz) settling time so it is fairly fast too. I spent a lot of time looking at various DAC solutions.

    Care to post your circle drawing code? I am curious as to why it is being goofy.

  5. #35
    Join Date
    May 2013
    Location
    Fort Mill, SC
    Posts
    556

    Default

    Below is the code I was testing. Since your code using trig to make a circle was not working, I decided to use a Sin Wave Table for my ease of monitoring what numbers I am actually using. I start the y array index at 50 for a 90 degree phase difference, since there are 200 points total. I was wrong earlier when I stated that my magic working number was 8191 and the magic not working number is 8192. The max number I am sending with this code is 16382 (works) but code with max number 16384 (does not work). Have a look and see if I am missing something. I agree with you that there should be no magic number and that it is most likely an issue with comms, or masking.

    // Open Laser Show DAC Example - Circle
    // Draws a nice circle and shifts the phase so it rotates.

    #include <OLSD.h>
    #include <standard.h>

    OLSD dac;

    //This works max number 16382
    //unsigned int x[] = {
    // 8191, 8448, 8705, 8962, 9218, 9472, 9726, 9978, 10228, 10476, 10722, 10966, 11206, 11444, 11679, 11910, 12137, 12361, 12580, 12795, 13006, 13211, 13412, 13608, 13798, 13983, 14162, 14335, 14502, 14663, 14818, 14966, 15107, 15241, 15369, 15489, 15602, 15708, 15807, 15898, 15981, 16057, 16125, 16185, 16237, 16281, 16317, 16346, 16366, 16378, 16382, 16378, 16366, 16346, 16317, 16281, 16237, 16185, 16125, 16057, 15981, 15898, 15807, 15708, 15602, 15489, 15369, 15241, 15107, 14966, 14818, 14663, 14502, 14335, 14162, 13983, 13798, 13608, 13412, 13211, 13006, 12795, 12580, 12361, 12137, 11910, 11679, 11444, 11206, 10966, 10722, 10476, 10228, 9978, 9726, 9472, 9218, 8962, 8705, 8448, 8191, 7934, 7677, 7420, 7164, 6910, 6656, 6404, 6154, 5906, 5660, 5416, 5176, 4938, 4703, 4472, 4245, 4021, 3802, 3587, 3376, 3171, 2970, 2774, 2584, 2399, 2220, 2047, 1880, 1719, 1564, 1416, 1275, 1141, 1013, 893, 780, 674, 575, 484, 401, 325, 257, 197, 145, 101, 65, 36, 16, 4, 0, 4, 16, 36, 65, 101, 145, 197, 257, 325, 401, 484, 575, 674, 780, 893, 1013, 1141, 1275, 1416, 1564, 1719, 1880, 2047, 2220, 2399, 2584, 2774, 2970, 3171, 3376, 3587, 3802, 4021, 4245, 4472, 4703, 4938, 5176, 5416, 5660, 5906, 6154, 6404, 6656, 6910, 7164, 7420, 7677, 7934
    //};
    //unsigned int y[] = {
    // 8191, 8448, 8705, 8962, 9218, 9472, 9726, 9978, 10228, 10476, 10722, 10966, 11206, 11444, 11679, 11910, 12137, 12361, 12580, 12795, 13006, 13211, 13412, 13608, 13798, 13983, 14162, 14335, 14502, 14663, 14818, 14966, 15107, 15241, 15369, 15489, 15602, 15708, 15807, 15898, 15981, 16057, 16125, 16185, 16237, 16281, 16317, 16346, 16366, 16378, 16382, 16378, 16366, 16346, 16317, 16281, 16237, 16185, 16125, 16057, 15981, 15898, 15807, 15708, 15602, 15489, 15369, 15241, 15107, 14966, 14818, 14663, 14502, 14335, 14162, 13983, 13798, 13608, 13412, 13211, 13006, 12795, 12580, 12361, 12137, 11910, 11679, 11444, 11206, 10966, 10722, 10476, 10228, 9978, 9726, 9472, 9218, 8962, 8705, 8448, 8191, 7934, 7677, 7420, 7164, 6910, 6656, 6404, 6154, 5906, 5660, 5416, 5176, 4938, 4703, 4472, 4245, 4021, 3802, 3587, 3376, 3171, 2970, 2774, 2584, 2399, 2220, 2047, 1880, 1719, 1564, 1416, 1275, 1141, 1013, 893, 780, 674, 575, 484, 401, 325, 257, 197, 145, 101, 65, 36, 16, 4, 0, 4, 16, 36, 65, 101, 145, 197, 257, 325, 401, 484, 575, 674, 780, 893, 1013, 1141, 1275, 1416, 1564, 1719, 1880, 2047, 2220, 2399, 2584, 2774, 2970, 3171, 3376, 3587, 3802, 4021, 4245, 4472, 4703, 4938, 5176, 5416, 5660, 5906, 6154, 6404, 6656, 6910, 7164, 7420, 7677, 7934
    //};

    //This does not work max number 16384
    unsigned int x[] = {
    8192, 8449, 8706, 8963, 9219, 9474, 9727, 9979, 10229, 10477, 10723, 10967, 11208, 11445, 11680, 11911, 12139, 12362, 12581, 12797, 13007, 13213, 13414, 13609, 13800, 13985, 14164, 14337, 14504, 14665, 14819, 14967, 15109, 15243, 15371, 15491, 15604, 15710, 15809, 15900, 15983, 16059, 16127, 16187, 16239, 16283, 16319, 16348, 16368, 16380, 16384, 16380, 16368, 16348, 16319, 16283, 16239, 16187, 16127, 16059, 15983, 15900, 15809, 15710, 15604, 15491, 15371, 15243, 15109, 14967, 14819, 14665, 14504, 14337, 14164, 13985, 13800, 13609, 13414, 13213, 13007, 12797, 12581, 12362, 12139, 11911, 11680, 11445, 11208, 10967, 10723, 10477, 10229, 9979, 9727, 9474, 9219, 8963, 8706, 8449, 8192, 7935, 7678, 7421, 7165, 6910, 6657, 6405, 6155, 5907, 5661, 5417, 5176, 4939, 4704, 4473, 4245, 4022, 3803, 3587, 3377, 3171, 2970, 2775, 2584, 2399, 2220, 2047, 1880, 1719, 1565, 1417, 1275, 1141, 1013, 893, 780, 674, 575, 484, 401, 325, 257, 197, 145, 101, 65, 36, 16, 4, 0, 4, 16, 36, 65, 101, 145, 197, 257, 325, 401, 484, 575, 674, 780, 893, 1013, 1141, 1275, 1417, 1565, 1719, 1880, 2047, 2220, 2399, 2584, 2775, 2970, 3171, 3377, 3587, 3803, 4022, 4245, 4473, 4704, 4939, 5176, 5417, 5661, 5907, 6155, 6405, 6657, 6910, 7165, 7421, 7678, 7935
    };
    unsigned int y[] = {
    8192, 8449, 8706, 8963, 9219, 9474, 9727, 9979, 10229, 10477, 10723, 10967, 11208, 11445, 11680, 11911, 12139, 12362, 12581, 12797, 13007, 13213, 13414, 13609, 13800, 13985, 14164, 14337, 14504, 14665, 14819, 14967, 15109, 15243, 15371, 15491, 15604, 15710, 15809, 15900, 15983, 16059, 16127, 16187, 16239, 16283, 16319, 16348, 16368, 16380, 16384, 16380, 16368, 16348, 16319, 16283, 16239, 16187, 16127, 16059, 15983, 15900, 15809, 15710, 15604, 15491, 15371, 15243, 15109, 14967, 14819, 14665, 14504, 14337, 14164, 13985, 13800, 13609, 13414, 13213, 13007, 12797, 12581, 12362, 12139, 11911, 11680, 11445, 11208, 10967, 10723, 10477, 10229, 9979, 9727, 9474, 9219, 8963, 8706, 8449, 8192, 7935, 7678, 7421, 7165, 6910, 6657, 6405, 6155, 5907, 5661, 5417, 5176, 4939, 4704, 4473, 4245, 4022, 3803, 3587, 3377, 3171, 2970, 2775, 2584, 2399, 2220, 2047, 1880, 1719, 1565, 1417, 1275, 1141, 1013, 893, 780, 674, 575, 484, 401, 325, 257, 197, 145, 101, 65, 36, 16, 4, 0, 4, 16, 36, 65, 101, 145, 197, 257, 325, 401, 484, 575, 674, 780, 893, 1013, 1141, 1275, 1417, 1565, 1719, 1880, 2047, 2220, 2399, 2584, 2775, 2970, 3171, 3377, 3587, 3803, 4022, 4245, 4473, 4704, 4939, 5176, 5417, 5661, 5907, 6155, 6405, 6657, 6910, 7165, 7421, 7678, 7935
    };
    int a = 0;
    int b = 50;
    unsigned int x_send;
    unsigned int y_send;

    long previousMillis = 0;

    void setup()
    {
    dac.Init();
    // Set the point output rate really slow since floating point is really slow
    // No need to go faster
    dac.SetOutputRate(12000);
    }

    // Phase is global so it is persistant through the loop function callss
    float phase = 0.0;

    void loop()
    {
    unsigned long currentMillis = millis();
    //float x,y,a;

    // Calculate and draw a circle using sine and cosine
    // This is a little slow given the floating point math on this processor
    //for (a = 0.0; a <= (2.0 * PI); a += 0.1)
    // Calculate x and y using our angle in radians
    // Include a phase shift so the circle rotates
    //x = sin(a + phase);
    //y = cos(a);
    // Change the +/-1.0 numbers into unsigned integers
    //x = x * 32760.0 + 32760.0;
    //y = y * 32760.0 + 32760.0;
    // Output the point
    x_send = x[a];
    y_send = y[b];

    //if(currentMillis - previousMillis > 500){
    //previousMillis = currentMillis;
    dac.OutputPoint(x_send, y_send, 255, 255, 255);
    a++;
    b++;
    if(a >= sizeof(x)/sizeof(int)){
    a = 0;
    }
    if(b >= sizeof(y)/sizeof(int)){
    b = 0;
    }
    //}


    // Change the phase for next time we draw the circle
    //phase += (PI / 360.0);
    //if (phase > (2.0 * PI)) phase = 0.0;
    }

  6. #36
    Join Date
    Feb 2009
    Location
    East Coast of Southern Virginia
    Posts
    536

    Default

    I don't see anything wrong with that code. 16384 when shifted down 4 bits is 1024. Perhaps there is something in the code that forms the SPI data packet to the DAC. Can you post that?

    I will try your code tonight when I get home. That is an interesting way of bounds checking your a and b. I have not seen that before but it makes perfect sense. I always like looking at other peoples code. I often times learn something new.

    Also two more things... when you are putting large arrays in your program it takes away from the available RAM. This is probably not a problem here however the ATMega328 only has 2k of RAM. If you can stand a little slower access to your arrays try putting them in flash memory explicitly. There is an example in the firmware code. There are test patterns built in that are triggered by the button press.

    Also I noticed that both X and Y arrays have the same values. You can optimized your code a little (and save ram) if you just use one of them and delete the other. Since they are the same waveform (they graph really nicely in Excel) you can just simplify your code to:

    x_send = x[a];
    y_send = x[b];

    That way you have to indexes like you currently use and 1 sine look up table.
    Last edited by cfavreau; 05-17-2013 at 07:09.

  7. #37
    Join Date
    May 2013
    Location
    Fort Mill, SC
    Posts
    556

    Default

    Thanks for the suggestions on optimization.

    Here is the OLSD.cpp file that the header pulls in. I did not make any changes to the OLSD.h file. The only changes I made to the OLSD.cpp file was change the clock speed and added code for the clock phasing, so it would work with my DAC.

    // OLSD.CPP
    // Open Laser Show DAC (OLSD)
    // Library for outputting points to the OLSD board

    // Open Laser Show DAC - Arduino Shield
    // Copyright (c) 2011 Chris Favreau
    // cfavreau@fab-favreau.com

    #include "olsd.h"
    #include "standard.h"

    // These have moved to the OLSD.H File!
    //#define V4 1
    //#define V3 1
    //#define VHARP 1

    // SPI Data Register Definitions
    #define DDR_SPI DDRB
    #define DD_MOSI DDB3
    #define DD_MISO DDB4
    #define DD_SCK DDB5

    // Output Rate Timer Related Constants
    #define MIN_PPS_RATE 1000
    #define MAX_PPS_RATE 30000
    #define DEFAULT_PPS 12000

    #define TIMER_FUDGE_FACTOR 128
    #define DEFAULT_TIMEOUT TIMER_FUDGE_FACTOR + 65002 //64202 // 12 kpps

    volatile unsigned char output_flag = 0;
    volatile unsigned int timer_start_value = 0;

    #ifdef V4
    #define LEDINIT ddrd.bit2 = 1; portd.bit2 = 1;
    #define LEDBIT ddrd.bit2
    #endif

    #ifdef V3
    #define LEDINIT ddrc.bit4 = 1; portc.bit4 = 1;
    #define LEDBIT ddrc.bit4
    #endif

    #ifdef VHARP
    #define LEDINIT ddrc.bit4 = 1; portc.bit4 = 1;
    #define LEDBIT ddrc.bit4
    #endif

    ISR(TIMER1_OVF_vect)
    {
    // Reset the counter
    TCNT1 = timer_start_value;

    // Check to see if the output flag has been reset
    // TODO - put this back in!
    /*
    if (output_flag > 5)
    {
    // BLANK!!!!
    // TODO
    // Red = 0
    // Green = 0
    // Blue = 0
    PORTC = (PORTC & 0xF8);
    // Shutter = 1
    // LED - BIT4 - leave ALONE!
    // Switch - BIT5 - leave ALONE!
    portc.bit3 = 1;
    }
    */

    // Output a point NOW!
    output_flag++;
    }

    OLSD::OLSD()
    {
    status_counter = 0;
    bUseRateTimer = TRUE;
    output_flag = 0;
    timer_start_value = 0;

    Init();
    }

    OLSD::~OLSD()
    {
    }

    void OLSD::InitPorts(void)
    {
    // Laser Harp Board uses PortC in the same manner
    // Initialize our IO Ports
    // Port C = Button + LED + Shutter + Blue
    DDRC = 0b00011111;
    PORTC = 0b00111000;

    #ifdef V4
    // Color Latch Bit
    ddrb.bit0 = 1;
    portd.bit0 = 1;
    #endif

    #ifdef V3
    // V3 PortD
    ///*
    // Port D - Serial + Red and Green
    DDRD = 0b11111100;
    PORTD = 0b00000011;
    #endif

    #ifdef VHARP
    // Laser Harp Port D
    // Port D - Serial + Harp Enable + Harp Sync + Harp Pos.
    // Serial Port Pins
    ddrd.bit0 = 0;
    ddrd.bit1 = 0;
    // Enable the pullups on these pins
    portd.bit0 = 1;
    portd.bit1 = 1;
    // Harp Enable (Input)
    ddrd.bit2 = 0;
    // Enable the pull up
    portd.bit2 = 1;
    // Harp Sync/Clk (Output)
    ddrd.bit3 = 1;
    // Harp Pos. Bits (Outputs)
    ddrd.bit4 = 1;
    ddrd.bit5 = 1;
    ddrd.bit6 = 1;
    ddrd.bit7 = 1;
    #endif

    // Initialize our SPI port to output to our DAC
    ddrb.bit2 = 1;
    portb.bit2 = 1;
    InitSPI();

    // LDAC - disable
    ddrb.bit1 = 1;
    portb.bit1 = 1;

    // CTS Pin
    //ddrb.bit0 = 1;
    //portb.bit0 = 0;

    LEDINIT;

    // Turn the LED ON
    LEDBIT = 1;
    }

    void OLSD::InitSPI(void)
    {
    DDR_SPI |= (1 << DD_MOSI) | (1 << DD_SCK);
    // Enable SPI Master and Set Clock rate to CLK / 2 (I.E. 16MHz)
    // and MSB first and Clock Polarity is Rising on the Leading Edge (Mode 0).
    SPCR |= (1 << SPE) | (1 << MSTR) | (0<<CPOL) | (1<<CPHA) | (0 << SPR1) | (0 << SPR0);
    SPSR |= (0 << SPI2X); //We need the fast 2X mode.
    }

    void OLSD::InitTimers(void)
    {
    // Intialize the Timer1

    // Stop the timer
    TCCR1A = 0x00;
    TCCR1B = 0x00;

    // Set the initial timeout value to the default output rate
    SetOutputRate(DEFAULT_PPS);

    // Configure the Timer1 Overflow Interrupt to be ON
    TIMSK1 = 0b00000001;

    // Select the IO clock with NO prescalar
    TCCR1A = 0x00;
    TCCR1B = 0x01;
    }

    void OLSD::Init(void)
    {
    status_counter = 0;
    output_flag = 0;
    timer_start_value = 0;

    // Turn Off Interrupts
    cli();
    // Initlialize our IO ports
    InitPorts();
    // Initialize our Hardware Timers
    InitTimers();
    // Turn ON Interrupts
    sei();
    }

    void OLSD::SetOutputRate(unsigned int pps)
    {
    // Bounds check the points per second
    if (pps > MAX_PPS_RATE) pps = MAX_PPS_RATE;
    if (pps < MIN_PPS_RATE) pps = MIN_PPS_RATE;

    // Convert points per second to thousands of points per second
    pps /= 1000;

    // Calculate the timer timeout value from the
    // number of points per second we are supposed
    // to display
    // Timer ceiling - (Clock Rate in kHZ / PPS) + Fudge Factor (found with scope)
    timer_start_value = 0xFFFF - (16000 / pps) + TIMER_FUDGE_FACTOR;

    // Set the timer count register
    TCNT1 = timer_start_value;
    }

    void OLSD::OutputPoint(unsigned int x, unsigned int y, unsigned char red, unsigned char green, unsigned char blue)
    {
    unsigned int spi_word;

    // Scale the X and Y to 12 bit numbers
    x = x >> 4;
    y = y >> 4;

    // Bounds check X and Y
    if (x > 4095) x = 4095;
    if (y > 4095) y = 4095;

    // Wait for the output flag
    while (!output_flag) asm("nop");
    // Reset the output flag
    output_flag = 0;

    // Pull the LDAC line high
    portb.bit1 = 1;

    // Load DAC A
    // X X X PowerMode Load Output AddrB AddrA
    spi_word = 0b0000000000000000 | (y & 0x0FFF);
    // Pull down chip select so the DAC knows we are taling to it
    portb.bit2 = 0;
    // Upper Byte of the command
    SPDR = spi_word >> 8;
    while (!(SPSR & (1 << SPIF)));
    // Lower Byte of the command
    SPDR = spi_word & 0x00FF;
    while (!(SPSR & (1 << SPIF)));
    // Pull up chip select
    portb.bit2 = 1;

    // Load DAC B and update the output (assign a 0 to output)
    spi_word = 0b0001000000000000 | (x & 0x0FFF);
    // Pull down chip select so the DAC knows we are taling to it
    portb.bit2 = 0;
    // Upper Byte of the command
    SPDR = spi_word >> 8;
    while (!(SPSR & (1 << SPIF)));
    // Lower Byte of the command
    SPDR = spi_word & 0x00FF;
    while (!(SPSR & (1 << SPIF)));
    // Pull up chip select
    portb.bit2 = 1;

    #ifdef V4

    // Color Latches
    portb.bit0 = 0;

    // Fifth bits are the UPPER Nibble
    _BYTE fifthbits = 0;
    if (red) fifthbits |= 0x10;
    if (green) fifthbits |= 0x20;
    if (blue) fifthbits |= 0x40;

    // Colors
    // *** REMEMBER that a shift register passes the 1st 8 bits
    // on to the 2nd shift register so we do the BLUE first!
    // B goes first
    SPDR = fifthbits | blue;
    while (!(SPSR & (1 << SPIF)));

    // RG go second
    SPDR = (green << 4) | red;
    while (!(SPSR & (1 << SPIF)));

    // Now latch the Colors
    portb.bit0 = 1;

    #endif

    #ifdef V3
    // V3 Colors
    // Reduce all colors to 3 bit resolution
    red = red >> 5;
    green = green >> 5;
    blue = blue >> 5;
    // Red = 0
    // Green = 0
    PORTD = 0b00000011 | (red << 5) | (green << 2);

    // Blue = 0
    // Shutter = 0
    PORTC = 0b00110000 | blue;
    #endif

    #ifdef VHARP
    // Laser Harp TTL RGB --------------------------
    // Write the R G B bits
    _BYTE rgb = PORTC & 0b00111000;
    if (red > 0) rgb |= 0x01;
    if (green > 0) rgb |= 0x02;
    if (blue > 0) rgb |= 0x04;
    PORTC = rgb;
    #endif

    // Open the shutter
    // TODO

    // Pull the LDAC line LOW to load the DAC's values
    portb.bit1 = 0;

    // Do the Status LED
    status_counter++;
    if (status_counter < 500)
    {
    // Reset the LED to flip
    LEDBIT = 1;
    }
    else
    {
    LEDBIT = 0;
    }
    if (status_counter > 1000) status_counter = 0;
    }

    // Additional function to operate the Position Port on the Laser Harp Board
    void OLSD::SetPositionPort(_BOOL SyncBitOn, _BYTE nString)
    {
    #ifdef VHARP
    // Set string bits
    // nString should only be from 0 to 15
    PORTD = (PORTD & 0x0F) | (nString << 4);

    // Toggle sync line ON
    portd.bit3 = (SyncBitOn ? 1 : 0);
    #endif
    }

  8. #38
    Join Date
    Feb 2009
    Location
    East Coast of Southern Virginia
    Posts
    536

    Default

    I cannot see anything immediate. The only thing I might suggest is waiting more time in between the chip selects... put 8 asm("NOP"); lines after each chip select toggle... and if that doesn't work try slowing down the SPI a little more. It could be a timing problem. I know the DAC0832 (a popular parallel DAC) wigged out and did weird things if you tried to flip the IO too quickly.

  9. #39
    Join Date
    May 2013
    Location
    Fort Mill, SC
    Posts
    556

    Default

    cfavreau,

    I have another question for you. Would I need to modify the OLSD.dll file for the Nano to be seen by LSX? I figure since I had to modify the description in the firmware so the OLSD test program would communicate with the Nano I may also need to modify the OLSD.dll so LSX can see the Nano. Can you give me some insight on how I might go about this? Thanks

  10. #40
    Join Date
    Feb 2008
    Posts
    1

    Default

    Hi!
    There is such a defiance om the v3 version
    That would be my question to you Fiesta2 resents the drivers of this to anyone?
    Thanks in advance,

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •