Looks like you're missing a generic I2C and SPI drivers.
It looks like "storage" might be a better name for your "io" package. I've only ever heard io refer to "input/output" but all of your other packages could be classified as io in that case (com, net, sensor).
Off the top of your heads, do you guys have any suggestions for any of these?
I think your object names need to specify particular products. For example, Parallax sells two color sensors, and they interface in drastically different ways. So sensor.color (or sensor.light.color) is too generic. And even the same product might interface in several different ways, requiring several different objects. The TSL1401 linescan module, for example, has an analog output, entailing either an A/D converter (but which one?) or a sigma-delta input circuit. Or ... the analog output can simply be thresholded by driving a logic input pin.
-Phil
Sensors are going to get messy very fast, so I am focusing on more general objects first. However, you can see from the current objects that I am trying to be as specific as possible with object names.
It looks like "storage" might be a better name for your "io" package. I've only ever heard io refer to "input/output" but all of your other packages could be classified as io in that case (com, net, sensor).
Haha, yes, good call. Let's call it "storage". There aren't actually any objects named "io" at this point.
The only good solution I have for testing SPI is with a logic analyzer.
No generic I2C in the OBEX??? That's awful... is that really true???
No no no no, I didn't mean there wasn't one in the OBEX. I meant not in the Spin library at present, and I don't know which I2C object is good. Any recommendations from anyone?
TV.spin should be used for TV. It works well with graphics.spin too.
With a little work, VGA.spin also works with graphics.spin.
These two core drivers, along with graphics.spin do a lot. We have pushed what can be done in all sorts of ways, and that's good. However, the basic capabilities and resolutions in this set of code is well matched to both the overall Propeller capabilities and many projects.
The drivers are hybrid tile and bitmap capable. Graphics.spin can deliver pixels, text, etc... it can also be used to draw in windows, which can be very useful on mixed displays, where tiles and colors may be used in creative ways to avoid the ram and buffer cost of a full bitmap.
One can also display the ROM text by using the larger 32 pixel tile size, and TV_Text is a dedicated driver that does this.
Brett, also take a look at the Simple IDE libraries to see how they are sorted out with subfolders for different sensors. Andy gave this a lot of thought and it has become very permanent in our code ecosystem, so you might want to mimic it to provide portability for people who know one code system and want to switch to another.
These two core drivers, along with graphics.spin do a lot. We have pushed what can be done in all sorts of ways, and that's good. However, the basic capabilities and resolutions in this set of code is well matched to both the overall Propeller capabilities and many projects.
The drivers are hybrid tile and bitmap capable. Graphics.spin can deliver pixels, text, etc... it can also be used to draw in windows, which can be very useful on mixed displays, where tiles and colors may be used in creative ways to avoid the ram and buffer cost of a full bitmap.
One can also display the ROM text by using the larger 32 pixel tile size, and TV_Text is a dedicated driver that does this.
More can be done than most are aware of, IMHO.
The TV demo was one of the first ones I ran when I set up my first Propeller. It was awesome! But I had a hard time figuring out how it worked so I stopped playing around with it. >.>
See my signature for more on that. Honestly, I could write a short book on Chip's really clever driver.... A lot of people have had trouble fully utilizing it.
So far as I have been able to tell, actually configuring and using the driver is not all that difficult. What is difficult is people unaware of graphics techniques and video basics.
There has definitely been an overreliance on video objects in the demo code.
Well, to be fair, not everyone uses serial. I frankly do not use it much at all and prefer a character driver most of the time. This depends a lot on how people set up and why they do so.
I'll run a capture card to get nice output in a window on my laptop, and I do it to get rapid, mixed text, graphics display of program data, vars, etc...
I've seen others use serial and a scope or blinking lights or sounds to do similar things.
Brett, also take a look at the Simple IDE libraries to see how they are sorted out with subfolders for different sensors. Andy gave this a lot of thought and it has become very permanent in our code ecosystem, so you might want to mimic it to provide portability for people who know one code system and want to switch to another.
Ken Gracey
I think something like that may have already emerged on accident.
One of the most frustrating things I found early on was the naming for character outputs.
IIRC...
FDX uses .tx(ch)
TV uses .out(ch)
In my PropOS I use a stdin and stdout driver via rendezvous locations in hub.
So standard programs use the stdin and stdout objects and I load drivers such as fdx (serial), tv & kbd, etc.
However, this might be a little advanced for beginners, but worth mentioning anyway.
Off the top of your heads, do you guys have any suggestions for any of these? Can you think of any I haven't listed here that should be covered by this library? -
As long as the VGA drivers are of the tile and palette type, like both VGA and TV.spin are, graphics.spin can be set to render into any area of VGA tiles arranged like they are in TV.spin.
There isn't enough RAM for full screen VGA displays at even 640x480. But, say one wanted a text display, with some graphics in it. Point the tiles to contain text at the internal ROM font, like TV_text.spin does, and stack up some tiles pointed to HUB RAM to serve as mini frame buffers. More than one can be done, just the total of unique bitmap graphics cannot exceed the HUB RAM space available for them.
From there, you add up your X and Y tile sizes, and call gr.setup with the information needed to point to that tile group, then call graphics methods, until what you want rendered is rendered. If there is more than one buffer area, call gr.setup again, and repeat. This can be done as often as needed to update any bitmap regions of the display.
IIRC, the 1024x768 VGA driver Chip did shows examples of doing this.
One of the most frustrating things I found early on was the naming for character outputs.
IIRC...
FDX uses .tx(ch)
TV uses .out(ch)
Yes, that is one gripe I hope to resolve. I will be going through and making the naming uniform. Right now I've settled on Char and CharIn because Spin doesn't support overloading and these make sense if there are commands like Str, Chars, Dec, Hex, etc. in the mix. This may change if it makes sense to do so.
In my PropOS I use a stdin and stdout driver via rendezvous locations in hub.
So standard programs use the stdin and stdout objects and I load drivers such as fdx (serial), tv & kbd, etc.
However, this might be a little advanced for beginners, but worth mentioning anyway.
How exactly does that work? How are you attaching objects to other objects? That sounds awesome and I'm not familiar with doing that in Spin.
I did some review and it looks like the Parallax Serial Terminal, which is based on FullDuplexSerial, has incorporated this change to allow resizing the buffer. If that is the only change, then I have already incorporated this update into the library (I'll be posting about that shortly).
Thanks for the links to all the objects! I'll look through them more tomorrow.
There has definitely been an overreliance on video objects in the demo code.
Well, to be fair, not everyone uses serial. I frankly do not use it much at all and prefer a character driver most of the time. This depends a lot on how people set up and why they do so.
I'll run a capture card to get nice output in a window on my laptop, and I do it to get rapid, mixed text, graphics display of program data, vars, etc...
I've seen others use serial and a scope or blinking lights or sounds to do similar things.
I know what you mean. I do most development on the LameStation so it's generally easier to just put it on the screen. There just needs to be more examples that don't require a specific hardware setup. Even better, if we put together more "terminal" drivers that are API-compatible with the serial driver, they can just be swapped out. Now that would be nice.
Off the top of your heads, do you guys have any suggestions for any of these? Can you think of any I haven't listed here that should be covered by this library? -
Should add ADCs MCP3202, 3204, 3208
Oooh, that would be a good one. Do you know any good drivers for it? Preferably one that can be used for all 3. Then it can be one object called:
As long as the VGA drivers are of the tile and palette type, like both VGA and TV.spin are, graphics.spin can be set to render into any area of VGA tiles arranged like they are in TV.spin.
There isn't enough RAM for full screen VGA displays at even 640x480. But, say one wanted a text display, with some graphics in it. Point the tiles to contain text at the internal ROM font, like TV_text.spin does, and stack up some tiles pointed to HUB RAM to serve as mini frame buffers. More than one can be done, just the total of unique bitmap graphics cannot exceed the HUB RAM space available for them.
From there, you add up your X and Y tile sizes, and call gr.setup with the information needed to point to that tile group, then call graphics methods, until what you want rendered is rendered. If there is more than one buffer area, call gr.setup again, and repeat. This can be done as often as needed to update any bitmap regions of the display.
IIRC, the 1024x768 VGA driver Chip did shows examples of doing this.
That's what I meant by, "a little bit of work"
I never did understand how those tiled video drivers work. That's why I was so adamant about giving the LameStation a frame buffer. Have you ever considered writing this book? I'd have a much better case for keeping all these video drivers in the library if I could explain to someone how to use them.
com.serial takes the core of Parallax Serial Terminal (which was basically the upgraded FullDuplexSerial object), and makes it a standalone object. Then com.serial.terminal (which was Parallax Serial Terminal) is just a wrapper around com.serial with some added control functions. The number-to-string functions have been offloaded onto string.numbers. In this way, both the serial core and the conversion functions only have to be maintained in one place for the whole library to be updated. This is a huge time-saver for maintenance.
I also added/updated the following easy, short demos. I'll be adding more tomorrow, and removing the ones labeled FullDuplexSerial.
Finally, the existing floating point libraries have been removed, and F32 has been added as math.float. I still need to rename its functions. With that in mind, does anyone know any good fixed-point math objects? I'd like to have math.fixed as well.
Hopefully this gives you guys a much better idea of what my expectations are for this library. It's not as hard as you might think to meet the criteria for inclusion. I did all of this in the span of a couple hours.
Here are the main things I am enforcing.
Indent levels
Function and constant names
Documentation comments in markdown
Outside of that, it's not as important. Your object doesn't need to be perfect. So for anyone still holding back, don't be shy; give it a try!
com.serial takes the core of Parallax Serial Terminal (which was basically the upgraded FullDuplexSerial object), and makes it a standalone object. Then com.serial.terminal (which was Parallax Serial Terminal) is just a wrapper around com.serial with some added control functions. The number-to-string functions have been offloaded onto string.numbers. In this way, both the serial core and the conversion functions only have to be maintained in one place for the whole library to be updated. This is a huge time-saver for maintenance.
I also added/updated the following easy, short demos. I'll be adding more tomorrow, and removing the ones labeled FullDuplexSerial.
Finally, the existing floating point libraries have been removed, and F32 has been added as math.float. I still need to rename its functions. With that in mind, does anyone know any good fixed-point math objects? I'd like to have math.fixed as well.
Hopefully this gives you guys a much better idea of what my expectations are for this library. It's not as hard as you might think to meet the criteria for inclusion. I did all of this in the span of a couple hours.
Here are the main things I am enforcing.
Indent levels
Function and constant names
Documentation comments in markdown
Outside of that, it's not as important. Your object doesn't need to be perfect. So for anyone still holding back, don't be shy; give it a try!
This all sounds great! If you can figure out a way to make use of Cluso99's rendevous console I/O interface to allow the serial driver to be swapped for one of the LCD drivers it would be even better.
Off the top of your heads, do you guys have any suggestions for any of these? Can you think of any I haven't listed here that should be covered by this library? -
Should add ADCs MCP3202, 3204, 3208
Oooh, that would be a good one. Do you know any good drivers for it? Preferably one that can be used for all 3. Then it can be one object called:
there is no function difference between an MCP3202, MCP3204 and MCP3208, only how many channels. So, the most you'd want to do is check the channel requested and, if too high, return an error. Other than that, all of the logic remains the same. Then the only difference between MCP300X, MCP320X, and MCP330X is how many bits you shift in. All of the bits are still in the same order, channels are selected in the same way, etc etc.
Brett, maybe. I've got some stuff written for the Parallax, what I call reference drivers. A lot of that is in the HYDRA book too.
The other drivers all vary considerably, and some are specific purpose too.
At this time, I remain unsure just what to put into such a work. Seems like it would have to cover video formats, signals, general graphics concepts, graphics hardware concepts such as tiles, sprites, colors, buffering strategies, etc... along with specific implementation details and math for the various drivers out there. Frankly, the HYDRA book, coupled with one on game design and graphics from the 90's era covers it well. That is for the Parallax drivers, and at least one other high color, game oriented one.
Andre' and I discussed this some time back. If someone gets "The Black Art of Game design" and the HYDRA book, they can do a lot.
One exception is tricks for technical, or instrumentation type displays. Game tricks apply, but can be hard to map over to a more industrial application...
So, I arrived at a place where it is either a real book, like maybe one people pay for, or it won't do too much more good than a forum search and or some time spent with the code would.
I'm not convinced the audience is all that large too. Could be bigger, build and they will come, but I really don't know.
So there is the state of it. I really don't know what would make sense, and the effort is non trivial enough to make that an obstacle.
The rendezvous idea is actually quite simple, but it does require a fixed location to pass the data.
Here is the basis of _hubdef3
CON
' OS Hub Definitions...
' ------------------ bytes
_HubFree = $7FFC ' 4 ' \ stores total hub available (typ $7800)
' | (hub is allocated to the OS above this value)
' / (eg $7000 means $0000-$6FFF is available)
_OS_DateTime = $7FF8 ' 4 'Year20xx Month Date Hours Minutes Seconds
' (00-63) (1-12) (1-31) (00-23) (00-59) (00-59)
' 000000___0000____00000___00000____000000____000000
'To convert to FAT16/32 format, shift >>1 then add 16<<25
' --> Y(7)M(4)D(5)H(5)M(6)S*2(5bits) Base=1980
' (FYI seconds in 4yrs = 126,230,400)
_OS_Rows = $7FF7 ' 1 ' \ combined <lf> and rows
_LF_MASK = $80 ' | b7 : 1= <lf> ON; 0= strip <lf>
_ROW_MASK = $7F ' / b0-6: no of rows on screen (0-127)
_OS_Columns = $7FF6 ' 1 ' no of cols on screen (0-255)
_OS_Cogs = $7FF5 ' 1 ' stay resident cogs: 1= don't stop on reboot
_OS_Clkmode = $7FF4 ' 1 ' clkmode: saved fm hub byte $0004
_OS_Clkfreq = $7FF0 ' 4 ' clkfreq(Hz): saved fm hub long $0000
_SDpins = $7FEC ' 4 ' \ sd pins packed 4 bytes
' ' / Byte 3=/CS, 2=DI, 1=CLK, 0=DO
_SIOpins = $7FE8 ' 4 ' \ serial pins and mode settings (and cog#)
' ' / Byte 3=cog, 2=mode, 1=SO, 0=SI
_SIObaud = $7FE4 ' 4 ' serial baud (speed typ 115,200)
_Hardware = $7FE0 ' 4 ' \ hardware: hi-word=company, lo-word=config
' | $0001 = Cluso99 $0001 = RamBlade 1
' | $0001 = Cluso99 $0002 = TriBlade#2
' | $0001 = Cluso99 $0003 = RamBlade3
' | $0001 = Cluso99 $0004 = P8XBlade2
' / $0001 = Cluso99 $0007 = CpuBlade7
' ^^^ may be more valuable for something else??
_AuxIn = $7FDC ' 4 ' auxilary input rendezvous
_AuxOut = $7FD8 ' 4 ' auxilary output rendezvous
_StdIn = $7FD4 ' 4 ' standard input rendezvous
_StdOut = $7FD0 ' 4 ' standard output rendezvous
_OSreserved = $7FC8 ' 8 ' undefined
_SDparam = $7FC4 ' 4 ' parameter \ for SD FAT driver
_SDcommand = $7FC0 ' 4 ' command /
_pBuffer_C = $7F80 ' 64 '| ' \ user buffers...
_pBuffer_B = $7F40 ' 64 '| ' | (maybe serial in and serial out buffers?)
_pBuffer_A = $7F00 ' 64 '| ' / (used to pass parameters between modules)
_pBuffer = $7F00 ' 192 '^ ' / ...joins all 3 buffers A+B+C
_pCogTables = $7E00 ' 256 ' \ 8*32B cog usage tables
' | TBD
' | Current thinking is...
' | 1 byte for "type"
' | 1 long for sector address to retrieve filename
' | However, could also be used as 2*16byte buffers
' / with the head+tail(s) kept in _StdIn & _StdOut
_pSectorBuf = $7C00 ' 512 ' SD card i/o buffer
_pSpinVector = $7800 ' 1024 ' vector table for Cluso's faster spin interpreter
_HUB_RESERVED = $7800 ' $7800-$7FFF currently reserved by the OS
_HUB_RAMSIZE = $8000 ' Total hub ram
Note the 4 longs _StdIn, _StdOut, _AuxIn, _AuxOut
Here is _StdOut.spin
VAR
long pRENDEZVOUS
PUB start(rendezvous)
pRENDEZVOUS := rendezvous 'get rendezvous location
PUB out(c)
'' Print a character
c |= $100 '0.FF -> 100..1FF 'add bit9=1 (allows $00 to be passed)
repeat while long[pRENDEZVOUS] 'wait for mailbox to be empty (=$0)
long[pRENDEZVOUS] := c 'place in mailbox for driver to act on
PUB str(stringptr)
'' Print a zero-terminated string
repeat strsize(stringptr)
out(byte[stringptr++])
PUB dec(value) | _i
'' Print a decimal number
if value < 0
-value
out("-")
_i := 1_000_000_000
repeat 10
if value => _i
out(value / _i + "0")
value //= _i
result~~
elseif result or _i == 1
out("0")
_i /= 10
PUB hex(value, digits)
'' Print a hexadecimal number
value <<= (8 - digits) << 2
repeat digits
out(lookupz((value <-= 4) & $F : "0".."9", "A".."F"))
PUB bin(value, digits)
'' Print a binary number
value <<= 32 - digits
repeat digits
out((value <-= 1) & 1 + "0")
and _StdIn.spin
VAR
long pRENDEZVOUS 'stores a pointer to the hub mailbox
PUB start(rendezvous)
pRENDEZVOUS := rendezvous 'get rendezvous location
PUB in : c
'' Wait for an input character
repeat until c := long[pRendezvous] 'wait until the mailbox has a character
long[pRendezvous]~ 'clear the mailbox
c &= $FF '$100 -> $00 'extract lower 8 bits (byte)
PUB peek
'' Returns a 0 if the buffer is empty,
'' else next character (+$100) but doesn't remove from the buffer.
'' The user routine must extract the 8 bits as the whole long is passed.
return long[pRendezvous] 'return ALL bits (long) in the mailbox
and _PCSIO.spin (how I use FDX as the cog for doing the real serial I/O via _StdIn & _StdOut
CON
RX1FIFO_SIZE = 160 '640 bytes
TX1FIFO_SIZE = 160 '640 bytes
VAR
long cog 'cog flag/id
long params[4] 'for passing parameters
PUB start(inRENDEZVOUS, outRENDEZVOUS, serPins, baud)
'' Start Serial driver - starts a cog if necessary
'' returns cog+1 if it had to start a cog, false if cog was already running.
'' serPins = rxPin << 8 | txPin
'' baud = baud
''
long[outRENDEZVOUS] := 4 'Ping Ser Driver
waitcnt(clkfreq>>2+cnt)
if long[outRENDEZVOUS] == 0
return False 'is alive
'else start driver
long[inRENDEZVOUS] := 0 'clear the rendezvous locations
long[outRENDEZVOUS] := ">"
params[0] := inRENDEZVOUS 'pass the parameters
params[1] := outRENDEZVOUS
params[2] := serPins
params[3] := clkfreq / baud
cog := cognew(@entry, @params) + 1 'Start the cog
repeat while long[outRENDEZVOUS] 'wait until cleared (ok to go)
return cog 'cog+1 (=0=false if failed)
DAT
ORG 0
'
' Initialisation.
'
entry mov t1,par 'get the address of the parameter list
rdlong rx1ptr,t1 'inRENDEZVOUS
add t1,#4
rdlong tx1ptr,t1 'outRENDEZVOUS
add t1,#4
rdlong t2,t1 'serPins
test t2,#$80 wz 'if $FF, disable tx
if_z mov tx1mask,#1 '=txmask
if_z shl tx1mask,t2
shr t2,#8 'rxPin
test t2,#$80 wz 'if $FF, disable rx
if_z mov rx1mask,#1 '=rxmask
if_z shl rx1mask,t2
add t1,#4
rdlong baud1,t1 'baudticks
' wrlong cNull,rx1ptr 'cleared by spin
wrlong cNull,tx1ptr 'signal OK to go
or OUTA,tx1mask
or DIRA,tx1mask
jmp dRx1
rx1ptr long 0
tx1ptr long 0
rx1mask long 0
tx1mask long 0
baud1 long 0
'
' Receiver
'
aRx1_Start mov rx1bits,#9 '# of bits to receive
mov rx1cnt,baud1
shr rx1cnt,#2 'quarter of a bit tick ...
add rx1cnt,baud1 '... plus a full bit tick
mov dRx1,#aRx1_Wait
aRx1_Wait test rx1mask, INA WC 'Wait for start bit
if_c jmp #aRx1_Get
add rx1cnt, CNT
mov dRx1,#aRx1_Bits
aRx1_Bits mov t1,rx1cnt 'Check if bit receive period done
sub t1,cnt
cmps t1,#0 WC 'Time to sample yet?
if_nc jmp #aRx1_Get
test rx1mask, INA WC 'Receive bit into carry
rcr rx1data,#1 'Carry into Rx buffer
add rx1cnt,baud1 'Go to next bit period
djnz rx1bits,#aRx1_Bits 'Get next bit
if_nc jmp #aRx1_Start
and rx1data,cRxAnd 'Mask out the unwanted bits
rol rx1data,rx1rol 'Put the data into the correct byte
mov dRx1,#aRx1_Put
jmp dTx1 'Go do some transmitter code
'General variables for the receiver
cRxAnd long %0111_1111_1000_0000_0000_0000_0000_0000
rx1len long 0
rx1maxlen long (tx1fifo - rx1fifo - 1) * 4
dRx1 long aRx1_Start
'Variables used to receive a byte into the FIFO
rx1data long 0
rx1bits long 0
rx1cnt long 0
rx1rol long 9
rx1out long 0
rx1put long rx1fifo
rx1putb long $80
'Variables used to grab a byte from the FIFO
rx1ror long 0
rx1get long rx1fifo
rx1getb long $80
aRx1_Put cmp rx1len,rx1maxlen WZ
if_z jmp #(aRx1_Get+2)
mov dRx1,#aRx1_Start
add rx1len,#1
or rx1out,rx1data 'Merge in the new data byte
arp1 mov rx1fifo,rx1out 'Write to the FIFO memory
add rx1rol,#8 'Prapare for the next byte
rol rx1putb,#8 WC 'C true every 4 cycles
if_nc jmp dTx1
add rx1put,#1
cmp rx1put,#tx1fifo WZ
if_z mov rx1put,#rx1fifo
movd arp1,rx1put 'Set the new FIFO destination
mov rx1out,#0
jmp dTx1
aRx1_Get cmp rx1len,#0 WZ
if_z jmp dTx1
rdlong t1,rx1ptr WZ 'Is the receive buffer empty?
if_nz jmp dTx1 'Jump if not
sub rx1len,#1
arg1 mov t1,rx1fifo
ror t1,rx1ror
and t1,#$ff WZ
if_z or t1,#$100 '$00=$100
wrlong t1,rx1ptr
add rx1ror,#8
rol rx1getb,#8 WC 'C true every 4 cycles
if_nc jmp dTx1
add rx1get,#1
cmp rx1get,#tx1fifo WZ
if_z mov rx1get,#rx1fifo
movs arg1,rx1get
jmp dTx1
'
' Transmitter
'
aTx1_Start cmp tx1len,#0 WZ
if_z jmp #aTx1_Put
mov dTx1,#aTx1_Byte
sub tx1len,#1
atg1 mov tx1data,tx1fifo
ror tx1data,tx1ror
and tx1data,#$ff
add tx1ror,#8
rol tx1getb,#8 WC
if_nc jmp dRx1
add tx1get,#1
cmp tx1get,#fifo1end WZ
if_z mov tx1get,#tx1fifo
movs atg1,tx1get
jmp dRx1
aTx1_Byte shl tx1data,#2
or tx1data,cFixedBits 'or in a idle line state and a start bit
mov tx1bits,#11
mov tx1cnt,cnt
aTx1_Bits shr tx1data,#1 WC
muxc OUTA,tx1mask
add tx1cnt,baud1 'Bit period counter
mov dTx1,#aTx1_Wait
jmp dRx1
aTx1_Wait mov t1,tx1cnt 'Check bit period
sub t1,CNT
cmps t1,#0 WC 'Is bit period done yet?
if_nc jmp #aTx1_Put
djnz tx1bits,#aTx1_Bits 'Transmit next bit
mov dTx1,#aTx1_Start
jmp dRx1
aTx1_Put cmp tx1len,#(fifo1end-tx1fifo) WZ
if_z jmp dRx1
rdlong t1,tx1ptr WZ
if_z jmp dRx1
wrlong cNull,tx1ptr
add tx1len,#1
and t1,#$ff
shl t1,tx1rol
add tx1rol,#8
or tx1out,t1
atp1 mov tx1fifo,tx1out
rol tx1putb,#8 WC
if_nc jmp dRx1
add tx1put,#1
cmp tx1put,#fifo1end WZ
if_z mov tx1put,#tx1fifo
movd atp1,tx1put
mov tx1out,#0
jmp dRx1
'General variables for the transmitter
tx1len long 0
tx1maxlen long (fifo1end - tx1fifo - 1) * 4
dTx1 long aTx1_Start
'Variables used to grab the transmit a byte from the FIFO
tx1data long 0
tx1bits long 0
tx1cnt long 0
tx1ror long 0
tx1get long tx1fifo
tx1getb long $80
'Variables used to receive a byte into the FIFO
tx1rol long 0
tx1put long tx1fifo
tx1putb long $80
tx1out long 0
'
' Data
'
cFixedBits long %1_0000_0000_0_1 'Stop + 8 x Data + Start + Idle bits
'cMinusOne long -1
cNull long 0
t1 long 0
t2 long 0
'
' The buffer sizes may be freely adjusted. As long as the code still compiles
' into the cog. The sizes are currently at their maximum, but may be adjusted
' to favour either the receiver or tranmitter.
'
rx1fifo res RX1FIFO_SIZE
tx1fifo res TX1FIFO_SIZE
fifo1end
FIT 496
I interface to these routines using these calls...
PRI GetKey
result := stdin.in ' wait for an input char
if result == _backspaceKeycode ' backspace keycode is 200 but convert to 8
result := _backspaceCharacter
PRI PrintHexadecimal(number, length)
PrintString(str.integerToHexadecimal(number, length))
PRI PrintDecimal(number) ' print the decimal value, useful for debugging
PrintString(str.integerToDecimal(number, 10))
PRI PrintStringCR(pstring) ' sends string to output devices (vga/serial) with CRLF
PrintString(pstring)
crlf
PRI PrintString(pstring) ' sends string to output devices (vga/serial) without CRLF
repeat strsize(pstring)
PrintChar(byte[pstring++])
PRI PrintChar(c) ' sends character to output devices (vga/serial)
if c <> _lineFeedCharacter
stdout.out(c) ' send char to output device
elseif byte[_hub#_OS_Rows] & _hub#_LF_MASK
stdout.out(c) ' send <lf> to output device
PUB CRLF
PrintChar(_carriageReturnCharacter) ' sends <cr> to output device
PrintChar(_lineFeedCharacter) ' sends <lf> to output device
Note the way I use <LF>. I have a flag in the hub rendezvous section that determines whether <LF> is send which can be turned on/off In my OS.
I use Kye's ASCII0_STREngine.spin for all the main string conversions.
However, I would change stringConcatenation to stringAppend as it is more meaningful.
Comments
It looks like "storage" might be a better name for your "io" package. I've only ever heard io refer to "input/output" but all of your other packages could be classified as io in that case (com, net, sensor).
Sensors are going to get messy very fast, so I am focusing on more general objects first. However, you can see from the current objects that I am trying to be as specific as possible with object names.
This is a learning experience however and the specifics of the naming convention are still being ironed out.
There appears to be an SPI driver but I'm not entirely sure how to test it. I2C, 1-Wire, CAN, and USB are all missing.
Haha, yes, good call. Let's call it "storage". There aren't actually any objects named "io" at this point.
John Abshier
No generic I2C in the OBEX??? That's awful... is that really true???
No no no no, I didn't mean there wasn't one in the OBEX. I meant not in the Spin library at present, and I don't know which I2C object is good. Any recommendations from anyone?
Sweet! Thanks! This looks like it can largely be used as is.
Not only that, it also comes with a demo! Woohoo!
I have a question. Can anyone tell me how FFDS1, the serial terminal included with F32, compares with FullDuplexSerial?
With a little work, VGA.spin also works with graphics.spin.
These two core drivers, along with graphics.spin do a lot. We have pushed what can be done in all sorts of ways, and that's good. However, the basic capabilities and resolutions in this set of code is well matched to both the overall Propeller capabilities and many projects.
The drivers are hybrid tile and bitmap capable. Graphics.spin can deliver pixels, text, etc... it can also be used to draw in windows, which can be very useful on mixed displays, where tiles and colors may be used in creative ways to avoid the ram and buffer cost of a full bitmap.
One can also display the ROM text by using the larger 32 pixel tile size, and TV_Text is a dedicated driver that does this.
More can be done than most are aware of, IMHO.
Ken Gracey
These are currently display.tv and display.tv.graphics in the library.
Can you elaborate on "a little work"?
The TV demo was one of the first ones I ran when I set up my first Propeller. It was awesome! But I had a hard time figuring out how it worked so I stopped playing around with it. >.>
So far as I have been able to tell, actually configuring and using the driver is not all that difficult. What is difficult is people unaware of graphics techniques and video basics.
I'll expand on the other thing in a bit.
Well, to be fair, not everyone uses serial. I frankly do not use it much at all and prefer a character driver most of the time. This depends a lot on how people set up and why they do so.
I'll run a capture card to get nice output in a window on my laptop, and I do it to get rapid, mixed text, graphics display of program data, vars, etc...
I've seen others use serial and a scope or blinking lights or sounds to do similar things.
I think something like that may have already emerged on accident.
The Spin standard library:
Compared to the Simple libraries:
IIRC...
FDX uses .tx(ch)
TV uses .out(ch)
In my PropOS I use a stdin and stdout driver via rendezvous locations in hub.
So standard programs use the stdin and stdout objects and I load drivers such as fdx (serial), tv & kbd, etc.
However, this might be a little advanced for beginners, but worth mentioning anyway.
Here are links to some good objects...
FullDuplexSerial_rr004 http://obex.parallax.com/object/249
Debug to TV using 1pin (includes 1pin kbd) http://obex.parallax.com/object/196
1pin TV Text (Eric Ball) http://obex.parallax.com/object/438
Nokia 5110 for the P1V http://forums.parallax.com/discussion/157003/adding-things-to-your-de0-p1-nokia-5110-lcd-etc
Nokia 5110 (a few versions on this thread including mine) http://forums.parallax.com/discussion/128736/new-nokia-5110-display-driver-in-the-obex
and some more info http://forums.parallax.com/discussion/148839/using-the-prop-pins-to-power-ics-modules
1.44" 128x128 color LCD (often called 5110 color) http://forums.parallax.com/discussion/159911/color-lcd-driver-for-cheap-1-44-spi-128-128-v1-1-red-black-pcbs
Should add ADCs MCP3202, 3204, 3208
As long as the VGA drivers are of the tile and palette type, like both VGA and TV.spin are, graphics.spin can be set to render into any area of VGA tiles arranged like they are in TV.spin.
There isn't enough RAM for full screen VGA displays at even 640x480. But, say one wanted a text display, with some graphics in it. Point the tiles to contain text at the internal ROM font, like TV_text.spin does, and stack up some tiles pointed to HUB RAM to serve as mini frame buffers. More than one can be done, just the total of unique bitmap graphics cannot exceed the HUB RAM space available for them.
From there, you add up your X and Y tile sizes, and call gr.setup with the information needed to point to that tile group, then call graphics methods, until what you want rendered is rendered. If there is more than one buffer area, call gr.setup again, and repeat. This can be done as often as needed to update any bitmap regions of the display.
IIRC, the 1024x768 VGA driver Chip did shows examples of doing this.
That's what I meant by, "a little bit of work"
Yes, that is one gripe I hope to resolve. I will be going through and making the naming uniform. Right now I've settled on Char and CharIn because Spin doesn't support overloading and these make sense if there are commands like Str, Chars, Dec, Hex, etc. in the mix. This may change if it makes sense to do so.
How exactly does that work? How are you attaching objects to other objects? That sounds awesome and I'm not familiar with doing that in Spin.
I did some review and it looks like the Parallax Serial Terminal, which is based on FullDuplexSerial, has incorporated this change to allow resizing the buffer. If that is the only change, then I have already incorporated this update into the library (I'll be posting about that shortly).
Thanks for the links to all the objects! I'll look through them more tomorrow.
I know what you mean. I do most development on the LameStation so it's generally easier to just put it on the screen. There just needs to be more examples that don't require a specific hardware setup. Even better, if we put together more "terminal" drivers that are API-compatible with the serial driver, they can just be swapped out. Now that would be nice.
Oooh, that would be a good one. Do you know any good drivers for it? Preferably one that can be used for all 3. Then it can be one object called:
I never did understand how those tiled video drivers work. That's why I was so adamant about giving the LameStation a frame buffer. Have you ever considered writing this book? I'd have a much better case for keeping all these video drivers in the library if I could explain to someone how to use them.
So today I reworked the following objects.
https://github.com/parallaxinc/spin-standard-library/tree/master/library
com.serial takes the core of Parallax Serial Terminal (which was basically the upgraded FullDuplexSerial object), and makes it a standalone object. Then com.serial.terminal (which was Parallax Serial Terminal) is just a wrapper around com.serial with some added control functions. The number-to-string functions have been offloaded onto string.numbers. In this way, both the serial core and the conversion functions only have to be maintained in one place for the whole library to be updated. This is a huge time-saver for maintenance.
I also added/updated the following easy, short demos. I'll be adding more tomorrow, and removing the ones labeled FullDuplexSerial.
https://github.com/parallaxinc/spin-standard-library/tree/master/library/demos/com/serial
Finally, the existing floating point libraries have been removed, and F32 has been added as math.float. I still need to rename its functions. With that in mind, does anyone know any good fixed-point math objects? I'd like to have math.fixed as well.
Hopefully this gives you guys a much better idea of what my expectations are for this library. It's not as hard as you might think to meet the criteria for inclusion. I did all of this in the span of a couple hours.
Here are the main things I am enforcing.
Outside of that, it's not as important. Your object doesn't need to be perfect. So for anyone still holding back, don't be shy; give it a try!
I'd recommend picking your favorite Spin object for any of the MCP3xxx devices and then use my MCP3000 object from PropWare as inspiration for tweaking it.
https://github.com/DavidZemon/PropWare/blob/release-2.0/PropWare/mcp3000.h
there is no function difference between an MCP3202, MCP3204 and MCP3208, only how many channels. So, the most you'd want to do is check the channel requested and, if too high, return an error. Other than that, all of the logic remains the same. Then the only difference between MCP300X, MCP320X, and MCP330X is how many bits you shift in. All of the bits are still in the same order, channels are selected in the same way, etc etc.
I went there - looked at some of the work - fantastic!
Erlend
The other drivers all vary considerably, and some are specific purpose too.
At this time, I remain unsure just what to put into such a work. Seems like it would have to cover video formats, signals, general graphics concepts, graphics hardware concepts such as tiles, sprites, colors, buffering strategies, etc... along with specific implementation details and math for the various drivers out there. Frankly, the HYDRA book, coupled with one on game design and graphics from the 90's era covers it well. That is for the Parallax drivers, and at least one other high color, game oriented one.
Andre' and I discussed this some time back. If someone gets "The Black Art of Game design" and the HYDRA book, they can do a lot.
One exception is tricks for technical, or instrumentation type displays. Game tricks apply, but can be hard to map over to a more industrial application...
So, I arrived at a place where it is either a real book, like maybe one people pay for, or it won't do too much more good than a forum search and or some time spent with the code would.
I'm not convinced the audience is all that large too. Could be bigger, build and they will come, but I really don't know.
So there is the state of it. I really don't know what would make sense, and the effort is non trivial enough to make that an obstacle.
Here is the basis of _hubdef3
Note the 4 longs _StdIn, _StdOut, _AuxIn, _AuxOut
Here is _StdOut.spin and _StdIn.spin
I use Kye's ASCII0_STREngine.spin for all the main string conversions.
However, I would change stringConcatenation to stringAppend as it is more meaningful.