Shop OBEX P1 Docs P2 Docs Learn Events
What am i doing wrong with my code? — Parallax Forums

What am i doing wrong with my code?

grasshoppergrasshopper Posts: 438
edited 2008-03-14 22:23 in Propeller 1
I am trying to read the data from an ADS8341 16 bit 4 channel A/D convertor using internal clock mode.
The data sheet states that to read from channel 1 using internal clock mode i need to send out a 8 bits 11010110

here is my code

 

CON
  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000
  
  CS            = 13            'Propeller Pin
  Din           = 14            'Propeller Pin
  Dout          = 15            'Propeller Pin use a resistor on this pin                             
  Clk           = 12            'Propeller Pin

 
OBJ 
    SER[noparse][[/noparse] 3 ] : "FullDuplexSerial"
    
pub start
  ser[noparse][[/noparse] 0 ].start(31, 30, 0, 9600)     'Sets up Com port (Rxpin,Txpin,mode,baud) 
  ser[noparse][[/noparse] 1 ].start(15, 14, 0, 9600)     'Set up com from IC
  dira[noparse][[/noparse]CS]~~                               'sets pin as output 

  repeat

    outa[noparse][[/noparse]CS]~~                    'sets pin 7 high  
    outa[noparse][[/noparse]CS]~                      'sets pin 7 low activating the ADS8341
    
    ser[noparse][[/noparse] 1 ].str(string("%11010110"))
    waitcnt (1_000_000 * 50 + cnt )
     
    outa[noparse][[/noparse]CS]~~                    'sets pin 7 high  
    outa[noparse][[/noparse]CS]~                      'sets pin 7 low activating the ADS8341
    
    waitcnt (1_000_000 * 50 + cnt )
    ser[noparse][[/noparse] 0 ].str(ser[noparse][[/noparse] 1 ].rx)  
    ser.tx(13)                          'line feed
    ser.tx(10)  
   





the data sheet can be found at www.chipcatalog.com/Datasheet/2838D5B2E81B44E3DC343E2C4AAB9B9A.htm

Comments

  • Nick MuellerNick Mueller Posts: 815
    edited 2008-03-14 16:04
    Did you read the datasheet? The chip requires a clock for DIN and DOUT and FullDuplexSerial doesn't provide that.

    Nick

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Never use force, just go for a bigger hammer!

    The DIY Digital-Readout for mills, lathes etc.:
    YADRO
  • grasshoppergrasshopper Posts: 438
    edited 2008-03-14 16:09
    I read the data sheet and on page 14 i translated it as Internal clock mode i only needed a CS high to low transition to read the data.
    Hum ! ill take another look
  • Harrison.Harrison. Posts: 484
    edited 2008-03-14 16:11
    I looked through the datasheet quickly and saw that the ADC is basically a SPI ADC with the ability to use the SPI clock to control the SAR conversion steps.

    So lets make a list of the key points listed in the datasheet:
    • synchronous serial interface (SPI)
    • internal and external clock modes for the ADC conversion only
    • requires configuration via the serial interface

    The above specifications mean that you should be using a SPI object, not FullDuplexSerial. SPI_Engine is a good choice, and so is BS2 Functions. I would highly recommend you use the internal clock for ADC conversion clock since external clocking will likely cause you more problems (like minimum 24kHz clock, etc).

    Your posted code also has a few fundamental flaws that would prevent it from working even if you got the ADC communication working perfectly. To send a binary number, you would use ser.tx(%11010110) and not ser.str(...). To echo the received data to another FullDuplexSerial object, you would need a repeat block and ser1.tx(ser2.rx).

    So try rewriting your code using SPI Engine and make sure you look at the clocking/data requirements for the chip. The information about when to read the data with regards to the clock rising/falling edge is extremely important.
  • grasshoppergrasshopper Posts: 438
    edited 2008-03-14 16:16
    Harrison Thank you very much! I will be back later on I am sure with more questions. I will look up the SPI object you mentioned.
  • grasshoppergrasshopper Posts: 438
    edited 2008-03-14 17:36
    More questions about my new program

    
    {{ ADS0831 4 channel 16 bit a/d  
    
    ***********************************************************************
    
                     M.J.A  3/11/08
        
    ***********************************************************************
    
                    ADS8341                  
                 ┌───────────────┐   
                ─┤1 +vcc  DCLK 16├─  Pin 12 on propeller             
                ─┤2 Ch0     CS 15├─  Pin 13 on propeller
                ─┤3 Ch1    DIN 14├─  Pin 14 on propeller
                ─┤4 Ch2   BUSY 13├─
                ─┤5 Ch3   DOUT 12├─  Pin 15 on propeller with a 1KOhm resistor in series  
                ─┤6 Com    GND 11├─   
                ─┤7 Ch2    GND 10├─  
                ─┤8 Vref  +Vcc 9 ├─
                 └───────────────┘                                           
                                              
    Notes  
    
    }}
    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
      CS    = 13
      Din   = 14
      Dout  = 15
      Dclk  = 12
      Bits  = 8
      Mode  = 0
      Value = %11010110  'Data out to select 1 of 4 channels on the A/D
      Rbits = 16         '16bits of data receivable
      
    
     
    OBJ 
      Shift :"SPI engine"
      SER   :"Fullduplexserial"
      
        
    pub start   | TEMP_data
      SER.start(31, 30, 0, 9600)    'Sets up Com port for computer (Rxpin,TXpin,mode,baud) 
      dira[noparse][[/noparse]CS]~~                     'sets pin as output  
     
    repeat
    
     
      Shift.start  
      outa[noparse][[/noparse]CS]~~                    'sets pin 7 high  
      outa[noparse][[/noparse]CS]~                     'sets pin 7 low activating the ADS0831
    
      Shift.SHIFTOUT(Din, Dclk, Mode, Bits, Value)
      Shift.Stop
      
      outa[noparse][[/noparse]CS]~~                    'sets pin 7 high  
      outa[noparse][[/noparse]CS]~                     'sets pin 7 low activating the ADS0831
      
      shift.SHIFTIN(Dout, Dclk, Mode, RBits)
      result := TEMP_data
      Shift.Stop
      outa[noparse][[/noparse]CS]~~                    'sets pin 7 high
    
    
      
      ser.tx(10)                          'line feed
      ser.tx(13)                          'carriage return
      waitcnt (1_000_000 * 50 + cnt )
      
      ser.str(string("Results =   "))    
      ser.dec(TEMP_data)                   'display decimal value of lm34temp
      ser.str(string("binary value is   "))     
      ser.bin(TEMP_data,16)                 'display binary value of lm34temp 
      ser.tx(13)                          'line feed
      ser.tx(10)                          'carriage return
    
    
    



    I need to know what the following is for

    Shift.SHIFTOUT(Din, Dclk, Mode, Bits, Value) 
    
    



    What does "mode" do? and "Value"?
    Can some one explain to me if i am approaching this correctly?
  • hippyhippy Posts: 1,981
    edited 2008-03-14 17:50
    @ grasshopper : What 'mode' and 'value' do will probably be defined or explained in
    your "SPI Engine" object, wherever that came from.

    Looks like you're on the right track though.
  • grasshoppergrasshopper Posts: 438
    edited 2008-03-14 17:55
    Hippy the object i am using is documented but not well enough for my wild mind to grasp.

    Here is the object i am using

    {{
                                                                                    
    Notes:
    Consecutive SHIFTIN/SHIFTOUT updates through Spin at 80 MHz is about 14kHz (Bit rate about 112k) 
    
    Consecutive SHIFTIN/SHIFTOUT updates through Assembly at 80 MHz is about 310kHz (Bit rate about 2.5M)
    
    }}
    
    
    {
                                    ********************************************
                                                     SPI Engine             V1.1    
                                    ********************************************
                                          coded by Beau Schwabe (Parallax)
                                    ********************************************
    Revision History:
             V1.0   - original program
             
             V1.1   - fixed problem with SHIFTOUT MSBFIRST option
                    - fixed argument allocation in the SPI Engines main loop
    }
    
    CON
    
      #1,_SHIFTOUT,_SHIFTIN
    VAR
    
        long     cog, command, Flag
        
    PUB SHIFTOUT(Dpin, Cpin, Mode, Bits, Value)             'Once called from Spin, SHIFTOUT remains running in its own COG.
        if Flag == 0                                        'If SHIFTOUT is called with 'Bits' set to Zero, then the COG will shut
           start                                            'down.  Another way to shut the COG down is to call 'stop' from Spin.
        setcommand(_SHIFTOUT, @Dpin)
        
    PUB SHIFTIN(Dpin, Cpin, Mode, Bits)|Value               'Once called from Spin, SHIFTIN remains running in its own COG.
        if Flag == 0                                        'If SHIFTIN is called with 'Bits' set to Zero, then the COG will shut
           start                                            'down.  Another way to shut the COG down is to call 'stop' from Spin.
        setcommand(_SHIFTIN, @Dpin)
        result := Value
    '------------------------------------------------------------------------------------------------------------------------------
    
    PUB start : okay
    '' Start SPI Engine - starts a cog
    '' returns false if no cog available
        stop
        Flag := 1
        okay := cog := cognew(@loop, @command) + 1
    
    PUB stop
    '' Stop SPI Engine - frees a cog
        Flag := 0
        if cog
           cogstop(cog~ - 1)
        command~
    
    PRI setcommand(cmd, argptr)
        command := cmd << 16 + argptr                       'write command and pointer
        repeat while command                                'wait for command to be cleared, signifying receipt
    '################################################################################################################
    
    DAT           org
    '  
    ' SPI Engine - main loop
    '
    loop          rdlong  t1,par          wz                'wait for command
            if_z  jmp     #loop
                  movd    :arg,#arg0                        'get 5 arguments ; arg0 to arg4
                  mov     t2,t1                             '    &#9474;
                  mov     t3,#5                             '&#61626;&#9472;&#9472;&#9472;&#9496; 
    :arg          rdlong  arg0,t2
                  add     :arg,d0
                  add     t2,#4
                  djnz    t3,#:arg
                  mov     address,t1                        'preserve address location for passing
                                                            'variables back to Spin language.
                  wrlong  zero,par                          'zero command to signify command received
                  ror     t1,#16+2                          'lookup command address
                  add     t1,#jumps
                  movs    :table,t1
                  rol     t1,#2
                  shl     t1,#3
    :table        mov     t2,0
                  shr     t2,t1
                  and     t2,#$FF
                  jmp     t2                                'jump to command
    jumps         byte    0                                 '0
                  byte    SHIFTOUT_                         '1
                  byte    SHIFTIN_                          '2
                  byte    NotUsed_                          '3
    NotUsed_      jmp     #loop
    '################################################################################################################
    SHIFTOUT_                                               'SHIFTOUT Entry
                  mov     t4,             arg3      wz      '     Load number of data bits
        if_z      jmp     #Done                             '     '0' number of Bits = Done
                  mov     t1,             #1        wz      '     Configure DataPin
                  shl     t1,             arg0
                  muxz    outa,           t1                '          PreSet DataPin LOW
                  muxnz   dira,           t1                '          Set DataPin to an OUTPUT
                  mov     t2,             #1        wz      '     Configure ClockPin
                  shl     t2,             arg1
                  muxz    outa,           t2                '          PreSet ClockPin LOW
                  muxnz   dira,           t2                '          Set ClockPin to an OUTPUT
                  sub     LSBFIRST,       arg2    wz,nr     '     Detect LSBFIRST mode for SHIFTOUT
        if_z      jmp     #LSBFIRST_
                  sub     MSBFIRST,       arg2    wz,nr     '     Detect MSBFIRST mode for SHIFTOUT
        if_z      jmp     #MSBFIRST_             
                  jmp     #loop                             '     Go wait for next command
    '------------------------------------------------------------------------------------------------------------------------------
    SHIFTIN_                                                'SHIFTIN Entry
                  mov     t4,             arg3      wz      '     Load number of data bits
        if_z      jmp     #Done                             '     '0' number of Bits = Done
                  mov     t1,             #1        wz      '     Configure DataPin
                  shl     t1,             arg0
                  muxz    dira,           t1                '          Set DataPin to an INPUT
                  mov     t2,             #1        wz      '     Configure ClockPin
                  shl     t2,             arg1
                  muxz    outa,           t2                '          PreSet ClockPin LOW
                  muxnz   dira,           t2                '          Set ClockPin to an OUTPUT
                  sub     MSBPRE,         arg2    wz,nr     '     Detect MSBPRE mode for SHIFTIN
        if_z      jmp     #MSBPRE_
                  sub     LSBPRE,         arg2    wz,nr     '     Detect LSBPRE mode for SHIFTIN
        if_z      jmp     #LSBPRE_
                  sub     MSBPOST,        arg2    wz,nr     '     Detect MSBPOST mode for SHIFTIN
        if_z      jmp     #MSBPOST_
                  sub     LSBPOST,        arg2    wz,nr     '     Detect LSBPOST mode for SHIFTIN
        if_z      jmp     #LSBPOST_
                  jmp     #loop                             '     Go wait for next command
    '------------------------------------------------------------------------------------------------------------------------------              
    MSBPRE_                                                 '     Receive Data MSBPRE
    MSBPRE_Sin    test    t1,             ina     wc        '          Read Data Bit into 'C' flag
                  rcl     t3,             #1                '          rotate "C" flag into return value
                  call    #Clock                            '          Send clock pulse
                  djnz    t4,             #MSBPRE_Sin       '          Decrement t4 ; jump if not Zero
                  jmp     #Update_SHIFTIN                   '     Pass received data to SHIFTIN receive variable
    '------------------------------------------------------------------------------------------------------------------------------              
    LSBPRE_                                                 '     Receive Data LSBPRE
    LSBPRE_Sin    test    t1,             ina       wc      '          Read Data Bit into 'C' flag
                  rcr     t3,             #1                '          rotate "C" flag into return value
                  call    #Clock                            '          Send clock pulse
                  djnz    t4,             #LSBPRE_Sin       '     Decrement t4 ; jump if not Zero
                  mov     t4,             #32               '     For LSB shift data right 32 - #Bits when done
                  sub     t4,             arg3
                  shr     t3,             t4
                  jmp     #Update_SHIFTIN                   '     Pass received data to SHIFTIN receive variable
    '------------------------------------------------------------------------------------------------------------------------------
    MSBPOST_                                                '     Receive Data MSBPOST
    MSBPOST_Sin   call    #Clock                            '          Send clock pulse
                  test    t1,             ina     wc        '          Read Data Bit into 'C' flag
                  rcl     t3,             #1                '          rotate "C" flag into return value
                  djnz    t4,             #MSBPOST_Sin      '          Decrement t4 ; jump if not Zero
                  jmp     #Update_SHIFTIN                   '     Pass received data to SHIFTIN receive variable
    '------------------------------------------------------------------------------------------------------------------------------
    LSBPOST_                                                '     Receive Data LSBPOST
    LSBPOST_Sin   call    #Clock                            '          Send clock pulse
                  test    t1,             ina       wc      '          Read Data Bit into 'C' flag
                  rcr     t3,             #1                '          rotate "C" flag into return value
                  djnz    t4,             #LSBPOST_Sin      '          Decrement t4 ; jump if not Zero
                  mov     t4,             #32               '     For LSB shift data right 32 - #Bits when done
                  sub     t4,             arg3
                  shr     t3,             t4
                  jmp     #Update_SHIFTIN                   '     Pass received data to SHIFTIN receive variable
    '------------------------------------------------------------------------------------------------------------------------------
    LSBFIRST_                                               '     Send Data LSBFIRST
                  mov     t3,             arg4              '          Load t3 with DataValue
    LSB_Sout      test    t3,             #1      wc       '          Test LSB of DataValue
                  muxc    outa,           t1                '          Set DataBit HIGH or LOW
                  shr     t3,             #1                '          Prepare for next DataBit
                  call    #Clock                            '          Send clock pulse
                  djnz    t4,             #LSB_Sout         '          Decrement t4 ; jump if not Zero
                  mov     t3,             #0      wz        '          Force DataBit LOW
                  muxnz   outa,           t1
                  jmp     #loop                             '     Go wait for next command
    '------------------------------------------------------------------------------------------------------------------------------
    MSBFIRST_                                               '     Send Data MSBFIRST
                  mov     t3,             arg4              '          Load t3 with DataValue
                  mov     t5,             #%1               '          Create MSB mask     ;     load t5 with "1"
                  shl     t5,             arg3              '          Shift "1" N number of bits to the left.
                  shr     t5,             #1                '          Shifting the number of bits left actually puts
                                                            '          us one more place to the left than we want. To
                                                            '          compensate we'll shift one position right.              
    MSB_Sout      test    t3,             t5      wc        '          Test MSB of DataValue
                  muxc    outa,           t1                '          Set DataBit HIGH or LOW
                  shr     t5,             #1                '          Prepare for next DataBit
                  call    #Clock                            '          Send clock pulse
                  djnz    t4,             #MSB_Sout         '          Decrement t4 ; jump if not Zero
                  mov     t3,             #0      wz        '          Force DataBit LOW
                  muxnz   outa,           t1
                  
                  jmp     #loop                             '     Go wait for next command
    '------------------------------------------------------------------------------------------------------------------------------
    Update_SHIFTIN
                  mov     t1,             address           '     Write data back to Arg4
                  add     t1,             #16               '          Arg0 = #0 ; Arg1 = #4 ; Arg2 = #8 ; Arg3 = #12 ; Arg4 = #16
                  wrlong  t3,             t1
                  jmp     #loop                             '     Go wait for next command
    '------------------------------------------------------------------------------------------------------------------------------
    Clock
                  mov     t2,             #0      wz,nr     '     Clock Pin
                  muxz    outa,           t2                '          Set ClockPin HIGH
                  muxnz   outa,           t2                '          Set ClockPin LOW
    Clock_ret     ret                                       '          return
    '------------------------------------------------------------------------------------------------------------------------------
    Done                                                    '     Shut COG down
                  mov     t2,             #0                '          Preset temp variable to Zero
                  mov     t1,             par               '          Read the address of the first perimeter
                  add     t1,             #4                '          Add offset for the second perimeter ; The 'Flag' variable
                  wrlong  t2,             t1                '          Reset the 'Flag' variable to Zero
                  CogID   t1                                '          Read CogID
                  COGSTOP t1                                '          Stop this Cog!
    '------------------------------------------------------------------------------------------------------------------------------
    {
    ########################### Defined data ###########################
    }
    zero                    long    0                       'constants
    d0                      long    $200
    
    MSBPRE                  long    $0                      '          Applies to SHIFTIN
    LSBPRE                  long    $1                      '          Applies to SHIFTIN
    MSBPOST                 long    $2                      '          Applies to SHIFTIN
    LSBPOST                 long    $3                      '          Applies to SHIFTIN
    LSBFIRST                long    $4                      '          Applies to SHIFTOUT
    MSBFIRST                long    $5                      '          Applies to SHIFTOUT
    {
    ########################### Undefined data ###########################
    }
                                                            'temp variables
    t1                      res     1                       '     Used for DataPin mask     and     COG shutdown 
    t2                      res     1                       '     Used for CLockPin mask    and     COG shutdown
    t3                      res     1                       '     Used to hold DataValue SHIFTIN/SHIFTOUT
    t4                      res     1                       '     Used to hold # of Bits
    t5                      res     1                       '     Used for temporary data mask
    address                 res     1                       '     Used to hold return address of first Argument passed
    
    arg0                    res     1                       'arguments passed to/from high-level Spin
    arg1                    res     1
    arg2                    res     1
    arg3                    res     1
    arg4                    res     1
    
    
    




    Let me know what you think it is as i eagerly wait
  • Beau SchwabeBeau Schwabe Posts: 6,559
    edited 2008-03-14 19:07
    grasshopper,
    There may be a reason that this code was not implemented into the object exchange... I only had a chance to do limited testing with a few shiftin/shiftout IC's (74HC165, and 74HC595).
    It's probably just too fast for some other IC's and needs to be slowed down a bit, but I don't know that for sure.· Where I would slow it down would be in this section of code...

    '------------------------------------------------------------------------------------------------------------------------------
    Clock
                  mov     t2,             #0      wz,nr     '     Clock Pin
                  muxz    outa,           t2                '          Set ClockPin HIGH
                  muxnz   outa,           t2                '          Set ClockPin LOW
    Clock_ret     ret                                       '          return
    '------------------------------------------------------------------------------------------------------------------------------
    

    ... by inserting NOP or delays in-between where the clock goes HIGH or LOW.

    Alternatively you could try the BS2_Function library and use the SHIFTIN/SHIFTOUT routines there.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.
  • grasshoppergrasshopper Posts: 438
    edited 2008-03-14 22:23
    Just to recap I got it to work using the BS2 Object Thanks to all that helped.

    I posted the "New" code for any one that needs to use it on a ADS8341E 16bit 4 channel A to D converter

    
    {
     ************************************************************************************************************
     *  Michael A.  3/11/2008                                                                                                        
     ************************************************************************************************************
    }
    
    {{  TESTING UNIT Ver 2.50
     
    }}
    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
      
    
    
      AD_CS         = 13             'AD Chip Select
      AD_Din        = 14             'AD Data IN
      AD_Dout       = 15             'AD Data out
      AD_Dclk       = 12             'AD clock
      
      esc           = $1B           'Escape code
      cr            = $0D           'Carriage Return code                 
      lf            = $0A           'Line Feed code
      eos           = $FF           'End of string code
      eog           = $FF           'End of graphics code
      space         = $20           'Space character code
      
    VAR
    
      Long X
      long T
      
    OBJ
       
    
      LCD           : "LCDFINAL22"
      BASIC         : "BS2_Functions"
      
    PUB MAIN
    
      dira[noparse][[/noparse]AD_CS]~~                                         'sets pin as output    
      LCD.init                                              'Initialize the display
      LCD.Cls                                               'Clear the Display
      waitcnt (1_000_000 * 50 + cnt )  
      AD_DATA                                                'Call AD_Data Method
    
    Pub AD_DATA  | R , Channel_One
    
      Channel_One := %11010111                              'Allows me to read CH1
      BASIC.Start(31,30)                                    'Turn on Basic Object
      
    repeat
      t := 0                                                'Set to 0 used for avg.
      X := 0                                                'Set to 0 used for avg
      outa[noparse][[/noparse]AD_CS]~~                                         'Chip Select high "OFF"    
      repeat R from 0 to 99                                 'my loop for getting an average AtoD number
        outa[noparse][[/noparse]AD_CS]~                                        'Chip Select low "ON"   
        waitcnt (500_000 + cnt )                            'Pause a bit not sure if i need this
        Basic.SHIFTOUT(AD_Din,AD_DClk,Channel_One,BASIC#MSBFIRST,8)
        waitcnt (500_000 + cnt )                            'Again Pause
        X := BASIC.SHIFTIN(AD_Dout,AD_DCLK,BASIC#MSBPOST,16)
        outa[noparse][[/noparse]AD_CS]~~                                       'Chip Select High "OFF" 
        T  := T + X                                          'ADD up and repeat 
    
      T := T / 100                                           'Now take an average
      
      lcd.home                                               'Set up Display 2X20
      LCD.str(string("Data = "))                             'Display Data = 
      LCD.dec(T)                                             'Display a dec number avg.
    
    



    Again thanks people. . .
    tongue.gif
Sign In or Register to comment.