Shop OBEX P1 Docs P2 Docs Learn Events
'Rotate Left' Not Rotating — Parallax Forums

'Rotate Left' Not Rotating

The manual says 'rotate left' causes the MSB to rotate to the LSB. The second expression 'should' return 225. What am I missing?
CON
          _clkmode = xtal1 + pll16x
          _xinfreq = 5_000_000                                      

OBJ
     pst  : "Parallax Serial Terminal"
         
VAR 
   byte temp

PUB main 
    pst.Start(57600)                      
    WAITCNT(clkfreq + CNT)
  
    one := (%00011110 << 4)     'shift left
    pst.dec(one)                  
    pst.Chars(pst#NL, 1)
    pst.bin(one, 8)
    pst.Chars(pst#NL, 1)
    
    one := (%00011110 <- 4)      'rotate left      
    pst.dec(one)                 'both return 224 
    pst.Chars(pst#NL, 1)
    pst.bin(one, 8)
    pst.Chars(pst#NL, 1)

Comments

  • ErNaErNa Posts: 1,752
    Maybe it's a 32 bit word, that is shifted?
  • I declared it in the VAR block as a byte.
  • ErNaErNa Posts: 1,752
    As the prop is a 32 bit processor, he might not care ;-) So it might happen, that the byte is converted to a long, the operation executed and the result again stored as a byte. You could try to use the extend sign operator ~
  • The bits do rotate when I declared it as a long. I better take a closer look at some code that does serial 8-bit data transfer. I'm trying to build a 'basic' SPI object and I've been studying objects like 'Simple Serial' but I couldn't figure out how to get the return values that I expected.
  • JonnyMacJonnyMac Posts: 9,104
    edited 2017-04-01 17:13
    Remember that many Spin operators connect directly to PASM counterparts which operate on 32-bit values. In you section situation the MSB one is ended up in BIT8 which is getting truncated by the byte definition of the variable.

    Here's a routine that may help you do 8-bit SPI -- output and input is MSBFIRST.
    pub shift_io(b) 
    
      b <<= 24                                                      ' move to byte[3]
      repeat 8
        outa[mosi] := b <-= 1                                       ' rotate MSB (bit31) to bit0 for output
        outa[sclk] := 1                                             ' clock the bit
        outa[sclk] := 0
        if (ina[miso])                                              ' if input is 1
          b |= 1                                                    '  set bit 0
        else                                                        ' else
          b &= !1                                                   '  clear bit 0  
    
      return b.byte[0]
    
    The output byte gets moved into BYTE3 so that it the MSB can be rotated into BIT0 for output. After clocking that bit out, the input (MISO) line is checked b.bit0 is set or cleared as required. There are not bit operators in Spin, so we have to do with with a mask.
  • JonnyMac, I want to reach through the monitor and shake your hand.
    As soon as I saw:
    b <<= 24
    
    I said "That's it!"
    MISO was the next hurdle. Thank you. The datsheet for the nRF24L01 says MISO and MOSI are shifted in/out simultaneously. I believe I have to shift out $FF for every byte I want to read out of the device. I have been trying to get telemetry to work.
  • Sorry, I wrote that off the top of my head thinking the MISO bit would be available post-clock. If the first MISO bit is available after the CS line drops, you can do it like this (taken from a working object this time!).
    pri spi_readwrite(datain) : dataout
    
    '' Shifts datain into MCP2515, receives and returns dataout (from MCP2515)
    
      datain <<= 24                                                 ' prep for MSB output
    
      repeat 8
        outa[mosi] := datain <-= 1                                  ' datain msb --> MOSI  
        dataout := (dataout << 1) | ina[miso]                       ' MISO <-- dataout msb 
        outa[sck] := 1                                              ' clock high
        outa[sck] := 0                                              ' clock low
       
      return dataout.byte[0]
    
  • JonnyMac, Another gem. Sometimes I have to play the tape over and over before it sinks in. That's brilliant:
    dataout := (dataout << 1) | ina[miso]
    
    It took me a while but it clicked. I thought dataout was being overwritten each time through the loop when I said "The previous value in dataout is shifted left 'before' it overwrites the destination."
    In 'my' experiments I assumed '+=' would be the logical choice because it 'didn't' overwrite the previous value.
Sign In or Register to comment.