I also picked up this book, I was looking for something on PASM and this was the only one I found. I have to agree with red, its current state is that of a draft, many spelling and general errors are distracting at least for me to keep with the flow of the book. There is also a little repetition as it seems things were moved around but the original part not removed. Overall I think it was helpful, I am about half way done with the book. It has a lot of well documented code and examples that are easy to follow.
Honestly, I think it's rough and needs some serious editing before I would consider it of commercial quality. In many cases it feels like the author is repeating things he's seen in this thread and doesn't understand them himself. This may just be a styling issue which copy-editing could address but regardless, it was the impression I was left with.
I brought this book a few months ago as I wanted to lean a bit more about PASM. My immediate need was to increase the measurement speed of an MCP320x ADC beyond the ability of SPIN. This book used this device extensively in its examples. The idea of using the MCP320x device as a leaning tool is a good one since it requires I/O, timing and general passing back and forth of values to the main hub memory. Unfortunately the book does not directly address the details in MCP320x datasheet regarding I/O (minimum and maximum clock speed, minimum sampling capacitor charge time, etc.). There were some missed opportunities to really help the reader understand the intricacies of this device and how PASM can handle them quite nicely. It seems like the author had the right idea of starting out with SPIN to introduce how the MCP320x works. In fact I would have written the first example program with no loops (yup, every painful clock tick and data line I/O on its own line). Then show how you can condense the SPIN code down - perhaps taking two or three iterations to get to something nice and tight. Then transition this same approach with PASM showing how similar the languages are and where PASM differs and how much faster it can run. Condensing PASM to its minimal size seems quite tricky to me as a beginner as it requires much more attention to detail. If the book had taken this approach it might have been more effective in teaching me PASM.
While I got a few tips from reviewing the code examples, the book itself lacked flow and continuity. I could see glimpses of points trying to be made but it seems too disjointed to be readable to any reasonable extent. It reads like a draft concept of an "Introduction to PASM" rather than an initial publication. A bit verbose in several sections, the illustrations lack clarity as the very thin lines are hard to see, the overall text formatting is poor and the index is awful. This book would have greatly benefited from some editing by a third party (the editing process has value!).
I have gleaned far more PASM learning from potatohead's and desilva's PASM pdfs than from this book.
The SPIN manual is a good reference guide for PASM too but it lacks practical examples for each command and virtually no examples of common command snippets. As a beginner I had to spend lots of time looking for examples of how to do basic SPIN coding somewhat efficiently. Seems like well documented PASM examples for the beginner are quite rare. Parallax has a scant set of 19 application notes (and it seems like you have to go to the Parallax Semiconductor site to get them now). I have often wondered why Parallax has not written an "Introduction to SPIN" and an "Introduction to PASM". Especially since they seem to want to promote the Propeller chip to the beginner student.
I don't think I'm alone in still waiting for a good "Introduction to PASM" tome.
I'm an experienced Assembly programmer.
But PASM still eludes me.
I just haven't found a starting point yet.
Please tell me about this. I understand something about people who have not had assembly experience, but I really don't understand experienced assembly language programmers having trouble with PASM. What sort of questions are you asking and how do those link to concepts you may or may not associate with PASM?
If you could enlighten me, and it's not a problem to put it here, I would very much appreciate that discussion. That applies to anyone BTW. Thanks.
I am confident that a much better book could be written for beginners. A much better book.
Any one who cared to do so could have done so but no one is even threatening to do so even as I type..
People who know a lot more about PASM than I do could have done it. They did not.
Parallax has not done so... so far.
No one has.
The book did you some good if one, you now know a bit more about PASM than you before started and two if you can now write simple code in PASM
The answers to both questions are yes (from those buyers who cared to answer the questions for me).
So many technical books are so full of data sheets copied from the internet files. I chose not to do that.
I also did not repeat what is already in the Propeller Manual.
There are about 90 pages of code in the book and each and every line is commented.
Most of the code on the internet is Greek to beginners. It was to me.
Comments about flow and style may indeed be relevant but do not address the learning experience directly.
I asked at least 100 questions on the forum as I wrote the book.
The answers were sincere but not overly enlightening to my beginner's mind set.
I had to figure most of it out the hard way. Hopefully my efforts will save beginners some headaches.
PLEASE WRITE A BETTER BOOK.
Light a candle, don't just curse the darkness.
I am confident that a much better book could be written for beginners. A much better book.
Any one who cared to do so could have done so but no one is even threatening to do so even as I type..
People who know a lot more about PASM than I do could have done it. They did not.
Parallax has not done so... so far.
No one has.
The book did you some good if one, you now know a bit more about PASM than you before started and two if you can now write simple code in PASM
The answers to both questions are yes (from those buyers who cared to answer the questions for me).
So many technical books are so full of data sheets copied from the internet files. I chose not to do that.
I also did not repeat what is already in the Propeller Manual.
There are about 90 pages of code in the book and each and every line is commented.
Most of the code on the internet is Greek to beginners. It was to me.
Comments about flow and style may indeed be relevant but do not address the learning experience directly.
I asked at least 100 questions on the forum as I wrote the book.
The answers were sincere but not overly enlightening to my beginner's mind set.
I had to figure most of it out the hard way. Hopefully my efforts will save beginners some headaches.
PLEASE WRITE A BETTER BOOK.
Light a candle, don't just curse the darkness.
Harprit
I hope you didn't take my comments negatively. As I said before, overall it is a helpful book. So far (Not yet finished) I have picked up many things I didn't know. I was just saying it needs a bit of review to make it flow better and remove some errors, but this was not a put down of the book but more a suggestion for the next revision. Also as you just noted, as well did I, that this book fills a void as it was the only one I found that covered PASM.
PLEASE WRITE A BETTER BOOK.
Light a candle, don't just curse the darkness.
Yes. Needs to happen. Maybe someday. You did work hard and you did write a book. I've refrained from any commenting on it, because you made your contribution to fill a vacuum, and you did it with your best intent too. And it's going to benefit some people.
While I got a few tips from reviewing the code examples, the book itself lacked flow and continuity. I could see glimpses of points trying to be made but it seems
too disjointed to be readable to any reasonable extent. It reads like a draft concept of an "Introduction to PASM" rather than an initial publication. A bit verbose in
several sections, the illustrations lack clarity as the very thin lines are hard to see, the overall text formatting is poor and the index is awful. This book would have
greatly benefited from some editing by a third party (the editing process has value!).
I just read the comments before I was planing on purchasing the book, but your comments sound as though you could
be talking about Harprit's book on SPIN.
I have gleaned far more PASM learning from potatohead's and desilva's PASM pdfs than from this book.
Unfortunately Potatohead's and Desilva's PASM pdfs didn't help me, and that is why I was interested in Harprit's
book on PASM.
I have the Parallax book by Gunther Daubach for Programming the SX, Several books on programming the PIC, assembly
programming the 486, by Irvine and other mpu's. They have helped me develop some basic ideas, but all I own is Parallax
products, and I really have no interest in any other manufactures products.
I realize writing a book on such a specialized subject like this is not a money maker for the author, and Parallax can't
pay someone for all the time it takes to write a proper book. Why can't Parallax (with some help) write a downloadable
PDF similar to the Basic Stamp books, that were free to download, and with that old style Parallax experience?
Keep it simple, and use the IC's Parallax sells as examples people can incorporate into their own projects, instead of
projects we will never build.
I also have many of Jon Williams Nuts and Volts articles, but to many of them deal with projects I have no interest in,
and for me, that is similar to reading a book about programming a PIC in assembly without the interest or intention to
ever do so.
Overall I think it was helpful, I am about half way done with the book. It has a lot of well documented code and examples that are easy to follow.
The book has a LOT of well documented easy to follow code, many of the examples and OBEX stuff I have found have complex parts that have a general statement of what they intend to do rather than what every line is doing like in the book. The content of the book is good, and was informative.
I wish a lot more of the buyers would post here instead of telling me about it.
You can learn a lot from the book if you are a beginner. 80 pages of pure PASM code. Every line documented and easy to follow. I send you the file so you don't have to retype a thing.
Unfortunately the fingers of naysayers are faster to the keys than those that were helped.
I am pretty sure no one else will write a book. I have two books on PICs that with their two e-versions have been in the top 50 PIC books every week for well over three years. Often number 1 is a book by me. That is 4 out of the top 50!!!! I think its a record. My royalty check from McGraw last quarter $21.00.
Here is a review of my books written as the reviewer reviewed another book NOT written by me.
Two of the best books on PIC controllers are written by Mr. Harprit Singh Sandhu. They both contain a lot of circuit examples , and programming examples to work with the circuits. The books are based on the Melabs Lab-X1 demo board, but you do not need the board to get a feel for the controllers, or the programming. Mr. Sandhu steps through his programs with great detail, and makes them very easy to follow with excellent programming commenting.
The programming used in his books is based on MeLabs Pic Basic Pro. Pic Basic Pro comes in various versions, so depending on your needs, the cost can vary between free, $49 fr a student, $120 for Silver, and $250 for a Gold license. I bought the silver license, and have been very happy with it.
I have two of Mr. Sandhu's books, and a coupe of others that explain PIC functions, and circuit examples with Basic org ramming examples. The some of the best advice Mr. Sandhu will give you is about the data sheets, and various PIC's. That is to pick a PIC to work with, and study it so you will know it well. The programming will be much easier once you understand the functions of the PIC you choose to work with However, both of his books are based on the Lab-X1, and the 16F877a PIC. This PIC is a 40 pin work horse of a PIC, but once you can work with this one PIC, you will be able to easily work with most others. The programming from one PIC can be transferred to many others with very little rework, or effort.
I hope you, as a reader, feel I have helped you get on the fast track to learning about PIC programming. It is a lot of fun, easy, and well worth the time you will put into it.
My spin and PASM books are in the same vein. As regards the gripe about my repeating stuff (which is minimal). This is a reference text you will use hundreds of times. You should not have to spend time finding lines of specific code in the middle of hard to understand machine language. Repeating it where needed in the discussion avoids this.
And the book is not full of data sheets copied from the internet or information that is already in the Propeller manual. Not one line.
I read your unedited post very late last night and note that you have deleted some or your questions by this afternoon.
I do not remember your exact wording now but here goes. Maybe this will help.
I found that I could use 100K pots on the 3208 without problems. The usual recommendation is 5K pots. Since the pots are all placed across the power supply, they eat up the amps pretty fast and soon the prop starts to reset and readings become unreliable for low and high values of the pot reading (at 12 bits). Specially important if you want to or need to place 8 units across the power supply.
The slow down on the 3208 at lower voltages can be compensated for by slowing down the Propeller if that is necessary. My experience was that the chip was fast enough to keep up with the Prop. In these cases it is best to run a test to satisfy yourself for the conditions that you have on your board are not creating a problem.
I dwell on the 3208 in the book so that I can stick with one chip that has almost universal appeal if you are interested in real time inputs and in reading all sorts of sensors. If you learn to use the 3208, the rest will be easier.
Call me if you want to discuss further 217 269 8737 any time.
I decided to post these questions here rather than call because it may help someone else.
(1) I am having problems understanding some of the pasm code from "064 PASM_Book_ReadPot.spin."
Primarily the Global Label "read_bit." My problem is recognizing how the data is transferred from the
data out pin #27 to the PAR register.
Today I realized the Z-flag might be treated as a global variable that can be changed by any instruction
line after it has been set?
For several days now, I could not see the relationship between "temp" and "dat_red." Note: If you look
at my version of the code, I tried to use the Basic Stamp and SXB code conventions, and changed some
of the names to be more meaningful to me. Such as: "longTmp" instead of "temp," and "readData"
instead of "dat_red."
I was unable to use the Propeller Manual to solve this problem by myself. I have used the MCP3208
data sheet to get a more in depth understanding of the adc chip.
read_bit mov temp, ina 'read in what is in all the input lines
andn temp, mask26 wz 'mask off except Dout line & Set Z flag
shl Dat_red, #1 'shift register left 1 bit ready for next bit
if_nz add Dat_red, #1 'if value is positive add 1 to data register
call #Tog_Clk 'toggle clock to get next bit ready in Dout
sub count, #1 wz 'decrement "bits read" counter. Set Z flag
if_nz jmp #read_bit 'go up and do it again if counter not yet 0
mov mem, par 'get address of par into mem
wrlong dat_red, mem 'write it in HUB to share it as P.Val
call #Chip_Sel_Hi 'Put chip to sleep by de-selecting it
jmp #generate 'go back to do it all again
This is my version of the code:
Read_Bit mov longTmp, ina ' Read all input pin status, and store in longTmp
andn longTmp, mask26 wz ' Mask off all pins except Dout pin, and set Z flag
'' If the WZ effect is specified, the Z flag is set (1) if the resulting Value equals zero.
'' If the WC effect is specified, the C flag is set equal to Value’s original bit 31. The
'' result is written to Value unless the NR effect is specified.
'' SHL (Shift Left) shifts Value left by Bits places and sets the new LSBs to 0.
'' ??? Is the Zero Flag treated as a global variable that can be changed by any
'' ??? instruction after it is set?
'' ??? Is the a method that is more transparent to demonstrate how the Data out
'' ??? pin (longTmp) is recorded on each index itteration?
' %00000000_00000000_00000000_00000000
shl readData, #1 ' %00000000_00000000_00000000_0000000
if_nz add readData, #1 ' if Z clear, add 1 to readData.
call #Toggle_Clk
sub index, #1 wz
if_nz jmp #Read_Bit
mov parMem, par
wrlong readData, parMem
call #CS_Hi
jmp #Generate
(2) I am having problems finding a truth table for the "andn" instruction. The Propeller
manual describes it as: "ANDN (bitwise AND NOT) performs a bitwise AND of the inverted
value (bitwise NOT) of Value2 into that of Value1"
'---------- Subroutines ----------------------------------------------------------
Clk_Hi or outa, ClkBit ' Pin #27
'' Bitwise OR:
'' The result in each position is 1 if the first bit is 1 or the
'' second bit is 1 or both bits are 1; otherwise, the result is 0.
Clk_Bit_ret ret ' Used to mark the end of the sub.
'----------------------------------------
Clk_Low andn outa, ClkBit
Clk_Low_ret ret
I have looked at Microsoft, Wikipedia and other programming websites and they don't
seem to use the same terminology for some bitwise operators.
Can someone please help me understand ANDN? and does the ANDN and the OR
effect the entire 32 bit long?
Harprit recommends to use the Propeller Manual and the MCP3208 data sheet
as additional references in addition to the book. Despite the fact the books unfinished
appearance, the book has worked well for me because it isn't perfect. It kinda forced
me to study, and that works for my personality. It is difficult for me to accept something
as real, genuine, or a fact, without my own investigation into what is presented to me.
Despite the well documented code, I ended adding my own comments, some directly
from the mcp3208 data sheet and propeller manual. I also documented the step by step
process of the mcp3208.
The largest difference to me, is the code is relatively easy to read, and therefore easy
for me to follow and develop a deeper understanding of the basics. On the other hand,
trying to read polished code in some other books has made it difficult for me to continue
reading those books.
For example: this is my take on Harprit's code:
CON
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
' -------------------------------------------------------------------------------
VAR
long PVal
' -----------------------------------------------------------------------------------
OBJ
fds : "FullDuplexSerial"
' ------------------------------------------------------------------------------------
PUB
fds.start(31,30,0,115200)
cognew(@generate, @PVal)
repeat
fds.bin(P_Val, 12)
fds.tx($d)
fds.dec(P_Val)
fds.tx(" ")
fds.tx($1)
waitcnt(clkfreq / 60 + cnt)
' -----------------------------------------------------------------------------------
DAT
'' DATA IN is always read from the device
'' on the RISING EDGE of the clock.
'' DATA OUT is always read from the device
'' on the FALLING EDGE of the clock.
org 0 ' Starting point.
Generate mov dira, SetDira ' Set Direction.
'' Initiating communication with MCP3208
'' is done by bringing the CS line low.
'' If the device was powered up with the
'' CS pin low, it must be brought high
'' and back low to initiate communication.
'' The first clock received with CS low
'' and DIN high will constitute a START
'' BIT.
call #CS_Low ' Chip select, pull low.
call #Clk_Low ' In order to start, Clk must be set low.
call #Din_Hi ' In order to start, Data In must be set high.
call #Toggle_Clk ' In order for the mcp3208 to read data from the Propeller
' the, we need to toggle the clock to high and back to configure Start Bit.
' The first Toggle_clk recieved with CS_low & Din_hi will constitute
' the first START_BIT.
'' START_BIT Declared
call #Din_Hi ' Din_hi sets the single or differential mode of the data configuration,
' when set Hi the MCP3208 is set to read from 8 single ended inputs.
call #Toggle_clk ' Toggle clk from low to high and back to low to configure Data In.
'' SINGLE_END Declared
call #Din_low ' Din_low sets data configuration bit D2
' CH 0 input configuration on D2-D0 is %000
call #Toggle_Clk ' Toggle clk from low to high and back to low to configure Data In.
call #Din_Low ' Din_low sets data configuration bit D1
call #Toggle_Clk ' Toggle clk from low to high and back to low to configure Data In.
call #Din_Low ' Din_low sets data configuration bit D0
call #Toggle_Clk ' Toggle clk from low to high and back to low to configure Data In.
'' FOURTH_RISING_CLOCK
'' SAMPLE_PERIOD_BEGINS
'' The MCP3208 will begin to sample the analog
'' input on the fourth rising edge of the clock
'' after the start bit has been received.
'' Once the D0 bit is input, one more clock is required to
'' complete the sample and hold period (DIN is a “don’t
'' care” for this clock).
'' The sample period will end on the falling
'' edge of the fifth clock following the start
'' bit.
call #Toggle_Clk ' Sample period ends
'' On the falling edge of the next clock, the MCP3208 will
'' output a low null bit.
'' The MCP3208 must shift from recieving instruction as the clock
'' rises, to supplying data on the falling edge of the clock. In
'' order to do so, it takes 1 1/2 clock cycles to make the change.
call #Toggle_Clk ' Triggers the first output as the Null Bit.
mov readData, #0 ' No real data from the MCP3208, so clear the file location. Mainly applies to the 2nd data
' read, and every data read afterwards.
mov index, #12 ' Creates an index that counts down after each Clock Cycle. (it was count)
'' The next 12 clocks will output the result of the conversion
'' with MSB first.
'' Data is always output from the device on the falling edge
'' of the clock.
'' If all 12 data bits have been transmitted and the device
'' continues to receive clocks while the CS is held low, the
'' device will output the conversion result LSB first.
'' If more clocks are provided to the MCP3208
'' while CS is still low (after the LSB first data has been
'' transmitted), the device will clock out zeros indefinitely.
Read_Bit mov longTmp, ina ' Read all input pin status, and store in longTmp
andn longTmp, mask26 wz ' Mask off all pins except Dout pin, and set Z flag
'' If the WZ effect is specified, the Z flag is set (1) if the resulting Value equals zero.
'' If the WC effect is specified, the C flag is set equal to Value’s original bit 31. The
'' result is written to Value unless the NR effect is specified.
'' SHL (Shift Left) shifts Value left by Bits places and sets the new LSBs to 0.
'' ??? Is the Zero Flag treated as a global variable that can be changed by any
'' ??? instruction after it is set?
'' ??? Is the a method that is more transparent to demonstrate how the Data out
'' ??? pin (longTmp) is recorded on each index itteration?
' %00000000_00000000_00000000_00000000
shl readData, #1 ' %00000000_00000000_00000000_0000000
if_nz add readData, #1 ' if Z clear, add 1 to readData.
call #Toggle_Clk
sub index, #1 wz
if_nz jmp #Read_Bit
mov parMem, par
wrlong readData, parMem
call #CS_Hi
jmp #Generate
'---------- Subroutines ----------------------------------------------------------
Clk_Hi or outa, ClkBit ' Pin #27
''
Bitwise OR:
'' The result in each position is 1 if the first bit is 1 or the
'' second bit is 1 or both bits are 1; otherwise, the result is 0.
Clk_Bit_ret ret ' Used to mark the end of the sub.
'----------------------------------------
Clk_Low andn outa, ClkBit
Clk_Low_ret ret
'-----------------------------------------
Toggle_Clk call #Clk_Hi
call #Clk_Low
Toggle_Clk_ret ret
'-------------------------------------------
Din_Hi or outa, DinBit
Din_Hi_ret ret
'------------------------------------------
Din_Low andn outa, DinBit
Din_Low_ret ret
'------------------------------------------
CS_Hi or outa, CSBit
CS_Hi_ret ret
'---------------------------------------------
CS_Low andn outa, CSBit
CS_Low_ret ret
'--------------------------------------------
Read_Next_Bit mov longTmp, ina
or longTmp, mask26
Read_Next_Bit_ret ret
' ---------- Constants -------------------------------------------------------------
SetDira long %00001011_11000000_00001111_11111111 'Set dira register
CSBit long %00000001_00000000_00000000_00000000 'Chip select bit 24
DinBit long %00000010_00000000_00000000_00000000 'Data in bit 25
DoutBit long %00000100_00000000_00000000_00000000 'Data out bit 26
ClkBit long %00001000_00000000_00000000_00000000 'Clock bit 27
Mask26 long %11111011_11111111_11111111_11111111 'Mask forDout bit only
Pin23 long %00000000_10000000_00000000_00000000 'osc line
Pin22 long %00000000_01000000_00000000_00000000 'Speaker line
' --------- Variables ------------------------------------------------------------
longTmp res 1
index res 1
readData res 1
parMem res 1
' ------------- End of Program ----------------------------------------------------------
Fit
' -------------------- Definitions ----------------------------------------------------------------
' CALL pg. 268
And this is Harprit's original code:
{{-------------------------------------------------------------------------------
PASM_Book_ReadPot.SPIN
Function of program
Makes an electronic Metronome.
Notes: Program reads a potentiometer
See details in book
Program PASM_Book_ReadPot.SPIN
Book PASM for beginners, Propeller 102
Section Outputs
Programmer Harprit Sandhu
Date Jan 10 2013
Revisions: Report errors to harprit.sandhu@gmail.com
--------------------------------------------------------------------------------}}
CON
_clkmode = xtal1 + pll16x 'set clock
_xinfreq = 5_000_000 'crystal freq
VAR
long P_Val 'declare variable
OBJ
fds : "FullDuplexSerial" 'for display to PST
PUB Main
fds.start(31,30,0,115200) 'start console at 115200 for debug output
cognew(@generate, @P_Val) 'start new Cog at "generate" and read variable into P_Val in PASM
repeat 'loop
fds.bin(P_val,12) 'print value to the PST in binary
fds.tx($d) 'new line
fds.dec(P_val) 'print value as decimal
fds.tx(" ") 'space
fds.tx($1) 'home to 0,0
waitcnt(clkfreq/60+cnt) 'flicker free wait
DAT org 0 'sets the starting point in Cog
generate mov dira, set_dira 'sets direction of the prop pins
call #chip_sel_lo 'selects chip by pulling line low
call #Clk_lo 'START. Clock needs to be low to load data
call #Din_hi 'must start with Din high to set up 3208
call #Tog_clk 'clk hi-lo to read data
call #Din_Hi 'SINGLE DIFF mode, will be made Low to load
call #Tog_Clk 'toggle clock line hi low to read data
call #Din_Lo 'D2 Low to load input line sel sequence 000 for line 0
call #Tog_Clk 'toggle clock line hi then low to read in the data
call #Din_Lo 'D1 Low to load input line sel sequence 000 for line 0
call #Tog_Clk 'toggle clock line hi then low to read in the data
call #Din_Lo 'D0 Low to load input line sel sequence 000 for line 0
call #Tog_Clk 'toggle clock line hi low to read in the data
call #Din_Lo 'blank bit needs a clock cycle, next
call #Tog_Clk 'toggle clock line hi then low to read the data
'next toggle is for the null bit, nothing read
call #Tog_Clk 'toggle clock line hi then low to read the data
mov dat_red, #0 'Clear register we will read data into
mov count, #12 'Counter for number of bits we will read
read_bit mov temp, ina 'read in what is in all the input lines
andn temp, mask26 wz 'mask off except Dout line & Set Z flag
shl Dat_red, #1 'shift register left 1 bit ready for next bit
if_nz add Dat_red, #1 'if value is positive add 1 to data register
call #Tog_Clk 'toggle clock to get next bit ready in Dout
sub count, #1 wz 'decrement "bits read" counter. Set Z flag
if_nz jmp #read_bit 'go up and do it again if counter not yet 0
mov mem, par 'get address of par into mem
wrlong dat_red, mem 'write it in HUB to share it as P.Val
call #Chip_Sel_Hi 'Put chip to sleep by de-selecting it
jmp #generate 'go back to do it all again
'Subroutines
Clk_Hi or outa, clk_bit 'OR it with the Clock Bit to make high
Clk_Hi_ret ret 'return from this subroutine
Clk_Lo andn outa , clk_bit 'ANDN it with the Clock Bi to make low
Clk_Lo_ret ret 'return from this subroutine
Tog_Clk call #Clk_hi 'make clock bit high
call #clk_lo 'make clock bit low
Tog_Clk_ret ret 'return from this subroutine
Din_Hi or outa , din_Bit 'Makes the Din high
Din_Hi_ret ret 'return from this subroutine
Din_Lo andn outa , din_Bit 'makes Din low
Din_Lo_ret ret 'return from this subroutine
Chip_Sel_Hi or outa , chs_Bit 'Makes Chip select high
Chip_Sel_Hi_ret ret 'return from this subroutine
Chip_Sel_Lo andn outa, chs_Bit 'makes chip select low
Chip_Sel_Lo_ret ret 'return from this subroutine
Read_Next_Bit mov temp, ina 'Get the INA register
or temp, mask26 'mask all but Din bit
Read_Next_Bit_ret ret 'return from this subroutine
'======================
'Constants. This is similar to the CON block in SPIN but these are not constants
'because they can be changed. These are initial values.
Set_dira long %00001011_11000000_00001111_11111111 'Set dira register
Chs_Bit long %00000001_00000000_00000000_00000000 'Chip select bit 24
Din_Bit long %00000010_00000000_00000000_00000000 'Data in bit 25
Dout_Bit long %00000100_00000000_00000000_00000000 'Data out bit 26
Clk_Bit long %00001000_00000000_00000000_00000000 'Clock bit 27
mask26 long %11111011_11111111_11111111_11111111 'Mask forDout bit only
Pin_23 long %00000000_10000000_00000000_00000000 'osc line
Pin_22 long %00000000_01000000_00000000_00000000 'Speaker line
'============================
'Variables. This section is similar to the VAR block in SPIN.
'These are blank variable space designators
temp res 1 'temporary storage variable, misc
count res 1 'read bit counter
Dat_Red res 1 'data being read
mem res 1 'par location
Fit
A big thanks to Parallax & Jazzed for the Simple IDE. It has been very helpful for
working on the PASM code!
I always had trouble with value2, value1 being mixed in with source and destination. Value 1 = destination, value 2 = source.
ANDN requires you derive the truth table from the core two that describe the operation of the instruction:
For each bit, NOT does:
0 = 1
1 = 0
This is just a simple invert the bits function.
For each bit, AND does:
1 and 1 = 1
0 and 1 = 0
1 and 0 = 0
0 and 0 = 0
This is a simple, set the bit only when both argument bits are one function.
For each bit, combining the two looks like this:
Value 1 AND (NOT value 2)
1 AND (NOT 1) = 1 AND 0 = 0
1 AND (NOT 0) = 1 AND 1 = 1
0 AND (NOT 1) = 0 AND 0 = 0
0 AND (NOT 0) = 0 AND 1 = 0
The operators work on all the bits. When we do something like AND destination, source, all of the bits in source get operated on in tandem with the bits in destination with the result written to destination.
ANDN 0111_1000, 1011_0100 =
First let's NOT the source, applying the truth table above to each bit: (invert them)
0100_1011
Then we do the AND:
0100_1000
0111_1000
0100_1000
One easy way to remember what OR, AND, NOT, XOR do is to think of them like this:
OR is useful when you want to make sure a bit is 1 no matter what. It's truth table is:
0 OR 0 = 0
1 OR 0 = 1
0 OR 1 = 1
1 OR 1 = 1
The 1's in your mask are active and will do something to the other value. The 0's are inactive and do nothing.
AND is useful when you want to make sure a bit is 0 no matter what. It's truth table is:
0 AND 0 = 0
1 AND 0 = 0
0 AND 1 = 0
1 AND 1 = 1
In this case, the 0's are active and will do something to the other value. The 1's are inactive and do nothing.
NOT is useful when you want to invert a bit. It's truth table is:
NOT 0 = 1
NOT 1 = 0
And XOR is useful when you want to toggle a bit. It's truth table is:
0 XOR 0 = 0
1 XOR 0 = 1
0 XOR 1 = 1
1 XOR 1 = 0
In your mask, the 1's will toggle bits in the other value, the 0's won't.
And now let's talk about masks a little bit.
When you encounter multiple operations, you solve in the order they happen, which can take a bit of thinking when the instruction wording and argument placement isn't intuitive as ANDN sort of is.
Now, the power of these things comes with the use of masks. A mask is a pattern that can control which bits are impacted in a long. For this post, I'm going to use words, just because it's shorter, but masks work the same way no matter what your data size is.
Say we have this word:
1100_0011_0001_1010
and we want to make sure bits 3, 4, 6, 7, and 13 are set to 1.
1100_0011_0001_1010 (Original)
0011_1100_1110_0101 (After NOT)
0010_0000_1101_1000 (now AND with the NOT result above, not the original)
0010_0000_1100_0000
Looks to me like it places a 1 in the destination ONLY when there are 1's unique to the destination value. It's truth table is then a combination of the above:
I'm not surprised that you find that code confusing; Harprit is using an inverse mask to check an I/O pin... why???
Okay, suppose the input register is: 11001100_11110000_00001111_00110011
That register is ANDN'd with......... : 11111011_11111111_11111111_11111111 <- any bit with a 1 in it is cleared to zero, and bits with 0 are unchanged
The result of that instruction is...... : 00000100_00000000_00000000_00000000
There is still one bit set so the Z flag is clear.
A one is added to Dat_red by first shifting Dat_red left one, and adding one to the low-bit if the Z flag is clear
A much simpler method is to take the input register: 11001100_11110000_00001111_00110011
Use an AND instruction to isolate the bit............... : 00000100_00000000_00000000_00000000 <- any bit with a 0 is cleared to zero, bits with 1 are unchanged
Which also gives the result.................................. : 00000100_00000000_00000000_00000000
And instead of using the Z flag, use the C flag which is set if the result has an odd number of bits set.
Using the C flag makes updating the Dat_red register easier since you can then use a RCL instruction.
read_bit mov temp, ina
and temp, mask26 wc 'where mask26 = |<26
rcl Dat_red, #1
But even that is needlessly complicated unless there's some reason to have a copy of ina.
Consider that the TEST instruction acts just like a AND instruction, only affecting flags and not a result
read_bit test mask26, ina wc
rcl Dat_red, #1
Here's my simplified version of the entire read_bit routine:
read_bit
mov loop_counter, #12 ' Receive 12 bits from the MCP3208
mov Dat_red, #0 ' Clear the Dat_red register
:loop
test mask26, ina wc ' Set the C flag if input 26 is high, where mask26 is |<26
rcl Dat_red, #1 ' Rotate C into the low-bit of Dat_red
or outa, clk_bit ' Output a high on the clock
andn outa, clk_bit ' Output a low on the clock ... why were these in nested subroutines???
djnz loop_counter, #:loop ' Repeat 12 times
wrlong dat_red, par ' Store the result in par
or outa, chs_Bit ' Make Chip select high ... it's silly to create subroutines for a single instruction
jmp #generate
I could be off on this one, but you may want to add a couple of cycles to the loop to account for the clocks between the end of channel select and the start of data to account for an indeterminant bit and the null bit prior to the actual 12 bit value. On the MC3201, this is 3 cycles for a 15 clock count, and looks like 14 clocks for the MC3208 but I have not used the multi-channel chips and have not fired up the lab in months......... Oh, also, mask the results for however many bits you want to use of the whole value. (Idea grabbed from one of jonnymac's objects)
Please, please, please. This book is for beginners, beginners, beginners. Absolute beginners.
So.... Comments as to not using sophisticated or rigidly required techniques may not really be applicable in this frame.
Example I use the ANDN instruction extensively to read a bit because it eliminates the need to learn a new command in the middle of what is already pretty confusing code.
The learning process has to be as "simple and stupid as possible" if it is going to work for a complicated system. I tried to keep it simple. Too simple for some.
The general complaint is something like "I learned a bit from this book but not enough!" Well...... it is now your job to take it to the next level.
On my not going into the intricacies of the 3208... That is not for beginners. The thing is complicated enough as it is.
I use two and three line subroutines so that the main code flows more easily. This is one of those necessary simplifications.
The constant statements that published code is impossible to read should not be taken lightly. It is a real problem. As a part of this I looked at Chip's OBEX for the 3208 for comparison and edification.
It is very elegant, very compact and VERY impressive. I was very much taken by the power of the language as used by an expert.
It is not heavily commented. I DID NOT FULLY COMPREHEND ONE SINGLE LINE.
Bill M.
The data moves from the 3208 to the register we are reading into, a bit at a time
For each bit we test the z flag to see if it is 0 or 1.
In either case we move the register we are reading into one bit at a time as we read the data in
If the z flag was 0, that's it. We are done.
If it was not 0 we add 1 to the register we are reading into.
The data is never actually read directly into anything. The z flag determines if we are going to add a 0 or a 1
The z flag is set as set or cleared after the instruction in which it was specified is executed.
It can be tested after that if nothing else disturbs it. It does not have to be done immediately.
Your other commentary is pretty much self explanatory as are the comments by others.
Thanks for your kind comments
I admire the effort you are putting into learning PASM. I wish you every success.
And you may still want to talk to me!
The book might be for beginners, beginners, beginners, and absolute beginners, but this thread is about Propeller Assembly for beginners.
There are a total of 78 PASM instructions, many of these are variants of other instructions, and many others are strongly similar.
If you can understand ANDN, you can understand AND, TEST, and TESTN.
If you understand SHL, you should be able to understand SHR, ROL, ROR, RCL, and RCR.
If you understand SUB #1 wz / if_z JMP, you absolutely should be able to understand DJNZ.
There is nothing sophisticated about any of those.
Out of those 78 instructions, there are just over a dozen dissimilar ones that I use regularly. I don't think that's beyond the ability of a beginner to learn. Those instructions are certainly easier to understand than the inner workings of a chip like the MCP3208.
You mentioned Chip Gracey's MCP3208 object, and I agree that it is a very elegant object and not something I'd expect a complete beginner to to be able to write. It should not be too difficult to understand however. I used it as the basis for my own driver:
{{
This sample routine is based on code from Chip Gracey's MCP3208 12-bit/8-channel ADC Driver v1.0
The data-out and data-in pins are tied together and are operated on by D_mask
A single register, t1, is used for sending the configuration bits and also for receiving the data bits. Data is sent from the upper bits and read into the lower bits
D_mask is initially set to an output in order to transmit the configuration bits, and then changed to an input to receive the data bits
__
CS 
CLK 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9
Din 
         
│ │ A2 A1 A0 │ │ A2 A1 A0
│ SGL/Diff │ SGL/Diff
Start Start
Dout ───────────────────────────────────────────────────────
D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
}}
Sample
mov bit_counter,#20 ' Entire sample routine clocks twenty bits
mov t1,#%1_1000 ' t1 contains Start, SGL/Diff, A2, A1, and A0 bits
or t1,Channel ' Channel contains a value 0 to 7 (%000 to %111)
shl t1,#32-6 ' move start, SGL/Diff, A2, A1, and A0 to upper bits of t1
' plus 1 bit to clock while CS is high before sending the start bit
mov cnt,delay_time ' The MCP3208 datasheet specifies a 250ns minimum time for clock pulses
add cnt,cnt
andn outa,CLK_mask
:loop
cmp bit_counter,#14 wc,wz ' Determine if header has been sent
if_ae or dira,D_mask ' Make D_mask an output if it hasn't
if_b andn dira,D_mask ' Make D_mask an input if it has
shl t1,#1 wc,nr ' Move the msb of t1 into C, do not update t1
muxc outa,D_mask ' Output the bit (only works while D_mask is an output)
waitcnt cnt,Delay_time
or outa,CLK_mask ' Output a high on the clock
test D_mask,ina wc ' Read a bit from D_mask into C
rcl t1,#1 ' Rotate C into the lsb of t1
waitcnt cnt,delay_time
andn outa,CLK_mask ' Output a low on the clock
andn outa,CS_mask ' Output a low on chip_select - Only needs to be high for the first clock
djnz bit_counter,#:loop ' Repeat twenty times
and t1,_4095 ' Mask the 12 bits of the result
or outa,CS_mask ' Output a high on chip_select
Sample_ret ret
Okay, I guess that was a bit complicated with 15 different instructions, but can you at least see how it works with the comments and the signal diagram?
ANDN inverts the Source mask before it ANDs the destination, if you want to clear a specific bit (you don't care if current state of it's a 0 or 1)
If your AND mask is all 1s except the bit you want to go zero then all the 1 ones in destination will stay 1 as 1&1 =1 and a 0 &1 =0 so zeros will stay 0
The bit location that is a 0 in the mask (after inversion) will result in a forced 0 as 1&0=0 and 0&0=0
Form a msp430 perspective calling it BitClear makes it easier to understand: BIC.W not.src .and. dst → dst
Could you live without a ANDN, sure you could invert the mask by hand or use NEG first to invert the mask.
As you only have 496 lines of code, every trick to get something done in one line is good that is why there is cmpsub, muxz, and sumz etc
example i use the andn instruction extensively to read a bit because it eliminates the need to learn a new command in the middle of what is already pretty confusing code. the learning process has to be as "simple and stupid as possible" if it is going to work for a complicated system. I tried to keep it simple. Too simple for some.
... and this is the kind of trap that a technical editor will catch. 95% of the art of writing a GREAT technical book is in charting the order in which you teach to minimize dependencies and make sure you are not forced to teach too much at one time.
If you're having to contort the language in an example to use previously taught opcodes in a way that a "native speaker" wouldn't, you probably need to review that section.
If you teach it that way, people will use it even after you've taught then the "native speaker" method later.
The book might be for beginners, beginners, beginners, and absolute beginners, but this thread is about Propeller Assembly for beginners.
There are a total of 78 PASM instructions, many of these are variants of other instructions, and many others are strongly similar.
If you can understand ANDN, you can understand AND, TEST, and TESTN.
If you understand SHL, you should be able to understand SHR, ROL, ROR, RCL, and RCR.
If you understand SUB #1 wz / if_z JMP, you absolutely should be able to understand DJNZ.
There is nothing sophisticated about any of those.
Out of those 78 instructions, there are just over a dozen dissimilar ones that I use regularly. I don't think that's beyond the ability of a beginner to learn. Those instructions are certainly easier to understand than the inner workings of a chip like the MCP3208.
You mentioned Chip Gracey's MCP3208 object, and I agree that it is a very elegant object and not something I'd expect a complete beginner to to be able to write. It should not be too difficult to understand however. I used it as the basis for my own driver:
{{
This sample routine is based on code from Chip Gracey's MCP3208 12-bit/8-channel ADC Driver v1.0
The data-out and data-in pins are tied together and are operated on by D_mask
A single register, t1, is used for sending the configuration bits and also for receiving the data bits. Data is sent from the upper bits and read into the lower bits
D_mask is initially set to an output in order to transmit the configuration bits, and then changed to an input to receive the data bits
__
CS 
CLK 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9
Din 
         
│ │ A2 A1 A0 │ │ A2 A1 A0
│ SGL/Diff │ SGL/Diff
Start Start
Dout ───────────────────────────────────────────────────────
D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
}}
Sample
mov bit_counter,#20 ' Entire sample routine clocks twenty bits
mov t1,#%1_1000 ' t1 contains Start, SGL/Diff, A2, A1, and A0 bits
or t1,Channel ' Channel contains a value 0 to 7 (%000 to %111)
shl t1,#32-6 ' move start, SGL/Diff, A2, A1, and A0 to upper bits of t1
' plus 1 bit to clock while CS is high before sending the start bit
mov cnt,delay_time ' The MCP3208 datasheet specifies a 250ns minimum time for clock pulses
add cnt,cnt
andn outa,CLK_mask
:loop
cmp bit_counter,#14 wc,wz ' Determine if header has been sent
if_ae or dira,D_mask ' Make D_mask an output if it hasn't
if_b andn dira,D_mask ' Make D_mask an input if it has
shl t1,#1 wc,nr ' Move the msb of t1 into C, do not update t1
muxc outa,D_mask ' Output the bit (only works while D_mask is an output)
waitcnt cnt,Delay_time
or outa,CLK_mask ' Output a high on the clock
test D_mask,ina wc ' Read a bit from D_mask into C
rcl t1,#1 ' Rotate C into the lsb of t1
waitcnt cnt,delay_time
andn outa,CLK_mask ' Output a low on the clock
andn outa,CS_mask ' Output a low on chip_select - Only needs to be high for the first clock
djnz bit_counter,#:loop ' Repeat twenty times
and t1,_4095 ' Mask the 12 bits of the result
or outa,CS_mask ' Output a high on chip_select
Sample_ret ret
Okay, I guess that was a bit complicated with 15 different instructions, but can you at least see how it works with the comments and the signal diagram?
Nice chunk of code, doubt I would have come up with your way of setting up the chip in the same sequence as actually reading out the value. Neat!
Thanks Potatohead, ChrisGadd, and Tonyp12 for your input on my "andn" question. You're help transformed
andn into a simple instruction.
I finally understood that piece of code tonight, I have been reviewing your advice for the last couple days. I was
really hung up on why there wasn't a mov instruction to link "temp with dat_red."
I really needed to understand the program before I actually tried it. Thanks Harprit and ChrisGadd. Chris, I am
beginning to understand your last post, I will keep working on it.
I have one other question about programming for the mcp3208. The data sheet stated: "If the mcp3208 was
powered up with the CS pin low, it must be brought high and back low to initiate communication."
If all Propeller i/o pins are set as inputs during start up, is it possible the CS pin was low?
I looked at Chip's and Johnny Mac's code and I didn't see any code that toggled CS one time only to
initiate communication.
I stopped following this thread a long time ago, but have been waiting for this book to come out for a long time. Reading the last two pages of this thread it looks like the book is available?? I typed the title in to google but couldn't find anything related to this book except the thread... If propeller assembly for beginners is out how much is it, and where can you buy it?
I stopped following this thread a long time ago, but have been waiting for this book to come out for a long time. Reading the last two pages of this thread it looks like the book is available?? I typed the title in to google but couldn't find anything related to this book except the thread... If propeller assembly for beginners is out how much is it, and where can you buy it?
It's been out since March.
Post #740 tells you how to get it. (Direct from the author)
I have my credit card out, where do I pre-order your PASM book?? I have your Beginners book and love it and refer to it often in my attempt to learn and use the Prop...
I have my credit card out, where do I pre-order your PASM book?? I have your Beginners book and love it and refer to it often in my attempt to learn and use the Prop...
Mike
I'm too little for credit cards
Send me $35.00 via paypal will mail it as soon as I can get out of my drive. We are in for 10 inches of snow
I'll send you the code file right away after receiving your order
H
Comments
I brought this book a few months ago as I wanted to lean a bit more about PASM. My immediate need was to increase the measurement speed of an MCP320x ADC beyond the ability of SPIN. This book used this device extensively in its examples. The idea of using the MCP320x device as a leaning tool is a good one since it requires I/O, timing and general passing back and forth of values to the main hub memory. Unfortunately the book does not directly address the details in MCP320x datasheet regarding I/O (minimum and maximum clock speed, minimum sampling capacitor charge time, etc.). There were some missed opportunities to really help the reader understand the intricacies of this device and how PASM can handle them quite nicely. It seems like the author had the right idea of starting out with SPIN to introduce how the MCP320x works. In fact I would have written the first example program with no loops (yup, every painful clock tick and data line I/O on its own line). Then show how you can condense the SPIN code down - perhaps taking two or three iterations to get to something nice and tight. Then transition this same approach with PASM showing how similar the languages are and where PASM differs and how much faster it can run. Condensing PASM to its minimal size seems quite tricky to me as a beginner as it requires much more attention to detail. If the book had taken this approach it might have been more effective in teaching me PASM.
While I got a few tips from reviewing the code examples, the book itself lacked flow and continuity. I could see glimpses of points trying to be made but it seems too disjointed to be readable to any reasonable extent. It reads like a draft concept of an "Introduction to PASM" rather than an initial publication. A bit verbose in several sections, the illustrations lack clarity as the very thin lines are hard to see, the overall text formatting is poor and the index is awful. This book would have greatly benefited from some editing by a third party (the editing process has value!).
I have gleaned far more PASM learning from potatohead's and desilva's PASM pdfs than from this book.
The SPIN manual is a good reference guide for PASM too but it lacks practical examples for each command and virtually no examples of common command snippets. As a beginner I had to spend lots of time looking for examples of how to do basic SPIN coding somewhat efficiently. Seems like well documented PASM examples for the beginner are quite rare. Parallax has a scant set of 19 application notes (and it seems like you have to go to the Parallax Semiconductor site to get them now). I have often wondered why Parallax has not written an "Introduction to SPIN" and an "Introduction to PASM". Especially since they seem to want to promote the Propeller chip to the beginner student.
I don't think I'm alone in still waiting for a good "Introduction to PASM" tome.
Please tell me about this. I understand something about people who have not had assembly experience, but I really don't understand experienced assembly language programmers having trouble with PASM. What sort of questions are you asking and how do those link to concepts you may or may not associate with PASM?
If you could enlighten me, and it's not a problem to put it here, I would very much appreciate that discussion. That applies to anyone BTW. Thanks.
Any one who cared to do so could have done so but no one is even threatening to do so even as I type..
People who know a lot more about PASM than I do could have done it. They did not.
Parallax has not done so... so far.
No one has.
The book did you some good if one, you now know a bit more about PASM than you before started and two if you can now write simple code in PASM
The answers to both questions are yes (from those buyers who cared to answer the questions for me).
So many technical books are so full of data sheets copied from the internet files. I chose not to do that.
I also did not repeat what is already in the Propeller Manual.
There are about 90 pages of code in the book and each and every line is commented.
Most of the code on the internet is Greek to beginners. It was to me.
Comments about flow and style may indeed be relevant but do not address the learning experience directly.
I asked at least 100 questions on the forum as I wrote the book.
The answers were sincere but not overly enlightening to my beginner's mind set.
I had to figure most of it out the hard way. Hopefully my efforts will save beginners some headaches.
PLEASE WRITE A BETTER BOOK.
Light a candle, don't just curse the darkness.
Harprit
I hope you didn't take my comments negatively. As I said before, overall it is a helpful book. So far (Not yet finished) I have picked up many things I didn't know. I was just saying it needs a bit of review to make it flow better and remove some errors, but this was not a put down of the book but more a suggestion for the next revision. Also as you just noted, as well did I, that this book fills a void as it was the only one I found that covered PASM.
Thanks for your work on this book.
Yes. Needs to happen. Maybe someday. You did work hard and you did write a book. I've refrained from any commenting on it, because you made your contribution to fill a vacuum, and you did it with your best intent too. And it's going to benefit some people.
If you're an experienced Assembly Programmer, surely you could follow de Silva despite its quirkiness.
I just read the comments before I was planing on purchasing the book, but your comments sound as though you could
be talking about Harprit's book on SPIN.
Unfortunately Potatohead's and Desilva's PASM pdfs didn't help me, and that is why I was interested in Harprit's
book on PASM.
I have the Parallax book by Gunther Daubach for Programming the SX, Several books on programming the PIC, assembly
programming the 486, by Irvine and other mpu's. They have helped me develop some basic ideas, but all I own is Parallax
products, and I really have no interest in any other manufactures products.
I realize writing a book on such a specialized subject like this is not a money maker for the author, and Parallax can't
pay someone for all the time it takes to write a proper book. Why can't Parallax (with some help) write a downloadable
PDF similar to the Basic Stamp books, that were free to download, and with that old style Parallax experience?
Keep it simple, and use the IC's Parallax sells as examples people can incorporate into their own projects, instead of
projects we will never build.
I also have many of Jon Williams Nuts and Volts articles, but to many of them deal with projects I have no interest in,
and for me, that is similar to reading a book about programming a PIC in assembly without the interest or intention to
ever do so.
Sorry, but it was kinda difficult to read it any other way. Is there any positive features you can point out?
Thanks
Bill M.
ps; maybe create a wiki page that anyone can contribute too.
In the post I was referring to, I pointed out improvements and what I liked:
The book has a LOT of well documented easy to follow code, many of the examples and OBEX stuff I have found have complex parts that have a general statement of what they intend to do rather than what every line is doing like in the book. The content of the book is good, and was informative.
I wish a lot more of the buyers would post here instead of telling me about it.
You can learn a lot from the book if you are a beginner. 80 pages of pure PASM code. Every line documented and easy to follow. I send you the file so you don't have to retype a thing.
Unfortunately the fingers of naysayers are faster to the keys than those that were helped.
I am pretty sure no one else will write a book. I have two books on PICs that with their two e-versions have been in the top 50 PIC books every week for well over three years. Often number 1 is a book by me. That is 4 out of the top 50!!!! I think its a record.
My royalty check from McGraw last quarter $21.00.
Here is a review of my books written as the reviewer reviewed another book NOT written by me.
Two of the best books on PIC controllers are written by Mr. Harprit Singh Sandhu. They both contain a lot of circuit examples , and programming examples to work with the circuits. The books are based on the Melabs Lab-X1 demo board, but you do not need the board to get a feel for the controllers, or the programming. Mr. Sandhu steps through his programs with great detail, and makes them very easy to follow with excellent programming commenting.
The programming used in his books is based on MeLabs Pic Basic Pro. Pic Basic Pro comes in various versions, so depending on your needs, the cost can vary between free, $49 fr a student, $120 for Silver, and $250 for a Gold license. I bought the silver license, and have been very happy with it.
I have two of Mr. Sandhu's books, and a coupe of others that explain PIC functions, and circuit examples with Basic org ramming examples. The some of the best advice Mr. Sandhu will give you is about the data sheets, and various PIC's. That is to pick a PIC to work with, and study it so you will know it well. The programming will be much easier once you understand the functions of the PIC you choose to work with However, both of his books are based on the Lab-X1, and the 16F877a PIC. This PIC is a 40 pin work horse of a PIC, but once you can work with this one PIC, you will be able to easily work with most others. The programming from one PIC can be transferred to many others with very little rework, or effort.
I hope you, as a reader, feel I have helped you get on the fast track to learning about PIC programming. It is a lot of fun, easy, and well worth the time you will put into it.
My spin and PASM books are in the same vein. As regards the gripe about my repeating stuff (which is minimal). This is a reference text you will use hundreds of times. You should not have to spend time finding lines of specific code in the middle of hard to understand machine language. Repeating it where needed in the discussion avoids this.
And the book is not full of data sheets copied from the internet or information that is already in the Propeller manual. Not one line.
H
Thanks
Bill M.
Thanks for your kind comment.
I read your unedited post very late last night and note that you have deleted some or your questions by this afternoon.
I do not remember your exact wording now but here goes. Maybe this will help.
I found that I could use 100K pots on the 3208 without problems. The usual recommendation is 5K pots. Since the pots are all placed across the power supply, they eat up the amps pretty fast and soon the prop starts to reset and readings become unreliable for low and high values of the pot reading (at 12 bits). Specially important if you want to or need to place 8 units across the power supply.
The slow down on the 3208 at lower voltages can be compensated for by slowing down the Propeller if that is necessary. My experience was that the chip was fast enough to keep up with the Prop. In these cases it is best to run a test to satisfy yourself for the conditions that you have on your board are not creating a problem.
I dwell on the 3208 in the book so that I can stick with one chip that has almost universal appeal if you are interested in real time inputs and in reading all sorts of sensors. If you learn to use the 3208, the rest will be easier.
Call me if you want to discuss further 217 269 8737 any time.
H
Ah! the good old days.
(1) I am having problems understanding some of the pasm code from "064 PASM_Book_ReadPot.spin."
Primarily the Global Label "read_bit." My problem is recognizing how the data is transferred from the
data out pin #27 to the PAR register.
Today I realized the Z-flag might be treated as a global variable that can be changed by any instruction
line after it has been set?
For several days now, I could not see the relationship between "temp" and "dat_red." Note: If you look
at my version of the code, I tried to use the Basic Stamp and SXB code conventions, and changed some
of the names to be more meaningful to me. Such as: "longTmp" instead of "temp," and "readData"
instead of "dat_red."
I was unable to use the Propeller Manual to solve this problem by myself. I have used the MCP3208
data sheet to get a more in depth understanding of the adc chip.
This is my version of the code:
(2) I am having problems finding a truth table for the "andn" instruction. The Propeller
manual describes it as: "ANDN (bitwise AND NOT) performs a bitwise AND of the inverted
value (bitwise NOT) of Value2 into that of Value1"
I have looked at Microsoft, Wikipedia and other programming websites and they don't
seem to use the same terminology for some bitwise operators.
Can someone please help me understand ANDN? and does the ANDN and the OR
effect the entire 32 bit long?
Harprit recommends to use the Propeller Manual and the MCP3208 data sheet
as additional references in addition to the book. Despite the fact the books unfinished
appearance, the book has worked well for me because it isn't perfect. It kinda forced
me to study, and that works for my personality. It is difficult for me to accept something
as real, genuine, or a fact, without my own investigation into what is presented to me.
Despite the well documented code, I ended adding my own comments, some directly
from the mcp3208 data sheet and propeller manual. I also documented the step by step
process of the mcp3208.
The largest difference to me, is the code is relatively easy to read, and therefore easy
for me to follow and develop a deeper understanding of the basics. On the other hand,
trying to read polished code in some other books has made it difficult for me to continue
reading those books.
For example: this is my take on Harprit's code:
And this is Harprit's original code:
A big thanks to Parallax & Jazzed for the Simple IDE. It has been very helpful for
working on the PASM code!
Bill M.
ANDN requires you derive the truth table from the core two that describe the operation of the instruction:
For each bit, NOT does:
0 = 1
1 = 0
This is just a simple invert the bits function.
For each bit, AND does:
1 and 1 = 1
0 and 1 = 0
1 and 0 = 0
0 and 0 = 0
This is a simple, set the bit only when both argument bits are one function.
For each bit, combining the two looks like this:
The operators work on all the bits. When we do something like AND destination, source, all of the bits in source get operated on in tandem with the bits in destination with the result written to destination.
ANDN 0111_1000, 1011_0100 =
First let's NOT the source, applying the truth table above to each bit: (invert them)
0100_1011
Then we do the AND:
0100_1000
0111_1000
0100_1000
One easy way to remember what OR, AND, NOT, XOR do is to think of them like this:
OR is useful when you want to make sure a bit is 1 no matter what. It's truth table is:
0 OR 0 = 0
1 OR 0 = 1
0 OR 1 = 1
1 OR 1 = 1
The 1's in your mask are active and will do something to the other value. The 0's are inactive and do nothing.
AND is useful when you want to make sure a bit is 0 no matter what. It's truth table is:
0 AND 0 = 0
1 AND 0 = 0
0 AND 1 = 0
1 AND 1 = 1
In this case, the 0's are active and will do something to the other value. The 1's are inactive and do nothing.
NOT is useful when you want to invert a bit. It's truth table is:
NOT 0 = 1
NOT 1 = 0
And XOR is useful when you want to toggle a bit. It's truth table is:
0 XOR 0 = 0
1 XOR 0 = 1
0 XOR 1 = 1
1 XOR 1 = 0
In your mask, the 1's will toggle bits in the other value, the 0's won't.
And now let's talk about masks a little bit.
When you encounter multiple operations, you solve in the order they happen, which can take a bit of thinking when the instruction wording and argument placement isn't intuitive as ANDN sort of is.
Now, the power of these things comes with the use of masks. A mask is a pattern that can control which bits are impacted in a long. For this post, I'm going to use words, just because it's shorter, but masks work the same way no matter what your data size is.
Say we have this word:
1100_0011_0001_1010
and we want to make sure bits 3, 4, 6, 7, and 13 are set to 1.
The mask looks like this:
0010_0000_1101_1000
Apply the OR function thus:
1100_0011_0001_1010
0010_0000_1101_1000
1110_0011_1101_1010
Here is that same mask applied using ANDN:
1100_0011_0001_1010 (Original)
0011_1100_1110_0101 (After NOT)
0010_0000_1101_1000 (now AND with the NOT result above, not the original)
0010_0000_1100_0000
Looks to me like it places a 1 in the destination ONLY when there are 1's unique to the destination value. It's truth table is then a combination of the above:
1 ANDN 1 = 0
0 ANDN 1 = 0
1 ANDN 0 = 1
0 ANDN 0 = 0
Hope this helps!
I will get back to you in a day or two with some answers and/or comments
H
Okay, suppose the input register is: 11001100_11110000_00001111_00110011
That register is ANDN'd with......... : 11111011_11111111_11111111_11111111 <- any bit with a 1 in it is cleared to zero, and bits with 0 are unchanged
The result of that instruction is...... : 00000100_00000000_00000000_00000000
There is still one bit set so the Z flag is clear.
A one is added to Dat_red by first shifting Dat_red left one, and adding one to the low-bit if the Z flag is clear
A much simpler method is to take the input register: 11001100_11110000_00001111_00110011
Use an AND instruction to isolate the bit............... : 00000100_00000000_00000000_00000000 <- any bit with a 0 is cleared to zero, bits with 1 are unchanged
Which also gives the result.................................. : 00000100_00000000_00000000_00000000
And instead of using the Z flag, use the C flag which is set if the result has an odd number of bits set.
Using the C flag makes updating the Dat_red register easier since you can then use a RCL instruction.
This or this But even that is needlessly complicated unless there's some reason to have a copy of ina.
Consider that the TEST instruction acts just like a AND instruction, only affecting flags and not a result
Here's my simplified version of the entire read_bit routine:
So.... Comments as to not using sophisticated or rigidly required techniques may not really be applicable in this frame.
Example I use the ANDN instruction extensively to read a bit because it eliminates the need to learn a new command in the middle of what is already pretty confusing code.
The learning process has to be as "simple and stupid as possible" if it is going to work for a complicated system. I tried to keep it simple. Too simple for some.
The general complaint is something like "I learned a bit from this book but not enough!" Well...... it is now your job to take it to the next level.
On my not going into the intricacies of the 3208... That is not for beginners. The thing is complicated enough as it is.
I use two and three line subroutines so that the main code flows more easily. This is one of those necessary simplifications.
The constant statements that published code is impossible to read should not be taken lightly. It is a real problem. As a part of this I looked at Chip's OBEX for the 3208 for comparison and edification.
It is very elegant, very compact and VERY impressive. I was very much taken by the power of the language as used by an expert.
It is not heavily commented. I DID NOT FULLY COMPREHEND ONE SINGLE LINE.
Bill M.
The data moves from the 3208 to the register we are reading into, a bit at a time
For each bit we test the z flag to see if it is 0 or 1.
In either case we move the register we are reading into one bit at a time as we read the data in
If the z flag was 0, that's it. We are done.
If it was not 0 we add 1 to the register we are reading into.
The data is never actually read directly into anything. The z flag determines if we are going to add a 0 or a 1
The z flag is set as set or cleared after the instruction in which it was specified is executed.
It can be tested after that if nothing else disturbs it. It does not have to be done immediately.
Your other commentary is pretty much self explanatory as are the comments by others.
Thanks for your kind comments
I admire the effort you are putting into learning PASM. I wish you every success.
And you may still want to talk to me!
H
There are a total of 78 PASM instructions, many of these are variants of other instructions, and many others are strongly similar.
If you can understand ANDN, you can understand AND, TEST, and TESTN.
If you understand SHL, you should be able to understand SHR, ROL, ROR, RCL, and RCR.
If you understand SUB #1 wz / if_z JMP, you absolutely should be able to understand DJNZ.
There is nothing sophisticated about any of those.
Out of those 78 instructions, there are just over a dozen dissimilar ones that I use regularly. I don't think that's beyond the ability of a beginner to learn. Those instructions are certainly easier to understand than the inner workings of a chip like the MCP3208.
You mentioned Chip Gracey's MCP3208 object, and I agree that it is a very elegant object and not something I'd expect a complete beginner to to be able to write. It should not be too difficult to understand however. I used it as the basis for my own driver: Okay, I guess that was a bit complicated with 15 different instructions, but can you at least see how it works with the comments and the signal diagram?
If your AND mask is all 1s except the bit you want to go zero then all the 1 ones in destination will stay 1 as 1&1 =1 and a 0 &1 =0 so zeros will stay 0
The bit location that is a 0 in the mask (after inversion) will result in a forced 0 as 1&0=0 and 0&0=0
Form a msp430 perspective calling it BitClear makes it easier to understand: BIC.W not.src .and. dst → dst
Could you live without a ANDN, sure you could invert the mask by hand or use NEG first to invert the mask.
As you only have 496 lines of code, every trick to get something done in one line is good that is why there is cmpsub, muxz, and sumz etc
... and this is the kind of trap that a technical editor will catch. 95% of the art of writing a GREAT technical book is in charting the order in which you teach to minimize dependencies and make sure you are not forced to teach too much at one time.
If you're having to contort the language in an example to use previously taught opcodes in a way that a "native speaker" wouldn't, you probably need to review that section.
If you teach it that way, people will use it even after you've taught then the "native speaker" method later.
Nice chunk of code, doubt I would have come up with your way of setting up the chip in the same sequence as actually reading out the value. Neat!
FF
andn into a simple instruction.
I finally understood that piece of code tonight, I have been reviewing your advice for the last couple days. I was
really hung up on why there wasn't a mov instruction to link "temp with dat_red."
I really needed to understand the program before I actually tried it. Thanks Harprit and ChrisGadd. Chris, I am
beginning to understand your last post, I will keep working on it.
I have one other question about programming for the mcp3208. The data sheet stated: "If the mcp3208 was
powered up with the CS pin low, it must be brought high and back low to initiate communication."
If all Propeller i/o pins are set as inputs during start up, is it possible the CS pin was low?
I looked at Chip's and Johnny Mac's code and I didn't see any code that toggled CS one time only to
initiate communication.
Thanks
Bill M.
Edit: If you used Chip's MCP3208 object correctly it toggles the CS pin as it is supposed to.
This sets the CS pin low
This sets the CS pin high
Look for those instruction's in Chip's assembly program
It's been out since March.
Post #740 tells you how to get it. (Direct from the author)
I have my credit card out, where do I pre-order your PASM book?? I have your Beginners book and love it and refer to it often in my attempt to learn and use the Prop...
Waiting patiently for your new book...
Mike B. North Carolina
See Post #808 (above) or go right to Post #740
I'm too little for credit cards
Send me $35.00 via paypal will mail it as soon as I can get out of my drive. We are in for 10 inches of snow
I'll send you the code file right away after receiving your order
H