Page 3 of 3 FirstFirst 123
Results 21 to 29 of 29

Thread: SDK for DACs

  1. #21
    Join Date
    Mar 2006
    Posts
    2,478

    Default

    Gary, I mentioned the DAC's double buffering in the previous post so you can see I didn't miss it.

    What I'm getting at is, can you look at the DAC directly, the hardware, see if if's got direct sync with the circuit that receives from the USB? If it has, that could solve your problem, as it can be clocked to send from the local buffer at the USB far end one frame as and when the DAC wants it. The USB buffer might hold a lot more frames, and all the flow control is taken care of by USB itself.

    That method would work but it's something the maker of the DAC needs to sort out, it's not something you'd likely have access to control directly unless that was already provided.

    Someone, somewhere, needs a bigger buffer.

  2. #22
    Join Date
    Dec 2006
    Location
    Pflugerville, TX, USA
    Posts
    1,977

    Default

    Beats me. I wouldn't even know what to look for. But, the hardware/firmware isn't going to change so I'll have to deal with it on my end.

  3. #23
    Join Date
    Aug 2007
    Location
    Indianapolis, IN
    Posts
    196

    Default Medialas MLD driver format

    I did some snooping around and as far as I can tell the MLD files in Mamba Black are actually regular DLL files that have been renamed.

    There are a set of functions exported by the MLD files

    Code:
    Drivers are simply Windows DLLs. If you want to write your own driver, you will have to
    implement and export the following functions (Delphi syntax):
     
    function MLRegisterDriver(b: PChar): word stdcall;
    This function has to copy the characters MLDevice into the buffer b. This is to make sure the
    DLL is a valid driver. The function can return a number, which will then be passed to as
    parameter h in the functions below (in case the hardware driver supports multiple clients, and
    has to keep track of them).
    function MLDevicePresent: boolean; stdcall;
    This function should return true if the device is present (or if there is no way to determine it).
    function MLKind: word; stdcall;
    Returns 1 for a frame oriented device, 2 for a point oriented device, 4 for an animation
    oriented device. (For the different devices see MLDraw.) If the function is not present a frame
    oriented device will be assumed.
    Mamba calls these functions on program start, so it can list all output devices that are
    available.
    The following functions are used to do output to the device. The parameter h is the above
    mentioned return value from MLRegisterDriver, c is the channel number (in case the
    hardware can support multiple output channels, mamba always uses channel 0).
    function MLGetName(n: pchar): boolean; stdcall;
    When called the driver should copy a name (20 chars max) to n
    function MLInitDevice(h: word): boolean; stdcall;
    Called once when the driver is selected.
    function MLInitShow(h, c: word): boolean; stdcall;
    Called immediately before output starts
    function MLDraw(h, c: word; d: PChar; n: integer): boolean; stdcall;
    For a frame oriented device (Riya PCI Pro for example) this function is called for each frame.
    D is a pointer to an array with n points
    Point= packed record
    x,y,z: word;
    r,g,b: byte;
    reserved1, reserved2, reserved3: byte;
    intensity, reserved4, repeatpoint: byte;
    end;
    if repeatpoint is greater than 0 it should be displayed 1+repeatpoint times.
    For a point oriented device (MediaLas PCI 12 for example) this function is called once for
    each point (same data format).
    For animation oriented devices (MediaLas HotBoard for example) there will be a call to
    MLInitShow, followed by calls to MLDraw for each frame, after the show is through
    MLHaltShow will be called, and the data can be sent to the device.
    function MLHaltShow(h, c: word): boolean; stdcall;
     
    Called when output stops.
    function MLHalt: boolean; stdcall;
    Called when the driver is unloaded
    function MLParams(h: word; c: word; p: PChar): boolean; stdcall;
    p is a pointer to a Params structure
    Params= packed record
    size: word;
    pointrate: longint;
    invertblanking: boolean;
    end;
    size is the size in bytes of the complete structure (right now values of 6 or 7 are used, please
    make sure you driver checks for this parameters). For a frame oriented driver this function is
    used to set the scanrate in points per second. If invertblanking is set, the driver should invert
    all intensity values (if possible). The driver should use safe default values.
    Using a driver with your own software
    If you plan to use a MediaLas driver with your own software you should at least call the
    following functions:
    MLDevicePresent (on startup)
    MLInitDevice (before first output)
    MLInitShow (before output starts)
    MLHaltShow (to end output)
    MLHalt (before closing program)
    It is highly recommended to call MLKind (if present) to check whether the device is point,
    frame, or animation oriented.
    When calling MLName please make sure the buffer you pass is at least 21 bytes long. When
    calling MLParams, set the size parameter correctly.
    A simple example driver and program (in Delphi) is available, please contact MediaLas
    technical support.
    Page 19
    19
    Suggested parallel port DAC with Maxim MAX506ACPP:
    D0-D7 (Pin2-9) Data
    Strobe (Pin 1) A0
    Autofeed (Pin 14) A1
    Select Input (Pin 17) Write
    LPT pin -> MAX 506 pin
    1 -> 17 (A0)
    2 -> 14 (D0)
    3 -> 13 (D1)
    4 -> 12 (D2)
    5 -> 11 (D3)
    6 -> 10 (D4)
    7 -> 9 (D5)
    8 -> 8 (D6)
    9 -> 7 (D7)
    14 -> 16 (A1)
    17 -> 15 (-WR)
    25 -> 6 (DGND)
    MAX 506:
    3 (Vss), 5 (AGND), 6 (DGND) -> Ground
    4 (VREF), 18 (Vdd) -> +5V
    Output pins on the MAX506
    2 (VoutA): Channel 1 (0..+5V)
    1 (VoutB): Channel 2 (0..+5V)
    20 (VoutC): Channel 3 (0..+5V)
    19 (VoutD): Channel 4 (0..+5V)
    (With MediaLas PCI Board 5V can be obtained from Pin 37 of the 37 Pin sub-D connector.)
    Writing/using drivers 
     
    Drivers are simply Windows DLLs. If you want to write your own driver, you will have to 
    implement and export the following functions (Delphi syntax): 
    function MLRegisterDriver(b: PChar): word stdcall; 
    This function has to copy the characters MLDevice into the buffer b. This is to make sure the 
    DLL is a valid driver. The function can return a number, which will then be passed to as 
    parameter h in the functions below (in case the hardware driver supports multiple clients, and 
    has to keep track of them). 
    function MLDevicePresent: boolean; stdcall; 
    This function should return true if the device is present (or if there is no way to determine it). 
    function MLKind: word; stdcall; 
    Returns 1 for a frame oriented device, 2 for a point oriented device, 4 for an animation 
    oriented device. (For the different devices see MLDraw.) If the function is not present a frame 
    oriented device will be assumed. 
    Mamba calls these functions on program start, so it can list all output devices that are 
    available. 
    The following functions are used to do output to the device. The parameter h is the above 
    mentioned return value from MLRegisterDriver, c is the channel number (in case the 
    hardware can support multiple output channels, mamba always uses channel 0). 
    function MLGetName(n: pchar): boolean; stdcall; 
    When called the driver should copy a name (20 chars max) to n 
    function MLInitDevice(h: word): boolean; stdcall; 
    Called once when the driver is selected. 
    function MLInitShow(h, c: word): boolean; stdcall; 
    Called immediately before output starts 
    function MLDraw(h, c: word; d: PChar; n: integer): boolean; stdcall; 
    For a frame oriented device (Riya PCI Pro for example) this function is called for each frame. 
    D is a pointer to an array with n points 
    Point= packed record 
    x,y,z: word; 
    r,g,b: byte; 
    reserved1, reserved2, reserved3: byte; 
    intensity, reserved4, repeatpoint: byte; 
    end; 
    if repeatpoint is greater than 0 it should be displayed 1+repeatpoint times. 
    For a point oriented device (MediaLas PCI 12 for example) this function is called once for 
    each point (same data format). 
    For animation oriented devices (MediaLas HotBoard for example) there will be a call to 
    MLInitShow, followed by calls to MLDraw for each frame, after the show is through 
    MLHaltShow will be called, and the data can be sent to the device. 
    function MLHaltShow(h, c: word): boolean; stdcall;
     
    Called when output stops. 
    function MLHalt: boolean; stdcall; 
    Called when the driver is unloaded 
    function MLParams(h: word; c: word; p: PChar): boolean; stdcall; 
    p is a pointer to a Params structure 
    Params= packed record 
    size: word; 
    pointrate: longint; 
    invertblanking: boolean; 
    end; 
    size is the size in bytes of the complete structure (right now values of 6 or 7 are used, please 
    make sure you driver checks for this parameters). For a frame oriented driver this function is 
    used to set the scanrate in points per second. If invertblanking is set, the driver should invert 
    all intensity values (if possible). The driver should use safe default values. 
    Using a driver with your own software 
    If you plan to use a MediaLas driver with your own software you should at least call the 
    following functions: 
    MLDevicePresent (on startup) 
    MLInitDevice (before first output) 
    MLInitShow (before output starts) 
    MLHaltShow (to end output) 
    MLHalt (before closing program) 
    It is highly recommended to call MLKind (if present) to check whether the device is point, 
    frame, or animation oriented. 
    When calling MLName please make sure the buffer you pass is at least 21 bytes long. When 
    calling MLParams, set the size parameter correctly. 
    A simple example driver and program (in Delphi) is available, please contact MediaLas technical support
    ...

  4. #24
    Join Date
    Aug 2007
    Location
    Indianapolis, IN
    Posts
    196

    Default

    and here's some code taken from the Laserfreak forum...

    Code:
    I'm a little bit confused if we're talking about native Easylase support or MLD architecture (which supports Easylase and many more). 
    Below you will find a code example which I used to check my own ML-driver. It opens the driver, draws a square with 4 points at 1000pps, and closes the driver. There's no error handling included. 
    I hope the code is understandable. 
    I attached my ML driver for testing. It will work even if there's no output device connected. 
     
    #pragma pack(1) // this is necessary to avoid integer alignment of the structure elements 
    typedef struct 
    { 
    unsigned short x, y, z; 
    unsigned char r, g, b; 
    unsigned char reserved1, reserved2, reserved3; 
    unsigned char intensity, reserved4, repeatpoint; 
    } tMLPoint; 
     
    typedef struct 
    { 
    unsigned char Size; 
    int PointRate; 
    boolean invert; 
    } tMLParam; 
    #pragma pack() 
     
    typedef unsigned short __stdcall (*tMLRegisterDriver)(char *Name); 
    typedef bool __stdcall (*tMLDevicePresent)(void); 
    typedef unsigned short __stdcall (*tMLKind)(void); 
    typedef bool __stdcall (*tMLGetName)(char *Name); 
    typedef bool __stdcall (*tMLInitDevice)(unsigned short Handle); 
    typedef bool __stdcall (*tMLInitShow)(unsigned short Handle, unsigned short c); 
    typedef bool __stdcall (*tMLDraw)(unsigned short Handle, unsigned short c, char *pPoints, int NumOfPoints); 
    typedef bool __stdcall (*tMLHaltShow)(unsigned short Handle, unsigned short c); 
    typedef bool __stdcall (*tMLHalt)(void); 
    typedef bool __stdcall (*tMLParams)(unsigned short Handle, unsigned short c, unsigned char *pParams); 
     
    void main(void) 
    { 
    tMLRegisterDriver fMLRegisterDriver; 
    tMLDevicePresent fMLDevicePresent; 
    tMLKind fMLKind; 
    tMLGetName fMLGetName; 
    tMLInitDevice fMLInitDevice; 
    tMLInitShow fMLInitShow; 
    tMLDraw fMLDraw; 
    tMLHaltShow fMLHaltShow; 
    tMLHalt fMLHalt; 
    tMLParams fMLParams; 
     
    HINSTANCE Handle; 
    char buffer[21]; 
    unsigned short kind, h; 
    boolean result; 
    tMLParam Param; 
    tMLPoint Points[4]; 
     
    Handle = LoadLibrary("lumax.mld"); 
    Param.Size = 7; 
    Param.PointRate = 1000; 
    Param.invert = 0; 
    Points[0].x = 0;    Points[0].y = 0;    Points[0].r = 255; Points[0].g = 255; Points[0].b = 255; 
    Points[1].x = 4095; Points[1].y = 0;    Points[1].r = 255; Points[1].g = 255; Points[1].b = 255; 
    Points[2].x = 4095; Points[2].y = 4095; Points[2].r = 255; Points[2].g = 255; Points[2].b = 255; 
    Points[3].x = 0;    Points[3].y = 4095; Points[3].r = 255; Points[3].g = 255; Points[3].b = 255; 
     
    fMLRegisterDriver = (tMLRegisterDriver)GetProcAddress(Handle, "MLRegisterDriver"); 
    fMLDevicePresent = (tMLDevicePresent)GetProcAddress(Handle, "MLDevicePresent"); 
    fMLKind = (tMLKind)GetProcAddress(Handle, "MLKind"); 
    fMLGetName = (tMLGetName)GetProcAddress(Handle, "MLGetName"); 
    fMLInitDevice = (tMLInitDevice)GetProcAddress(Handle, "MLInitDevice"); 
    fMLInitShow = (tMLInitShow)GetProcAddress(Handle, "MLInitShow"); 
    fMLDraw = (tMLDraw)GetProcAddress(Handle, "MLDraw"); 
    fMLHaltShow = (tMLHaltShow)GetProcAddress(Handle, "MLHaltShow"); 
    fMLHalt = (tMLHalt)GetProcAddress(Handle, "MLHalt"); 
    fMLParams = (tMLParams)GetProcAddress(Handle, "MLParams"); 
     
    result = fMLDevicePresent(); // function should return true if device is present 
    result = fMLGetName(buffer); // function should return name of the driver in buffer 
    kind = fMLKind(); // function should return 1 for frame oriented devices 
    h = fMLRegisterDriver(buffer); // function should return device handle and the string "MLDevice" in buffer 
    result = fMLInitDevice(h); 
    result = fMLInitShow(h, 0); 
    result = fMLParams(h, 0, (char*)&Param); 
    result = fMLDraw(h, 0, (char*)Points, 4); 
    result = fMLHaltShow(h, 0); 
    result = fMLHalt(); 
     
    FreeLibrary(Handle); 
    } 
     
    
    I thought that might be useful for anyone else looking into MediaLas support.

    Steve

  5. #25
    Join Date
    Dec 2006
    Location
    Pflugerville, TX, USA
    Posts
    1,977

    Default

    That's true. I remember that now. The API is published so drivers can be made for any DAC and then plugged in to work with Mamba.

  6. #26
    Join Date
    Aug 2007
    Location
    Ukraine
    Posts
    128

    Default

    Hello!

    We have free API for our controllers too

    http://www.riyalasers.com/download/R...RO_SDK_NET.ZIP

    Ihor Ralko

  7. #27
    Join Date
    Dec 2006
    Location
    Pflugerville, TX, USA
    Posts
    1,977

    Default

    Lots of options... but so disheartening to see all these people working hard on different systems that don't even work together.

  8. #28
    Join Date
    Dec 2006
    Location
    Netherlands
    Posts
    983

    Default

    RIYA seems to work in the same way: continuously calling the below function to get the state of the card.


    Ihor, is there any specific reason you didn't design the card to tell the software that a new frame can be loaded? That would be more convinient to program and possibly save pocessing workload..

    cheers


    Code:
    unsigned char Ri_SetIntCh (unsigned char CardID); 
    
    The function, which indexes frame changes in the device.
    The controller can perform two operations in the same time: data transfer
    between PC and card and frame scanning.
    Each channel of card has 512 kilobytes of memory, which is segmented 
    into two buffers: temporary buffer 1and temporary buffer 2. 
    The card loads frame data in the free temporary buffer, and, at the same
    time, outputs the second temporary buffer to the Dacs. After loading the
    primary temporary buffer end the current frame and change buffers (in
    hardware).
    The given function signals this buffer change.
    When Ri_SetIntCh is "1", you can load the next frame.
    When Ri_SetIntCh is "0", you are at the last show frame, expressed by
    a "0" .
    In show mode, you need to continually call this function to load the next
    frame.

  9. #29
    Join Date
    Apr 2007
    Posts
    98

    Exclamation

    I've spent some time investigating things about USB and the quintessence is: It's incredibly ugly but cheap USB itself relies very much on polling (in contrast to SCSI and Firewire which both demand much more sophisticated controller chips), I can recommend some great books for everybody interested in details. Apart from questions about cost-effectivity, there are basically two kinds of chipsets out there: Chips for USB-to-something purposes which support USB 1.1 speeds (12 MBit/s) and USB 2.0 High-Speed Controllers specifically for mass storage purposes. Custom chips (for quite a lot of money) are available, of course.

Posting Permissions

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