Syntax in Spin?

Hi guys,

I've been playing with Spin again and trying to figure out how to form this expression..

I'd like to use a variable to indicate a range of pins -
as in outa [8..11] := Mot_RoR
so as outa[motorpins] := MotRoR

The individual pins named as below ... MotA1, MotA2, MotB1, MotB2.
But how to express all four at once?

Richard

' Pin Definitions:
' LSB MSB
' 000000000 01111111 11122222 2222233
' 012345678 90123456 78901234 5678901
PADpins = %11111111_00000000_00000000_00000000 ' 0..7 Touchpads
MOTPins = %00000000_11110000_00000000_00000000 ' 8..11 Motor Control
PWMpins = %00000000_00001100_00000000_00000000 ' 12..13 Motor PWM
LCDpins = %00000000_00000010_00000000_00000000 ' 14 LCD Display
IRCpins = %00000000_00000001_00000000_00000000 ' 15 Infra Red Controller
LEDpins = %00000000_00000000_11111111_00000000 ' 16..23 QS LEDs
OBXpins = %00000000_00000000_00000000_11110000 ' 24..27 Obsticle sensors
EPCpins = %00000000_00000000_00000000_00001000 ' 28 EEPROM Clock
EPDpins = %00000000_00000000_00000000_00000100 ' 29 EEPROM Data
USBpins = %00000000_00000000_00000000_00000011 ' 30..31 USB
OUTpins = MOTpins| PWMpins| LEDpins| LCDpins
'======================================
' Motor control pins for TB6612FNG
MotA1 = 8
MotA2 = 9
MotB1 = 10
MotB2 = 11
PWMA = 12
PWMB = 13

' Motor Direction Masks for TB6612FNG
Mot_Fwd = %0110 ' Go fwd
Mot_Aft = %1001 ' Go Aft

Mot_Rit = %0010 ' Turn Right
Mot_Lft = %0100 ' Turn Left

Mot_RoR = %1010 ' Rotate Right
Mot_RoL = %0101 ' Rotate Left

Mot_Off = %0000 ' All Stop

Comments

  • I believe you mean
    outa [MotA1..MotB2] := Mot_RoR
    
    (i.e., you want to affect the pins MotA1 through MotB2 using the mask Mot_RoR?)

    Cheers
    --
    WIP Spin drivers for various devices: LSM9DS1 IMU (SPI) | Newhaven 4x20 OLED (I2C) | MLX90621 (I2C) | SHT3x (I2C) | SSD1306 OLED (I2C; P1-SPIN, P2-SPIN2) | TCS3x7x (I2C) | MAX31856 (SPI) | BMP280 (I2C) | TMC2130 (SPI) | nRF24L01+ (SPI) | MLX90614 (I2C) | MAX9744 (I2C) | DS28CM00 (I2C) | TSL2591 (I2C) | CC1101 (SPI) | SX1231 (SPI)
  • Yes, but sometimes the pins are not contiguous...

    Is it possible to set a pattern for them (that is not contiguous)?
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 22,289
    edited 2018-08-12 - 20:33:22
    In your examples above, you have the longs reversed. LSB is on the righthand side or your %... constants. So bits 0..7 would be:

    %00000000_00000000_00000000_11111111

    -Phil
    “Perfection is achieved not when there is nothing more to add, but when there is nothing left to take away. -Antoine de Saint-Exupery
  • avsa242avsa242 Posts: 141
    edited 2018-08-12 - 20:53:33
    Something like
    outa := (PWMPins | LEDPins | LCDPins) | (Mot_Fwd << 20)
    

    replacing Mot_Fwd with whichever other constant...essentially affects the entire outa register

    See attached serial demo for 'illustration' (just spits out numbers, doesn't affect the outa register)


    EDIT:
    Regarding what Phil said, the '20' would need to be adjusted to the least significant motor pin, if your pin constants are indeed backwards
    --
    WIP Spin drivers for various devices: LSM9DS1 IMU (SPI) | Newhaven 4x20 OLED (I2C) | MLX90621 (I2C) | SHT3x (I2C) | SSD1306 OLED (I2C; P1-SPIN, P2-SPIN2) | TCS3x7x (I2C) | MAX31856 (SPI) | BMP280 (I2C) | TMC2130 (SPI) | nRF24L01+ (SPI) | MLX90614 (I2C) | MAX9744 (I2C) | DS28CM00 (I2C) | TSL2591 (I2C) | CC1101 (SPI) | SX1231 (SPI)
  • cavelambcavelamb Posts: 679
    edited 2018-08-12 - 20:55:37
    Interesting, Phil.
    I had them the way you show but couldn't get it working until I turned the whole mess around.
    No I wonder if I'm running backwards??? :blush:

    Why does this work???
    MotA1 = 8
    MotA2 = 9
    MotB1 = 10
    MotB2 = 11
    PWMA = 12
    PWMB = 13
    MotPins = %00000000_00000000_00111111_00000000
    PWMpins = %00000000_00000000_00110000_00000000

    'stopping motors
    dira [MOTpins] := 0
    outa [PWMpins] := 1 ' set PWM pins hi to release brakes


  • I need to dig into that and see what's going on there!
  • avsa, thank you for the example. I've looked at it briefly just now.
    I'll study it next.

    I've been trying to un-confuse myself, but it just seems to get worse...

    Program is set up to run on a QuickStart with a two-line LCD display for cross check
    and an IR remote control decoder for input.

    Just walking through the numbers (1 to 7) for LED.

    This test was cobbled together to try to get to the bottom of it.
    LED1 through LED8 are intended to be bit patterns for the LEDs.
    That seems to work as expected - when setting the directions via dira[16..23] := %11111111

    But setting directions via dira[LEDpins] := LEDpins (commented out below) doesn't work
    with the pin mask going either way...

    LEDpins = %00000000_00000000_11111111_00000000 ' 16..23 QS LEDs
    ' LEDpins = %00000000_11111111_00000000_00000000 ' 16..23 QS LEDs

    So something between me, the compiler and the Propeller is badly disconnected!


    CON
      _CLKMODE = XTAL1 + PLL16X        ' 80 Mhz clock
      _XINFREQ = 5_000_000
      OneSec = _XINFREQ
      MSec   = _XINFREQ / 1_000     * 8
      USec   = _XINFREQ / 1_000_000
      
    '======================================
      IRCpin         = 15                ' IR Receiver - Propeller Pin
    
    ' Liquid Crystal Display - 2 line'
      LCDpin = 14
      LCDon1        = $16               ' LCD on; cursor off, blink off
    
    
    '======================================
    ' this program is trying to work out the bit patterns for LED pins.
    '
    ' LED pins are [16..23]
    ' Trying to get the bit maks direction correct here...
    
      LEDpins = %00000000_00000000_11111111_00000000  ' 16..23    QS LEDs
    '  LEDpins = %00000000_11111111_00000000_00000000  ' 16..23    QS LEDs
    
        
    ' Pin Definitions:
    '         LSB--MSB  
      LED1 = %10000000
      LED2 = %01000000
      LED3 = %00100000
      LED4 = %00010000
      LED5 = %00001000
      LED6 = %00000100
      LED7 = %00000010
      LED8 = %00000001
     
    '======================================
    OBJ
      ir      : "IRC"
      lcd     : "serial_lcd"
      num     : "simple_numbers"
    
     '====================================== 
    VAR
      long Stack1[6]
      long IRcog              
       
      Byte IRC_ret, x1 , x2    
      Byte LED
      
    '======================================
    PUB Init | freq, index, cog, IRcode
    
    ' Init IR remote
      IRcog := ir.Start(IRCpin, @IRC_ret)  ' Pin of IR receiver, address of variable
    
    '======================================
    ' init LCD
    
      if lcd.start(LCDpin, 9600, 2)
        lcd.putc(lcd#Lcd_On1)              ' no cursor
        lcd.backlight(1)
        lcd.cls
        WaitMs(100)    
        lcd.str(string("BIT MASK Test"))
            
    '===================================== '
    
      LED := 0
      
    ' pin directions
      outa[16..23] := $00                ' all LED pins off
      '
    ' Here is what I'm stuck on...
    ' The first line ( dira[16..24] ) works as expected
    ' LEDs light up as they are supposed to.
    
    ' but can't get ( dira [LEDpins] ) going with either mask ...
    ' the LEDs do not light up!
    
      
      dira[16..23] := %11111111          ' make LED pins outputs
    
    '  dira[LEDpins] := LEDpins          ' make LED pins outputs
    
    
    ' Top of IR Code input loop:
      if IRcog > 0
          repeat
    
            If IRC_ret <> ir#NoNewCode     ' we have a key code
               IRcode := IRC_ret
               ir.Start(IRCpin, @IRC_ret)  ' set up for next code         
                          
               case IRcode                 ' Parse the key code                 
               
                 ' control keys                     
    
                  ir#chUp  :
    
                    LCD.CLS
                    lcd.str(string("CH UP = "))
                    
                    If LED < 8 
                       LED := LED +1
                    else
                       LED := 1       ' wrap around
    
                  ir#chDn  :
                   
                    LCD.CLS 
                    lcd.str(string("CH DN = "))
    
                     If LED > 1 
                        LED := LED -1
                     else
                        LED := 8       ' wrap around
    
                ' numeric keys
                                  
                  ir#zero  :
                    LCD.CLS                
                    lcd.str(string("<0> "))
    
                                
                  ir#one   :
                    LCD.CLS                
                    lcd.str(string("<1> "))
                    LED := 1
                    
                  ir#two   :
                    LCD.CLS                
                    lcd.str(string("<2> "))
                    LED := 2
                    
                  ir#three :
                    LCD.CLS                
                    lcd.str(string("<3> "))
                    LED := 3
                                    
                  ir#four  :
                    LCD.CLS                
                    lcd.str(string("<4> "))
                    LED := 4
                    
                  ir#five  :
                    LCD.CLS                
                    lcd.str(string("<5> "))
                    LED := 5
                     
    
                  ir#six   :
                    LCD.CLS                
                    lcd.str(string("<6> "))
                    LED := 6 
                      
                  ir#seven :
                    LCD.CLS                
                    lcd.str(string("<7> "))
                    LED := 7
    
                  ir#eight :
                    LCD.CLS                
                    lcd.str(string("<8> "))
                    LED := 8
    
               waitcnt((clkfreq / 1000) * 30 + cnt)
    
      
              LCD.str(num.dec(LED))        
    
    
              case LED
               
                 1:
                   outa [16..23] := LED1
                 2:
                   outa [16..23] := LED2                        
                 3:
                   outa [16..23] := LED3
                 4:
                   outa [16..23] := LED4
                 5:
                   outa [16..23] := LED5 
                 6:
                   outa [16..23] := LED6 
                 7:
                   outa [16..23] := LED7 
                 8:
                   outa [16..23] := LED8 
    
                               
            waitcnt((clkfreq / 1000) * 30 + cnt) 
    
    '======================================
    PUB WaitMS(W)                        'wait for W milliseconds
      W := W * MSec                
      WaitCNT (W+cnt)
    
    '======================================
    





  • For what it's worth, the project is running.
    Simple remote control software so far, but
    I'd like to better understand why I don't
    understand some of this mess...

    https://youtube.com/watch?v=OsBPsCHbUa8
  • T ChapT Chap Posts: 3,984
    edited 2018-08-12 - 23:11:11
    When you need affect a range of 8 pins using %11111111 you are moving the values %11111111 into the values for the pins. However when you want to affect a range of 8 pins using %00000000_11111111_00000000_00000000 you are actually setting the value. %00000000 to the pins. Think in terms of using 8 bits to assign into a range of 8 pins. You are trying to cram 32 bits into an 8 bit range of pins.
  • cavelambcavelamb Posts: 679
    edited 2018-08-12 - 23:14:35
    I am???


    LEDpins = %00000000_00000000_11111111_00000000 ' 16..23 QS LEDs
    ' LEDpins = %00000000_11111111_00000000_00000000 ' 16..23 QS LEDs


    dira[LEDpins] := LEDpins ' make LED pins outputs - that's all 32 bits


    My question really is - Which end is which?

    verses

    dira[16..23] := %11111111 ' make LED pins outputs
  • T ChapT Chap Posts: 3,984
    edited 2018-08-12 - 23:23:52
    Sorry I missed what you were doing. For pins 16-23 then LEDpins = %00000000_11111111_00000000_00000000 ' 16..23 will work. As long as you are ok with all other pins being set to 0. Seems like you would only want to affecting 8 pins though via outa[xx] not all 32.
  • cavelambcavelamb Posts: 679
    edited 2018-08-12 - 23:37:11
    Or just accept that we address pins with hard coded numbers?

    But that won't help out-of-sequence pins.

    OR with the contents of PIN register?
    Then AND with mask to be set?

    I need to go back to the documentation.
  • When you are using Dira[xx] on all pins you are asking for headaches. Since you know the range and the range isn’t changing why not keep it simple [16..23].
  • T Chap wrote: »
    When you are using Dira[xx] on all pins you are asking for headaches. Since you know the range and the range isn’t changing why not keep it simple [16..23].

    As in KISS...
  • T ChapT Chap Posts: 3,984
    edited 2018-08-13 - 00:03:37
    If you try to use OR to affect a dir register and let’s say a pin is already 1 (out) but you want the pin to be 0 (in) and you say dira[0] |= 0 which is Bitwise OR 0 the pin will stay 1. you can set a pin to output using bitwise OR 1 but then if you want to set back to input you can’t use bitwise OR 0 you’d have to use bitwise AND 0 (dira[0] &= 0) So it gets be more work trying to do that way. Just keep it simple

    VAR byte ledstate
    Ledstate := %00000000 ‘or as needed
    dira[16..23] := %11111111
    Outa[16..23] := ledstate

  • If you want to use bitmasks with & and |,then use OUTA and DIRA registers without any brackets.

    OUTA[pin] accesses one single pin, with the number in brackets.

    OUTA[Highpin..Lowpin] accesses a contiguous range of pins. Always write the higher pin first in the brackets, otherwise the bits get written in reverse order. If you have a range of 8 bits (ie. 23..16), the lower 8 bits of the value (7..0) gets written to that bit range.

    The bracket syntax does not allow to write to a range of pins in random order (non contiguous).
  • cavelambcavelamb Posts: 679
    edited 2018-08-13 - 03:52:06
    Ariba, amigo mio!

    I do believe you figured it out for me.

    I was writing Low bit to high bit... outa [16..23] := backwards_bits
    Reverse order...
    Which worked mo betta with the mask backwards?

    I'll see if I can straighten that out (and still have running code).

    Gracias,


    PS:
    Would you show me a syntax example of no brackets?

    Outa pinmask := bit mask ???


    Richardo
  • AribaAriba Posts: 2,211
    edited 2018-08-13 - 14:07:26
    You're welcome Richardo

    Here some snippets with that use DIRA and OUTA direct as 32bit registers:
    CON
      LEDpins = %00000000_11111111_00000000_00000000 ' 23..16 QS LEDs
      LED8 = %10000000
      LED7 = %01000000
      LED6 = %00100000
      LED5 = %00010000
      LED4 = %00001000
      LED3 = %00000100
      LED2 = %00000010
      LED1 = %00000001
    
    
    PUB ...
    
      DIRA |= LEDpins                        'set LED pins as outputs
    
      OUTA := (OUTA & !LEDpins) | LED1<<16   'write LED1 pattern to LED pins
      OUTA[23..16] := LED1                   'the same with brackets
    

    Andy
  • Got it.

    Lovely examples of addressing with and, or and shifting.

    Thank you!

    Richard
  • T ChapT Chap Posts: 3,984
    edited 2018-08-13 - 15:38:02
    Don’t forget that you can just as easily read the dira/outa register and see what your states are. If you have a terminal connected you can display outa in binary as a 32 bit value, then do some process and view it again to see if you are getting the result you want. Demystify the contents of the register. You can create some test code just to affect the registers with what you want to see happen and it’s easier than using the acutal leds for debug, because if the leds are wrong you still can’t see what the problem is.
  • That was what the LCD display was for, T Chap.
    Cross check.

    I've never had much luck with the terminal function.
    I like getting it straight from the Prop.
  • Yes. Lcd or terminal or whatever. This is a quick test to show dira.
Sign In or Register to comment.